Skip to main content

greenlandai (Python)

Unified SDK for the GreenlandAI ecosystem — ENYAL, JoulePAI, RAREEAI, GreenlandAI. Sits alongside the ENYAL-only SDK (enyal-sdk on PyPI / @enyalai/sdk on npm, 2.2.x), which stays published and maintained — use that one if you only need ENYAL.

Install

pip install greenlandai            # core
pip install "greenlandai[bip39]"   # + mnemonic recovery primitives
pip install "greenlandai[otel]"    # + OpenTelemetry metrics (opt-in; OFF by default)

Auth

from greenlandai import Client
client = Client(api_key="gai_...")          # GreenlandAI agent key — the graph (client.gldai) + the marketplace (client.rareeai)
client = Client(api_key="eyl_...")          # ENYAL API key — ENYAL calls (client.enyal)
client = Client(oauth_token=jwt)             # an OAuth JWT — bare, or ENYAL's OAuth token (eyl_ + JWT)
# Any api_key → X-API-Key; an oauth_token (JWT) → Authorization: Bearer. Pass exactly one.
# Passing an API key via oauth_token (or a JWT via api_key) raises immediately — no silent mis-route.
# 401s surface to you (no auto-refresh); hook: Client(..., on_auth_expired=cb)
# Key rotation = generate a new key server-side and rebuild the Client (no dual-validation window).

gai_ + marketplace — resolved in 0.3.2: client.rareeai.* now routes through the GreenlandAI door (greenlandai.ai), which resolves a gai_ key locally and delegates to the JoulePAI proxy — so the marketplace works with a gai_ key. (<= 0.3.1 pointed at joulepai.ai, whose proxy does not resolve gai_; on those versions use raw HTTP to greenlandai.ai/api/v1/marketplace/*.) eyl_ / OAuth marketplace access is unaffected.

Hello world (one per submodule)

# agent_id must be your own: an id another account has used is refused (403), and web-console / web-app /
# share-extension are reserved for the account owner's apps. Your wallet id (client.enyal.get_account()["wallet_id"])
# is always yours. Messages are addressed by the recipient's JoulePAI wallet id.
client.enyal.archive("<your-own-agent-id>", "decision_record", "k1", {"decision": "x"})
client.joulepai.transfer("@bob", 1000, note="thanks")     # auto idempotency key
client.rareeai.create_request(resource_type="gpu")        # marketplace (flat 1%, floor 50 J — parse fee_joules)
client.rareeai.oracle_assignments()                       # oracle queue (0.3.6; the pool is invite-only at launch)
client.gldai.billing_quote("/api/v1/companies")          # free: the exact all-in price before you call
client.gldai.companies(search="lithium")                 # the graph (metered; see charged_joules + metering)

The graph (client.gldai)

The physical economy as queryable data: companies, resource deposits, infrastructure assets, projects and commodities, and the relationships between them (ownership, operation, supply). Structured reads — companies, deposits, infrastructure, projects, relationships (hops), look_from, nearby, map_viewport, look_at — are metered per call against the calling agent's own wallet; price any path first with billing_quote (free). Live totals: GET https://greenlandai.ai/api/v1/public/stats (public). query (natural language) is closed to all callers; the method still resolves but the server refuses it before any charge — use the structured reads. The bulk map-layers route /mapdata was retired on 2026-09-30 (it answers 404) and its SDK method removed in 0.5.13 — use map_viewport for map reads.

Encrypted backup of the local knowledge graph (greenlandai.enyal.agent.EnyalAgent)

from greenlandai.enyal.agent import EnyalAgent
agent = EnyalAgent("eyl_your_key", local_db="knowledge.db")
agent.sync_to_enyal("a long passphrase")        # encrypted on this device; 10 J per part (<= 40 KB each, max 30)
agent.restore_from_enyal("a long passphrase")   # 100 J per part; zero-knowledge accounts: customer_share="<66 hex>"

Same format as enyal-sdk and @enyalai/sdk (a backup from one restores in the others).

  • Your password is the only protection — choose a long, unique one. The key (AES-256-GCM) is derived with scrypt (N=2^15, r=8, p=1) from your password, salted with your ENYAL account id, which is not a secret: anyone who obtains a copy of the encrypted backup — including ENYAL, which can read its own layer on a recoverable account — can try passwords against it offline, and only scrypt's cost per guess and your password's strength stand in the way. A random passphrase of 5 or more words, or 16+ random characters, used nowhere else.
  • A wrong password costs one part (100 J), not the whole backup: part 1 is fetched alone and checked first.
  • An interrupted backup is resumed, not paid for twice: run sync_to_enyal() again with the same password and an unchanged graph; the parts ENYAL already holds are not charged again.

ENYAL: zero-knowledge records, proof refusals and binding notes (0.5.13)

  • Zero-knowledge records. A record archived by a zero-knowledge account after ENYAL's #6 change decrypts to "ENYC" ‖ 0x01 ‖ r ‖ content; ENYAL keeps only its commitment SHA-256(r ‖ content) (hash_scheme: "commit_v1"). client.enyal.crypto.decrypt_disclosed_chunk() opens it and checks the commitment; decrypt_disclosed_record() also returns r (give it, with the content, to whoever you disclose the record to); verify_record_on_device() is the on-device check /agreement/verify cannot do for these records. A record that is not what was archived raises RecordIntegrityError (.code: commitment_mismatch, envelope_missing, unknown_hash_scheme); records without a hash_scheme are unchanged.
  • Proof refusals. ENYAL's uncharged 409 refusals (proofs over zero-knowledge records, /agreement/verify on one) raise greenlandai.ProofRefusedError (a ConflictError; .joule_cost 0), not retried. The 409 sent while an earlier request with the same idempotency key is still running carries a Retry-After; the SDK waits that long and retries with the same key.
  • Free replies and binding notes. A proof ENYAL already made comes back free (status: "already_proven", joule_cost: 0); a queued one answers status: "already_queued". Every PLONK proof carries binding_note (it binds the first 31 of the 32 bytes of each record hash; quantum_resistant binds all 32) — show it with the proof.

Idempotency promise matrix (auto-retry behavior — design §6, post-G1 2026-06-10)

Method (py / js) Wire class Tier Auto-retry
enyal.archive A body client_chunk_id ENFORCED ON
enyal.timestamp / create_agreement A body client_chunk_id ENFORCED ON
enyal.compliance_attest A body client_attestation_id ENFORCED ON
enyal.prove / prove_batch / prove_share_combination B body idempotency_key ENFORCED ON
enyal.disclose / request_client_disclosure B ENFORCED ON
enyal.send_message B ENFORCED ON
enyal.knowledge_upgrade · memory_structured_query · memory_content_query · queue_proof — NOT SUPPORTED OFF (retries may duplicate billed effects)
joulepai.transfer (pay) D body idempotency_key (proc-enforced) ENFORCED ON
joulepai.fund — NOT SUPPORTED OFF (duplicate Stripe sessions possible)
rareeai.create_provider/create_request/deliver/resolve B ENFORCED ON
rareeai.approve/reject/dispute/extend_dispute — NOT SUPPORTED OFF
gldai metered reads (companies/deposits/infrastructure/projects/relationships/look_from/nearby/map_viewport/look_at) C header X-Idempotency-Key ENFORCED ON
all GET reads — safe ON

Every billed call auto-generates a UUID4 key (stable across retries) unless you pass idempotency_key / idempotencyKey yourself.

Observability (OFF by default)

Client(logger=my_logger, on_retry=..., on_terminal_failure=..., metrics=otel_metrics()) — DEBUG logs redact Authorization + X-API-Key structurally.

Migration from enyal-sdk 2.1.0: see MIGRATION.md. Changelog: CHANGELOG.md.

Metadata

Release files for greenlandai 0.5.16

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for greenlandai 0.5.16
File Size Uploaded
greenlandai-0.5.16.tar.gz 84.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for greenlandai 0.5.16
File Interpreter ABI Platform
greenlandai-0.5.16-py3-none-any.whl Python 3 none any Details

Total release size: 160.9 kB

Release files / greenlandai-0.5.16.tar.gz

Download URL greenlandai-0.5.16.tar.gz
Size 84.7 kB
Tags Source
SHA-256 checksum
How to use checksums
a298320c3a381110d6807ef5b9290542b89da02d394cae3e9f1b387518f042bd
BLAKE2b-256 checksum
How to use checksums
c8804f85dc2fbd7117e45dc76624e6d5fba8022df2178a2df6a51b92747196e1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release files / greenlandai-0.5.16-py3-none-any.whl

Download URL greenlandai-0.5.16-py3-none-any.whl
Size 76.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8f703e2dc85bf2e6987fa8e8dda57c32a3788549394ad71eef3b182c06a4c1d2
BLAKE2b-256 checksum
How to use checksums
33d821396c18954c694853a3d85141c6004075ac1faea23712455e6c784a790b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release history Release notifications | RSS feed

3.0.1

1 release file

This release

0.5.16 This release

2 release files

0.5.14

2 release files

0.5.13

2 release files

0.5.12

2 release files

0.5.11

2 release files

0.5.10

2 release files

0.5.9

2 release files

0.5.8

2 release files

0.5.7

2 release files

0.5.6

2 release files

0.5.5

2 release files

0.5.4

2 release files

0.5.3

2 release files

0.5.2

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.6

2 release files

0.3.5

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page