@haven_ai/sdk 0.5.0-alpha.1 → 0.6.0-alpha.0
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/README.md +2 -1
- package/dist/{base64-BUMXmruY.d.cts → base64-cD9kR4JL.d.cts} +243 -16
- package/dist/{base64-BUMXmruY.d.ts → base64-cD9kR4JL.d.ts} +243 -16
- package/dist/{chunk-KQ7JXKTV.js → chunk-3WSEX3GW.js} +315 -6
- package/dist/chunk-3WSEX3GW.js.map +1 -0
- package/dist/{chunk-GLNG2GF7.js → chunk-63GPTEEY.js} +42 -6
- package/dist/chunk-63GPTEEY.js.map +1 -0
- package/dist/{chunk-QSSVOPWA.cjs → chunk-CK4NLLMO.cjs} +333 -17
- package/dist/chunk-CK4NLLMO.cjs.map +1 -0
- package/dist/{chunk-JKUIE45B.cjs → chunk-S42QSWJY.cjs} +42 -6
- package/dist/chunk-S42QSWJY.cjs.map +1 -0
- package/dist/edge.cjs +85 -57
- package/dist/edge.d.cts +24 -4
- package/dist/edge.d.ts +24 -4
- package/dist/edge.js +3 -3
- package/dist/index.cjs +485 -294
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +47 -3
- package/dist/index.d.ts +47 -3
- package/dist/index.js +192 -21
- package/dist/index.js.map +1 -1
- package/dist/test-support.cjs +18 -18
- package/dist/test-support.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-GLNG2GF7.js.map +0 -1
- package/dist/chunk-JKUIE45B.cjs.map +0 -1
- package/dist/chunk-KQ7JXKTV.js.map +0 -1
- package/dist/chunk-QSSVOPWA.cjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/connector-channel.ts","../src/types.ts","../src/userop-binding.ts","../src/settlement-child.ts","../src/delegate-account.ts","../src/redemption-guard.ts"],"names":["isAddress","getAddress","keccak256","encodeAbiParameters","refuse","pad","encodeFunctionData","encodeDeployData","getContractAddress","decodeFunctionData","decodeAbiParameters"],"mappings":"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","file":"chunk-S42QSWJY.cjs","sourcesContent":["/**\n * The npm dist-tag the published Haven packages tell a user to re-run (#2423,\n * slice 3 of epic #2420).\n *\n * ## Why a constant and not a literal\n *\n * Roughly a dozen user- and agent-facing strings across `@haven_ai/sdk`,\n * `@haven_ai/signer`, `@haven_ai/connect` and the hosted MCP server say some\n * form of \"re-run `npx @haven_ai/connect@alpha`\". Every one of them was a\n * hard-coded literal, which is correct only for a build published under the\n * `alpha` dist-tag. Once `dev`-branch snapshots publish under a `dev` tag\n * (#2421), a snapshot build telling its tester to re-run `@alpha` would hand\n * them the production connector — silently replacing the very build they are\n * testing. So the tag becomes one build-time constant and every hint derives\n * from it.\n *\n * ## Who writes it\n *\n * `scripts/release-bump.mjs` rewrites {@link HAVEN_CONNECTOR_CHANNEL} from the\n * version it is bumping to, using exactly the rule `.github/workflows/publish.yml`\n * uses to pick the `--tag` for that same version:\n *\n * | version | dist-tag / channel |\n * |---|---|\n * | `0.1.34-alpha.0` | `alpha` |\n * | `0.0.0-dev.202609021200.abc1234` | `dev` |\n * | `0.2.0` | `latest` |\n *\n * One rule, two consumers. `scripts/ci/connector-channel-agreement.test.mjs`\n * executes the workflow's own shell and the bump script's own function over the\n * same version table and fails if they ever disagree.\n *\n * ## Build-time here, run-time there\n *\n * A published tarball cannot read a deployment's environment, so for the\n * published packages the channel is baked in at release time. A surface that is\n * *deployed* rather than published has no release at which to bake anything in,\n * so it reads the `HAVEN_CONNECTOR_CHANNEL` environment variable and falls back\n * to this constant. Two surfaces do that: the hosted MCP server\n * (`packages/mcp-server/src/connector-channel.ts`) and, since slice 2 (#2422),\n * the backend's connector handout (`parseConnectorChannel` in\n * `packages/backend/src/config.ts`). All three readers share one variable name,\n * one default and one validation pattern, and that agreement is EXECUTED rather\n * than asserted: `packages/backend/src/__tests__/connector-channel.test.ts`\n * runs this module's `resolveConnectorChannel` and the backend's\n * `parseConnectorChannel` over the same input table and fails if they ever\n * diverge.\n *\n * **This says nothing about how any environment is configured.** Setting the\n * variable anywhere is an operator action (epic #2420, operator step 3); no\n * code here can observe it and none of this comment asserts it has happened.\n */\n\n/** The published connector package. Never varies; only its tag does. */\nexport const CONNECTOR_PACKAGE_NAME = '@haven_ai/connect'\n\n/**\n * The npm dist-tag this build's re-run hints name.\n *\n * **Do not hand-edit.** `scripts/release-bump.mjs` owns this literal the same\n * way it owns `CONNECTOR_VERSION` and its siblings, and\n * `scripts/release-bump.test.mjs` fails if the two drift.\n */\nexport const HAVEN_CONNECTOR_CHANNEL = 'alpha'\n\n/**\n * A channel is a bare npm dist-tag: lowercase, starts with a letter, and may\n * carry digits and hyphens. This is not only a tidiness check — the resulting\n * spec is interpolated into an `npx <spec> …` command line that a human pastes\n * into a real terminal, so the pattern is also a shell boundary. It cannot\n * express a different package, a registry, a path or a shell metacharacter:\n * a wrong value selects another Haven channel and nothing else.\n *\n * Deliberately identical to `CONNECTOR_CHANNEL_PATTERN` in the backend's\n * `config.ts` (#2422): two readers of one environment variable that disagree\n * about what is valid is a worse failure than either rule alone. Pinned by an\n * executing agreement test, not by this comment.\n */\nconst CHANNEL_PATTERN = /^[a-z][a-z0-9-]{0,31}$/\n\n/** True when `value` is a well-formed dist-tag. */\nexport function isConnectorChannel(value: string): boolean {\n return CHANNEL_PATTERN.test(value)\n}\n\n/**\n * Resolve a channel from a deployment's `HAVEN_CONNECTOR_CHANNEL`.\n *\n * - unset, empty or whitespace ⇒ `fallback` (dashboards store a cleared\n * variable as `\"\"`, and that must land on the production-safe value);\n * - well-formed ⇒ itself;\n * - anything else ⇒ **throws**. It does not quietly fall back: a typo such as\n * `dve` would then land on the production channel, and the environment would\n * look fixed while reproducing the exact defect this slice removes.\n *\n * Well-formed-but-wrong (`dve` again) is *not* caught here and cannot be — it\n * fails later at `npx`, where the error names the package. Stated rather than\n * implied.\n */\nexport function resolveConnectorChannel(\n raw: string | undefined | null,\n fallback: string = HAVEN_CONNECTOR_CHANNEL,\n): string {\n const trimmed = (raw ?? '').trim()\n if (trimmed === '') return fallback\n if (!isConnectorChannel(trimmed)) {\n throw new Error(\n `HAVEN_CONNECTOR_CHANNEL is set to ${JSON.stringify(raw)}, which is not a valid npm ` +\n 'dist-tag (lowercase letter first, then letters, digits or hyphens). Refusing to start ' +\n 'rather than fall back to the default channel, because falling back would hand out the ' +\n 'production connector while looking configured.',\n )\n }\n return trimmed\n}\n\n/** `@haven_ai/connect@<channel>` — the spec an `npx` invocation names. */\nexport function connectorSpec(channel: string = HAVEN_CONNECTOR_CHANNEL): string {\n return `${CONNECTOR_PACKAGE_NAME}@${channel}`\n}\n\n/**\n * The re-run command every hint embeds.\n *\n * `connectorRerunCommand()` → `npx @haven_ai/connect@alpha`\n * `connectorRerunCommand('--doctor')` → `npx @haven_ai/connect@alpha --doctor`\n *\n * `args` is appended verbatim so each call site keeps its own flags and its own\n * surrounding sentence. The wording of those sentences is deliberately NOT\n * moved here: several are inside signer refusal messages that users and agents\n * pattern-match on, and this change is meant to move the channel token and\n * nothing else.\n */\nexport function connectorRerunCommand(\n args?: string,\n options?: { channel?: string; npxFlags?: string },\n): string {\n const channel = options?.channel ?? HAVEN_CONNECTOR_CHANNEL\n const flags = options?.npxFlags ? `${options.npxFlags} ` : ''\n const command = `npx ${flags}${connectorSpec(channel)}`\n return args ? `${command} ${args}` : command\n}\n","import { HAVEN_CONNECTOR_CHANNEL, connectorRerunCommand } from './connector-channel.js'\n\n// ── Client Configuration ─────────────────────────────────────────\n\nexport interface HavenClientConfig {\n /** Haven API key (sk_agent_xxx) */\n apiKey: string\n\n /** Agent's delegate EOA private key. If provided, the SDK handles signing automatically. */\n delegateKey?: string\n\n /** Haven API base URL (default: http://localhost:3001) */\n baseUrl?: string\n\n /** Optional wallet identity to send as the x402-wallet header. */\n x402Wallet?: string\n\n /** Timeout in ms for individual HTTP requests (default: 30000) */\n requestTimeout?: number\n /** Timeout (ms) for MERCHANT-facing requests — x402/MPP probes, MCP\n * handshakes, paid retries. Separate from requestTimeout (Haven API):\n * merchants may settle on-chain synchronously, so the default is\n * deliberately generous. #1300. */\n merchantTimeout?: number\n\n /** Timeout in ms when polling for tx confirmation (default: 90000) */\n confirmationTimeout?: number\n\n /** Polling interval in ms when waiting for confirmation (default: 3000) */\n pollingInterval?: number\n\n /**\n * Extra headers to attach to every request to the Haven API.\n *\n * Used by the MCP server to tag requests with `X-Haven-MCP-Tool: <name>`\n * so the backend can record an audit-log entry per tool invocation. Has\n * no effect on outbound merchant requests (x402 / MPP) — those are\n * standard HTTP and never carry Haven-internal headers.\n */\n defaultHeaders?: Record<string, string>\n\n /**\n * `<package>/<version>` naming the published package that embeds this\n * client, sent on every Haven API request as `X-Haven-Client` (#3303) so the\n * backend can tell an outdated client what to run. Defaults to\n * `@haven_ai/sdk/<this SDK's version>`. It cannot be set through\n * `defaultHeaders` — the transport writes it last.\n */\n clientIdentity?: string\n\n /**\n * JSON-RPC RPC URLs keyed by EIP-155 chain ID.\n *\n * When provided for a chain, the SDK waits for ≥1 on-chain confirmation of\n * the funding tx (account → delegate EOA) before retrying the merchant. This prevents\n * the race where the merchant's `balanceOf(delegate)` call runs before the\n * funding block has propagated to the merchant's RPC node.\n *\n * Without this option the SDK proceeds as soon as Haven's backend confirms\n * submission (backward-compatible default). Set it to a reliable RPC\n * endpoint (e.g. Alchemy / Infura) for production usage.\n *\n * @example { 8453: 'https://mainnet.base.org' }\n */\n chainRpcs?: Record<number, string>\n}\n\n// ── Payment Types ────────────────────────────────────────────────\n\nexport interface PaymentRequest {\n /** Token symbol: \"EURe\", \"USDC.e\", or \"xDAI\" */\n token: string\n\n /** Amount as a decimal string, e.g. \"5.00\" */\n amount: string\n\n /** Recipient Ethereum address (0x...) */\n to: string\n\n /**\n * Optional dedupe key (#1207): a retried request with the same key returns\n * the FIRST request's result instead of minting a second transfer or a\n * second approval. Same contract as /machine-payments/send. Max 128 chars.\n */\n idempotencyKey?: string\n\n /**\n * #3329: redeem against this open task budget's child delegation instead\n * of the agent's budget delegation directly — `[task child, budget]`. The\n * backend refuses (404/409) when the id is unknown, not open, or its\n * token/recipient/parent disagree with this request.\n */\n taskBudgetId?: string\n}\n\nexport interface SignData {\n /** The hash to sign (keccak256, 0x-prefixed) */\n hash: string\n\n /**\n * Delegation rail: 'eip712_userop' (funding redemption) or\n * 'eip712_delegation' (erc7710 settlement child). The backend spec makes it\n * required; the legacy AllowanceModule reading — absent = raw ECDSA over\n * `hash` — is retired (#2850), and the SDK client refuses an absent scheme.\n * The session rail's 'eip191_userop' is retired (#834).\n *\n * When present, `hash` is NOT what gets signed — `typed_data` is (#1138).\n */\n signature_scheme?: 'eip712_userop' | 'eip712_delegation'\n\n /**\n * EIP-712 payload the account validates, signed VERBATIM (#829). Present\n * whenever `signature_scheme` is — never reconstruct it from `components`.\n */\n typed_data?: {\n domain: Record<string, unknown>\n types: Record<string, unknown>\n primaryType: string\n message: Record<string, unknown>\n }\n\n /** Breakdown of values that were hashed — useful for debugging */\n components: {\n /**\n * The PAYER account (the user's smart account). Not to be confused with\n * `account`, which on the funding shapes holds the DELEGATE account\n * address.\n */\n payer_account?: string\n token: string\n to: string\n amount: string\n payment_token: string\n payment: string\n nonce: number\n }\n\n /** Human-readable signing instructions */\n instructions: string\n}\n\nexport interface PaymentIntent {\n /** Unique payment ID */\n paymentId: string\n\n /** Current status */\n status: 'pending_signature'\n\n /** ISO 8601 expiry timestamp */\n expiresAt: string\n\n /** Data needed to sign the payment */\n signData: SignData\n}\n\nexport type PaymentStatus =\n | 'pending_signature'\n | 'submitted'\n | 'confirmed'\n | 'pending_approval'\n | 'approved'\n | 'proposed'\n | 'executed'\n | 'rejected'\n | 'expired'\n | 'failed'\n\nexport interface PaymentResult {\n /** Unique payment ID */\n paymentId: string\n\n /** Final status */\n status: PaymentStatus\n\n /** Token that was sent */\n token: string\n\n /** Amount that was sent (human-readable) */\n amount: string\n\n /** Recipient address */\n to: string\n\n /** On-chain transaction hash (present when confirmed) */\n txHash: string | null\n\n /** Error message (present when failed) */\n errorMessage: string | null\n\n /** Block explorer URL for the transaction (chain-dependent) */\n explorerUrl: string | null\n\n /** ISO 8601 timestamps */\n createdAt: string\n signedAt: string | null\n submittedAt: string | null\n confirmedAt: string | null\n expiresAt: string\n\n /**\n * Platform fee surfaced on the result so it's never silently collected. Dark\n * today (`amount` \"0\", `applied` false); always present so it's visible the\n * moment fees go live.\n */\n fee?: PaymentFee | null\n}\n\n/** The Haven platform fee applied to a payment (#386). */\nexport interface PaymentFee {\n /** Human-readable fee amount (\"0\" while the fee module is dark). */\n amount: string\n /** Token the fee is denominated in. */\n token: string\n /** Fee as basis points of gross (0 while dark). */\n basisPoints: number\n /** True when a non-zero fee was actually applied. */\n applied: boolean\n}\n\n// ── x402 Types ──────────────────────────────────────────────────\n\n/** Payment requirements from an HTTP 402 response (x402 protocol). */\nexport interface X402PaymentRequired {\n x402Version: number\n resource: {\n url: string\n description?: string\n mimeType?: string\n // #2361: merchants may carry additional resource fields (the demo\n // merchant's `serviceName`, for one). The v2 payment envelope echoes\n // `resource` back VERBATIM, so unknown keys must survive normalization\n // rather than being stripped into a shape the merchant never sent.\n [key: string]: unknown\n }\n accepts: X402PaymentOption[]\n error?: string\n extensions?: Record<string, unknown>\n}\n\n/** A single payment option from x402 PaymentRequired. */\nexport interface X402PaymentOption {\n scheme: string // \"exact\"\n network: string // CAIP-2 chain ID or x402 network, e.g. \"eip155:8453\" or \"base\"\n amount: string // Atomic units\n maxAmountRequired?: string // Atomic units (official x402 field)\n resource?: string\n description?: string\n mimeType?: string\n asset: string // Token contract address\n payTo: string // Recipient address\n maxTimeoutSeconds: number\n /**\n * Merchant-supplied scheme metadata. Two keys are load-bearing for Haven\n * (#1453), both from MetaMask's erc7710 x402 shape:\n *\n * assetTransferMethod — 'erc7710' marks this entry as settleable by\n * redeeming a delegation chain. Absent/other means\n * the standard EIP-3009 authorization.\n * facilitatorAddresses — who may redeem it, pinned into the settlement\n * child's redeemer caveat (#1058).\n *\n * Left as an open record on purpose: the field is the merchant's, and\n * narrowing it to Haven's two keys would silently drop everything else a\n * merchant sends. Read it through `x402AssetTransferMethod` /\n * `x402FacilitatorAddresses` rather than indexing it raw.\n */\n extra?: Record<string, unknown>\n}\n\n/** Receipt returned after a successful x402 payment. */\nexport interface X402Receipt {\n success: boolean\n paymentId: string\n txHash: string\n token: string\n amount: string\n to: string\n resourceUrl: string\n explorerUrl: string\n accepted?: X402PaymentOption\n paymentHeader?: string\n merchantTo?: string | null\n payer?: string\n chainId?: number\n haven?: {\n paymentId: string\n fundingTxHash: string\n fundingExplorerUrl: string\n }\n merchant?: {\n payTo: string | null\n settlementTxHash?: string | null\n settlementExplorerUrl?: string | null\n }\n x402?: {\n amount: string\n token: string\n network: string\n asset: string\n resource: string\n }\n}\n\nexport interface X402AuthorizationOptions {\n /** Stable caller-supplied key for this user intent. Prevents duplicate approvals across fresh 402 quotes. */\n idempotencyKey?: string\n /**\n * #1307: the merchant MCP-tool call context this quote was made against\n * (merchant_url, tool_name, arguments, mcp_transport). Persisted on the\n * intent so `getX402MerchantCallContext` can rehydrate it by payment_id at\n * settle/complete time instead of the caller re-threading it. Optional —\n * omit for a non-MCP-tool x402 merchant (plain HTTP resource).\n */\n mcpCallContext?: X402McpCallContext\n /**\n * #1348: the agent's delegate address, when the caller already resolved it\n * from `getAgent()` in this same flow — skips `createX402Intent`'s internal\n * agent fetch (one full round trip on every guided purchase). Staleness\n * caveat (#1358 review): the backend derives the funding shape by comparing\n * `payTo` to the CURRENT delegate address, so a value made stale by a\n * delegate rotation mid-flow is not always a clean failure — a pinned-budget\n * agent gets a 403, but an open-budget delegation agent would route to the\n * settlement shape with the stale address. The window is one tool call\n * (previously sub-millisecond, now the merchant-quote duration), never\n * externally suppliable; server-truth hardening is tracked in #1360. Only\n * pass an address fetched in THIS flow; omit to keep the self-contained\n * fetch.\n */\n delegateAddress?: string\n /**\n * #3329: redeem against this open task budget's child delegation for the\n * funding leg / erc7710 settlement child instead of the agent's budget\n * delegation directly. Same refusal contract as `PaymentRequest.taskBudgetId`.\n * On the EIP-3009 funding leg (`authorizeX402`, `fetch()`, `payX402Quote()`)\n * a task budget's recipient pin is compared with the agent's own delegate\n * wallet, so a merchant-pinned task budget is refused there\n * (`task_budget_recipient_mismatch`); it pays through erc7710 only (#3378).\n */\n taskBudgetId?: string\n}\n\n/**\n * Keyless x402 construct result.\n *\n * Returned by `createX402Intent` — the non-custodial half of an x402 payment.\n * It carries the unsigned funding payload (`signData`, account → delegate EOA)\n * plus everything the *edge* needs to build and sign the EIP-3009 merchant\n * header itself. The construct path never signs; both delegate signatures\n * (funding payload + merchant header) happen on the machine that holds the key.\n */\nexport interface X402Intent {\n /** Haven payment id for the funding transfer. */\n paymentId: string\n /** Stable key used to create or refresh this x402 funding intent. */\n idempotencyKey: string\n status: 'pending_signature'\n /** ISO 8601 expiry of the funding intent, if returned. */\n expiresAt?: string\n /** The unsigned funding payload to sign with the delegate key (account → delegate EOA). */\n signData: SignData\n /** The selected x402 option — the edge needs this to build the EIP-3009 header. */\n accepted: X402PaymentOption\n /** Resource URL the 402 came from. */\n resourceUrl: string\n /** Merchant payTo address (the final recipient of the EIP-3009 transfer). */\n merchantTo: string\n /** Atomic amount the edge signer must authorize in the merchant header. */\n amountAtomic: string\n /** Token contract the merchant header must pay. */\n asset: string\n /** x402 network the merchant header must use. */\n network: string\n /** Haven-authenticated binding over the x402 expected context. */\n expectedAuth: X402ExpectedAuth\n /**\n * #1690: the payer identity Haven bound into the expected context (v3),\n * relayed VERBATIM to the signer's wire shape. Absent until the backend\n * flips X402_EMIT_PAYER_CONTEXT.\n */\n payerDelegate?: string\n payerAgentId?: string\n /**\n * EIP-712 digest of `signData.typed_data`, present on the delegation rail\n * (#1138). The edge signer needs it to reconstruct the v2 expected-context\n * message that Haven signed.\n */\n expectedTypedDataHash?: string\n /** Delegate EOA the funding transfer tops up (the x402 payer). */\n fundingTo: string\n}\n\nexport interface X402ExpectedContext {\n paymentId: string\n payloadHash: string\n resourceUrl: string\n merchantTo: string\n amount: string\n asset: string\n network: string\n /** Optional ISO expiry for the funding/quote window. When present, it is bound into the Haven-authenticated context. */\n expiresAt?: string\n /**\n * EIP-712 digest of the typed data the account actually validates\n * (delegation rail, #1138). Present ⇒ the context is **version 2** and the\n * signer must sign that typed data, never `payloadHash`.\n *\n * On the delegation rail `payloadHash` is the bare ERC-4337 UserOp hash,\n * which is NOT what the account validates — binding it alone would leave the\n * edge signer unable to verify the payload it is being asked to sign. Binding\n * this digest makes Haven's declaration cover the real payload.\n *\n * Absent ⇒ the retired version-1 bare-hash context. Since #3272 the backend\n * never emits one (`signX402ExpectedContext` requires this field) and\n * `@haven_ai/signer` refuses it with its version-mismatch refusal; the field\n * stays optional here only because the type also describes older payloads.\n */\n typedDataHash?: string\n /**\n * The DELEGATE ADDRESS this quote was created for (#1690). Present ⇒ the\n * context is **version 3** and the signer refuses to sign when this is not\n * its own delegate — the guard that turns \"quote as agent A, sign as agent\n * B\" from an on-chain revert three layers later into a named refusal.\n * Inside the Haven-signed message on purpose: outside it, it is forgeable.\n */\n payerDelegate?: string\n /** The paying agent's id, for the refusal message's diagnosis (#1690). */\n payerAgentId?: string\n}\n\nexport interface X402ExpectedAuth {\n /**\n * 2 = carries `typedDataHash` (delegation rail, #1138). 3 = additionally binds\n * the payer identity (#1690). 1 (hash-only, retired Safe rail) is never\n * emitted since #3272 and the signer refuses it.\n *\n * Deliberately `number`, not a literal union (#1143). This is an **inbound**\n * value: a signer parses a context Haven produced, and a signer older than the\n * backend will legitimately receive a version it does not know. A closed union\n * makes that state unrepresentable, which pushed the rejection down to the\n * schema boundary and produced a raw validation error naming neither the cause\n * nor the fix. The supported set lives in the signer\n * (`SUPPORTED_X402_EXPECTED_VERSIONS`), which fails closed on anything outside\n * it with an actionable message.\n */\n version: number\n message: string\n signature: string\n signer: string\n}\n\n/** Serializable HTTP request state for retrying the same x402 merchant request. */\nexport interface X402RequestSnapshot {\n url: string\n method: string\n headers: [string, string][]\n body?: string\n}\n\nexport interface X402McpTransport {\n handshakeRequired: boolean\n source: 'path' | 'bazaar'\n}\n\n/**\n * #1307: the merchant MCP-tool call an x402 quote was made against — carried\n * through `createX402Intent`'s options so Haven can persist it for the\n * settle-leg rehydration handoff (`getX402MerchantCallContext`). Convenience\n * metadata for retrying the merchant's OWN JSON-RPC call, never payment\n * authority.\n */\nexport interface X402McpCallContext {\n merchantUrl: string\n toolName: string\n arguments?: Record<string, unknown>\n mcpTransport?: X402McpTransport\n}\n\n/**\n * Response shape of `getX402MerchantCallContext` — the stored merchant call\n * context for a payment_id, rehydrated instead of re-threaded (#1307).\n */\nexport interface X402MerchantCallContext {\n paymentId: string\n merchantUrl: string\n toolName: string\n arguments: Record<string, unknown>\n mcpTransport?: X402McpTransport\n}\n\n/** @internal */\nexport interface RawX402MerchantCallContext {\n payment_id: string\n merchant_url: string\n tool_name: string\n arguments?: Record<string, unknown>\n mcp_transport?: { handshake_required: boolean; source: 'path' | 'bazaar' }\n error?: string\n error_code?: string\n status?: string\n}\n\n/** Quote parsed from an HTTP 402 response without creating a Haven payment. */\nexport interface X402Quote {\n rail: 'x402'\n idempotencyKey: string\n paymentRequired: X402PaymentRequired\n accepted: X402PaymentOption\n /**\n * #2054: which selector produced `accepted`, and therefore which entry every\n * amount on this quote describes. `'standard'` is the untagged,\n * EIP-3009-settleable entry; `'erc7710'` means the merchant advertises NO\n * standard entry, so the quote describes its erc7710 one — settleable only\n * from a delegation-rail account, a fact the quote layer cannot see (the\n * rail is a property of the ACCOUNT, not of the 402). This field is\n * descriptive: the actual settlement scheme is still chosen later, with the\n * rail in hand, by `selectX402SettlementScheme`.\n */\n acceptedScheme: 'standard' | 'erc7710'\n request: X402RequestSnapshot\n mcpTransport?: X402McpTransport\n resourceUrl: string\n /** #3097: `resourceUrl` (the merchant's declaration) is not `request.url` (what was quoted). */\n resourceUrlDiffersFromRequest: boolean\n description: string | null\n mimeType: string | null\n amountAtomic: string\n amount: string\n token: string\n /**\n * #1351: decimals for `asset` on `network`, resolved from the SAME\n * address→token binding that produced `token` — the quote's own authority on\n * how many atomic units one human unit is. `null` when the merchant's asset\n * is not a token Haven recognises on that network, in which case `token` is\n * an unverified fallback label and NO human→atomic conversion is safe.\n * Consumers converting a human-denominated figure (a user-intent spending\n * cap) MUST fail closed on `null` rather than assume 6.\n */\n decimals: number | null\n asset: string\n network: string\n chainId: number | null\n merchantAddress: string\n maxTimeoutSeconds: number\n}\n\n/** State bundle an agent can persist while waiting for manual x402 approval. */\nexport interface X402ResumeState {\n rail: 'x402'\n paymentId: string\n idempotencyKey: string\n paymentRequired: X402PaymentRequired\n accepted: X402PaymentOption\n url: string\n request?: X402RequestSnapshot\n resourceUrl: string\n description: string | null\n amountAtomic: string\n amount: string\n token: string\n asset: string\n network: string\n chainId: number | null\n merchantAddress: string\n}\n\n// #1328: MppAuthorizationOptions / MppQuote / MppResumeState / ResumeAuthorizedMppInput\n// / ResumeMppPaymentInput / MachinePaymentChallenge / MachinePaymentReceipt were\n// the wire types for the retired mpp_demo challenge/quote/resume client surface\n// (`quoteMpp` / `payMppChallenge` / `resumeMppPayment` / `authorizeMachinePayment`,\n// all removed from client.ts). `MachinePaymentRail` stays — it is still the read-path\n// vocabulary for historical payment/evidence/status rows (mpp_demo, mpp_crypto,\n// stripe_deposit, spt all remain valid values there).\n\nexport type PaymentResumeState = X402ResumeState\n\nexport interface ResumeAuthorizedX402Input extends X402AuthorizationOptions {\n /** Payment or approval request ID returned by authorizeX402 / haven.fetch. */\n paymentId: string\n\n /** Original or freshly parsed x402 requirements for the merchant retry. */\n paymentRequired: X402PaymentRequired\n}\n\nexport interface ResumeX402PaymentInput extends X402AuthorizationOptions {\n /** Payment or approval request ID returned by authorizeX402 / haven.fetch. */\n paymentId: string\n\n /** Original paid URL. If paymentRequired is omitted, Haven will call it once to re-read the 402 challenge. */\n url: string\n\n /** Original fetch options. Reused for the 402 probe and final merchant retry. */\n init?: RequestInit\n\n /** Serializable original request captured by quoteX402() / pending approval errors. */\n request?: X402RequestSnapshot\n\n /** Original or freshly parsed x402 requirements. Supplying this avoids an extra merchant 402 probe. */\n paymentRequired?: X402PaymentRequired\n}\n\n// ── Machine Payment Types ───────────────────────────────────────\n//\n// The wire-shape TYPES for the retired mpp_demo challenge/quote/resume\n// client surface (MachinePaymentChallenge, MachinePaymentReceipt,\n// MppAuthorizationOptions, ResumeAuthorizedMppInput, ResumeMppPaymentInput)\n// were removed with it (#1328). MachinePaymentRail stays: it is still the\n// read-path vocabulary on historical payment/evidence/status responses.\n\nexport type MachinePaymentRail =\n | 'x402'\n | 'mpp_demo'\n | 'mpp_crypto'\n | 'stripe_deposit'\n | 'spt'\n\nexport interface HavenAgent {\n id: string\n name: string\n status: string\n /** The agent's Haven account (smart account) address. */\n accountAddress: string\n delegateAddress: string\n chainId: number\n /**\n * Which on-chain policy primitive gates this agent's spend (#1306): the\n * legacy Safe AllowanceModule (retired — no account can enter it since\n * #1984, and it cannot spend since #1986) or the delegation\n * rail's active budget delegations (#1090). Read-only reporting — the\n * on-chain state is the actual gate either way, this only says which\n * mechanism a caller should read/derive from.\n */\n executionRail: 'legacy' | 'delegation'\n}\n\nexport interface HavenAllowance {\n id: string\n tokenAddress: string\n tokenSymbol: string\n configuredAmount: string\n resetPeriodMin: number\n /**\n * #3128: human-readable `onchain.remaining`, e.g. \"4.96 USDC\" — the SAME\n * string {@link HavenAgentAllowanceSummary.remainingDisplay} carries for\n * this allowance, computed by one function from `onchain.remaining` and\n * the token's decimals, so the two reads cannot disagree. Additive; the\n * wire carries no display form (it is derived client-side).\n */\n remainingDisplay: string\n onchain: {\n amount: string\n spent: string\n remaining: string\n effectiveSpent: string\n resetTimeMin: number\n lastResetMin: number\n nonce: number\n isResetPending: boolean\n /**\n * Delegation rail only (#1319, provenance for #1145's fallback): true\n * when `remaining` came from a live on-chain enforcer read, false when\n * the read failed and `remaining` is the fallback full configured\n * budget. Undefined on the legacy AllowanceModule rail, which has no\n * fallback concept. Reporting only — the on-chain policy remains the\n * actual spend gate either way.\n */\n remainingIsFromChain?: boolean\n }\n}\n\nexport interface HavenAllowanceSummary {\n agentId: string\n accountAddress: string\n delegateAddress: string\n chainId: number\n allowances: HavenAllowance[]\n}\n\n/**\n * Post-purchase allowance/budget summary attached to a settled x402 payment\n * (#1310). Read-only reporting — the on-chain policy remains the actual\n * spend gate either way, this only says what is left after the purchase.\n *\n * Deliberately the SAME rail-labeled field spelling as #1306's\n * catalog-purchase preflight `allowance` block (never a new spelling),\n * minus the preflight-only `sufficient` field: post-purchase reporting\n * answers \"what is left\", not \"was this purchase covered\". Read through the\n * exact same source as {@link HavenAllowanceSummary} / `haven_get_allowances`\n * (`GET /machine-payments/allowances`; delegation-rail values are the #1090\n * `deriveDelegationBudgets`-backed enforcer read, never `agent_allowances`),\n * so this can never disagree with `haven_get_allowances` for the same\n * fixture.\n */\nexport interface PostPurchaseAllowanceSummary {\n /** Which on-chain policy primitive gates this agent's spend (#1306 labeling). */\n rail: 'legacy' | 'delegation'\n /** Remaining atomic units, read through the same source as {@link HavenAllowance.onchain.remaining}. */\n remaining_atomic: string\n /** Human-readable remaining, e.g. \"4.96 USDC\". Omitted when the token's decimals are unknown. */\n remaining_display?: string\n token_symbol?: string\n token_address?: string\n /** Minutes — mirrors {@link HavenAllowance.resetPeriodMin} / the delegation's period. */\n reset_period?: number\n source: 'allowance_module' | 'active_delegations'\n}\n\n/**\n * #3126 — the answer to \"is there money actually HELD behind my budget?\",\n * asked as a sufficiency signal rather than a balance.\n *\n * Every other agent-readable figure in this package describes SPEND\n * AUTHORITY — what the agent is PERMITTED to move this period\n * ({@link HavenAllowanceSummary}). This shape answers the different question\n * of whether the account HOLDS funds behind that authority, and deliberately\n * answers it as `covered: boolean | null`, never as a figure: a constrained\n * actor has no business reading the treasury total, and the boolean answers\n * the only decision an agent has (attempt the payment, or tell the user\n * funds are missing).\n *\n * The naming keeps the two concepts apart (the #3126 binding constraint):\n * `budgetRemainingAtomic` is AUTHORITY — the same value\n * {@link HavenAllowanceSummary} reports per token as `onchain.remaining` —\n * while `covered` speaks only of HELD funds. Nothing here is named like the\n * authority fields (`remaining`, `available`); nothing here returns a\n * balance.\n *\n * `covered: null` means the chain read FAILED — unverifiable, never a\n * guess. The same honesty rule `x402-funding-leg.ts`'s `delegateCanFund`\n * established (#1521): treat null as \"we do not know\", not as \"funded\" or\n * as absence; `coverageError` carries why.\n */\nexport interface HavenBalanceCoverage {\n /**\n * true: the chain reports the agent's account holds at least\n * `checkedAmountAtomic` of the token. false: the chain read succeeded and\n * reports LESS — tell the user funds are missing rather than retrying.\n * null: the chain read failed — unverifiable, never treated as absence.\n */\n covered: boolean | null\n /** Present only when `covered` is null: why the chain read could not answer. */\n coverageError?: string\n chainId: number\n tokenAddress: string\n tokenSymbol: string\n /** The amount the coverage question was asked about, in atomic units. */\n checkedAmountAtomic: string\n /**\n * Context, AUTHORITY not holdings: the agent's remaining spend authority\n * for the requested token, in atomic units — the same derivation\n * {@link HavenAllowanceSummary} reports (`onchain.remaining`; the #1090\n * derivation, the #1145 enforcer read). Zero when no active budget row\n * names the token. Compare it with `covered`, never instead of it.\n */\n budgetRemainingAtomic: string\n /**\n * Provenance of `budgetRemainingAtomic` (#1319, same semantics as\n * {@link HavenAllowance.onchain.remainingIsFromChain}): true when the\n * budget figure came from a live enforcer read, false when it fell back\n * to the configured budget. Absent when no budget row existed for the\n * token (nothing was read).\n */\n budgetRemainingIsFromChain?: boolean\n}\n\n/** @internal wire shape of {@link HavenBalanceCoverage}. */\nexport interface RawHavenBalanceCoverage {\n covered: boolean | null\n coverage_error?: string\n chain_id: number\n token_address: string\n token_symbol: string\n checked_amount_atomic: string\n budget_remaining_atomic: string\n budget_remaining_is_from_chain?: boolean\n}\n\n/**\n * Affirmative spend-readiness for the authenticated agent, derived from the raw\n * agent status plus the remaining spend authority the backend reports per rail\n * (the active budget delegation on the delegation rail — #1135; the retired\n * AllowanceModule rail used an on-chain allowance instead):\n * - `ready` — active and at least one token has remaining spend authority.\n * - `needs_approval`— active but no remaining spend authority to auto-spend.\n * The over-budget outcome differs by rail: on the retired\n * AllowanceModule rail the payment was queued for the wallet\n * owner to approve in Haven; on the delegation rail there is\n * NO approval queue — an over-budget redemption reverts\n * on-chain, so the owner must grant or raise the budget in\n * Haven before the agent can pay.\n * - `revoked` — the agent's status is not `active`; nothing auto-executes.\n *\n * Note: a hard-paused/disabled credential is rejected by the API before this\n * call returns, so it surfaces as an API error rather than `revoked`. `revoked`\n * is reached when the request authenticates but the agent status is non-active.\n *\n * Wallet token balance is intentionally NOT folded in here: the on-chain\n * remaining allowance is the gate Haven enforces, and insufficient wallet\n * funding surfaces at pay time as INSUFFICIENT_FUNDS.\n */\nexport type HavenAgentReadiness = 'ready' | 'needs_approval' | 'revoked'\n\n/**\n * Compact, agent-facing per-token spend authority for the bootstrap summary.\n *\n * #3128: a deliberately DIFFERENT view of the same allowance as\n * {@link HavenAllowance} — flat, no `onchain` block, no spent/nonce/reset-time\n * detail — but never a disjoint one: every field here is present on or\n * derived from the {@link HavenAllowance} with the same `id`, and\n * `remainingAtomic` / `remainingDisplay` equal that allowance's\n * `onchain.remaining` / `remainingDisplay` byte for byte (pinned by test). A\n * client that wants the id AND a display amount can therefore use either\n * read alone.\n */\nexport interface HavenAgentAllowanceSummary {\n /** #3128: the {@link HavenAllowance.id} this row summarises. */\n id: string\n tokenSymbol: string\n /** #3128: the {@link HavenAllowance.tokenAddress}. */\n tokenAddress: string\n /** Live on-chain remaining allowance in atomic units. */\n remainingAtomic: string\n /** Human-readable remaining, e.g. \"4.96 USDC\". */\n remainingDisplay: string\n /** Configured allowance amount (atomic) the owner granted. */\n configuredAmount: string\n resetPeriodMin: number\n isResetPending: boolean\n}\n\n/**\n * One-shot \"am I ready?\" bootstrap: identity + live spend authority + a\n * readiness signal, so an agent can answer \"who am I and can I pay right now\"\n * from a single call at session start. Superset of {@link HavenAgent}.\n */\nexport interface HavenAgentSummary extends HavenAgent {\n /**\n * @deprecated Use {@link HavenAgentSummary.spend_authority_readiness} —\n * same value, honest name. This signal covers hosted identity + on-chain\n * spend authority ONLY; it says nothing about the LOCAL signer, which the\n * hosted side cannot see (verify via a signer tool or connect --doctor).\n * Kept as an alias; removal earliest after the next release train (#1590).\n */\n readiness: HavenAgentReadiness\n /**\n * Spend-authority readiness: hosted identity + on-chain remaining spend\n * authority. Deliberately named for what it covers — the LOCAL signer's\n * availability is NOT included and must be verified separately (a signer\n * tool call, or the connector's `--doctor`, whose exact command this build\n * renders from `HAVEN_CONNECTOR_CHANNEL` — see `connector-channel.ts`).\n */\n spend_authority_readiness: HavenAgentReadiness\n allowances: HavenAgentAllowanceSummary[]\n /**\n * #3329: open, unexpired task budgets — a derived VIEW, same discipline as\n * {@link HavenAgentSummary.allowances}. Populated from\n * `GET /task-budgets?status=open`; empty (never throws) against a backend\n * that predates #3329's route (a 404 there is treated as \"no task\n * budgets\", not a fetch failure).\n */\n taskBudgets: HavenTaskBudgetSummary[]\n}\n\n/** #3329: task-budget lifecycle status, as the wire names it. */\nexport type HavenTaskBudgetStatus = 'pending' | 'open' | 'closing' | 'closed'\n\n/** #3329: the wire shape of `components.schemas.TaskBudget` (snake_case). */\nexport interface RawTaskBudget {\n id: string\n agent_id: string\n chain_id: number\n token_address: string\n recipient_address: string | null\n parent_delegation_hash: string\n delegation_hash: string\n label: string | null\n max_atomic: string\n status: HavenTaskBudgetStatus\n expires_at: number\n is_expired: boolean\n created_at: string\n opened_at: string | null\n closed_at: string | null\n close_tx_hash: string | null\n}\n\n/** #3329: `RawTaskBudget`, camelCased — what every SDK task-budget method returns. */\nexport interface HavenTaskBudget {\n id: string\n agentId: string\n chainId: number\n tokenAddress: string\n recipientAddress: string | null\n parentDelegationHash: string\n delegationHash: string\n label: string | null\n maxAtomic: string\n status: HavenTaskBudgetStatus\n expiresAt: number\n isExpired: boolean\n createdAt: string\n openedAt: string | null\n closedAt: string | null\n closeTxHash: string | null\n}\n\n/**\n * #3329: the condensed row `getAgentSummary()` carries per open, unexpired\n * task budget — enough to render a \"reserved by open task budgets\" line and\n * a task-budget list without a second read.\n */\nexport interface HavenTaskBudgetSummary {\n id: string\n label: string | null\n tokenAddress: string\n maxAtomic: string\n maxDisplay: string\n recipientAddress: string | null\n expiresAt: number\n}\n\n/** #3329: `POST /task-budgets` and `POST /task-budgets/:id/close` — the sign-then-submit envelope. */\nexport interface HavenTaskBudgetSignData {\n signature_scheme: 'eip712_delegation' | 'eip712_userop'\n typed_data: Record<string, unknown>\n}\n\nexport interface OpenTaskBudgetResult {\n taskBudget: HavenTaskBudget\n signData: HavenTaskBudgetSignData\n nextAction: string\n instructions: string\n}\n\nexport interface CloseTaskBudgetResult {\n taskBudget: HavenTaskBudget\n status: HavenTaskBudgetStatus\n /** Present only when the close needed a signature (an OPEN, unexpired budget). */\n signData?: HavenTaskBudgetSignData\n nextAction?: string\n}\n\nexport interface SubmitTaskBudgetResult {\n taskBudget: HavenTaskBudget\n status: HavenTaskBudgetStatus\n /** Present only once the close UserOp lands (`status === 'closed'` from `closing`). */\n closeTxHash?: string\n}\n\n/** #3329: `GET /task-budgets/:id/sign-context` — `purpose: 'open'` shape. */\nexport interface TaskBudgetOpenSignContext {\n taskBudgetId: string\n purpose: 'open'\n taskSignContextVersion: number\n typedData: Record<string, unknown>\n expected: {\n delegateAccount: string\n chainId: number\n tokenAddress: string\n maxAmountAtomic: string\n recipientAddress: string | null\n expiresAt: number\n parentDelegationHash: string\n }\n}\n\n/** #3329: `GET /task-budgets/:id/sign-context` — `purpose: 'close'` shape. */\nexport interface TaskBudgetCloseSignContext {\n taskBudgetId: string\n purpose: 'close'\n taskSignContextVersion: number\n typedData: Record<string, unknown>\n userOperation: Record<string, unknown>\n userOpHash: string\n expected: {\n delegateAccount: string\n chainId: number\n delegationHash: string\n }\n}\n\nexport type TaskBudgetSignContext = TaskBudgetOpenSignContext | TaskBudgetCloseSignContext\n\n// ── Task-budget wire responses ──────────────────────────────────────────\n\nexport interface RawOpenTaskBudgetResponse {\n task_budget: RawTaskBudget\n sign_data: HavenTaskBudgetSignData\n next_action: string\n instructions: string\n}\n\nexport interface RawSubmitTaskBudgetResponse {\n task_budget: RawTaskBudget\n status: HavenTaskBudgetStatus\n close_tx_hash?: string\n}\n\nexport interface RawCloseTaskBudgetResponse {\n task_budget: RawTaskBudget\n status: HavenTaskBudgetStatus\n sign_data?: HavenTaskBudgetSignData\n next_action?: string\n}\n\nexport interface RawTaskBudgetSignContext {\n task_budget_id: string\n purpose: 'open' | 'close'\n task_sign_context_version: number\n typed_data: Record<string, unknown>\n user_operation?: Record<string, unknown>\n user_op_hash?: string\n expected: Record<string, unknown>\n}\n\n/**\n * #2960 — one party vocabulary for \"who paid\" a Haven payment, additive\n * alongside every existing lone `payer*`/`*Address` field (same discipline\n * as the #2907 `safe`/`account` dual-emit, except these four are DISTINCT\n * addresses, not same-value twins of one old field).\n */\nexport interface PaymentParties {\n treasuryAccount: string | null\n delegate: string | null\n delegateAccount: string | null\n merchant: string | null\n}\n\n/** @internal wire shape of {@link PaymentParties}. */\nexport interface RawPaymentParties {\n treasury_account: string | null\n delegate: string | null\n delegate_account: string | null\n merchant: string | null\n}\n\n/**\n * #3132 (owner decision 3 on #3130): what population a list row came from and\n * what narrowed it, as two values. Receipts are `{ source: 'agent', filter:\n * null }` — this agent's evidence rows only, no query-time narrowing. The\n * wallet feed (`GET /transactions`, the CLI's `activity list`) is\n * `source: 'wallet'` with `filter: 'agent'` when `agentId` narrows it, and it\n * is a DIFFERENT population (explorer window plus synthesized intents; sweeps\n * and funding legs included), never this view. A receipt read is not a\n * transaction-history read.\n */\nexport interface HavenListScope {\n source: 'wallet' | 'agent'\n filter: 'agent' | 'account' | 'account+agent' | null\n}\n\nexport interface HavenPaymentReceipt {\n id: string\n /** #3132: present when the backend states it (absent on an older backend). */\n scope?: HavenListScope\n paymentId: string\n paymentIntentId?: string | null\n approvalRequestId?: string | null\n /**\n * #3134: the payment protocol this receipt settled on — one of the\n * evidence-eligible rails (`x402`, `mpp_demo`, `mpp_crypto`, `spt`) — under the\n * name the transactions feed uses for the same concept. Distinct from\n * `scope.source`, which names the LIST population (#3132) — the transaction\n * row carries the same two. Same name, narrower domain: never `'direct'`\n * here — the feed's SQL default for an intent that names no protocol has no\n * receipt analogue, because no protocol means no evidence row.\n */\n source: string\n /**\n * #3134: the evidence row's recorded proof status, under the transactions\n * feed's name. Same name, different nullability: `string` here because a\n * receipt IS the evidence row, `string | null` on the feed, where a row may\n * LEFT JOIN to none (#3132) — do not share a non-null-asserting helper.\n */\n paymentProofStatus: string\n /**\n * @deprecated (#2998) meaning depends on the settlement scheme — the\n * account → delegate funding transaction on eip3009, the (only) settlement\n * transaction on erc7710. Prefer {@link fundingTxHash} / {@link settlementTxHash}, which\n * name which is which.\n */\n txHash: string\n /** The account → delegate funding transaction, relayed by Haven (#2998); null on erc7710 (no funding leg) and on retired mpp-rail rows. */\n fundingTxHash: string | null\n /**\n * The delegate → merchant settlement transaction (#2998). Trust level differs\n * by scheme: on erc7710 it is `txHash` itself and Haven VERIFIED it on-chain\n * before the receipt existed; on eip3009 it is the merchant's claim as relayed\n * (PAYMENT-RESPONSE), NOT verified on-chain by Haven — cite it as such.\n */\n settlementTxHash: string | null\n chainId: number\n /** #3134: the paid resource, under the transactions feed's protocol-prefixed name (`string | null` there; a receipt always has one). */\n x402ResourceUrl: string\n /** #3134: the merchant paid, under the transactions feed's protocol-prefixed name. */\n x402MerchantAddress: string | null\n payerAddress: string\n /** #2960: additive alongside `payerAddress` above (`parties.treasury_account` only). */\n parties?: PaymentParties\n settlementAddress: string\n tokenSymbol: string\n tokenAddress: string\n amountRaw: string\n amount: string\n challengeId: string | null\n idempotencyKey: string | null\n challengePayload?: Record<string, unknown> | null\n selectedPayment?: Record<string, unknown> | null\n paymentProofHeaderName: string | null\n protocolReceiptHeaderName: string | null\n /**\n * #3125 — the merchant's `PAYMENT-RESPONSE` object relayed VERBATIM:\n * opaque, unvalidated, unverified, MERCHANT-CONTROLLED third-party data.\n * Haven neither authors nor verifies anything inside it, including\n * `protocolReceiptPayload.payer` —\n * that `payer` is the merchant's claim, NOT Haven's record, and is not\n * {@link payerAddress} (Haven's own, authoritative; field observation\n * 2026-09-18: the two held different addresses on every row read). For who\n * paid, read `parties` ({@link PaymentParties}) — `treasuryAccount`,\n * `delegate`, `delegateAccount`, `merchant` are Haven-derived and\n * authoritative; anything inside this object is not.\n *\n * Deliberately NOT namespaced or key-prefixed on the wire (#3125): the\n * relay must stay the merchant's object verbatim (its `transaction` key\n * feeds `settlementTxHash`), and prefixing the envelope could not prefix\n * the merchant-controlled keys inside it — the `payer` collision lives\n * there, so provenance is made legible at the read surfaces instead (this\n * comment and the tool descriptions).\n */\n protocolReceiptPayload?: Record<string, unknown> | null\n merchantStatus: number | null\n confirmedAt: string | null\n createdAt: string\n updatedAt: string\n}\n\n// ── Delegate Sweep Types ─────────────────────────────────────────\n\n/**\n * How long this SDK waits for an on-chain confirmation before it stops\n * waiting (#1756).\n *\n * Lives here rather than in `client.ts` so the payment-confirmation poller\n * and the delegate sweep share ONE number instead of forking it. The SDK's\n * other chain waits are already bounded (`waitForFundingTx` at 30 s), so a\n * fourth independently chosen literal is exactly the drift this constant\n * exists to prevent.\n */\nexport const DEFAULT_CONFIRMATION_TIMEOUT_MS = 90_000\n\n/**\n * Whether a sweep transfer was observed to confirm (#1756).\n *\n * The distinction is the point: `unconfirmed` means the transfer was\n * BROADCAST and may still land, which is neither success nor failure. It must\n * never be collapsed into either — reporting a still-pending transaction as\n * done, or as failed, are the same defect in opposite directions.\n */\nexport type SweepConfirmation =\n /** A receipt was observed. The funds are in the agent's Haven account. */\n | 'confirmed'\n /**\n * Broadcast, but no receipt within `DEFAULT_CONFIRMATION_TIMEOUT_MS` (or the\n * node returned no receipt). The transaction is still in the mempool and may\n * mine at any time. `txHash` is the broadcast hash — check it on the\n * explorer before re-running the sweep, and expect a re-run to find nothing\n * stranded if it has since landed.\n */\n | 'unconfirmed'\n\n/** One transferred asset in a delegate sweep. */\nexport interface SweepEntry {\n /** 'USDC' or 'ETH' */\n asset: string\n /** Human-readable amount swept (e.g. \"0.12\") */\n amount: string\n /** Atomic amount swept */\n amountAtomic: string\n /**\n * Transaction hash of the sweep transfer.\n *\n * The RECEIPT hash when `confirmation` is `confirmed`; the BROADCAST hash\n * when it is `unconfirmed` — which is the whole reason the sweep returns\n * instead of throwing on a deadline, since this hash is the only thing that\n * lets a user recover the transfer by hand (#1756).\n */\n txHash: string\n /** Block explorer URL for the tx */\n explorerUrl: string\n /**\n * Did this transfer confirm on-chain within the deadline? (#1756)\n *\n * `unconfirmed` entries have MOVED NOTHING YET and may still move. Do not\n * report a sweep as complete without checking this on every entry.\n */\n confirmation: SweepConfirmation\n}\n\n/** Result of a `sweepDelegate()` call. */\nexport interface SweepResult {\n /** Address funds were swept FROM */\n fromAddress: string\n /** Address funds were swept TO (always the agent's Haven account) */\n toAddress: string\n /** Chain the sweep occurred on */\n chainId: number\n /** One entry per transferred asset. Empty when nothing was stranded. */\n transfers: SweepEntry[]\n /**\n * True when ANY entry is `unconfirmed` — i.e. the sweep broadcast something\n * it could not confirm within the deadline (#1756).\n *\n * Derived from `transfers`, and present anyway because the consumer most\n * likely to misread this result is an LLM reading the JSON of the\n * `haven_sweep_delegate` tool, which will otherwise see a populated\n * `transfers` array and report the money as recovered.\n */\n unconfirmed: boolean\n}\n\n// ── Agent Payment State Types ────────────────────────────────────\n\nexport type PaymentStateKind = 'payment_intent' | 'approval_request'\n\nexport interface AgentPaymentEnumSchema {\n type: 'string'\n enum: readonly string[]\n description: string\n 'x-enumDescriptions': Record<string, string>\n}\n\nexport const AgentPaymentPhase = {\n /** The agent must sign and submit the prepared payment before Haven can relay it. */\n AgentSignatureRequired: 'agent_signature_required',\n /** Haven has received the signed payment and the agent should poll for confirmation. */\n PaymentSubmitted: 'payment_submitted',\n /** The direct payment is confirmed; the agent does not need to do more for this payment id. */\n PaymentConfirmed: 'payment_confirmed',\n /**\n * #2115: RETIRED wire value — no live rail produces it. It described the\n * Safe rail's approval queue, which no longer exists. Kept so a stored value\n * still typechecks; see `AgentPaymentPhaseDescriptions` below for the\n * agent-visible wording, which this comment used to contradict.\n */\n UserApprovalRequired: 'user_approval_required',\n /** #2115: RETIRED wire value — no live rail produces it. Stop and tell the user. */\n UserExecutionRequired: 'user_execution_required',\n /** #2115: RETIRED wire value — no live rail produces it. Stop and tell the user. */\n WaitingForAdditionalApprovals: 'waiting_for_additional_approvals',\n /** The Haven funding leg was sent; the agent can continue the merchant/protocol leg. */\n FundingSent: 'funding_sent',\n /** The payment was rejected and cannot proceed; the agent should stop and tell the user. */\n Rejected: 'rejected',\n /** The payment expired before completion. */\n Expired: 'expired',\n /** Haven could not complete the payment; the agent should stop and surface the failure. */\n Failed: 'failed',\n /**\n * Pre-flight check determined the delegate's existing balance plus the\n * remaining on-chain budget cannot cover the requested amount, so no\n * payment intent was created. The account must be funded or the agent's\n * budget raised before retrying — #2115: the old wording contrasted this\n * with `UserApprovalRequired` as if that were a live alternative, and named\n * the retired rail's Safe and per-token allowance as the fix.\n */\n InsufficientFunds: 'insufficient_funds',\n /**\n * Haven's funding leg (account → delegate, the #946 EIP-3009 bridge)\n * confirmed on-chain, but the merchant rejected the x402 retry. The delegate\n * wallet may hold stranded USDC that was never settled to the merchant. The\n * agent should stop, tell the user, and wait for the sweep flow to reclaim\n * the funds.\n */\n FundedButUnsettled: 'funded_but_unsettled',\n} as const\n\nexport type AgentPaymentPhase = (typeof AgentPaymentPhase)[keyof typeof AgentPaymentPhase]\n\nexport const AgentPaymentNextAction = {\n /** Sign with the delegate key and submit the payment to Haven. */\n SignAndSubmitPayment: 'sign_and_submit_payment',\n /** Poll getPaymentStatus later using this payment id. */\n CheckStatusLater: 'check_status_later',\n /** No further agent action is required for this payment id. */\n None: 'none',\n /**\n * #2115: RETIRED wire value — no live rail produces it and nothing maps to\n * it. Stop and tell the user rather than polling; no approval will arrive.\n */\n WaitForUserApproval: 'wait_for_user_approval',\n /** #2115: RETIRED wire value — no live rail produces it. Stop and tell the user rather than polling. */\n WaitForUserToCompletePayment: 'wait_for_user_to_complete_payment',\n /** Resume this payment id and retry the original x402 request with the merchant payment header. */\n RetryOriginalX402Request: 'retry_original_x402_request',\n /** Stop retrying this payment and tell the user what happened. */\n StopAndTellUser: 'stop_and_tell_user',\n /** Ask again only if the user still wants the payment after expiry. */\n RequestAgainIfUserStillWantsIt: 'request_again_if_user_still_wants_it',\n /** #1307: retry the SAME tool call, supplying the explicit context fields the server could not rehydrate. */\n RetryWithExplicitContext: 'retry_with_explicit_context',\n /**\n * The x402 funding/quote window expired. Re-quote the same logical merchant\n * operation with the same idempotency key to stay double-charge-safe.\n */\n PaymentWindowExpired: 'payment_window_expired',\n /**\n * Stop and tell the user that the originating account needs to be funded or\n * the agent's per-token allowance needs to be raised before the payment\n * can succeed. A user approval will not fix this state on its own.\n *\n * #2914: the account-vocabulary spelling, and the only one — the\n * pre-#2907 `fund_safe_or_raise_allowance` wire value (and the\n * `AgentPaymentNextActionAccountAlias` seam #2908 added to bridge it) are\n * retired along with the rest of the #2908 compatibility window.\n */\n FundAccountOrRaiseAllowance: 'fund_account_or_raise_allowance',\n /**\n * The delegate wallet may hold funds that were sent from the agent's Haven\n * account but never settled to the merchant. The wallet owner should initiate\n * a sweep to return those funds to that account.\n */\n SweepStrandedFunds: 'sweep_stranded_funds',\n /**\n * #2970: a `submitted` erc7710 x402 intent whose settlement window has\n * passed with no on-chain settlement evidence Haven could verify. Distinct\n * from {@link CheckStatusLater}, which this REPLACES once the window is\n * past — but it is not futile: Haven's settlement sweep (120s tick) scans\n * each candidate over its own window plus a 120s clock-skew allowance, so\n * it can still attribute the settlement for a short while after this value\n * first appears. Poll {@link CheckStatusLater}'s tool\n * (`haven_get_payment_status`) once more, roughly two minutes later; if it\n * still shows no evidence, tell the user the goods were delivered but\n * Haven holds no verified settlement evidence for this payment. If the\n * agent holds the merchant's real settlement transaction hash (from\n * `PAYMENT-RESPONSE`'s `transaction` field, or a prior settle/complete\n * result's `settlement_tx_hash`), report it with the hosted\n * `haven_report_settlement_evidence` tool instead of waiting —\n * `haven_report_x402_outcome` takes no hash and refuses a non-`confirmed`\n * intent.\n */\n AwaitingSettlementEvidence: 'awaiting_settlement_evidence',\n} as const\n\nexport type AgentPaymentNextAction = (typeof AgentPaymentNextAction)[keyof typeof AgentPaymentNextAction]\n\nexport const AgentPaymentFailureCode = {\n /** A merchant-authoritative x402 price exceeds the caller's pre-funding max_amount cap. */\n PriceExceedsMax: 'PRICE_EXCEEDS_MAX',\n /** The x402 funding/quote window expired before the signer or hosted settle step could finish. */\n PaymentWindowExpired: 'PAYMENT_WINDOW_EXPIRED',\n /** The merchant rejected the paid retry. On eip3009 the funding leg had succeeded (sweep);\n * on erc7710 there is no funding leg — nothing to sweep, follow the message (#2983). */\n MerchantRejectedAfterFunding: 'MERCHANT_REJECTED_AFTER_FUNDING',\n /** #1300 review: funding is on-chain but the merchant never ANSWERED the\n * paid retry within the timeout. NOT proof of rejection — the merchant\n * may still settle late, so the guidance is verify-then-act. On eip3009\n * the funding leg had succeeded (verify-then-sweep); on erc7710 there is\n * no funding leg — nothing to sweep, follow the message (#3000). */\n MerchantUnresponsiveAfterFunding: 'MERCHANT_UNRESPONSIVE_AFTER_FUNDING',\n /**\n * #1307: the caller omitted merchant_url/tool_name (asking Haven to\n * rehydrate the stored MCP merchant-call context by payment_id), but no\n * usable context was stored for this intent — either it was never an\n * MCP-tool quote, or the stored context is incomplete. The fallback is\n * mechanical: re-send merchant_url, tool_name, arguments, and\n * mcp_transport explicitly (the version-skew path).\n */\n MerchantCallContextUnavailable: 'MERCHANT_CALL_CONTEXT_UNAVAILABLE',\n /**\n * #1351: the caller supplied BOTH the atomic `max_amount` and the\n * human-denominated `max_amount_human` cap for one purchase. Haven refuses\n * to guess which the user meant — the two differ by a factor of 10^decimals,\n * so picking wrong is exactly the silent-overspend this cap exists to\n * prevent. Rejected before any merchant probe, funding intent, or signature.\n */\n AmbiguousMaxAmount: 'AMBIGUOUS_MAX_AMOUNT',\n /**\n * #1351: a human-denominated cap was supplied, but it cannot be converted to\n * atomic units against THIS quote — either the quote's asset has no known\n * decimals on its network, or the cap carries more fraction digits than the\n * asset can represent (truncating it would silently change the user's cap).\n * The fallback is the exact atomic `max_amount`.\n */\n MaxAmountUnconvertible: 'MAX_AMOUNT_UNCONVERTIBLE',\n /**\n * #2979: the merchant answered a `tools/call` probe with its own\n * machine-readable \"cannot settle right now\" refusal (HTTP 503,\n * `{ error: 'merchant_not_ready', reason_code, ... }`) instead of a 402\n * challenge — e.g. its settlement wallet is out of gas. No 402 was ever\n * issued and no payment was created; this is honest and (per\n * `retry_after_s`, when present) usually transient, unlike a permanent\n * endpoint miss.\n */\n MerchantNotReady: 'MERCHANT_NOT_READY',\n} as const\n\nexport type AgentPaymentFailureCode = (typeof AgentPaymentFailureCode)[keyof typeof AgentPaymentFailureCode]\n\n/**\n * Stable rail identifier carried on Haven agent payment responses and resume\n * state.\n *\n * Two layers of vocabulary share this enum because both reach the wire:\n *\n * - **Categorical rails** identify the rail family and are used as the\n * `PaymentResumeState` discriminator: `direct`, `x402` (`mpp` remains a\n * valid categorical VALUE on historical status reads, but #1328 retired\n * the `MppResumeState` variant that used to carry it — the mpp_demo\n * client resume flow no longer exists).\n * - **Granular rails** identify the specific protocol the backend persists\n * and returns on response bodies: `mpp_demo`, `mpp_crypto`,\n * `stripe_deposit`, `spt`. `x402` doubles as both categorical and\n * granular.\n *\n * Consumers reading the top-level `rail` field on a payment status response\n * should treat any `mpp*` value as the MPP family — this still applies to\n * historical `mpp_demo` rows, which remain readable.\n */\nexport const AgentPaymentRail = {\n /** Standard Haven payment from the user's account, redeemed through the agent's budget delegation. */\n Direct: 'direct',\n /** x402 HTTP 402 payment flow with a Haven funding leg and merchant retry leg. */\n X402: 'x402',\n /** Machine Payment Protocol family — categorical value used as a resume-state discriminator. */\n Mpp: 'mpp',\n /** Haven internal MPP demo rail. Not for production traffic. */\n MppDemo: 'mpp_demo',\n /** Crypto-settled MPP rail. */\n MppCrypto: 'mpp_crypto',\n /** Stripe-deposit-backed MPP rail. */\n StripeDeposit: 'stripe_deposit',\n /** Stripe Payment Token MPP rail. */\n Spt: 'spt',\n} as const\n\nexport type AgentPaymentRail = (typeof AgentPaymentRail)[keyof typeof AgentPaymentRail]\n\nexport type PaymentPhase = AgentPaymentPhase\n\nexport type PaymentNextAction = AgentPaymentNextAction\n\nexport const AGENT_PAYMENT_PHASE_VALUES = Object.values(AgentPaymentPhase)\n\nexport const AGENT_PAYMENT_NEXT_ACTION_VALUES = Object.values(AgentPaymentNextAction)\n\nexport const AGENT_PAYMENT_FAILURE_CODE_VALUES = Object.values(AgentPaymentFailureCode)\n\nexport const AGENT_PAYMENT_RAIL_VALUES = Object.values(AgentPaymentRail)\n\nexport const AgentPaymentPhaseDescriptions: Record<AgentPaymentPhase, string> = {\n [AgentPaymentPhase.AgentSignatureRequired]: 'The agent must sign and submit the prepared payment before Haven can relay it.',\n [AgentPaymentPhase.PaymentSubmitted]: 'Haven has received the signed payment and the agent should poll for confirmation.',\n [AgentPaymentPhase.PaymentConfirmed]: 'The direct payment is confirmed; the agent does not need to do more for this payment id.',\n [AgentPaymentPhase.UserApprovalRequired]: 'Retired wire value: no live rail produces it. It described the Safe rail\\'s approval queue, which no longer exists — an out-of-policy payment is declined before any money moves. If it is ever seen, stop and tell the user; no approval is pending.',\n [AgentPaymentPhase.UserExecutionRequired]: 'Retired wire value: no live rail produces it. Stop and tell the user.',\n [AgentPaymentPhase.WaitingForAdditionalApprovals]: 'Retired wire value: no live rail produces it. Stop and tell the user.',\n [AgentPaymentPhase.FundingSent]: 'The Haven funding leg was sent; the agent can continue the merchant/protocol leg.',\n [AgentPaymentPhase.Rejected]: 'The payment was rejected and cannot proceed; the agent should stop and tell the user.',\n [AgentPaymentPhase.Expired]: 'The payment expired before completion.',\n [AgentPaymentPhase.Failed]: 'Haven could not complete the payment; the agent should stop and surface the failure.',\n [AgentPaymentPhase.InsufficientFunds]:\n 'Pre-flight check determined the delegate balance plus the remaining on-chain budget cannot cover the requested amount, so no payment was created. The account must be funded or the agent budget raised before retrying.',\n [AgentPaymentPhase.FundedButUnsettled]:\n \"Haven's funding leg confirmed on-chain but the merchant rejected the x402 retry. The delegate wallet may hold stranded funds. The agent should stop and wait for the wallet owner to sweep the stranded funds back to the account.\",\n}\n\nexport const AgentPaymentNextActionDescriptions: Record<AgentPaymentNextAction, string> = {\n [AgentPaymentNextAction.SignAndSubmitPayment]: 'Sign with the delegate key and submit the payment to Haven.',\n [AgentPaymentNextAction.CheckStatusLater]: 'Poll getPaymentStatus later using this payment id.',\n [AgentPaymentNextAction.None]: 'No further agent action is required for this payment id.',\n [AgentPaymentNextAction.WaitForUserApproval]: 'Retired wire value: no live rail produces it, and nothing maps to it. It described a per-payment approval queue that no longer exists. If it is ever seen, stop and tell the user rather than polling — no approval will arrive.',\n [AgentPaymentNextAction.WaitForUserToCompletePayment]: 'Retired wire value: no live rail produces it. Stop and tell the user rather than polling.',\n [AgentPaymentNextAction.RetryOriginalX402Request]: 'Resume this payment id and retry the original x402 request with the merchant payment header.',\n [AgentPaymentNextAction.StopAndTellUser]: 'Stop retrying this payment and tell the user what happened.',\n [AgentPaymentNextAction.RequestAgainIfUserStillWantsIt]: 'Ask again only if the user still wants the payment after expiry.',\n [AgentPaymentNextAction.PaymentWindowExpired]:\n 'The x402 funding/quote window expired. Re-quote with the same idempotency key before asking the signer to build a merchant payment header again.',\n [AgentPaymentNextAction.FundAccountOrRaiseAllowance]:\n 'Stop and tell the user that the account needs to be funded or the agent budget raised before the payment can succeed.',\n [AgentPaymentNextAction.RetryWithExplicitContext]:\n 'Retry the same tool call, this time passing merchant_url, tool_name, arguments, and mcp_transport explicitly — the server had no stored context to rehydrate for this payment id.',\n [AgentPaymentNextAction.SweepStrandedFunds]:\n 'Tell the user that funds may be stranded in the delegate wallet and prompt them to initiate a sweep in Haven to return them to the originating account.',\n [AgentPaymentNextAction.AwaitingSettlementEvidence]:\n \"The settlement window passed with no verified on-chain evidence yet. If you hold the merchant's real settlement transaction hash, report it with haven_report_settlement_evidence. Otherwise, Haven's settlement sweep may still attribute it within about two minutes — poll getPaymentStatus once more, then tell the user the goods were delivered but unverified if it still shows nothing.\",\n}\n\nexport const AgentPaymentFailureCodeDescriptions: Record<AgentPaymentFailureCode, string> = {\n [AgentPaymentFailureCode.PriceExceedsMax]:\n \"The merchant-authoritative x402 amount exceeds the caller's max_amount cap. No funding transfer was created; ask the user before retrying with a larger cap.\",\n [AgentPaymentFailureCode.PaymentWindowExpired]:\n 'The x402 funding/quote window expired before the signer or hosted settle step could finish. Re-quote via haven_pay_mcp_tool with the same idempotency key to avoid duplicate funding.',\n [AgentPaymentFailureCode.MerchantRejectedAfterFunding]:\n 'The merchant rejected the paid retry. eip3009: the funding leg succeeded — stop retrying the merchant and reconcile stranded delegate funds with haven_sweep_delegate. erc7710: no funding leg, nothing to sweep — follow the message (re-quote later, or check haven_get_payment_status after the window first).',\n [AgentPaymentFailureCode.MerchantUnresponsiveAfterFunding]:\n 'The merchant did not answer the paid retry before the timeout. The merchant may still settle late. eip3009: the funding leg succeeded — check haven_get_payment_status, retry haven_complete_mcp_tool once, sweep only if no settlement appears. erc7710: no funding leg, nothing to sweep, and haven_complete_mcp_tool has no erc7710 branch — do not retry it; check haven_get_payment_status after the payment window and re-quote only if it shows no settlement.',\n [AgentPaymentFailureCode.MerchantCallContextUnavailable]:\n 'merchant_url/tool_name were omitted and no stored merchant call context is available for this payment_id. Re-send merchant_url, tool_name, arguments, and mcp_transport explicitly.',\n [AgentPaymentFailureCode.AmbiguousMaxAmount]:\n 'Both max_amount (atomic units) and max_amount_human (whole tokens) were supplied for one purchase. Nothing was contacted and nothing was spent. Re-send with exactly ONE: max_amount_human for a cap the user stated in tokens, max_amount for an exact atomic figure.',\n [AgentPaymentFailureCode.MaxAmountUnconvertible]:\n \"max_amount_human could not be converted to atomic units against this quote's asset — either its decimals are unknown to Haven or the cap has more decimal places than the asset supports. Nothing was spent. Round the cap, or re-send it as an exact atomic max_amount.\",\n [AgentPaymentFailureCode.MerchantNotReady]:\n 'The merchant refused the probe with its own \"cannot settle right now\" signal instead of a 402 challenge. No payment was created. Often transient — retry later (see retry_after_s in the message, if given) rather than treating this as a broken or wrong endpoint.',\n}\n\n/**\n * #1308: machine-readable warning codes carried in the `warnings` array on\n * x402 MCP tool responses. Warnings are ADVISORY — they never replace a\n * refusal, and existing failure codes stay authoritative for errors. The\n * legacy `cap_warning` string field is kept for compatibility; the structured\n * entry carries the same message under MISSING_MAX_AMOUNT.\n */\nexport const AgentPaymentWarningCode = {\n /** No max_amount cap was supplied — the live quoted price was accepted as-is. */\n MissingMaxAmount: 'MISSING_MAX_AMOUNT',\n /** The signing window closes soon; sign promptly or re-quote with the same idempotency key. */\n QuoteExpiresSoon: 'QUOTE_EXPIRES_SOON',\n /** The merchant URL was resolved via discovery — pass the RESOLVED url forward. */\n MerchantUrlDiscovered: 'MERCHANT_URL_DISCOVERED',\n /**\n * #1306: the catalog's last-verified price_atomic differs from the LIVE\n * merchant quote for a guided catalog purchase. The catalog price is only\n * ever indicative; the live quote in the same response is authoritative.\n */\n CatalogPriceDiffers: 'CATALOG_PRICE_DIFFERS',\n /**\n * #1306: the rail-aware allowance/budget pre-check could not be read (RPC\n * failure, etc). `sufficient` is reported as null rather than a fabricated\n * true/false — the on-chain policy remains the actual gate either way.\n */\n AllowanceCheckUnavailable: 'ALLOWANCE_CHECK_UNAVAILABLE',\n /**\n * #1319: the delegation-rail read itself SUCCEEDED, but the remaining\n * figure it returned is the #1145 fallback (the full configured budget)\n * rather than a live ERC20PeriodTransferEnforcer read — `sufficient` is a\n * real true/false, just computed from an optimistic number. Distinct from\n * {@link AgentPaymentWarningCode.AllowanceCheckUnavailable}, which fires\n * when the read failed outright and `sufficient` degrades to null. The\n * on-chain policy re-checks at redemption either way; this only says the\n * guidance shown here may be optimistic.\n */\n AllowanceReadOptimistic: 'ALLOWANCE_READ_OPTIMISTIC',\n /**\n * #2991: the quote tools' `expected_settlement_scheme` prediction of what\n * `haven_prepare_catalog_purchase` / `haven_pay_mcp_tool` will actually\n * select could not be computed — the agent's execution rail could not be\n * read from Haven, so `expected_settlement_scheme` is `null` rather than a\n * guess. `accepted_scheme` (the merchant's offer) is unaffected.\n */\n X402SchemeUnknown: 'X402_SCHEME_UNKNOWN',\n /**\n * #2968: the merchant answered 200 and handed over goods, but Haven holds NO\n * on-chain evidence that the payment moved. `settled: false` beside this code\n * is not a failure — it is the absence of proof, and the two must travel\n * together so an agent can tell \"the user has the goods\" apart from \"the\n * money moved\". Carries the intent's `expires_at`: after that instant the\n * settlement can no longer land at all.\n */\n SettlementUnconfirmed: 'SETTLEMENT_UNCONFIRMED',\n} as const\n\nexport type AgentPaymentWarningCode =\n (typeof AgentPaymentWarningCode)[keyof typeof AgentPaymentWarningCode]\n\nexport interface AgentPaymentWarning {\n code: AgentPaymentWarningCode\n message: string\n}\n\n/**\n * #1308: the structured next-step contract on x402 MCP tool responses. It\n * EXTENDS the existing taxonomy — `next_action` values come from\n * AgentPaymentNextAction, never a parallel vocabulary. `next_arguments`\n * carries the small, literally-usable arguments; bulky pass-through fields\n * (payment_required) are named in `reason` and taken from the SAME response.\n */\nexport interface AgentNextStep {\n /** From `AgentPaymentNextAction`. */\n next_action: AgentPaymentNextAction\n /**\n * Claude-family namespaced tool name for the next call\n * (`mcp__<server>__<tool>`), when one exists.\n *\n * **Namespaced with the DEFAULT server names**, which is the most the hosted\n * server can know: local server names are the client's own config and never\n * reach Haven. Two runtimes are already not the default — Codex names servers\n * by config key (`haven`, `haven_signer`), and a connector run with\n * `--name <slug>` wires `haven-<slug>` / `haven-signer-<slug>` (#1694). On\n * either, this field and `next_tool_server` name a server the client does not\n * have. Prefer {@link AgentNextStep.next_tool_server_role} plus\n * {@link AgentNextStep.next_tool_name} whenever your servers are not the\n * default pair; see #2550.\n */\n next_tool?: string\n /**\n * The server half of `next_tool`, unprefixed — `haven` or `haven-signer`.\n * Carries the same default-name caveat as `next_tool` (#1588, #2550).\n */\n next_tool_server?: string\n /** The bare tool name, callable on whichever server plays the role below. */\n next_tool_name?: string\n /**\n * Which of the CLIENT'S OWN servers to call (#2550). Runtime-neutral, and\n * the field to resolve against when your server names are not the defaults —\n * it names a role rather than a name the hosted server had to guess.\n */\n next_tool_server_role?: 'hosted' | 'signer'\n /** Small literal arguments for next_tool. Bulky fields are referenced by reason. */\n next_arguments?: Record<string, unknown>\n /**\n * #3101 (epic #3105, decision 3): present exactly when `next_tool` is\n * absent — why no tool is named (the payment id is unknown, nothing is left\n * to do, the arguments could not be built). `next_tool` is never null.\n */\n next_tool_omitted_reason?: string\n /** False when the agent should stop and involve the user before continuing. */\n safe_to_continue: boolean\n reason: string\n}\n\n/**\n * #1349: compact, Haven-generated reporting evidence for a completed x402\n * merchant purchase. `status`, money fields, merchant endpoint/address, and\n * funding transaction come from Haven payment state; `product` and\n * `invoice_id` are optional merchant-supplied display metadata. The raw\n * merchant result remains separate evidence and MUST NOT be used to infer\n * settlement status.\n */\nexport interface AgentPurchaseSummary {\n /** Set only after Haven has completed the funding and merchant-settlement flow. */\n status: 'settled'\n product: string | null\n amount: string | null\n amount_atomic: string | null\n asset: string | null\n network: string | null\n merchant: {\n address: string | null\n resource_url: string | null\n }\n /** Merchant-supplied identifier, or null when the merchant did not supply one. */\n invoice_id: string | null\n funding_tx_hash: string | null\n /** Optional merchant receipt reference parsed from PAYMENT-RESPONSE; not Haven settlement proof. */\n settlement_tx_hash: string | null\n /** Same read-only allowance block returned at the top level, or null when unavailable. */\n allowance: PostPurchaseAllowanceSummary | null\n}\n\n/** #1308: compact reporting summary — what the agent tells the user. */\nexport interface AgentPaymentSummary {\n payment_id: string\n status: string\n amount?: string\n amount_atomic?: string\n token?: string\n network?: string\n expires_at?: string\n product?: string\n /**\n * Default reporting contract for a successful `haven_settle_mcp_tool` call.\n * The merchant's raw `result` remains available separately as advanced\n * evidence; do not parse it to determine whether a payment settled.\n */\n purchase_summary?: AgentPurchaseSummary\n}\n\nexport const AgentPaymentRailDescriptions: Record<AgentPaymentRail, string> = {\n [AgentPaymentRail.Direct]: 'Standard Haven payment from the user-controlled account, redeeming the agent\\'s on-chain budget delegation.',\n [AgentPaymentRail.X402]: 'x402 HTTP 402 payment flow with a Haven funding leg and merchant retry leg.',\n [AgentPaymentRail.Mpp]: 'Categorical MPP rail value used as a resume-state discriminator. Response bodies carry a granular mpp_* value instead.',\n [AgentPaymentRail.MppDemo]: 'Haven internal MPP demo rail. Not for production traffic.',\n [AgentPaymentRail.MppCrypto]: 'Crypto-settled MPP rail.',\n [AgentPaymentRail.StripeDeposit]: 'Stripe-deposit-backed MPP rail.',\n [AgentPaymentRail.Spt]: 'Stripe Payment Token MPP rail.',\n}\n\nexport const AgentPaymentPhaseSchema: AgentPaymentEnumSchema = {\n type: 'string',\n enum: AGENT_PAYMENT_PHASE_VALUES,\n description: 'Stable Haven agent payment state phase.',\n 'x-enumDescriptions': AgentPaymentPhaseDescriptions,\n}\n\nexport const AgentPaymentNextActionSchema: AgentPaymentEnumSchema = {\n type: 'string',\n enum: AGENT_PAYMENT_NEXT_ACTION_VALUES,\n description: 'Stable next action an agent should take for a Haven payment state.',\n 'x-enumDescriptions': AgentPaymentNextActionDescriptions,\n}\n\nexport const AgentPaymentFailureCodeSchema: AgentPaymentEnumSchema = {\n type: 'string',\n enum: AGENT_PAYMENT_FAILURE_CODE_VALUES,\n description: 'Stable machine-readable failure codes for Haven agent payment recovery paths.',\n 'x-enumDescriptions': AgentPaymentFailureCodeDescriptions,\n}\n\nexport const AgentPaymentRailSchema: AgentPaymentEnumSchema = {\n type: 'string',\n enum: AGENT_PAYMENT_RAIL_VALUES,\n description: 'Stable rail identifier for Haven agent payment states.',\n 'x-enumDescriptions': AgentPaymentRailDescriptions,\n}\n\nexport interface PaymentStatusResult {\n paymentId: string\n kind: PaymentStateKind\n rail: string\n status: PaymentStatus | string\n phase: PaymentPhase\n nextAction: PaymentNextAction\n amount: string\n token: string\n resourceUrl: string | null\n merchantAddress: string | null\n /** Delegate EOA captured on the payment intent when it was created. */\n payerAddress?: string | null\n /** #2960: additive alongside `payerAddress` above (`parties.delegate` only). */\n parties?: PaymentParties\n txHash: string | null\n expiresAt: string\n chainId: number\n message: string\n /** Platform fee surfaced so it's never silently collected (#386). */\n fee?: PaymentFee | null\n amountAtomic?: string | null\n asset?: string | null\n network?: string | null\n description?: string | null\n idempotencyKey?: string | null\n x402?: {\n amountAtomic: string | null\n asset: string | null\n network: string | null\n resourceUrl: string | null\n merchantAddress: string | null\n description: string | null\n idempotencyKey: string | null\n }\n mpp?: {\n amountAtomic: string | null\n asset: string | null\n network: string | null\n resourceUrl: string | null\n merchantAddress: string | null\n description: string | null\n idempotencyKey: string | null\n challengeId: string | null\n }\n}\n\n// ── PendingApproval (REMOVED, #2115) ────────────────────────────────────────\n//\n// `export interface PendingApproval extends PaymentStatusResult` stood here\n// with `nextAction: typeof AgentPaymentNextAction.WaitForUserApproval`. It is\n// REMOVED rather than retained-with-a-note, and the distinction from #2113's\n// retention decision is the point:\n//\n// - #2113 retained the `isPendingApproval` BRANCHES in both MCP runtimes and\n// the `pending` / `pending_approval` arms of `nextActionForStatus` here in\n// the SDK. Those are runtime code that still does useful work if a\n// pre-retirement row is ever read back — it answers `stop_and_tell_user`.\n// Retaining them is fail-closed.\n// - This was not runtime code. It was a TYPE asserting that a result with\n// `nextAction === 'wait_for_user_approval'` exists to be narrowed to. After\n// #2113 nothing in the SDK maps any status to `WaitForUserApproval`\n// (`nextActionForStatus` in `payment-state.ts`; zero non-test emissions\n// repo-wide), so no value the SDK produces can inhabit it. A consumer who\n// writes against it has written unreachable code with no runtime signal —\n// retaining it is not fail-closed, it is a promise the type system repeats.\n//\n// Its wire twin is already gone: #2105/PR #2112 deleted the `PendingApproval`\n// and `X402PendingApproval` schemas from `packages/backend/src/openapi/spec.ts`\n// outright (pinned by `spec.test.ts`), so the contract of record no longer\n// describes this shape on any response. This hand-written twin was what was\n// left, flagged on #1289 by that session.\n//\n// `PaymentStateKind` keeps `'approval_request'` and `AgentPaymentNextAction`\n// keeps `WaitForUserApproval` — both are retained wire values carrying the\n// #2055-style \"Retired wire value\" descriptions, and both are still reachable\n// from raw server data. What is gone is the interface that promised a\n// well-formed result of that shape.\n\n\n/** @internal */\nexport interface RawX402AuthorizeResponse {\n success?: boolean\n payment_id: string\n kind?: string\n rail?: string\n status: string\n phase?: string\n next_action?: string\n message?: string\n remaining?: string | null\n requested?: string\n tx_hash?: string\n chain_id?: number\n account_address?: string\n payer?: string\n token?: string\n amount?: string\n amount_atomic?: string | null\n asset?: string | null\n network?: string | null\n description?: string | null\n idempotency_key?: string | null\n to?: string\n merchant_to?: string | null\n merchant_address?: string | null\n x402_expected_auth?: X402ExpectedAuth\n resource_url?: string\n explorer_url?: string\n x402?: RawX402StateContext\n mpp?: RawMppStateContext\n challenge_id?: string\n expires_at?: string\n sign_data?: SignData\n error?: string\n}\n\n/** @internal Response of `POST /x402/:id/settle` (erc7710 direct settlement). */\nexport interface RawX402SettleResponse {\n success?: boolean\n payment_id?: string\n /** The backend-assembled MetaMask erc7710 X-PAYMENT header. */\n payment_header?: string\n status?: string\n error?: string\n}\n\n/**\n * Result of an erc7710 direct settlement (#1454).\n *\n * Deliberately NOT an `X402Receipt`. A 3009 receipt describes a completed\n * two-leg payment — funding tx included — whereas here nothing has settled yet\n * when this returns: the merchant redeems the delegation chain when the caller\n * retries with the header. Reusing the receipt type would let a caller read\n * `txHash` as \"paid\" on a payment that has not moved a cent.\n */\nexport interface X402Erc7710Settlement {\n paymentId: string\n /**\n * Pass verbatim as the `PAYMENT-SIGNATURE` header on the merchant retry —\n * that name ALONE. erc7710 is always x402 v2, and this header carries the\n * delegation chain, so also sending the legacy `X-PAYMENT` overflows the\n * merchant's header limit (HTTP 431, #2341).\n */\n paymentHeader: string\n /** The merchant address the child delegation is pinned to. */\n merchantPayTo: string\n amountAtomic: string\n asset: string\n network: string\n /** Facilitators the child is redeemable by, when the merchant advertised any. */\n facilitatorAddresses: string[] | null\n}\n\n// ── API Response Shapes (raw, snake_case from server) ────────────\n\n/** @internal */\nexport interface RawCreateResponse {\n payment_id: string\n kind?: string\n status: string\n phase?: string\n next_action?: string\n message?: string\n remaining?: string | null\n requested?: string\n expires_at: string\n sign_data: {\n hash: string\n /** 'eip712_userop' = delegation rail; absent = legacy AllowanceModule (raw ECDSA). The session rail's 'eip191_userop' is retired (#834). */\n signature_scheme?: 'eip712_userop'\n components: {\n /** The payer account — NOT the delegate `account`. */\n payer_account?: string\n token: string\n to: string\n amount: string\n payment_token: string\n payment: string\n nonce: number\n }\n instructions: string\n }\n error?: string\n supported?: string[]\n}\n\n/** @internal */\nexport interface RawSignResponse {\n payment_id: string\n kind?: string\n status: string\n phase?: string\n next_action?: string\n message?: string\n remaining?: string | null\n requested?: string\n tx_hash?: string\n token?: string\n amount?: string\n amount_atomic?: string | null\n asset?: string | null\n network?: string | null\n description?: string | null\n idempotency_key?: string | null\n to?: string\n merchant_to?: string | null\n merchant_address?: string | null\n resource_url?: string\n rail?: string\n x402?: RawX402StateContext\n mpp?: RawMppStateContext\n challenge_id?: string\n explorer_url?: string\n chain_id?: number\n expires_at?: string\n error?: string\n details?: string\n}\n\n/** @internal */\nexport interface RawStatusResponse {\n payment_id: string\n status: string\n token: string\n amount: string\n to: string\n tx_hash: string | null\n explorer_url?: string | null\n chain_id?: number\n fee?: { amount: string; token: string; basis_points: number; applied: boolean } | null\n error_message: string | null\n created_at: string\n signed_at: string | null\n submitted_at: string | null\n confirmed_at: string | null\n expires_at: string\n}\n\n/** @internal */\nexport interface RawPaymentStatusResult {\n payment_id: string\n kind: PaymentStateKind\n rail: string\n status: string\n phase: PaymentPhase\n next_action: PaymentNextAction\n amount: string\n token: string\n resource_url: string | null\n merchant_address: string | null\n payer_address?: string | null\n /** #2960: additive alongside `payer_address` above (`parties.delegate` only). */\n parties?: RawPaymentParties\n tx_hash: string | null\n expires_at: string\n chain_id: number\n message: string\n fee?: { amount: string; token: string; basis_points: number; applied: boolean } | null\n amount_atomic?: string | null\n asset?: string | null\n network?: string | null\n description?: string | null\n idempotency_key?: string | null\n x402?: RawX402StateContext\n mpp?: RawMppStateContext\n}\n\n/** @internal */\nexport interface RawHavenAgent {\n id: string\n name: string\n status: string\n account_address?: string\n delegate_address: string\n chain_id: number\n execution_rail: string\n}\n\n/** @internal */\nexport interface RawHavenAllowance {\n id: string\n token_address: string\n token_symbol: string\n configured_amount: string\n reset_period_min: number\n onchain: {\n amount: string\n spent: string\n remaining: string\n effective_spent: string\n reset_time_min: number\n last_reset_min: number\n nonce: number\n is_reset_pending: boolean\n /** #1319 — see {@link HavenAllowance.onchain.remainingIsFromChain}. */\n remaining_is_from_chain?: boolean\n }\n}\n\n/** @internal */\nexport interface RawHavenAllowanceSummary {\n agent_id: string\n account_address?: string\n delegate_address: string\n chain_id: number\n allowances: RawHavenAllowance[]\n}\n\n/** @internal */\nexport interface RawHavenPaymentReceipt {\n id: string\n /** #3132: present on a backend that states list scope per row; absent on older backends. */\n scope?: { source: 'wallet' | 'agent'; filter: 'agent' | 'account' | 'account+agent' | null }\n payment_id: string\n payment_intent_id?: string | null\n approval_request_id?: string | null\n rail: string\n proof_status: string\n /** @deprecated (#2998) — see `funding_tx_hash` / `settlement_tx_hash`. */\n tx_hash: string\n funding_tx_hash?: string | null\n settlement_tx_hash?: string | null\n chain_id: number\n resource_url: string\n merchant_address: string | null\n payer_address: string\n /** #2960: additive alongside `payer_address` above (`parties.treasury_account` only). */\n parties?: RawPaymentParties\n settlement_address: string\n token_symbol: string\n token_address: string\n amount_raw: string\n amount_human: string\n challenge_id: string | null\n idempotency_key: string | null\n challenge_payload?: Record<string, unknown> | null\n selected_payment?: Record<string, unknown> | null\n payment_proof_header_name: string | null\n protocol_receipt_header_name: string | null\n protocol_receipt_payload?: Record<string, unknown> | null\n merchant_status: number | null\n confirmed_at: string | null\n created_at: string\n updated_at: string\n}\n\n/** @internal */\n/** One payable service in Haven's merchant catalog (epic #1717). */\nexport interface HavenCatalogEntry {\n id: string\n name: string\n description: string\n category: string\n resourceUrl: string\n rail: 'x402' | 'mpp'\n protocol: 'http' | 'mcp'\n toolName: string | null\n toolArguments: Record<string, unknown> | null\n priceDisplay: string | null\n priceAtomic: string | null\n asset: string | null\n network: string | null\n status: 'active' | 'degraded' | 'delisted'\n verifiedAt: string | null\n /**\n * Where the entry came from. `operator` = curated in migrations/scripts\n * (the operator vouches for the listing; the catalog refresh probe still\n * checks the endpoint, see `verifiedPayable`). `ingestion` = submitted\n * through the Verified Payable Directory and passed domain-ownership proof\n * plus the read-only quote probe.\n */\n source: 'operator' | 'ingestion'\n /** True only for `ingestion` entries — the one ownership claim. See the epic's trust claim (never merchant honesty or quality). */\n domainVerified: boolean\n /**\n * True when Haven watched this endpoint answer a live quote (#2978): the\n * directory probe for `ingestion` rows, the periodic catalog refresh probe\n * for `operator` rows (`status === 'active'` with `verifiedAt` set). False\n * for a degraded row of either source. `discoverTools({ verified:\n * 'verified' })` filters on this field, not on `source`.\n */\n verifiedPayable: boolean\n /**\n * The merchant this entry belongs to (#3078). OPTIONAL on purpose: an\n * installed SDK may face a backend that predates the merchant layer, and\n * `discoverTools` must keep working against it — the field is absent, not\n * null, in that case.\n */\n merchant?: HavenCatalogMerchant\n}\n\n/** A catalog entry's merchant as the wire carries it (#3078). */\nexport interface HavenCatalogMerchant {\n id: string\n slug: string\n name: string\n /** `coming_soon` never reaches an entry in practice (a prospect has no offers). */\n listingStatus: 'live' | 'coming_soon'\n /** Haven-run test content: the demo store and the stranded-funds fixture. */\n isTestMerchant: boolean\n}\n\n/** @internal */\nexport interface RawCatalogEntryMerchant {\n id: string\n slug: string\n name: string\n listing_status: 'live' | 'coming_soon'\n is_test_merchant: boolean\n}\n\n/** @internal */\nexport interface RawCatalogEntry {\n id: string\n name: string\n description: string\n category: string\n resource_url: string\n rail: 'x402' | 'mpp'\n protocol: 'http' | 'mcp'\n tool_name: string | null\n tool_arguments: Record<string, unknown> | null\n price_display: string | null\n price_atomic: string | null\n asset: string | null\n network: string | null\n status: 'active' | 'degraded' | 'delisted'\n verified_at: string | null\n source: 'operator' | 'ingestion'\n domain_verified: boolean\n verified_payable: boolean\n /** Absent from a backend older than #3078; null when the join resolved nothing. */\n merchant?: RawCatalogEntryMerchant | null\n}\n\nexport interface RawHavenPaymentReceiptsResponse {\n receipts: RawHavenPaymentReceipt[]\n /** #3128 — optional on the wire so an older backend still maps. */\n total?: number\n has_more?: boolean\n next_cursor?: string | null\n}\n\n/**\n * #3128: one page of receipts. `total` is the count Haven holds for the\n * agent (an empty page with `total: 0` means no receipt exists — there is no\n * indexing delay behind this list); `hasMore` says the page was cut at the\n * limit; `nextCursor` is fed back as `cursor` for the next page. Against a\n * backend older than #3128 the three are `null` — \"unknown\", never a\n * fabricated 0 / false.\n */\nexport interface HavenPaymentReceiptsPage {\n receipts: HavenPaymentReceipt[]\n total: number | null\n hasMore: boolean | null\n nextCursor: string | null\n}\n\n/** @internal */\n/** Wire shape of POST /catalog/submit (#1717, #1716). */\nexport interface CatalogSubmissionAccepted {\n id: string\n verify_token: string\n status: 'submitted' | 'ownership_verified' | 'verified_payable'\n}\n\n/** @internal Client-facing submission handle. */\nexport interface HavenCatalogSubmission {\n id: string\n verifyToken: string\n status: 'submitted' | 'ownership_verified' | 'verified_payable'\n}\n\nexport interface RawX402StateContext {\n amount_atomic?: string | null\n asset?: string | null\n network?: string | null\n resource_url?: string | null\n merchant_address?: string | null\n description?: string | null\n idempotency_key?: string | null\n}\n\n/** @internal */\nexport interface RawMppStateContext {\n amount_atomic?: string | null\n asset?: string | null\n network?: string | null\n resource_url?: string | null\n merchant_address?: string | null\n description?: string | null\n idempotency_key?: string | null\n challenge_id?: string | null\n}\n\n// ── Error Types ──────────────────────────────────────────────────\n\nexport class HavenError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly statusCode?: number,\n public readonly paymentId?: string,\n ) {\n super(message)\n this.name = 'HavenError'\n }\n}\n\nexport class HavenApiError extends HavenError {\n constructor(\n message: string,\n statusCode: number,\n public readonly body?: unknown,\n paymentId?: string,\n ) {\n super(message, 'API_ERROR', statusCode, paymentId)\n this.name = 'HavenApiError'\n }\n}\n\n/**\n * #1300: quoteX402 hit a URL that answered something other than 402 — the\n * typed form of \"this is not the x402 endpoint\". Exists so consumers (the\n * hosted MCP's #1271 discovery trigger) can key on a class instead of\n * message text.\n */\n/**\n * #1300: a merchant-facing fetch hit the client-side merchantTimeout. Typed\n * so consumers can distinguish \"merchant never answered\" from a real HTTP\n * error response — the funded-retry path routes this to verify-then-sweep\n * guidance instead of a bare 504.\n */\nexport class MerchantTimeoutError extends HavenApiError {\n readonly merchantErrorCode = 'merchant_timeout' as const\n constructor(message: string) {\n super(message, 504)\n this.name = 'MerchantTimeoutError'\n }\n}\n\nexport class X402UnexpectedStatusError extends HavenApiError {\n readonly x402ErrorCode = 'unexpected_non_402_status' as const\n /**\n * #2979: `body` is the merchant's own JSON, when the non-402 response\n * carried one — e.g. the demo merchant's `/mcp` readiness gate answers\n * `503 { error: 'merchant_not_ready', reason_code, ... }`. Optional and\n * best-effort: a non-JSON or unreadable body leaves this `undefined`, same\n * as before this field existed. Consumers key on it (not on the message\n * string) to distinguish an honest, machine-readable merchant refusal from\n * a genuine \"this is not the x402 endpoint\" miss, which otherwise look\n * identical — both are just \"some non-402 status\".\n */\n constructor(message: string, statusCode: number, body?: unknown) {\n super(message, statusCode, body)\n this.name = 'X402UnexpectedStatusError'\n }\n}\n\n/**\n * #1521: the idempotency key resolved to a payment that has already settled,\n * and the delegate can no longer fund a fresh authorization for it.\n *\n * This is the typed form of \"you already bought this\". It exists because the\n * alternative was indefensible: the SDK used to mint a new EIP-3009\n * authorization against the spent delegate and hand it back paired with the\n * ORIGINAL payment's `txHash`, so the caller learned what had happened only\n * from a merchant-side balance error that reads identically to a broken\n * payment rail.\n *\n * `receipt` is the ORIGINAL payment — a real receipt for real settled funds,\n * deliberately carrying no `paymentHeader`, because any header minted here\n * would be exactly the unfundable artifact this error replaces.\n */\nexport class X402AlreadySettledError extends HavenApiError {\n readonly x402ErrorCode = 'already_settled' as const\n constructor(\n message: string,\n public readonly receipt: X402Receipt,\n /**\n * `settled` — the delegate was checked on-chain and cannot fund a fresh\n * authorization, so this payment demonstrably completed.\n * `unverifiable` — no `chainRpcs` entry for the chain, so fundability\n * could not be established either way. Same refusal, weaker claim; say\n * which, rather than assert what was not checked.\n */\n public readonly basis: 'settled' | 'unverifiable',\n ) {\n super(message, 409, undefined, receipt.paymentId)\n this.name = 'X402AlreadySettledError'\n }\n}\n\nexport class HavenPaymentStateError extends HavenApiError {\n resumeState?: X402ResumeState\n\n constructor(\n message: string,\n statusCode: number,\n public readonly state: PaymentStatusResult,\n body?: unknown,\n ) {\n super(message, statusCode, body, state.paymentId)\n this.name = 'HavenPaymentStateError'\n }\n\n get status(): string {\n return this.state.status\n }\n\n get phase(): PaymentPhase {\n return this.state.phase\n }\n\n get nextAction(): PaymentNextAction {\n return this.state.nextAction\n }\n}\n\nexport class HavenSigningError extends HavenError {\n constructor(message: string) {\n super(message, 'SIGNING_ERROR')\n this.name = 'HavenSigningError'\n }\n}\n\n/**\n * #2972: `MerchantCompletion.reportSettlementEvidence` /\n * `HavenClient.reportSettlementEvidence` refuse a `0x00…00` settlement hash\n * BEFORE any network call — see `isZeroSettlementTxHash`. That marker is\n * never a real transaction (the demo merchant's own \"delivered, not settled\"\n * value), so posting it to `POST /machine-payments/evidence` could only ever\n * come back refused, at the cost of a real round trip. A typed error rather\n * than a `HavenApiError`-shaped 400: no request was ever attempted, so there\n * is no HTTP status or response body to carry.\n */\nexport class HavenZeroSettlementHashError extends HavenError {\n constructor(paymentId: string) {\n super(\n 'settlement_tx_hash is the zero hash (0x00…00), which is never a real settlement ' +\n 'transaction — refused before any report was sent.',\n 'ZERO_SETTLEMENT_HASH',\n 400,\n paymentId,\n )\n this.name = 'HavenZeroSettlementHashError'\n }\n}\n\n/**\n * Refusal codes the local signer returns when it does not recognise the\n * VERSION of a Haven-signed binding it was asked to sign (#1309). Distinct\n * from `AgentPaymentFailureCode`: these describe a **signer capability**\n * problem (this install cannot evaluate what Haven sent), not a payment-domain\n * outcome, and they never reach the backend's REST/OpenAPI surface — only the\n * local signer's own MCP tool responses (`haven_sign` / `haven_sign_x402` /\n * `haven_sign_sweep_delegate`). That is also why this pair does not go through\n * the `AgentPaymentFailureCode` four-gate (sdk → backend mirror → spec →\n * api-types): there is no backend mirror to keep in sync with.\n */\nexport const SignerRefusalCode = {\n /** `SUPPORTED_X402_EXPECTED_VERSIONS` in `@haven_ai/signer` does not include the received version. */\n UnsupportedExpectedContextVersion: 'UNSUPPORTED_EXPECTED_CONTEXT_VERSION',\n /** `SUPPORTED_SWEEP_BINDING_VERSIONS` in `@haven_ai/signer` does not include the received version. */\n UnsupportedSweepBindingVersion: 'UNSUPPORTED_SWEEP_BINDING_VERSION',\n} as const\n\nexport type SignerRefusalCode = (typeof SignerRefusalCode)[keyof typeof SignerRefusalCode]\n\n/**\n * Canonical recovery guidance for a stale local signer (#1309) — the ONE\n * string both the signer's structured refusal (`fallback` field, carried by\n * `HavenUnsupportedSignerVersionError`) and the hosted quote's advisory\n * `signer_compatibility.fallback` (#1155) render, so an agent that meets\n * either surface is told the identical fix. A second hand-maintained copy of\n * this sentence is exactly how the two surfaces could start disagreeing about\n * what to do.\n */\nexport function signerUpdateFallback(channel: string = HAVEN_CONNECTOR_CHANNEL): string {\n return (\n `Update @haven_ai/signer by rerunning \\`${connectorRerunCommand(undefined, { channel })}\\`, which reinstalls the ` +\n 'pinned MCP runtime, then retry the same signing call. Nothing was signed or spent — the ' +\n 'quote or payment this version came from is unaffected and does not need to be re-quoted.'\n )\n}\n\n/**\n * The same sentence rendered for THIS build's channel (#2423). Every existing\n * consumer keeps importing this constant and keeps getting a string; the only\n * thing that moved is that `alpha` is no longer typed into it.\n *\n * The hosted MCP server is the one caller that does NOT use this constant: it\n * is deployed rather than published, so it renders `signerUpdateFallback()`\n * with the channel its own environment names.\n */\nexport const SIGNER_UPDATE_FALLBACK = signerUpdateFallback()\n\n/**\n * Thrown by the local signer when a Haven-signed binding (x402 expected\n * context or sweep authorization) carries a version outside what this signer\n * install enforces (#1143, structured as #1309). Machine-readable: `code`,\n * `supportedVersions`, and `receivedVersion` are DERIVED from the signer's own\n * `SUPPORTED_X402_EXPECTED_VERSIONS` / `SUPPORTED_SWEEP_BINDING_VERSIONS`\n * constants at the throw site, never a second literal — see\n * `assertSupportedBindingVersion` in `@haven_ai/signer`.\n *\n * This narrows HOW the refusal is reported. It does not weaken it: nothing is\n * signed either way, and the version stays inside the Haven-signed binding\n * message (callers must not \"fix\" a mismatch by rewriting it).\n */\nexport class HavenUnsupportedSignerVersionError extends HavenError {\n constructor(\n message: string,\n code: SignerRefusalCode,\n public readonly supportedVersions: readonly number[],\n public readonly receivedVersion: number,\n public readonly fallback: string,\n ) {\n super(message, code)\n this.name = 'HavenUnsupportedSignerVersionError'\n }\n}\n\nexport class HavenTimeoutError extends HavenError {\n constructor(paymentId: string) {\n super(\n `Timed out waiting for payment ${paymentId} to confirm`,\n 'TIMEOUT',\n undefined,\n paymentId,\n )\n this.name = 'HavenTimeoutError'\n }\n}\n","import { encodeAbiParameters, getAddress, isAddress, keccak256, type Hex } from 'viem'\nimport { HavenError } from './types.js'\n\n/**\n * #3271: the integrity check every client runs before signing a direct\n * delegation-rail payment's typed data.\n *\n * A direct payment (`POST /payments`, surfaced as `haven_send` / `haven_pay`)\n * is signed as the HybridDeleGator's EIP-712 `PackedUserOperation`, and Haven\n * returns two things for it: that typed data, and `payload_hash` — the\n * ERC-4337 v0.7 UserOperation hash of the same operation. Nothing used to tie\n * the two together at signing time. The typed data is multi-KB and reaches the\n * signer through a language model when it is relayed by hand, so one corrupted\n * character produced a valid-looking signature over the wrong digest, and the\n * first sign of it was `AA24 signature error` from the bundler (#3271,\n * reproduced on dev 2026-09-24).\n *\n * This recomputes the v0.7 hash from the typed data's own message and domain\n * and refuses unless it equals `payload_hash`, and it pins the parts of the\n * typed data the hash does NOT cover (domain name/version/verifyingContract,\n * the field list, the EntryPoint). It is a CORRUPTION check: the caller supplies\n * both values, so it proves they describe the same operation, never that Haven\n * prepared it. Provenance is the byte-free sign context (`payment_id`); what a\n * delegate key will sign at all is `assertBoundDirectPaymentUserOp`\n * (`direct-payment-guard.ts`, #3272 / #3283), which every caller of this check\n * — `HavenClient.signForData` and the signer's `haven_sign` — runs next.\n *\n * Pure viem, no ethers: `@haven_ai/sdk/edge` re-exports it for the edge signer,\n * and `edge-imports.test.ts` pins that graph.\n */\n\n/** Version of the direct-payment sign context (`GET /payments/:id/sign-context`). */\nexport const DIRECT_SIGN_CONTEXT_VERSION = 1\n\n/** The HybridDeleGator EIP-712 domain, in the canonical EIP-712 field order. */\nconst EIP712_DOMAIN_FIELDS = [\n { name: 'name', type: 'string' },\n { name: 'version', type: 'string' },\n { name: 'chainId', type: 'uint256' },\n { name: 'verifyingContract', type: 'address' },\n] as const\n\n/** The ERC-4337 v0.7 EntryPoint — the only one the delegation rail submits to. */\nexport const ENTRY_POINT_V07 = '0x0000000071727De22E5E9d8BAf0edAc6f37da032'\n\n/**\n * The HybridDeleGator EIP-712 domain constants and the `PackedUserOperation`\n * field list, vendored from `@metamask/smart-accounts-kit`\n * (`contracts.HybridDeleGator.constants`, `SIGNABLE_USER_OP_TYPED_DATA`) so the\n * published packages need no runtime dependency on the kit. Pinned equal to the\n * kit's values by `userop-binding.test.ts`.\n */\nexport const HYBRID_DELEGATOR_DOMAIN_NAME = 'HybridDeleGator'\nexport const HYBRID_DELEGATOR_DOMAIN_VERSION = '1'\nexport const PACKED_USER_OPERATION_FIELDS: ReadonlyArray<{ name: string; type: string }> = [\n { name: 'sender', type: 'address' },\n { name: 'nonce', type: 'uint256' },\n { name: 'initCode', type: 'bytes' },\n { name: 'callData', type: 'bytes' },\n { name: 'accountGasLimits', type: 'bytes32' },\n { name: 'preVerificationGas', type: 'uint256' },\n { name: 'gasFees', type: 'bytes32' },\n { name: 'paymasterAndData', type: 'bytes' },\n { name: 'entryPoint', type: 'address' },\n]\n\n/** Refusal raised when UserOperation typed data (a direct payment, or the SDK's x402 funding leg) does not match its `payload_hash`. */\nexport class HavenUserOpBindingError extends HavenError {\n constructor(message: string) {\n super(message, 'USEROP_BINDING_MISMATCH')\n this.name = 'HavenUserOpBindingError'\n }\n}\n\n/** True when the typed data is a `PackedUserOperation` (the direct-payment shape). */\nexport function isPackedUserOperationTypedData(value: unknown): boolean {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as { primaryType?: unknown }).primaryType === 'PackedUserOperation'\n )\n}\n\nconst HEX = /^0x[0-9a-fA-F]*$/\nconst BYTES32 = /^0x[0-9a-fA-F]{64}$/\n\nfunction refuse(detail: string): never {\n throw new HavenUserOpBindingError(\n `Refusing to sign: this UserOperation typed data does not match its payload_hash (${detail}). ` +\n 'The payload was altered between the Haven result and this call — sign by payment_id so the ' +\n 'signer fetches the exact bytes, or pass typed_data_b64 from the result unchanged.',\n )\n}\n\nfunction hexField(message: Record<string, unknown>, key: string, pattern: RegExp): Hex {\n const value = message[key]\n if (typeof value !== 'string' || !pattern.test(value)) refuse(`message.${key} is not well-formed`)\n return value as Hex\n}\n\nfunction uintField(message: Record<string, unknown>, key: string): bigint {\n const value = message[key]\n try {\n if (typeof value === 'bigint') return value\n if ((typeof value === 'string' && /^(0x[0-9a-fA-F]+|[0-9]+)$/.test(value)) || typeof value === 'number') {\n const n = BigInt(value)\n if (n >= 0n) return n\n }\n } catch {\n // fall through to the refusal\n }\n return refuse(`message.${key} is not an unsigned integer`)\n}\n\nfunction addressField(value: unknown, where: string): `0x${string}` {\n if (typeof value !== 'string' || !isAddress(value, { strict: false })) refuse(`${where} is not an address`)\n return getAddress(value as string)\n}\n\n/**\n * Compute the ERC-4337 v0.7 UserOperation hash from a HybridDeleGator\n * `PackedUserOperation` typed-data object — the value Haven returns as\n * `payload_hash` for a direct payment (`getUserOperationHash`, entryPoint 0.7).\n */\nexport function packedUserOperationHash(typedData: unknown): Hex {\n if (!isPackedUserOperationTypedData(typedData)) refuse('primaryType is not PackedUserOperation')\n const td = typedData as { domain?: Record<string, unknown>; message?: Record<string, unknown> }\n const message = td.message\n if (!message || typeof message !== 'object') refuse('message is missing')\n const chainId = uintField({ chainId: td.domain?.chainId }, 'chainId')\n const inner = keccak256(\n encodeAbiParameters(\n [\n { type: 'address' },\n { type: 'uint256' },\n { type: 'bytes32' },\n { type: 'bytes32' },\n { type: 'bytes32' },\n { type: 'uint256' },\n { type: 'bytes32' },\n { type: 'bytes32' },\n ],\n [\n addressField(message.sender, 'message.sender'),\n uintField(message, 'nonce'),\n keccak256(hexField(message, 'initCode', HEX)),\n keccak256(hexField(message, 'callData', HEX)),\n hexField(message, 'accountGasLimits', BYTES32),\n uintField(message, 'preVerificationGas'),\n hexField(message, 'gasFees', BYTES32),\n keccak256(hexField(message, 'paymasterAndData', HEX)),\n ],\n ),\n )\n return keccak256(\n encodeAbiParameters(\n [{ type: 'bytes32' }, { type: 'address' }, { type: 'uint256' }],\n [inner, addressField(message.entryPoint, 'message.entryPoint'), chainId],\n ),\n )\n}\n\n/**\n * Refuse (throw `HavenUserOpBindingError`) unless this `PackedUserOperation`\n * typed data is the operation `payloadHash` names, in the HybridDeleGator\n * domain of its own sender, against the v0.7 EntryPoint. Returns the\n * recomputed hash.\n */\nexport function assertUserOpTypedDataBinding(typedData: unknown, payloadHash: string): Hex {\n if (typeof payloadHash !== 'string' || !BYTES32.test(payloadHash)) refuse('payload_hash is not a 32-byte hex string')\n if (!isPackedUserOperationTypedData(typedData)) refuse('primaryType is not PackedUserOperation')\n const td = typedData as {\n domain?: Record<string, unknown>\n types?: Record<string, unknown>\n message?: Record<string, unknown>\n }\n const domain = td.domain ?? {}\n const message = td.message ?? {}\n if (domain.name !== HYBRID_DELEGATOR_DOMAIN_NAME) refuse('domain.name is not HybridDeleGator')\n if (domain.version !== HYBRID_DELEGATOR_DOMAIN_VERSION) refuse('domain.version is not 1')\n if (addressField(domain.verifyingContract, 'domain.verifyingContract') !== addressField(message.sender, 'message.sender')) {\n refuse('domain.verifyingContract is not message.sender')\n }\n if (addressField(message.entryPoint, 'message.entryPoint') !== getAddress(ENTRY_POINT_V07)) {\n refuse('message.entryPoint is not the v0.7 EntryPoint')\n }\n const fields = (td.types ?? {}).PackedUserOperation\n if (\n !Array.isArray(fields) ||\n fields.length !== PACKED_USER_OPERATION_FIELDS.length ||\n fields.some(\n (f, i) =>\n !f ||\n (f as { name?: unknown }).name !== PACKED_USER_OPERATION_FIELDS[i].name ||\n (f as { type?: unknown }).type !== PACKED_USER_OPERATION_FIELDS[i].type,\n )\n ) {\n refuse('types.PackedUserOperation is not the HybridDeleGator field list')\n }\n const extraTypes = Object.keys(td.types ?? {}).filter((k) => k !== 'PackedUserOperation' && k !== 'EIP712Domain')\n if (extraTypes.length > 0) refuse(`unexpected types: ${extraTypes.join(', ')}`)\n // The domain separator is not covered by payload_hash, and viem honours a\n // supplied `types.EIP712Domain` and any extra domain key (e.g. `salt`) when\n // it builds the digest — so both are pinned exactly, or a corrupted domain\n // would pass this check and still sign over the wrong digest.\n const domainKeys = Object.keys(domain).sort()\n if (domainKeys.join(',') !== [...EIP712_DOMAIN_FIELDS.map((f) => f.name)].sort().join(',')) {\n refuse(`domain keys are not exactly ${EIP712_DOMAIN_FIELDS.map((f) => f.name).join(', ')}`)\n }\n const declaredDomain = (td.types ?? {}).EIP712Domain\n if (\n declaredDomain !== undefined &&\n (!Array.isArray(declaredDomain) ||\n declaredDomain.length !== EIP712_DOMAIN_FIELDS.length ||\n declaredDomain.some(\n (f, i) =>\n !f ||\n (f as { name?: unknown }).name !== EIP712_DOMAIN_FIELDS[i].name ||\n (f as { type?: unknown }).type !== EIP712_DOMAIN_FIELDS[i].type,\n ))\n ) {\n refuse('types.EIP712Domain is not the canonical name/version/chainId/verifyingContract list')\n }\n const recomputed = packedUserOperationHash(typedData)\n if (recomputed.toLowerCase() !== payloadHash.toLowerCase()) refuse('recomputed UserOperation hash differs')\n return recomputed\n}\n","/**\n * Independent verification of an erc7710 x402 settlement child (#1455).\n *\n * Moved from `@haven_ai/signer` into the SDK by #3283 (epic #3284) so the\n * signer and `HavenClient.signForData` run ONE verifier. The signer checks the\n * child against the Haven-signed expected context; the SDK checks it against\n * the merchant's own 402, which Haven does not produce.\n *\n * WHY THIS EXISTS. `assertExpectedBinding` proves Haven *declared* a payload:\n * the expected context is signed by `HAVEN_X402_BINDING_SIGNER` and commits to\n * the digest of the exact bytes being signed. That is a real property, and it\n * is not this one. It says nothing about what the payload MEANS.\n *\n * A backend that declared `merchantTo = the real merchant` while pinning a\n * different payee in the child's `AllowedCalldata` caveat would produce a\n * perfectly consistent pair: the declaration binds the digest, the digest is\n * the child's, and the child pays someone else. The signature is the authority\n * here — the merchant's facilitator redeems it and pulls from the treasury — so\n * the signer has to re-derive the meaning locally or it is a pass-through with\n * extra steps.\n *\n * ADDRESSES ARE PINNED HERE ON PURPOSE. Reading the enforcer map from Haven\n * would make the check circular: an attacker who can pick which contract counts\n * as \"the payee enforcer\" can satisfy any comparison. Taking\n * `@metamask/smart-accounts-kit` as a runtime dependency was the other option\n * and was rejected — this package installs on users' machines. The constants\n * below are snapshot-pinned and cross-checked against the kit by a test\n * (`packages/signer/src/settlement-child.pins.test.ts`), the same pattern\n * `packages/core/src/chains.ts` uses against its registry.\n *\n * EXTRA CAVEATS ARE ALLOWED, and that is deliberate — verified, not assumed\n * (#1455 review challenged it directly).\n *\n * `DelegationManager.redeemDelegations` loops every caveat of every delegation\n * and calls `beforeHook` on each, with no break and no try/catch: a single\n * revert aborts the whole redemption, and nothing lets one caveat cause another\n * to be skipped. Top-level caveats are therefore strictly AND-ed, so one this\n * file does not recognise can only add a constraint, never remove one.\n *\n * The specific challenge was `LogicalOrWrapperEnforcer`, whose terms encode\n * several caveat GROUPS and whose own security notice warns that \"the redeemer\n * can select the least restrictive group, bypassing stricter requirements in\n * other groups\". That warning is about groups INSIDE the wrapper — it binds\n * whoever authors wrapper terms. The wrapper is itself one caveat among the\n * delegation's, so it is AND-ed with the four required below and cannot unlock\n * them.\n *\n * The shape that WOULD be dangerous is the inverse: a required caveat hidden\n * inside a wrapper group instead of sitting at top level, where the redeemer\n * could select a group that omits it. This file scans top-level caveats and\n * refuses on absence, so that child is refused for lacking the caveat — which\n * is the correct outcome and is pinned by a test.\n */\n\nimport { HavenSigningError } from './types.js'\n\n/** DelegationManager, the EIP-712 `verifyingContract` for a delegation. */\nexport const DELEGATION_MANAGER = '0xdb9B1e94B5b69Df7e401DDbedE43491141047dB3'\n\n/**\n * Caveat enforcers, by role. Deterministically deployed, so Base and Base\n * Sepolia share addresses — verified for both chains by the pin test.\n */\nexport const CAVEAT_ENFORCERS = {\n erc20TransferAmount: '0xf100b0819427117EcF76Ed94B358B1A5b5C6D2Fc',\n allowedCalldata: '0xc2b0d624c1c4319760C96503BA27C347F3260f55',\n timestamp: '0x1046bb45C8d673d4ea75321280DB34899413c069',\n redeemer: '0xE144b0b2618071B4E56f746313528a669c7E65c5',\n} as const\n\n/** The backend's own ceiling (`MAX_SETTLEMENT_WINDOW_SECONDS`), enforced again here. */\nexport const MAX_SETTLEMENT_WINDOW_SECONDS = 600\n\nexport interface SettlementChildTypedData {\n domain: { name?: string; version?: string; chainId?: number | string; verifyingContract?: string }\n types: Record<string, unknown>\n primaryType: string\n message: Record<string, unknown>\n}\n\ninterface Caveat {\n enforcer: string\n terms: string\n}\n\n/**\n * True when this typed data is a delegation — the shape that must never be\n * signed unbound. Excludes a SELF-delegation (`delegate === delegator`,\n * #3329): that is the shape of a task-budget child\n * (`task-budget-guards.ts`'s `isTaskChildTypedData`), a DIFFERENT typed-data\n * class verified by a different function against a different expectation. A\n * real settlement child's `delegate` is always a facilitator or\n * `ANY_BENEFICIARY` — never this account's own address — so narrowing here\n * costs this verifier nothing and keeps the two classes from ever\n * overlapping.\n */\nexport function isSettlementChildTypedData(value: unknown): value is SettlementChildTypedData {\n const td = value as SettlementChildTypedData | undefined\n if (\n !td ||\n td.primaryType !== 'Delegation' ||\n typeof td.domain?.verifyingContract !== 'string' ||\n !Array.isArray((td.message as { caveats?: unknown })?.caveats)\n ) {\n return false\n }\n const delegate = td.message?.delegate\n const delegator = td.message?.delegator\n if (\n typeof delegate === 'string' &&\n typeof delegator === 'string' &&\n delegate.toLowerCase() === delegator.toLowerCase()\n ) {\n return false\n }\n return true\n}\n\nfunction same(a: string | undefined, b: string | undefined): boolean {\n return !!a && !!b && a.toLowerCase() === b.toLowerCase()\n}\n\nfunction hex(value: string): string {\n return value.startsWith('0x') ? value.slice(2).toLowerCase() : value.toLowerCase()\n}\n\n/** Byte slice [start, end) of a `0x…` string, as lowercase hex without prefix. */\nfunction slice(terms: string, start: number, end?: number): string {\n const body = hex(terms)\n return end === undefined ? body.slice(start * 2) : body.slice(start * 2, end * 2)\n}\n\nfunction findCaveat(caveats: Caveat[], enforcer: string): Caveat | undefined {\n return caveats.find((c) => same(c.enforcer, enforcer))\n}\n\nfunction refuse(what: string, detail: string): never {\n throw new HavenSigningError(\n `Refusing to sign the x402 settlement child: ${what}. ${detail} ` +\n 'The signature on this child is what lets a merchant pull from the treasury, so it is ' +\n 'verified locally against an expectation Haven cannot rewrite, rather than trusted.',\n )\n}\n\n/**\n * Map an x402 network string to a chain id. Local on purpose (#1455 review):\n * the chain must come from Haven's SIGNED `network` field, never from the\n * payload under verification — see `verifySettlementChild`.\n */\nexport function chainIdForNetwork(network: string | undefined): number | undefined {\n if (!network) return undefined\n const caip = /^eip155:(\\d+)$/.exec(network)\n if (caip) return Number(caip[1])\n if (network === 'base') return 8453\n if (network === 'base-sepolia') return 84532\n return undefined\n}\n\nexport interface SettlementChildExpectation {\n merchantTo: string\n amount: string\n asset: string\n /**\n * Derived from the expected context's SIGNED `network`, never from\n * `typedData.domain.chainId`. Comparing the payload's own claim against\n * itself is a check that cannot fail — which is exactly what shipped in the\n * first draft of this file's call site, and what the review caught.\n */\n chainId: number\n /** ISO timestamp; the child must not outlive it. */\n expiresAt?: string\n /**\n * #3283 / #3281 criterion 8: the signer's OWN derived delegate account.\n * When set, the child's `delegator` must be exactly this account — the\n * child is a re-delegation of this agent's budget, never a grant from some\n * other account the key happens to control.\n */\n delegatorAccount?: string\n /**\n * #3283: the facilitator addresses the merchant's 402 advertised\n * (`extra.facilitatorAddresses`). When non-empty, the child must carry a\n * `RedeemerEnforcer` caveat pinning exactly this set — otherwise the child\n * is a bearer instrument any party could redeem within its bounds.\n */\n redeemers?: readonly string[]\n}\n\n/** `@metamask/delegation-core`'s `ROOT_AUTHORITY` — a delegation chained to nothing. */\nexport const ROOT_AUTHORITY = `0x${'ff'.repeat(32)}`\n\n/**\n * Verify a settlement child implements what the expected context declares.\n * Throws `HavenSigningError` on any disagreement; returns nothing on success.\n *\n * `now` is injectable so the expiry checks are testable without faking clocks.\n */\nexport function verifySettlementChild(\n typedData: SettlementChildTypedData,\n expected: SettlementChildExpectation,\n now: number = Date.now(),\n): void {\n // ── The delegation's own frame ────────────────────────────────────────────\n if (typedData.primaryType !== 'Delegation') {\n refuse('it is not a Delegation payload', `primaryType was '${typedData.primaryType}'.`)\n }\n if (!same(typedData.domain?.verifyingContract, DELEGATION_MANAGER)) {\n // A different verifying contract means a different DelegationManager —\n // every caveat address below would then be meaningless to compare.\n refuse(\n 'the EIP-712 domain names an unknown DelegationManager',\n `Expected ${DELEGATION_MANAGER}, got ${typedData.domain?.verifyingContract}.`,\n )\n }\n const domainChain = Number(typedData.domain?.chainId)\n if (!Number.isFinite(domainChain) || domainChain !== expected.chainId) {\n refuse(\n 'it is scoped to the wrong chain',\n `The expected context says chain ${expected.chainId}; the child says ${typedData.domain?.chainId}.`,\n )\n }\n\n // ── Authority: a re-delegation of the budget, never a root grant ──────────\n // A settlement child's `authority` is the hash of the agent's budget\n // delegation (`parentDelegation` in the backend's builder), so the\n // DelegationManager meters the spend through that budget's enforcers. A\n // ROOT authority would instead make the child a grant straight from its\n // `delegator` — the agent's own account — to whoever redeems it (#3283 /\n // #3281 criterion 8). Any non-ROOT authority must resolve on-chain to a\n // delegation made TO this account, which only the account owner can sign,\n // so the budget's caveats still bound it; the exact parent hash is not\n // knowable here without trusting Haven for it, and is not needed for that.\n const authority = typedData.message?.authority\n if (typeof authority !== 'string' || !/^0x[0-9a-fA-F]{64}$/.test(authority)) {\n refuse('its authority is not a 32-byte delegation hash', `Got ${String(authority)}.`)\n }\n if (authority.toLowerCase() === ROOT_AUTHORITY) {\n refuse(\n 'it is a ROOT delegation, not a re-delegation of the agent budget',\n \"A root child would grant its redeemer authority over the agent's own account instead \" +\n \"of spending through the budget delegation's enforcers.\",\n )\n }\n if (expected.delegatorAccount !== undefined) {\n const delegator = typedData.message?.delegator\n if (typeof delegator !== 'string' || !same(delegator, expected.delegatorAccount)) {\n refuse(\n \"it is delegated by an account other than this agent's own\",\n `Expected delegator ${expected.delegatorAccount}; the child names ${String(delegator)}.`,\n )\n }\n // #3329: a settlement child's `delegate` is a facilitator or\n // `ANY_BENEFICIARY` — never this same account. `delegate === delegator`\n // is a SELF-delegation, the task-budget child shape\n // (`task-budget-guards.ts`'s `isTaskChildTypedData`), a DIFFERENT\n // typed-data class verified by a different function against a different\n // expectation. Refused here whatever its amount/payee/expiry say: those\n // caveats can coincidentally match a settlement expectation (a task\n // child's caveats are real EIP-712 bytes, not inert placeholders), and\n // this is the one check in this function that reads WHO may redeem\n // rather than what the redemption is bounded to.\n const delegate = typedData.message?.delegate\n if (typeof delegate === 'string' && same(delegate, delegator)) {\n refuse(\n 'its delegate is the same account as its delegator (a self-delegation)',\n 'A settlement child is always redeemed by a facilitator or left open to any redeemer — ' +\n 'never redeemable only by the account that granted it. This is the shape of a ' +\n 'task-budget child, a different typed-data class Haven never signs through this path.',\n )\n }\n }\n\n const caveats = (typedData.message?.caveats as Caveat[] | undefined) ?? []\n if (caveats.length === 0) {\n refuse('it carries no caveats at all', 'An unconstrained delegation is not a payment.')\n }\n\n // ── Asset + amount: `ERC20TransferAmountEnforcer` ─────────────────────────\n // terms = 20-byte token ‖ 32-byte amount\n const transfer = findCaveat(caveats, CAVEAT_ENFORCERS.erc20TransferAmount)\n if (!transfer) {\n refuse(\n 'it has no ERC-20 transfer-amount caveat',\n 'Without it the delegation is not bounded to an amount.',\n )\n }\n const token = `0x${slice(transfer.terms, 0, 20)}`\n if (!same(token, expected.asset)) {\n refuse('it spends a different token', `Expected ${expected.asset}, child pins ${token}.`)\n }\n const amount = BigInt(`0x${slice(transfer.terms, 20, 52)}`)\n if (amount !== BigInt(expected.amount)) {\n refuse(\n 'the amount does not match',\n `The expected context says ${expected.amount}; the child allows ${amount.toString()}.`,\n )\n }\n\n // ── Payee: `AllowedCalldataEnforcer` ──────────────────────────────────────\n // terms = uint256 startIndex ‖ 32-byte value. startIndex 4 is the `to` word\n // of `transfer(address,uint256)`, i.e. the payee is pinned.\n const calldata = findCaveat(caveats, CAVEAT_ENFORCERS.allowedCalldata)\n if (!calldata) {\n refuse(\n 'it has no payee pin',\n 'Without an allowed-calldata caveat the merchant could redeem it to any address.',\n )\n }\n const startIndex = BigInt(`0x${slice(calldata.terms, 0, 32)}`)\n if (startIndex !== 4n) {\n refuse(\n 'the payee pin points at the wrong calldata offset',\n `Expected offset 4 (the transfer's \\`to\\` word), got ${startIndex.toString()}.`,\n )\n }\n // The value is the address left-padded to 32 bytes: 12 zero bytes then 20.\n const paddedPayee = slice(calldata.terms, 32, 64)\n if (paddedPayee.slice(0, 24) !== '0'.repeat(24)) {\n refuse('the pinned payee is not a plain address', 'Its 32-byte word is not a padded address.')\n }\n const payee = `0x${paddedPayee.slice(24)}`\n if (!same(payee, expected.merchantTo)) {\n refuse(\n 'it pays a different address than Haven declared',\n `The expected context says ${expected.merchantTo}; the child pins ${payee}.`,\n )\n }\n\n // ── Expiry: `TimestampEnforcer` ───────────────────────────────────────────\n // terms = uint128 afterThreshold ‖ uint128 beforeThreshold (seconds).\n const timestamp = findCaveat(caveats, CAVEAT_ENFORCERS.timestamp)\n if (!timestamp) {\n refuse('it never expires', 'A settlement child without a timestamp caveat is open-ended.')\n }\n const beforeThreshold = Number(BigInt(`0x${slice(timestamp.terms, 16, 32)}`))\n if (beforeThreshold <= 0) {\n refuse('its expiry is unset', 'The timestamp caveat has no upper bound.')\n }\n const nowSec = Math.floor(now / 1000)\n if (beforeThreshold <= nowSec) {\n refuse('it has already expired', `Expiry ${beforeThreshold} is not in the future.`)\n }\n if (beforeThreshold > nowSec + MAX_SETTLEMENT_WINDOW_SECONDS) {\n // The backend clamps to this; re-checking locally means a backend that\n // stopped clamping cannot hand out a long-lived grant unnoticed.\n refuse(\n 'its window is longer than a settlement may live',\n `Expiry is ${beforeThreshold - nowSec}s out; the ceiling is ${MAX_SETTLEMENT_WINDOW_SECONDS}s.`,\n )\n }\n // ── Facilitator pin: `RedeemerEnforcer` ───────────────────────────────────\n // terms = the allowed redeemers, 20 bytes each, packed.\n if (expected.redeemers && expected.redeemers.length > 0) {\n const redeemer = findCaveat(caveats, CAVEAT_ENFORCERS.redeemer)\n if (!redeemer) {\n refuse(\n 'it has no facilitator pin',\n 'The merchant advertised facilitators, so the child must be redeemable only by them.',\n )\n }\n const body = hex(redeemer.terms)\n if (body.length === 0 || body.length % 40 !== 0) {\n refuse('its facilitator pin is malformed', 'The redeemer terms are not a list of addresses.')\n }\n const pinned = new Set<string>()\n for (let i = 0; i < body.length; i += 40) pinned.add(body.slice(i, i + 40))\n const wanted = new Set(expected.redeemers.map((a) => hex(a)))\n if (pinned.size !== wanted.size || [...wanted].some((a) => !pinned.has(a))) {\n refuse(\n 'it is redeemable by different facilitators than the merchant advertised',\n `Expected ${[...wanted].map((a) => `0x${a}`).join(', ')}; the child pins ${[...pinned].map((a) => `0x${a}`).join(', ')}.`,\n )\n }\n }\n\n if (expected.expiresAt) {\n const declared = Math.floor(Date.parse(expected.expiresAt) / 1000)\n if (Number.isFinite(declared) && beforeThreshold > declared) {\n refuse(\n 'it outlives the payment window Haven declared',\n `The expected context expires at ${expected.expiresAt}; the child lives to ${beforeThreshold}.`,\n )\n }\n }\n}\n","/**\n * The counterfactual HybridDeleGator account address for an owner EOA (#3272).\n *\n * `haven_sign`'s unbound branch (`@haven_ai/signer`'s `tools.ts`) and, since\n * #3283, `HavenClient.signForData` (`direct-payment-guard.ts`) sign a\n * `PackedUserOperation`\n * only when its `sender` (== `domain.verifyingContract`) is THIS SIGNER'S OWN\n * delegate account — never any other HybridDeleGator, and never a third\n * party's. Haven provisions that account counterfactually at signup (#970):\n * it may have zero on-chain transactions, so the signer must be able to\n * compute its address OFFLINE, from nothing but the delegate key's own\n * address.\n *\n * This is exactly what `@metamask/smart-accounts-kit`'s\n * `getCounterfactualAccountData` computes for\n * `implementation: 'Hybrid'`, `deployParams: [owner, [], [], []]` (no passkey\n * co-owners — the only shape Haven's signup flow provisions), `deploySalt:\n * '0x'`: CREATE2 of an `ERC1967Proxy(HybridDeleGatorImpl, initialize(owner,\n * [], [], []))` behind the `SimpleFactory`.\n *\n * VENDORED, NOT IMPORTED. `@metamask/smart-accounts-kit` is a devDependency\n * only (see `package.json`) — this package installs on users' machines and\n * must not carry it at runtime. The constants below (the factory and\n * implementation addresses, the `ERC1967Proxy` bytecode) are copied from the\n * kit's pinned environment / `@metamask/delegation-abis`' bytecode export,\n * exactly like `settlement-child.ts` vendors the DelegationManager and caveat\n * enforcer addresses for the same reason. Cross-checked against the kit by\n * `packages/signer/src/delegate-account.pins.test.ts`, including against the real, on-chain\n * `direct-payment-userop.json` fixture.\n */\nimport {\n encodeDeployData,\n encodeFunctionData,\n getContractAddress,\n pad,\n type Address,\n} from 'viem'\n\n/**\n * SimpleFactory — deterministically deployed, so Base and Base Sepolia share\n * the address (matches `packages/backend/src/rails/delegation-contracts.ts`'s\n * `simpleFactory` pin for both chains).\n */\nexport const SIMPLE_FACTORY_ADDRESS: Address = '0x69Aa2f9fe1572F1B640E1bbc512f5c3a734fc77c'\n\n/**\n * HybridDeleGator implementation — matches `delegation-contracts.ts`'s\n * `hybridDeleGatorImpl` pin for both chains.\n */\nexport const HYBRID_DELEGATOR_IMPLEMENTATION: Address = '0x48dBe696A4D990079e039489bA2053B36E8FFEC4'\n\n/**\n * `ERC1967Proxy` creation bytecode, vendored from\n * `@metamask/delegation-abis`' `bytecode` export (`ERC1967Proxy`, ~2 KB) — the\n * proxy every DeleGator account (Hybrid or otherwise) deploys behind. Every\n * MetaMask smart account on this chain family is one of these, so the\n * bytecode is effectively as stable as the framework's ABI.\n */\nconst ERC1967_PROXY_BYTECODE =\n '0x60806040526040516103f03803806103f08339810160408190526100229161025e565b61002c8282610033565b5050610341565b61003c82610091565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a280511561008557610080828261010c565b505050565b61008d61017f565b5050565b806001600160a01b03163b5f036100cb57604051634c9c8ce360e01b81526001600160a01b03821660048201526024015b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b0392909216919091179055565b60605f80846001600160a01b0316846040516101289190610326565b5f60405180830381855af49150503d805f8114610160576040519150601f19603f3d011682016040523d82523d5f602084013e610165565b606091505b5090925090506101768583836101a0565b95945050505050565b341561019e5760405163b398979f60e01b815260040160405180910390fd5b565b6060826101b5576101b0826101ff565b6101f8565b81511580156101cc57506001600160a01b0384163b155b156101f557604051639996b31560e01b81526001600160a01b03851660048201526024016100c2565b50805b9392505050565b80511561020f5780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b634e487b7160e01b5f52604160045260245ffd5b5f5b8381101561025657818101518382015260200161023e565b50505f910152565b5f806040838503121561026f575f80fd5b82516001600160a01b0381168114610285575f80fd5b60208401519092506001600160401b03808211156102a1575f80fd5b818501915085601f8301126102b4575f80fd5b8151818111156102c6576102c6610228565b604051601f8201601f19908116603f011681019083821181831017156102ee576102ee610228565b81604052828152886020848701011115610306575f80fd5b61031783602083016020880161023c565b80955050505050509250929050565b5f825161033781846020870161023c565b9190910192915050565b60a38061034d5f395ff3fe6080604052600a600c565b005b60186014601a565b6050565b565b5f604b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b905090565b365f80375f80365f845af43d5f803e8080156069573d5ff35b3d5ffdfea2646970667358221220fd2cc92935c943d341edacaf5318a0b9ab0185ce62ef72e95ab393ef358730c464736f6c63430008170033' as const\n\n/** Minimal `ERC1967Proxy` ABI — only the constructor `encodeDeployData` needs. */\nconst ERC1967_PROXY_ABI = [\n {\n type: 'constructor',\n inputs: [\n { name: 'implementation', type: 'address' },\n { name: '_data', type: 'bytes' },\n ],\n stateMutability: 'payable',\n },\n] as const\n\n/**\n * Minimal `HybridDeleGator` ABI — only the `initialize` selector this module\n * needs, with no passkey co-owners (`_keyIds`/`_xValues`/`_yValues` empty).\n */\nconst HYBRID_DELEGATOR_INITIALIZE_ABI = [\n {\n type: 'function',\n name: 'initialize',\n inputs: [\n { name: '_owner', type: 'address' },\n { name: '_keyIds', type: 'string[]' },\n { name: '_xValues', type: 'uint256[]' },\n { name: '_yValues', type: 'uint256[]' },\n ],\n outputs: [],\n stateMutability: 'nonpayable',\n },\n] as const\n\n/** CREATE2 salt Haven provisions every account with (#970) — no salted variants. */\nconst DEPLOY_SALT = pad('0x', { size: 32 })\n\n/**\n * Derive the counterfactual HybridDeleGator account address for `owner`, with\n * no passkey co-owners — the only shape Haven's signup flow provisions\n * (#970). Pure and offline: no RPC call, no dependency on the account having\n * been deployed. Verified byte-for-byte against\n * `@metamask/smart-accounts-kit`'s `getCounterfactualAccountData` by\n * `packages/signer/src/delegate-account.pins.test.ts`, including against a real Base Sepolia payload served by the dev backend\n * (`direct-payment-userop.json`).\n */\nexport function deriveDelegateAccountAddress(owner: Address): Address {\n const initData = encodeFunctionData({\n abi: HYBRID_DELEGATOR_INITIALIZE_ABI,\n functionName: 'initialize',\n args: [owner, [], [], []],\n })\n const proxyCreationCode = encodeDeployData({\n abi: ERC1967_PROXY_ABI,\n args: [HYBRID_DELEGATOR_IMPLEMENTATION, initData],\n bytecode: ERC1967_PROXY_BYTECODE,\n })\n return getContractAddress({\n bytecode: proxyCreationCode,\n from: SIMPLE_FACTORY_ADDRESS,\n opcode: 'CREATE2',\n salt: DEPLOY_SALT,\n })\n}\n","/**\n * #3272 (B1 follow-up) — what `DelegationManager.redeemDelegations` actually\n * does with the bytes `haven_sign`'s unbound branch allows through.\n *\n * `assertBoundDirectPaymentUserOp` (then in the signer's `tools.ts`, now\n * `direct-payment-guard.ts`) used to stop at \"the inner\n * call decodes as `redeemDelegations`\" — it never looked at the ARGUMENTS.\n * MetaMask's DelegationManager (v1.3.0) treats an EMPTY permission context\n * (an ABI-encoded `Delegation[]` of length 0) as self-authorised: with no\n * delegation to check, it calls `IDeleGatorCore(msg.sender).executeFromExecutor`\n * directly — running the paired `executionCallData` AS THE ACCOUNT, with no\n * caveat, no budget, no recipient pin. Since `HybridDeleGator.transferOwnership`\n * / `updateSigners` / `addKey` are `onlyEntryPointOrSelf`, a self-call in that\n * slot captures the account exactly as a bare `execute(self, 0,\n * transferOwnership(attacker))` would — the redeemDelegations wrapper was\n * never inspected past its own selector.\n *\n * This module decodes and verifies the REAL redemption shape Haven's backend\n * emits (`packages/backend/src/rails/delegation-rail.ts` `prepareRedemption`):\n * exactly one permission context, exactly one delegation in it, whose\n * `delegate` is this signer's own account (so the redemption authority is\n * this signer's, not forwarded from elsewhere) and whose `delegator` is a\n * DIFFERENT address (so it is a real grant, not a no-op self-delegation),\n * under `ExecutionMode.SingleDefault`, with no trailing or non-canonical\n * bytes anywhere in the chain.\n *\n * The `Delegation`/`Caveat` tuple shape is vendored from\n * `@metamask/delegation-abis`' `IDelegationManager` ABI (a devDependency\n * only, in `@haven_ai/signer`'s `package.json`) and pinned against the kit's\n * own encoder by `packages/signer/src/redemption-guard.pins.test.ts`.\n *\n * TASK BUDGETS (#3329) widen the accepted chain from exactly one link to ONE\n * OR TWO: `[budget]` (unchanged) or `[task child, budget]` — leaf first, as\n * everywhere else in this file. The two-link case is safe by the SAME\n * reasoning as the one-link case, extended one hop: the task child's own\n * `delegate` AND `delegator` are this signer's OWN account (a\n * SELF-delegation — `assertOwnTaskChild` in `task-budget-guards.ts` is what\n * proves its caveats narrow, never widen, the budget it chains under), and\n * the budget link underneath it keeps the existing (3)/(4) shape: delegate ==\n * own account, delegator != own account (a real grant from elsewhere). A\n * chain redeemed this way can therefore only ever be AS OR MORE restrictive\n * than redeeming the budget directly — the task child ADDS caveats (amount,\n * recipient, expiry); it can never remove one, because\n * `DelegationManager.redeemDelegations` ANDs every caveat of every link in\n * the chain (the same AND-only property `settlement-child.ts`'s header\n * documents). Any OTHER two-link chain — a leaf delegated by a third party, a\n * leaf whose delegate is not this signer's own account, a chain longer than\n * two — is refused exactly as before.\n */\nimport {\n decodeAbiParameters,\n decodeFunctionData,\n encodeAbiParameters,\n encodeFunctionData,\n type Address,\n type Hex,\n} from 'viem'\nimport { HavenSigningError } from './types.js'\n\n/** `Caveat` — `(address enforcer, bytes terms, bytes args)`. */\nconst CAVEAT_COMPONENTS = [\n { name: 'enforcer', type: 'address' },\n { name: 'terms', type: 'bytes' },\n { name: 'args', type: 'bytes' },\n] as const\n\n/** `Delegation` — `(address delegate, address delegator, bytes32 authority, Caveat[] caveats, uint256 salt, bytes signature)`. */\nexport const DELEGATION_TUPLE_COMPONENTS = [\n { name: 'delegate', type: 'address' },\n { name: 'delegator', type: 'address' },\n { name: 'authority', type: 'bytes32' },\n { name: 'caveats', type: 'tuple[]', components: CAVEAT_COMPONENTS },\n { name: 'salt', type: 'uint256' },\n { name: 'signature', type: 'bytes' },\n] as const\n\n/** A permission context is `abi.encode(Delegation[])` — ONE dynamic array parameter. */\nconst DELEGATION_ARRAY_PARAM = [\n { type: 'tuple[]', components: DELEGATION_TUPLE_COMPONENTS },\n] as const\n\n/** `DelegationManager.redeemDelegations(bytes[],bytes32[],bytes[])` — selector `0xcef6d209`. */\nexport const REDEEM_DELEGATIONS_ABI = [\n {\n type: 'function',\n name: 'redeemDelegations',\n inputs: [\n { name: '_permissionContexts', type: 'bytes[]' },\n { name: '_modes', type: 'bytes32[]' },\n { name: '_executionCallDatas', type: 'bytes[]' },\n ],\n outputs: [],\n stateMutability: 'nonpayable',\n },\n] as const\n\n/**\n * `ExecutionMode.SingleDefault` — all-zero `bytes32`\n * (`@metamask/smart-accounts-kit`'s `ExecutionMode` enum). The backend never\n * emits any other mode (`delegation-rail.ts`'s `prepareRedemption` always\n * passes `[ExecutionMode.SingleDefault]`), so any other value here is refused\n * rather than interpreted.\n */\nexport const SINGLE_DEFAULT_MODE: Hex = `0x${'00'.repeat(32)}`\n\nfunction refuse(detail: string): never {\n throw new HavenSigningError(\n `Refusing to sign: this UserOperation's redeemDelegations call ${detail}. This signer only ` +\n \"signs one of two shapes: a single grant to the agent's own account, or a self-delegated \" +\n 'task-budget child redeemed under it (the two-link [task child, budget] chain).',\n )\n}\n\n/**\n * Verify `redeemCalldata` (the bytes passed to `execute()`, selector already\n * confirmed to be `redeemDelegations` by the caller) is EXACTLY one of Haven's\n * two shapes: a single delegation redeemed by `ownAccount` and granted by\n * someone else, or (#3329) that grant behind one task-budget child `ownAccount`\n * delegated to itself; in `SingleDefault` mode, with no encoding slack\n * anywhere. Throws\n * `HavenSigningError` (never returns) on any disagreement.\n */\nexport function assertRedeemsOwnBudgetDelegation(redeemCalldata: Hex, ownAccount: Address): void {\n let permissionContexts: readonly Hex[]\n let modes: readonly Hex[]\n let executionCallDatas: readonly Hex[]\n try {\n const { args } = decodeFunctionData({ abi: REDEEM_DELEGATIONS_ABI, data: redeemCalldata })\n ;[permissionContexts, modes, executionCallDatas] = args as unknown as [\n readonly Hex[],\n readonly Hex[],\n readonly Hex[],\n ]\n } catch {\n refuse('is not a well-formed redeemDelegations(bytes[],bytes32[],bytes[]) call')\n }\n\n // (6a) Canonical encoding: re-encoding what was decoded must reproduce the\n // EXACT bytes — refuses trailing bytes or any other non-canonical padding\n // `decodeFunctionData` silently tolerates.\n const reEncoded = encodeFunctionData({\n abi: REDEEM_DELEGATIONS_ABI,\n functionName: 'redeemDelegations',\n args: [permissionContexts as Hex[], modes as Hex[], executionCallDatas as Hex[]],\n })\n if (reEncoded.toLowerCase() !== redeemCalldata.toLowerCase()) {\n refuse('does not re-encode to the exact bytes signed (trailing or non-canonical bytes)')\n }\n\n // (1) Arrays present, equal length, non-empty. Haven always redeems\n // exactly one delegation chain against exactly one execution.\n if (\n permissionContexts.length === 0 ||\n permissionContexts.length !== modes.length ||\n permissionContexts.length !== executionCallDatas.length\n ) {\n refuse(\n `has mismatched or empty argument arrays (permissionContexts=${permissionContexts.length}, ` +\n `modes=${modes.length}, executionCallDatas=${executionCallDatas.length})`,\n )\n }\n if (permissionContexts.length !== 1) {\n refuse(`redeems ${permissionContexts.length} delegation chains at once, not exactly one`)\n }\n\n // (5) Mode: SingleDefault only — the only mode Haven's backend ever emits.\n if (modes[0].toLowerCase() !== SINGLE_DEFAULT_MODE.toLowerCase()) {\n refuse(`uses execution mode ${modes[0]}, not ExecutionMode.SingleDefault`)\n }\n\n // (2) THE B1 FIX: the permission context must decode as a NON-EMPTY\n // Delegation[]. An empty array (`abi.encode([])`) is exactly the shape\n // MetaMask's DelegationManager treats as self-authorised — the bypass this\n // function exists to close. A malformed context is refused the same way.\n let delegations: ReadonlyArray<{\n delegate: Address\n delegator: Address\n authority: Hex\n caveats: readonly unknown[]\n salt: bigint\n signature: Hex\n }>\n try {\n const [decoded] = decodeAbiParameters(DELEGATION_ARRAY_PARAM, permissionContexts[0])\n delegations = decoded as typeof delegations\n } catch {\n refuse(\"carries a permission context that does not decode as an ABI-encoded Delegation[]\")\n }\n if (delegations.length === 0) {\n refuse(\n 'carries an EMPTY delegation chain — DelegationManager treats this as self-authorised ' +\n \"and runs the paired execution as the account, with no caveat, budget or recipient pin\",\n )\n }\n // (2b) One OR TWO links (#3329). Haven's budget delegation is a single\n // grant from the user's account to this agent's account (`delegations:\n // [[delegation]]` in the backend's prepareRedemption) — one link. A task\n // budget payment redeems `[task child, budget]` — two links, leaf first.\n // Anything else is never emitted.\n if (delegations.length !== 1 && delegations.length !== 2) {\n refuse(\n `carries a ${delegations.length}-link delegation chain, not the single budget grant or the ` +\n 'two-link [task child, budget] chain Haven emits',\n )\n }\n\n // (6b) Canonical encoding of the permission context itself.\n const reEncodedContext = encodeAbiParameters(DELEGATION_ARRAY_PARAM, [delegations as never])\n if (reEncodedContext.toLowerCase() !== permissionContexts[0].toLowerCase()) {\n refuse('carries a permission context with trailing or non-canonical bytes')\n }\n\n // (3) Leaf delegation — index 0, the redeemer's own link in the chain\n // (mirrors the backend's `delegations: [[delegation]]`, a one-link chain\n // whose sole entry IS the leaf) — must delegate to THIS signer's own\n // account. A delegate naming any other address means this redemption\n // authorises a DIFFERENT account's spend, and this signer's key would be\n // the one producing that authority.\n const leaf = delegations[0]\n if (leaf.delegate.toLowerCase() !== ownAccount.toLowerCase()) {\n refuse(\n `is redeemed for delegate ${leaf.delegate}, not this signer's own account (${ownAccount})`,\n )\n }\n\n if (delegations.length === 2) {\n // #3329: the two-link task-budget chain. The leaf (the task child) must\n // be SELF-delegated — `delegator` is this signer's own account too — the\n // shape `assertOwnTaskChild` (`task-budget-guards.ts`) already proved is\n // a narrowing re-delegation, never a grant from elsewhere.\n if (leaf.delegator.toLowerCase() !== ownAccount.toLowerCase()) {\n refuse(\n `carries a two-link chain whose leaf is delegated by ${leaf.delegator}, not this signer's ` +\n `own account (${ownAccount}) — a task-budget child is always self-delegated`,\n )\n }\n const budget = delegations[1]\n if (budget.delegate.toLowerCase() !== ownAccount.toLowerCase()) {\n refuse(\n `carries a two-link chain whose second link delegates to ${budget.delegate}, not this ` +\n `signer's own account (${ownAccount})`,\n )\n }\n if (budget.delegator.toLowerCase() === ownAccount.toLowerCase()) {\n refuse(\n \"carries a two-link chain whose budget link is granted by this signer's OWN account — a \" +\n 'real budget delegation always comes from elsewhere',\n )\n }\n return\n }\n\n // (4) One-link chain: the delegation's own delegator must NOT be this\n // signer's own account — a self-to-self delegation is exactly the B1 shape\n // restated: it authorises nothing beyond what the account already is, so\n // it must be a real grant FROM somewhere else (the treasury/budget owner).\n const root = delegations[delegations.length - 1]\n if (root.delegator.toLowerCase() === ownAccount.toLowerCase()) {\n refuse(\n \"carries a root delegation granted by this signer's OWN account — a real budget \" +\n 'delegation always comes from elsewhere',\n )\n }\n}\n"]}
|