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

@grandprotocol/sdk

v0.2.1

Published

The official TypeScript SDK for Grand Protocol, cohesive payment infrastructure for AI agents

Readme

@grandprotocol/sdk

The payment rail for autonomous AI agents, in one import.

Agents rent compute, call paid APIs, and hire other agents. Every one of those services picks a payment protocol, and right now that means x402 or MPP. This SDK lets your agent pay either one through a single pay() call, with every transaction settled and recorded on Robinhood Chain.

You write the request. Grand Protocol negotiates the protocol, checks your spend policy, signs the payment, and hands you back the API response together with a transaction hash you can look up on-chain.

import { GrandProtocol } from "@grandprotocol/sdk";

const grand = new GrandProtocol({
  agentId: "research-agent-v2",
  apiKey: process.env.GRAND_API_KEY!,
});

const result = await grand.pay({
  endpoint: "https://api.dune.com/v1/query/1234/results",
});

result.data;        // the response body from Dune
result.protocol;    // "mpp"  (detected, not configured)
result.amountPaid;  // { usdg: 0.002 }
result.txHash;      // 0x5e9a...c41f on Robinhood Chain

Install

npm install @grandprotocol/sdk
  • Node.js 18 or newer (the SDK uses the built-in fetch, so there are no runtime dependencies)
  • Ships ESM and CommonJS builds with full TypeScript declarations

What happens inside pay()

The whole point of the SDK is that you never think about the steps below. It is still worth knowing what they are.

  1. Your agent's request is forwarded to the Grand Protocol gateway along with your agentId.
  2. The gateway calls the target endpoint. If the service answers with HTTP 402, the gateway reads the response and works out whether the service speaks x402 or MPP. If a service supports both, x402 wins by default because it is lower overhead and fully on-chain.
  3. Your spend policy is enforced before any money moves. Daily budget, per-call limit, domain allowlist, rate limit. A call that would breach policy is rejected here, not after the fact.
  4. The payment is constructed and signed. For x402 that is an EIP-712 typed-data signature and a PAYMENT-SIGNATURE header. For MPP it is a session, reused across calls where possible.
  5. The original request is retried with payment attached and the service responds normally.
  6. The settlement is recorded on Robinhood Chain, including the protocol used, the amount, the counterparty, and the policy check result.

You receive the service's response and the on-chain transaction hash in the same object.


Agent wallets

Every agentId maps to a smart contract wallet on Robinhood Chain, deployed deterministically from the ID. The wallet holds USDG and is the source of funds for every payment the agent makes. It is provisioned the first time the agent is seen and returned unchanged after that.

const wallet = await grand.wallet.get();
wallet.address;       // 0x7A3f...b1A2
wallet.balance.usdg;  // 42.5

// Shorthand when you only need the number
const { usdg } = await grand.wallet.balance();

// Top up from the funding source attached to your account
const receipt = await grand.wallet.fund({ usdg: 50 });
receipt.txHash;   // funding transaction on Robinhood Chain
receipt.balance;  // { usdg: 92.5 }

Wallets are non-custodial. Grand Protocol cannot move funds without a valid transaction signed by the agent's registered key. You can also send USDG straight to the wallet address from any Robinhood Chain wallet.


Spend policies

Policies are set once per agent and enforced by the gateway on every call. There is no per-request budgeting code to write, and no way for a runaway loop to spend past the cap.

await grand.policies.set({
  dailyBudget: { usdg: 100 },
  perCallLimit: { usdg: 1.0 },
  allowedDomains: ["api.dune.com", "api.browserbase.com", "fal.ai"],
  blockedDomains: [],
  rateLimit: { calls: 500, window: "1h" },
});

const active = await grand.policies.get();

| Field | Effect | | --- | --- | | dailyBudget | Total USDG the agent may spend in a rolling 24-hour window | | perCallLimit | Maximum USDG for any single payment | | allowedDomains | If set, payments are only permitted to these hosts | | blockedDomains | Hosts that are always refused, even if allowlisted | | rateLimit | Maximum number of paid calls per window, for example { calls: 500, window: "1h" } |

A payment that fails a policy check throws PolicyViolationError and nothing leaves the wallet. Policy violations are logged on-chain, so an auditor can see what was attempted as well as what was paid.


Transactions

The ledger is the blockchain. The transactions resource is a convenient view over it.

const page = await grand.transactions.list({ limit: 50 });
page.transactions;  // Transaction[]
page.total;         // count across all pages
page.hasMore;       // true if there is another page

// Narrow by protocol and time range
const januaryX402 = await grand.transactions.list({
  protocol: "x402",
  from: "2026-01-01T00:00:00Z",
  to: "2026-01-31T23:59:59Z",
  offset: 0,
});

// Look up a single payment
const tx = await grand.transactions.get("0x5e9a3f...c41f");
tx.status;        // "confirmed" | "pending" | "failed"
tx.explorerUrl;   // direct link to the Robinhood Chain explorer
tx.parentTxHash;  // set when this payment was made on behalf of another agent

Each transaction record carries the agent, the endpoint, the amount, the protocol, a timestamp, a status, and an explorer link. When an orchestrating agent delegates work to a sub-agent, the sub-agent's payments carry the orchestrator's transaction hash in parentTxHash, so the whole chain of spending is traceable from the top.


Idempotency

Pass an idempotencyKey on any pay() or fund() call to make retries safe. If the same key is seen twice, the gateway returns the original result instead of paying again.

await grand.pay({
  endpoint: "https://api.fal.ai/v1/inference",
  method: "POST",
  body: { model: "flux-pro", prompt: "a lighthouse at dusk" },
  idempotencyKey: `job-${jobId}`,
});

Privacy mode

By default every payment is fully transparent on Robinhood Chain. For workloads where the counterparty or amount is sensitive, you can opt into zero-knowledge settlement per call.

const result = await grand.pay({
  endpoint: "https://api.service.com/resource",
  method: "POST",
  body: { query: "..." },
  privacy: {
    mode: "full",                            // or "confidential_amount"
    disclosureKey: complianceOfficerPubKey,  // optional
  },
});

result.txHash;           // a nullifier hash, no identity on-chain
result.privateNote;      // encrypted note for your own records
result.disclosureProof;  // openable only by the disclosureKey holder

| Mode | On-chain visibility | | --- | --- | | transparent | Everything public. This is the default when privacy is omitted. | | confidential_amount | Counterparty visible, amount hidden | | full | Neither counterparty nor amount visible |

Supplying a disclosureKey lets a named auditor decrypt the payment later without making it public. Private payments are routed through a separate gateway path and still count against your spend policies.


Errors

Every error thrown by the SDK extends GrandError, which exposes a machine-readable code and, where relevant, the HTTP statusCode from the gateway.

import {
  GrandProtocol,
  GrandError,
  AuthenticationError,
  InsufficientFundsError,
  PolicyViolationError,
  RateLimitError,
  APIError,
} from "@grandprotocol/sdk";

try {
  await grand.pay({ endpoint: "https://api.service.com/resource" });
} catch (err) {
  if (err instanceof InsufficientFundsError) {
    await grand.wallet.fund({ usdg: 25 });
  } else if (err instanceof PolicyViolationError) {
    // blocked by dailyBudget, perCallLimit, domain rules, or rateLimit
  } else if (err instanceof RateLimitError) {
    // back off and retry
  } else if (err instanceof GrandError) {
    console.error(err.code, err.statusCode, err.message);
  }
}

| Class | code | Gateway status | When | | --- | --- | --- | --- | | AuthenticationError | authentication_error | 401 | The API key is missing, revoked, or wrong | | InsufficientFundsError | insufficient_funds | 402 | The agent wallet cannot cover the payment | | PolicyViolationError | policy_violation | 403 | A spend policy rejected the call | | RateLimitError | rate_limit_exceeded | 429 | The agent's rateLimit window is exhausted | | APIError | api_error | anything else | Any other non-2xx response from the gateway |


API reference

new GrandProtocol(config)

| Option | Type | Required | Description | | --- | --- | --- | --- | | agentId | string | Yes | Stable identifier for this agent. Determines the wallet address. | | apiKey | string | Yes | Your Grand Protocol API key | | baseUrl | string | No | Gateway URL. Defaults to https://api.grandprotocol.org. |

The constructor throws immediately if agentId or apiKey is empty.

grand.pay(options): Promise<PayResult>

| Option | Type | Default | Description | | --- | --- | --- | --- | | endpoint | string | required | The paid service URL | | method | "GET" \| "POST" \| "PUT" \| "PATCH" \| "DELETE" | "GET" | HTTP method | | body | unknown | | Request body, JSON-encoded | | headers | Record<string, string> | | Extra headers forwarded to the service | | privacy | PrivacyOptions | | Enable zero-knowledge settlement | | idempotencyKey | string | | Deduplicate retries |

Returns { status, txHash, amountPaid, protocol, data, privateNote?, disclosureProof? }.

grand.wallet

| Method | Returns | | --- | --- | | get() | WalletInfo with agentId, address, and balance | | balance() | { usdg: number } | | fund({ usdg, idempotencyKey? }) | FundResult with txHash, amount, and the new balance |

grand.transactions

| Method | Returns | | --- | --- | | list({ limit?, offset?, protocol?, from?, to? }) | { transactions, total, hasMore } | | get(txHash) | A single Transaction |

grand.policies

| Method | Returns | | --- | --- | | get() | The active SpendPolicy for this agent | | set(policy) | The saved SpendPolicy |

All option and result types are exported: GrandConfig, PayOptions, PayResult, PrivacyOptions, WalletInfo, WalletBalance, FundOptions, FundResult, Transaction, TransactionList, ListTransactionsOptions, and SpendPolicy.


About the settlement layer

Robinhood Chain is an Ethereum Layer 2 built on the Arbitrum stack, with 100ms block times and settlement to Ethereum for security. It is fully EVM-compatible, so existing wallets, indexers, and x402 tooling work without changes. USDG is the settlement token for every Grand Protocol payment.

| | | | --- | --- | | Chain ID | 4663 (mainnet), 46630 (testnet) | | Gas token | ETH | | Settlement token | USDG (ERC-20) |


What this SDK is not

  • Not an agent framework. Bring your own orchestration. This package only handles paying for things.
  • Not a wallet you have to manage. Keys are registered per agent and never pass through your application code.
  • Not a fee layer. Grand Protocol takes no percentage of transaction volume.

Documentation · Dashboard · grandprotocol.org

MIT licensed.