npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@greenlandai/sdk

v0.5.13

Published

Unified SDK for the GreenlandAI ecosystem (ENYAL, JoulePAI, RAREEAI, GreenlandAI)

Readme

greenlandai (JavaScript)

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

npm install @greenlandai/sdk

Auth

import { Client } from "@greenlandai/sdk";        // ESM
const { Client } = require("@greenlandai/sdk");     // CJS
const client = new Client({ apiKey: "gai_..." });    // GreenlandAI agent key — the graph (client.gldai) + the marketplace (client.rareeai)
const client = new Client({ apiKey: "eyl_..." });    // ENYAL API key — ENYAL calls (client.enyal)
const client = new Client({ oauthToken: jwt });      // an OAuth JWT — bare, or ENYAL's OAuth token (eyl_ + JWT)
// Any apiKey → X-API-Key; an oauthToken (JWT) → Authorization: Bearer. Pass exactly one.
// Passing an API key via oauthToken (or a JWT via apiKey) throws immediately — no silent mis-route.
// 401s surface to you (no auto-refresh); hook: onAuthExpired

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)

// agentId 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.getAccount()).wallet_id
// is always yours. Messages are addressed by the recipient's JoulePAI wallet id.
await client.enyal.archive({ agentId: "<your-own-agent-id>", chunkType: "decision_record", chunkKey: "k1", data: { decision: "x" } });
await client.joulepai.transfer("@bob", 1000, { note: "thanks" });   // auto idempotency key
await client.rareeai.createRequest({ resourceType: "gpu" });   // marketplace (flat 1%, floor 50 J — parse fee_joules)
await client.rareeai.oracleAssignments();                      // oracle queue (0.3.6; the pool is invite-only at launch)
await client.gldai.billingQuote("/api/v1/companies");      // free: the exact all-in price before you call
await 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 mapViewport for map reads.

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.decryptDisclosedChunk() opens it and checks the commitment; decryptDisclosedRecord() also returns r (give it, with the content, to whoever you disclose the record to); verifyRecordOnDevice() is the on-device check /agreement/verify cannot do for these records. A record that is not what was archived throws 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) throw ProofRefusedError (a ConflictError; .jouleCost 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; quantumResistant 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)

new Client({ apiKey, logger: console, onRetry, onTerminalFailure, metrics }) — DEBUG logs redact Authorization + X-API-Key structurally.

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