API reference
Every export from @obscura-app/sdk, one section per symbol.
class Obscura
The agent-side client. Wraps fetch and handles the x402 payment
handshake transparently.
ts
import { Obscura } from "@obscura-app/sdk";
const agent = new Obscura(options: ObscuraOptions);ObscuraOptions
| Option | Type | Required | Default | Description |
|---|---|---|---|---|
apiKey | string | Yes | — | Agent API key (pk_…) from the dashboard. |
baseUrl | string | Yes | — | URL of the Obscura backend that signs payments (the host of your deployed apps/web). |
fetch | typeof globalThis.fetch | No | native fetch | Inject a custom fetch (undici, node-fetch, a mock in tests). |
signTimeoutMs | number | No | 60000 | Per-request timeout for /api/x402/sign. Mixer round-trip cold-path P99 lands around 45s — leave headroom. |
signMaxRetries | number | No | 2 | Auto-retry attempts on transient failures. 0 disables retry. Terminal errors never retry. |
signRetryBaseMs | number | No | 500 | First retry backoff in ms; doubles each retry, capped at 8s. |
agent.fetch(url, init?)
Behaves like fetch. On a 402 response with a PAYMENT-REQUIRED header,
signs via Obscura + retries the request with a PAYMENT-SIGNATURE
header. Returns the final Response.
Throws ObscuraError on any failure — see Error handling.
class ObscuraError
Typed error thrown by agent.fetch().
ts
import { ObscuraError } from "@obscura-app/sdk";
try {
await agent.fetch(url);
} catch (err) {
if (err instanceof ObscuraError) {
console.log(err.code); // ObscuraErrorCode
console.log(err.message); // human string
console.log(err.status); // HTTP status (only set for server-side codes)
}
}ObscuraError.code: ObscuraErrorCode
String literal union of every error the SDK can surface. See the error-code table for each code's meaning.
ts
type ObscuraErrorCode =
// Server-side (propagated from /api/x402/sign)
| "missing_token"
| "invalid_token"
| "agent_inactive"
| "invalid_challenge"
| "over_cap"
| "insufficient_funds"
| "rate_limited"
| "conflict"
| "signing_failed"
| "bad_request"
| "server_error"
// SDK-side
| "no_payment_required_header"
| "network_error"
| "timeout"
| "unknown";Protocol-level notes
- Confidential transfer. Each
PAYMENT-SIGNATUREis anumbra-mixer-v1envelope: a base64-encoded JSON of{queueSignature, callbackSignature, recipientEtaAddress, asset, amount, resource, scheme, network, proofSignature}. The merchant verifies it on-chain via Helius RPC before serving. - Obscura is never in the response path. Only
/api/x402/signsits between you and the merchant, and only during the brief signing window. Your response data flows agent ↔ merchant directly. - Replay protection is built in. Each
queueSignatureis bound to a specific (resource URL, amount, asset, recipient ETA) tuple, and the merchant SDK rejects re-presentation of the same signature within a 5-minute window. - No SOL on the agent side. Obscura's backend submits the queue + callback transactions and pays the network fee from a treasury wallet. Your agent only ever needs the configured stablecoin.