yeetful 0.3.1 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/agent.cjs CHANGED
@@ -254,7 +254,10 @@ function yeetful(options) {
254
254
  note: r.note
255
255
  })
256
256
  });
257
- if (!res.ok) log(`ledger sync \u2192 ${res.status} for ${r.host}`);
257
+ if (!res.ok) {
258
+ const moved = res.redirected ? ` (request was redirected to ${new URL(res.url).origin}, which strips the auth header \u2014 set ledgerUrl to that origin)` : "";
259
+ log(`ledger sync \u2192 ${res.status} for ${r.host}${moved}`);
260
+ }
258
261
  }).catch((err) => {
259
262
  log(`ledger sync failed for ${r.host}: ${err instanceof Error ? err.message : err}`);
260
263
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils.ts","../src/client.ts","../src/agent.ts"],"names":["pay"],"mappings":"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","file":"agent.cjs","sourcesContent":["import type { X402Network } from './types.js'\n\nconst USDC_BY_NETWORK: Record<X402Network, `0x${string}`> = {\n base: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n 'base-sepolia': '0x036CbD53842c5426634e7929541eC2318f3dCF7e',\n ethereum: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n optimism: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85',\n arbitrum: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',\n polygon: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n}\n\nexport const USDC_DECIMALS = 6\n\n/** Returns the canonical USDC contract address for a supported network. */\nexport function usdcAddress(network: X402Network): `0x${string}` {\n return USDC_BY_NETWORK[network]\n}\n\n/**\n * Convert a human-friendly USD amount (e.g. \"0.01\") into atomic USDC units.\n * Fixed-point to avoid float drift — safer than Number math for payments.\n */\nexport function usdToAtomic(amount: string | number, decimals = USDC_DECIMALS): string {\n const str = typeof amount === 'number' ? amount.toString() : amount\n if (!/^\\d+(\\.\\d+)?$/.test(str)) {\n throw new Error(`Invalid amount: ${str}`)\n }\n const [whole, frac = ''] = str.split('.')\n const padded = frac.slice(0, decimals).padEnd(decimals, '0')\n return (BigInt(whole ?? '0') * 10n ** BigInt(decimals) + BigInt(padded || '0')).toString()\n}\n\nconst utf8Encoder = new TextEncoder()\nconst utf8Decoder = new TextDecoder()\n\n/** Base64 encode a JSON value — works in Node 18+ and browsers. */\nexport function encodePayment(value: unknown): string {\n const bytes = utf8Encoder.encode(JSON.stringify(value))\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(bytes).toString('base64')\n }\n let binary = ''\n for (const byte of bytes) binary += String.fromCharCode(byte)\n return btoa(binary)\n}\n\n/** Base64 decode a payment header value back into JSON. */\nexport function decodePayment<T = unknown>(b64: string): T {\n let bytes: Uint8Array\n if (typeof Buffer !== 'undefined') {\n bytes = new Uint8Array(Buffer.from(b64, 'base64'))\n } else {\n const binary = atob(b64)\n bytes = new Uint8Array(binary.length)\n for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i)\n }\n return JSON.parse(utf8Decoder.decode(bytes)) as T\n}\n\n/** Generate a random 32-byte nonce as a 0x-prefixed hex string. */\nexport function randomNonce(): `0x${string}` {\n const bytes = new Uint8Array(32)\n globalThis.crypto.getRandomValues(bytes)\n return ('0x' + Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('')) as `0x${string}`\n}\n","import type { Address, Hex, WalletClient } from 'viem'\nimport type {\n ExactEvmPayload,\n PaymentEnvelopeV2,\n PaymentPayload,\n PaymentRequiredResponse,\n PaymentRequirement,\n X402Network,\n} from './types.js'\nimport { decodePayment, encodePayment, randomNonce } from './utils.js'\n\nexport interface ClientOptions {\n /** A viem WalletClient able to sign EIP-712 typed data. */\n wallet: WalletClient\n /** Underlying fetch to wrap (defaults to global fetch). */\n fetch?: typeof fetch\n /**\n * Hook called before signing. Return `false` to reject the payment.\n * Useful for showing a confirmation UI to the user.\n */\n onPaymentRequired?: (requirement: PaymentRequirement) => boolean | Promise<boolean>\n /** Only allow payments up to this atomic-units cap. Safety belt. */\n maxAmountAtomic?: bigint\n /** Restrict to specific networks (defaults to all). */\n allowedNetworks?: X402Network[]\n}\n\n/**\n * Create a fetch wrapper that transparently handles x402 payments —\n * protocol v1 (\"base\" networks, `maxAmountRequired`, `X-PAYMENT` header)\n * and v2 (CAIP-2 networks, `amount`, `PAYMENT-SIGNATURE` envelope) alike.\n *\n * On a 402 response, it picks the cheapest acceptable requirement,\n * signs an EIP-3009 authorization with the provided wallet, and retries\n * the request with the version-appropriate payment header.\n *\n * @example\n * ```ts\n * const pay = createPaymentClient({ wallet })\n * const res = await pay('https://api.example.com/premium')\n * ```\n */\nexport function createPaymentClient(options: ClientOptions) {\n const baseFetch = options.fetch ?? globalThis.fetch.bind(globalThis)\n\n return async function payFetch(\n input: string | URL | Request,\n init: RequestInit = {},\n ): Promise<Response> {\n const first = await baseFetch(input, init)\n if (first.status !== 402) return first\n\n const requirements = await parsePaymentRequired(first)\n const requirement = selectRequirement(requirements.accepts ?? [], options)\n if (!requirement) {\n throw new PaymentError('No acceptable payment requirement matched client constraints', requirements)\n }\n\n if (options.onPaymentRequired) {\n const approved = await options.onPaymentRequired(requirement)\n if (!approved) throw new PaymentError('Payment rejected by user', requirements)\n }\n\n const payload = await signExactAuthorization(options.wallet, requirement)\n const header = buildPaymentHeader(requirements, requirement, payload)\n const headers = new Headers(init.headers)\n headers.set(header.name, header.value)\n\n return baseFetch(input, { ...init, headers })\n }\n}\n\nexport class PaymentError extends Error {\n readonly requirements?: PaymentRequiredResponse\n constructor(message: string, requirements?: PaymentRequiredResponse) {\n super(message)\n this.name = 'PaymentError'\n this.requirements = requirements\n }\n}\n\n/**\n * Atomic units owed for a requirement, version-agnostic: x402 v2 prices in\n * `amount`, v1 in `maxAmountRequired`. Returns null when absent or\n * unparseable (never throws — selection must be able to skip bad entries).\n */\nexport function requirementAtomicAmount(req: PaymentRequirement): bigint | null {\n const raw = req.amount ?? req.maxAmountRequired\n if (raw == null) return null\n try {\n return BigInt(raw)\n } catch {\n return null\n }\n}\n\nasync function parsePaymentRequired(res: Response): Promise<PaymentRequiredResponse> {\n try {\n return (await res.clone().json()) as PaymentRequiredResponse\n } catch {\n // v2 servers mirror the discovery document base64-encoded in the\n // `payment-required` response header — fall back to it for non-JSON bodies.\n const header = res.headers.get('payment-required')\n if (header) {\n try {\n return decodePayment<PaymentRequiredResponse>(header)\n } catch {\n /* fall through to the error below */\n }\n }\n throw new PaymentError('402 response did not contain a valid x402 discovery body')\n }\n}\n\nfunction selectRequirement(\n accepts: PaymentRequirement[],\n opts: ClientOptions,\n): PaymentRequirement | undefined {\n const priced = accepts\n .filter((a) => a.scheme === 'exact')\n // Only EVM networks this client can sign for (drops e.g. \"solana:…\").\n .filter((a) => chainIdForNetwork(a.network) !== null)\n .filter(\n (a) =>\n !opts.allowedNetworks ||\n opts.allowedNetworks.some((n) => chainIdForNetwork(n) === chainIdForNetwork(a.network)),\n )\n .map((a) => ({ req: a, amount: requirementAtomicAmount(a) }))\n .filter((e): e is { req: PaymentRequirement; amount: bigint } => e.amount !== null)\n .filter((e) => !opts.maxAmountAtomic || e.amount <= opts.maxAmountAtomic)\n\n return priced.sort((a, b) => (a.amount < b.amount ? -1 : 1))[0]?.req\n}\n\n/** Build the version-appropriate payment header for a signed authorization. */\nfunction buildPaymentHeader(\n challenge: PaymentRequiredResponse,\n requirement: PaymentRequirement,\n payload: ExactEvmPayload,\n): { name: string; value: string } {\n const version = challenge.x402Version ?? 1\n if (version >= 2) {\n const envelope: PaymentEnvelopeV2 = {\n x402Version: version,\n resource: challenge.resource,\n accepted: requirement,\n payload,\n extensions: challenge.extensions ?? {},\n }\n return { name: 'PAYMENT-SIGNATURE', value: encodePayment(envelope) }\n }\n const v1: PaymentPayload = {\n x402Version: 1,\n scheme: 'exact',\n network: requirement.network,\n payload,\n }\n return { name: 'X-PAYMENT', value: encodePayment(v1) }\n}\n\n/** Sign an EIP-3009 `TransferWithAuthorization` for the given requirement. */\nexport async function signExactAuthorization(\n wallet: WalletClient,\n requirement: PaymentRequirement,\n): Promise<ExactEvmPayload> {\n const account = wallet.account\n if (!account) throw new PaymentError('Wallet has no account attached')\n\n const value = requirementAtomicAmount(requirement)\n if (value === null) {\n throw new PaymentError('x402 requirement is missing a payment amount')\n }\n const chainId = chainIdForNetwork(requirement.network)\n if (chainId === null) {\n throw new PaymentError(`Unsupported x402 network: ${requirement.network}`)\n }\n\n const now = Math.floor(Date.now() / 1000)\n const validAfter = BigInt(now - 60)\n const validBefore = BigInt(now + (requirement.maxTimeoutSeconds ?? 600))\n const nonce = randomNonce()\n\n const tokenName =\n (requirement.extra?.name as string | undefined) ?? 'USD Coin'\n const tokenVersion =\n (requirement.extra?.version as string | undefined) ?? '2'\n\n const signature = (await wallet.signTypedData({\n account,\n domain: {\n name: tokenName,\n version: tokenVersion,\n chainId,\n verifyingContract: requirement.asset,\n },\n types: {\n TransferWithAuthorization: [\n { name: 'from', type: 'address' },\n { name: 'to', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'validAfter', type: 'uint256' },\n { name: 'validBefore', type: 'uint256' },\n { name: 'nonce', type: 'bytes32' },\n ],\n },\n primaryType: 'TransferWithAuthorization',\n message: {\n from: account.address as Address,\n to: requirement.payTo,\n value,\n validAfter,\n validBefore,\n nonce,\n },\n })) as Hex\n\n return {\n signature,\n authorization: {\n from: account.address as Address,\n to: requirement.payTo,\n value: value.toString(),\n validAfter: validAfter.toString(),\n validBefore: validBefore.toString(),\n nonce,\n },\n }\n}\n\n/**\n * Sign a requirement into the x402 **v1** `X-PAYMENT` payload shape.\n * Kept for back-compat; `createPaymentClient` is version-aware internally.\n */\nexport async function signPayment(\n wallet: WalletClient,\n requirement: PaymentRequirement,\n): Promise<PaymentPayload> {\n return {\n x402Version: 1,\n scheme: 'exact',\n network: requirement.network,\n payload: await signExactAuthorization(wallet, requirement),\n }\n}\n\n/** Resolve a network to an EVM chain id — v1 friendly names and CAIP-2 ids. */\nfunction chainIdForNetwork(network: string): number | null {\n if (network.startsWith('eip155:')) {\n const id = Number(network.slice('eip155:'.length))\n return Number.isInteger(id) && id > 0 ? id : null\n }\n switch (network as X402Network) {\n case 'base':\n return 8453\n case 'base-sepolia':\n return 84532\n case 'ethereum':\n return 1\n case 'optimism':\n return 10\n case 'arbitrum':\n return 42161\n case 'polygon':\n return 137\n default:\n return null\n }\n}\n","/**\n * yeetful/agent — the \"agent expense account.\"\n *\n * Wrap your agent's HTTP calls in a single grant-aware `pay()`. Before any x402\n * payment is signed it enforces a spend grant — an allowlist of hosts plus\n * per-call / per-day / lifetime USD caps and an expiry — then pays via the\n * standard x402 client and emits a receipt for every call.\n *\n * One grant authorizes MANY endpoints (the allowlist). It's a guardrail for\n * your own agents (runaway loops, bugs, prompt-injected tool calls) and the\n * receipt feed behind budgets + audit. Enforcement here is local + instant;\n * for hard, adversarial guarantees back the grant with an on-chain Spend\n * Permission (the wallet contract caps spend regardless of this SDK).\n *\n * @example\n * ```ts\n * import { yeetful } from 'yeetful/agent'\n *\n * const pay = yeetful({\n * wallet, // viem WalletClient\n * grant: {\n * id: 'cmbq…', // hosted grant id (yeetful.com)\n * allow: ['tripadvisor.x402.paysponge.com', 'anthropic.yeetful.com'],\n * perCallUsd: 0.05,\n * perDayUsd: 2,\n * expiresAt: '2026-12-31',\n * },\n * apiKey: process.env.YEETFUL_API_KEY, // yf_… → receipts sync to your dashboard\n * onReceipt: (r) => console.log(r.host, r.amountUsd, r.txHash),\n * })\n *\n * const res = await pay('https://tripadvisor.x402.paysponge.com/api/v1/location/search?searchQuery=tokyo')\n * // throws GrantError on NOT_ALLOWED / OVER_PER_CALL / BUDGET_EXCEEDED / EXPIRED\n * ```\n */\n\nimport type { WalletClient } from 'viem'\nimport { createPaymentClient, PaymentError, requirementAtomicAmount } from './client.js'\nimport { decodePayment } from './utils.js'\nimport type { PaymentRequirement, SettleResult, X402Network } from './types.js'\n\nexport type GrantViolation =\n | 'EXPIRED'\n | 'REVOKED'\n | 'NOT_ALLOWED'\n | 'OVER_PER_CALL'\n | 'BUDGET_EXCEEDED'\n\nexport class GrantError extends Error {\n constructor(\n public code: GrantViolation,\n message: string,\n ) {\n super(message)\n this.name = 'GrantError'\n }\n}\n\n/** A scoped spend authorization (mirrors the hosted SpendGrant). */\nexport interface GrantPolicy {\n /** Optional id of the hosted grant this mirrors. */\n id?: string\n /** Exact hostnames this grant may pay (e.g. \"tripadvisor.x402.paysponge.com\"). */\n allow: string[]\n perCallUsd: number\n perDayUsd: number\n /** Optional lifetime cap across the life of this client instance. */\n totalUsd?: number | null\n /** Unix ms, ISO string, or Date. Omit for no expiry. */\n expiresAt?: number | string | Date\n /** 'active' | 'revoked'. Defaults to active. */\n status?: string\n}\n\n/** A single authorization decision — the audit trail + x402 receipt. */\nexport interface Receipt {\n host: string\n amountUsd: number\n ok: boolean\n txHash?: string\n /** \"settled\" on success, or the GrantViolation code on a denial. */\n note: string\n ts: number\n}\n\nexport interface AgentOptions {\n /** viem WalletClient that signs the EIP-3009 payment. */\n wallet: WalletClient\n /** The spend grant to enforce. */\n grant: GrantPolicy\n /** Underlying fetch (defaults to global fetch). */\n fetch?: typeof fetch\n /** Restrict payments to specific networks (defaults to all). */\n allowedNetworks?: X402Network[]\n /** Called after every decision — wire this to your ledger / dashboard. */\n onReceipt?: (receipt: Receipt) => void | Promise<void>\n /** Human-readable progress logging. */\n onEvent?: (message: string) => void\n /**\n * Yeetful API key (`yf_…`, minted at yeetful.com while signed in). Together\n * with `grant.id` it turns on hosted-ledger sync: every receipt is POSTed to\n * `{ledgerUrl}/api/grants/{grant.id}/ledger` with Bearer auth, so the\n * dashboard's budgets/audit trail include this agent's calls. Sync is\n * best-effort and never blocks or fails a payment.\n */\n apiKey?: string\n /** Base URL of the hosted ledger. Defaults to https://yeetful.com. */\n ledgerUrl?: string\n}\n\nexport interface PayFn {\n (input: string | URL | Request, init?: RequestInit): Promise<Response>\n /** USD spent under this grant since UTC midnight (this client instance). */\n spentTodayUsd(): number\n /** USD remaining in today's budget. */\n remainingTodayUsd(): number\n /** USD spent over the life of this client instance. */\n spentTotalUsd(): number\n /**\n * Resolves once every hosted-ledger sync issued so far has settled (no-op\n * without `apiKey`). Await this before a short-lived script exits so the\n * last receipts aren't dropped with the process.\n */\n flushLedger(): Promise<void>\n}\n\nfunction expiryMs(expiresAt: GrantPolicy['expiresAt']): number {\n if (expiresAt == null) return Infinity\n if (expiresAt instanceof Date) return expiresAt.getTime()\n if (typeof expiresAt === 'number') return expiresAt\n const t = new Date(expiresAt).getTime()\n return Number.isNaN(t) ? Infinity : t\n}\n\nfunction utcDayIndex(ms: number): number {\n return Math.floor(ms / 86_400_000)\n}\n\nfunction hostOf(input: string | URL | Request): string {\n const url = typeof input === 'string' ? input : input instanceof URL ? input.href : input.url\n try {\n return new URL(url).host.toLowerCase()\n } catch {\n return ''\n }\n}\n\n/** Pull the settlement tx hash from the settle header, if present\n * (`PAYMENT-RESPONSE` on x402 v2, `X-PAYMENT-RESPONSE` on v1). */\nfunction txHashOf(res: Response): string | undefined {\n const header = res.headers.get('payment-response') ?? res.headers.get('x-payment-response')\n if (!header) return undefined\n try {\n return decodePayment<SettleResult>(header).transaction\n } catch {\n return undefined\n }\n}\n\n/**\n * Create a grant-aware paid `fetch`. Enforces the grant locally before signing\n * any x402 payment, pays with the wallet, and emits a receipt per call.\n */\nexport function yeetful(options: AgentOptions): PayFn {\n const { wallet, grant, onReceipt, onEvent } = options\n const log = onEvent ?? (() => {})\n\n let spentToday = 0\n let spentTotal = 0\n let dayIndex = utcDayIndex(Date.now())\n\n // ── Hosted-ledger sync (optional): receipts → POST /api/grants/:id/ledger ──\n const ledgerEndpoint =\n options.apiKey && grant.id\n ? `${(options.ledgerUrl ?? 'https://yeetful.com').replace(/\\/+$/, '')}/api/grants/${grant.id}/ledger`\n : null\n if (options.apiKey && !grant.id) {\n log('hosted-ledger sync disabled: grant.id is not set (use the id of your yeetful.com grant)')\n }\n // A chain (not fire-and-forget) so receipts land in order and flushLedger()\n // can await them; one failed POST is logged and never poisons the chain.\n let ledgerChain: Promise<void> = Promise.resolve()\n const ledgerFetch = options.fetch ?? globalThis.fetch\n const sync = (r: Receipt) => {\n if (!ledgerEndpoint) return\n ledgerChain = ledgerChain\n .then(async () => {\n const res = await ledgerFetch(ledgerEndpoint, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n authorization: `Bearer ${options.apiKey}`,\n },\n body: JSON.stringify({\n host: r.host,\n amountUsd: r.amountUsd,\n ok: r.ok,\n txHash: r.txHash,\n note: r.note,\n }),\n })\n if (!res.ok) log(`ledger sync → ${res.status} for ${r.host}`)\n })\n .catch((err) => {\n log(`ledger sync failed for ${r.host}: ${err instanceof Error ? err.message : err}`)\n })\n }\n\n const emit = (r: Receipt) => {\n sync(r)\n void Promise.resolve(onReceipt?.(r)).catch(() => {})\n }\n const deny = (host: string, code: GrantViolation, msg: string): never => {\n emit({ host, amountUsd: 0, ok: false, note: code, ts: Date.now() })\n log(`✗ ${host} — ${code}: ${msg}`)\n throw new GrantError(code, msg)\n }\n\n const pay = async function pay(\n input: string | URL | Request,\n init: RequestInit = {},\n ): Promise<Response> {\n // Roll the daily budget at UTC midnight.\n const today = utcDayIndex(Date.now())\n if (today !== dayIndex) {\n dayIndex = today\n spentToday = 0\n }\n\n const host = hostOf(input)\n\n // ── Pre-flight policy (no network): status → expiry → allowlist ─────────\n if ((grant.status ?? 'active') === 'revoked') deny(host, 'REVOKED', 'grant is revoked')\n if (Date.now() > expiryMs(grant.expiresAt)) deny(host, 'EXPIRED', 'grant has expired')\n if (!grant.allow.map((h) => h.toLowerCase()).includes(host)) {\n deny(host, 'NOT_ALLOWED', `${host} is not in this grant's allowlist`)\n }\n\n // Price is only known from the 402 challenge — check caps in the hook,\n // which runs after the challenge is parsed and before the payment is signed.\n let pricedUsd = 0\n const client = createPaymentClient({\n wallet,\n fetch: options.fetch,\n allowedNetworks: options.allowedNetworks,\n // Per-call enforcement lives in the hook (not maxAmountAtomic) so an\n // over-cap call surfaces a clean GrantError instead of a filtered no-match.\n onPaymentRequired: (req: PaymentRequirement) => {\n // Version-agnostic price (v2 `amount`, v1 `maxAmountRequired`).\n // Selection already dropped unpriced entries, so this can't be null.\n const price = Number(requirementAtomicAmount(req) ?? 0n) / 1e6\n if (price > grant.perCallUsd) {\n deny(host, 'OVER_PER_CALL', `$${price.toFixed(4)} exceeds per-call cap $${grant.perCallUsd}`)\n }\n if (spentToday + price > grant.perDayUsd) {\n deny(host, 'BUDGET_EXCEEDED', `$${(spentToday + price).toFixed(2)} exceeds today's cap $${grant.perDayUsd}`)\n }\n if (grant.totalUsd != null && spentTotal + price > grant.totalUsd) {\n deny(host, 'BUDGET_EXCEEDED', `$${(spentTotal + price).toFixed(2)} exceeds lifetime cap $${grant.totalUsd}`)\n }\n pricedUsd = price\n return true\n },\n })\n\n let res: Response\n try {\n res = await client(input, init)\n } catch (err) {\n if (err instanceof GrantError) throw err // already denied + receipted\n // A rejection from the underlying client (e.g. no acceptable requirement).\n const note = err instanceof PaymentError ? 'payment-failed' : 'error'\n emit({ host, amountUsd: 0, ok: false, note, ts: Date.now() })\n throw err\n }\n\n // Settled (or a free, non-402 call where pricedUsd stayed 0).\n if (pricedUsd > 0) {\n spentToday += pricedUsd\n spentTotal += pricedUsd\n }\n const txHash = txHashOf(res)\n emit({ host, amountUsd: pricedUsd, ok: true, txHash, note: 'settled', ts: Date.now() })\n log(`✓ ${host} — $${pricedUsd.toFixed(4)} · today $${spentToday.toFixed(2)}/$${grant.perDayUsd}`)\n return res\n } as PayFn\n\n pay.spentTodayUsd = () => spentToday\n pay.remainingTodayUsd = () => Math.max(0, grant.perDayUsd - spentToday)\n pay.spentTotalUsd = () => spentTotal\n pay.flushLedger = () => ledgerChain\n return pay\n}\n"]}
1
+ {"version":3,"sources":["../src/utils.ts","../src/client.ts","../src/agent.ts"],"names":["pay"],"mappings":"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","file":"agent.cjs","sourcesContent":["import type { X402Network } from './types.js'\n\nconst USDC_BY_NETWORK: Record<X402Network, `0x${string}`> = {\n base: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n 'base-sepolia': '0x036CbD53842c5426634e7929541eC2318f3dCF7e',\n ethereum: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n optimism: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85',\n arbitrum: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',\n polygon: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n}\n\nexport const USDC_DECIMALS = 6\n\n/** Returns the canonical USDC contract address for a supported network. */\nexport function usdcAddress(network: X402Network): `0x${string}` {\n return USDC_BY_NETWORK[network]\n}\n\n/**\n * Convert a human-friendly USD amount (e.g. \"0.01\") into atomic USDC units.\n * Fixed-point to avoid float drift — safer than Number math for payments.\n */\nexport function usdToAtomic(amount: string | number, decimals = USDC_DECIMALS): string {\n const str = typeof amount === 'number' ? amount.toString() : amount\n if (!/^\\d+(\\.\\d+)?$/.test(str)) {\n throw new Error(`Invalid amount: ${str}`)\n }\n const [whole, frac = ''] = str.split('.')\n const padded = frac.slice(0, decimals).padEnd(decimals, '0')\n return (BigInt(whole ?? '0') * 10n ** BigInt(decimals) + BigInt(padded || '0')).toString()\n}\n\nconst utf8Encoder = new TextEncoder()\nconst utf8Decoder = new TextDecoder()\n\n/** Base64 encode a JSON value — works in Node 18+ and browsers. */\nexport function encodePayment(value: unknown): string {\n const bytes = utf8Encoder.encode(JSON.stringify(value))\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(bytes).toString('base64')\n }\n let binary = ''\n for (const byte of bytes) binary += String.fromCharCode(byte)\n return btoa(binary)\n}\n\n/** Base64 decode a payment header value back into JSON. */\nexport function decodePayment<T = unknown>(b64: string): T {\n let bytes: Uint8Array\n if (typeof Buffer !== 'undefined') {\n bytes = new Uint8Array(Buffer.from(b64, 'base64'))\n } else {\n const binary = atob(b64)\n bytes = new Uint8Array(binary.length)\n for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i)\n }\n return JSON.parse(utf8Decoder.decode(bytes)) as T\n}\n\n/** Generate a random 32-byte nonce as a 0x-prefixed hex string. */\nexport function randomNonce(): `0x${string}` {\n const bytes = new Uint8Array(32)\n globalThis.crypto.getRandomValues(bytes)\n return ('0x' + Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('')) as `0x${string}`\n}\n","import type { Address, Hex, WalletClient } from 'viem'\nimport type {\n ExactEvmPayload,\n PaymentEnvelopeV2,\n PaymentPayload,\n PaymentRequiredResponse,\n PaymentRequirement,\n X402Network,\n} from './types.js'\nimport { decodePayment, encodePayment, randomNonce } from './utils.js'\n\nexport interface ClientOptions {\n /** A viem WalletClient able to sign EIP-712 typed data. */\n wallet: WalletClient\n /** Underlying fetch to wrap (defaults to global fetch). */\n fetch?: typeof fetch\n /**\n * Hook called before signing. Return `false` to reject the payment.\n * Useful for showing a confirmation UI to the user.\n */\n onPaymentRequired?: (requirement: PaymentRequirement) => boolean | Promise<boolean>\n /** Only allow payments up to this atomic-units cap. Safety belt. */\n maxAmountAtomic?: bigint\n /** Restrict to specific networks (defaults to all). */\n allowedNetworks?: X402Network[]\n}\n\n/**\n * Create a fetch wrapper that transparently handles x402 payments —\n * protocol v1 (\"base\" networks, `maxAmountRequired`, `X-PAYMENT` header)\n * and v2 (CAIP-2 networks, `amount`, `PAYMENT-SIGNATURE` envelope) alike.\n *\n * On a 402 response, it picks the cheapest acceptable requirement,\n * signs an EIP-3009 authorization with the provided wallet, and retries\n * the request with the version-appropriate payment header.\n *\n * @example\n * ```ts\n * const pay = createPaymentClient({ wallet })\n * const res = await pay('https://api.example.com/premium')\n * ```\n */\nexport function createPaymentClient(options: ClientOptions) {\n const baseFetch = options.fetch ?? globalThis.fetch.bind(globalThis)\n\n return async function payFetch(\n input: string | URL | Request,\n init: RequestInit = {},\n ): Promise<Response> {\n const first = await baseFetch(input, init)\n if (first.status !== 402) return first\n\n const requirements = await parsePaymentRequired(first)\n const requirement = selectRequirement(requirements.accepts ?? [], options)\n if (!requirement) {\n throw new PaymentError('No acceptable payment requirement matched client constraints', requirements)\n }\n\n if (options.onPaymentRequired) {\n const approved = await options.onPaymentRequired(requirement)\n if (!approved) throw new PaymentError('Payment rejected by user', requirements)\n }\n\n const payload = await signExactAuthorization(options.wallet, requirement)\n const header = buildPaymentHeader(requirements, requirement, payload)\n const headers = new Headers(init.headers)\n headers.set(header.name, header.value)\n\n return baseFetch(input, { ...init, headers })\n }\n}\n\nexport class PaymentError extends Error {\n readonly requirements?: PaymentRequiredResponse\n constructor(message: string, requirements?: PaymentRequiredResponse) {\n super(message)\n this.name = 'PaymentError'\n this.requirements = requirements\n }\n}\n\n/**\n * Atomic units owed for a requirement, version-agnostic: x402 v2 prices in\n * `amount`, v1 in `maxAmountRequired`. Returns null when absent or\n * unparseable (never throws — selection must be able to skip bad entries).\n */\nexport function requirementAtomicAmount(req: PaymentRequirement): bigint | null {\n const raw = req.amount ?? req.maxAmountRequired\n if (raw == null) return null\n try {\n return BigInt(raw)\n } catch {\n return null\n }\n}\n\nasync function parsePaymentRequired(res: Response): Promise<PaymentRequiredResponse> {\n try {\n return (await res.clone().json()) as PaymentRequiredResponse\n } catch {\n // v2 servers mirror the discovery document base64-encoded in the\n // `payment-required` response header — fall back to it for non-JSON bodies.\n const header = res.headers.get('payment-required')\n if (header) {\n try {\n return decodePayment<PaymentRequiredResponse>(header)\n } catch {\n /* fall through to the error below */\n }\n }\n throw new PaymentError('402 response did not contain a valid x402 discovery body')\n }\n}\n\nfunction selectRequirement(\n accepts: PaymentRequirement[],\n opts: ClientOptions,\n): PaymentRequirement | undefined {\n const priced = accepts\n .filter((a) => a.scheme === 'exact')\n // Only EVM networks this client can sign for (drops e.g. \"solana:…\").\n .filter((a) => chainIdForNetwork(a.network) !== null)\n .filter(\n (a) =>\n !opts.allowedNetworks ||\n opts.allowedNetworks.some((n) => chainIdForNetwork(n) === chainIdForNetwork(a.network)),\n )\n .map((a) => ({ req: a, amount: requirementAtomicAmount(a) }))\n .filter((e): e is { req: PaymentRequirement; amount: bigint } => e.amount !== null)\n .filter((e) => !opts.maxAmountAtomic || e.amount <= opts.maxAmountAtomic)\n\n return priced.sort((a, b) => (a.amount < b.amount ? -1 : 1))[0]?.req\n}\n\n/** Build the version-appropriate payment header for a signed authorization. */\nfunction buildPaymentHeader(\n challenge: PaymentRequiredResponse,\n requirement: PaymentRequirement,\n payload: ExactEvmPayload,\n): { name: string; value: string } {\n const version = challenge.x402Version ?? 1\n if (version >= 2) {\n const envelope: PaymentEnvelopeV2 = {\n x402Version: version,\n resource: challenge.resource,\n accepted: requirement,\n payload,\n extensions: challenge.extensions ?? {},\n }\n return { name: 'PAYMENT-SIGNATURE', value: encodePayment(envelope) }\n }\n const v1: PaymentPayload = {\n x402Version: 1,\n scheme: 'exact',\n network: requirement.network,\n payload,\n }\n return { name: 'X-PAYMENT', value: encodePayment(v1) }\n}\n\n/** Sign an EIP-3009 `TransferWithAuthorization` for the given requirement. */\nexport async function signExactAuthorization(\n wallet: WalletClient,\n requirement: PaymentRequirement,\n): Promise<ExactEvmPayload> {\n const account = wallet.account\n if (!account) throw new PaymentError('Wallet has no account attached')\n\n const value = requirementAtomicAmount(requirement)\n if (value === null) {\n throw new PaymentError('x402 requirement is missing a payment amount')\n }\n const chainId = chainIdForNetwork(requirement.network)\n if (chainId === null) {\n throw new PaymentError(`Unsupported x402 network: ${requirement.network}`)\n }\n\n const now = Math.floor(Date.now() / 1000)\n const validAfter = BigInt(now - 60)\n const validBefore = BigInt(now + (requirement.maxTimeoutSeconds ?? 600))\n const nonce = randomNonce()\n\n const tokenName =\n (requirement.extra?.name as string | undefined) ?? 'USD Coin'\n const tokenVersion =\n (requirement.extra?.version as string | undefined) ?? '2'\n\n const signature = (await wallet.signTypedData({\n account,\n domain: {\n name: tokenName,\n version: tokenVersion,\n chainId,\n verifyingContract: requirement.asset,\n },\n types: {\n TransferWithAuthorization: [\n { name: 'from', type: 'address' },\n { name: 'to', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'validAfter', type: 'uint256' },\n { name: 'validBefore', type: 'uint256' },\n { name: 'nonce', type: 'bytes32' },\n ],\n },\n primaryType: 'TransferWithAuthorization',\n message: {\n from: account.address as Address,\n to: requirement.payTo,\n value,\n validAfter,\n validBefore,\n nonce,\n },\n })) as Hex\n\n return {\n signature,\n authorization: {\n from: account.address as Address,\n to: requirement.payTo,\n value: value.toString(),\n validAfter: validAfter.toString(),\n validBefore: validBefore.toString(),\n nonce,\n },\n }\n}\n\n/**\n * Sign a requirement into the x402 **v1** `X-PAYMENT` payload shape.\n * Kept for back-compat; `createPaymentClient` is version-aware internally.\n */\nexport async function signPayment(\n wallet: WalletClient,\n requirement: PaymentRequirement,\n): Promise<PaymentPayload> {\n return {\n x402Version: 1,\n scheme: 'exact',\n network: requirement.network,\n payload: await signExactAuthorization(wallet, requirement),\n }\n}\n\n/** Resolve a network to an EVM chain id — v1 friendly names and CAIP-2 ids. */\nfunction chainIdForNetwork(network: string): number | null {\n if (network.startsWith('eip155:')) {\n const id = Number(network.slice('eip155:'.length))\n return Number.isInteger(id) && id > 0 ? id : null\n }\n switch (network as X402Network) {\n case 'base':\n return 8453\n case 'base-sepolia':\n return 84532\n case 'ethereum':\n return 1\n case 'optimism':\n return 10\n case 'arbitrum':\n return 42161\n case 'polygon':\n return 137\n default:\n return null\n }\n}\n","/**\n * yeetful/agent — the \"agent expense account.\"\n *\n * Wrap your agent's HTTP calls in a single grant-aware `pay()`. Before any x402\n * payment is signed it enforces a spend grant — an allowlist of hosts plus\n * per-call / per-day / lifetime USD caps and an expiry — then pays via the\n * standard x402 client and emits a receipt for every call.\n *\n * One grant authorizes MANY endpoints (the allowlist). It's a guardrail for\n * your own agents (runaway loops, bugs, prompt-injected tool calls) and the\n * receipt feed behind budgets + audit. Enforcement here is local + instant;\n * for hard, adversarial guarantees back the grant with an on-chain Spend\n * Permission (the wallet contract caps spend regardless of this SDK).\n *\n * @example\n * ```ts\n * import { yeetful } from 'yeetful/agent'\n *\n * const pay = yeetful({\n * wallet, // viem WalletClient\n * grant: {\n * id: 'cmbq…', // hosted grant id (yeetful.com)\n * allow: ['tripadvisor.x402.paysponge.com', 'anthropic.yeetful.com'],\n * perCallUsd: 0.05,\n * perDayUsd: 2,\n * expiresAt: '2026-12-31',\n * },\n * apiKey: process.env.YEETFUL_API_KEY, // yf_… → receipts sync to your dashboard\n * onReceipt: (r) => console.log(r.host, r.amountUsd, r.txHash),\n * })\n *\n * const res = await pay('https://tripadvisor.x402.paysponge.com/api/v1/location/search?searchQuery=tokyo')\n * // throws GrantError on NOT_ALLOWED / OVER_PER_CALL / BUDGET_EXCEEDED / EXPIRED\n * ```\n */\n\nimport type { WalletClient } from 'viem'\nimport { createPaymentClient, PaymentError, requirementAtomicAmount } from './client.js'\nimport { decodePayment } from './utils.js'\nimport type { PaymentRequirement, SettleResult, X402Network } from './types.js'\n\nexport type GrantViolation =\n | 'EXPIRED'\n | 'REVOKED'\n | 'NOT_ALLOWED'\n | 'OVER_PER_CALL'\n | 'BUDGET_EXCEEDED'\n\nexport class GrantError extends Error {\n constructor(\n public code: GrantViolation,\n message: string,\n ) {\n super(message)\n this.name = 'GrantError'\n }\n}\n\n/** A scoped spend authorization (mirrors the hosted SpendGrant). */\nexport interface GrantPolicy {\n /** Optional id of the hosted grant this mirrors. */\n id?: string\n /** Exact hostnames this grant may pay (e.g. \"tripadvisor.x402.paysponge.com\"). */\n allow: string[]\n perCallUsd: number\n perDayUsd: number\n /** Optional lifetime cap across the life of this client instance. */\n totalUsd?: number | null\n /** Unix ms, ISO string, or Date. Omit for no expiry. */\n expiresAt?: number | string | Date\n /** 'active' | 'revoked'. Defaults to active. */\n status?: string\n}\n\n/** A single authorization decision — the audit trail + x402 receipt. */\nexport interface Receipt {\n host: string\n amountUsd: number\n ok: boolean\n txHash?: string\n /** \"settled\" on success, or the GrantViolation code on a denial. */\n note: string\n ts: number\n}\n\nexport interface AgentOptions {\n /** viem WalletClient that signs the EIP-3009 payment. */\n wallet: WalletClient\n /** The spend grant to enforce. */\n grant: GrantPolicy\n /** Underlying fetch (defaults to global fetch). */\n fetch?: typeof fetch\n /** Restrict payments to specific networks (defaults to all). */\n allowedNetworks?: X402Network[]\n /** Called after every decision — wire this to your ledger / dashboard. */\n onReceipt?: (receipt: Receipt) => void | Promise<void>\n /** Human-readable progress logging. */\n onEvent?: (message: string) => void\n /**\n * Yeetful API key (`yf_…`, minted at yeetful.com while signed in). Together\n * with `grant.id` it turns on hosted-ledger sync: every receipt is POSTed to\n * `{ledgerUrl}/api/grants/{grant.id}/ledger` with Bearer auth, so the\n * dashboard's budgets/audit trail include this agent's calls. Sync is\n * best-effort and never blocks or fails a payment.\n */\n apiKey?: string\n /** Base URL of the hosted ledger. Defaults to https://yeetful.com. */\n ledgerUrl?: string\n}\n\nexport interface PayFn {\n (input: string | URL | Request, init?: RequestInit): Promise<Response>\n /** USD spent under this grant since UTC midnight (this client instance). */\n spentTodayUsd(): number\n /** USD remaining in today's budget. */\n remainingTodayUsd(): number\n /** USD spent over the life of this client instance. */\n spentTotalUsd(): number\n /**\n * Resolves once every hosted-ledger sync issued so far has settled (no-op\n * without `apiKey`). Await this before a short-lived script exits so the\n * last receipts aren't dropped with the process.\n */\n flushLedger(): Promise<void>\n}\n\nfunction expiryMs(expiresAt: GrantPolicy['expiresAt']): number {\n if (expiresAt == null) return Infinity\n if (expiresAt instanceof Date) return expiresAt.getTime()\n if (typeof expiresAt === 'number') return expiresAt\n const t = new Date(expiresAt).getTime()\n return Number.isNaN(t) ? Infinity : t\n}\n\nfunction utcDayIndex(ms: number): number {\n return Math.floor(ms / 86_400_000)\n}\n\nfunction hostOf(input: string | URL | Request): string {\n const url = typeof input === 'string' ? input : input instanceof URL ? input.href : input.url\n try {\n return new URL(url).host.toLowerCase()\n } catch {\n return ''\n }\n}\n\n/** Pull the settlement tx hash from the settle header, if present\n * (`PAYMENT-RESPONSE` on x402 v2, `X-PAYMENT-RESPONSE` on v1). */\nfunction txHashOf(res: Response): string | undefined {\n const header = res.headers.get('payment-response') ?? res.headers.get('x-payment-response')\n if (!header) return undefined\n try {\n return decodePayment<SettleResult>(header).transaction\n } catch {\n return undefined\n }\n}\n\n/**\n * Create a grant-aware paid `fetch`. Enforces the grant locally before signing\n * any x402 payment, pays with the wallet, and emits a receipt per call.\n */\nexport function yeetful(options: AgentOptions): PayFn {\n const { wallet, grant, onReceipt, onEvent } = options\n const log = onEvent ?? (() => {})\n\n let spentToday = 0\n let spentTotal = 0\n let dayIndex = utcDayIndex(Date.now())\n\n // ── Hosted-ledger sync (optional): receipts → POST /api/grants/:id/ledger ──\n const ledgerEndpoint =\n options.apiKey && grant.id\n ? `${(options.ledgerUrl ?? 'https://yeetful.com').replace(/\\/+$/, '')}/api/grants/${grant.id}/ledger`\n : null\n if (options.apiKey && !grant.id) {\n log('hosted-ledger sync disabled: grant.id is not set (use the id of your yeetful.com grant)')\n }\n // A chain (not fire-and-forget) so receipts land in order and flushLedger()\n // can await them; one failed POST is logged and never poisons the chain.\n let ledgerChain: Promise<void> = Promise.resolve()\n const ledgerFetch = options.fetch ?? globalThis.fetch\n const sync = (r: Receipt) => {\n if (!ledgerEndpoint) return\n ledgerChain = ledgerChain\n .then(async () => {\n const res = await ledgerFetch(ledgerEndpoint, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n authorization: `Bearer ${options.apiKey}`,\n },\n body: JSON.stringify({\n host: r.host,\n amountUsd: r.amountUsd,\n ok: r.ok,\n txHash: r.txHash,\n note: r.note,\n }),\n })\n if (!res.ok) {\n // fetch silently DROPS the Authorization header when it follows a\n // cross-origin redirect (e.g. apex → www) — surface the real cause.\n const moved = res.redirected\n ? ` (request was redirected to ${new URL(res.url).origin}, which strips the auth header — set ledgerUrl to that origin)`\n : ''\n log(`ledger sync → ${res.status} for ${r.host}${moved}`)\n }\n })\n .catch((err) => {\n log(`ledger sync failed for ${r.host}: ${err instanceof Error ? err.message : err}`)\n })\n }\n\n const emit = (r: Receipt) => {\n sync(r)\n void Promise.resolve(onReceipt?.(r)).catch(() => {})\n }\n const deny = (host: string, code: GrantViolation, msg: string): never => {\n emit({ host, amountUsd: 0, ok: false, note: code, ts: Date.now() })\n log(`✗ ${host} — ${code}: ${msg}`)\n throw new GrantError(code, msg)\n }\n\n const pay = async function pay(\n input: string | URL | Request,\n init: RequestInit = {},\n ): Promise<Response> {\n // Roll the daily budget at UTC midnight.\n const today = utcDayIndex(Date.now())\n if (today !== dayIndex) {\n dayIndex = today\n spentToday = 0\n }\n\n const host = hostOf(input)\n\n // ── Pre-flight policy (no network): status → expiry → allowlist ─────────\n if ((grant.status ?? 'active') === 'revoked') deny(host, 'REVOKED', 'grant is revoked')\n if (Date.now() > expiryMs(grant.expiresAt)) deny(host, 'EXPIRED', 'grant has expired')\n if (!grant.allow.map((h) => h.toLowerCase()).includes(host)) {\n deny(host, 'NOT_ALLOWED', `${host} is not in this grant's allowlist`)\n }\n\n // Price is only known from the 402 challenge — check caps in the hook,\n // which runs after the challenge is parsed and before the payment is signed.\n let pricedUsd = 0\n const client = createPaymentClient({\n wallet,\n fetch: options.fetch,\n allowedNetworks: options.allowedNetworks,\n // Per-call enforcement lives in the hook (not maxAmountAtomic) so an\n // over-cap call surfaces a clean GrantError instead of a filtered no-match.\n onPaymentRequired: (req: PaymentRequirement) => {\n // Version-agnostic price (v2 `amount`, v1 `maxAmountRequired`).\n // Selection already dropped unpriced entries, so this can't be null.\n const price = Number(requirementAtomicAmount(req) ?? 0n) / 1e6\n if (price > grant.perCallUsd) {\n deny(host, 'OVER_PER_CALL', `$${price.toFixed(4)} exceeds per-call cap $${grant.perCallUsd}`)\n }\n if (spentToday + price > grant.perDayUsd) {\n deny(host, 'BUDGET_EXCEEDED', `$${(spentToday + price).toFixed(2)} exceeds today's cap $${grant.perDayUsd}`)\n }\n if (grant.totalUsd != null && spentTotal + price > grant.totalUsd) {\n deny(host, 'BUDGET_EXCEEDED', `$${(spentTotal + price).toFixed(2)} exceeds lifetime cap $${grant.totalUsd}`)\n }\n pricedUsd = price\n return true\n },\n })\n\n let res: Response\n try {\n res = await client(input, init)\n } catch (err) {\n if (err instanceof GrantError) throw err // already denied + receipted\n // A rejection from the underlying client (e.g. no acceptable requirement).\n const note = err instanceof PaymentError ? 'payment-failed' : 'error'\n emit({ host, amountUsd: 0, ok: false, note, ts: Date.now() })\n throw err\n }\n\n // Settled (or a free, non-402 call where pricedUsd stayed 0).\n if (pricedUsd > 0) {\n spentToday += pricedUsd\n spentTotal += pricedUsd\n }\n const txHash = txHashOf(res)\n emit({ host, amountUsd: pricedUsd, ok: true, txHash, note: 'settled', ts: Date.now() })\n log(`✓ ${host} — $${pricedUsd.toFixed(4)} · today $${spentToday.toFixed(2)}/$${grant.perDayUsd}`)\n return res\n } as PayFn\n\n pay.spentTodayUsd = () => spentToday\n pay.remainingTodayUsd = () => Math.max(0, grant.perDayUsd - spentToday)\n pay.spentTotalUsd = () => spentTotal\n pay.flushLedger = () => ledgerChain\n return pay\n}\n"]}
package/dist/agent.js CHANGED
@@ -252,7 +252,10 @@ function yeetful(options) {
252
252
  note: r.note
253
253
  })
254
254
  });
255
- if (!res.ok) log(`ledger sync \u2192 ${res.status} for ${r.host}`);
255
+ if (!res.ok) {
256
+ const moved = res.redirected ? ` (request was redirected to ${new URL(res.url).origin}, which strips the auth header \u2014 set ledgerUrl to that origin)` : "";
257
+ log(`ledger sync \u2192 ${res.status} for ${r.host}${moved}`);
258
+ }
256
259
  }).catch((err) => {
257
260
  log(`ledger sync failed for ${r.host}: ${err instanceof Error ? err.message : err}`);
258
261
  });
package/dist/agent.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils.ts","../src/client.ts","../src/agent.ts"],"names":["pay"],"mappings":"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","file":"agent.js","sourcesContent":["import type { X402Network } from './types.js'\n\nconst USDC_BY_NETWORK: Record<X402Network, `0x${string}`> = {\n base: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n 'base-sepolia': '0x036CbD53842c5426634e7929541eC2318f3dCF7e',\n ethereum: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n optimism: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85',\n arbitrum: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',\n polygon: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n}\n\nexport const USDC_DECIMALS = 6\n\n/** Returns the canonical USDC contract address for a supported network. */\nexport function usdcAddress(network: X402Network): `0x${string}` {\n return USDC_BY_NETWORK[network]\n}\n\n/**\n * Convert a human-friendly USD amount (e.g. \"0.01\") into atomic USDC units.\n * Fixed-point to avoid float drift — safer than Number math for payments.\n */\nexport function usdToAtomic(amount: string | number, decimals = USDC_DECIMALS): string {\n const str = typeof amount === 'number' ? amount.toString() : amount\n if (!/^\\d+(\\.\\d+)?$/.test(str)) {\n throw new Error(`Invalid amount: ${str}`)\n }\n const [whole, frac = ''] = str.split('.')\n const padded = frac.slice(0, decimals).padEnd(decimals, '0')\n return (BigInt(whole ?? '0') * 10n ** BigInt(decimals) + BigInt(padded || '0')).toString()\n}\n\nconst utf8Encoder = new TextEncoder()\nconst utf8Decoder = new TextDecoder()\n\n/** Base64 encode a JSON value — works in Node 18+ and browsers. */\nexport function encodePayment(value: unknown): string {\n const bytes = utf8Encoder.encode(JSON.stringify(value))\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(bytes).toString('base64')\n }\n let binary = ''\n for (const byte of bytes) binary += String.fromCharCode(byte)\n return btoa(binary)\n}\n\n/** Base64 decode a payment header value back into JSON. */\nexport function decodePayment<T = unknown>(b64: string): T {\n let bytes: Uint8Array\n if (typeof Buffer !== 'undefined') {\n bytes = new Uint8Array(Buffer.from(b64, 'base64'))\n } else {\n const binary = atob(b64)\n bytes = new Uint8Array(binary.length)\n for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i)\n }\n return JSON.parse(utf8Decoder.decode(bytes)) as T\n}\n\n/** Generate a random 32-byte nonce as a 0x-prefixed hex string. */\nexport function randomNonce(): `0x${string}` {\n const bytes = new Uint8Array(32)\n globalThis.crypto.getRandomValues(bytes)\n return ('0x' + Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('')) as `0x${string}`\n}\n","import type { Address, Hex, WalletClient } from 'viem'\nimport type {\n ExactEvmPayload,\n PaymentEnvelopeV2,\n PaymentPayload,\n PaymentRequiredResponse,\n PaymentRequirement,\n X402Network,\n} from './types.js'\nimport { decodePayment, encodePayment, randomNonce } from './utils.js'\n\nexport interface ClientOptions {\n /** A viem WalletClient able to sign EIP-712 typed data. */\n wallet: WalletClient\n /** Underlying fetch to wrap (defaults to global fetch). */\n fetch?: typeof fetch\n /**\n * Hook called before signing. Return `false` to reject the payment.\n * Useful for showing a confirmation UI to the user.\n */\n onPaymentRequired?: (requirement: PaymentRequirement) => boolean | Promise<boolean>\n /** Only allow payments up to this atomic-units cap. Safety belt. */\n maxAmountAtomic?: bigint\n /** Restrict to specific networks (defaults to all). */\n allowedNetworks?: X402Network[]\n}\n\n/**\n * Create a fetch wrapper that transparently handles x402 payments —\n * protocol v1 (\"base\" networks, `maxAmountRequired`, `X-PAYMENT` header)\n * and v2 (CAIP-2 networks, `amount`, `PAYMENT-SIGNATURE` envelope) alike.\n *\n * On a 402 response, it picks the cheapest acceptable requirement,\n * signs an EIP-3009 authorization with the provided wallet, and retries\n * the request with the version-appropriate payment header.\n *\n * @example\n * ```ts\n * const pay = createPaymentClient({ wallet })\n * const res = await pay('https://api.example.com/premium')\n * ```\n */\nexport function createPaymentClient(options: ClientOptions) {\n const baseFetch = options.fetch ?? globalThis.fetch.bind(globalThis)\n\n return async function payFetch(\n input: string | URL | Request,\n init: RequestInit = {},\n ): Promise<Response> {\n const first = await baseFetch(input, init)\n if (first.status !== 402) return first\n\n const requirements = await parsePaymentRequired(first)\n const requirement = selectRequirement(requirements.accepts ?? [], options)\n if (!requirement) {\n throw new PaymentError('No acceptable payment requirement matched client constraints', requirements)\n }\n\n if (options.onPaymentRequired) {\n const approved = await options.onPaymentRequired(requirement)\n if (!approved) throw new PaymentError('Payment rejected by user', requirements)\n }\n\n const payload = await signExactAuthorization(options.wallet, requirement)\n const header = buildPaymentHeader(requirements, requirement, payload)\n const headers = new Headers(init.headers)\n headers.set(header.name, header.value)\n\n return baseFetch(input, { ...init, headers })\n }\n}\n\nexport class PaymentError extends Error {\n readonly requirements?: PaymentRequiredResponse\n constructor(message: string, requirements?: PaymentRequiredResponse) {\n super(message)\n this.name = 'PaymentError'\n this.requirements = requirements\n }\n}\n\n/**\n * Atomic units owed for a requirement, version-agnostic: x402 v2 prices in\n * `amount`, v1 in `maxAmountRequired`. Returns null when absent or\n * unparseable (never throws — selection must be able to skip bad entries).\n */\nexport function requirementAtomicAmount(req: PaymentRequirement): bigint | null {\n const raw = req.amount ?? req.maxAmountRequired\n if (raw == null) return null\n try {\n return BigInt(raw)\n } catch {\n return null\n }\n}\n\nasync function parsePaymentRequired(res: Response): Promise<PaymentRequiredResponse> {\n try {\n return (await res.clone().json()) as PaymentRequiredResponse\n } catch {\n // v2 servers mirror the discovery document base64-encoded in the\n // `payment-required` response header — fall back to it for non-JSON bodies.\n const header = res.headers.get('payment-required')\n if (header) {\n try {\n return decodePayment<PaymentRequiredResponse>(header)\n } catch {\n /* fall through to the error below */\n }\n }\n throw new PaymentError('402 response did not contain a valid x402 discovery body')\n }\n}\n\nfunction selectRequirement(\n accepts: PaymentRequirement[],\n opts: ClientOptions,\n): PaymentRequirement | undefined {\n const priced = accepts\n .filter((a) => a.scheme === 'exact')\n // Only EVM networks this client can sign for (drops e.g. \"solana:…\").\n .filter((a) => chainIdForNetwork(a.network) !== null)\n .filter(\n (a) =>\n !opts.allowedNetworks ||\n opts.allowedNetworks.some((n) => chainIdForNetwork(n) === chainIdForNetwork(a.network)),\n )\n .map((a) => ({ req: a, amount: requirementAtomicAmount(a) }))\n .filter((e): e is { req: PaymentRequirement; amount: bigint } => e.amount !== null)\n .filter((e) => !opts.maxAmountAtomic || e.amount <= opts.maxAmountAtomic)\n\n return priced.sort((a, b) => (a.amount < b.amount ? -1 : 1))[0]?.req\n}\n\n/** Build the version-appropriate payment header for a signed authorization. */\nfunction buildPaymentHeader(\n challenge: PaymentRequiredResponse,\n requirement: PaymentRequirement,\n payload: ExactEvmPayload,\n): { name: string; value: string } {\n const version = challenge.x402Version ?? 1\n if (version >= 2) {\n const envelope: PaymentEnvelopeV2 = {\n x402Version: version,\n resource: challenge.resource,\n accepted: requirement,\n payload,\n extensions: challenge.extensions ?? {},\n }\n return { name: 'PAYMENT-SIGNATURE', value: encodePayment(envelope) }\n }\n const v1: PaymentPayload = {\n x402Version: 1,\n scheme: 'exact',\n network: requirement.network,\n payload,\n }\n return { name: 'X-PAYMENT', value: encodePayment(v1) }\n}\n\n/** Sign an EIP-3009 `TransferWithAuthorization` for the given requirement. */\nexport async function signExactAuthorization(\n wallet: WalletClient,\n requirement: PaymentRequirement,\n): Promise<ExactEvmPayload> {\n const account = wallet.account\n if (!account) throw new PaymentError('Wallet has no account attached')\n\n const value = requirementAtomicAmount(requirement)\n if (value === null) {\n throw new PaymentError('x402 requirement is missing a payment amount')\n }\n const chainId = chainIdForNetwork(requirement.network)\n if (chainId === null) {\n throw new PaymentError(`Unsupported x402 network: ${requirement.network}`)\n }\n\n const now = Math.floor(Date.now() / 1000)\n const validAfter = BigInt(now - 60)\n const validBefore = BigInt(now + (requirement.maxTimeoutSeconds ?? 600))\n const nonce = randomNonce()\n\n const tokenName =\n (requirement.extra?.name as string | undefined) ?? 'USD Coin'\n const tokenVersion =\n (requirement.extra?.version as string | undefined) ?? '2'\n\n const signature = (await wallet.signTypedData({\n account,\n domain: {\n name: tokenName,\n version: tokenVersion,\n chainId,\n verifyingContract: requirement.asset,\n },\n types: {\n TransferWithAuthorization: [\n { name: 'from', type: 'address' },\n { name: 'to', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'validAfter', type: 'uint256' },\n { name: 'validBefore', type: 'uint256' },\n { name: 'nonce', type: 'bytes32' },\n ],\n },\n primaryType: 'TransferWithAuthorization',\n message: {\n from: account.address as Address,\n to: requirement.payTo,\n value,\n validAfter,\n validBefore,\n nonce,\n },\n })) as Hex\n\n return {\n signature,\n authorization: {\n from: account.address as Address,\n to: requirement.payTo,\n value: value.toString(),\n validAfter: validAfter.toString(),\n validBefore: validBefore.toString(),\n nonce,\n },\n }\n}\n\n/**\n * Sign a requirement into the x402 **v1** `X-PAYMENT` payload shape.\n * Kept for back-compat; `createPaymentClient` is version-aware internally.\n */\nexport async function signPayment(\n wallet: WalletClient,\n requirement: PaymentRequirement,\n): Promise<PaymentPayload> {\n return {\n x402Version: 1,\n scheme: 'exact',\n network: requirement.network,\n payload: await signExactAuthorization(wallet, requirement),\n }\n}\n\n/** Resolve a network to an EVM chain id — v1 friendly names and CAIP-2 ids. */\nfunction chainIdForNetwork(network: string): number | null {\n if (network.startsWith('eip155:')) {\n const id = Number(network.slice('eip155:'.length))\n return Number.isInteger(id) && id > 0 ? id : null\n }\n switch (network as X402Network) {\n case 'base':\n return 8453\n case 'base-sepolia':\n return 84532\n case 'ethereum':\n return 1\n case 'optimism':\n return 10\n case 'arbitrum':\n return 42161\n case 'polygon':\n return 137\n default:\n return null\n }\n}\n","/**\n * yeetful/agent — the \"agent expense account.\"\n *\n * Wrap your agent's HTTP calls in a single grant-aware `pay()`. Before any x402\n * payment is signed it enforces a spend grant — an allowlist of hosts plus\n * per-call / per-day / lifetime USD caps and an expiry — then pays via the\n * standard x402 client and emits a receipt for every call.\n *\n * One grant authorizes MANY endpoints (the allowlist). It's a guardrail for\n * your own agents (runaway loops, bugs, prompt-injected tool calls) and the\n * receipt feed behind budgets + audit. Enforcement here is local + instant;\n * for hard, adversarial guarantees back the grant with an on-chain Spend\n * Permission (the wallet contract caps spend regardless of this SDK).\n *\n * @example\n * ```ts\n * import { yeetful } from 'yeetful/agent'\n *\n * const pay = yeetful({\n * wallet, // viem WalletClient\n * grant: {\n * id: 'cmbq…', // hosted grant id (yeetful.com)\n * allow: ['tripadvisor.x402.paysponge.com', 'anthropic.yeetful.com'],\n * perCallUsd: 0.05,\n * perDayUsd: 2,\n * expiresAt: '2026-12-31',\n * },\n * apiKey: process.env.YEETFUL_API_KEY, // yf_… → receipts sync to your dashboard\n * onReceipt: (r) => console.log(r.host, r.amountUsd, r.txHash),\n * })\n *\n * const res = await pay('https://tripadvisor.x402.paysponge.com/api/v1/location/search?searchQuery=tokyo')\n * // throws GrantError on NOT_ALLOWED / OVER_PER_CALL / BUDGET_EXCEEDED / EXPIRED\n * ```\n */\n\nimport type { WalletClient } from 'viem'\nimport { createPaymentClient, PaymentError, requirementAtomicAmount } from './client.js'\nimport { decodePayment } from './utils.js'\nimport type { PaymentRequirement, SettleResult, X402Network } from './types.js'\n\nexport type GrantViolation =\n | 'EXPIRED'\n | 'REVOKED'\n | 'NOT_ALLOWED'\n | 'OVER_PER_CALL'\n | 'BUDGET_EXCEEDED'\n\nexport class GrantError extends Error {\n constructor(\n public code: GrantViolation,\n message: string,\n ) {\n super(message)\n this.name = 'GrantError'\n }\n}\n\n/** A scoped spend authorization (mirrors the hosted SpendGrant). */\nexport interface GrantPolicy {\n /** Optional id of the hosted grant this mirrors. */\n id?: string\n /** Exact hostnames this grant may pay (e.g. \"tripadvisor.x402.paysponge.com\"). */\n allow: string[]\n perCallUsd: number\n perDayUsd: number\n /** Optional lifetime cap across the life of this client instance. */\n totalUsd?: number | null\n /** Unix ms, ISO string, or Date. Omit for no expiry. */\n expiresAt?: number | string | Date\n /** 'active' | 'revoked'. Defaults to active. */\n status?: string\n}\n\n/** A single authorization decision — the audit trail + x402 receipt. */\nexport interface Receipt {\n host: string\n amountUsd: number\n ok: boolean\n txHash?: string\n /** \"settled\" on success, or the GrantViolation code on a denial. */\n note: string\n ts: number\n}\n\nexport interface AgentOptions {\n /** viem WalletClient that signs the EIP-3009 payment. */\n wallet: WalletClient\n /** The spend grant to enforce. */\n grant: GrantPolicy\n /** Underlying fetch (defaults to global fetch). */\n fetch?: typeof fetch\n /** Restrict payments to specific networks (defaults to all). */\n allowedNetworks?: X402Network[]\n /** Called after every decision — wire this to your ledger / dashboard. */\n onReceipt?: (receipt: Receipt) => void | Promise<void>\n /** Human-readable progress logging. */\n onEvent?: (message: string) => void\n /**\n * Yeetful API key (`yf_…`, minted at yeetful.com while signed in). Together\n * with `grant.id` it turns on hosted-ledger sync: every receipt is POSTed to\n * `{ledgerUrl}/api/grants/{grant.id}/ledger` with Bearer auth, so the\n * dashboard's budgets/audit trail include this agent's calls. Sync is\n * best-effort and never blocks or fails a payment.\n */\n apiKey?: string\n /** Base URL of the hosted ledger. Defaults to https://yeetful.com. */\n ledgerUrl?: string\n}\n\nexport interface PayFn {\n (input: string | URL | Request, init?: RequestInit): Promise<Response>\n /** USD spent under this grant since UTC midnight (this client instance). */\n spentTodayUsd(): number\n /** USD remaining in today's budget. */\n remainingTodayUsd(): number\n /** USD spent over the life of this client instance. */\n spentTotalUsd(): number\n /**\n * Resolves once every hosted-ledger sync issued so far has settled (no-op\n * without `apiKey`). Await this before a short-lived script exits so the\n * last receipts aren't dropped with the process.\n */\n flushLedger(): Promise<void>\n}\n\nfunction expiryMs(expiresAt: GrantPolicy['expiresAt']): number {\n if (expiresAt == null) return Infinity\n if (expiresAt instanceof Date) return expiresAt.getTime()\n if (typeof expiresAt === 'number') return expiresAt\n const t = new Date(expiresAt).getTime()\n return Number.isNaN(t) ? Infinity : t\n}\n\nfunction utcDayIndex(ms: number): number {\n return Math.floor(ms / 86_400_000)\n}\n\nfunction hostOf(input: string | URL | Request): string {\n const url = typeof input === 'string' ? input : input instanceof URL ? input.href : input.url\n try {\n return new URL(url).host.toLowerCase()\n } catch {\n return ''\n }\n}\n\n/** Pull the settlement tx hash from the settle header, if present\n * (`PAYMENT-RESPONSE` on x402 v2, `X-PAYMENT-RESPONSE` on v1). */\nfunction txHashOf(res: Response): string | undefined {\n const header = res.headers.get('payment-response') ?? res.headers.get('x-payment-response')\n if (!header) return undefined\n try {\n return decodePayment<SettleResult>(header).transaction\n } catch {\n return undefined\n }\n}\n\n/**\n * Create a grant-aware paid `fetch`. Enforces the grant locally before signing\n * any x402 payment, pays with the wallet, and emits a receipt per call.\n */\nexport function yeetful(options: AgentOptions): PayFn {\n const { wallet, grant, onReceipt, onEvent } = options\n const log = onEvent ?? (() => {})\n\n let spentToday = 0\n let spentTotal = 0\n let dayIndex = utcDayIndex(Date.now())\n\n // ── Hosted-ledger sync (optional): receipts → POST /api/grants/:id/ledger ──\n const ledgerEndpoint =\n options.apiKey && grant.id\n ? `${(options.ledgerUrl ?? 'https://yeetful.com').replace(/\\/+$/, '')}/api/grants/${grant.id}/ledger`\n : null\n if (options.apiKey && !grant.id) {\n log('hosted-ledger sync disabled: grant.id is not set (use the id of your yeetful.com grant)')\n }\n // A chain (not fire-and-forget) so receipts land in order and flushLedger()\n // can await them; one failed POST is logged and never poisons the chain.\n let ledgerChain: Promise<void> = Promise.resolve()\n const ledgerFetch = options.fetch ?? globalThis.fetch\n const sync = (r: Receipt) => {\n if (!ledgerEndpoint) return\n ledgerChain = ledgerChain\n .then(async () => {\n const res = await ledgerFetch(ledgerEndpoint, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n authorization: `Bearer ${options.apiKey}`,\n },\n body: JSON.stringify({\n host: r.host,\n amountUsd: r.amountUsd,\n ok: r.ok,\n txHash: r.txHash,\n note: r.note,\n }),\n })\n if (!res.ok) log(`ledger sync → ${res.status} for ${r.host}`)\n })\n .catch((err) => {\n log(`ledger sync failed for ${r.host}: ${err instanceof Error ? err.message : err}`)\n })\n }\n\n const emit = (r: Receipt) => {\n sync(r)\n void Promise.resolve(onReceipt?.(r)).catch(() => {})\n }\n const deny = (host: string, code: GrantViolation, msg: string): never => {\n emit({ host, amountUsd: 0, ok: false, note: code, ts: Date.now() })\n log(`✗ ${host} — ${code}: ${msg}`)\n throw new GrantError(code, msg)\n }\n\n const pay = async function pay(\n input: string | URL | Request,\n init: RequestInit = {},\n ): Promise<Response> {\n // Roll the daily budget at UTC midnight.\n const today = utcDayIndex(Date.now())\n if (today !== dayIndex) {\n dayIndex = today\n spentToday = 0\n }\n\n const host = hostOf(input)\n\n // ── Pre-flight policy (no network): status → expiry → allowlist ─────────\n if ((grant.status ?? 'active') === 'revoked') deny(host, 'REVOKED', 'grant is revoked')\n if (Date.now() > expiryMs(grant.expiresAt)) deny(host, 'EXPIRED', 'grant has expired')\n if (!grant.allow.map((h) => h.toLowerCase()).includes(host)) {\n deny(host, 'NOT_ALLOWED', `${host} is not in this grant's allowlist`)\n }\n\n // Price is only known from the 402 challenge — check caps in the hook,\n // which runs after the challenge is parsed and before the payment is signed.\n let pricedUsd = 0\n const client = createPaymentClient({\n wallet,\n fetch: options.fetch,\n allowedNetworks: options.allowedNetworks,\n // Per-call enforcement lives in the hook (not maxAmountAtomic) so an\n // over-cap call surfaces a clean GrantError instead of a filtered no-match.\n onPaymentRequired: (req: PaymentRequirement) => {\n // Version-agnostic price (v2 `amount`, v1 `maxAmountRequired`).\n // Selection already dropped unpriced entries, so this can't be null.\n const price = Number(requirementAtomicAmount(req) ?? 0n) / 1e6\n if (price > grant.perCallUsd) {\n deny(host, 'OVER_PER_CALL', `$${price.toFixed(4)} exceeds per-call cap $${grant.perCallUsd}`)\n }\n if (spentToday + price > grant.perDayUsd) {\n deny(host, 'BUDGET_EXCEEDED', `$${(spentToday + price).toFixed(2)} exceeds today's cap $${grant.perDayUsd}`)\n }\n if (grant.totalUsd != null && spentTotal + price > grant.totalUsd) {\n deny(host, 'BUDGET_EXCEEDED', `$${(spentTotal + price).toFixed(2)} exceeds lifetime cap $${grant.totalUsd}`)\n }\n pricedUsd = price\n return true\n },\n })\n\n let res: Response\n try {\n res = await client(input, init)\n } catch (err) {\n if (err instanceof GrantError) throw err // already denied + receipted\n // A rejection from the underlying client (e.g. no acceptable requirement).\n const note = err instanceof PaymentError ? 'payment-failed' : 'error'\n emit({ host, amountUsd: 0, ok: false, note, ts: Date.now() })\n throw err\n }\n\n // Settled (or a free, non-402 call where pricedUsd stayed 0).\n if (pricedUsd > 0) {\n spentToday += pricedUsd\n spentTotal += pricedUsd\n }\n const txHash = txHashOf(res)\n emit({ host, amountUsd: pricedUsd, ok: true, txHash, note: 'settled', ts: Date.now() })\n log(`✓ ${host} — $${pricedUsd.toFixed(4)} · today $${spentToday.toFixed(2)}/$${grant.perDayUsd}`)\n return res\n } as PayFn\n\n pay.spentTodayUsd = () => spentToday\n pay.remainingTodayUsd = () => Math.max(0, grant.perDayUsd - spentToday)\n pay.spentTotalUsd = () => spentTotal\n pay.flushLedger = () => ledgerChain\n return pay\n}\n"]}
1
+ {"version":3,"sources":["../src/utils.ts","../src/client.ts","../src/agent.ts"],"names":["pay"],"mappings":"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","file":"agent.js","sourcesContent":["import type { X402Network } from './types.js'\n\nconst USDC_BY_NETWORK: Record<X402Network, `0x${string}`> = {\n base: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n 'base-sepolia': '0x036CbD53842c5426634e7929541eC2318f3dCF7e',\n ethereum: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n optimism: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85',\n arbitrum: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',\n polygon: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n}\n\nexport const USDC_DECIMALS = 6\n\n/** Returns the canonical USDC contract address for a supported network. */\nexport function usdcAddress(network: X402Network): `0x${string}` {\n return USDC_BY_NETWORK[network]\n}\n\n/**\n * Convert a human-friendly USD amount (e.g. \"0.01\") into atomic USDC units.\n * Fixed-point to avoid float drift — safer than Number math for payments.\n */\nexport function usdToAtomic(amount: string | number, decimals = USDC_DECIMALS): string {\n const str = typeof amount === 'number' ? amount.toString() : amount\n if (!/^\\d+(\\.\\d+)?$/.test(str)) {\n throw new Error(`Invalid amount: ${str}`)\n }\n const [whole, frac = ''] = str.split('.')\n const padded = frac.slice(0, decimals).padEnd(decimals, '0')\n return (BigInt(whole ?? '0') * 10n ** BigInt(decimals) + BigInt(padded || '0')).toString()\n}\n\nconst utf8Encoder = new TextEncoder()\nconst utf8Decoder = new TextDecoder()\n\n/** Base64 encode a JSON value — works in Node 18+ and browsers. */\nexport function encodePayment(value: unknown): string {\n const bytes = utf8Encoder.encode(JSON.stringify(value))\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(bytes).toString('base64')\n }\n let binary = ''\n for (const byte of bytes) binary += String.fromCharCode(byte)\n return btoa(binary)\n}\n\n/** Base64 decode a payment header value back into JSON. */\nexport function decodePayment<T = unknown>(b64: string): T {\n let bytes: Uint8Array\n if (typeof Buffer !== 'undefined') {\n bytes = new Uint8Array(Buffer.from(b64, 'base64'))\n } else {\n const binary = atob(b64)\n bytes = new Uint8Array(binary.length)\n for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i)\n }\n return JSON.parse(utf8Decoder.decode(bytes)) as T\n}\n\n/** Generate a random 32-byte nonce as a 0x-prefixed hex string. */\nexport function randomNonce(): `0x${string}` {\n const bytes = new Uint8Array(32)\n globalThis.crypto.getRandomValues(bytes)\n return ('0x' + Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('')) as `0x${string}`\n}\n","import type { Address, Hex, WalletClient } from 'viem'\nimport type {\n ExactEvmPayload,\n PaymentEnvelopeV2,\n PaymentPayload,\n PaymentRequiredResponse,\n PaymentRequirement,\n X402Network,\n} from './types.js'\nimport { decodePayment, encodePayment, randomNonce } from './utils.js'\n\nexport interface ClientOptions {\n /** A viem WalletClient able to sign EIP-712 typed data. */\n wallet: WalletClient\n /** Underlying fetch to wrap (defaults to global fetch). */\n fetch?: typeof fetch\n /**\n * Hook called before signing. Return `false` to reject the payment.\n * Useful for showing a confirmation UI to the user.\n */\n onPaymentRequired?: (requirement: PaymentRequirement) => boolean | Promise<boolean>\n /** Only allow payments up to this atomic-units cap. Safety belt. */\n maxAmountAtomic?: bigint\n /** Restrict to specific networks (defaults to all). */\n allowedNetworks?: X402Network[]\n}\n\n/**\n * Create a fetch wrapper that transparently handles x402 payments —\n * protocol v1 (\"base\" networks, `maxAmountRequired`, `X-PAYMENT` header)\n * and v2 (CAIP-2 networks, `amount`, `PAYMENT-SIGNATURE` envelope) alike.\n *\n * On a 402 response, it picks the cheapest acceptable requirement,\n * signs an EIP-3009 authorization with the provided wallet, and retries\n * the request with the version-appropriate payment header.\n *\n * @example\n * ```ts\n * const pay = createPaymentClient({ wallet })\n * const res = await pay('https://api.example.com/premium')\n * ```\n */\nexport function createPaymentClient(options: ClientOptions) {\n const baseFetch = options.fetch ?? globalThis.fetch.bind(globalThis)\n\n return async function payFetch(\n input: string | URL | Request,\n init: RequestInit = {},\n ): Promise<Response> {\n const first = await baseFetch(input, init)\n if (first.status !== 402) return first\n\n const requirements = await parsePaymentRequired(first)\n const requirement = selectRequirement(requirements.accepts ?? [], options)\n if (!requirement) {\n throw new PaymentError('No acceptable payment requirement matched client constraints', requirements)\n }\n\n if (options.onPaymentRequired) {\n const approved = await options.onPaymentRequired(requirement)\n if (!approved) throw new PaymentError('Payment rejected by user', requirements)\n }\n\n const payload = await signExactAuthorization(options.wallet, requirement)\n const header = buildPaymentHeader(requirements, requirement, payload)\n const headers = new Headers(init.headers)\n headers.set(header.name, header.value)\n\n return baseFetch(input, { ...init, headers })\n }\n}\n\nexport class PaymentError extends Error {\n readonly requirements?: PaymentRequiredResponse\n constructor(message: string, requirements?: PaymentRequiredResponse) {\n super(message)\n this.name = 'PaymentError'\n this.requirements = requirements\n }\n}\n\n/**\n * Atomic units owed for a requirement, version-agnostic: x402 v2 prices in\n * `amount`, v1 in `maxAmountRequired`. Returns null when absent or\n * unparseable (never throws — selection must be able to skip bad entries).\n */\nexport function requirementAtomicAmount(req: PaymentRequirement): bigint | null {\n const raw = req.amount ?? req.maxAmountRequired\n if (raw == null) return null\n try {\n return BigInt(raw)\n } catch {\n return null\n }\n}\n\nasync function parsePaymentRequired(res: Response): Promise<PaymentRequiredResponse> {\n try {\n return (await res.clone().json()) as PaymentRequiredResponse\n } catch {\n // v2 servers mirror the discovery document base64-encoded in the\n // `payment-required` response header — fall back to it for non-JSON bodies.\n const header = res.headers.get('payment-required')\n if (header) {\n try {\n return decodePayment<PaymentRequiredResponse>(header)\n } catch {\n /* fall through to the error below */\n }\n }\n throw new PaymentError('402 response did not contain a valid x402 discovery body')\n }\n}\n\nfunction selectRequirement(\n accepts: PaymentRequirement[],\n opts: ClientOptions,\n): PaymentRequirement | undefined {\n const priced = accepts\n .filter((a) => a.scheme === 'exact')\n // Only EVM networks this client can sign for (drops e.g. \"solana:…\").\n .filter((a) => chainIdForNetwork(a.network) !== null)\n .filter(\n (a) =>\n !opts.allowedNetworks ||\n opts.allowedNetworks.some((n) => chainIdForNetwork(n) === chainIdForNetwork(a.network)),\n )\n .map((a) => ({ req: a, amount: requirementAtomicAmount(a) }))\n .filter((e): e is { req: PaymentRequirement; amount: bigint } => e.amount !== null)\n .filter((e) => !opts.maxAmountAtomic || e.amount <= opts.maxAmountAtomic)\n\n return priced.sort((a, b) => (a.amount < b.amount ? -1 : 1))[0]?.req\n}\n\n/** Build the version-appropriate payment header for a signed authorization. */\nfunction buildPaymentHeader(\n challenge: PaymentRequiredResponse,\n requirement: PaymentRequirement,\n payload: ExactEvmPayload,\n): { name: string; value: string } {\n const version = challenge.x402Version ?? 1\n if (version >= 2) {\n const envelope: PaymentEnvelopeV2 = {\n x402Version: version,\n resource: challenge.resource,\n accepted: requirement,\n payload,\n extensions: challenge.extensions ?? {},\n }\n return { name: 'PAYMENT-SIGNATURE', value: encodePayment(envelope) }\n }\n const v1: PaymentPayload = {\n x402Version: 1,\n scheme: 'exact',\n network: requirement.network,\n payload,\n }\n return { name: 'X-PAYMENT', value: encodePayment(v1) }\n}\n\n/** Sign an EIP-3009 `TransferWithAuthorization` for the given requirement. */\nexport async function signExactAuthorization(\n wallet: WalletClient,\n requirement: PaymentRequirement,\n): Promise<ExactEvmPayload> {\n const account = wallet.account\n if (!account) throw new PaymentError('Wallet has no account attached')\n\n const value = requirementAtomicAmount(requirement)\n if (value === null) {\n throw new PaymentError('x402 requirement is missing a payment amount')\n }\n const chainId = chainIdForNetwork(requirement.network)\n if (chainId === null) {\n throw new PaymentError(`Unsupported x402 network: ${requirement.network}`)\n }\n\n const now = Math.floor(Date.now() / 1000)\n const validAfter = BigInt(now - 60)\n const validBefore = BigInt(now + (requirement.maxTimeoutSeconds ?? 600))\n const nonce = randomNonce()\n\n const tokenName =\n (requirement.extra?.name as string | undefined) ?? 'USD Coin'\n const tokenVersion =\n (requirement.extra?.version as string | undefined) ?? '2'\n\n const signature = (await wallet.signTypedData({\n account,\n domain: {\n name: tokenName,\n version: tokenVersion,\n chainId,\n verifyingContract: requirement.asset,\n },\n types: {\n TransferWithAuthorization: [\n { name: 'from', type: 'address' },\n { name: 'to', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'validAfter', type: 'uint256' },\n { name: 'validBefore', type: 'uint256' },\n { name: 'nonce', type: 'bytes32' },\n ],\n },\n primaryType: 'TransferWithAuthorization',\n message: {\n from: account.address as Address,\n to: requirement.payTo,\n value,\n validAfter,\n validBefore,\n nonce,\n },\n })) as Hex\n\n return {\n signature,\n authorization: {\n from: account.address as Address,\n to: requirement.payTo,\n value: value.toString(),\n validAfter: validAfter.toString(),\n validBefore: validBefore.toString(),\n nonce,\n },\n }\n}\n\n/**\n * Sign a requirement into the x402 **v1** `X-PAYMENT` payload shape.\n * Kept for back-compat; `createPaymentClient` is version-aware internally.\n */\nexport async function signPayment(\n wallet: WalletClient,\n requirement: PaymentRequirement,\n): Promise<PaymentPayload> {\n return {\n x402Version: 1,\n scheme: 'exact',\n network: requirement.network,\n payload: await signExactAuthorization(wallet, requirement),\n }\n}\n\n/** Resolve a network to an EVM chain id — v1 friendly names and CAIP-2 ids. */\nfunction chainIdForNetwork(network: string): number | null {\n if (network.startsWith('eip155:')) {\n const id = Number(network.slice('eip155:'.length))\n return Number.isInteger(id) && id > 0 ? id : null\n }\n switch (network as X402Network) {\n case 'base':\n return 8453\n case 'base-sepolia':\n return 84532\n case 'ethereum':\n return 1\n case 'optimism':\n return 10\n case 'arbitrum':\n return 42161\n case 'polygon':\n return 137\n default:\n return null\n }\n}\n","/**\n * yeetful/agent — the \"agent expense account.\"\n *\n * Wrap your agent's HTTP calls in a single grant-aware `pay()`. Before any x402\n * payment is signed it enforces a spend grant — an allowlist of hosts plus\n * per-call / per-day / lifetime USD caps and an expiry — then pays via the\n * standard x402 client and emits a receipt for every call.\n *\n * One grant authorizes MANY endpoints (the allowlist). It's a guardrail for\n * your own agents (runaway loops, bugs, prompt-injected tool calls) and the\n * receipt feed behind budgets + audit. Enforcement here is local + instant;\n * for hard, adversarial guarantees back the grant with an on-chain Spend\n * Permission (the wallet contract caps spend regardless of this SDK).\n *\n * @example\n * ```ts\n * import { yeetful } from 'yeetful/agent'\n *\n * const pay = yeetful({\n * wallet, // viem WalletClient\n * grant: {\n * id: 'cmbq…', // hosted grant id (yeetful.com)\n * allow: ['tripadvisor.x402.paysponge.com', 'anthropic.yeetful.com'],\n * perCallUsd: 0.05,\n * perDayUsd: 2,\n * expiresAt: '2026-12-31',\n * },\n * apiKey: process.env.YEETFUL_API_KEY, // yf_… → receipts sync to your dashboard\n * onReceipt: (r) => console.log(r.host, r.amountUsd, r.txHash),\n * })\n *\n * const res = await pay('https://tripadvisor.x402.paysponge.com/api/v1/location/search?searchQuery=tokyo')\n * // throws GrantError on NOT_ALLOWED / OVER_PER_CALL / BUDGET_EXCEEDED / EXPIRED\n * ```\n */\n\nimport type { WalletClient } from 'viem'\nimport { createPaymentClient, PaymentError, requirementAtomicAmount } from './client.js'\nimport { decodePayment } from './utils.js'\nimport type { PaymentRequirement, SettleResult, X402Network } from './types.js'\n\nexport type GrantViolation =\n | 'EXPIRED'\n | 'REVOKED'\n | 'NOT_ALLOWED'\n | 'OVER_PER_CALL'\n | 'BUDGET_EXCEEDED'\n\nexport class GrantError extends Error {\n constructor(\n public code: GrantViolation,\n message: string,\n ) {\n super(message)\n this.name = 'GrantError'\n }\n}\n\n/** A scoped spend authorization (mirrors the hosted SpendGrant). */\nexport interface GrantPolicy {\n /** Optional id of the hosted grant this mirrors. */\n id?: string\n /** Exact hostnames this grant may pay (e.g. \"tripadvisor.x402.paysponge.com\"). */\n allow: string[]\n perCallUsd: number\n perDayUsd: number\n /** Optional lifetime cap across the life of this client instance. */\n totalUsd?: number | null\n /** Unix ms, ISO string, or Date. Omit for no expiry. */\n expiresAt?: number | string | Date\n /** 'active' | 'revoked'. Defaults to active. */\n status?: string\n}\n\n/** A single authorization decision — the audit trail + x402 receipt. */\nexport interface Receipt {\n host: string\n amountUsd: number\n ok: boolean\n txHash?: string\n /** \"settled\" on success, or the GrantViolation code on a denial. */\n note: string\n ts: number\n}\n\nexport interface AgentOptions {\n /** viem WalletClient that signs the EIP-3009 payment. */\n wallet: WalletClient\n /** The spend grant to enforce. */\n grant: GrantPolicy\n /** Underlying fetch (defaults to global fetch). */\n fetch?: typeof fetch\n /** Restrict payments to specific networks (defaults to all). */\n allowedNetworks?: X402Network[]\n /** Called after every decision — wire this to your ledger / dashboard. */\n onReceipt?: (receipt: Receipt) => void | Promise<void>\n /** Human-readable progress logging. */\n onEvent?: (message: string) => void\n /**\n * Yeetful API key (`yf_…`, minted at yeetful.com while signed in). Together\n * with `grant.id` it turns on hosted-ledger sync: every receipt is POSTed to\n * `{ledgerUrl}/api/grants/{grant.id}/ledger` with Bearer auth, so the\n * dashboard's budgets/audit trail include this agent's calls. Sync is\n * best-effort and never blocks or fails a payment.\n */\n apiKey?: string\n /** Base URL of the hosted ledger. Defaults to https://yeetful.com. */\n ledgerUrl?: string\n}\n\nexport interface PayFn {\n (input: string | URL | Request, init?: RequestInit): Promise<Response>\n /** USD spent under this grant since UTC midnight (this client instance). */\n spentTodayUsd(): number\n /** USD remaining in today's budget. */\n remainingTodayUsd(): number\n /** USD spent over the life of this client instance. */\n spentTotalUsd(): number\n /**\n * Resolves once every hosted-ledger sync issued so far has settled (no-op\n * without `apiKey`). Await this before a short-lived script exits so the\n * last receipts aren't dropped with the process.\n */\n flushLedger(): Promise<void>\n}\n\nfunction expiryMs(expiresAt: GrantPolicy['expiresAt']): number {\n if (expiresAt == null) return Infinity\n if (expiresAt instanceof Date) return expiresAt.getTime()\n if (typeof expiresAt === 'number') return expiresAt\n const t = new Date(expiresAt).getTime()\n return Number.isNaN(t) ? Infinity : t\n}\n\nfunction utcDayIndex(ms: number): number {\n return Math.floor(ms / 86_400_000)\n}\n\nfunction hostOf(input: string | URL | Request): string {\n const url = typeof input === 'string' ? input : input instanceof URL ? input.href : input.url\n try {\n return new URL(url).host.toLowerCase()\n } catch {\n return ''\n }\n}\n\n/** Pull the settlement tx hash from the settle header, if present\n * (`PAYMENT-RESPONSE` on x402 v2, `X-PAYMENT-RESPONSE` on v1). */\nfunction txHashOf(res: Response): string | undefined {\n const header = res.headers.get('payment-response') ?? res.headers.get('x-payment-response')\n if (!header) return undefined\n try {\n return decodePayment<SettleResult>(header).transaction\n } catch {\n return undefined\n }\n}\n\n/**\n * Create a grant-aware paid `fetch`. Enforces the grant locally before signing\n * any x402 payment, pays with the wallet, and emits a receipt per call.\n */\nexport function yeetful(options: AgentOptions): PayFn {\n const { wallet, grant, onReceipt, onEvent } = options\n const log = onEvent ?? (() => {})\n\n let spentToday = 0\n let spentTotal = 0\n let dayIndex = utcDayIndex(Date.now())\n\n // ── Hosted-ledger sync (optional): receipts → POST /api/grants/:id/ledger ──\n const ledgerEndpoint =\n options.apiKey && grant.id\n ? `${(options.ledgerUrl ?? 'https://yeetful.com').replace(/\\/+$/, '')}/api/grants/${grant.id}/ledger`\n : null\n if (options.apiKey && !grant.id) {\n log('hosted-ledger sync disabled: grant.id is not set (use the id of your yeetful.com grant)')\n }\n // A chain (not fire-and-forget) so receipts land in order and flushLedger()\n // can await them; one failed POST is logged and never poisons the chain.\n let ledgerChain: Promise<void> = Promise.resolve()\n const ledgerFetch = options.fetch ?? globalThis.fetch\n const sync = (r: Receipt) => {\n if (!ledgerEndpoint) return\n ledgerChain = ledgerChain\n .then(async () => {\n const res = await ledgerFetch(ledgerEndpoint, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n authorization: `Bearer ${options.apiKey}`,\n },\n body: JSON.stringify({\n host: r.host,\n amountUsd: r.amountUsd,\n ok: r.ok,\n txHash: r.txHash,\n note: r.note,\n }),\n })\n if (!res.ok) {\n // fetch silently DROPS the Authorization header when it follows a\n // cross-origin redirect (e.g. apex → www) — surface the real cause.\n const moved = res.redirected\n ? ` (request was redirected to ${new URL(res.url).origin}, which strips the auth header — set ledgerUrl to that origin)`\n : ''\n log(`ledger sync → ${res.status} for ${r.host}${moved}`)\n }\n })\n .catch((err) => {\n log(`ledger sync failed for ${r.host}: ${err instanceof Error ? err.message : err}`)\n })\n }\n\n const emit = (r: Receipt) => {\n sync(r)\n void Promise.resolve(onReceipt?.(r)).catch(() => {})\n }\n const deny = (host: string, code: GrantViolation, msg: string): never => {\n emit({ host, amountUsd: 0, ok: false, note: code, ts: Date.now() })\n log(`✗ ${host} — ${code}: ${msg}`)\n throw new GrantError(code, msg)\n }\n\n const pay = async function pay(\n input: string | URL | Request,\n init: RequestInit = {},\n ): Promise<Response> {\n // Roll the daily budget at UTC midnight.\n const today = utcDayIndex(Date.now())\n if (today !== dayIndex) {\n dayIndex = today\n spentToday = 0\n }\n\n const host = hostOf(input)\n\n // ── Pre-flight policy (no network): status → expiry → allowlist ─────────\n if ((grant.status ?? 'active') === 'revoked') deny(host, 'REVOKED', 'grant is revoked')\n if (Date.now() > expiryMs(grant.expiresAt)) deny(host, 'EXPIRED', 'grant has expired')\n if (!grant.allow.map((h) => h.toLowerCase()).includes(host)) {\n deny(host, 'NOT_ALLOWED', `${host} is not in this grant's allowlist`)\n }\n\n // Price is only known from the 402 challenge — check caps in the hook,\n // which runs after the challenge is parsed and before the payment is signed.\n let pricedUsd = 0\n const client = createPaymentClient({\n wallet,\n fetch: options.fetch,\n allowedNetworks: options.allowedNetworks,\n // Per-call enforcement lives in the hook (not maxAmountAtomic) so an\n // over-cap call surfaces a clean GrantError instead of a filtered no-match.\n onPaymentRequired: (req: PaymentRequirement) => {\n // Version-agnostic price (v2 `amount`, v1 `maxAmountRequired`).\n // Selection already dropped unpriced entries, so this can't be null.\n const price = Number(requirementAtomicAmount(req) ?? 0n) / 1e6\n if (price > grant.perCallUsd) {\n deny(host, 'OVER_PER_CALL', `$${price.toFixed(4)} exceeds per-call cap $${grant.perCallUsd}`)\n }\n if (spentToday + price > grant.perDayUsd) {\n deny(host, 'BUDGET_EXCEEDED', `$${(spentToday + price).toFixed(2)} exceeds today's cap $${grant.perDayUsd}`)\n }\n if (grant.totalUsd != null && spentTotal + price > grant.totalUsd) {\n deny(host, 'BUDGET_EXCEEDED', `$${(spentTotal + price).toFixed(2)} exceeds lifetime cap $${grant.totalUsd}`)\n }\n pricedUsd = price\n return true\n },\n })\n\n let res: Response\n try {\n res = await client(input, init)\n } catch (err) {\n if (err instanceof GrantError) throw err // already denied + receipted\n // A rejection from the underlying client (e.g. no acceptable requirement).\n const note = err instanceof PaymentError ? 'payment-failed' : 'error'\n emit({ host, amountUsd: 0, ok: false, note, ts: Date.now() })\n throw err\n }\n\n // Settled (or a free, non-402 call where pricedUsd stayed 0).\n if (pricedUsd > 0) {\n spentToday += pricedUsd\n spentTotal += pricedUsd\n }\n const txHash = txHashOf(res)\n emit({ host, amountUsd: pricedUsd, ok: true, txHash, note: 'settled', ts: Date.now() })\n log(`✓ ${host} — $${pricedUsd.toFixed(4)} · today $${spentToday.toFixed(2)}/$${grant.perDayUsd}`)\n return res\n } as PayFn\n\n pay.spentTodayUsd = () => spentToday\n pay.remainingTodayUsd = () => Math.max(0, grant.perDayUsd - spentToday)\n pay.spentTotalUsd = () => spentTotal\n pay.flushLedger = () => ledgerChain\n return pay\n}\n"]}
package/dist/index.cjs CHANGED
@@ -283,7 +283,10 @@ function yeetful(options) {
283
283
  note: r.note
284
284
  })
285
285
  });
286
- if (!res.ok) log(`ledger sync \u2192 ${res.status} for ${r.host}`);
286
+ if (!res.ok) {
287
+ const moved = res.redirected ? ` (request was redirected to ${new URL(res.url).origin}, which strips the auth header \u2014 set ledgerUrl to that origin)` : "";
288
+ log(`ledger sync \u2192 ${res.status} for ${r.host}${moved}`);
289
+ }
287
290
  }).catch((err) => {
288
291
  log(`ledger sync failed for ${r.host}: ${err instanceof Error ? err.message : err}`);
289
292
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils.ts","../src/client.ts","../src/agent.ts","../src/facilitator.ts","../src/server.ts"],"names":["pay","payer"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { X402Network } from './types.js'\n\nconst USDC_BY_NETWORK: Record<X402Network, `0x${string}`> = {\n base: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n 'base-sepolia': '0x036CbD53842c5426634e7929541eC2318f3dCF7e',\n ethereum: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n optimism: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85',\n arbitrum: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',\n polygon: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n}\n\nexport const USDC_DECIMALS = 6\n\n/** Returns the canonical USDC contract address for a supported network. */\nexport function usdcAddress(network: X402Network): `0x${string}` {\n return USDC_BY_NETWORK[network]\n}\n\n/**\n * Convert a human-friendly USD amount (e.g. \"0.01\") into atomic USDC units.\n * Fixed-point to avoid float drift — safer than Number math for payments.\n */\nexport function usdToAtomic(amount: string | number, decimals = USDC_DECIMALS): string {\n const str = typeof amount === 'number' ? amount.toString() : amount\n if (!/^\\d+(\\.\\d+)?$/.test(str)) {\n throw new Error(`Invalid amount: ${str}`)\n }\n const [whole, frac = ''] = str.split('.')\n const padded = frac.slice(0, decimals).padEnd(decimals, '0')\n return (BigInt(whole ?? '0') * 10n ** BigInt(decimals) + BigInt(padded || '0')).toString()\n}\n\nconst utf8Encoder = new TextEncoder()\nconst utf8Decoder = new TextDecoder()\n\n/** Base64 encode a JSON value — works in Node 18+ and browsers. */\nexport function encodePayment(value: unknown): string {\n const bytes = utf8Encoder.encode(JSON.stringify(value))\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(bytes).toString('base64')\n }\n let binary = ''\n for (const byte of bytes) binary += String.fromCharCode(byte)\n return btoa(binary)\n}\n\n/** Base64 decode a payment header value back into JSON. */\nexport function decodePayment<T = unknown>(b64: string): T {\n let bytes: Uint8Array\n if (typeof Buffer !== 'undefined') {\n bytes = new Uint8Array(Buffer.from(b64, 'base64'))\n } else {\n const binary = atob(b64)\n bytes = new Uint8Array(binary.length)\n for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i)\n }\n return JSON.parse(utf8Decoder.decode(bytes)) as T\n}\n\n/** Generate a random 32-byte nonce as a 0x-prefixed hex string. */\nexport function randomNonce(): `0x${string}` {\n const bytes = new Uint8Array(32)\n globalThis.crypto.getRandomValues(bytes)\n return ('0x' + Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('')) as `0x${string}`\n}\n","import type { Address, Hex, WalletClient } from 'viem'\nimport type {\n ExactEvmPayload,\n PaymentEnvelopeV2,\n PaymentPayload,\n PaymentRequiredResponse,\n PaymentRequirement,\n X402Network,\n} from './types.js'\nimport { decodePayment, encodePayment, randomNonce } from './utils.js'\n\nexport interface ClientOptions {\n /** A viem WalletClient able to sign EIP-712 typed data. */\n wallet: WalletClient\n /** Underlying fetch to wrap (defaults to global fetch). */\n fetch?: typeof fetch\n /**\n * Hook called before signing. Return `false` to reject the payment.\n * Useful for showing a confirmation UI to the user.\n */\n onPaymentRequired?: (requirement: PaymentRequirement) => boolean | Promise<boolean>\n /** Only allow payments up to this atomic-units cap. Safety belt. */\n maxAmountAtomic?: bigint\n /** Restrict to specific networks (defaults to all). */\n allowedNetworks?: X402Network[]\n}\n\n/**\n * Create a fetch wrapper that transparently handles x402 payments —\n * protocol v1 (\"base\" networks, `maxAmountRequired`, `X-PAYMENT` header)\n * and v2 (CAIP-2 networks, `amount`, `PAYMENT-SIGNATURE` envelope) alike.\n *\n * On a 402 response, it picks the cheapest acceptable requirement,\n * signs an EIP-3009 authorization with the provided wallet, and retries\n * the request with the version-appropriate payment header.\n *\n * @example\n * ```ts\n * const pay = createPaymentClient({ wallet })\n * const res = await pay('https://api.example.com/premium')\n * ```\n */\nexport function createPaymentClient(options: ClientOptions) {\n const baseFetch = options.fetch ?? globalThis.fetch.bind(globalThis)\n\n return async function payFetch(\n input: string | URL | Request,\n init: RequestInit = {},\n ): Promise<Response> {\n const first = await baseFetch(input, init)\n if (first.status !== 402) return first\n\n const requirements = await parsePaymentRequired(first)\n const requirement = selectRequirement(requirements.accepts ?? [], options)\n if (!requirement) {\n throw new PaymentError('No acceptable payment requirement matched client constraints', requirements)\n }\n\n if (options.onPaymentRequired) {\n const approved = await options.onPaymentRequired(requirement)\n if (!approved) throw new PaymentError('Payment rejected by user', requirements)\n }\n\n const payload = await signExactAuthorization(options.wallet, requirement)\n const header = buildPaymentHeader(requirements, requirement, payload)\n const headers = new Headers(init.headers)\n headers.set(header.name, header.value)\n\n return baseFetch(input, { ...init, headers })\n }\n}\n\nexport class PaymentError extends Error {\n readonly requirements?: PaymentRequiredResponse\n constructor(message: string, requirements?: PaymentRequiredResponse) {\n super(message)\n this.name = 'PaymentError'\n this.requirements = requirements\n }\n}\n\n/**\n * Atomic units owed for a requirement, version-agnostic: x402 v2 prices in\n * `amount`, v1 in `maxAmountRequired`. Returns null when absent or\n * unparseable (never throws — selection must be able to skip bad entries).\n */\nexport function requirementAtomicAmount(req: PaymentRequirement): bigint | null {\n const raw = req.amount ?? req.maxAmountRequired\n if (raw == null) return null\n try {\n return BigInt(raw)\n } catch {\n return null\n }\n}\n\nasync function parsePaymentRequired(res: Response): Promise<PaymentRequiredResponse> {\n try {\n return (await res.clone().json()) as PaymentRequiredResponse\n } catch {\n // v2 servers mirror the discovery document base64-encoded in the\n // `payment-required` response header — fall back to it for non-JSON bodies.\n const header = res.headers.get('payment-required')\n if (header) {\n try {\n return decodePayment<PaymentRequiredResponse>(header)\n } catch {\n /* fall through to the error below */\n }\n }\n throw new PaymentError('402 response did not contain a valid x402 discovery body')\n }\n}\n\nfunction selectRequirement(\n accepts: PaymentRequirement[],\n opts: ClientOptions,\n): PaymentRequirement | undefined {\n const priced = accepts\n .filter((a) => a.scheme === 'exact')\n // Only EVM networks this client can sign for (drops e.g. \"solana:…\").\n .filter((a) => chainIdForNetwork(a.network) !== null)\n .filter(\n (a) =>\n !opts.allowedNetworks ||\n opts.allowedNetworks.some((n) => chainIdForNetwork(n) === chainIdForNetwork(a.network)),\n )\n .map((a) => ({ req: a, amount: requirementAtomicAmount(a) }))\n .filter((e): e is { req: PaymentRequirement; amount: bigint } => e.amount !== null)\n .filter((e) => !opts.maxAmountAtomic || e.amount <= opts.maxAmountAtomic)\n\n return priced.sort((a, b) => (a.amount < b.amount ? -1 : 1))[0]?.req\n}\n\n/** Build the version-appropriate payment header for a signed authorization. */\nfunction buildPaymentHeader(\n challenge: PaymentRequiredResponse,\n requirement: PaymentRequirement,\n payload: ExactEvmPayload,\n): { name: string; value: string } {\n const version = challenge.x402Version ?? 1\n if (version >= 2) {\n const envelope: PaymentEnvelopeV2 = {\n x402Version: version,\n resource: challenge.resource,\n accepted: requirement,\n payload,\n extensions: challenge.extensions ?? {},\n }\n return { name: 'PAYMENT-SIGNATURE', value: encodePayment(envelope) }\n }\n const v1: PaymentPayload = {\n x402Version: 1,\n scheme: 'exact',\n network: requirement.network,\n payload,\n }\n return { name: 'X-PAYMENT', value: encodePayment(v1) }\n}\n\n/** Sign an EIP-3009 `TransferWithAuthorization` for the given requirement. */\nexport async function signExactAuthorization(\n wallet: WalletClient,\n requirement: PaymentRequirement,\n): Promise<ExactEvmPayload> {\n const account = wallet.account\n if (!account) throw new PaymentError('Wallet has no account attached')\n\n const value = requirementAtomicAmount(requirement)\n if (value === null) {\n throw new PaymentError('x402 requirement is missing a payment amount')\n }\n const chainId = chainIdForNetwork(requirement.network)\n if (chainId === null) {\n throw new PaymentError(`Unsupported x402 network: ${requirement.network}`)\n }\n\n const now = Math.floor(Date.now() / 1000)\n const validAfter = BigInt(now - 60)\n const validBefore = BigInt(now + (requirement.maxTimeoutSeconds ?? 600))\n const nonce = randomNonce()\n\n const tokenName =\n (requirement.extra?.name as string | undefined) ?? 'USD Coin'\n const tokenVersion =\n (requirement.extra?.version as string | undefined) ?? '2'\n\n const signature = (await wallet.signTypedData({\n account,\n domain: {\n name: tokenName,\n version: tokenVersion,\n chainId,\n verifyingContract: requirement.asset,\n },\n types: {\n TransferWithAuthorization: [\n { name: 'from', type: 'address' },\n { name: 'to', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'validAfter', type: 'uint256' },\n { name: 'validBefore', type: 'uint256' },\n { name: 'nonce', type: 'bytes32' },\n ],\n },\n primaryType: 'TransferWithAuthorization',\n message: {\n from: account.address as Address,\n to: requirement.payTo,\n value,\n validAfter,\n validBefore,\n nonce,\n },\n })) as Hex\n\n return {\n signature,\n authorization: {\n from: account.address as Address,\n to: requirement.payTo,\n value: value.toString(),\n validAfter: validAfter.toString(),\n validBefore: validBefore.toString(),\n nonce,\n },\n }\n}\n\n/**\n * Sign a requirement into the x402 **v1** `X-PAYMENT` payload shape.\n * Kept for back-compat; `createPaymentClient` is version-aware internally.\n */\nexport async function signPayment(\n wallet: WalletClient,\n requirement: PaymentRequirement,\n): Promise<PaymentPayload> {\n return {\n x402Version: 1,\n scheme: 'exact',\n network: requirement.network,\n payload: await signExactAuthorization(wallet, requirement),\n }\n}\n\n/** Resolve a network to an EVM chain id — v1 friendly names and CAIP-2 ids. */\nfunction chainIdForNetwork(network: string): number | null {\n if (network.startsWith('eip155:')) {\n const id = Number(network.slice('eip155:'.length))\n return Number.isInteger(id) && id > 0 ? id : null\n }\n switch (network as X402Network) {\n case 'base':\n return 8453\n case 'base-sepolia':\n return 84532\n case 'ethereum':\n return 1\n case 'optimism':\n return 10\n case 'arbitrum':\n return 42161\n case 'polygon':\n return 137\n default:\n return null\n }\n}\n","/**\n * yeetful/agent — the \"agent expense account.\"\n *\n * Wrap your agent's HTTP calls in a single grant-aware `pay()`. Before any x402\n * payment is signed it enforces a spend grant — an allowlist of hosts plus\n * per-call / per-day / lifetime USD caps and an expiry — then pays via the\n * standard x402 client and emits a receipt for every call.\n *\n * One grant authorizes MANY endpoints (the allowlist). It's a guardrail for\n * your own agents (runaway loops, bugs, prompt-injected tool calls) and the\n * receipt feed behind budgets + audit. Enforcement here is local + instant;\n * for hard, adversarial guarantees back the grant with an on-chain Spend\n * Permission (the wallet contract caps spend regardless of this SDK).\n *\n * @example\n * ```ts\n * import { yeetful } from 'yeetful/agent'\n *\n * const pay = yeetful({\n * wallet, // viem WalletClient\n * grant: {\n * id: 'cmbq…', // hosted grant id (yeetful.com)\n * allow: ['tripadvisor.x402.paysponge.com', 'anthropic.yeetful.com'],\n * perCallUsd: 0.05,\n * perDayUsd: 2,\n * expiresAt: '2026-12-31',\n * },\n * apiKey: process.env.YEETFUL_API_KEY, // yf_… → receipts sync to your dashboard\n * onReceipt: (r) => console.log(r.host, r.amountUsd, r.txHash),\n * })\n *\n * const res = await pay('https://tripadvisor.x402.paysponge.com/api/v1/location/search?searchQuery=tokyo')\n * // throws GrantError on NOT_ALLOWED / OVER_PER_CALL / BUDGET_EXCEEDED / EXPIRED\n * ```\n */\n\nimport type { WalletClient } from 'viem'\nimport { createPaymentClient, PaymentError, requirementAtomicAmount } from './client.js'\nimport { decodePayment } from './utils.js'\nimport type { PaymentRequirement, SettleResult, X402Network } from './types.js'\n\nexport type GrantViolation =\n | 'EXPIRED'\n | 'REVOKED'\n | 'NOT_ALLOWED'\n | 'OVER_PER_CALL'\n | 'BUDGET_EXCEEDED'\n\nexport class GrantError extends Error {\n constructor(\n public code: GrantViolation,\n message: string,\n ) {\n super(message)\n this.name = 'GrantError'\n }\n}\n\n/** A scoped spend authorization (mirrors the hosted SpendGrant). */\nexport interface GrantPolicy {\n /** Optional id of the hosted grant this mirrors. */\n id?: string\n /** Exact hostnames this grant may pay (e.g. \"tripadvisor.x402.paysponge.com\"). */\n allow: string[]\n perCallUsd: number\n perDayUsd: number\n /** Optional lifetime cap across the life of this client instance. */\n totalUsd?: number | null\n /** Unix ms, ISO string, or Date. Omit for no expiry. */\n expiresAt?: number | string | Date\n /** 'active' | 'revoked'. Defaults to active. */\n status?: string\n}\n\n/** A single authorization decision — the audit trail + x402 receipt. */\nexport interface Receipt {\n host: string\n amountUsd: number\n ok: boolean\n txHash?: string\n /** \"settled\" on success, or the GrantViolation code on a denial. */\n note: string\n ts: number\n}\n\nexport interface AgentOptions {\n /** viem WalletClient that signs the EIP-3009 payment. */\n wallet: WalletClient\n /** The spend grant to enforce. */\n grant: GrantPolicy\n /** Underlying fetch (defaults to global fetch). */\n fetch?: typeof fetch\n /** Restrict payments to specific networks (defaults to all). */\n allowedNetworks?: X402Network[]\n /** Called after every decision — wire this to your ledger / dashboard. */\n onReceipt?: (receipt: Receipt) => void | Promise<void>\n /** Human-readable progress logging. */\n onEvent?: (message: string) => void\n /**\n * Yeetful API key (`yf_…`, minted at yeetful.com while signed in). Together\n * with `grant.id` it turns on hosted-ledger sync: every receipt is POSTed to\n * `{ledgerUrl}/api/grants/{grant.id}/ledger` with Bearer auth, so the\n * dashboard's budgets/audit trail include this agent's calls. Sync is\n * best-effort and never blocks or fails a payment.\n */\n apiKey?: string\n /** Base URL of the hosted ledger. Defaults to https://yeetful.com. */\n ledgerUrl?: string\n}\n\nexport interface PayFn {\n (input: string | URL | Request, init?: RequestInit): Promise<Response>\n /** USD spent under this grant since UTC midnight (this client instance). */\n spentTodayUsd(): number\n /** USD remaining in today's budget. */\n remainingTodayUsd(): number\n /** USD spent over the life of this client instance. */\n spentTotalUsd(): number\n /**\n * Resolves once every hosted-ledger sync issued so far has settled (no-op\n * without `apiKey`). Await this before a short-lived script exits so the\n * last receipts aren't dropped with the process.\n */\n flushLedger(): Promise<void>\n}\n\nfunction expiryMs(expiresAt: GrantPolicy['expiresAt']): number {\n if (expiresAt == null) return Infinity\n if (expiresAt instanceof Date) return expiresAt.getTime()\n if (typeof expiresAt === 'number') return expiresAt\n const t = new Date(expiresAt).getTime()\n return Number.isNaN(t) ? Infinity : t\n}\n\nfunction utcDayIndex(ms: number): number {\n return Math.floor(ms / 86_400_000)\n}\n\nfunction hostOf(input: string | URL | Request): string {\n const url = typeof input === 'string' ? input : input instanceof URL ? input.href : input.url\n try {\n return new URL(url).host.toLowerCase()\n } catch {\n return ''\n }\n}\n\n/** Pull the settlement tx hash from the settle header, if present\n * (`PAYMENT-RESPONSE` on x402 v2, `X-PAYMENT-RESPONSE` on v1). */\nfunction txHashOf(res: Response): string | undefined {\n const header = res.headers.get('payment-response') ?? res.headers.get('x-payment-response')\n if (!header) return undefined\n try {\n return decodePayment<SettleResult>(header).transaction\n } catch {\n return undefined\n }\n}\n\n/**\n * Create a grant-aware paid `fetch`. Enforces the grant locally before signing\n * any x402 payment, pays with the wallet, and emits a receipt per call.\n */\nexport function yeetful(options: AgentOptions): PayFn {\n const { wallet, grant, onReceipt, onEvent } = options\n const log = onEvent ?? (() => {})\n\n let spentToday = 0\n let spentTotal = 0\n let dayIndex = utcDayIndex(Date.now())\n\n // ── Hosted-ledger sync (optional): receipts → POST /api/grants/:id/ledger ──\n const ledgerEndpoint =\n options.apiKey && grant.id\n ? `${(options.ledgerUrl ?? 'https://yeetful.com').replace(/\\/+$/, '')}/api/grants/${grant.id}/ledger`\n : null\n if (options.apiKey && !grant.id) {\n log('hosted-ledger sync disabled: grant.id is not set (use the id of your yeetful.com grant)')\n }\n // A chain (not fire-and-forget) so receipts land in order and flushLedger()\n // can await them; one failed POST is logged and never poisons the chain.\n let ledgerChain: Promise<void> = Promise.resolve()\n const ledgerFetch = options.fetch ?? globalThis.fetch\n const sync = (r: Receipt) => {\n if (!ledgerEndpoint) return\n ledgerChain = ledgerChain\n .then(async () => {\n const res = await ledgerFetch(ledgerEndpoint, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n authorization: `Bearer ${options.apiKey}`,\n },\n body: JSON.stringify({\n host: r.host,\n amountUsd: r.amountUsd,\n ok: r.ok,\n txHash: r.txHash,\n note: r.note,\n }),\n })\n if (!res.ok) log(`ledger sync → ${res.status} for ${r.host}`)\n })\n .catch((err) => {\n log(`ledger sync failed for ${r.host}: ${err instanceof Error ? err.message : err}`)\n })\n }\n\n const emit = (r: Receipt) => {\n sync(r)\n void Promise.resolve(onReceipt?.(r)).catch(() => {})\n }\n const deny = (host: string, code: GrantViolation, msg: string): never => {\n emit({ host, amountUsd: 0, ok: false, note: code, ts: Date.now() })\n log(`✗ ${host} — ${code}: ${msg}`)\n throw new GrantError(code, msg)\n }\n\n const pay = async function pay(\n input: string | URL | Request,\n init: RequestInit = {},\n ): Promise<Response> {\n // Roll the daily budget at UTC midnight.\n const today = utcDayIndex(Date.now())\n if (today !== dayIndex) {\n dayIndex = today\n spentToday = 0\n }\n\n const host = hostOf(input)\n\n // ── Pre-flight policy (no network): status → expiry → allowlist ─────────\n if ((grant.status ?? 'active') === 'revoked') deny(host, 'REVOKED', 'grant is revoked')\n if (Date.now() > expiryMs(grant.expiresAt)) deny(host, 'EXPIRED', 'grant has expired')\n if (!grant.allow.map((h) => h.toLowerCase()).includes(host)) {\n deny(host, 'NOT_ALLOWED', `${host} is not in this grant's allowlist`)\n }\n\n // Price is only known from the 402 challenge — check caps in the hook,\n // which runs after the challenge is parsed and before the payment is signed.\n let pricedUsd = 0\n const client = createPaymentClient({\n wallet,\n fetch: options.fetch,\n allowedNetworks: options.allowedNetworks,\n // Per-call enforcement lives in the hook (not maxAmountAtomic) so an\n // over-cap call surfaces a clean GrantError instead of a filtered no-match.\n onPaymentRequired: (req: PaymentRequirement) => {\n // Version-agnostic price (v2 `amount`, v1 `maxAmountRequired`).\n // Selection already dropped unpriced entries, so this can't be null.\n const price = Number(requirementAtomicAmount(req) ?? 0n) / 1e6\n if (price > grant.perCallUsd) {\n deny(host, 'OVER_PER_CALL', `$${price.toFixed(4)} exceeds per-call cap $${grant.perCallUsd}`)\n }\n if (spentToday + price > grant.perDayUsd) {\n deny(host, 'BUDGET_EXCEEDED', `$${(spentToday + price).toFixed(2)} exceeds today's cap $${grant.perDayUsd}`)\n }\n if (grant.totalUsd != null && spentTotal + price > grant.totalUsd) {\n deny(host, 'BUDGET_EXCEEDED', `$${(spentTotal + price).toFixed(2)} exceeds lifetime cap $${grant.totalUsd}`)\n }\n pricedUsd = price\n return true\n },\n })\n\n let res: Response\n try {\n res = await client(input, init)\n } catch (err) {\n if (err instanceof GrantError) throw err // already denied + receipted\n // A rejection from the underlying client (e.g. no acceptable requirement).\n const note = err instanceof PaymentError ? 'payment-failed' : 'error'\n emit({ host, amountUsd: 0, ok: false, note, ts: Date.now() })\n throw err\n }\n\n // Settled (or a free, non-402 call where pricedUsd stayed 0).\n if (pricedUsd > 0) {\n spentToday += pricedUsd\n spentTotal += pricedUsd\n }\n const txHash = txHashOf(res)\n emit({ host, amountUsd: pricedUsd, ok: true, txHash, note: 'settled', ts: Date.now() })\n log(`✓ ${host} — $${pricedUsd.toFixed(4)} · today $${spentToday.toFixed(2)}/$${grant.perDayUsd}`)\n return res\n } as PayFn\n\n pay.spentTodayUsd = () => spentToday\n pay.remainingTodayUsd = () => Math.max(0, grant.perDayUsd - spentToday)\n pay.spentTotalUsd = () => spentTotal\n pay.flushLedger = () => ledgerChain\n return pay\n}\n","import type {\n FacilitatorConfig,\n PaymentPayload,\n PaymentRequirement,\n SettleResult,\n VerifyResult,\n} from './types.js'\n\n/**\n * Thin wrapper around an x402 facilitator HTTP service.\n * The facilitator verifies signed payment authorizations and settles them on-chain.\n */\nexport class Facilitator {\n private readonly url: string\n private readonly authHeader?: string\n private readonly fetcher: typeof fetch\n\n constructor(config: FacilitatorConfig) {\n this.url = config.url.replace(/\\/$/, '')\n this.authHeader = config.authHeader\n this.fetcher = config.fetch ?? globalThis.fetch.bind(globalThis)\n }\n\n async verify(\n payment: PaymentPayload,\n requirement: PaymentRequirement,\n ): Promise<VerifyResult> {\n return this.post<VerifyResult>('/verify', { paymentPayload: payment, paymentRequirements: requirement })\n }\n\n async settle(\n payment: PaymentPayload,\n requirement: PaymentRequirement,\n ): Promise<SettleResult> {\n return this.post<SettleResult>('/settle', { paymentPayload: payment, paymentRequirements: requirement })\n }\n\n private async post<T>(path: string, body: unknown): Promise<T> {\n const res = await this.fetcher(this.url + path, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n ...(this.authHeader ? { authorization: this.authHeader } : {}),\n },\n body: JSON.stringify(body),\n })\n if (!res.ok) {\n const text = await res.text().catch(() => '')\n throw new Error(`Facilitator ${path} failed: ${res.status} ${text}`)\n }\n return (await res.json()) as T\n }\n}\n\n/** Default hosted facilitator. Override for self-hosted deployments. */\nexport const DEFAULT_FACILITATOR_URL = 'https://facilitator.yeetful.com'\n","import type { Address } from 'viem'\nimport { Facilitator, DEFAULT_FACILITATOR_URL } from './facilitator.js'\nimport type {\n FacilitatorConfig,\n PaymentPayload,\n PaymentRequirement,\n PaymentRequiredResponse,\n SettleResult,\n X402Network,\n} from './types.js'\nimport { decodePayment, encodePayment, usdcAddress, usdToAtomic } from './utils.js'\n\nexport interface RouteGateOptions {\n /** Price in USD, e.g. \"0.01\". Converted to USDC atomic units. */\n price: string | number\n /** Recipient address that receives the funds. */\n recipient: Address\n /** Network(s) to accept. Defaults to `['base']`. Pass an array for multi-chain. */\n network?: X402Network | X402Network[]\n /** Override the payment asset (defaults to USDC for the given network). */\n asset?: Address\n /** Human-readable description of the resource. */\n description?: string\n /** Seconds the signed authorization is valid. Default: 600. */\n maxTimeoutSeconds?: number\n /** Facilitator config, or `false` to skip verification/settlement (trust-mode). */\n facilitator?: FacilitatorConfig | false\n /**\n * Optional resource identifier (defaults to the request URL). Useful for\n * logging / receipts.\n */\n resource?: string\n}\n\n/**\n * Runtime-agnostic gate: given a Fetch-API `Request`, either returns a 402\n * `Response` or a `{ settle }` handle. After your handler runs, call `settle()`\n * to finalize the payment and get a `X-PAYMENT-RESPONSE` header to attach.\n *\n * This is the building block used by the framework adapters (`./next`, `./express`).\n */\nexport async function gate(\n request: Request,\n opts: RouteGateOptions,\n): Promise<\n | { type: 'paymentRequired'; response: Response }\n | { type: 'ok'; payer: Address; settle: () => Promise<{ header: string; result: SettleResult }> }\n> {\n const requirements = buildRequirements(request, opts)\n\n const header = request.headers.get('x-payment') ?? request.headers.get('X-PAYMENT')\n if (!header) {\n return { type: 'paymentRequired', response: paymentRequiredResponse(requirements) }\n }\n\n let payment: PaymentPayload\n try {\n payment = decodePayment<PaymentPayload>(header)\n } catch {\n return {\n type: 'paymentRequired',\n response: paymentRequiredResponse(requirements, 'Invalid X-PAYMENT header'),\n }\n }\n\n const matched = requirements.find(\n (r) => r.network === payment.network && r.scheme === payment.scheme,\n )\n if (!matched) {\n return {\n type: 'paymentRequired',\n response: paymentRequiredResponse(requirements, 'Payment does not match any accepted requirement'),\n }\n }\n\n if (opts.facilitator === false) {\n const payer = payment.payload.authorization.from as Address\n return {\n type: 'ok',\n payer,\n settle: async () => ({\n header: encodePayment({ success: true, network: matched.network }),\n result: { success: true },\n }),\n }\n }\n\n const facilitator = new Facilitator(opts.facilitator ?? { url: DEFAULT_FACILITATOR_URL })\n const verified = await facilitator.verify(payment, matched)\n if (!verified.isValid) {\n return {\n type: 'paymentRequired',\n response: paymentRequiredResponse(\n requirements,\n verified.invalidReason ?? 'Payment verification failed',\n ),\n }\n }\n\n const payer = (verified.payer ?? payment.payload.authorization.from) as Address\n\n return {\n type: 'ok',\n payer,\n settle: async () => {\n const result = await facilitator.settle(payment, matched)\n return {\n header: encodePayment({\n success: result.success,\n transaction: result.transaction,\n network: result.network ?? matched.network,\n errorReason: result.errorReason,\n payer,\n }),\n result,\n }\n },\n }\n}\n\nfunction buildRequirements(request: Request, opts: RouteGateOptions): PaymentRequirement[] {\n const networks = Array.isArray(opts.network) ? opts.network : [opts.network ?? 'base']\n const atomic = usdToAtomic(opts.price)\n const resource = opts.resource ?? request.url\n\n return networks.map((network) => ({\n scheme: 'exact',\n network,\n asset: opts.asset ?? usdcAddress(network),\n maxAmountRequired: atomic,\n payTo: opts.recipient,\n description: opts.description,\n resource,\n maxTimeoutSeconds: opts.maxTimeoutSeconds ?? 600,\n extra: { name: 'USD Coin', version: '2' },\n }))\n}\n\nfunction paymentRequiredResponse(\n accepts: PaymentRequirement[],\n error?: string,\n): Response {\n const body: PaymentRequiredResponse = { x402Version: 1, accepts, ...(error ? { error } : {}) }\n return new Response(JSON.stringify(body), {\n status: 402,\n headers: { 'content-type': 'application/json' },\n })\n}\n\nexport { Facilitator, DEFAULT_FACILITATOR_URL } from './facilitator.js'\n"]}
1
+ {"version":3,"sources":["../src/utils.ts","../src/client.ts","../src/agent.ts","../src/facilitator.ts","../src/server.ts"],"names":["pay","payer"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { X402Network } from './types.js'\n\nconst USDC_BY_NETWORK: Record<X402Network, `0x${string}`> = {\n base: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n 'base-sepolia': '0x036CbD53842c5426634e7929541eC2318f3dCF7e',\n ethereum: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n optimism: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85',\n arbitrum: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',\n polygon: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n}\n\nexport const USDC_DECIMALS = 6\n\n/** Returns the canonical USDC contract address for a supported network. */\nexport function usdcAddress(network: X402Network): `0x${string}` {\n return USDC_BY_NETWORK[network]\n}\n\n/**\n * Convert a human-friendly USD amount (e.g. \"0.01\") into atomic USDC units.\n * Fixed-point to avoid float drift — safer than Number math for payments.\n */\nexport function usdToAtomic(amount: string | number, decimals = USDC_DECIMALS): string {\n const str = typeof amount === 'number' ? amount.toString() : amount\n if (!/^\\d+(\\.\\d+)?$/.test(str)) {\n throw new Error(`Invalid amount: ${str}`)\n }\n const [whole, frac = ''] = str.split('.')\n const padded = frac.slice(0, decimals).padEnd(decimals, '0')\n return (BigInt(whole ?? '0') * 10n ** BigInt(decimals) + BigInt(padded || '0')).toString()\n}\n\nconst utf8Encoder = new TextEncoder()\nconst utf8Decoder = new TextDecoder()\n\n/** Base64 encode a JSON value — works in Node 18+ and browsers. */\nexport function encodePayment(value: unknown): string {\n const bytes = utf8Encoder.encode(JSON.stringify(value))\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(bytes).toString('base64')\n }\n let binary = ''\n for (const byte of bytes) binary += String.fromCharCode(byte)\n return btoa(binary)\n}\n\n/** Base64 decode a payment header value back into JSON. */\nexport function decodePayment<T = unknown>(b64: string): T {\n let bytes: Uint8Array\n if (typeof Buffer !== 'undefined') {\n bytes = new Uint8Array(Buffer.from(b64, 'base64'))\n } else {\n const binary = atob(b64)\n bytes = new Uint8Array(binary.length)\n for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i)\n }\n return JSON.parse(utf8Decoder.decode(bytes)) as T\n}\n\n/** Generate a random 32-byte nonce as a 0x-prefixed hex string. */\nexport function randomNonce(): `0x${string}` {\n const bytes = new Uint8Array(32)\n globalThis.crypto.getRandomValues(bytes)\n return ('0x' + Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('')) as `0x${string}`\n}\n","import type { Address, Hex, WalletClient } from 'viem'\nimport type {\n ExactEvmPayload,\n PaymentEnvelopeV2,\n PaymentPayload,\n PaymentRequiredResponse,\n PaymentRequirement,\n X402Network,\n} from './types.js'\nimport { decodePayment, encodePayment, randomNonce } from './utils.js'\n\nexport interface ClientOptions {\n /** A viem WalletClient able to sign EIP-712 typed data. */\n wallet: WalletClient\n /** Underlying fetch to wrap (defaults to global fetch). */\n fetch?: typeof fetch\n /**\n * Hook called before signing. Return `false` to reject the payment.\n * Useful for showing a confirmation UI to the user.\n */\n onPaymentRequired?: (requirement: PaymentRequirement) => boolean | Promise<boolean>\n /** Only allow payments up to this atomic-units cap. Safety belt. */\n maxAmountAtomic?: bigint\n /** Restrict to specific networks (defaults to all). */\n allowedNetworks?: X402Network[]\n}\n\n/**\n * Create a fetch wrapper that transparently handles x402 payments —\n * protocol v1 (\"base\" networks, `maxAmountRequired`, `X-PAYMENT` header)\n * and v2 (CAIP-2 networks, `amount`, `PAYMENT-SIGNATURE` envelope) alike.\n *\n * On a 402 response, it picks the cheapest acceptable requirement,\n * signs an EIP-3009 authorization with the provided wallet, and retries\n * the request with the version-appropriate payment header.\n *\n * @example\n * ```ts\n * const pay = createPaymentClient({ wallet })\n * const res = await pay('https://api.example.com/premium')\n * ```\n */\nexport function createPaymentClient(options: ClientOptions) {\n const baseFetch = options.fetch ?? globalThis.fetch.bind(globalThis)\n\n return async function payFetch(\n input: string | URL | Request,\n init: RequestInit = {},\n ): Promise<Response> {\n const first = await baseFetch(input, init)\n if (first.status !== 402) return first\n\n const requirements = await parsePaymentRequired(first)\n const requirement = selectRequirement(requirements.accepts ?? [], options)\n if (!requirement) {\n throw new PaymentError('No acceptable payment requirement matched client constraints', requirements)\n }\n\n if (options.onPaymentRequired) {\n const approved = await options.onPaymentRequired(requirement)\n if (!approved) throw new PaymentError('Payment rejected by user', requirements)\n }\n\n const payload = await signExactAuthorization(options.wallet, requirement)\n const header = buildPaymentHeader(requirements, requirement, payload)\n const headers = new Headers(init.headers)\n headers.set(header.name, header.value)\n\n return baseFetch(input, { ...init, headers })\n }\n}\n\nexport class PaymentError extends Error {\n readonly requirements?: PaymentRequiredResponse\n constructor(message: string, requirements?: PaymentRequiredResponse) {\n super(message)\n this.name = 'PaymentError'\n this.requirements = requirements\n }\n}\n\n/**\n * Atomic units owed for a requirement, version-agnostic: x402 v2 prices in\n * `amount`, v1 in `maxAmountRequired`. Returns null when absent or\n * unparseable (never throws — selection must be able to skip bad entries).\n */\nexport function requirementAtomicAmount(req: PaymentRequirement): bigint | null {\n const raw = req.amount ?? req.maxAmountRequired\n if (raw == null) return null\n try {\n return BigInt(raw)\n } catch {\n return null\n }\n}\n\nasync function parsePaymentRequired(res: Response): Promise<PaymentRequiredResponse> {\n try {\n return (await res.clone().json()) as PaymentRequiredResponse\n } catch {\n // v2 servers mirror the discovery document base64-encoded in the\n // `payment-required` response header — fall back to it for non-JSON bodies.\n const header = res.headers.get('payment-required')\n if (header) {\n try {\n return decodePayment<PaymentRequiredResponse>(header)\n } catch {\n /* fall through to the error below */\n }\n }\n throw new PaymentError('402 response did not contain a valid x402 discovery body')\n }\n}\n\nfunction selectRequirement(\n accepts: PaymentRequirement[],\n opts: ClientOptions,\n): PaymentRequirement | undefined {\n const priced = accepts\n .filter((a) => a.scheme === 'exact')\n // Only EVM networks this client can sign for (drops e.g. \"solana:…\").\n .filter((a) => chainIdForNetwork(a.network) !== null)\n .filter(\n (a) =>\n !opts.allowedNetworks ||\n opts.allowedNetworks.some((n) => chainIdForNetwork(n) === chainIdForNetwork(a.network)),\n )\n .map((a) => ({ req: a, amount: requirementAtomicAmount(a) }))\n .filter((e): e is { req: PaymentRequirement; amount: bigint } => e.amount !== null)\n .filter((e) => !opts.maxAmountAtomic || e.amount <= opts.maxAmountAtomic)\n\n return priced.sort((a, b) => (a.amount < b.amount ? -1 : 1))[0]?.req\n}\n\n/** Build the version-appropriate payment header for a signed authorization. */\nfunction buildPaymentHeader(\n challenge: PaymentRequiredResponse,\n requirement: PaymentRequirement,\n payload: ExactEvmPayload,\n): { name: string; value: string } {\n const version = challenge.x402Version ?? 1\n if (version >= 2) {\n const envelope: PaymentEnvelopeV2 = {\n x402Version: version,\n resource: challenge.resource,\n accepted: requirement,\n payload,\n extensions: challenge.extensions ?? {},\n }\n return { name: 'PAYMENT-SIGNATURE', value: encodePayment(envelope) }\n }\n const v1: PaymentPayload = {\n x402Version: 1,\n scheme: 'exact',\n network: requirement.network,\n payload,\n }\n return { name: 'X-PAYMENT', value: encodePayment(v1) }\n}\n\n/** Sign an EIP-3009 `TransferWithAuthorization` for the given requirement. */\nexport async function signExactAuthorization(\n wallet: WalletClient,\n requirement: PaymentRequirement,\n): Promise<ExactEvmPayload> {\n const account = wallet.account\n if (!account) throw new PaymentError('Wallet has no account attached')\n\n const value = requirementAtomicAmount(requirement)\n if (value === null) {\n throw new PaymentError('x402 requirement is missing a payment amount')\n }\n const chainId = chainIdForNetwork(requirement.network)\n if (chainId === null) {\n throw new PaymentError(`Unsupported x402 network: ${requirement.network}`)\n }\n\n const now = Math.floor(Date.now() / 1000)\n const validAfter = BigInt(now - 60)\n const validBefore = BigInt(now + (requirement.maxTimeoutSeconds ?? 600))\n const nonce = randomNonce()\n\n const tokenName =\n (requirement.extra?.name as string | undefined) ?? 'USD Coin'\n const tokenVersion =\n (requirement.extra?.version as string | undefined) ?? '2'\n\n const signature = (await wallet.signTypedData({\n account,\n domain: {\n name: tokenName,\n version: tokenVersion,\n chainId,\n verifyingContract: requirement.asset,\n },\n types: {\n TransferWithAuthorization: [\n { name: 'from', type: 'address' },\n { name: 'to', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'validAfter', type: 'uint256' },\n { name: 'validBefore', type: 'uint256' },\n { name: 'nonce', type: 'bytes32' },\n ],\n },\n primaryType: 'TransferWithAuthorization',\n message: {\n from: account.address as Address,\n to: requirement.payTo,\n value,\n validAfter,\n validBefore,\n nonce,\n },\n })) as Hex\n\n return {\n signature,\n authorization: {\n from: account.address as Address,\n to: requirement.payTo,\n value: value.toString(),\n validAfter: validAfter.toString(),\n validBefore: validBefore.toString(),\n nonce,\n },\n }\n}\n\n/**\n * Sign a requirement into the x402 **v1** `X-PAYMENT` payload shape.\n * Kept for back-compat; `createPaymentClient` is version-aware internally.\n */\nexport async function signPayment(\n wallet: WalletClient,\n requirement: PaymentRequirement,\n): Promise<PaymentPayload> {\n return {\n x402Version: 1,\n scheme: 'exact',\n network: requirement.network,\n payload: await signExactAuthorization(wallet, requirement),\n }\n}\n\n/** Resolve a network to an EVM chain id — v1 friendly names and CAIP-2 ids. */\nfunction chainIdForNetwork(network: string): number | null {\n if (network.startsWith('eip155:')) {\n const id = Number(network.slice('eip155:'.length))\n return Number.isInteger(id) && id > 0 ? id : null\n }\n switch (network as X402Network) {\n case 'base':\n return 8453\n case 'base-sepolia':\n return 84532\n case 'ethereum':\n return 1\n case 'optimism':\n return 10\n case 'arbitrum':\n return 42161\n case 'polygon':\n return 137\n default:\n return null\n }\n}\n","/**\n * yeetful/agent — the \"agent expense account.\"\n *\n * Wrap your agent's HTTP calls in a single grant-aware `pay()`. Before any x402\n * payment is signed it enforces a spend grant — an allowlist of hosts plus\n * per-call / per-day / lifetime USD caps and an expiry — then pays via the\n * standard x402 client and emits a receipt for every call.\n *\n * One grant authorizes MANY endpoints (the allowlist). It's a guardrail for\n * your own agents (runaway loops, bugs, prompt-injected tool calls) and the\n * receipt feed behind budgets + audit. Enforcement here is local + instant;\n * for hard, adversarial guarantees back the grant with an on-chain Spend\n * Permission (the wallet contract caps spend regardless of this SDK).\n *\n * @example\n * ```ts\n * import { yeetful } from 'yeetful/agent'\n *\n * const pay = yeetful({\n * wallet, // viem WalletClient\n * grant: {\n * id: 'cmbq…', // hosted grant id (yeetful.com)\n * allow: ['tripadvisor.x402.paysponge.com', 'anthropic.yeetful.com'],\n * perCallUsd: 0.05,\n * perDayUsd: 2,\n * expiresAt: '2026-12-31',\n * },\n * apiKey: process.env.YEETFUL_API_KEY, // yf_… → receipts sync to your dashboard\n * onReceipt: (r) => console.log(r.host, r.amountUsd, r.txHash),\n * })\n *\n * const res = await pay('https://tripadvisor.x402.paysponge.com/api/v1/location/search?searchQuery=tokyo')\n * // throws GrantError on NOT_ALLOWED / OVER_PER_CALL / BUDGET_EXCEEDED / EXPIRED\n * ```\n */\n\nimport type { WalletClient } from 'viem'\nimport { createPaymentClient, PaymentError, requirementAtomicAmount } from './client.js'\nimport { decodePayment } from './utils.js'\nimport type { PaymentRequirement, SettleResult, X402Network } from './types.js'\n\nexport type GrantViolation =\n | 'EXPIRED'\n | 'REVOKED'\n | 'NOT_ALLOWED'\n | 'OVER_PER_CALL'\n | 'BUDGET_EXCEEDED'\n\nexport class GrantError extends Error {\n constructor(\n public code: GrantViolation,\n message: string,\n ) {\n super(message)\n this.name = 'GrantError'\n }\n}\n\n/** A scoped spend authorization (mirrors the hosted SpendGrant). */\nexport interface GrantPolicy {\n /** Optional id of the hosted grant this mirrors. */\n id?: string\n /** Exact hostnames this grant may pay (e.g. \"tripadvisor.x402.paysponge.com\"). */\n allow: string[]\n perCallUsd: number\n perDayUsd: number\n /** Optional lifetime cap across the life of this client instance. */\n totalUsd?: number | null\n /** Unix ms, ISO string, or Date. Omit for no expiry. */\n expiresAt?: number | string | Date\n /** 'active' | 'revoked'. Defaults to active. */\n status?: string\n}\n\n/** A single authorization decision — the audit trail + x402 receipt. */\nexport interface Receipt {\n host: string\n amountUsd: number\n ok: boolean\n txHash?: string\n /** \"settled\" on success, or the GrantViolation code on a denial. */\n note: string\n ts: number\n}\n\nexport interface AgentOptions {\n /** viem WalletClient that signs the EIP-3009 payment. */\n wallet: WalletClient\n /** The spend grant to enforce. */\n grant: GrantPolicy\n /** Underlying fetch (defaults to global fetch). */\n fetch?: typeof fetch\n /** Restrict payments to specific networks (defaults to all). */\n allowedNetworks?: X402Network[]\n /** Called after every decision — wire this to your ledger / dashboard. */\n onReceipt?: (receipt: Receipt) => void | Promise<void>\n /** Human-readable progress logging. */\n onEvent?: (message: string) => void\n /**\n * Yeetful API key (`yf_…`, minted at yeetful.com while signed in). Together\n * with `grant.id` it turns on hosted-ledger sync: every receipt is POSTed to\n * `{ledgerUrl}/api/grants/{grant.id}/ledger` with Bearer auth, so the\n * dashboard's budgets/audit trail include this agent's calls. Sync is\n * best-effort and never blocks or fails a payment.\n */\n apiKey?: string\n /** Base URL of the hosted ledger. Defaults to https://yeetful.com. */\n ledgerUrl?: string\n}\n\nexport interface PayFn {\n (input: string | URL | Request, init?: RequestInit): Promise<Response>\n /** USD spent under this grant since UTC midnight (this client instance). */\n spentTodayUsd(): number\n /** USD remaining in today's budget. */\n remainingTodayUsd(): number\n /** USD spent over the life of this client instance. */\n spentTotalUsd(): number\n /**\n * Resolves once every hosted-ledger sync issued so far has settled (no-op\n * without `apiKey`). Await this before a short-lived script exits so the\n * last receipts aren't dropped with the process.\n */\n flushLedger(): Promise<void>\n}\n\nfunction expiryMs(expiresAt: GrantPolicy['expiresAt']): number {\n if (expiresAt == null) return Infinity\n if (expiresAt instanceof Date) return expiresAt.getTime()\n if (typeof expiresAt === 'number') return expiresAt\n const t = new Date(expiresAt).getTime()\n return Number.isNaN(t) ? Infinity : t\n}\n\nfunction utcDayIndex(ms: number): number {\n return Math.floor(ms / 86_400_000)\n}\n\nfunction hostOf(input: string | URL | Request): string {\n const url = typeof input === 'string' ? input : input instanceof URL ? input.href : input.url\n try {\n return new URL(url).host.toLowerCase()\n } catch {\n return ''\n }\n}\n\n/** Pull the settlement tx hash from the settle header, if present\n * (`PAYMENT-RESPONSE` on x402 v2, `X-PAYMENT-RESPONSE` on v1). */\nfunction txHashOf(res: Response): string | undefined {\n const header = res.headers.get('payment-response') ?? res.headers.get('x-payment-response')\n if (!header) return undefined\n try {\n return decodePayment<SettleResult>(header).transaction\n } catch {\n return undefined\n }\n}\n\n/**\n * Create a grant-aware paid `fetch`. Enforces the grant locally before signing\n * any x402 payment, pays with the wallet, and emits a receipt per call.\n */\nexport function yeetful(options: AgentOptions): PayFn {\n const { wallet, grant, onReceipt, onEvent } = options\n const log = onEvent ?? (() => {})\n\n let spentToday = 0\n let spentTotal = 0\n let dayIndex = utcDayIndex(Date.now())\n\n // ── Hosted-ledger sync (optional): receipts → POST /api/grants/:id/ledger ──\n const ledgerEndpoint =\n options.apiKey && grant.id\n ? `${(options.ledgerUrl ?? 'https://yeetful.com').replace(/\\/+$/, '')}/api/grants/${grant.id}/ledger`\n : null\n if (options.apiKey && !grant.id) {\n log('hosted-ledger sync disabled: grant.id is not set (use the id of your yeetful.com grant)')\n }\n // A chain (not fire-and-forget) so receipts land in order and flushLedger()\n // can await them; one failed POST is logged and never poisons the chain.\n let ledgerChain: Promise<void> = Promise.resolve()\n const ledgerFetch = options.fetch ?? globalThis.fetch\n const sync = (r: Receipt) => {\n if (!ledgerEndpoint) return\n ledgerChain = ledgerChain\n .then(async () => {\n const res = await ledgerFetch(ledgerEndpoint, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n authorization: `Bearer ${options.apiKey}`,\n },\n body: JSON.stringify({\n host: r.host,\n amountUsd: r.amountUsd,\n ok: r.ok,\n txHash: r.txHash,\n note: r.note,\n }),\n })\n if (!res.ok) {\n // fetch silently DROPS the Authorization header when it follows a\n // cross-origin redirect (e.g. apex → www) — surface the real cause.\n const moved = res.redirected\n ? ` (request was redirected to ${new URL(res.url).origin}, which strips the auth header — set ledgerUrl to that origin)`\n : ''\n log(`ledger sync → ${res.status} for ${r.host}${moved}`)\n }\n })\n .catch((err) => {\n log(`ledger sync failed for ${r.host}: ${err instanceof Error ? err.message : err}`)\n })\n }\n\n const emit = (r: Receipt) => {\n sync(r)\n void Promise.resolve(onReceipt?.(r)).catch(() => {})\n }\n const deny = (host: string, code: GrantViolation, msg: string): never => {\n emit({ host, amountUsd: 0, ok: false, note: code, ts: Date.now() })\n log(`✗ ${host} — ${code}: ${msg}`)\n throw new GrantError(code, msg)\n }\n\n const pay = async function pay(\n input: string | URL | Request,\n init: RequestInit = {},\n ): Promise<Response> {\n // Roll the daily budget at UTC midnight.\n const today = utcDayIndex(Date.now())\n if (today !== dayIndex) {\n dayIndex = today\n spentToday = 0\n }\n\n const host = hostOf(input)\n\n // ── Pre-flight policy (no network): status → expiry → allowlist ─────────\n if ((grant.status ?? 'active') === 'revoked') deny(host, 'REVOKED', 'grant is revoked')\n if (Date.now() > expiryMs(grant.expiresAt)) deny(host, 'EXPIRED', 'grant has expired')\n if (!grant.allow.map((h) => h.toLowerCase()).includes(host)) {\n deny(host, 'NOT_ALLOWED', `${host} is not in this grant's allowlist`)\n }\n\n // Price is only known from the 402 challenge — check caps in the hook,\n // which runs after the challenge is parsed and before the payment is signed.\n let pricedUsd = 0\n const client = createPaymentClient({\n wallet,\n fetch: options.fetch,\n allowedNetworks: options.allowedNetworks,\n // Per-call enforcement lives in the hook (not maxAmountAtomic) so an\n // over-cap call surfaces a clean GrantError instead of a filtered no-match.\n onPaymentRequired: (req: PaymentRequirement) => {\n // Version-agnostic price (v2 `amount`, v1 `maxAmountRequired`).\n // Selection already dropped unpriced entries, so this can't be null.\n const price = Number(requirementAtomicAmount(req) ?? 0n) / 1e6\n if (price > grant.perCallUsd) {\n deny(host, 'OVER_PER_CALL', `$${price.toFixed(4)} exceeds per-call cap $${grant.perCallUsd}`)\n }\n if (spentToday + price > grant.perDayUsd) {\n deny(host, 'BUDGET_EXCEEDED', `$${(spentToday + price).toFixed(2)} exceeds today's cap $${grant.perDayUsd}`)\n }\n if (grant.totalUsd != null && spentTotal + price > grant.totalUsd) {\n deny(host, 'BUDGET_EXCEEDED', `$${(spentTotal + price).toFixed(2)} exceeds lifetime cap $${grant.totalUsd}`)\n }\n pricedUsd = price\n return true\n },\n })\n\n let res: Response\n try {\n res = await client(input, init)\n } catch (err) {\n if (err instanceof GrantError) throw err // already denied + receipted\n // A rejection from the underlying client (e.g. no acceptable requirement).\n const note = err instanceof PaymentError ? 'payment-failed' : 'error'\n emit({ host, amountUsd: 0, ok: false, note, ts: Date.now() })\n throw err\n }\n\n // Settled (or a free, non-402 call where pricedUsd stayed 0).\n if (pricedUsd > 0) {\n spentToday += pricedUsd\n spentTotal += pricedUsd\n }\n const txHash = txHashOf(res)\n emit({ host, amountUsd: pricedUsd, ok: true, txHash, note: 'settled', ts: Date.now() })\n log(`✓ ${host} — $${pricedUsd.toFixed(4)} · today $${spentToday.toFixed(2)}/$${grant.perDayUsd}`)\n return res\n } as PayFn\n\n pay.spentTodayUsd = () => spentToday\n pay.remainingTodayUsd = () => Math.max(0, grant.perDayUsd - spentToday)\n pay.spentTotalUsd = () => spentTotal\n pay.flushLedger = () => ledgerChain\n return pay\n}\n","import type {\n FacilitatorConfig,\n PaymentPayload,\n PaymentRequirement,\n SettleResult,\n VerifyResult,\n} from './types.js'\n\n/**\n * Thin wrapper around an x402 facilitator HTTP service.\n * The facilitator verifies signed payment authorizations and settles them on-chain.\n */\nexport class Facilitator {\n private readonly url: string\n private readonly authHeader?: string\n private readonly fetcher: typeof fetch\n\n constructor(config: FacilitatorConfig) {\n this.url = config.url.replace(/\\/$/, '')\n this.authHeader = config.authHeader\n this.fetcher = config.fetch ?? globalThis.fetch.bind(globalThis)\n }\n\n async verify(\n payment: PaymentPayload,\n requirement: PaymentRequirement,\n ): Promise<VerifyResult> {\n return this.post<VerifyResult>('/verify', { paymentPayload: payment, paymentRequirements: requirement })\n }\n\n async settle(\n payment: PaymentPayload,\n requirement: PaymentRequirement,\n ): Promise<SettleResult> {\n return this.post<SettleResult>('/settle', { paymentPayload: payment, paymentRequirements: requirement })\n }\n\n private async post<T>(path: string, body: unknown): Promise<T> {\n const res = await this.fetcher(this.url + path, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n ...(this.authHeader ? { authorization: this.authHeader } : {}),\n },\n body: JSON.stringify(body),\n })\n if (!res.ok) {\n const text = await res.text().catch(() => '')\n throw new Error(`Facilitator ${path} failed: ${res.status} ${text}`)\n }\n return (await res.json()) as T\n }\n}\n\n/** Default hosted facilitator. Override for self-hosted deployments. */\nexport const DEFAULT_FACILITATOR_URL = 'https://facilitator.yeetful.com'\n","import type { Address } from 'viem'\nimport { Facilitator, DEFAULT_FACILITATOR_URL } from './facilitator.js'\nimport type {\n FacilitatorConfig,\n PaymentPayload,\n PaymentRequirement,\n PaymentRequiredResponse,\n SettleResult,\n X402Network,\n} from './types.js'\nimport { decodePayment, encodePayment, usdcAddress, usdToAtomic } from './utils.js'\n\nexport interface RouteGateOptions {\n /** Price in USD, e.g. \"0.01\". Converted to USDC atomic units. */\n price: string | number\n /** Recipient address that receives the funds. */\n recipient: Address\n /** Network(s) to accept. Defaults to `['base']`. Pass an array for multi-chain. */\n network?: X402Network | X402Network[]\n /** Override the payment asset (defaults to USDC for the given network). */\n asset?: Address\n /** Human-readable description of the resource. */\n description?: string\n /** Seconds the signed authorization is valid. Default: 600. */\n maxTimeoutSeconds?: number\n /** Facilitator config, or `false` to skip verification/settlement (trust-mode). */\n facilitator?: FacilitatorConfig | false\n /**\n * Optional resource identifier (defaults to the request URL). Useful for\n * logging / receipts.\n */\n resource?: string\n}\n\n/**\n * Runtime-agnostic gate: given a Fetch-API `Request`, either returns a 402\n * `Response` or a `{ settle }` handle. After your handler runs, call `settle()`\n * to finalize the payment and get a `X-PAYMENT-RESPONSE` header to attach.\n *\n * This is the building block used by the framework adapters (`./next`, `./express`).\n */\nexport async function gate(\n request: Request,\n opts: RouteGateOptions,\n): Promise<\n | { type: 'paymentRequired'; response: Response }\n | { type: 'ok'; payer: Address; settle: () => Promise<{ header: string; result: SettleResult }> }\n> {\n const requirements = buildRequirements(request, opts)\n\n const header = request.headers.get('x-payment') ?? request.headers.get('X-PAYMENT')\n if (!header) {\n return { type: 'paymentRequired', response: paymentRequiredResponse(requirements) }\n }\n\n let payment: PaymentPayload\n try {\n payment = decodePayment<PaymentPayload>(header)\n } catch {\n return {\n type: 'paymentRequired',\n response: paymentRequiredResponse(requirements, 'Invalid X-PAYMENT header'),\n }\n }\n\n const matched = requirements.find(\n (r) => r.network === payment.network && r.scheme === payment.scheme,\n )\n if (!matched) {\n return {\n type: 'paymentRequired',\n response: paymentRequiredResponse(requirements, 'Payment does not match any accepted requirement'),\n }\n }\n\n if (opts.facilitator === false) {\n const payer = payment.payload.authorization.from as Address\n return {\n type: 'ok',\n payer,\n settle: async () => ({\n header: encodePayment({ success: true, network: matched.network }),\n result: { success: true },\n }),\n }\n }\n\n const facilitator = new Facilitator(opts.facilitator ?? { url: DEFAULT_FACILITATOR_URL })\n const verified = await facilitator.verify(payment, matched)\n if (!verified.isValid) {\n return {\n type: 'paymentRequired',\n response: paymentRequiredResponse(\n requirements,\n verified.invalidReason ?? 'Payment verification failed',\n ),\n }\n }\n\n const payer = (verified.payer ?? payment.payload.authorization.from) as Address\n\n return {\n type: 'ok',\n payer,\n settle: async () => {\n const result = await facilitator.settle(payment, matched)\n return {\n header: encodePayment({\n success: result.success,\n transaction: result.transaction,\n network: result.network ?? matched.network,\n errorReason: result.errorReason,\n payer,\n }),\n result,\n }\n },\n }\n}\n\nfunction buildRequirements(request: Request, opts: RouteGateOptions): PaymentRequirement[] {\n const networks = Array.isArray(opts.network) ? opts.network : [opts.network ?? 'base']\n const atomic = usdToAtomic(opts.price)\n const resource = opts.resource ?? request.url\n\n return networks.map((network) => ({\n scheme: 'exact',\n network,\n asset: opts.asset ?? usdcAddress(network),\n maxAmountRequired: atomic,\n payTo: opts.recipient,\n description: opts.description,\n resource,\n maxTimeoutSeconds: opts.maxTimeoutSeconds ?? 600,\n extra: { name: 'USD Coin', version: '2' },\n }))\n}\n\nfunction paymentRequiredResponse(\n accepts: PaymentRequirement[],\n error?: string,\n): Response {\n const body: PaymentRequiredResponse = { x402Version: 1, accepts, ...(error ? { error } : {}) }\n return new Response(JSON.stringify(body), {\n status: 402,\n headers: { 'content-type': 'application/json' },\n })\n}\n\nexport { Facilitator, DEFAULT_FACILITATOR_URL } from './facilitator.js'\n"]}
package/dist/index.js CHANGED
@@ -281,7 +281,10 @@ function yeetful(options) {
281
281
  note: r.note
282
282
  })
283
283
  });
284
- if (!res.ok) log(`ledger sync \u2192 ${res.status} for ${r.host}`);
284
+ if (!res.ok) {
285
+ const moved = res.redirected ? ` (request was redirected to ${new URL(res.url).origin}, which strips the auth header \u2014 set ledgerUrl to that origin)` : "";
286
+ log(`ledger sync \u2192 ${res.status} for ${r.host}${moved}`);
287
+ }
285
288
  }).catch((err) => {
286
289
  log(`ledger sync failed for ${r.host}: ${err instanceof Error ? err.message : err}`);
287
290
  });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils.ts","../src/client.ts","../src/agent.ts","../src/facilitator.ts","../src/server.ts"],"names":["pay","payer"],"mappings":";AAEA,IAAM,eAAA,GAAsD;AAAA,EAC1D,IAAA,EAAM,4CAAA;AAAA,EACN,cAAA,EAAgB,4CAAA;AAAA,EAChB,QAAA,EAAU,4CAAA;AAAA,EACV,QAAA,EAAU,4CAAA;AAAA,EACV,QAAA,EAAU,4CAAA;AAAA,EACV,OAAA,EAAS;AACX,CAAA;AAEO,IAAM,aAAA,GAAgB,CAAA;AAGtB,SAAS,YAAY,OAAA,EAAqC;AAC/D,EAAA,OAAO,gBAAgB,OAAO,CAAA;AAChC;AAMO,SAAS,WAAA,CAAY,MAAA,EAAyB,QAAA,GAAW,aAAA,EAAuB;AACrF,EAAA,MAAM,MAAM,OAAO,MAAA,KAAW,QAAA,GAAW,MAAA,CAAO,UAAS,GAAI,MAAA;AAC7D,EAAA,IAAI,CAAC,eAAA,CAAgB,IAAA,CAAK,GAAG,CAAA,EAAG;AAC9B,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,gBAAA,EAAmB,GAAG,CAAA,CAAE,CAAA;AAAA,EAC1C;AACA,EAAA,MAAM,CAAC,KAAA,EAAO,IAAA,GAAO,EAAE,CAAA,GAAI,GAAA,CAAI,MAAM,GAAG,CAAA;AACxC,EAAA,MAAM,MAAA,GAAS,KAAK,KAAA,CAAM,CAAA,EAAG,QAAQ,CAAA,CAAE,MAAA,CAAO,UAAU,GAAG,CAAA;AAC3D,EAAA,OAAA,CAAQ,MAAA,CAAO,KAAA,IAAS,GAAG,CAAA,GAAI,GAAA,IAAO,MAAA,CAAO,QAAQ,CAAA,GAAI,MAAA,CAAO,MAAA,IAAU,GAAG,CAAA,EAAG,QAAA,EAAS;AAC3F;AAEA,IAAM,WAAA,GAAc,IAAI,WAAA,EAAY;AACpC,IAAM,WAAA,GAAc,IAAI,WAAA,EAAY;AAG7B,SAAS,cAAc,KAAA,EAAwB;AACpD,EAAA,MAAM,QAAQ,WAAA,CAAY,MAAA,CAAO,IAAA,CAAK,SAAA,CAAU,KAAK,CAAC,CAAA;AACtD,EAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,IAAA,OAAO,MAAA,CAAO,IAAA,CAAK,KAAK,CAAA,CAAE,SAAS,QAAQ,CAAA;AAAA,EAC7C;AACA,EAAA,IAAI,MAAA,GAAS,EAAA;AACb,EAAA,KAAA,MAAW,IAAA,IAAQ,KAAA,EAAO,MAAA,IAAU,MAAA,CAAO,aAAa,IAAI,CAAA;AAC5D,EAAA,OAAO,KAAK,MAAM,CAAA;AACpB;AAGO,SAAS,cAA2B,GAAA,EAAgB;AACzD,EAAA,IAAI,KAAA;AACJ,EAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,IAAA,KAAA,GAAQ,IAAI,UAAA,CAAW,MAAA,CAAO,IAAA,CAAK,GAAA,EAAK,QAAQ,CAAC,CAAA;AAAA,EACnD,CAAA,MAAO;AACL,IAAA,MAAM,MAAA,GAAS,KAAK,GAAG,CAAA;AACvB,IAAA,KAAA,GAAQ,IAAI,UAAA,CAAW,MAAA,CAAO,MAAM,CAAA;AACpC,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,MAAA,CAAO,MAAA,EAAQ,CAAA,EAAA,EAAK,KAAA,CAAM,CAAC,CAAA,GAAI,MAAA,CAAO,UAAA,CAAW,CAAC,CAAA;AAAA,EACxE;AACA,EAAA,OAAO,IAAA,CAAK,KAAA,CAAM,WAAA,CAAY,MAAA,CAAO,KAAK,CAAC,CAAA;AAC7C;AAGO,SAAS,WAAA,GAA6B;AAC3C,EAAA,MAAM,KAAA,GAAQ,IAAI,UAAA,CAAW,EAAE,CAAA;AAC/B,EAAA,UAAA,CAAW,MAAA,CAAO,gBAAgB,KAAK,CAAA;AACvC,EAAA,OAAQ,OAAO,KAAA,CAAM,IAAA,CAAK,KAAA,EAAO,CAAC,MAAM,CAAA,CAAE,QAAA,CAAS,EAAE,CAAA,CAAE,SAAS,CAAA,EAAG,GAAG,CAAC,CAAA,CAAE,KAAK,EAAE,CAAA;AAClF;;;ACtBO,SAAS,oBAAoB,OAAA,EAAwB;AAC1D,EAAA,MAAM,YAAY,OAAA,CAAQ,KAAA,IAAS,UAAA,CAAW,KAAA,CAAM,KAAK,UAAU,CAAA;AAEnE,EAAA,OAAO,eAAe,QAAA,CACpB,KAAA,EACA,IAAA,GAAoB,EAAC,EACF;AACnB,IAAA,MAAM,KAAA,GAAQ,MAAM,SAAA,CAAU,KAAA,EAAO,IAAI,CAAA;AACzC,IAAA,IAAI,KAAA,CAAM,MAAA,KAAW,GAAA,EAAK,OAAO,KAAA;AAEjC,IAAA,MAAM,YAAA,GAAe,MAAM,oBAAA,CAAqB,KAAK,CAAA;AACrD,IAAA,MAAM,cAAc,iBAAA,CAAkB,YAAA,CAAa,OAAA,IAAW,IAAI,OAAO,CAAA;AACzE,IAAA,IAAI,CAAC,WAAA,EAAa;AAChB,MAAA,MAAM,IAAI,YAAA,CAAa,8DAAA,EAAgE,YAAY,CAAA;AAAA,IACrG;AAEA,IAAA,IAAI,QAAQ,iBAAA,EAAmB;AAC7B,MAAA,MAAM,QAAA,GAAW,MAAM,OAAA,CAAQ,iBAAA,CAAkB,WAAW,CAAA;AAC5D,MAAA,IAAI,CAAC,QAAA,EAAU,MAAM,IAAI,YAAA,CAAa,4BAA4B,YAAY,CAAA;AAAA,IAChF;AAEA,IAAA,MAAM,OAAA,GAAU,MAAM,sBAAA,CAAuB,OAAA,CAAQ,QAAQ,WAAW,CAAA;AACxE,IAAA,MAAM,MAAA,GAAS,kBAAA,CAAmB,YAAA,EAAc,WAAA,EAAa,OAAO,CAAA;AACpE,IAAA,MAAM,OAAA,GAAU,IAAI,OAAA,CAAQ,IAAA,CAAK,OAAO,CAAA;AACxC,IAAA,OAAA,CAAQ,GAAA,CAAI,MAAA,CAAO,IAAA,EAAM,MAAA,CAAO,KAAK,CAAA;AAErC,IAAA,OAAO,UAAU,KAAA,EAAO,EAAE,GAAG,IAAA,EAAM,SAAS,CAAA;AAAA,EAC9C,CAAA;AACF;AAEO,IAAM,YAAA,GAAN,cAA2B,KAAA,CAAM;AAAA,EAC7B,YAAA;AAAA,EACT,WAAA,CAAY,SAAiB,YAAA,EAAwC;AACnE,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,cAAA;AACZ,IAAA,IAAA,CAAK,YAAA,GAAe,YAAA;AAAA,EACtB;AACF;AAOO,SAAS,wBAAwB,GAAA,EAAwC;AAC9E,EAAA,MAAM,GAAA,GAAM,GAAA,CAAI,MAAA,IAAU,GAAA,CAAI,iBAAA;AAC9B,EAAA,IAAI,GAAA,IAAO,MAAM,OAAO,IAAA;AACxB,EAAA,IAAI;AACF,IAAA,OAAO,OAAO,GAAG,CAAA;AAAA,EACnB,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAEA,eAAe,qBAAqB,GAAA,EAAiD;AACnF,EAAA,IAAI;AACF,IAAA,OAAQ,MAAM,GAAA,CAAI,KAAA,EAAM,CAAE,IAAA,EAAK;AAAA,EACjC,CAAA,CAAA,MAAQ;AAGN,IAAA,MAAM,MAAA,GAAS,GAAA,CAAI,OAAA,CAAQ,GAAA,CAAI,kBAAkB,CAAA;AACjD,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,IAAI;AACF,QAAA,OAAO,cAAuC,MAAM,CAAA;AAAA,MACtD,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AACA,IAAA,MAAM,IAAI,aAAa,0DAA0D,CAAA;AAAA,EACnF;AACF;AAEA,SAAS,iBAAA,CACP,SACA,IAAA,EACgC;AAChC,EAAA,MAAM,SAAS,OAAA,CACZ,MAAA,CAAO,CAAC,CAAA,KAAM,EAAE,MAAA,KAAW,OAAO,CAAA,CAElC,MAAA,CAAO,CAAC,CAAA,KAAM,iBAAA,CAAkB,EAAE,OAAO,CAAA,KAAM,IAAI,CAAA,CACnD,MAAA;AAAA,IACC,CAAC,CAAA,KACC,CAAC,IAAA,CAAK,eAAA,IACN,KAAK,eAAA,CAAgB,IAAA,CAAK,CAAC,CAAA,KAAM,kBAAkB,CAAC,CAAA,KAAM,iBAAA,CAAkB,CAAA,CAAE,OAAO,CAAC;AAAA,GAC1F,CACC,GAAA,CAAI,CAAC,CAAA,MAAO,EAAE,GAAA,EAAK,CAAA,EAAG,MAAA,EAAQ,uBAAA,CAAwB,CAAC,CAAA,EAAE,CAAE,CAAA,CAC3D,MAAA,CAAO,CAAC,CAAA,KAAwD,CAAA,CAAE,MAAA,KAAW,IAAI,CAAA,CACjF,MAAA,CAAO,CAAC,CAAA,KAAM,CAAC,IAAA,CAAK,eAAA,IAAmB,CAAA,CAAE,MAAA,IAAU,KAAK,eAAe,CAAA;AAE1E,EAAA,OAAO,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAO,CAAA,CAAE,MAAA,GAAS,CAAA,CAAE,MAAA,GAAS,EAAA,GAAK,CAAE,CAAA,CAAE,CAAC,CAAA,EAAG,GAAA;AACnE;AAGA,SAAS,kBAAA,CACP,SAAA,EACA,WAAA,EACA,OAAA,EACiC;AACjC,EAAA,MAAM,OAAA,GAAU,UAAU,WAAA,IAAe,CAAA;AACzC,EAAA,IAAI,WAAW,CAAA,EAAG;AAChB,IAAA,MAAM,QAAA,GAA8B;AAAA,MAClC,WAAA,EAAa,OAAA;AAAA,MACb,UAAU,SAAA,CAAU,QAAA;AAAA,MACpB,QAAA,EAAU,WAAA;AAAA,MACV,OAAA;AAAA,MACA,UAAA,EAAY,SAAA,CAAU,UAAA,IAAc;AAAC,KACvC;AACA,IAAA,OAAO,EAAE,IAAA,EAAM,mBAAA,EAAqB,KAAA,EAAO,aAAA,CAAc,QAAQ,CAAA,EAAE;AAAA,EACrE;AACA,EAAA,MAAM,EAAA,GAAqB;AAAA,IACzB,WAAA,EAAa,CAAA;AAAA,IACb,MAAA,EAAQ,OAAA;AAAA,IACR,SAAS,WAAA,CAAY,OAAA;AAAA,IACrB;AAAA,GACF;AACA,EAAA,OAAO,EAAE,IAAA,EAAM,WAAA,EAAa,KAAA,EAAO,aAAA,CAAc,EAAE,CAAA,EAAE;AACvD;AAGA,eAAsB,sBAAA,CACpB,QACA,WAAA,EAC0B;AAC1B,EAAA,MAAM,UAAU,MAAA,CAAO,OAAA;AACvB,EAAA,IAAI,CAAC,OAAA,EAAS,MAAM,IAAI,aAAa,gCAAgC,CAAA;AAErE,EAAA,MAAM,KAAA,GAAQ,wBAAwB,WAAW,CAAA;AACjD,EAAA,IAAI,UAAU,IAAA,EAAM;AAClB,IAAA,MAAM,IAAI,aAAa,8CAA8C,CAAA;AAAA,EACvE;AACA,EAAA,MAAM,OAAA,GAAU,iBAAA,CAAkB,WAAA,CAAY,OAAO,CAAA;AACrD,EAAA,IAAI,YAAY,IAAA,EAAM;AACpB,IAAA,MAAM,IAAI,YAAA,CAAa,CAAA,0BAAA,EAA6B,WAAA,CAAY,OAAO,CAAA,CAAE,CAAA;AAAA,EAC3E;AAEA,EAAA,MAAM,MAAM,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,GAAA,KAAQ,GAAI,CAAA;AACxC,EAAA,MAAM,UAAA,GAAa,MAAA,CAAO,GAAA,GAAM,EAAE,CAAA;AAClC,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,GAAA,IAAO,WAAA,CAAY,qBAAqB,GAAA,CAAI,CAAA;AACvE,EAAA,MAAM,QAAQ,WAAA,EAAY;AAE1B,EAAA,MAAM,SAAA,GACH,WAAA,CAAY,KAAA,EAAO,IAAA,IAA+B,UAAA;AACrD,EAAA,MAAM,YAAA,GACH,WAAA,CAAY,KAAA,EAAO,OAAA,IAAkC,GAAA;AAExD,EAAA,MAAM,SAAA,GAAa,MAAM,MAAA,CAAO,aAAA,CAAc;AAAA,IAC5C,OAAA;AAAA,IACA,MAAA,EAAQ;AAAA,MACN,IAAA,EAAM,SAAA;AAAA,MACN,OAAA,EAAS,YAAA;AAAA,MACT,OAAA;AAAA,MACA,mBAAmB,WAAA,CAAY;AAAA,KACjC;AAAA,IACA,KAAA,EAAO;AAAA,MACL,yBAAA,EAA2B;AAAA,QACzB,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,SAAA,EAAU;AAAA,QAChC,EAAE,IAAA,EAAM,IAAA,EAAM,IAAA,EAAM,SAAA,EAAU;AAAA,QAC9B,EAAE,IAAA,EAAM,OAAA,EAAS,IAAA,EAAM,SAAA,EAAU;AAAA,QACjC,EAAE,IAAA,EAAM,YAAA,EAAc,IAAA,EAAM,SAAA,EAAU;AAAA,QACtC,EAAE,IAAA,EAAM,aAAA,EAAe,IAAA,EAAM,SAAA,EAAU;AAAA,QACvC,EAAE,IAAA,EAAM,OAAA,EAAS,IAAA,EAAM,SAAA;AAAU;AACnC,KACF;AAAA,IACA,WAAA,EAAa,2BAAA;AAAA,IACb,OAAA,EAAS;AAAA,MACP,MAAM,OAAA,CAAQ,OAAA;AAAA,MACd,IAAI,WAAA,CAAY,KAAA;AAAA,MAChB,KAAA;AAAA,MACA,UAAA;AAAA,MACA,WAAA;AAAA,MACA;AAAA;AACF,GACD,CAAA;AAED,EAAA,OAAO;AAAA,IACL,SAAA;AAAA,IACA,aAAA,EAAe;AAAA,MACb,MAAM,OAAA,CAAQ,OAAA;AAAA,MACd,IAAI,WAAA,CAAY,KAAA;AAAA,MAChB,KAAA,EAAO,MAAM,QAAA,EAAS;AAAA,MACtB,UAAA,EAAY,WAAW,QAAA,EAAS;AAAA,MAChC,WAAA,EAAa,YAAY,QAAA,EAAS;AAAA,MAClC;AAAA;AACF,GACF;AACF;AAMA,eAAsB,WAAA,CACpB,QACA,WAAA,EACyB;AACzB,EAAA,OAAO;AAAA,IACL,WAAA,EAAa,CAAA;AAAA,IACb,MAAA,EAAQ,OAAA;AAAA,IACR,SAAS,WAAA,CAAY,OAAA;AAAA,IACrB,OAAA,EAAS,MAAM,sBAAA,CAAuB,MAAA,EAAQ,WAAW;AAAA,GAC3D;AACF;AAGA,SAAS,kBAAkB,OAAA,EAAgC;AACzD,EAAA,IAAI,OAAA,CAAQ,UAAA,CAAW,SAAS,CAAA,EAAG;AACjC,IAAA,MAAM,KAAK,MAAA,CAAO,OAAA,CAAQ,KAAA,CAAM,SAAA,CAAU,MAAM,CAAC,CAAA;AACjD,IAAA,OAAO,OAAO,SAAA,CAAU,EAAE,CAAA,IAAK,EAAA,GAAK,IAAI,EAAA,GAAK,IAAA;AAAA,EAC/C;AACA,EAAA,QAAQ,OAAA;AAAwB,IAC9B,KAAK,MAAA;AACH,MAAA,OAAO,IAAA;AAAA,IACT,KAAK,cAAA;AACH,MAAA,OAAO,KAAA;AAAA,IACT,KAAK,UAAA;AACH,MAAA,OAAO,CAAA;AAAA,IACT,KAAK,UAAA;AACH,MAAA,OAAO,EAAA;AAAA,IACT,KAAK,UAAA;AACH,MAAA,OAAO,KAAA;AAAA,IACT,KAAK,SAAA;AACH,MAAA,OAAO,GAAA;AAAA,IACT;AACE,MAAA,OAAO,IAAA;AAAA;AAEb;;;AC3NO,IAAM,UAAA,GAAN,cAAyB,KAAA,CAAM;AAAA,EACpC,WAAA,CACS,MACP,OAAA,EACA;AACA,IAAA,KAAA,CAAM,OAAO,CAAA;AAHN,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAIP,IAAA,IAAA,CAAK,IAAA,GAAO,YAAA;AAAA,EACd;AAAA,EALS,IAAA;AAMX;AAsEA,SAAS,SAAS,SAAA,EAA6C;AAC7D,EAAA,IAAI,SAAA,IAAa,MAAM,OAAO,QAAA;AAC9B,EAAA,IAAI,SAAA,YAAqB,IAAA,EAAM,OAAO,SAAA,CAAU,OAAA,EAAQ;AACxD,EAAA,IAAI,OAAO,SAAA,KAAc,QAAA,EAAU,OAAO,SAAA;AAC1C,EAAA,MAAM,CAAA,GAAI,IAAI,IAAA,CAAK,SAAS,EAAE,OAAA,EAAQ;AACtC,EAAA,OAAO,MAAA,CAAO,KAAA,CAAM,CAAC,CAAA,GAAI,QAAA,GAAW,CAAA;AACtC;AAEA,SAAS,YAAY,EAAA,EAAoB;AACvC,EAAA,OAAO,IAAA,CAAK,KAAA,CAAM,EAAA,GAAK,KAAU,CAAA;AACnC;AAEA,SAAS,OAAO,KAAA,EAAuC;AACrD,EAAA,MAAM,GAAA,GAAM,OAAO,KAAA,KAAU,QAAA,GAAW,QAAQ,KAAA,YAAiB,GAAA,GAAM,KAAA,CAAM,IAAA,GAAO,KAAA,CAAM,GAAA;AAC1F,EAAA,IAAI;AACF,IAAA,OAAO,IAAI,GAAA,CAAI,GAAG,CAAA,CAAE,KAAK,WAAA,EAAY;AAAA,EACvC,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAA;AAAA,EACT;AACF;AAIA,SAAS,SAAS,GAAA,EAAmC;AACnD,EAAA,MAAM,MAAA,GAAS,IAAI,OAAA,CAAQ,GAAA,CAAI,kBAAkB,CAAA,IAAK,GAAA,CAAI,OAAA,CAAQ,GAAA,CAAI,oBAAoB,CAAA;AAC1F,EAAA,IAAI,CAAC,QAAQ,OAAO,MAAA;AACpB,EAAA,IAAI;AACF,IAAA,OAAO,aAAA,CAA4B,MAAM,CAAA,CAAE,WAAA;AAAA,EAC7C,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,MAAA;AAAA,EACT;AACF;AAMO,SAAS,QAAQ,OAAA,EAA8B;AACpD,EAAA,MAAM,EAAE,MAAA,EAAQ,KAAA,EAAO,SAAA,EAAW,SAAQ,GAAI,OAAA;AAC9C,EAAA,MAAM,GAAA,GAAM,YAAY,MAAM;AAAA,EAAC,CAAA,CAAA;AAE/B,EAAA,IAAI,UAAA,GAAa,CAAA;AACjB,EAAA,IAAI,UAAA,GAAa,CAAA;AACjB,EAAA,IAAI,QAAA,GAAW,WAAA,CAAY,IAAA,CAAK,GAAA,EAAK,CAAA;AAGrC,EAAA,MAAM,iBACJ,OAAA,CAAQ,MAAA,IAAU,KAAA,CAAM,EAAA,GACpB,IAAI,OAAA,CAAQ,SAAA,IAAa,qBAAA,EAAuB,OAAA,CAAQ,QAAQ,EAAE,CAAC,CAAA,YAAA,EAAe,KAAA,CAAM,EAAE,CAAA,OAAA,CAAA,GAC1F,IAAA;AACN,EAAA,IAAI,OAAA,CAAQ,MAAA,IAAU,CAAC,KAAA,CAAM,EAAA,EAAI;AAC/B,IAAA,GAAA,CAAI,yFAAyF,CAAA;AAAA,EAC/F;AAGA,EAAA,IAAI,WAAA,GAA6B,QAAQ,OAAA,EAAQ;AACjD,EAAA,MAAM,WAAA,GAAc,OAAA,CAAQ,KAAA,IAAS,UAAA,CAAW,KAAA;AAChD,EAAA,MAAM,IAAA,GAAO,CAAC,CAAA,KAAe;AAC3B,IAAA,IAAI,CAAC,cAAA,EAAgB;AACrB,IAAA,WAAA,GAAc,WAAA,CACX,KAAK,YAAY;AAChB,MAAA,MAAM,GAAA,GAAM,MAAM,WAAA,CAAY,cAAA,EAAgB;AAAA,QAC5C,MAAA,EAAQ,MAAA;AAAA,QACR,OAAA,EAAS;AAAA,UACP,cAAA,EAAgB,kBAAA;AAAA,UAChB,aAAA,EAAe,CAAA,OAAA,EAAU,OAAA,CAAQ,MAAM,CAAA;AAAA,SACzC;AAAA,QACA,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,UACnB,MAAM,CAAA,CAAE,IAAA;AAAA,UACR,WAAW,CAAA,CAAE,SAAA;AAAA,UACb,IAAI,CAAA,CAAE,EAAA;AAAA,UACN,QAAQ,CAAA,CAAE,MAAA;AAAA,UACV,MAAM,CAAA,CAAE;AAAA,SACT;AAAA,OACF,CAAA;AACD,MAAA,IAAI,CAAC,GAAA,CAAI,EAAA,EAAI,GAAA,CAAI,CAAA,mBAAA,EAAiB,IAAI,MAAM,CAAA,KAAA,EAAQ,CAAA,CAAE,IAAI,CAAA,CAAE,CAAA;AAAA,IAC9D,CAAC,CAAA,CACA,KAAA,CAAM,CAAC,GAAA,KAAQ;AACd,MAAA,GAAA,CAAI,CAAA,uBAAA,EAA0B,EAAE,IAAI,CAAA,EAAA,EAAK,eAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,GAAG,CAAA,CAAE,CAAA;AAAA,IACrF,CAAC,CAAA;AAAA,EACL,CAAA;AAEA,EAAA,MAAM,IAAA,GAAO,CAAC,CAAA,KAAe;AAC3B,IAAA,IAAA,CAAK,CAAC,CAAA;AACN,IAAA,KAAK,QAAQ,OAAA,CAAQ,SAAA,GAAY,CAAC,CAAC,CAAA,CAAE,MAAM,MAAM;AAAA,IAAC,CAAC,CAAA;AAAA,EACrD,CAAA;AACA,EAAA,MAAM,IAAA,GAAO,CAAC,IAAA,EAAc,IAAA,EAAsB,GAAA,KAAuB;AACvE,IAAA,IAAA,CAAK,EAAE,IAAA,EAAM,SAAA,EAAW,CAAA,EAAG,EAAA,EAAI,KAAA,EAAO,IAAA,EAAM,IAAA,EAAM,EAAA,EAAI,IAAA,CAAK,GAAA,EAAI,EAAG,CAAA;AAClE,IAAA,GAAA,CAAI,UAAK,IAAI,CAAA,QAAA,EAAM,IAAI,CAAA,EAAA,EAAK,GAAG,CAAA,CAAE,CAAA;AACjC,IAAA,MAAM,IAAI,UAAA,CAAW,IAAA,EAAM,GAAG,CAAA;AAAA,EAChC,CAAA;AAEA,EAAA,MAAM,MAAM,eAAeA,IAAAA,CACzB,KAAA,EACA,IAAA,GAAoB,EAAC,EACF;AAEnB,IAAA,MAAM,KAAA,GAAQ,WAAA,CAAY,IAAA,CAAK,GAAA,EAAK,CAAA;AACpC,IAAA,IAAI,UAAU,QAAA,EAAU;AACtB,MAAA,QAAA,GAAW,KAAA;AACX,MAAA,UAAA,GAAa,CAAA;AAAA,IACf;AAEA,IAAA,MAAM,IAAA,GAAO,OAAO,KAAK,CAAA;AAGzB,IAAA,IAAA,CAAK,MAAM,MAAA,IAAU,QAAA,MAAc,WAAW,IAAA,CAAK,IAAA,EAAM,WAAW,kBAAkB,CAAA;AACtF,IAAA,IAAI,IAAA,CAAK,GAAA,EAAI,GAAI,QAAA,CAAS,KAAA,CAAM,SAAS,CAAA,EAAG,IAAA,CAAK,IAAA,EAAM,SAAA,EAAW,mBAAmB,CAAA;AACrF,IAAA,IAAI,CAAC,KAAA,CAAM,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,WAAA,EAAa,CAAA,CAAE,QAAA,CAAS,IAAI,CAAA,EAAG;AAC3D,MAAA,IAAA,CAAK,IAAA,EAAM,aAAA,EAAe,CAAA,EAAG,IAAI,CAAA,iCAAA,CAAmC,CAAA;AAAA,IACtE;AAIA,IAAA,IAAI,SAAA,GAAY,CAAA;AAChB,IAAA,MAAM,SAAS,mBAAA,CAAoB;AAAA,MACjC,MAAA;AAAA,MACA,OAAO,OAAA,CAAQ,KAAA;AAAA,MACf,iBAAiB,OAAA,CAAQ,eAAA;AAAA;AAAA;AAAA,MAGzB,iBAAA,EAAmB,CAAC,GAAA,KAA4B;AAG9C,QAAA,MAAM,QAAQ,MAAA,CAAO,uBAAA,CAAwB,GAAG,CAAA,IAAK,EAAE,CAAA,GAAI,GAAA;AAC3D,QAAA,IAAI,KAAA,GAAQ,MAAM,UAAA,EAAY;AAC5B,UAAA,IAAA,CAAK,IAAA,EAAM,eAAA,EAAiB,CAAA,CAAA,EAAI,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAC,CAAA,uBAAA,EAA0B,KAAA,CAAM,UAAU,CAAA,CAAE,CAAA;AAAA,QAC9F;AACA,QAAA,IAAI,UAAA,GAAa,KAAA,GAAQ,KAAA,CAAM,SAAA,EAAW;AACxC,UAAA,IAAA,CAAK,IAAA,EAAM,iBAAA,EAAmB,CAAA,CAAA,EAAA,CAAK,UAAA,GAAa,KAAA,EAAO,OAAA,CAAQ,CAAC,CAAC,CAAA,sBAAA,EAAyB,KAAA,CAAM,SAAS,CAAA,CAAE,CAAA;AAAA,QAC7G;AACA,QAAA,IAAI,MAAM,QAAA,IAAY,IAAA,IAAQ,UAAA,GAAa,KAAA,GAAQ,MAAM,QAAA,EAAU;AACjE,UAAA,IAAA,CAAK,IAAA,EAAM,iBAAA,EAAmB,CAAA,CAAA,EAAA,CAAK,UAAA,GAAa,KAAA,EAAO,OAAA,CAAQ,CAAC,CAAC,CAAA,uBAAA,EAA0B,KAAA,CAAM,QAAQ,CAAA,CAAE,CAAA;AAAA,QAC7G;AACA,QAAA,SAAA,GAAY,KAAA;AACZ,QAAA,OAAO,IAAA;AAAA,MACT;AAAA,KACD,CAAA;AAED,IAAA,IAAI,GAAA;AACJ,IAAA,IAAI;AACF,MAAA,GAAA,GAAM,MAAM,MAAA,CAAO,KAAA,EAAO,IAAI,CAAA;AAAA,IAChC,SAAS,GAAA,EAAK;AACZ,MAAA,IAAI,GAAA,YAAe,YAAY,MAAM,GAAA;AAErC,MAAA,MAAM,IAAA,GAAO,GAAA,YAAe,YAAA,GAAe,gBAAA,GAAmB,OAAA;AAC9D,MAAA,IAAA,CAAK,EAAE,IAAA,EAAM,SAAA,EAAW,CAAA,EAAG,EAAA,EAAI,KAAA,EAAO,IAAA,EAAM,EAAA,EAAI,IAAA,CAAK,GAAA,EAAI,EAAG,CAAA;AAC5D,MAAA,MAAM,GAAA;AAAA,IACR;AAGA,IAAA,IAAI,YAAY,CAAA,EAAG;AACjB,MAAA,UAAA,IAAc,SAAA;AACd,MAAA,UAAA,IAAc,SAAA;AAAA,IAChB;AACA,IAAA,MAAM,MAAA,GAAS,SAAS,GAAG,CAAA;AAC3B,IAAA,IAAA,CAAK,EAAE,IAAA,EAAM,SAAA,EAAW,SAAA,EAAW,EAAA,EAAI,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,SAAA,EAAW,EAAA,EAAI,IAAA,CAAK,GAAA,IAAO,CAAA;AACtF,IAAA,GAAA,CAAI,CAAA,OAAA,EAAK,IAAI,CAAA,SAAA,EAAO,SAAA,CAAU,QAAQ,CAAC,CAAC,CAAA,aAAA,EAAa,UAAA,CAAW,QAAQ,CAAC,CAAC,CAAA,EAAA,EAAK,KAAA,CAAM,SAAS,CAAA,CAAE,CAAA;AAChG,IAAA,OAAO,GAAA;AAAA,EACT,CAAA;AAEA,EAAA,GAAA,CAAI,gBAAgB,MAAM,UAAA;AAC1B,EAAA,GAAA,CAAI,oBAAoB,MAAM,IAAA,CAAK,IAAI,CAAA,EAAG,KAAA,CAAM,YAAY,UAAU,CAAA;AACtE,EAAA,GAAA,CAAI,gBAAgB,MAAM,UAAA;AAC1B,EAAA,GAAA,CAAI,cAAc,MAAM,WAAA;AACxB,EAAA,OAAO,GAAA;AACT;;;ACxRO,IAAM,cAAN,MAAkB;AAAA,EACN,GAAA;AAAA,EACA,UAAA;AAAA,EACA,OAAA;AAAA,EAEjB,YAAY,MAAA,EAA2B;AACrC,IAAA,IAAA,CAAK,GAAA,GAAM,MAAA,CAAO,GAAA,CAAI,OAAA,CAAQ,OAAO,EAAE,CAAA;AACvC,IAAA,IAAA,CAAK,aAAa,MAAA,CAAO,UAAA;AACzB,IAAA,IAAA,CAAK,UAAU,MAAA,CAAO,KAAA,IAAS,UAAA,CAAW,KAAA,CAAM,KAAK,UAAU,CAAA;AAAA,EACjE;AAAA,EAEA,MAAM,MAAA,CACJ,OAAA,EACA,WAAA,EACuB;AACvB,IAAA,OAAO,IAAA,CAAK,KAAmB,SAAA,EAAW,EAAE,gBAAgB,OAAA,EAAS,mBAAA,EAAqB,aAAa,CAAA;AAAA,EACzG;AAAA,EAEA,MAAM,MAAA,CACJ,OAAA,EACA,WAAA,EACuB;AACvB,IAAA,OAAO,IAAA,CAAK,KAAmB,SAAA,EAAW,EAAE,gBAAgB,OAAA,EAAS,mBAAA,EAAqB,aAAa,CAAA;AAAA,EACzG;AAAA,EAEA,MAAc,IAAA,CAAQ,IAAA,EAAc,IAAA,EAA2B;AAC7D,IAAA,MAAM,MAAM,MAAM,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,MAAM,IAAA,EAAM;AAAA,MAC9C,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,kBAAA;AAAA,QAChB,GAAI,KAAK,UAAA,GAAa,EAAE,eAAe,IAAA,CAAK,UAAA,KAAe;AAAC,OAC9D;AAAA,MACA,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,IAAI;AAAA,KAC1B,CAAA;AACD,IAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,MAAA,MAAM,OAAO,MAAM,GAAA,CAAI,MAAK,CAAE,KAAA,CAAM,MAAM,EAAE,CAAA;AAC5C,MAAA,MAAM,IAAI,MAAM,CAAA,YAAA,EAAe,IAAI,YAAY,GAAA,CAAI,MAAM,CAAA,CAAA,EAAI,IAAI,CAAA,CAAE,CAAA;AAAA,IACrE;AACA,IAAA,OAAQ,MAAM,IAAI,IAAA,EAAK;AAAA,EACzB;AACF;AAGO,IAAM,uBAAA,GAA0B;;;ACdvC,eAAsB,IAAA,CACpB,SACA,IAAA,EAIA;AACA,EAAA,MAAM,YAAA,GAAe,iBAAA,CAAkB,OAAA,EAAS,IAAI,CAAA;AAEpD,EAAA,MAAM,MAAA,GAAS,QAAQ,OAAA,CAAQ,GAAA,CAAI,WAAW,CAAA,IAAK,OAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,WAAW,CAAA;AAClF,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,OAAO,EAAE,IAAA,EAAM,iBAAA,EAAmB,QAAA,EAAU,uBAAA,CAAwB,YAAY,CAAA,EAAE;AAAA,EACpF;AAEA,EAAA,IAAI,OAAA;AACJ,EAAA,IAAI;AACF,IAAA,OAAA,GAAU,cAA8B,MAAM,CAAA;AAAA,EAChD,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,iBAAA;AAAA,MACN,QAAA,EAAU,uBAAA,CAAwB,YAAA,EAAc,0BAA0B;AAAA,KAC5E;AAAA,EACF;AAEA,EAAA,MAAM,UAAU,YAAA,CAAa,IAAA;AAAA,IAC3B,CAAC,MAAM,CAAA,CAAE,OAAA,KAAY,QAAQ,OAAA,IAAW,CAAA,CAAE,WAAW,OAAA,CAAQ;AAAA,GAC/D;AACA,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,iBAAA;AAAA,MACN,QAAA,EAAU,uBAAA,CAAwB,YAAA,EAAc,iDAAiD;AAAA,KACnG;AAAA,EACF;AAEA,EAAA,IAAI,IAAA,CAAK,gBAAgB,KAAA,EAAO;AAC9B,IAAA,MAAMC,MAAAA,GAAQ,OAAA,CAAQ,OAAA,CAAQ,aAAA,CAAc,IAAA;AAC5C,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,IAAA;AAAA,MACN,KAAA,EAAAA,MAAAA;AAAA,MACA,QAAQ,aAAa;AAAA,QACnB,MAAA,EAAQ,cAAc,EAAE,OAAA,EAAS,MAAM,OAAA,EAAS,OAAA,CAAQ,SAAS,CAAA;AAAA,QACjE,MAAA,EAAQ,EAAE,OAAA,EAAS,IAAA;AAAK,OAC1B;AAAA,KACF;AAAA,EACF;AAEA,EAAA,MAAM,WAAA,GAAc,IAAI,WAAA,CAAY,IAAA,CAAK,eAAe,EAAE,GAAA,EAAK,yBAAyB,CAAA;AACxF,EAAA,MAAM,QAAA,GAAW,MAAM,WAAA,CAAY,MAAA,CAAO,SAAS,OAAO,CAAA;AAC1D,EAAA,IAAI,CAAC,SAAS,OAAA,EAAS;AACrB,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,iBAAA;AAAA,MACN,QAAA,EAAU,uBAAA;AAAA,QACR,YAAA;AAAA,QACA,SAAS,aAAA,IAAiB;AAAA;AAC5B,KACF;AAAA,EACF;AAEA,EAAA,MAAM,KAAA,GAAS,QAAA,CAAS,KAAA,IAAS,OAAA,CAAQ,QAAQ,aAAA,CAAc,IAAA;AAE/D,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,IAAA;AAAA,IACN,KAAA;AAAA,IACA,QAAQ,YAAY;AAClB,MAAA,MAAM,MAAA,GAAS,MAAM,WAAA,CAAY,MAAA,CAAO,SAAS,OAAO,CAAA;AACxD,MAAA,OAAO;AAAA,QACL,QAAQ,aAAA,CAAc;AAAA,UACpB,SAAS,MAAA,CAAO,OAAA;AAAA,UAChB,aAAa,MAAA,CAAO,WAAA;AAAA,UACpB,OAAA,EAAS,MAAA,CAAO,OAAA,IAAW,OAAA,CAAQ,OAAA;AAAA,UACnC,aAAa,MAAA,CAAO,WAAA;AAAA,UACpB;AAAA,SACD,CAAA;AAAA,QACD;AAAA,OACF;AAAA,IACF;AAAA,GACF;AACF;AAEA,SAAS,iBAAA,CAAkB,SAAkB,IAAA,EAA8C;AACzF,EAAA,MAAM,QAAA,GAAW,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,OAAO,CAAA,GAAI,IAAA,CAAK,OAAA,GAAU,CAAC,IAAA,CAAK,OAAA,IAAW,MAAM,CAAA;AACrF,EAAA,MAAM,MAAA,GAAS,WAAA,CAAY,IAAA,CAAK,KAAK,CAAA;AACrC,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,QAAA,IAAY,OAAA,CAAQ,GAAA;AAE1C,EAAA,OAAO,QAAA,CAAS,GAAA,CAAI,CAAC,OAAA,MAAa;AAAA,IAChC,MAAA,EAAQ,OAAA;AAAA,IACR,OAAA;AAAA,IACA,KAAA,EAAO,IAAA,CAAK,KAAA,IAAS,WAAA,CAAY,OAAO,CAAA;AAAA,IACxC,iBAAA,EAAmB,MAAA;AAAA,IACnB,OAAO,IAAA,CAAK,SAAA;AAAA,IACZ,aAAa,IAAA,CAAK,WAAA;AAAA,IAClB,QAAA;AAAA,IACA,iBAAA,EAAmB,KAAK,iBAAA,IAAqB,GAAA;AAAA,IAC7C,KAAA,EAAO,EAAE,IAAA,EAAM,UAAA,EAAY,SAAS,GAAA;AAAI,GAC1C,CAAE,CAAA;AACJ;AAEA,SAAS,uBAAA,CACP,SACA,KAAA,EACU;AACV,EAAA,MAAM,IAAA,GAAgC,EAAE,WAAA,EAAa,CAAA,EAAG,OAAA,EAAS,GAAI,KAAA,GAAQ,EAAE,KAAA,EAAM,GAAI,EAAC,EAAG;AAC7F,EAAA,OAAO,IAAI,QAAA,CAAS,IAAA,CAAK,SAAA,CAAU,IAAI,CAAA,EAAG;AAAA,IACxC,MAAA,EAAQ,GAAA;AAAA,IACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA;AAAmB,GAC/C,CAAA;AACH","file":"index.js","sourcesContent":["import type { X402Network } from './types.js'\n\nconst USDC_BY_NETWORK: Record<X402Network, `0x${string}`> = {\n base: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n 'base-sepolia': '0x036CbD53842c5426634e7929541eC2318f3dCF7e',\n ethereum: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n optimism: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85',\n arbitrum: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',\n polygon: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n}\n\nexport const USDC_DECIMALS = 6\n\n/** Returns the canonical USDC contract address for a supported network. */\nexport function usdcAddress(network: X402Network): `0x${string}` {\n return USDC_BY_NETWORK[network]\n}\n\n/**\n * Convert a human-friendly USD amount (e.g. \"0.01\") into atomic USDC units.\n * Fixed-point to avoid float drift — safer than Number math for payments.\n */\nexport function usdToAtomic(amount: string | number, decimals = USDC_DECIMALS): string {\n const str = typeof amount === 'number' ? amount.toString() : amount\n if (!/^\\d+(\\.\\d+)?$/.test(str)) {\n throw new Error(`Invalid amount: ${str}`)\n }\n const [whole, frac = ''] = str.split('.')\n const padded = frac.slice(0, decimals).padEnd(decimals, '0')\n return (BigInt(whole ?? '0') * 10n ** BigInt(decimals) + BigInt(padded || '0')).toString()\n}\n\nconst utf8Encoder = new TextEncoder()\nconst utf8Decoder = new TextDecoder()\n\n/** Base64 encode a JSON value — works in Node 18+ and browsers. */\nexport function encodePayment(value: unknown): string {\n const bytes = utf8Encoder.encode(JSON.stringify(value))\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(bytes).toString('base64')\n }\n let binary = ''\n for (const byte of bytes) binary += String.fromCharCode(byte)\n return btoa(binary)\n}\n\n/** Base64 decode a payment header value back into JSON. */\nexport function decodePayment<T = unknown>(b64: string): T {\n let bytes: Uint8Array\n if (typeof Buffer !== 'undefined') {\n bytes = new Uint8Array(Buffer.from(b64, 'base64'))\n } else {\n const binary = atob(b64)\n bytes = new Uint8Array(binary.length)\n for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i)\n }\n return JSON.parse(utf8Decoder.decode(bytes)) as T\n}\n\n/** Generate a random 32-byte nonce as a 0x-prefixed hex string. */\nexport function randomNonce(): `0x${string}` {\n const bytes = new Uint8Array(32)\n globalThis.crypto.getRandomValues(bytes)\n return ('0x' + Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('')) as `0x${string}`\n}\n","import type { Address, Hex, WalletClient } from 'viem'\nimport type {\n ExactEvmPayload,\n PaymentEnvelopeV2,\n PaymentPayload,\n PaymentRequiredResponse,\n PaymentRequirement,\n X402Network,\n} from './types.js'\nimport { decodePayment, encodePayment, randomNonce } from './utils.js'\n\nexport interface ClientOptions {\n /** A viem WalletClient able to sign EIP-712 typed data. */\n wallet: WalletClient\n /** Underlying fetch to wrap (defaults to global fetch). */\n fetch?: typeof fetch\n /**\n * Hook called before signing. Return `false` to reject the payment.\n * Useful for showing a confirmation UI to the user.\n */\n onPaymentRequired?: (requirement: PaymentRequirement) => boolean | Promise<boolean>\n /** Only allow payments up to this atomic-units cap. Safety belt. */\n maxAmountAtomic?: bigint\n /** Restrict to specific networks (defaults to all). */\n allowedNetworks?: X402Network[]\n}\n\n/**\n * Create a fetch wrapper that transparently handles x402 payments —\n * protocol v1 (\"base\" networks, `maxAmountRequired`, `X-PAYMENT` header)\n * and v2 (CAIP-2 networks, `amount`, `PAYMENT-SIGNATURE` envelope) alike.\n *\n * On a 402 response, it picks the cheapest acceptable requirement,\n * signs an EIP-3009 authorization with the provided wallet, and retries\n * the request with the version-appropriate payment header.\n *\n * @example\n * ```ts\n * const pay = createPaymentClient({ wallet })\n * const res = await pay('https://api.example.com/premium')\n * ```\n */\nexport function createPaymentClient(options: ClientOptions) {\n const baseFetch = options.fetch ?? globalThis.fetch.bind(globalThis)\n\n return async function payFetch(\n input: string | URL | Request,\n init: RequestInit = {},\n ): Promise<Response> {\n const first = await baseFetch(input, init)\n if (first.status !== 402) return first\n\n const requirements = await parsePaymentRequired(first)\n const requirement = selectRequirement(requirements.accepts ?? [], options)\n if (!requirement) {\n throw new PaymentError('No acceptable payment requirement matched client constraints', requirements)\n }\n\n if (options.onPaymentRequired) {\n const approved = await options.onPaymentRequired(requirement)\n if (!approved) throw new PaymentError('Payment rejected by user', requirements)\n }\n\n const payload = await signExactAuthorization(options.wallet, requirement)\n const header = buildPaymentHeader(requirements, requirement, payload)\n const headers = new Headers(init.headers)\n headers.set(header.name, header.value)\n\n return baseFetch(input, { ...init, headers })\n }\n}\n\nexport class PaymentError extends Error {\n readonly requirements?: PaymentRequiredResponse\n constructor(message: string, requirements?: PaymentRequiredResponse) {\n super(message)\n this.name = 'PaymentError'\n this.requirements = requirements\n }\n}\n\n/**\n * Atomic units owed for a requirement, version-agnostic: x402 v2 prices in\n * `amount`, v1 in `maxAmountRequired`. Returns null when absent or\n * unparseable (never throws — selection must be able to skip bad entries).\n */\nexport function requirementAtomicAmount(req: PaymentRequirement): bigint | null {\n const raw = req.amount ?? req.maxAmountRequired\n if (raw == null) return null\n try {\n return BigInt(raw)\n } catch {\n return null\n }\n}\n\nasync function parsePaymentRequired(res: Response): Promise<PaymentRequiredResponse> {\n try {\n return (await res.clone().json()) as PaymentRequiredResponse\n } catch {\n // v2 servers mirror the discovery document base64-encoded in the\n // `payment-required` response header — fall back to it for non-JSON bodies.\n const header = res.headers.get('payment-required')\n if (header) {\n try {\n return decodePayment<PaymentRequiredResponse>(header)\n } catch {\n /* fall through to the error below */\n }\n }\n throw new PaymentError('402 response did not contain a valid x402 discovery body')\n }\n}\n\nfunction selectRequirement(\n accepts: PaymentRequirement[],\n opts: ClientOptions,\n): PaymentRequirement | undefined {\n const priced = accepts\n .filter((a) => a.scheme === 'exact')\n // Only EVM networks this client can sign for (drops e.g. \"solana:…\").\n .filter((a) => chainIdForNetwork(a.network) !== null)\n .filter(\n (a) =>\n !opts.allowedNetworks ||\n opts.allowedNetworks.some((n) => chainIdForNetwork(n) === chainIdForNetwork(a.network)),\n )\n .map((a) => ({ req: a, amount: requirementAtomicAmount(a) }))\n .filter((e): e is { req: PaymentRequirement; amount: bigint } => e.amount !== null)\n .filter((e) => !opts.maxAmountAtomic || e.amount <= opts.maxAmountAtomic)\n\n return priced.sort((a, b) => (a.amount < b.amount ? -1 : 1))[0]?.req\n}\n\n/** Build the version-appropriate payment header for a signed authorization. */\nfunction buildPaymentHeader(\n challenge: PaymentRequiredResponse,\n requirement: PaymentRequirement,\n payload: ExactEvmPayload,\n): { name: string; value: string } {\n const version = challenge.x402Version ?? 1\n if (version >= 2) {\n const envelope: PaymentEnvelopeV2 = {\n x402Version: version,\n resource: challenge.resource,\n accepted: requirement,\n payload,\n extensions: challenge.extensions ?? {},\n }\n return { name: 'PAYMENT-SIGNATURE', value: encodePayment(envelope) }\n }\n const v1: PaymentPayload = {\n x402Version: 1,\n scheme: 'exact',\n network: requirement.network,\n payload,\n }\n return { name: 'X-PAYMENT', value: encodePayment(v1) }\n}\n\n/** Sign an EIP-3009 `TransferWithAuthorization` for the given requirement. */\nexport async function signExactAuthorization(\n wallet: WalletClient,\n requirement: PaymentRequirement,\n): Promise<ExactEvmPayload> {\n const account = wallet.account\n if (!account) throw new PaymentError('Wallet has no account attached')\n\n const value = requirementAtomicAmount(requirement)\n if (value === null) {\n throw new PaymentError('x402 requirement is missing a payment amount')\n }\n const chainId = chainIdForNetwork(requirement.network)\n if (chainId === null) {\n throw new PaymentError(`Unsupported x402 network: ${requirement.network}`)\n }\n\n const now = Math.floor(Date.now() / 1000)\n const validAfter = BigInt(now - 60)\n const validBefore = BigInt(now + (requirement.maxTimeoutSeconds ?? 600))\n const nonce = randomNonce()\n\n const tokenName =\n (requirement.extra?.name as string | undefined) ?? 'USD Coin'\n const tokenVersion =\n (requirement.extra?.version as string | undefined) ?? '2'\n\n const signature = (await wallet.signTypedData({\n account,\n domain: {\n name: tokenName,\n version: tokenVersion,\n chainId,\n verifyingContract: requirement.asset,\n },\n types: {\n TransferWithAuthorization: [\n { name: 'from', type: 'address' },\n { name: 'to', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'validAfter', type: 'uint256' },\n { name: 'validBefore', type: 'uint256' },\n { name: 'nonce', type: 'bytes32' },\n ],\n },\n primaryType: 'TransferWithAuthorization',\n message: {\n from: account.address as Address,\n to: requirement.payTo,\n value,\n validAfter,\n validBefore,\n nonce,\n },\n })) as Hex\n\n return {\n signature,\n authorization: {\n from: account.address as Address,\n to: requirement.payTo,\n value: value.toString(),\n validAfter: validAfter.toString(),\n validBefore: validBefore.toString(),\n nonce,\n },\n }\n}\n\n/**\n * Sign a requirement into the x402 **v1** `X-PAYMENT` payload shape.\n * Kept for back-compat; `createPaymentClient` is version-aware internally.\n */\nexport async function signPayment(\n wallet: WalletClient,\n requirement: PaymentRequirement,\n): Promise<PaymentPayload> {\n return {\n x402Version: 1,\n scheme: 'exact',\n network: requirement.network,\n payload: await signExactAuthorization(wallet, requirement),\n }\n}\n\n/** Resolve a network to an EVM chain id — v1 friendly names and CAIP-2 ids. */\nfunction chainIdForNetwork(network: string): number | null {\n if (network.startsWith('eip155:')) {\n const id = Number(network.slice('eip155:'.length))\n return Number.isInteger(id) && id > 0 ? id : null\n }\n switch (network as X402Network) {\n case 'base':\n return 8453\n case 'base-sepolia':\n return 84532\n case 'ethereum':\n return 1\n case 'optimism':\n return 10\n case 'arbitrum':\n return 42161\n case 'polygon':\n return 137\n default:\n return null\n }\n}\n","/**\n * yeetful/agent — the \"agent expense account.\"\n *\n * Wrap your agent's HTTP calls in a single grant-aware `pay()`. Before any x402\n * payment is signed it enforces a spend grant — an allowlist of hosts plus\n * per-call / per-day / lifetime USD caps and an expiry — then pays via the\n * standard x402 client and emits a receipt for every call.\n *\n * One grant authorizes MANY endpoints (the allowlist). It's a guardrail for\n * your own agents (runaway loops, bugs, prompt-injected tool calls) and the\n * receipt feed behind budgets + audit. Enforcement here is local + instant;\n * for hard, adversarial guarantees back the grant with an on-chain Spend\n * Permission (the wallet contract caps spend regardless of this SDK).\n *\n * @example\n * ```ts\n * import { yeetful } from 'yeetful/agent'\n *\n * const pay = yeetful({\n * wallet, // viem WalletClient\n * grant: {\n * id: 'cmbq…', // hosted grant id (yeetful.com)\n * allow: ['tripadvisor.x402.paysponge.com', 'anthropic.yeetful.com'],\n * perCallUsd: 0.05,\n * perDayUsd: 2,\n * expiresAt: '2026-12-31',\n * },\n * apiKey: process.env.YEETFUL_API_KEY, // yf_… → receipts sync to your dashboard\n * onReceipt: (r) => console.log(r.host, r.amountUsd, r.txHash),\n * })\n *\n * const res = await pay('https://tripadvisor.x402.paysponge.com/api/v1/location/search?searchQuery=tokyo')\n * // throws GrantError on NOT_ALLOWED / OVER_PER_CALL / BUDGET_EXCEEDED / EXPIRED\n * ```\n */\n\nimport type { WalletClient } from 'viem'\nimport { createPaymentClient, PaymentError, requirementAtomicAmount } from './client.js'\nimport { decodePayment } from './utils.js'\nimport type { PaymentRequirement, SettleResult, X402Network } from './types.js'\n\nexport type GrantViolation =\n | 'EXPIRED'\n | 'REVOKED'\n | 'NOT_ALLOWED'\n | 'OVER_PER_CALL'\n | 'BUDGET_EXCEEDED'\n\nexport class GrantError extends Error {\n constructor(\n public code: GrantViolation,\n message: string,\n ) {\n super(message)\n this.name = 'GrantError'\n }\n}\n\n/** A scoped spend authorization (mirrors the hosted SpendGrant). */\nexport interface GrantPolicy {\n /** Optional id of the hosted grant this mirrors. */\n id?: string\n /** Exact hostnames this grant may pay (e.g. \"tripadvisor.x402.paysponge.com\"). */\n allow: string[]\n perCallUsd: number\n perDayUsd: number\n /** Optional lifetime cap across the life of this client instance. */\n totalUsd?: number | null\n /** Unix ms, ISO string, or Date. Omit for no expiry. */\n expiresAt?: number | string | Date\n /** 'active' | 'revoked'. Defaults to active. */\n status?: string\n}\n\n/** A single authorization decision — the audit trail + x402 receipt. */\nexport interface Receipt {\n host: string\n amountUsd: number\n ok: boolean\n txHash?: string\n /** \"settled\" on success, or the GrantViolation code on a denial. */\n note: string\n ts: number\n}\n\nexport interface AgentOptions {\n /** viem WalletClient that signs the EIP-3009 payment. */\n wallet: WalletClient\n /** The spend grant to enforce. */\n grant: GrantPolicy\n /** Underlying fetch (defaults to global fetch). */\n fetch?: typeof fetch\n /** Restrict payments to specific networks (defaults to all). */\n allowedNetworks?: X402Network[]\n /** Called after every decision — wire this to your ledger / dashboard. */\n onReceipt?: (receipt: Receipt) => void | Promise<void>\n /** Human-readable progress logging. */\n onEvent?: (message: string) => void\n /**\n * Yeetful API key (`yf_…`, minted at yeetful.com while signed in). Together\n * with `grant.id` it turns on hosted-ledger sync: every receipt is POSTed to\n * `{ledgerUrl}/api/grants/{grant.id}/ledger` with Bearer auth, so the\n * dashboard's budgets/audit trail include this agent's calls. Sync is\n * best-effort and never blocks or fails a payment.\n */\n apiKey?: string\n /** Base URL of the hosted ledger. Defaults to https://yeetful.com. */\n ledgerUrl?: string\n}\n\nexport interface PayFn {\n (input: string | URL | Request, init?: RequestInit): Promise<Response>\n /** USD spent under this grant since UTC midnight (this client instance). */\n spentTodayUsd(): number\n /** USD remaining in today's budget. */\n remainingTodayUsd(): number\n /** USD spent over the life of this client instance. */\n spentTotalUsd(): number\n /**\n * Resolves once every hosted-ledger sync issued so far has settled (no-op\n * without `apiKey`). Await this before a short-lived script exits so the\n * last receipts aren't dropped with the process.\n */\n flushLedger(): Promise<void>\n}\n\nfunction expiryMs(expiresAt: GrantPolicy['expiresAt']): number {\n if (expiresAt == null) return Infinity\n if (expiresAt instanceof Date) return expiresAt.getTime()\n if (typeof expiresAt === 'number') return expiresAt\n const t = new Date(expiresAt).getTime()\n return Number.isNaN(t) ? Infinity : t\n}\n\nfunction utcDayIndex(ms: number): number {\n return Math.floor(ms / 86_400_000)\n}\n\nfunction hostOf(input: string | URL | Request): string {\n const url = typeof input === 'string' ? input : input instanceof URL ? input.href : input.url\n try {\n return new URL(url).host.toLowerCase()\n } catch {\n return ''\n }\n}\n\n/** Pull the settlement tx hash from the settle header, if present\n * (`PAYMENT-RESPONSE` on x402 v2, `X-PAYMENT-RESPONSE` on v1). */\nfunction txHashOf(res: Response): string | undefined {\n const header = res.headers.get('payment-response') ?? res.headers.get('x-payment-response')\n if (!header) return undefined\n try {\n return decodePayment<SettleResult>(header).transaction\n } catch {\n return undefined\n }\n}\n\n/**\n * Create a grant-aware paid `fetch`. Enforces the grant locally before signing\n * any x402 payment, pays with the wallet, and emits a receipt per call.\n */\nexport function yeetful(options: AgentOptions): PayFn {\n const { wallet, grant, onReceipt, onEvent } = options\n const log = onEvent ?? (() => {})\n\n let spentToday = 0\n let spentTotal = 0\n let dayIndex = utcDayIndex(Date.now())\n\n // ── Hosted-ledger sync (optional): receipts → POST /api/grants/:id/ledger ──\n const ledgerEndpoint =\n options.apiKey && grant.id\n ? `${(options.ledgerUrl ?? 'https://yeetful.com').replace(/\\/+$/, '')}/api/grants/${grant.id}/ledger`\n : null\n if (options.apiKey && !grant.id) {\n log('hosted-ledger sync disabled: grant.id is not set (use the id of your yeetful.com grant)')\n }\n // A chain (not fire-and-forget) so receipts land in order and flushLedger()\n // can await them; one failed POST is logged and never poisons the chain.\n let ledgerChain: Promise<void> = Promise.resolve()\n const ledgerFetch = options.fetch ?? globalThis.fetch\n const sync = (r: Receipt) => {\n if (!ledgerEndpoint) return\n ledgerChain = ledgerChain\n .then(async () => {\n const res = await ledgerFetch(ledgerEndpoint, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n authorization: `Bearer ${options.apiKey}`,\n },\n body: JSON.stringify({\n host: r.host,\n amountUsd: r.amountUsd,\n ok: r.ok,\n txHash: r.txHash,\n note: r.note,\n }),\n })\n if (!res.ok) log(`ledger sync → ${res.status} for ${r.host}`)\n })\n .catch((err) => {\n log(`ledger sync failed for ${r.host}: ${err instanceof Error ? err.message : err}`)\n })\n }\n\n const emit = (r: Receipt) => {\n sync(r)\n void Promise.resolve(onReceipt?.(r)).catch(() => {})\n }\n const deny = (host: string, code: GrantViolation, msg: string): never => {\n emit({ host, amountUsd: 0, ok: false, note: code, ts: Date.now() })\n log(`✗ ${host} — ${code}: ${msg}`)\n throw new GrantError(code, msg)\n }\n\n const pay = async function pay(\n input: string | URL | Request,\n init: RequestInit = {},\n ): Promise<Response> {\n // Roll the daily budget at UTC midnight.\n const today = utcDayIndex(Date.now())\n if (today !== dayIndex) {\n dayIndex = today\n spentToday = 0\n }\n\n const host = hostOf(input)\n\n // ── Pre-flight policy (no network): status → expiry → allowlist ─────────\n if ((grant.status ?? 'active') === 'revoked') deny(host, 'REVOKED', 'grant is revoked')\n if (Date.now() > expiryMs(grant.expiresAt)) deny(host, 'EXPIRED', 'grant has expired')\n if (!grant.allow.map((h) => h.toLowerCase()).includes(host)) {\n deny(host, 'NOT_ALLOWED', `${host} is not in this grant's allowlist`)\n }\n\n // Price is only known from the 402 challenge — check caps in the hook,\n // which runs after the challenge is parsed and before the payment is signed.\n let pricedUsd = 0\n const client = createPaymentClient({\n wallet,\n fetch: options.fetch,\n allowedNetworks: options.allowedNetworks,\n // Per-call enforcement lives in the hook (not maxAmountAtomic) so an\n // over-cap call surfaces a clean GrantError instead of a filtered no-match.\n onPaymentRequired: (req: PaymentRequirement) => {\n // Version-agnostic price (v2 `amount`, v1 `maxAmountRequired`).\n // Selection already dropped unpriced entries, so this can't be null.\n const price = Number(requirementAtomicAmount(req) ?? 0n) / 1e6\n if (price > grant.perCallUsd) {\n deny(host, 'OVER_PER_CALL', `$${price.toFixed(4)} exceeds per-call cap $${grant.perCallUsd}`)\n }\n if (spentToday + price > grant.perDayUsd) {\n deny(host, 'BUDGET_EXCEEDED', `$${(spentToday + price).toFixed(2)} exceeds today's cap $${grant.perDayUsd}`)\n }\n if (grant.totalUsd != null && spentTotal + price > grant.totalUsd) {\n deny(host, 'BUDGET_EXCEEDED', `$${(spentTotal + price).toFixed(2)} exceeds lifetime cap $${grant.totalUsd}`)\n }\n pricedUsd = price\n return true\n },\n })\n\n let res: Response\n try {\n res = await client(input, init)\n } catch (err) {\n if (err instanceof GrantError) throw err // already denied + receipted\n // A rejection from the underlying client (e.g. no acceptable requirement).\n const note = err instanceof PaymentError ? 'payment-failed' : 'error'\n emit({ host, amountUsd: 0, ok: false, note, ts: Date.now() })\n throw err\n }\n\n // Settled (or a free, non-402 call where pricedUsd stayed 0).\n if (pricedUsd > 0) {\n spentToday += pricedUsd\n spentTotal += pricedUsd\n }\n const txHash = txHashOf(res)\n emit({ host, amountUsd: pricedUsd, ok: true, txHash, note: 'settled', ts: Date.now() })\n log(`✓ ${host} — $${pricedUsd.toFixed(4)} · today $${spentToday.toFixed(2)}/$${grant.perDayUsd}`)\n return res\n } as PayFn\n\n pay.spentTodayUsd = () => spentToday\n pay.remainingTodayUsd = () => Math.max(0, grant.perDayUsd - spentToday)\n pay.spentTotalUsd = () => spentTotal\n pay.flushLedger = () => ledgerChain\n return pay\n}\n","import type {\n FacilitatorConfig,\n PaymentPayload,\n PaymentRequirement,\n SettleResult,\n VerifyResult,\n} from './types.js'\n\n/**\n * Thin wrapper around an x402 facilitator HTTP service.\n * The facilitator verifies signed payment authorizations and settles them on-chain.\n */\nexport class Facilitator {\n private readonly url: string\n private readonly authHeader?: string\n private readonly fetcher: typeof fetch\n\n constructor(config: FacilitatorConfig) {\n this.url = config.url.replace(/\\/$/, '')\n this.authHeader = config.authHeader\n this.fetcher = config.fetch ?? globalThis.fetch.bind(globalThis)\n }\n\n async verify(\n payment: PaymentPayload,\n requirement: PaymentRequirement,\n ): Promise<VerifyResult> {\n return this.post<VerifyResult>('/verify', { paymentPayload: payment, paymentRequirements: requirement })\n }\n\n async settle(\n payment: PaymentPayload,\n requirement: PaymentRequirement,\n ): Promise<SettleResult> {\n return this.post<SettleResult>('/settle', { paymentPayload: payment, paymentRequirements: requirement })\n }\n\n private async post<T>(path: string, body: unknown): Promise<T> {\n const res = await this.fetcher(this.url + path, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n ...(this.authHeader ? { authorization: this.authHeader } : {}),\n },\n body: JSON.stringify(body),\n })\n if (!res.ok) {\n const text = await res.text().catch(() => '')\n throw new Error(`Facilitator ${path} failed: ${res.status} ${text}`)\n }\n return (await res.json()) as T\n }\n}\n\n/** Default hosted facilitator. Override for self-hosted deployments. */\nexport const DEFAULT_FACILITATOR_URL = 'https://facilitator.yeetful.com'\n","import type { Address } from 'viem'\nimport { Facilitator, DEFAULT_FACILITATOR_URL } from './facilitator.js'\nimport type {\n FacilitatorConfig,\n PaymentPayload,\n PaymentRequirement,\n PaymentRequiredResponse,\n SettleResult,\n X402Network,\n} from './types.js'\nimport { decodePayment, encodePayment, usdcAddress, usdToAtomic } from './utils.js'\n\nexport interface RouteGateOptions {\n /** Price in USD, e.g. \"0.01\". Converted to USDC atomic units. */\n price: string | number\n /** Recipient address that receives the funds. */\n recipient: Address\n /** Network(s) to accept. Defaults to `['base']`. Pass an array for multi-chain. */\n network?: X402Network | X402Network[]\n /** Override the payment asset (defaults to USDC for the given network). */\n asset?: Address\n /** Human-readable description of the resource. */\n description?: string\n /** Seconds the signed authorization is valid. Default: 600. */\n maxTimeoutSeconds?: number\n /** Facilitator config, or `false` to skip verification/settlement (trust-mode). */\n facilitator?: FacilitatorConfig | false\n /**\n * Optional resource identifier (defaults to the request URL). Useful for\n * logging / receipts.\n */\n resource?: string\n}\n\n/**\n * Runtime-agnostic gate: given a Fetch-API `Request`, either returns a 402\n * `Response` or a `{ settle }` handle. After your handler runs, call `settle()`\n * to finalize the payment and get a `X-PAYMENT-RESPONSE` header to attach.\n *\n * This is the building block used by the framework adapters (`./next`, `./express`).\n */\nexport async function gate(\n request: Request,\n opts: RouteGateOptions,\n): Promise<\n | { type: 'paymentRequired'; response: Response }\n | { type: 'ok'; payer: Address; settle: () => Promise<{ header: string; result: SettleResult }> }\n> {\n const requirements = buildRequirements(request, opts)\n\n const header = request.headers.get('x-payment') ?? request.headers.get('X-PAYMENT')\n if (!header) {\n return { type: 'paymentRequired', response: paymentRequiredResponse(requirements) }\n }\n\n let payment: PaymentPayload\n try {\n payment = decodePayment<PaymentPayload>(header)\n } catch {\n return {\n type: 'paymentRequired',\n response: paymentRequiredResponse(requirements, 'Invalid X-PAYMENT header'),\n }\n }\n\n const matched = requirements.find(\n (r) => r.network === payment.network && r.scheme === payment.scheme,\n )\n if (!matched) {\n return {\n type: 'paymentRequired',\n response: paymentRequiredResponse(requirements, 'Payment does not match any accepted requirement'),\n }\n }\n\n if (opts.facilitator === false) {\n const payer = payment.payload.authorization.from as Address\n return {\n type: 'ok',\n payer,\n settle: async () => ({\n header: encodePayment({ success: true, network: matched.network }),\n result: { success: true },\n }),\n }\n }\n\n const facilitator = new Facilitator(opts.facilitator ?? { url: DEFAULT_FACILITATOR_URL })\n const verified = await facilitator.verify(payment, matched)\n if (!verified.isValid) {\n return {\n type: 'paymentRequired',\n response: paymentRequiredResponse(\n requirements,\n verified.invalidReason ?? 'Payment verification failed',\n ),\n }\n }\n\n const payer = (verified.payer ?? payment.payload.authorization.from) as Address\n\n return {\n type: 'ok',\n payer,\n settle: async () => {\n const result = await facilitator.settle(payment, matched)\n return {\n header: encodePayment({\n success: result.success,\n transaction: result.transaction,\n network: result.network ?? matched.network,\n errorReason: result.errorReason,\n payer,\n }),\n result,\n }\n },\n }\n}\n\nfunction buildRequirements(request: Request, opts: RouteGateOptions): PaymentRequirement[] {\n const networks = Array.isArray(opts.network) ? opts.network : [opts.network ?? 'base']\n const atomic = usdToAtomic(opts.price)\n const resource = opts.resource ?? request.url\n\n return networks.map((network) => ({\n scheme: 'exact',\n network,\n asset: opts.asset ?? usdcAddress(network),\n maxAmountRequired: atomic,\n payTo: opts.recipient,\n description: opts.description,\n resource,\n maxTimeoutSeconds: opts.maxTimeoutSeconds ?? 600,\n extra: { name: 'USD Coin', version: '2' },\n }))\n}\n\nfunction paymentRequiredResponse(\n accepts: PaymentRequirement[],\n error?: string,\n): Response {\n const body: PaymentRequiredResponse = { x402Version: 1, accepts, ...(error ? { error } : {}) }\n return new Response(JSON.stringify(body), {\n status: 402,\n headers: { 'content-type': 'application/json' },\n })\n}\n\nexport { Facilitator, DEFAULT_FACILITATOR_URL } from './facilitator.js'\n"]}
1
+ {"version":3,"sources":["../src/utils.ts","../src/client.ts","../src/agent.ts","../src/facilitator.ts","../src/server.ts"],"names":["pay","payer"],"mappings":"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","file":"index.js","sourcesContent":["import type { X402Network } from './types.js'\n\nconst USDC_BY_NETWORK: Record<X402Network, `0x${string}`> = {\n base: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n 'base-sepolia': '0x036CbD53842c5426634e7929541eC2318f3dCF7e',\n ethereum: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n optimism: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85',\n arbitrum: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',\n polygon: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n}\n\nexport const USDC_DECIMALS = 6\n\n/** Returns the canonical USDC contract address for a supported network. */\nexport function usdcAddress(network: X402Network): `0x${string}` {\n return USDC_BY_NETWORK[network]\n}\n\n/**\n * Convert a human-friendly USD amount (e.g. \"0.01\") into atomic USDC units.\n * Fixed-point to avoid float drift — safer than Number math for payments.\n */\nexport function usdToAtomic(amount: string | number, decimals = USDC_DECIMALS): string {\n const str = typeof amount === 'number' ? amount.toString() : amount\n if (!/^\\d+(\\.\\d+)?$/.test(str)) {\n throw new Error(`Invalid amount: ${str}`)\n }\n const [whole, frac = ''] = str.split('.')\n const padded = frac.slice(0, decimals).padEnd(decimals, '0')\n return (BigInt(whole ?? '0') * 10n ** BigInt(decimals) + BigInt(padded || '0')).toString()\n}\n\nconst utf8Encoder = new TextEncoder()\nconst utf8Decoder = new TextDecoder()\n\n/** Base64 encode a JSON value — works in Node 18+ and browsers. */\nexport function encodePayment(value: unknown): string {\n const bytes = utf8Encoder.encode(JSON.stringify(value))\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(bytes).toString('base64')\n }\n let binary = ''\n for (const byte of bytes) binary += String.fromCharCode(byte)\n return btoa(binary)\n}\n\n/** Base64 decode a payment header value back into JSON. */\nexport function decodePayment<T = unknown>(b64: string): T {\n let bytes: Uint8Array\n if (typeof Buffer !== 'undefined') {\n bytes = new Uint8Array(Buffer.from(b64, 'base64'))\n } else {\n const binary = atob(b64)\n bytes = new Uint8Array(binary.length)\n for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i)\n }\n return JSON.parse(utf8Decoder.decode(bytes)) as T\n}\n\n/** Generate a random 32-byte nonce as a 0x-prefixed hex string. */\nexport function randomNonce(): `0x${string}` {\n const bytes = new Uint8Array(32)\n globalThis.crypto.getRandomValues(bytes)\n return ('0x' + Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('')) as `0x${string}`\n}\n","import type { Address, Hex, WalletClient } from 'viem'\nimport type {\n ExactEvmPayload,\n PaymentEnvelopeV2,\n PaymentPayload,\n PaymentRequiredResponse,\n PaymentRequirement,\n X402Network,\n} from './types.js'\nimport { decodePayment, encodePayment, randomNonce } from './utils.js'\n\nexport interface ClientOptions {\n /** A viem WalletClient able to sign EIP-712 typed data. */\n wallet: WalletClient\n /** Underlying fetch to wrap (defaults to global fetch). */\n fetch?: typeof fetch\n /**\n * Hook called before signing. Return `false` to reject the payment.\n * Useful for showing a confirmation UI to the user.\n */\n onPaymentRequired?: (requirement: PaymentRequirement) => boolean | Promise<boolean>\n /** Only allow payments up to this atomic-units cap. Safety belt. */\n maxAmountAtomic?: bigint\n /** Restrict to specific networks (defaults to all). */\n allowedNetworks?: X402Network[]\n}\n\n/**\n * Create a fetch wrapper that transparently handles x402 payments —\n * protocol v1 (\"base\" networks, `maxAmountRequired`, `X-PAYMENT` header)\n * and v2 (CAIP-2 networks, `amount`, `PAYMENT-SIGNATURE` envelope) alike.\n *\n * On a 402 response, it picks the cheapest acceptable requirement,\n * signs an EIP-3009 authorization with the provided wallet, and retries\n * the request with the version-appropriate payment header.\n *\n * @example\n * ```ts\n * const pay = createPaymentClient({ wallet })\n * const res = await pay('https://api.example.com/premium')\n * ```\n */\nexport function createPaymentClient(options: ClientOptions) {\n const baseFetch = options.fetch ?? globalThis.fetch.bind(globalThis)\n\n return async function payFetch(\n input: string | URL | Request,\n init: RequestInit = {},\n ): Promise<Response> {\n const first = await baseFetch(input, init)\n if (first.status !== 402) return first\n\n const requirements = await parsePaymentRequired(first)\n const requirement = selectRequirement(requirements.accepts ?? [], options)\n if (!requirement) {\n throw new PaymentError('No acceptable payment requirement matched client constraints', requirements)\n }\n\n if (options.onPaymentRequired) {\n const approved = await options.onPaymentRequired(requirement)\n if (!approved) throw new PaymentError('Payment rejected by user', requirements)\n }\n\n const payload = await signExactAuthorization(options.wallet, requirement)\n const header = buildPaymentHeader(requirements, requirement, payload)\n const headers = new Headers(init.headers)\n headers.set(header.name, header.value)\n\n return baseFetch(input, { ...init, headers })\n }\n}\n\nexport class PaymentError extends Error {\n readonly requirements?: PaymentRequiredResponse\n constructor(message: string, requirements?: PaymentRequiredResponse) {\n super(message)\n this.name = 'PaymentError'\n this.requirements = requirements\n }\n}\n\n/**\n * Atomic units owed for a requirement, version-agnostic: x402 v2 prices in\n * `amount`, v1 in `maxAmountRequired`. Returns null when absent or\n * unparseable (never throws — selection must be able to skip bad entries).\n */\nexport function requirementAtomicAmount(req: PaymentRequirement): bigint | null {\n const raw = req.amount ?? req.maxAmountRequired\n if (raw == null) return null\n try {\n return BigInt(raw)\n } catch {\n return null\n }\n}\n\nasync function parsePaymentRequired(res: Response): Promise<PaymentRequiredResponse> {\n try {\n return (await res.clone().json()) as PaymentRequiredResponse\n } catch {\n // v2 servers mirror the discovery document base64-encoded in the\n // `payment-required` response header — fall back to it for non-JSON bodies.\n const header = res.headers.get('payment-required')\n if (header) {\n try {\n return decodePayment<PaymentRequiredResponse>(header)\n } catch {\n /* fall through to the error below */\n }\n }\n throw new PaymentError('402 response did not contain a valid x402 discovery body')\n }\n}\n\nfunction selectRequirement(\n accepts: PaymentRequirement[],\n opts: ClientOptions,\n): PaymentRequirement | undefined {\n const priced = accepts\n .filter((a) => a.scheme === 'exact')\n // Only EVM networks this client can sign for (drops e.g. \"solana:…\").\n .filter((a) => chainIdForNetwork(a.network) !== null)\n .filter(\n (a) =>\n !opts.allowedNetworks ||\n opts.allowedNetworks.some((n) => chainIdForNetwork(n) === chainIdForNetwork(a.network)),\n )\n .map((a) => ({ req: a, amount: requirementAtomicAmount(a) }))\n .filter((e): e is { req: PaymentRequirement; amount: bigint } => e.amount !== null)\n .filter((e) => !opts.maxAmountAtomic || e.amount <= opts.maxAmountAtomic)\n\n return priced.sort((a, b) => (a.amount < b.amount ? -1 : 1))[0]?.req\n}\n\n/** Build the version-appropriate payment header for a signed authorization. */\nfunction buildPaymentHeader(\n challenge: PaymentRequiredResponse,\n requirement: PaymentRequirement,\n payload: ExactEvmPayload,\n): { name: string; value: string } {\n const version = challenge.x402Version ?? 1\n if (version >= 2) {\n const envelope: PaymentEnvelopeV2 = {\n x402Version: version,\n resource: challenge.resource,\n accepted: requirement,\n payload,\n extensions: challenge.extensions ?? {},\n }\n return { name: 'PAYMENT-SIGNATURE', value: encodePayment(envelope) }\n }\n const v1: PaymentPayload = {\n x402Version: 1,\n scheme: 'exact',\n network: requirement.network,\n payload,\n }\n return { name: 'X-PAYMENT', value: encodePayment(v1) }\n}\n\n/** Sign an EIP-3009 `TransferWithAuthorization` for the given requirement. */\nexport async function signExactAuthorization(\n wallet: WalletClient,\n requirement: PaymentRequirement,\n): Promise<ExactEvmPayload> {\n const account = wallet.account\n if (!account) throw new PaymentError('Wallet has no account attached')\n\n const value = requirementAtomicAmount(requirement)\n if (value === null) {\n throw new PaymentError('x402 requirement is missing a payment amount')\n }\n const chainId = chainIdForNetwork(requirement.network)\n if (chainId === null) {\n throw new PaymentError(`Unsupported x402 network: ${requirement.network}`)\n }\n\n const now = Math.floor(Date.now() / 1000)\n const validAfter = BigInt(now - 60)\n const validBefore = BigInt(now + (requirement.maxTimeoutSeconds ?? 600))\n const nonce = randomNonce()\n\n const tokenName =\n (requirement.extra?.name as string | undefined) ?? 'USD Coin'\n const tokenVersion =\n (requirement.extra?.version as string | undefined) ?? '2'\n\n const signature = (await wallet.signTypedData({\n account,\n domain: {\n name: tokenName,\n version: tokenVersion,\n chainId,\n verifyingContract: requirement.asset,\n },\n types: {\n TransferWithAuthorization: [\n { name: 'from', type: 'address' },\n { name: 'to', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'validAfter', type: 'uint256' },\n { name: 'validBefore', type: 'uint256' },\n { name: 'nonce', type: 'bytes32' },\n ],\n },\n primaryType: 'TransferWithAuthorization',\n message: {\n from: account.address as Address,\n to: requirement.payTo,\n value,\n validAfter,\n validBefore,\n nonce,\n },\n })) as Hex\n\n return {\n signature,\n authorization: {\n from: account.address as Address,\n to: requirement.payTo,\n value: value.toString(),\n validAfter: validAfter.toString(),\n validBefore: validBefore.toString(),\n nonce,\n },\n }\n}\n\n/**\n * Sign a requirement into the x402 **v1** `X-PAYMENT` payload shape.\n * Kept for back-compat; `createPaymentClient` is version-aware internally.\n */\nexport async function signPayment(\n wallet: WalletClient,\n requirement: PaymentRequirement,\n): Promise<PaymentPayload> {\n return {\n x402Version: 1,\n scheme: 'exact',\n network: requirement.network,\n payload: await signExactAuthorization(wallet, requirement),\n }\n}\n\n/** Resolve a network to an EVM chain id — v1 friendly names and CAIP-2 ids. */\nfunction chainIdForNetwork(network: string): number | null {\n if (network.startsWith('eip155:')) {\n const id = Number(network.slice('eip155:'.length))\n return Number.isInteger(id) && id > 0 ? id : null\n }\n switch (network as X402Network) {\n case 'base':\n return 8453\n case 'base-sepolia':\n return 84532\n case 'ethereum':\n return 1\n case 'optimism':\n return 10\n case 'arbitrum':\n return 42161\n case 'polygon':\n return 137\n default:\n return null\n }\n}\n","/**\n * yeetful/agent — the \"agent expense account.\"\n *\n * Wrap your agent's HTTP calls in a single grant-aware `pay()`. Before any x402\n * payment is signed it enforces a spend grant — an allowlist of hosts plus\n * per-call / per-day / lifetime USD caps and an expiry — then pays via the\n * standard x402 client and emits a receipt for every call.\n *\n * One grant authorizes MANY endpoints (the allowlist). It's a guardrail for\n * your own agents (runaway loops, bugs, prompt-injected tool calls) and the\n * receipt feed behind budgets + audit. Enforcement here is local + instant;\n * for hard, adversarial guarantees back the grant with an on-chain Spend\n * Permission (the wallet contract caps spend regardless of this SDK).\n *\n * @example\n * ```ts\n * import { yeetful } from 'yeetful/agent'\n *\n * const pay = yeetful({\n * wallet, // viem WalletClient\n * grant: {\n * id: 'cmbq…', // hosted grant id (yeetful.com)\n * allow: ['tripadvisor.x402.paysponge.com', 'anthropic.yeetful.com'],\n * perCallUsd: 0.05,\n * perDayUsd: 2,\n * expiresAt: '2026-12-31',\n * },\n * apiKey: process.env.YEETFUL_API_KEY, // yf_… → receipts sync to your dashboard\n * onReceipt: (r) => console.log(r.host, r.amountUsd, r.txHash),\n * })\n *\n * const res = await pay('https://tripadvisor.x402.paysponge.com/api/v1/location/search?searchQuery=tokyo')\n * // throws GrantError on NOT_ALLOWED / OVER_PER_CALL / BUDGET_EXCEEDED / EXPIRED\n * ```\n */\n\nimport type { WalletClient } from 'viem'\nimport { createPaymentClient, PaymentError, requirementAtomicAmount } from './client.js'\nimport { decodePayment } from './utils.js'\nimport type { PaymentRequirement, SettleResult, X402Network } from './types.js'\n\nexport type GrantViolation =\n | 'EXPIRED'\n | 'REVOKED'\n | 'NOT_ALLOWED'\n | 'OVER_PER_CALL'\n | 'BUDGET_EXCEEDED'\n\nexport class GrantError extends Error {\n constructor(\n public code: GrantViolation,\n message: string,\n ) {\n super(message)\n this.name = 'GrantError'\n }\n}\n\n/** A scoped spend authorization (mirrors the hosted SpendGrant). */\nexport interface GrantPolicy {\n /** Optional id of the hosted grant this mirrors. */\n id?: string\n /** Exact hostnames this grant may pay (e.g. \"tripadvisor.x402.paysponge.com\"). */\n allow: string[]\n perCallUsd: number\n perDayUsd: number\n /** Optional lifetime cap across the life of this client instance. */\n totalUsd?: number | null\n /** Unix ms, ISO string, or Date. Omit for no expiry. */\n expiresAt?: number | string | Date\n /** 'active' | 'revoked'. Defaults to active. */\n status?: string\n}\n\n/** A single authorization decision — the audit trail + x402 receipt. */\nexport interface Receipt {\n host: string\n amountUsd: number\n ok: boolean\n txHash?: string\n /** \"settled\" on success, or the GrantViolation code on a denial. */\n note: string\n ts: number\n}\n\nexport interface AgentOptions {\n /** viem WalletClient that signs the EIP-3009 payment. */\n wallet: WalletClient\n /** The spend grant to enforce. */\n grant: GrantPolicy\n /** Underlying fetch (defaults to global fetch). */\n fetch?: typeof fetch\n /** Restrict payments to specific networks (defaults to all). */\n allowedNetworks?: X402Network[]\n /** Called after every decision — wire this to your ledger / dashboard. */\n onReceipt?: (receipt: Receipt) => void | Promise<void>\n /** Human-readable progress logging. */\n onEvent?: (message: string) => void\n /**\n * Yeetful API key (`yf_…`, minted at yeetful.com while signed in). Together\n * with `grant.id` it turns on hosted-ledger sync: every receipt is POSTed to\n * `{ledgerUrl}/api/grants/{grant.id}/ledger` with Bearer auth, so the\n * dashboard's budgets/audit trail include this agent's calls. Sync is\n * best-effort and never blocks or fails a payment.\n */\n apiKey?: string\n /** Base URL of the hosted ledger. Defaults to https://yeetful.com. */\n ledgerUrl?: string\n}\n\nexport interface PayFn {\n (input: string | URL | Request, init?: RequestInit): Promise<Response>\n /** USD spent under this grant since UTC midnight (this client instance). */\n spentTodayUsd(): number\n /** USD remaining in today's budget. */\n remainingTodayUsd(): number\n /** USD spent over the life of this client instance. */\n spentTotalUsd(): number\n /**\n * Resolves once every hosted-ledger sync issued so far has settled (no-op\n * without `apiKey`). Await this before a short-lived script exits so the\n * last receipts aren't dropped with the process.\n */\n flushLedger(): Promise<void>\n}\n\nfunction expiryMs(expiresAt: GrantPolicy['expiresAt']): number {\n if (expiresAt == null) return Infinity\n if (expiresAt instanceof Date) return expiresAt.getTime()\n if (typeof expiresAt === 'number') return expiresAt\n const t = new Date(expiresAt).getTime()\n return Number.isNaN(t) ? Infinity : t\n}\n\nfunction utcDayIndex(ms: number): number {\n return Math.floor(ms / 86_400_000)\n}\n\nfunction hostOf(input: string | URL | Request): string {\n const url = typeof input === 'string' ? input : input instanceof URL ? input.href : input.url\n try {\n return new URL(url).host.toLowerCase()\n } catch {\n return ''\n }\n}\n\n/** Pull the settlement tx hash from the settle header, if present\n * (`PAYMENT-RESPONSE` on x402 v2, `X-PAYMENT-RESPONSE` on v1). */\nfunction txHashOf(res: Response): string | undefined {\n const header = res.headers.get('payment-response') ?? res.headers.get('x-payment-response')\n if (!header) return undefined\n try {\n return decodePayment<SettleResult>(header).transaction\n } catch {\n return undefined\n }\n}\n\n/**\n * Create a grant-aware paid `fetch`. Enforces the grant locally before signing\n * any x402 payment, pays with the wallet, and emits a receipt per call.\n */\nexport function yeetful(options: AgentOptions): PayFn {\n const { wallet, grant, onReceipt, onEvent } = options\n const log = onEvent ?? (() => {})\n\n let spentToday = 0\n let spentTotal = 0\n let dayIndex = utcDayIndex(Date.now())\n\n // ── Hosted-ledger sync (optional): receipts → POST /api/grants/:id/ledger ──\n const ledgerEndpoint =\n options.apiKey && grant.id\n ? `${(options.ledgerUrl ?? 'https://yeetful.com').replace(/\\/+$/, '')}/api/grants/${grant.id}/ledger`\n : null\n if (options.apiKey && !grant.id) {\n log('hosted-ledger sync disabled: grant.id is not set (use the id of your yeetful.com grant)')\n }\n // A chain (not fire-and-forget) so receipts land in order and flushLedger()\n // can await them; one failed POST is logged and never poisons the chain.\n let ledgerChain: Promise<void> = Promise.resolve()\n const ledgerFetch = options.fetch ?? globalThis.fetch\n const sync = (r: Receipt) => {\n if (!ledgerEndpoint) return\n ledgerChain = ledgerChain\n .then(async () => {\n const res = await ledgerFetch(ledgerEndpoint, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n authorization: `Bearer ${options.apiKey}`,\n },\n body: JSON.stringify({\n host: r.host,\n amountUsd: r.amountUsd,\n ok: r.ok,\n txHash: r.txHash,\n note: r.note,\n }),\n })\n if (!res.ok) {\n // fetch silently DROPS the Authorization header when it follows a\n // cross-origin redirect (e.g. apex → www) — surface the real cause.\n const moved = res.redirected\n ? ` (request was redirected to ${new URL(res.url).origin}, which strips the auth header — set ledgerUrl to that origin)`\n : ''\n log(`ledger sync → ${res.status} for ${r.host}${moved}`)\n }\n })\n .catch((err) => {\n log(`ledger sync failed for ${r.host}: ${err instanceof Error ? err.message : err}`)\n })\n }\n\n const emit = (r: Receipt) => {\n sync(r)\n void Promise.resolve(onReceipt?.(r)).catch(() => {})\n }\n const deny = (host: string, code: GrantViolation, msg: string): never => {\n emit({ host, amountUsd: 0, ok: false, note: code, ts: Date.now() })\n log(`✗ ${host} — ${code}: ${msg}`)\n throw new GrantError(code, msg)\n }\n\n const pay = async function pay(\n input: string | URL | Request,\n init: RequestInit = {},\n ): Promise<Response> {\n // Roll the daily budget at UTC midnight.\n const today = utcDayIndex(Date.now())\n if (today !== dayIndex) {\n dayIndex = today\n spentToday = 0\n }\n\n const host = hostOf(input)\n\n // ── Pre-flight policy (no network): status → expiry → allowlist ─────────\n if ((grant.status ?? 'active') === 'revoked') deny(host, 'REVOKED', 'grant is revoked')\n if (Date.now() > expiryMs(grant.expiresAt)) deny(host, 'EXPIRED', 'grant has expired')\n if (!grant.allow.map((h) => h.toLowerCase()).includes(host)) {\n deny(host, 'NOT_ALLOWED', `${host} is not in this grant's allowlist`)\n }\n\n // Price is only known from the 402 challenge — check caps in the hook,\n // which runs after the challenge is parsed and before the payment is signed.\n let pricedUsd = 0\n const client = createPaymentClient({\n wallet,\n fetch: options.fetch,\n allowedNetworks: options.allowedNetworks,\n // Per-call enforcement lives in the hook (not maxAmountAtomic) so an\n // over-cap call surfaces a clean GrantError instead of a filtered no-match.\n onPaymentRequired: (req: PaymentRequirement) => {\n // Version-agnostic price (v2 `amount`, v1 `maxAmountRequired`).\n // Selection already dropped unpriced entries, so this can't be null.\n const price = Number(requirementAtomicAmount(req) ?? 0n) / 1e6\n if (price > grant.perCallUsd) {\n deny(host, 'OVER_PER_CALL', `$${price.toFixed(4)} exceeds per-call cap $${grant.perCallUsd}`)\n }\n if (spentToday + price > grant.perDayUsd) {\n deny(host, 'BUDGET_EXCEEDED', `$${(spentToday + price).toFixed(2)} exceeds today's cap $${grant.perDayUsd}`)\n }\n if (grant.totalUsd != null && spentTotal + price > grant.totalUsd) {\n deny(host, 'BUDGET_EXCEEDED', `$${(spentTotal + price).toFixed(2)} exceeds lifetime cap $${grant.totalUsd}`)\n }\n pricedUsd = price\n return true\n },\n })\n\n let res: Response\n try {\n res = await client(input, init)\n } catch (err) {\n if (err instanceof GrantError) throw err // already denied + receipted\n // A rejection from the underlying client (e.g. no acceptable requirement).\n const note = err instanceof PaymentError ? 'payment-failed' : 'error'\n emit({ host, amountUsd: 0, ok: false, note, ts: Date.now() })\n throw err\n }\n\n // Settled (or a free, non-402 call where pricedUsd stayed 0).\n if (pricedUsd > 0) {\n spentToday += pricedUsd\n spentTotal += pricedUsd\n }\n const txHash = txHashOf(res)\n emit({ host, amountUsd: pricedUsd, ok: true, txHash, note: 'settled', ts: Date.now() })\n log(`✓ ${host} — $${pricedUsd.toFixed(4)} · today $${spentToday.toFixed(2)}/$${grant.perDayUsd}`)\n return res\n } as PayFn\n\n pay.spentTodayUsd = () => spentToday\n pay.remainingTodayUsd = () => Math.max(0, grant.perDayUsd - spentToday)\n pay.spentTotalUsd = () => spentTotal\n pay.flushLedger = () => ledgerChain\n return pay\n}\n","import type {\n FacilitatorConfig,\n PaymentPayload,\n PaymentRequirement,\n SettleResult,\n VerifyResult,\n} from './types.js'\n\n/**\n * Thin wrapper around an x402 facilitator HTTP service.\n * The facilitator verifies signed payment authorizations and settles them on-chain.\n */\nexport class Facilitator {\n private readonly url: string\n private readonly authHeader?: string\n private readonly fetcher: typeof fetch\n\n constructor(config: FacilitatorConfig) {\n this.url = config.url.replace(/\\/$/, '')\n this.authHeader = config.authHeader\n this.fetcher = config.fetch ?? globalThis.fetch.bind(globalThis)\n }\n\n async verify(\n payment: PaymentPayload,\n requirement: PaymentRequirement,\n ): Promise<VerifyResult> {\n return this.post<VerifyResult>('/verify', { paymentPayload: payment, paymentRequirements: requirement })\n }\n\n async settle(\n payment: PaymentPayload,\n requirement: PaymentRequirement,\n ): Promise<SettleResult> {\n return this.post<SettleResult>('/settle', { paymentPayload: payment, paymentRequirements: requirement })\n }\n\n private async post<T>(path: string, body: unknown): Promise<T> {\n const res = await this.fetcher(this.url + path, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n ...(this.authHeader ? { authorization: this.authHeader } : {}),\n },\n body: JSON.stringify(body),\n })\n if (!res.ok) {\n const text = await res.text().catch(() => '')\n throw new Error(`Facilitator ${path} failed: ${res.status} ${text}`)\n }\n return (await res.json()) as T\n }\n}\n\n/** Default hosted facilitator. Override for self-hosted deployments. */\nexport const DEFAULT_FACILITATOR_URL = 'https://facilitator.yeetful.com'\n","import type { Address } from 'viem'\nimport { Facilitator, DEFAULT_FACILITATOR_URL } from './facilitator.js'\nimport type {\n FacilitatorConfig,\n PaymentPayload,\n PaymentRequirement,\n PaymentRequiredResponse,\n SettleResult,\n X402Network,\n} from './types.js'\nimport { decodePayment, encodePayment, usdcAddress, usdToAtomic } from './utils.js'\n\nexport interface RouteGateOptions {\n /** Price in USD, e.g. \"0.01\". Converted to USDC atomic units. */\n price: string | number\n /** Recipient address that receives the funds. */\n recipient: Address\n /** Network(s) to accept. Defaults to `['base']`. Pass an array for multi-chain. */\n network?: X402Network | X402Network[]\n /** Override the payment asset (defaults to USDC for the given network). */\n asset?: Address\n /** Human-readable description of the resource. */\n description?: string\n /** Seconds the signed authorization is valid. Default: 600. */\n maxTimeoutSeconds?: number\n /** Facilitator config, or `false` to skip verification/settlement (trust-mode). */\n facilitator?: FacilitatorConfig | false\n /**\n * Optional resource identifier (defaults to the request URL). Useful for\n * logging / receipts.\n */\n resource?: string\n}\n\n/**\n * Runtime-agnostic gate: given a Fetch-API `Request`, either returns a 402\n * `Response` or a `{ settle }` handle. After your handler runs, call `settle()`\n * to finalize the payment and get a `X-PAYMENT-RESPONSE` header to attach.\n *\n * This is the building block used by the framework adapters (`./next`, `./express`).\n */\nexport async function gate(\n request: Request,\n opts: RouteGateOptions,\n): Promise<\n | { type: 'paymentRequired'; response: Response }\n | { type: 'ok'; payer: Address; settle: () => Promise<{ header: string; result: SettleResult }> }\n> {\n const requirements = buildRequirements(request, opts)\n\n const header = request.headers.get('x-payment') ?? request.headers.get('X-PAYMENT')\n if (!header) {\n return { type: 'paymentRequired', response: paymentRequiredResponse(requirements) }\n }\n\n let payment: PaymentPayload\n try {\n payment = decodePayment<PaymentPayload>(header)\n } catch {\n return {\n type: 'paymentRequired',\n response: paymentRequiredResponse(requirements, 'Invalid X-PAYMENT header'),\n }\n }\n\n const matched = requirements.find(\n (r) => r.network === payment.network && r.scheme === payment.scheme,\n )\n if (!matched) {\n return {\n type: 'paymentRequired',\n response: paymentRequiredResponse(requirements, 'Payment does not match any accepted requirement'),\n }\n }\n\n if (opts.facilitator === false) {\n const payer = payment.payload.authorization.from as Address\n return {\n type: 'ok',\n payer,\n settle: async () => ({\n header: encodePayment({ success: true, network: matched.network }),\n result: { success: true },\n }),\n }\n }\n\n const facilitator = new Facilitator(opts.facilitator ?? { url: DEFAULT_FACILITATOR_URL })\n const verified = await facilitator.verify(payment, matched)\n if (!verified.isValid) {\n return {\n type: 'paymentRequired',\n response: paymentRequiredResponse(\n requirements,\n verified.invalidReason ?? 'Payment verification failed',\n ),\n }\n }\n\n const payer = (verified.payer ?? payment.payload.authorization.from) as Address\n\n return {\n type: 'ok',\n payer,\n settle: async () => {\n const result = await facilitator.settle(payment, matched)\n return {\n header: encodePayment({\n success: result.success,\n transaction: result.transaction,\n network: result.network ?? matched.network,\n errorReason: result.errorReason,\n payer,\n }),\n result,\n }\n },\n }\n}\n\nfunction buildRequirements(request: Request, opts: RouteGateOptions): PaymentRequirement[] {\n const networks = Array.isArray(opts.network) ? opts.network : [opts.network ?? 'base']\n const atomic = usdToAtomic(opts.price)\n const resource = opts.resource ?? request.url\n\n return networks.map((network) => ({\n scheme: 'exact',\n network,\n asset: opts.asset ?? usdcAddress(network),\n maxAmountRequired: atomic,\n payTo: opts.recipient,\n description: opts.description,\n resource,\n maxTimeoutSeconds: opts.maxTimeoutSeconds ?? 600,\n extra: { name: 'USD Coin', version: '2' },\n }))\n}\n\nfunction paymentRequiredResponse(\n accepts: PaymentRequirement[],\n error?: string,\n): Response {\n const body: PaymentRequiredResponse = { x402Version: 1, accepts, ...(error ? { error } : {}) }\n return new Response(JSON.stringify(body), {\n status: 402,\n headers: { 'content-type': 'application/json' },\n })\n}\n\nexport { Facilitator, DEFAULT_FACILITATOR_URL } from './facilitator.js'\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yeetful",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "Spend-controlled x402 for AI agents. Give an agent an expense account — an allowlist + per-call/per-day budget — and pay any x402 endpoint in a few lines. Plus drop-in x402 client/server helpers.",
5
5
  "keywords": [
6
6
  "x402",