@haven_ai/sdk 0.11.0-alpha.0 → 0.13.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.
Files changed (42) hide show
  1. package/README.md +37 -4
  2. package/dist/{base64-D4VZhgUg.d.ts → base64-C3mJNLYR.d.cts} +10 -2
  3. package/dist/{base64-DR4Gl8cD.d.cts → base64-CxzIc3KH.d.ts} +10 -2
  4. package/dist/{chunk-IKQIIMM6.cjs → chunk-4Z7PKLFD.cjs} +38 -37
  5. package/dist/chunk-4Z7PKLFD.cjs.map +1 -0
  6. package/dist/{chunk-34YJQFCM.js → chunk-CK6VRIPR.js} +3 -3
  7. package/dist/chunk-CK6VRIPR.js.map +1 -0
  8. package/dist/{chunk-ZDJ55LR7.js → chunk-CXQ42FOA.js} +7 -6
  9. package/dist/chunk-CXQ42FOA.js.map +1 -0
  10. package/dist/{chunk-MZKLAHBK.cjs → chunk-LZHCIK7L.cjs} +56 -4
  11. package/dist/chunk-LZHCIK7L.cjs.map +1 -0
  12. package/dist/{chunk-I7SL4A6X.js → chunk-MI7LVP56.js} +55 -5
  13. package/dist/chunk-MI7LVP56.js.map +1 -0
  14. package/dist/{chunk-DXBAN4SN.cjs → chunk-Z5MTKU6O.cjs} +4 -4
  15. package/dist/chunk-Z5MTKU6O.cjs.map +1 -0
  16. package/dist/edge.cjs +93 -93
  17. package/dist/edge.d.cts +11 -8
  18. package/dist/edge.d.ts +11 -8
  19. package/dist/edge.js +4 -4
  20. package/dist/index.cjs +456 -356
  21. package/dist/index.cjs.map +1 -1
  22. package/dist/index.d.cts +26 -15
  23. package/dist/index.d.ts +26 -15
  24. package/dist/index.js +140 -48
  25. package/dist/index.js.map +1 -1
  26. package/dist/{receipt-CbD8L0WL.d.ts → receipt-CTOPh2fm.d.ts} +5 -4
  27. package/dist/{receipt-_bWCELEH.d.cts → receipt-DwRqGjGb.d.cts} +5 -4
  28. package/dist/test-support.cjs +58 -21
  29. package/dist/test-support.cjs.map +1 -1
  30. package/dist/test-support.d.cts +47 -3
  31. package/dist/test-support.d.ts +47 -3
  32. package/dist/test-support.js +37 -3
  33. package/dist/test-support.js.map +1 -1
  34. package/dist/{types-DKmvjXK6.d.cts → types-3vUBmumz.d.cts} +163 -2
  35. package/dist/{types-DKmvjXK6.d.ts → types-3vUBmumz.d.ts} +163 -2
  36. package/package.json +2 -2
  37. package/dist/chunk-34YJQFCM.js.map +0 -1
  38. package/dist/chunk-DXBAN4SN.cjs.map +0 -1
  39. package/dist/chunk-I7SL4A6X.js.map +0 -1
  40. package/dist/chunk-IKQIIMM6.cjs.map +0 -1
  41. package/dist/chunk-MZKLAHBK.cjs.map +0 -1
  42. package/dist/chunk-ZDJ55LR7.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/test-support/direct-userop.ts","../src/test-support/signed-receipt.ts"],"names":["encodeAbiParameters"],"mappings":"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","file":"test-support.js","sourcesContent":["/**\n * #3272 — a real-shaped, BOUND direct-payment `PackedUserOperation` for\n * signer tests: `sender` is the counterfactual delegate account for a given\n * owner EOA, and `callData` is `execute(DelegationManager, 0,\n * redeemDelegations(...))` with a REAL redemption shape — one non-empty\n * `Delegation`, `delegate` = the signer's own account, `delegator` = a\n * distinct treasury address, `ExecutionMode.SingleDefault`, an\n * `encodePacked(target,value,callData)` execution — mirroring\n * `packages/backend/src/rails/delegation-rail.ts`'s `prepareRedemption`.\n * Replaces the toy 2-field / empty-callData / empty-arrays fixtures the\n * allowlist correctly refuses (including the B1 empty-permission-context\n * bypass, `buildEmptyPermissionContextRedemption` below, kept ONLY to\n * reproduce that exact refusal in a test).\n *\n * Moved here from `@haven_ai/signer` by #3283 so the SDK, the signer,\n * `@haven_ai/mcp` and `mcp-server` share ONE guard-valid builder. Published\n * as the `@haven_ai/sdk/test-support` subpath only because a sibling\n * package's tests cannot import this file by relative path (each package's\n * `tsc` `rootDir` is its own `src`). Test fixtures, not a signing API:\n * nothing here signs, and nothing the SDK or signer runs imports it.\n */\nimport {\n decodeAbiParameters,\n decodeFunctionData,\n encodeAbiParameters,\n encodeFunctionData,\n encodePacked,\n hashTypedData,\n type Address,\n type Hex,\n} from 'viem'\nimport {\n ENTRY_POINT_V07,\n HYBRID_DELEGATOR_DOMAIN_NAME,\n HYBRID_DELEGATOR_DOMAIN_VERSION,\n PACKED_USER_OPERATION_FIELDS,\n packedUserOperationHash,\n} from '../userop-binding.js'\nimport { DELEGATION_MANAGER } from '../settlement-child.js'\nimport { deriveDelegateAccountAddress } from '../delegate-account.js'\nimport { DELEGATION_TUPLE_COMPONENTS, REDEEM_DELEGATIONS_ABI, SINGLE_DEFAULT_MODE } from '../redemption-guard.js'\n\nconst ZERO_BYTES32 = `0x${'00'.repeat(32)}` as const\n\n/** `Delegation.authority` sentinel for a root (unchained) delegation — `@metamask/delegation-core`'s `ROOT_AUTHORITY`. */\nconst ROOT_AUTHORITY: Hex = `0x${'ff'.repeat(32)}`\n\n/** Stand-in treasury address — distinct from any derived signer account, matching the real fixture's `delegator`. */\nexport const DEFAULT_DELEGATOR: Address = '0x98989898989898989898989898989898989898De' as Address\n\nconst DELEGATION_ARRAY_PARAM = [\n { type: 'tuple[]', components: DELEGATION_TUPLE_COMPONENTS },\n] as const\n\nconst EXECUTE_ABI = [\n {\n type: 'function',\n name: 'execute',\n inputs: [\n {\n name: '_execution',\n type: 'tuple',\n components: [\n { name: 'target', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'callData', type: 'bytes' },\n ],\n },\n ],\n outputs: [],\n stateMutability: 'payable',\n },\n] as const\n\nconst TRANSFER_ABI = [\n {\n type: 'function',\n name: 'transfer',\n inputs: [\n { name: 'to', type: 'address' },\n { name: 'amount', type: 'uint256' },\n ],\n outputs: [{ type: 'bool' }],\n stateMutability: 'nonpayable',\n },\n] as const\n\nexport interface DelegationOverrides {\n /** The redeemer this delegation authorises — normally the signer's own derived account. */\n delegate: Address\n /** Who granted it — must differ from `delegate` for a real (non-self) delegation. */\n delegator?: Address\n authority?: Hex\n caveats?: Array<{ enforcer: Address; terms: Hex; args: Hex }>\n salt?: bigint\n signature?: Hex\n}\n\n/** A single, well-formed `Delegation` tuple — the ONE-link chain Haven's backend redeems (`delegations: [[delegation]]`). */\nexport function buildDelegation(overrides: DelegationOverrides) {\n return {\n delegate: overrides.delegate,\n delegator: overrides.delegator ?? DEFAULT_DELEGATOR,\n authority: overrides.authority ?? ROOT_AUTHORITY,\n caveats: overrides.caveats ?? [\n // A real-shaped (if inert for test purposes) TimestampEnforcer term —\n // real budget delegations always carry at least one caveat.\n { enforcer: '0x1046bb45C8d673d4ea75321280DB34899413c069' as Address, terms: `0x${'00'.repeat(32)}` as Hex, args: '0x' as Hex },\n ],\n salt: overrides.salt ?? 1n,\n signature: overrides.signature ?? (`0x${'ab'.repeat(65)}` as Hex),\n }\n}\n\n/** `abi.encode(Delegation[])` for a ONE-delegation chain — a Haven-shaped permission context. */\nexport function buildPermissionContext(delegation: ReturnType<typeof buildDelegation>): Hex {\n return encodeAbiParameters(DELEGATION_ARRAY_PARAM, [[delegation]])\n}\n\n/** `abi.encode(Delegation[])` for a MULTI-link chain (leaf first) — never emitted by Haven. */\nexport function buildChainPermissionContext(chain: ReturnType<typeof buildDelegation>[]): Hex {\n return encodeAbiParameters(DELEGATION_ARRAY_PARAM, [chain])\n}\n\n/** `abi.encode(Delegation[])` for an EMPTY chain — the exact B1 bypass shape MetaMask's DelegationManager treats as self-authorised. */\nexport function buildEmptyPermissionContext(): Hex {\n return encodeAbiParameters(DELEGATION_ARRAY_PARAM, [[]])\n}\n\n/** `encodePacked(address,uint256,bytes)` — the single-execution calldata `ExecutionMode.SingleDefault` expects. */\nexport function buildSingleExecutionCallData(target: Address, value: bigint, innerCallData: Hex): Hex {\n return encodePacked(['address', 'uint256', 'bytes'], [target, value, innerCallData])\n}\n\n/** A real-shaped ERC-20 `transfer(to, amount)` execution — what a budget redemption actually spends. */\nexport function buildTransferExecutionCallData(token: Address, to: Address, amount: bigint): Hex {\n return buildSingleExecutionCallData(\n token,\n 0n,\n encodeFunctionData({ abi: TRANSFER_ABI, functionName: 'transfer', args: [to, amount] }),\n )\n}\n\nexport interface BoundRedeemDelegationsOptions {\n /** The redeemer — normally the signer's own derived account (matches the UserOp's `sender`). */\n delegate: Address\n delegator?: Address\n caveats?: DelegationOverrides['caveats']\n /** Override the single execution's calldata entirely (default: a real-shaped ERC-20 transfer). */\n executionCallData?: Hex\n}\n\n/** `redeemDelegations([permissionContext], [SingleDefault], [executionCallData])` — the REAL, bound shape. */\nexport function buildBoundRedeemDelegationsCallData(options: BoundRedeemDelegationsOptions): Hex {\n const delegation = buildDelegation({ delegate: options.delegate, delegator: options.delegator, caveats: options.caveats })\n const permissionContext = buildPermissionContext(delegation)\n const executionCallData =\n options.executionCallData ??\n buildTransferExecutionCallData(\n '0x036CbD53842c5426634e7929541eC2318f3dCF7e' as Address, // Base Sepolia USDC, matches the real captured fixture\n '0x98ffBf30459a98FD80fAce18f519967769641F76' as Address,\n 10000n,\n )\n return encodeFunctionData({\n abi: REDEEM_DELEGATIONS_ABI,\n functionName: 'redeemDelegations',\n args: [[permissionContext], [SINGLE_DEFAULT_MODE], [executionCallData]],\n })\n}\n\n/**\n * #3272 (B1 regression): `redeemDelegations([emptyPermissionContext],\n * [SingleDefault], [selfCallCallData])` — one permission context whose\n * `Delegation[]` decodes EMPTY, paired with a self-call execution. This is\n * the exact live bypass: MetaMask's DelegationManager treats an empty chain\n * as self-authorised and runs `selfCallCallData` AS the account. Exists only\n * so a test can assert this is refused, never to build a shape any code path\n * signs.\n */\nexport function buildEmptyPermissionContextRedemption(selfCallCallData: Hex): Hex {\n return encodeFunctionData({\n abi: REDEEM_DELEGATIONS_ABI,\n functionName: 'redeemDelegations',\n args: [[buildEmptyPermissionContext()], [SINGLE_DEFAULT_MODE], [selfCallCallData]],\n })\n}\n\n/** `execute((address,uint256,bytes))` — selector `0x5c1c6dcd`. */\nexport function buildExecuteCallData(target: Address, value: bigint, innerCallData: Hex): Hex {\n return encodeFunctionData({\n abi: EXECUTE_ABI,\n functionName: 'execute',\n args: [{ target, value, callData: innerCallData }],\n })\n}\n\nexport interface BoundDirectUserOpOptions {\n /** The delegate EOA (`signer.delegateAddress`) that owns the account `sender` derives from. */\n delegate: Address\n chainId?: number | bigint | string\n /** Override the execute() target — default DELEGATION_MANAGER (the bound shape). */\n target?: Address\n /** Override the execute() value — default 0n. */\n value?: bigint\n /** Override the full message.callData (bypasses target/value/redeemDelegations construction). */\n callData?: Hex\n /** Override sender/verifyingContract directly instead of deriving it from `delegate`. */\n sender?: Address\n /** Override the redemption's delegator (default: a distinct treasury address). */\n delegator?: Address\n}\n\nexport interface BoundDirectUserOp {\n typedData: {\n domain: { name: string; version: string; chainId: number | bigint | string; verifyingContract: Address }\n types: { PackedUserOperation: Array<{ name: string; type: string }> }\n primaryType: 'PackedUserOperation'\n message: Record<string, unknown>\n }\n payloadHash: Hex\n sender: Address\n}\n\n/**\n * A real-shaped, self-consistent (correct v0.7 hash) `PackedUserOperation`.\n * By default it is fully BOUND per #3272's allowlist: `sender` is the\n * counterfactual account for `delegate`, and `callData` redeems ONE real\n * delegation (delegate = `sender`, delegator = a distinct treasury address)\n * through the DelegationManager. Override `target` / `callData` / `sender` /\n * `delegator` to build the negative-test shapes the allowlist must refuse.\n */\nexport function buildBoundDirectUserOp(options: BoundDirectUserOpOptions): BoundDirectUserOp {\n const chainId = options.chainId ?? 84532\n const sender = options.sender ?? deriveDelegateAccountAddress(options.delegate)\n const callData =\n options.callData ??\n buildExecuteCallData(\n options.target ?? (DELEGATION_MANAGER as Address),\n options.value ?? 0n,\n buildBoundRedeemDelegationsCallData({ delegate: sender, delegator: options.delegator }),\n )\n const typedData = {\n domain: {\n name: HYBRID_DELEGATOR_DOMAIN_NAME,\n version: HYBRID_DELEGATOR_DOMAIN_VERSION,\n chainId,\n verifyingContract: sender,\n },\n types: { PackedUserOperation: PACKED_USER_OPERATION_FIELDS.map((field) => ({ ...field })) },\n primaryType: 'PackedUserOperation' as const,\n message: {\n sender,\n nonce: '0',\n initCode: '0x',\n callData,\n accountGasLimits: ZERO_BYTES32,\n preVerificationGas: '0',\n gasFees: ZERO_BYTES32,\n paymasterAndData: '0x',\n entryPoint: ENTRY_POINT_V07,\n },\n }\n const payloadHash = packedUserOperationHash(typedData)\n return { typedData, payloadHash, sender }\n}\n\n/** A well-formed `execute()` self-call — `target === sender` — for the (d)/self-call negative tests. */\nexport function buildSelfCallCallData(sender: Address): Hex {\n const TRANSFER_OWNERSHIP_ABI = [\n { type: 'function', name: 'transferOwnership', inputs: [{ name: 'newOwner', type: 'address' }], outputs: [], stateMutability: 'nonpayable' },\n ] as const\n const inner = encodeFunctionData({\n abi: TRANSFER_OWNERSHIP_ABI,\n functionName: 'transferOwnership',\n args: ['0x000000000000000000000000000000000000dEaD' as Address],\n })\n return buildExecuteCallData(sender, 0n, inner)\n}\n\n/**\n * Re-target a REAL captured direct-payment UserOp (for example\n * `__fixtures__/direct-payment-userop.json`) at `newSender`: the UserOp's\n * `sender` / `verifyingContract` and the redeemed delegation's `delegate`\n * become `newSender`; the delegator, caveats, mode and execution stay the\n * production bytes. The captured fixture is bound to a delegate whose key is\n * not in the repository, so a test signs this rebuilt copy with a test key\n * whose derived account is `newSender` — proving the guard accepts the actual\n * production shape, not only this file's synthetic one.\n */\nexport function rebuildDirectUserOpForSender(\n fixtureTypedData: {\n domain: Record<string, unknown>\n types: Record<string, unknown>\n primaryType: string\n message: Record<string, unknown>\n },\n newSender: Address,\n) {\n const originalCallData = fixtureTypedData.message.callData as Hex\n const { args: executeArgs } = decodeFunctionData({ abi: EXECUTE_ABI, data: originalCallData })\n const execution = executeArgs[0] as { target: Address; value: bigint; callData: Hex }\n const { args: redeemArgs } = decodeFunctionData({ abi: REDEEM_DELEGATIONS_ABI, data: execution.callData })\n const [permissionContexts, modes, executionCallDatas] = redeemArgs as unknown as [\n readonly Hex[],\n readonly Hex[],\n readonly Hex[],\n ]\n const [delegations] = decodeAbiParameters(DELEGATION_ARRAY_PARAM, permissionContexts[0])\n const adjustedDelegations = (delegations as unknown as Array<Record<string, unknown>>).map((d, i) =>\n i === 0 ? { ...d, delegate: newSender } : d,\n )\n const adjustedPermissionContext = encodeAbiParameters(DELEGATION_ARRAY_PARAM, [adjustedDelegations as never])\n const adjustedRedeemCallData = encodeFunctionData({\n abi: REDEEM_DELEGATIONS_ABI,\n functionName: 'redeemDelegations',\n args: [[adjustedPermissionContext], modes as Hex[], executionCallDatas as Hex[]],\n })\n const adjustedCallData = encodeFunctionData({\n abi: EXECUTE_ABI,\n functionName: 'execute',\n args: [{ target: execution.target, value: execution.value, callData: adjustedRedeemCallData }],\n })\n const typedData = {\n ...fixtureTypedData,\n domain: { ...fixtureTypedData.domain, verifyingContract: newSender },\n message: { ...fixtureTypedData.message, sender: newSender, callData: adjustedCallData },\n }\n const payloadHash = packedUserOperationHash(typedData as never) as Hex\n return { typedData, payloadHash }\n}\n\nexport interface FundingLegUserOpOptions {\n /** The delegate EOA (`signer.delegateAddress`): the account is derived from it AND it is the transfer's recipient. */\n delegate: Address\n /** The quoted token (the expected context's `asset`). */\n asset: Address\n /** The quoted atomic amount (the expected context's `amount`). */\n amount: bigint | string\n chainId?: number\n /** Override the transfer recipient (default: `delegate`) — for the recipient-pin negative test. */\n recipient?: Address\n /** Override the budget delegation's caveats (e.g. a multi-KB term, for relay-size tests). */\n caveats?: DelegationOverrides['caveats']\n}\n\n/**\n * #3281: an x402 EIP-3009 bridge FUNDING LEG exactly as the backend builds it\n * (`delegation-authorize.ts` → `prepareDelegationPayment(agent, token,\n * payTo = the delegate EOA, amountRaw)` → `prepareRedemption`): the\n * direct-payment shape, whose single execution is\n * `transfer(<delegate EOA>, <amount>)` on the quoted token. Returns the typed\n * data, its v0.7 UserOp hash (the expected context's `payloadHash`) and its\n * EIP-712 digest (the expected context's `typedDataHash`).\n */\nexport function buildFundingLegUserOp(options: FundingLegUserOpOptions) {\n const sender = deriveDelegateAccountAddress(options.delegate)\n const callData = buildExecuteCallData(\n DELEGATION_MANAGER as Address,\n 0n,\n buildBoundRedeemDelegationsCallData({\n delegate: sender,\n caveats: options.caveats,\n executionCallData: buildTransferExecutionCallData(\n options.asset,\n options.recipient ?? options.delegate,\n BigInt(options.amount),\n ),\n }),\n )\n const { typedData, payloadHash } = buildBoundDirectUserOp({\n delegate: options.delegate,\n chainId: options.chainId ?? 84532,\n callData,\n })\n return { typedData, payloadHash, digest: hashTypedData(typedData as never) }\n}\n","/**\n * #3723 — a REAL signed erc7710 receipt bundle for handler-level tests: the\n * delegate key signs the DelegationManager EIP-712 digest rebuilt from the\n * bundle's own `signHash` + `onChain.chainId`, exactly the math\n * `verifyPaymentReceipt` performs. So `verifyPaymentReceipt(bundle)` returns\n * `{ verified: true, verifiedOver: 'delegation_digest' }` with the DEFAULT\n * ECDSA recovery — the first positive handler-level verify fixture on the\n * MCP runtimes (no stdio-originated payment is erc7710 live: `haven_send` is\n * direct and the stdio x402 path is the eip3009 bridge).\n *\n * Published on the `@haven_ai/sdk/test-support` subpath like the UserOp\n * builder: a sibling package's tests cannot import this file by relative\n * path. Test fixtures, not a signing API: nothing the SDK or signer runs\n * imports it.\n */\nimport { Wallet } from 'ethers'\nimport { concatHex, encodeAbiParameters, keccak256, toBytes, type Hex } from 'viem'\nimport { DELEGATION_MANAGER } from '../settlement-child.js'\nimport { RECEIPT_VERSION, type PaymentReceipt } from '../receipt.js'\n\n/** A fixed delegate key so fixtures are deterministic across runs. */\nexport const RECEIPT_DELEGATE_KEY = `0x${'77'.repeat(32)}` as const\n/** A distinct key, for signer_mismatch fixtures. */\nexport const OTHER_RECEIPT_KEY = `0x${'88'.repeat(32)}` as const\n\nconst EIP712_DOMAIN_TYPEHASH = keccak256(\n toBytes('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'),\n)\n\n/** Same rebuild the verifier does — mirrored here so drift turns the positive test red. */\nfunction delegationDigest(signHash: string, chainId: number): Hex {\n const domainSeparator = keccak256(\n encodeAbiParameters(\n [{ type: 'bytes32' }, { type: 'bytes32' }, { type: 'bytes32' }, { type: 'uint256' }, { type: 'address' }],\n [\n EIP712_DOMAIN_TYPEHASH,\n keccak256(toBytes('DelegationManager')),\n keccak256(toBytes('1')),\n BigInt(chainId),\n DELEGATION_MANAGER as Hex,\n ],\n ),\n )\n return keccak256(concatHex(['0x1901', domainSeparator, signHash as Hex]))\n}\n\nexport interface SignedErc7710Options {\n /** Defaults to `RECEIPT_DELEGATE_KEY`; pass `OTHER_RECEIPT_KEY` for a forged bundle. */\n delegateKey?: string\n signHash?: string\n chainId?: number\n paymentId?: string\n}\n\n/**\n * A signed erc7710 bundle whose `authorization.signature` recovers to the\n * delegate over the delegation digest — `verifyPaymentReceipt` verifies it\n * offline with the default recovery.\n */\nexport function signedErc7710Receipt(options: SignedErc7710Options = {}): PaymentReceipt {\n const chainId = options.chainId ?? 84532 // Base Sepolia — a chain the SDK pins\n const signHash = options.signHash ?? (`0x${'5e'.repeat(32)}` as const)\n const delegate = new Wallet(options.delegateKey ?? RECEIPT_DELEGATE_KEY)\n const signature = delegate.signingKey.sign(delegationDigest(signHash, chainId)).serialized\n return {\n version: RECEIPT_VERSION,\n paymentId: options.paymentId ?? 'pay_3723',\n payment: {\n token: 'USDC',\n tokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n amount: '0.50',\n amountSek: '5.25',\n recipient: '0x15179876c595922999C2d5DC7c23Cc7711fE799a',\n account: '0x135a9215604711AC70d970e12Caa812c53537EF4',\n chainId,\n settledAt: '2026-10-07T10:00:00.000Z',\n resourceUrl: 'https://merchant.example/resource',\n },\n authorization: {\n delegate: delegate.address,\n signHash,\n signature,\n signatureScheme: 'eip712_delegation',\n },\n onChain: { txHash: `0x${'cd'.repeat(32)}`, chainId },\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/test-support/direct-userop.ts","../src/test-support/signed-receipt.ts","../src/test-support/low-s.ts"],"names":["encodeAbiParameters"],"mappings":"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","file":"test-support.js","sourcesContent":["/**\n * #3272 — a real-shaped, BOUND direct-payment `PackedUserOperation` for\n * signer tests: `sender` is the counterfactual delegate account for a given\n * owner EOA, and `callData` is `execute(DelegationManager, 0,\n * redeemDelegations(...))` with a REAL redemption shape — one non-empty\n * `Delegation`, `delegate` = the signer's own account, `delegator` = a\n * distinct treasury address, `ExecutionMode.SingleDefault`, an\n * `encodePacked(target,value,callData)` execution — mirroring\n * `packages/backend/src/rails/delegation-rail.ts`'s `prepareRedemption`.\n * Replaces the toy 2-field / empty-callData / empty-arrays fixtures the\n * allowlist correctly refuses (including the B1 empty-permission-context\n * bypass, `buildEmptyPermissionContextRedemption` below, kept ONLY to\n * reproduce that exact refusal in a test).\n *\n * Moved here from `@haven_ai/signer` by #3283 so the SDK, the signer,\n * `@haven_ai/mcp` and `mcp-server` share ONE guard-valid builder. Published\n * as the `@haven_ai/sdk/test-support` subpath only because a sibling\n * package's tests cannot import this file by relative path (each package's\n * `tsc` `rootDir` is its own `src`). Test fixtures, not a signing API:\n * nothing here signs, and nothing the SDK or signer runs imports it.\n */\nimport {\n decodeAbiParameters,\n decodeFunctionData,\n encodeAbiParameters,\n encodeFunctionData,\n encodePacked,\n hashTypedData,\n type Address,\n type Hex,\n} from 'viem'\nimport {\n ENTRY_POINT_V07,\n HYBRID_DELEGATOR_DOMAIN_NAME,\n HYBRID_DELEGATOR_DOMAIN_VERSION,\n PACKED_USER_OPERATION_FIELDS,\n packedUserOperationHash,\n} from '../userop-binding.js'\nimport { DELEGATION_MANAGER } from '../settlement-child.js'\nimport { deriveDelegateAccountAddress } from '../delegate-account.js'\nimport { DELEGATION_TUPLE_COMPONENTS, REDEEM_DELEGATIONS_ABI, SINGLE_DEFAULT_MODE } from '../redemption-guard.js'\n\nconst ZERO_BYTES32 = `0x${'00'.repeat(32)}` as const\n\n/** `Delegation.authority` sentinel for a root (unchained) delegation — `@metamask/delegation-core`'s `ROOT_AUTHORITY`. */\nconst ROOT_AUTHORITY: Hex = `0x${'ff'.repeat(32)}`\n\n/** Stand-in treasury address — distinct from any derived signer account, matching the real fixture's `delegator`. */\nexport const DEFAULT_DELEGATOR: Address = '0x98989898989898989898989898989898989898De' as Address\n\nconst DELEGATION_ARRAY_PARAM = [\n { type: 'tuple[]', components: DELEGATION_TUPLE_COMPONENTS },\n] as const\n\nconst EXECUTE_ABI = [\n {\n type: 'function',\n name: 'execute',\n inputs: [\n {\n name: '_execution',\n type: 'tuple',\n components: [\n { name: 'target', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'callData', type: 'bytes' },\n ],\n },\n ],\n outputs: [],\n stateMutability: 'payable',\n },\n] as const\n\nconst TRANSFER_ABI = [\n {\n type: 'function',\n name: 'transfer',\n inputs: [\n { name: 'to', type: 'address' },\n { name: 'amount', type: 'uint256' },\n ],\n outputs: [{ type: 'bool' }],\n stateMutability: 'nonpayable',\n },\n] as const\n\nexport interface DelegationOverrides {\n /** The redeemer this delegation authorises — normally the signer's own derived account. */\n delegate: Address\n /** Who granted it — must differ from `delegate` for a real (non-self) delegation. */\n delegator?: Address\n authority?: Hex\n caveats?: Array<{ enforcer: Address; terms: Hex; args: Hex }>\n salt?: bigint\n signature?: Hex\n}\n\n/** A single, well-formed `Delegation` tuple — the ONE-link chain Haven's backend redeems (`delegations: [[delegation]]`). */\nexport function buildDelegation(overrides: DelegationOverrides) {\n return {\n delegate: overrides.delegate,\n delegator: overrides.delegator ?? DEFAULT_DELEGATOR,\n authority: overrides.authority ?? ROOT_AUTHORITY,\n caveats: overrides.caveats ?? [\n // A real-shaped (if inert for test purposes) TimestampEnforcer term —\n // real budget delegations always carry at least one caveat.\n { enforcer: '0x1046bb45C8d673d4ea75321280DB34899413c069' as Address, terms: `0x${'00'.repeat(32)}` as Hex, args: '0x' as Hex },\n ],\n salt: overrides.salt ?? 1n,\n signature: overrides.signature ?? (`0x${'ab'.repeat(65)}` as Hex),\n }\n}\n\n/** `abi.encode(Delegation[])` for a ONE-delegation chain — a Haven-shaped permission context. */\nexport function buildPermissionContext(delegation: ReturnType<typeof buildDelegation>): Hex {\n return encodeAbiParameters(DELEGATION_ARRAY_PARAM, [[delegation]])\n}\n\n/** `abi.encode(Delegation[])` for a MULTI-link chain (leaf first) — never emitted by Haven. */\nexport function buildChainPermissionContext(chain: ReturnType<typeof buildDelegation>[]): Hex {\n return encodeAbiParameters(DELEGATION_ARRAY_PARAM, [chain])\n}\n\n/** `abi.encode(Delegation[])` for an EMPTY chain — the exact B1 bypass shape MetaMask's DelegationManager treats as self-authorised. */\nexport function buildEmptyPermissionContext(): Hex {\n return encodeAbiParameters(DELEGATION_ARRAY_PARAM, [[]])\n}\n\n/** `encodePacked(address,uint256,bytes)` — the single-execution calldata `ExecutionMode.SingleDefault` expects. */\nexport function buildSingleExecutionCallData(target: Address, value: bigint, innerCallData: Hex): Hex {\n return encodePacked(['address', 'uint256', 'bytes'], [target, value, innerCallData])\n}\n\n/** A real-shaped ERC-20 `transfer(to, amount)` execution — what a budget redemption actually spends. */\nexport function buildTransferExecutionCallData(token: Address, to: Address, amount: bigint): Hex {\n return buildSingleExecutionCallData(\n token,\n 0n,\n encodeFunctionData({ abi: TRANSFER_ABI, functionName: 'transfer', args: [to, amount] }),\n )\n}\n\nexport interface BoundRedeemDelegationsOptions {\n /** The redeemer — normally the signer's own derived account (matches the UserOp's `sender`). */\n delegate: Address\n delegator?: Address\n caveats?: DelegationOverrides['caveats']\n /** Override the single execution's calldata entirely (default: a real-shaped ERC-20 transfer). */\n executionCallData?: Hex\n}\n\n/** `redeemDelegations([permissionContext], [SingleDefault], [executionCallData])` — the REAL, bound shape. */\nexport function buildBoundRedeemDelegationsCallData(options: BoundRedeemDelegationsOptions): Hex {\n const delegation = buildDelegation({ delegate: options.delegate, delegator: options.delegator, caveats: options.caveats })\n const permissionContext = buildPermissionContext(delegation)\n const executionCallData =\n options.executionCallData ??\n buildTransferExecutionCallData(\n '0x036CbD53842c5426634e7929541eC2318f3dCF7e' as Address, // Base Sepolia USDC, matches the real captured fixture\n '0x98ffBf30459a98FD80fAce18f519967769641F76' as Address,\n 10000n,\n )\n return encodeFunctionData({\n abi: REDEEM_DELEGATIONS_ABI,\n functionName: 'redeemDelegations',\n args: [[permissionContext], [SINGLE_DEFAULT_MODE], [executionCallData]],\n })\n}\n\n/**\n * #3272 (B1 regression): `redeemDelegations([emptyPermissionContext],\n * [SingleDefault], [selfCallCallData])` — one permission context whose\n * `Delegation[]` decodes EMPTY, paired with a self-call execution. This is\n * the exact live bypass: MetaMask's DelegationManager treats an empty chain\n * as self-authorised and runs `selfCallCallData` AS the account. Exists only\n * so a test can assert this is refused, never to build a shape any code path\n * signs.\n */\nexport function buildEmptyPermissionContextRedemption(selfCallCallData: Hex): Hex {\n return encodeFunctionData({\n abi: REDEEM_DELEGATIONS_ABI,\n functionName: 'redeemDelegations',\n args: [[buildEmptyPermissionContext()], [SINGLE_DEFAULT_MODE], [selfCallCallData]],\n })\n}\n\n/** `execute((address,uint256,bytes))` — selector `0x5c1c6dcd`. */\nexport function buildExecuteCallData(target: Address, value: bigint, innerCallData: Hex): Hex {\n return encodeFunctionData({\n abi: EXECUTE_ABI,\n functionName: 'execute',\n args: [{ target, value, callData: innerCallData }],\n })\n}\n\nexport interface BoundDirectUserOpOptions {\n /** The delegate EOA (`signer.delegateAddress`) that owns the account `sender` derives from. */\n delegate: Address\n chainId?: number | bigint | string\n /** Override the execute() target — default DELEGATION_MANAGER (the bound shape). */\n target?: Address\n /** Override the execute() value — default 0n. */\n value?: bigint\n /** Override the full message.callData (bypasses target/value/redeemDelegations construction). */\n callData?: Hex\n /** Override sender/verifyingContract directly instead of deriving it from `delegate`. */\n sender?: Address\n /** Override the redemption's delegator (default: a distinct treasury address). */\n delegator?: Address\n}\n\nexport interface BoundDirectUserOp {\n typedData: {\n domain: { name: string; version: string; chainId: number | bigint | string; verifyingContract: Address }\n types: { PackedUserOperation: Array<{ name: string; type: string }> }\n primaryType: 'PackedUserOperation'\n message: Record<string, unknown>\n }\n payloadHash: Hex\n sender: Address\n}\n\n/**\n * A real-shaped, self-consistent (correct v0.7 hash) `PackedUserOperation`.\n * By default it is fully BOUND per #3272's allowlist: `sender` is the\n * counterfactual account for `delegate`, and `callData` redeems ONE real\n * delegation (delegate = `sender`, delegator = a distinct treasury address)\n * through the DelegationManager. Override `target` / `callData` / `sender` /\n * `delegator` to build the negative-test shapes the allowlist must refuse.\n */\nexport function buildBoundDirectUserOp(options: BoundDirectUserOpOptions): BoundDirectUserOp {\n const chainId = options.chainId ?? 84532\n const sender = options.sender ?? deriveDelegateAccountAddress(options.delegate)\n const callData =\n options.callData ??\n buildExecuteCallData(\n options.target ?? (DELEGATION_MANAGER as Address),\n options.value ?? 0n,\n buildBoundRedeemDelegationsCallData({ delegate: sender, delegator: options.delegator }),\n )\n const typedData = {\n domain: {\n name: HYBRID_DELEGATOR_DOMAIN_NAME,\n version: HYBRID_DELEGATOR_DOMAIN_VERSION,\n chainId,\n verifyingContract: sender,\n },\n types: { PackedUserOperation: PACKED_USER_OPERATION_FIELDS.map((field) => ({ ...field })) },\n primaryType: 'PackedUserOperation' as const,\n message: {\n sender,\n nonce: '0',\n initCode: '0x',\n callData,\n accountGasLimits: ZERO_BYTES32,\n preVerificationGas: '0',\n gasFees: ZERO_BYTES32,\n paymasterAndData: '0x',\n entryPoint: ENTRY_POINT_V07,\n },\n }\n const payloadHash = packedUserOperationHash(typedData)\n return { typedData, payloadHash, sender }\n}\n\n/** A well-formed `execute()` self-call — `target === sender` — for the (d)/self-call negative tests. */\nexport function buildSelfCallCallData(sender: Address): Hex {\n const TRANSFER_OWNERSHIP_ABI = [\n { type: 'function', name: 'transferOwnership', inputs: [{ name: 'newOwner', type: 'address' }], outputs: [], stateMutability: 'nonpayable' },\n ] as const\n const inner = encodeFunctionData({\n abi: TRANSFER_OWNERSHIP_ABI,\n functionName: 'transferOwnership',\n args: ['0x000000000000000000000000000000000000dEaD' as Address],\n })\n return buildExecuteCallData(sender, 0n, inner)\n}\n\n/**\n * Re-target a REAL captured direct-payment UserOp (for example\n * `__fixtures__/direct-payment-userop.json`) at `newSender`: the UserOp's\n * `sender` / `verifyingContract` and the redeemed delegation's `delegate`\n * become `newSender`; the delegator, caveats, mode and execution stay the\n * production bytes. The captured fixture is bound to a delegate whose key is\n * not in the repository, so a test signs this rebuilt copy with a test key\n * whose derived account is `newSender` — proving the guard accepts the actual\n * production shape, not only this file's synthetic one.\n */\nexport function rebuildDirectUserOpForSender(\n fixtureTypedData: {\n domain: Record<string, unknown>\n types: Record<string, unknown>\n primaryType: string\n message: Record<string, unknown>\n },\n newSender: Address,\n) {\n const originalCallData = fixtureTypedData.message.callData as Hex\n const { args: executeArgs } = decodeFunctionData({ abi: EXECUTE_ABI, data: originalCallData })\n const execution = executeArgs[0] as { target: Address; value: bigint; callData: Hex }\n const { args: redeemArgs } = decodeFunctionData({ abi: REDEEM_DELEGATIONS_ABI, data: execution.callData })\n const [permissionContexts, modes, executionCallDatas] = redeemArgs as unknown as [\n readonly Hex[],\n readonly Hex[],\n readonly Hex[],\n ]\n const [delegations] = decodeAbiParameters(DELEGATION_ARRAY_PARAM, permissionContexts[0])\n const adjustedDelegations = (delegations as unknown as Array<Record<string, unknown>>).map((d, i) =>\n i === 0 ? { ...d, delegate: newSender } : d,\n )\n const adjustedPermissionContext = encodeAbiParameters(DELEGATION_ARRAY_PARAM, [adjustedDelegations as never])\n const adjustedRedeemCallData = encodeFunctionData({\n abi: REDEEM_DELEGATIONS_ABI,\n functionName: 'redeemDelegations',\n args: [[adjustedPermissionContext], modes as Hex[], executionCallDatas as Hex[]],\n })\n const adjustedCallData = encodeFunctionData({\n abi: EXECUTE_ABI,\n functionName: 'execute',\n args: [{ target: execution.target, value: execution.value, callData: adjustedRedeemCallData }],\n })\n const typedData = {\n ...fixtureTypedData,\n domain: { ...fixtureTypedData.domain, verifyingContract: newSender },\n message: { ...fixtureTypedData.message, sender: newSender, callData: adjustedCallData },\n }\n const payloadHash = packedUserOperationHash(typedData as never) as Hex\n return { typedData, payloadHash }\n}\n\nexport interface FundingLegUserOpOptions {\n /** The delegate EOA (`signer.delegateAddress`): the account is derived from it AND it is the transfer's recipient. */\n delegate: Address\n /** The quoted token (the expected context's `asset`). */\n asset: Address\n /** The quoted atomic amount (the expected context's `amount`). */\n amount: bigint | string\n chainId?: number\n /** Override the transfer recipient (default: `delegate`) — for the recipient-pin negative test. */\n recipient?: Address\n /** Override the budget delegation's caveats (e.g. a multi-KB term, for relay-size tests). */\n caveats?: DelegationOverrides['caveats']\n}\n\n/**\n * #3281: an x402 EIP-3009 bridge FUNDING LEG exactly as the backend builds it\n * (`delegation-authorize.ts` → `prepareDelegationPayment(agent, token,\n * payTo = the delegate EOA, amountRaw)` → `prepareRedemption`): the\n * direct-payment shape, whose single execution is\n * `transfer(<delegate EOA>, <amount>)` on the quoted token. Returns the typed\n * data, its v0.7 UserOp hash (the expected context's `payloadHash`) and its\n * EIP-712 digest (the expected context's `typedDataHash`).\n */\nexport function buildFundingLegUserOp(options: FundingLegUserOpOptions) {\n const sender = deriveDelegateAccountAddress(options.delegate)\n const callData = buildExecuteCallData(\n DELEGATION_MANAGER as Address,\n 0n,\n buildBoundRedeemDelegationsCallData({\n delegate: sender,\n caveats: options.caveats,\n executionCallData: buildTransferExecutionCallData(\n options.asset,\n options.recipient ?? options.delegate,\n BigInt(options.amount),\n ),\n }),\n )\n const { typedData, payloadHash } = buildBoundDirectUserOp({\n delegate: options.delegate,\n chainId: options.chainId ?? 84532,\n callData,\n })\n return { typedData, payloadHash, digest: hashTypedData(typedData as never) }\n}\n","/**\n * #3723 — a REAL signed erc7710 receipt bundle for handler-level tests: the\n * delegate key signs the DelegationManager EIP-712 digest rebuilt from the\n * bundle's own `signHash` + `onChain.chainId`, exactly the math\n * `verifyPaymentReceipt` performs. So `verifyPaymentReceipt(bundle)` returns\n * `{ verified: true, verifiedOver: 'delegation_digest' }` with the DEFAULT\n * ECDSA recovery — the first positive handler-level verify fixture on the\n * MCP runtimes (no stdio-originated payment is erc7710 live: `haven_send` is\n * direct and the stdio x402 path is the eip3009 bridge).\n *\n * Published on the `@haven_ai/sdk/test-support` subpath like the UserOp\n * builder: a sibling package's tests cannot import this file by relative\n * path. Test fixtures, not a signing API: nothing the SDK or signer runs\n * imports it.\n */\nimport { Wallet } from 'ethers'\nimport { concatHex, encodeAbiParameters, keccak256, toBytes, type Hex } from 'viem'\nimport { DELEGATION_MANAGER } from '../settlement-child.js'\nimport { RECEIPT_VERSION, type PaymentReceipt } from '../receipt.js'\n\n/** A fixed delegate key so fixtures are deterministic across runs. */\nexport const RECEIPT_DELEGATE_KEY = `0x${'77'.repeat(32)}` as const\n/** A distinct key, for signer_mismatch fixtures. */\nexport const OTHER_RECEIPT_KEY = `0x${'88'.repeat(32)}` as const\n\nconst EIP712_DOMAIN_TYPEHASH = keccak256(\n toBytes('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'),\n)\n\n/** Same rebuild the verifier does — mirrored here so drift turns the positive test red. */\nfunction delegationDigest(signHash: string, chainId: number): Hex {\n const domainSeparator = keccak256(\n encodeAbiParameters(\n [{ type: 'bytes32' }, { type: 'bytes32' }, { type: 'bytes32' }, { type: 'uint256' }, { type: 'address' }],\n [\n EIP712_DOMAIN_TYPEHASH,\n keccak256(toBytes('DelegationManager')),\n keccak256(toBytes('1')),\n BigInt(chainId),\n DELEGATION_MANAGER as Hex,\n ],\n ),\n )\n return keccak256(concatHex(['0x1901', domainSeparator, signHash as Hex]))\n}\n\nexport interface SignedErc7710Options {\n /** Defaults to `RECEIPT_DELEGATE_KEY`; pass `OTHER_RECEIPT_KEY` for a forged bundle. */\n delegateKey?: string\n signHash?: string\n chainId?: number\n paymentId?: string\n}\n\n/**\n * A signed erc7710 bundle whose `authorization.signature` recovers to the\n * delegate over the delegation digest — `verifyPaymentReceipt` verifies it\n * offline with the default recovery.\n */\nexport function signedErc7710Receipt(options: SignedErc7710Options = {}): PaymentReceipt {\n const chainId = options.chainId ?? 84532 // Base Sepolia — a chain the SDK pins\n const signHash = options.signHash ?? (`0x${'5e'.repeat(32)}` as const)\n const delegate = new Wallet(options.delegateKey ?? RECEIPT_DELEGATE_KEY)\n const signature = delegate.signingKey.sign(delegationDigest(signHash, chainId)).serialized\n return {\n version: RECEIPT_VERSION,\n paymentId: options.paymentId ?? 'pay_3723',\n payment: {\n token: 'USDC',\n tokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n amount: '0.50',\n amountSek: '5.25',\n recipient: '0x15179876c595922999C2d5DC7c23Cc7711fE799a',\n account: '0x135a9215604711AC70d970e12Caa812c53537EF4',\n chainId,\n settledAt: '2026-10-07T10:00:00.000Z',\n resourceUrl: 'https://merchant.example/resource',\n },\n authorization: {\n delegate: delegate.address,\n signHash,\n signature,\n signatureScheme: 'eip712_delegation',\n },\n onChain: { txHash: `0x${'cd'.repeat(32)}`, chainId },\n }\n}\n","/**\n * Canonical (low-s) ECDSA signature assertions for the EIP-3009 bridge (#4550).\n *\n * x402 facilitators reject a non-canonical (high-s) 65-byte EOA signature in\n * `exact` EIP-3009 verify, before settlement (x402-foundation/x402#2728,\n * aligned across SDKs in x402-foundation/x402#3964; wire reason\n * `invalid_exact_evm_non_canonical_signature`). Haven's bridge complies today\n * only because viem's `privateKeyToAccount().sign()` passes `lowS: true` to\n * noble secp256k1 — nothing in Haven checks it. Swapping the signing account\n * (a KMS signer, a hardware key, a different library) could ship high-s\n * headers that every facilitator rejects.\n *\n * The malleable twin `(r, n - s, v ^ 1)` recovers to the SAME address, so a\n * recovery-only test cannot catch it. These helpers assert the wire bytes.\n *\n * Test fixtures only: nothing the SDK or signer runs imports this entry.\n */\n\n/** secp256k1 group order divided by two — the canonical low-s ceiling. */\nexport const SECP256K1_HALF_N =\n 0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0n\n\nexport interface EcdsaSignatureParts {\n /** 32-byte `r`, big-endian. */\n r: bigint\n /** 32-byte `s`, big-endian. */\n s: bigint\n /** Recovery id as it appears on the wire: 27 or 28. */\n v: number\n /** Total signature length in bytes (65 for an EOA signature). */\n length: number\n}\n\n/**\n * Split a 65-byte `0x`-prefixed EOA signature into r/s/v.\n *\n * Throws on anything that is not exactly 65 bytes: a compact (64-byte) or\n * EIP-2098 signature is a different wire shape, and a low-s assertion that\n * silently accepted it would not be pinning the bytes the facilitator reads.\n */\nexport function parseEcdsaSignature(signature: string): EcdsaSignatureParts {\n if (!/^0x[0-9a-fA-F]*$/.test(signature)) {\n throw new Error(`signature is not 0x-prefixed hex: ${signature.slice(0, 20)}…`)\n }\n const hex = signature.slice(2)\n if (hex.length % 2 !== 0) {\n throw new Error(`signature has an odd number of hex digits (${hex.length})`)\n }\n const length = hex.length / 2\n if (length !== 65) {\n throw new Error(`signature must be 65 bytes, got ${length}`)\n }\n return {\n r: BigInt(`0x${hex.slice(0, 64)}`),\n s: BigInt(`0x${hex.slice(64, 128)}`),\n v: Number.parseInt(hex.slice(128, 130), 16),\n length,\n }\n}\n\n/**\n * Assert a wire signature is canonical low-s: 65 bytes, `v ∈ {27, 28}`,\n * `s ≤ n/2`. Throws with the offending value so a prove-red run names the\n * exact branch that regressed.\n */\nexport function assertLowSSignature(signature: string): EcdsaSignatureParts {\n const parts = parseEcdsaSignature(signature)\n if (parts.v !== 27 && parts.v !== 28) {\n throw new Error(`signature v must be 27 or 28, got ${parts.v}`)\n }\n if (parts.s > SECP256K1_HALF_N) {\n throw new Error(\n `signature is high-s (malleable): s=0x${parts.s.toString(16)} exceeds ` +\n `n/2=0x${SECP256K1_HALF_N.toString(16)}`,\n )\n }\n return parts\n}\n"]}
@@ -787,6 +787,14 @@ interface HavenAllowance {
787
787
  * compared alone — they do not add up. Never a balance figure.
788
788
  */
789
789
  fundsCoverRemaining: boolean | null;
790
+ /**
791
+ * #4355: when THIS budget next refills — the end of its current period
792
+ * (ISO 8601), or its start for a budget not yet started. `null` when it
793
+ * never refills again (it ends first), and on a backend that predates the
794
+ * field. With a remaining of 0 it says the budget is spent for this period
795
+ * and when it comes back — not that nobody approved one.
796
+ */
797
+ nextRefillAt: string | null;
790
798
  /**
791
799
  * #3518: this budget's SCOPE, so an agent holding more than one budget
792
800
  * for a token can name the merchant-locked one before paying. The
@@ -841,6 +849,14 @@ interface HavenAllowanceSummary {
841
849
  delegateAddress: string;
842
850
  chainId: number;
843
851
  allowances: HavenAllowance[];
852
+ /**
853
+ * #4352 (additive, decision 5): when the agent's only budgets for this
854
+ * chain have ENDED, the latest ended budget's expiry (ISO 8601) — read by
855
+ * the same narrow expired-row query the refusal answers use. `null` when no
856
+ * expired row exists; the field NEVER reports a live budget. `null` on a
857
+ * backend that predates the field.
858
+ */
859
+ budgetEndedAt: string | null;
844
860
  /** #3772: see {@link HavenAgent.supersededBy}. */
845
861
  supersededBy: HavenAgentSupersession | null;
846
862
  }
@@ -1040,6 +1056,8 @@ interface HavenAgentAllowanceSummary {
1040
1056
  * read: any non-boolean wire value maps to `null`, never `undefined`.
1041
1057
  */
1042
1058
  fundsCoverRemaining: boolean | null;
1059
+ /** #4355: the {@link HavenAllowance.nextRefillAt} projection. */
1060
+ nextRefillAt: string | null;
1043
1061
  }
1044
1062
  /**
1045
1063
  * One-shot "am I ready?" bootstrap: identity + live spend authority + a
@@ -1063,6 +1081,27 @@ interface HavenAgentSummary extends HavenAgent {
1063
1081
  * renders from `HAVEN_CONNECTOR_CHANNEL` — see `connector-channel.ts`).
1064
1082
  */
1065
1083
  spend_authority_readiness: HavenAgentReadiness;
1084
+ /**
1085
+ * #4355 (additive; the readiness values are unchanged — #4349 decision 5):
1086
+ * set only when readiness is `needs_approval` BECAUSE every live budget is
1087
+ * spent for its period — `allowances[]` has rows, all at remaining 0. It is
1088
+ * the earliest {@link HavenAgentAllowanceSummary.nextRefillAt} among them:
1089
+ * wait until then, or ask the owner to raise the budget. `null` otherwise:
1090
+ * ready, revoked, no budget approved (`allowances[]` empty), or a spent
1091
+ * budget that ends before it would refill.
1092
+ */
1093
+ budgetRefillsAt: string | null;
1094
+ /**
1095
+ * #4352 (additive; the readiness values are unchanged — #4349 decision 5):
1096
+ * set only when readiness is `needs_approval` BECAUSE the agent's only
1097
+ * budget(s) have ENDED — `allowances[]` is empty and the server's
1098
+ * expired-row read found one. The ended budget's expiry (ISO 8601): waiting
1099
+ * will not help; ask the owner to set a new one. `null` otherwise — ready,
1100
+ * revoked, no budget approved at all, live rows present (whether spendable
1101
+ * or all spent — the latter is {@link HavenAgentSummary.budgetRefillsAt}'s
1102
+ * case), or a backend that predates the field.
1103
+ */
1104
+ budgetEndedAt: string | null;
1066
1105
  allowances: HavenAgentAllowanceSummary[];
1067
1106
  /**
1068
1107
  * #3329: open, unexpired task budgets — a derived VIEW, same discipline as
@@ -1389,6 +1428,23 @@ interface HavenPaymentReceipt {
1389
1428
  paymentId: string;
1390
1429
  paymentIntentId?: string | null;
1391
1430
  approvalRequestId?: string | null;
1431
+ /**
1432
+ * #4469: which settlement branch moved the money (`eip3009` | `erc7710`),
1433
+ * from the intent (#946). The receipts wire declares this as raw text with
1434
+ * no enum (`packages/backend/src/openapi/spec.ts`), so it is typed
1435
+ * `string | null` here rather than narrowed: a value this SDK does not know
1436
+ * is still the backend's record, and narrowing it to `null` would erase it.
1437
+ * Absent on an older backend; `null` when the backend states no scheme
1438
+ * (legacy-rail receipts).
1439
+ */
1440
+ settlementScheme?: string | null;
1441
+ /**
1442
+ * #4469: the budget delegation that METERED this payment (#3518), uniform
1443
+ * across schemes. `string | null` on receipts — the backend sends
1444
+ * `?? null` — unlike {@link PaymentStatusResult.budgetDelegationHash}, which
1445
+ * is `string` and absent when unknown. Absent on an older backend.
1446
+ */
1447
+ budgetDelegationHash?: string | null;
1392
1448
  /**
1393
1449
  * #3134: the payment protocol this receipt settled on — one of the
1394
1450
  * evidence-eligible rails (`x402`, `mpp_demo`, `mpp_crypto`, `spt`) — under the
@@ -1464,6 +1520,32 @@ interface HavenPaymentReceipt {
1464
1520
  */
1465
1521
  protocolReceiptPayload?: Record<string, unknown> | null;
1466
1522
  merchantStatus: number | null;
1523
+ /**
1524
+ * #4469: the paying agent's own delivery verdict (#3770), when it reported
1525
+ * one — `ok` | `unusable` | `partial`. Evidence only: it never gates
1526
+ * anything and the payment itself is unchanged. Absent on an older backend;
1527
+ * `null` when the backend states "not reported".
1528
+ */
1529
+ deliveryQuality?: 'ok' | 'unusable' | 'partial' | null;
1530
+ /** #4469: the agent's optional note (max 2000 chars) saying what was wrong. Absent on an older backend. */
1531
+ deliveryNote?: string | null;
1532
+ /** #4469: when the agent reported the verdict (ISO 8601). Absent on an older backend. */
1533
+ deliveryReportedAt?: string | null;
1534
+ /**
1535
+ * #4469: the NON-SECRET pointer to a delivered good (#3778) — merchant,
1536
+ * product, value, order id. Never a redemption code or other credential:
1537
+ * those are refused at write. Absent on an older backend.
1538
+ */
1539
+ deliveryReference?: string | null;
1540
+ /**
1541
+ * #4534: the purchase correlation key. `purchaseGroupId` is the merchant's
1542
+ * own invoice/order id (or an agent-supplied group key) shared by every
1543
+ * payment of one purchase; `parentPaymentId` is the purchase payment a fee
1544
+ * call paid for. Both null on an ungrouped payment. Absent on an older
1545
+ * backend.
1546
+ */
1547
+ purchaseGroupId?: string | null;
1548
+ parentPaymentId?: string | null;
1467
1549
  confirmedAt: string | null;
1468
1550
  createdAt: string;
1469
1551
  updatedAt: string;
@@ -1839,6 +1921,18 @@ declare const AgentPaymentWarningCode: {
1839
1921
  * remains the actual gate either way.
1840
1922
  */
1841
1923
  readonly QuoteExceedsRemainingBudget: "QUOTE_EXCEEDS_REMAINING_BUDGET";
1924
+ /**
1925
+ * #4458: the agent's only budget for the token has ENDED — the quote-time
1926
+ * pre-check answered the typed 403 `delegation_expired`, not an over-budget
1927
+ * compare. Travels beside `budget_check.sufficient: false` and, on
1928
+ * `haven_quote_x402`, `safe_to_continue: false` with no prefilled cap. The
1929
+ * remedy is the owner setting a NEW budget: waiting for a period to reset
1930
+ * cannot help, which is why this is its own code rather than
1931
+ * {@link AgentPaymentWarningCode.QuoteExceedsRemainingBudget}. Additive: an
1932
+ * older backend never emits it, and the on-chain policy remains the actual
1933
+ * gate either way.
1934
+ */
1935
+ readonly QuoteBudgetEnded: "QUOTE_BUDGET_ENDED";
1842
1936
  /**
1843
1937
  * #3967: the MERCHANT reported a denial on one of its x402 payment options —
1844
1938
  * a known denial key (starting with `issuanceDenied`) in `accepts[].extra`.
@@ -1989,6 +2083,16 @@ interface PaymentStatusResult {
1989
2083
  * `delivered`'s own honesty rule.
1990
2084
  */
1991
2085
  merchantSettlementRecorded?: boolean;
2086
+ /**
2087
+ * #4530: the merchant settlement transaction Haven recorded and verified
2088
+ * on-chain — the transaction `merchantSettlementRecorded` reports, named so
2089
+ * a status read can confirm WHICH one was recorded (the settlement sweep
2090
+ * records one the agent never reported). Present only when
2091
+ * `merchantSettlementRecorded` is; absent otherwise, and never the
2092
+ * merchant's unverified echo. A public on-chain transaction id, not a
2093
+ * secret.
2094
+ */
2095
+ merchantSettlementTxHash?: string;
1992
2096
  /**
1993
2097
  * #3494: a bounded, redacted cause for a `failed` payment — present
1994
2098
  * (possibly `null`, when no message was recorded) only when `status` is
@@ -2172,9 +2276,66 @@ declare class HavenError extends Error {
2172
2276
  readonly paymentId?: string | undefined;
2173
2277
  constructor(message: string, code: string, statusCode?: number | undefined, paymentId?: string | undefined);
2174
2278
  }
2279
+ /**
2280
+ * #4470: why a `HavenApiError` happened, where its status alone cannot say.
2281
+ *
2282
+ * - `no_answer` — the transport got no usable answer: the request timed out
2283
+ * (status 408), `fetch` threw, or the body was not JSON (status 0). Whether
2284
+ * the call took effect is unknown, so a `GET` may be retried and a `POST`
2285
+ * must not be; `method` says which it was.
2286
+ * - `deterministic` — the SDK refused an answer it cannot use (a missing
2287
+ * field, the wrong shape). Repeating the same call gets the same answer,
2288
+ * whatever the status says.
2289
+ *
2290
+ * Absent on every other error, which keeps the status rule. A readonly field
2291
+ * rather than a subclass, so `name`, `code` and `statusCode` stay what
2292
+ * consumers already match on.
2293
+ */
2294
+ type HavenApiFailureCause = {
2295
+ readonly kind: 'no_answer';
2296
+ readonly method: 'GET' | 'POST';
2297
+ } | {
2298
+ readonly kind: 'deterministic';
2299
+ };
2175
2300
  declare class HavenApiError extends HavenError {
2176
2301
  readonly body?: unknown | undefined;
2177
- constructor(message: string, statusCode: number, body?: unknown | undefined, paymentId?: string);
2302
+ readonly failureCause?: HavenApiFailureCause | undefined;
2303
+ constructor(message: string, statusCode: number, body?: unknown | undefined, paymentId?: string, failureCause?: HavenApiFailureCause | undefined);
2304
+ /**
2305
+ * #4470: an error a retry cannot change. The census in
2306
+ * `haven-api-error-census.test.ts` requires every literal 5xx site to use
2307
+ * this or be allowlisted there with a reason.
2308
+ */
2309
+ static deterministic(message: string, statusCode: number, body?: unknown, paymentId?: string): HavenApiError;
2310
+ }
2311
+ /**
2312
+ * #4470: the funding transaction's confirmation could not be read — ethers'
2313
+ * `waitForTransaction` rejected (its `TIMEOUT`, or an RPC failure). Haven had
2314
+ * already submitted the funding leg, so funds may have reached the delegate:
2315
+ * the answer is check-status, never "tell the user it failed" and never a new
2316
+ * payment. The merchant was not called.
2317
+ *
2318
+ * Deliberately carries no `failureCause`: it is not a transport non-answer
2319
+ * (no Haven request went unanswered) and not deterministic (a later read may
2320
+ * see the receipt). Callers answer the class itself — the hosted delivery
2321
+ * step does in `ensureFundingConfirmedOrRefuse`; unwrapped, its 504 reads
2322
+ * "re-call once", which re-runs the same wait.
2323
+ */
2324
+ declare class FundingConfirmationUnknownError extends HavenApiError {
2325
+ readonly txHash: string;
2326
+ readonly chainId: number;
2327
+ readonly fundingErrorCode: "funding_confirmation_unknown";
2328
+ constructor(txHash: string, chainId: number, reason: string);
2329
+ }
2330
+ /**
2331
+ * #4470: the funding transaction was mined and reverted, so nothing reached
2332
+ * the delegate. Repeating the wait gets the same receipt.
2333
+ */
2334
+ declare class FundingRevertedError extends HavenApiError {
2335
+ readonly txHash: string;
2336
+ readonly chainId: number;
2337
+ readonly fundingErrorCode: "funding_reverted";
2338
+ constructor(txHash: string, chainId: number);
2178
2339
  }
2179
2340
  /**
2180
2341
  * #1300: quoteX402 hit a URL that answered something other than 402 — the
@@ -2380,4 +2541,4 @@ declare class HavenTimeoutError extends HavenError {
2380
2541
  constructor(paymentId: string);
2381
2542
  }
2382
2543
 
2383
- export { AgentPaymentNextActionSchema as $, type AgentPaymentWarning as A, type BudgetPrecheckResult as B, type CloseTaskBudgetResult as C, type X402ResumeState as D, type X402McpTransport as E, type X402MerchantCallContext as F, type X402IntentByKey as G, type HavenClientConfig as H, HavenError as I, AGENT_PAYMENT_FAILURE_CODE_VALUES as J, AGENT_PAYMENT_NEXT_ACTION_VALUES as K, AGENT_PAYMENT_PHASE_VALUES as L, type MerchantEgressPolicy as M, AGENT_PAYMENT_RAIL_VALUES as N, type OpenTaskBudgetResult as O, type PaymentRequest as P, type AgentNextStep as Q, type ResumeAuthorizedX402Input as R, type SweepResult as S, type TaskBudgetSignContext as T, type AgentPaymentEnumSchema as U, AgentPaymentFailureCode as V, AgentPaymentFailureCodeDescriptions as W, type X402PaymentRequired as X, AgentPaymentFailureCodeSchema as Y, AgentPaymentNextAction as Z, AgentPaymentNextActionDescriptions as _, type PaymentResult as a, AgentPaymentPhase as a0, AgentPaymentPhaseDescriptions as a1, AgentPaymentPhaseSchema as a2, AgentPaymentRail as a3, AgentPaymentRailDescriptions as a4, AgentPaymentRailSchema as a5, type AgentPaymentSummary as a6, AgentPaymentWarningCode as a7, type AgentPurchaseSummary as a8, type CatalogSubmissionAccepted as a9, type PaymentFee as aA, type PaymentNextAction as aB, type PaymentPhase as aC, type PaymentStatus as aD, SIGNER_UPDATE_FALLBACK as aE, SignerRefusalCode as aF, type SweepConfirmation as aG, type SweepEntry as aH, X402AlreadySettledError as aI, X402Erc7710AlreadySettledError as aJ, type X402ExpectedAuth as aK, type X402ExpectedContext as aL, type X402PaymentOption as aM, type X402RequestSnapshot as aN, X402TaskBudgetMismatchError as aO, X402UnexpectedStatusError as aP, assertPublicHttpsMerchantUrl as aQ, isPublicHttpsMerchantUrl as aR, publicHttpsMerchantUrlRefusal as aS, readBodyCapped as aT, signerUpdateFallback as aU, strictMerchantEgressPolicy as aV, type RawPaymentParties as aW, DEFAULT_CONFIRMATION_TIMEOUT_MS as aa, HOSTED_DISCOVERY_TIMEOUT_MS as ab, HOSTED_EGRESS_TIMEOUTS as ac, HOSTED_MAX_GET_REDIRECTS as ad, HOSTED_RESPONSE_BYTE_CAPS as ae, type HavenAgentAllowanceSummary as af, type HavenAgentReadiness as ag, type HavenAgentSupersession as ah, type HavenAllowance as ai, HavenApiError as aj, type HavenCatalogMerchant as ak, type HavenListScope as al, HavenPaymentStateError as am, HavenSigningError as an, HavenTimeoutError as ao, HavenUnsupportedSignerVersionError as ap, HavenZeroSettlementHashError as aq, MERCHANT_EGRESS_REFUSED_CODE as ar, MERCHANT_EGRESS_RESPONSE_CAP_CODE as as, type MachinePaymentRail as at, type MerchantEgressRefusalReason as au, MerchantEgressRefusedError as av, MerchantEgressResponseCapError as aw, type MerchantEgressTimeouts as ax, type MerchantEgressUse as ay, MerchantTimeoutError as az, type PaymentIntent as b, type X402AuthorizationOptions as c, type X402Intent as d, type PaymentStatusResult as e, type HavenAgent as f, type HavenAgentSummary as g, type HavenAllowanceSummary as h, type HavenBalanceCoverage as i, type PostPurchaseAllowanceSummary as j, type HavenCatalogEntry as k, type HavenCatalogSubmission as l, type HavenPaymentReceipt as m, type HavenPaymentReceiptsPage as n, type HavenTaskBudget as o, type SubmitTaskBudgetResult as p, type SubmitSubBudgetResult as q, type HavenPendingSubBudgetSignature as r, type CloseSubBudgetResult as s, type PaymentResumeState as t, type X402Receipt as u, type X402Quote as v, type X402Erc7710Settlement as w, type X402McpCallContext as x, type SignData as y, type ResumeX402PaymentInput as z };
2544
+ export { AgentPaymentNextActionSchema as $, type AgentPaymentWarning as A, type BudgetPrecheckResult as B, type CloseTaskBudgetResult as C, type X402ResumeState as D, type X402McpTransport as E, type X402MerchantCallContext as F, type X402IntentByKey as G, type HavenClientConfig as H, HavenError as I, AGENT_PAYMENT_FAILURE_CODE_VALUES as J, AGENT_PAYMENT_NEXT_ACTION_VALUES as K, AGENT_PAYMENT_PHASE_VALUES as L, type MerchantEgressPolicy as M, AGENT_PAYMENT_RAIL_VALUES as N, type OpenTaskBudgetResult as O, type PaymentRequest as P, type AgentNextStep as Q, type ResumeAuthorizedX402Input as R, type SweepResult as S, type TaskBudgetSignContext as T, type AgentPaymentEnumSchema as U, AgentPaymentFailureCode as V, AgentPaymentFailureCodeDescriptions as W, type X402PaymentRequired as X, AgentPaymentFailureCodeSchema as Y, AgentPaymentNextAction as Z, AgentPaymentNextActionDescriptions as _, type PaymentResult as a, AgentPaymentPhase as a0, AgentPaymentPhaseDescriptions as a1, AgentPaymentPhaseSchema as a2, AgentPaymentRail as a3, AgentPaymentRailDescriptions as a4, AgentPaymentRailSchema as a5, type AgentPaymentSummary as a6, AgentPaymentWarningCode as a7, type AgentPurchaseSummary as a8, type CatalogSubmissionAccepted as a9, type MerchantEgressTimeouts as aA, type MerchantEgressUse as aB, MerchantTimeoutError as aC, type PaymentFee as aD, type PaymentNextAction as aE, type PaymentPhase as aF, type PaymentStatus as aG, SIGNER_UPDATE_FALLBACK as aH, SignerRefusalCode as aI, type SweepConfirmation as aJ, type SweepEntry as aK, X402AlreadySettledError as aL, X402Erc7710AlreadySettledError as aM, type X402ExpectedAuth as aN, type X402ExpectedContext as aO, type X402PaymentOption as aP, type X402RequestSnapshot as aQ, X402TaskBudgetMismatchError as aR, X402UnexpectedStatusError as aS, assertPublicHttpsMerchantUrl as aT, isPublicHttpsMerchantUrl as aU, publicHttpsMerchantUrlRefusal as aV, readBodyCapped as aW, signerUpdateFallback as aX, strictMerchantEgressPolicy as aY, type RawPaymentParties as aZ, DEFAULT_CONFIRMATION_TIMEOUT_MS as aa, FundingConfirmationUnknownError as ab, FundingRevertedError as ac, HOSTED_DISCOVERY_TIMEOUT_MS as ad, HOSTED_EGRESS_TIMEOUTS as ae, HOSTED_MAX_GET_REDIRECTS as af, HOSTED_RESPONSE_BYTE_CAPS as ag, type HavenAgentAllowanceSummary as ah, type HavenAgentReadiness as ai, type HavenAgentSupersession as aj, type HavenAllowance as ak, HavenApiError as al, type HavenApiFailureCause as am, type HavenCatalogMerchant as an, type HavenListScope as ao, HavenPaymentStateError as ap, HavenSigningError as aq, HavenTimeoutError as ar, HavenUnsupportedSignerVersionError as as, HavenZeroSettlementHashError as at, MERCHANT_EGRESS_REFUSED_CODE as au, MERCHANT_EGRESS_RESPONSE_CAP_CODE as av, type MachinePaymentRail as aw, type MerchantEgressRefusalReason as ax, MerchantEgressRefusedError as ay, MerchantEgressResponseCapError as az, type PaymentIntent as b, type X402AuthorizationOptions as c, type X402Intent as d, type PaymentStatusResult as e, type HavenAgent as f, type HavenAgentSummary as g, type HavenAllowanceSummary as h, type HavenBalanceCoverage as i, type PostPurchaseAllowanceSummary as j, type HavenCatalogEntry as k, type HavenCatalogSubmission as l, type HavenPaymentReceipt as m, type HavenPaymentReceiptsPage as n, type HavenTaskBudget as o, type SubmitTaskBudgetResult as p, type SubmitSubBudgetResult as q, type HavenPendingSubBudgetSignature as r, type CloseSubBudgetResult as s, type PaymentResumeState as t, type X402Receipt as u, type X402Quote as v, type X402Erc7710Settlement as w, type X402McpCallContext as x, type SignData as y, type ResumeX402PaymentInput as z };
@@ -787,6 +787,14 @@ interface HavenAllowance {
787
787
  * compared alone — they do not add up. Never a balance figure.
788
788
  */
789
789
  fundsCoverRemaining: boolean | null;
790
+ /**
791
+ * #4355: when THIS budget next refills — the end of its current period
792
+ * (ISO 8601), or its start for a budget not yet started. `null` when it
793
+ * never refills again (it ends first), and on a backend that predates the
794
+ * field. With a remaining of 0 it says the budget is spent for this period
795
+ * and when it comes back — not that nobody approved one.
796
+ */
797
+ nextRefillAt: string | null;
790
798
  /**
791
799
  * #3518: this budget's SCOPE, so an agent holding more than one budget
792
800
  * for a token can name the merchant-locked one before paying. The
@@ -841,6 +849,14 @@ interface HavenAllowanceSummary {
841
849
  delegateAddress: string;
842
850
  chainId: number;
843
851
  allowances: HavenAllowance[];
852
+ /**
853
+ * #4352 (additive, decision 5): when the agent's only budgets for this
854
+ * chain have ENDED, the latest ended budget's expiry (ISO 8601) — read by
855
+ * the same narrow expired-row query the refusal answers use. `null` when no
856
+ * expired row exists; the field NEVER reports a live budget. `null` on a
857
+ * backend that predates the field.
858
+ */
859
+ budgetEndedAt: string | null;
844
860
  /** #3772: see {@link HavenAgent.supersededBy}. */
845
861
  supersededBy: HavenAgentSupersession | null;
846
862
  }
@@ -1040,6 +1056,8 @@ interface HavenAgentAllowanceSummary {
1040
1056
  * read: any non-boolean wire value maps to `null`, never `undefined`.
1041
1057
  */
1042
1058
  fundsCoverRemaining: boolean | null;
1059
+ /** #4355: the {@link HavenAllowance.nextRefillAt} projection. */
1060
+ nextRefillAt: string | null;
1043
1061
  }
1044
1062
  /**
1045
1063
  * One-shot "am I ready?" bootstrap: identity + live spend authority + a
@@ -1063,6 +1081,27 @@ interface HavenAgentSummary extends HavenAgent {
1063
1081
  * renders from `HAVEN_CONNECTOR_CHANNEL` — see `connector-channel.ts`).
1064
1082
  */
1065
1083
  spend_authority_readiness: HavenAgentReadiness;
1084
+ /**
1085
+ * #4355 (additive; the readiness values are unchanged — #4349 decision 5):
1086
+ * set only when readiness is `needs_approval` BECAUSE every live budget is
1087
+ * spent for its period — `allowances[]` has rows, all at remaining 0. It is
1088
+ * the earliest {@link HavenAgentAllowanceSummary.nextRefillAt} among them:
1089
+ * wait until then, or ask the owner to raise the budget. `null` otherwise:
1090
+ * ready, revoked, no budget approved (`allowances[]` empty), or a spent
1091
+ * budget that ends before it would refill.
1092
+ */
1093
+ budgetRefillsAt: string | null;
1094
+ /**
1095
+ * #4352 (additive; the readiness values are unchanged — #4349 decision 5):
1096
+ * set only when readiness is `needs_approval` BECAUSE the agent's only
1097
+ * budget(s) have ENDED — `allowances[]` is empty and the server's
1098
+ * expired-row read found one. The ended budget's expiry (ISO 8601): waiting
1099
+ * will not help; ask the owner to set a new one. `null` otherwise — ready,
1100
+ * revoked, no budget approved at all, live rows present (whether spendable
1101
+ * or all spent — the latter is {@link HavenAgentSummary.budgetRefillsAt}'s
1102
+ * case), or a backend that predates the field.
1103
+ */
1104
+ budgetEndedAt: string | null;
1066
1105
  allowances: HavenAgentAllowanceSummary[];
1067
1106
  /**
1068
1107
  * #3329: open, unexpired task budgets — a derived VIEW, same discipline as
@@ -1389,6 +1428,23 @@ interface HavenPaymentReceipt {
1389
1428
  paymentId: string;
1390
1429
  paymentIntentId?: string | null;
1391
1430
  approvalRequestId?: string | null;
1431
+ /**
1432
+ * #4469: which settlement branch moved the money (`eip3009` | `erc7710`),
1433
+ * from the intent (#946). The receipts wire declares this as raw text with
1434
+ * no enum (`packages/backend/src/openapi/spec.ts`), so it is typed
1435
+ * `string | null` here rather than narrowed: a value this SDK does not know
1436
+ * is still the backend's record, and narrowing it to `null` would erase it.
1437
+ * Absent on an older backend; `null` when the backend states no scheme
1438
+ * (legacy-rail receipts).
1439
+ */
1440
+ settlementScheme?: string | null;
1441
+ /**
1442
+ * #4469: the budget delegation that METERED this payment (#3518), uniform
1443
+ * across schemes. `string | null` on receipts — the backend sends
1444
+ * `?? null` — unlike {@link PaymentStatusResult.budgetDelegationHash}, which
1445
+ * is `string` and absent when unknown. Absent on an older backend.
1446
+ */
1447
+ budgetDelegationHash?: string | null;
1392
1448
  /**
1393
1449
  * #3134: the payment protocol this receipt settled on — one of the
1394
1450
  * evidence-eligible rails (`x402`, `mpp_demo`, `mpp_crypto`, `spt`) — under the
@@ -1464,6 +1520,32 @@ interface HavenPaymentReceipt {
1464
1520
  */
1465
1521
  protocolReceiptPayload?: Record<string, unknown> | null;
1466
1522
  merchantStatus: number | null;
1523
+ /**
1524
+ * #4469: the paying agent's own delivery verdict (#3770), when it reported
1525
+ * one — `ok` | `unusable` | `partial`. Evidence only: it never gates
1526
+ * anything and the payment itself is unchanged. Absent on an older backend;
1527
+ * `null` when the backend states "not reported".
1528
+ */
1529
+ deliveryQuality?: 'ok' | 'unusable' | 'partial' | null;
1530
+ /** #4469: the agent's optional note (max 2000 chars) saying what was wrong. Absent on an older backend. */
1531
+ deliveryNote?: string | null;
1532
+ /** #4469: when the agent reported the verdict (ISO 8601). Absent on an older backend. */
1533
+ deliveryReportedAt?: string | null;
1534
+ /**
1535
+ * #4469: the NON-SECRET pointer to a delivered good (#3778) — merchant,
1536
+ * product, value, order id. Never a redemption code or other credential:
1537
+ * those are refused at write. Absent on an older backend.
1538
+ */
1539
+ deliveryReference?: string | null;
1540
+ /**
1541
+ * #4534: the purchase correlation key. `purchaseGroupId` is the merchant's
1542
+ * own invoice/order id (or an agent-supplied group key) shared by every
1543
+ * payment of one purchase; `parentPaymentId` is the purchase payment a fee
1544
+ * call paid for. Both null on an ungrouped payment. Absent on an older
1545
+ * backend.
1546
+ */
1547
+ purchaseGroupId?: string | null;
1548
+ parentPaymentId?: string | null;
1467
1549
  confirmedAt: string | null;
1468
1550
  createdAt: string;
1469
1551
  updatedAt: string;
@@ -1839,6 +1921,18 @@ declare const AgentPaymentWarningCode: {
1839
1921
  * remains the actual gate either way.
1840
1922
  */
1841
1923
  readonly QuoteExceedsRemainingBudget: "QUOTE_EXCEEDS_REMAINING_BUDGET";
1924
+ /**
1925
+ * #4458: the agent's only budget for the token has ENDED — the quote-time
1926
+ * pre-check answered the typed 403 `delegation_expired`, not an over-budget
1927
+ * compare. Travels beside `budget_check.sufficient: false` and, on
1928
+ * `haven_quote_x402`, `safe_to_continue: false` with no prefilled cap. The
1929
+ * remedy is the owner setting a NEW budget: waiting for a period to reset
1930
+ * cannot help, which is why this is its own code rather than
1931
+ * {@link AgentPaymentWarningCode.QuoteExceedsRemainingBudget}. Additive: an
1932
+ * older backend never emits it, and the on-chain policy remains the actual
1933
+ * gate either way.
1934
+ */
1935
+ readonly QuoteBudgetEnded: "QUOTE_BUDGET_ENDED";
1842
1936
  /**
1843
1937
  * #3967: the MERCHANT reported a denial on one of its x402 payment options —
1844
1938
  * a known denial key (starting with `issuanceDenied`) in `accepts[].extra`.
@@ -1989,6 +2083,16 @@ interface PaymentStatusResult {
1989
2083
  * `delivered`'s own honesty rule.
1990
2084
  */
1991
2085
  merchantSettlementRecorded?: boolean;
2086
+ /**
2087
+ * #4530: the merchant settlement transaction Haven recorded and verified
2088
+ * on-chain — the transaction `merchantSettlementRecorded` reports, named so
2089
+ * a status read can confirm WHICH one was recorded (the settlement sweep
2090
+ * records one the agent never reported). Present only when
2091
+ * `merchantSettlementRecorded` is; absent otherwise, and never the
2092
+ * merchant's unverified echo. A public on-chain transaction id, not a
2093
+ * secret.
2094
+ */
2095
+ merchantSettlementTxHash?: string;
1992
2096
  /**
1993
2097
  * #3494: a bounded, redacted cause for a `failed` payment — present
1994
2098
  * (possibly `null`, when no message was recorded) only when `status` is
@@ -2172,9 +2276,66 @@ declare class HavenError extends Error {
2172
2276
  readonly paymentId?: string | undefined;
2173
2277
  constructor(message: string, code: string, statusCode?: number | undefined, paymentId?: string | undefined);
2174
2278
  }
2279
+ /**
2280
+ * #4470: why a `HavenApiError` happened, where its status alone cannot say.
2281
+ *
2282
+ * - `no_answer` — the transport got no usable answer: the request timed out
2283
+ * (status 408), `fetch` threw, or the body was not JSON (status 0). Whether
2284
+ * the call took effect is unknown, so a `GET` may be retried and a `POST`
2285
+ * must not be; `method` says which it was.
2286
+ * - `deterministic` — the SDK refused an answer it cannot use (a missing
2287
+ * field, the wrong shape). Repeating the same call gets the same answer,
2288
+ * whatever the status says.
2289
+ *
2290
+ * Absent on every other error, which keeps the status rule. A readonly field
2291
+ * rather than a subclass, so `name`, `code` and `statusCode` stay what
2292
+ * consumers already match on.
2293
+ */
2294
+ type HavenApiFailureCause = {
2295
+ readonly kind: 'no_answer';
2296
+ readonly method: 'GET' | 'POST';
2297
+ } | {
2298
+ readonly kind: 'deterministic';
2299
+ };
2175
2300
  declare class HavenApiError extends HavenError {
2176
2301
  readonly body?: unknown | undefined;
2177
- constructor(message: string, statusCode: number, body?: unknown | undefined, paymentId?: string);
2302
+ readonly failureCause?: HavenApiFailureCause | undefined;
2303
+ constructor(message: string, statusCode: number, body?: unknown | undefined, paymentId?: string, failureCause?: HavenApiFailureCause | undefined);
2304
+ /**
2305
+ * #4470: an error a retry cannot change. The census in
2306
+ * `haven-api-error-census.test.ts` requires every literal 5xx site to use
2307
+ * this or be allowlisted there with a reason.
2308
+ */
2309
+ static deterministic(message: string, statusCode: number, body?: unknown, paymentId?: string): HavenApiError;
2310
+ }
2311
+ /**
2312
+ * #4470: the funding transaction's confirmation could not be read — ethers'
2313
+ * `waitForTransaction` rejected (its `TIMEOUT`, or an RPC failure). Haven had
2314
+ * already submitted the funding leg, so funds may have reached the delegate:
2315
+ * the answer is check-status, never "tell the user it failed" and never a new
2316
+ * payment. The merchant was not called.
2317
+ *
2318
+ * Deliberately carries no `failureCause`: it is not a transport non-answer
2319
+ * (no Haven request went unanswered) and not deterministic (a later read may
2320
+ * see the receipt). Callers answer the class itself — the hosted delivery
2321
+ * step does in `ensureFundingConfirmedOrRefuse`; unwrapped, its 504 reads
2322
+ * "re-call once", which re-runs the same wait.
2323
+ */
2324
+ declare class FundingConfirmationUnknownError extends HavenApiError {
2325
+ readonly txHash: string;
2326
+ readonly chainId: number;
2327
+ readonly fundingErrorCode: "funding_confirmation_unknown";
2328
+ constructor(txHash: string, chainId: number, reason: string);
2329
+ }
2330
+ /**
2331
+ * #4470: the funding transaction was mined and reverted, so nothing reached
2332
+ * the delegate. Repeating the wait gets the same receipt.
2333
+ */
2334
+ declare class FundingRevertedError extends HavenApiError {
2335
+ readonly txHash: string;
2336
+ readonly chainId: number;
2337
+ readonly fundingErrorCode: "funding_reverted";
2338
+ constructor(txHash: string, chainId: number);
2178
2339
  }
2179
2340
  /**
2180
2341
  * #1300: quoteX402 hit a URL that answered something other than 402 — the
@@ -2380,4 +2541,4 @@ declare class HavenTimeoutError extends HavenError {
2380
2541
  constructor(paymentId: string);
2381
2542
  }
2382
2543
 
2383
- export { AgentPaymentNextActionSchema as $, type AgentPaymentWarning as A, type BudgetPrecheckResult as B, type CloseTaskBudgetResult as C, type X402ResumeState as D, type X402McpTransport as E, type X402MerchantCallContext as F, type X402IntentByKey as G, type HavenClientConfig as H, HavenError as I, AGENT_PAYMENT_FAILURE_CODE_VALUES as J, AGENT_PAYMENT_NEXT_ACTION_VALUES as K, AGENT_PAYMENT_PHASE_VALUES as L, type MerchantEgressPolicy as M, AGENT_PAYMENT_RAIL_VALUES as N, type OpenTaskBudgetResult as O, type PaymentRequest as P, type AgentNextStep as Q, type ResumeAuthorizedX402Input as R, type SweepResult as S, type TaskBudgetSignContext as T, type AgentPaymentEnumSchema as U, AgentPaymentFailureCode as V, AgentPaymentFailureCodeDescriptions as W, type X402PaymentRequired as X, AgentPaymentFailureCodeSchema as Y, AgentPaymentNextAction as Z, AgentPaymentNextActionDescriptions as _, type PaymentResult as a, AgentPaymentPhase as a0, AgentPaymentPhaseDescriptions as a1, AgentPaymentPhaseSchema as a2, AgentPaymentRail as a3, AgentPaymentRailDescriptions as a4, AgentPaymentRailSchema as a5, type AgentPaymentSummary as a6, AgentPaymentWarningCode as a7, type AgentPurchaseSummary as a8, type CatalogSubmissionAccepted as a9, type PaymentFee as aA, type PaymentNextAction as aB, type PaymentPhase as aC, type PaymentStatus as aD, SIGNER_UPDATE_FALLBACK as aE, SignerRefusalCode as aF, type SweepConfirmation as aG, type SweepEntry as aH, X402AlreadySettledError as aI, X402Erc7710AlreadySettledError as aJ, type X402ExpectedAuth as aK, type X402ExpectedContext as aL, type X402PaymentOption as aM, type X402RequestSnapshot as aN, X402TaskBudgetMismatchError as aO, X402UnexpectedStatusError as aP, assertPublicHttpsMerchantUrl as aQ, isPublicHttpsMerchantUrl as aR, publicHttpsMerchantUrlRefusal as aS, readBodyCapped as aT, signerUpdateFallback as aU, strictMerchantEgressPolicy as aV, type RawPaymentParties as aW, DEFAULT_CONFIRMATION_TIMEOUT_MS as aa, HOSTED_DISCOVERY_TIMEOUT_MS as ab, HOSTED_EGRESS_TIMEOUTS as ac, HOSTED_MAX_GET_REDIRECTS as ad, HOSTED_RESPONSE_BYTE_CAPS as ae, type HavenAgentAllowanceSummary as af, type HavenAgentReadiness as ag, type HavenAgentSupersession as ah, type HavenAllowance as ai, HavenApiError as aj, type HavenCatalogMerchant as ak, type HavenListScope as al, HavenPaymentStateError as am, HavenSigningError as an, HavenTimeoutError as ao, HavenUnsupportedSignerVersionError as ap, HavenZeroSettlementHashError as aq, MERCHANT_EGRESS_REFUSED_CODE as ar, MERCHANT_EGRESS_RESPONSE_CAP_CODE as as, type MachinePaymentRail as at, type MerchantEgressRefusalReason as au, MerchantEgressRefusedError as av, MerchantEgressResponseCapError as aw, type MerchantEgressTimeouts as ax, type MerchantEgressUse as ay, MerchantTimeoutError as az, type PaymentIntent as b, type X402AuthorizationOptions as c, type X402Intent as d, type PaymentStatusResult as e, type HavenAgent as f, type HavenAgentSummary as g, type HavenAllowanceSummary as h, type HavenBalanceCoverage as i, type PostPurchaseAllowanceSummary as j, type HavenCatalogEntry as k, type HavenCatalogSubmission as l, type HavenPaymentReceipt as m, type HavenPaymentReceiptsPage as n, type HavenTaskBudget as o, type SubmitTaskBudgetResult as p, type SubmitSubBudgetResult as q, type HavenPendingSubBudgetSignature as r, type CloseSubBudgetResult as s, type PaymentResumeState as t, type X402Receipt as u, type X402Quote as v, type X402Erc7710Settlement as w, type X402McpCallContext as x, type SignData as y, type ResumeX402PaymentInput as z };
2544
+ export { AgentPaymentNextActionSchema as $, type AgentPaymentWarning as A, type BudgetPrecheckResult as B, type CloseTaskBudgetResult as C, type X402ResumeState as D, type X402McpTransport as E, type X402MerchantCallContext as F, type X402IntentByKey as G, type HavenClientConfig as H, HavenError as I, AGENT_PAYMENT_FAILURE_CODE_VALUES as J, AGENT_PAYMENT_NEXT_ACTION_VALUES as K, AGENT_PAYMENT_PHASE_VALUES as L, type MerchantEgressPolicy as M, AGENT_PAYMENT_RAIL_VALUES as N, type OpenTaskBudgetResult as O, type PaymentRequest as P, type AgentNextStep as Q, type ResumeAuthorizedX402Input as R, type SweepResult as S, type TaskBudgetSignContext as T, type AgentPaymentEnumSchema as U, AgentPaymentFailureCode as V, AgentPaymentFailureCodeDescriptions as W, type X402PaymentRequired as X, AgentPaymentFailureCodeSchema as Y, AgentPaymentNextAction as Z, AgentPaymentNextActionDescriptions as _, type PaymentResult as a, AgentPaymentPhase as a0, AgentPaymentPhaseDescriptions as a1, AgentPaymentPhaseSchema as a2, AgentPaymentRail as a3, AgentPaymentRailDescriptions as a4, AgentPaymentRailSchema as a5, type AgentPaymentSummary as a6, AgentPaymentWarningCode as a7, type AgentPurchaseSummary as a8, type CatalogSubmissionAccepted as a9, type MerchantEgressTimeouts as aA, type MerchantEgressUse as aB, MerchantTimeoutError as aC, type PaymentFee as aD, type PaymentNextAction as aE, type PaymentPhase as aF, type PaymentStatus as aG, SIGNER_UPDATE_FALLBACK as aH, SignerRefusalCode as aI, type SweepConfirmation as aJ, type SweepEntry as aK, X402AlreadySettledError as aL, X402Erc7710AlreadySettledError as aM, type X402ExpectedAuth as aN, type X402ExpectedContext as aO, type X402PaymentOption as aP, type X402RequestSnapshot as aQ, X402TaskBudgetMismatchError as aR, X402UnexpectedStatusError as aS, assertPublicHttpsMerchantUrl as aT, isPublicHttpsMerchantUrl as aU, publicHttpsMerchantUrlRefusal as aV, readBodyCapped as aW, signerUpdateFallback as aX, strictMerchantEgressPolicy as aY, type RawPaymentParties as aZ, DEFAULT_CONFIRMATION_TIMEOUT_MS as aa, FundingConfirmationUnknownError as ab, FundingRevertedError as ac, HOSTED_DISCOVERY_TIMEOUT_MS as ad, HOSTED_EGRESS_TIMEOUTS as ae, HOSTED_MAX_GET_REDIRECTS as af, HOSTED_RESPONSE_BYTE_CAPS as ag, type HavenAgentAllowanceSummary as ah, type HavenAgentReadiness as ai, type HavenAgentSupersession as aj, type HavenAllowance as ak, HavenApiError as al, type HavenApiFailureCause as am, type HavenCatalogMerchant as an, type HavenListScope as ao, HavenPaymentStateError as ap, HavenSigningError as aq, HavenTimeoutError as ar, HavenUnsupportedSignerVersionError as as, HavenZeroSettlementHashError as at, MERCHANT_EGRESS_REFUSED_CODE as au, MERCHANT_EGRESS_RESPONSE_CAP_CODE as av, type MachinePaymentRail as aw, type MerchantEgressRefusalReason as ax, MerchantEgressRefusedError as ay, MerchantEgressResponseCapError as az, type PaymentIntent as b, type X402AuthorizationOptions as c, type X402Intent as d, type PaymentStatusResult as e, type HavenAgent as f, type HavenAgentSummary as g, type HavenAllowanceSummary as h, type HavenBalanceCoverage as i, type PostPurchaseAllowanceSummary as j, type HavenCatalogEntry as k, type HavenCatalogSubmission as l, type HavenPaymentReceipt as m, type HavenPaymentReceiptsPage as n, type HavenTaskBudget as o, type SubmitTaskBudgetResult as p, type SubmitSubBudgetResult as q, type HavenPendingSubBudgetSignature as r, type CloseSubBudgetResult as s, type PaymentResumeState as t, type X402Receipt as u, type X402Quote as v, type X402Erc7710Settlement as w, type X402McpCallContext as x, type SignData as y, type ResumeX402PaymentInput as z };