@drm3/sdk
v0.1.4
Published
The DRM3 network SDK. One package to integrate an app or agent with DRM3: identity (offline SSO verify), the user's credit balance, a cross-app switcher, cross-app alerts, an in-browser receipt viewer, partner key management, the x402 payment gateway core
Maintainers
Readme
What it is
The one package to put an app or an agent on the DRM3 network. Add an account, a credit balance, x402 payments, partner keys, and provenance receipts to the code you already have, then ship.
@drm3/sdk is a thin, typed client. Identity checks, x402 payments, and receipt chains verify
locally with Web Crypto; everything else is a plain HTTPS call to a DRM3 surface. There is no
service to host, no daemon, and no sidecar. It ships compiled and typed, and it carries the drm3
CLI for key operations in a terminal. Import a subpath into your code, or run npx drm3. That is the
whole SDK.
Install
npm install @drm3/sdk # or: pnpm add @drm3/sdk · yarn add @drm3/sdk · bun add @drm3/sdkTypeScript types are bundled, and the drm3 CLI installs alongside the library.
What you need
- The library: a JS runtime with
fetchand Web Crypto (crypto.subtle, Ed25519). Every current runtime has both: browsers, Node 20+, Deno, Bun, and edge or serverless runtimes including Cloudflare Workers, Vercel Edge, and Fly or Docker containers. - The
drm3CLI: Node 20 or newer. - One runtime dependency:
@noble/curvesand@noble/hashes(audited, zero-dependency crypto). Nothing else.
Install works the same on Windows, macOS, and Linux: it is a normal npm package, so if npm
runs, it installs. Module format is ESM with subpath exports and sideEffects: false, so a bundler
ships only the code you import.
What is in it
Each capability has its own subpath. A server never pulls the browser UI; a browser never pulls the Postgres driver.
| Import | What it does | Runs in |
|--------|--------------|---------|
| @drm3/sdk | Sign-in URLs, the live app catalog, the user's credit balance, Data Passport writes | server or browser |
| @drm3/sdk/sso | Verify the DRM3 identity token locally, per-app launch tokens, a revocation gate | server |
| @drm3/sdk/x402 | The x402 "exact" payment gateway: verify a signed payment, build the 402 offer | server |
| @drm3/sdk/meter | Non-custodial credit ledger: authorize / capture / void / settle, plus a multi-bucket wallet | server |
| @drm3/sdk/keys | Partner signing keys: generate, build a CSR, verify a receipt chain to the DRM3 Root | server or browser |
| @drm3/sdk/switcher | The cross-app switcher tile grid, one call | browser |
| @drm3/sdk/alerts | The cross-app alerts bell, one call | browser |
| @drm3/sdk/receipts | The in-browser provenance receipt viewer and a verify button | browser |
| drm3 (CLI) | Generate keys, submit a CSR, verify receipts, check partner status | terminal (Node 20+) |
Prebuilt browser bundles ship at @drm3/sdk/receipts/global and @drm3/sdk/alerts/global for a plain
<script> tag, no bundler required.
The CLI
The drm3 CLI is the terminal half of the SDK: the same signing discipline, for a human or an agent
at a prompt. Zero install with npx drm3. It makes an Ed25519 keypair locally (the private key never
leaves your machine), builds and submits a CSR, verifies a receipt chain to the DRM3 Root, and reads
live fleet and registry status.
npx drm3 keys generate --out signing.key # Ed25519 keypair, private key stays with you
npx drm3 keys submit --subject my-app --key signing.key
npx drm3 keys verify receipt.json
npx drm3 statusThe DRM3 surfaces it talks to
Four surfaces. Most of the SDK runs locally; the network calls are few and cacheable.
| Surface | Host | Used for |
|---------|------|----------|
| Account hub | drm3.network | sign in/out, credit balance, alerts, Passport writes, the revocation feed |
| Registry + CA | status.drm3.network | the app catalog, the public key registry, CSR submit and certificate issuance |
| Metered inference | queue.drm3.network | the optional shared credit meter |
| Base chain | USDC on Base | where an x402 payment settles, out of band. The SDK never touches it. |
Architecture
The app or agent is the center. It verifies identity, payments, and receipts locally, and makes a handful of cacheable calls to the DRM3 surfaces. It never holds a wallet key and never settles money.
The interactions
Every flow, its exact endpoint, and what stays local. Each diagram reads top to bottom.
Sign in
The user authenticates once at the hub and comes back with a drm3_sso token. Your app verifies that
token locally on every request after that, with no further call to the hub.
import { createRevocationGate, verifyActiveSsoToken } from "@drm3/sdk/sso";
const gate = createRevocationGate({ url: "https://drm3.network/api/sso/revocations" });
const claims = await verifyActiveSsoToken(process.env.DRM3_SSO_SECRET!, token, gate);
if (!claims) return new Response("unauthorized", { status: 401 }); // signature, expiry, revocation, all localSign out
One redirect clears the shared session across every DRM3 app, not just yours.
Generate a signing key
Fully local. The private key is created on your machine and never leaves it. DRM3 is not contacted.
npx drm3 keys generate --out signing.key # private key stays with youGet your key certified
You send a self-signed CSR carrying only your public key. A DRM3 operator approves it and the Root signs an attestation. DRM3 never sees your private key.
npx drm3 keys submit --subject my-app --key signing.keyVerify a key or a receipt chain
Anyone can do this. Fetch the public key registry once, then verify the Ed25519 chain locally: a receipt links to its issuer attestation, which links to the DRM3 Root.
npx drm3 keys verify receipt.jsonRead the credit balance
A single call to the hub with the user's identity token.
Meter usage
The ledger is yours (SQLite / D1 or Postgres). authorize reserves credits and cannot overdraft;
capture settles the real cost and releases the rest. The remote meter is optional, for the shared
metered-inference path only.
import { CreditsClient, InMemoryAdapter } from "@drm3/sdk/meter";
const credits = new CreditsClient({ adapter: new InMemoryAdapter() }); // or a D1 / Postgres adapter
const auth = await credits.authorize({ tenant: claims.sub, maxCredits: 100n });
if (!auth.ok) return new Response("payment required", { status: 402 });
await credits.capture(auth.reservation.id, { credits: 84n });Alerts
Read the user's cross-app alerts and mark them read. The same bell mounts in any DRM3 app.
Data access (Passport)
The user grants your app a Passport token at the hub's consent screen. Your app then writes into its own namespace under the user's record. The hub re-checks the token audience on every write.
x402 payment
Your app answers 402 with an offer. The agent signs an EIP-3009 authorization to payTo and retries.
verifyX402Payment checks the signature locally: it holds no key and broadcasts nothing. Settlement
is out of band - the signed authorization is submitted on-chain by the caller or a facilitator, which
moves USDC directly to payTo. The SDK does not settle and never custodies funds.
import { verifyX402Payment, x402Body } from "@drm3/sdk/x402";
const cfg = { payTo: process.env.X402_PAY_TO!, priceAtomic: 10_000n }; // 0.01 USDC on Base
const header = req.headers.get("x-payment");
if (!header) return Response.json(x402Body(cfg, { resource: "/answer", description: "One answer" }), { status: 402 });
const result = verifyX402Payment(header, cfg); // pure, holds no key
if (!result.ok) return new Response(result.error, { status: 402 });
// result.payer is recovered from the signature. Run your nonce-replay gate, then serve.Offers
x402Body builds the 402 menu. accepts is the machine-payable x402 requirement; offers and
hint are additive extras for humans and apps, and x402 clients ignore them.
Browser drop-ins
Three one-call widgets. Mount them into an element and they render, fetch, and stay in sync.
import { mountAppSwitcher } from "@drm3/sdk/switcher";
import { mountAlertsBell } from "@drm3/sdk/alerts";
import { mountVerifyButton } from "@drm3/sdk/receipts";
mountAppSwitcher(document.getElementById("switcher"));
mountAlertsBell(document.getElementById("bell"));
mountVerifyButton(document.getElementById("verify"), { receiptId });For agents and LLMs
An agent puts itself on the network the same way an app does: npm install @drm3/sdk, then import the
one subpath it needs. For keys, run npx drm3 keys generate --out signing.key (the private key stays
local) and verify receipt chains with npx drm3 keys verify. To pay an x402-gated endpoint, sign an
EIP-3009 authorization to the offer's payTo and retry with the X-PAYMENT header.
A machine-readable summary of the package, its subpaths, the CLI, and the DRM3 surfaces lives in
llms.txt.
Feedback and submissions
We do not accept pull requests or code contributions: the SDK is source-managed by DRM3 Labs Corp. so every app and agent on the network shares one signed, tested surface. We do want your ideas, feature requests, and bug reports. Open a GitHub issue on this repository, or email [email protected]. See CONTRIBUTING.md.
License
Free to use, including in commercial products. Use @drm3/sdk and the drm3 CLI to build and
ship your own apps and agents on the DRM3 network. No fee, no signup, no agreement to sign, and the
grant is not revoked as long as you play by the rules.
It is not open source: the SDK is DRM3 Labs Corp. property, so you cannot repackage or resell the SDK on its own, reverse-engineer it, or use it to build a competing network. Build anything you want on DRM3 with it; just do not clone or resell the SDK itself. Full terms in LICENSE. Questions: [email protected].
