@haven_ai/signer 0.4.0-alpha.0 → 0.5.0-alpha.1
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 +196 -35
- package/dist/cli.cjs +1350 -1101
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +1456 -1207
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +751 -520
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +208 -128
- package/dist/index.d.ts +208 -128
- package/dist/index.js +674 -451
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/settlement-child.ts","../src/core.ts","../src/capabilities.ts","../src/credentials.ts","../src/audit.ts","../src/next-step.ts","../src/sign-context.ts","../src/tools.ts","../src/consent.ts","../src/server.ts"],"names":["HavenSigningError","addressFromKey","signHash","verifySignature","privateKeyToAccount","randomUUID","hashTypedData","selectStandardPaymentOption","HavenApiError","toStandardPaymentRequirements","exact","decodeBase64Json","encodeBase64Json","x402V2PaymentEnvelope","buildSweepTypedData","recoverTypedDataAddress","buildSweepAuthorizationMessage","hashMessage","x402AuthorizationAmount","SignerRefusalCode","connectorRerunCommand","SIGNER_UPDATE_FALLBACK","HavenUnsupportedSignerVersionError","buildX402ExpectedMessage","HavenError","AgentPaymentFailureCode","readFile","stat","resolve","homedir","path","mkdir","dirname","appendFile","createHash","z","createNextStepBuilder","AgentPaymentNextAction","join","signature","writeFile","McpServer","isSupportedNodeVersion","unsupportedNodeVersionMessage","StdioServerTransport"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Independent verification of an erc7710 x402 settlement child (#1455).\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 * (`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 '@haven_ai/sdk'\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/** True when this typed data is a delegation — the shape that must never be signed unbound. */\nexport function isSettlementChildTypedData(value: unknown): value is SettlementChildTypedData {\n const td = value as SettlementChildTypedData | undefined\n return (\n !!td &&\n td.primaryType === 'Delegation' &&\n typeof td.domain?.verifyingContract === 'string' &&\n Array.isArray((td.message as { caveats?: unknown })?.caveats)\n )\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 the Haven-signed expected context 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\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 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 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","import { randomUUID } from 'node:crypto'\nimport { hashMessage, hashTypedData, recoverTypedDataAddress } from 'viem'\nimport { privateKeyToAccount } from 'viem/accounts'\nimport { exact } from 'x402/schemes'\nimport {\n chainIdForNetwork,\n isSettlementChildTypedData,\n verifySettlementChild,\n} from './settlement-child.js'\nimport {\n addressFromKey,\n buildX402ExpectedMessage,\n buildSweepAuthorizationMessage,\n buildSweepTypedData,\n signHash,\n verifySignature,\n selectStandardPaymentOption,\n toStandardPaymentRequirements,\n x402AuthorizationAmount,\n x402V2PaymentEnvelope,\n decodeBase64Json,\n encodeBase64Json,\n AgentPaymentFailureCode,\n HavenError,\n HavenSigningError,\n HavenApiError,\n HavenUnsupportedSignerVersionError,\n SignerRefusalCode,\n SIGNER_UPDATE_FALLBACK,\n connectorRerunCommand,\n type SweepAuthorization,\n type SweepExpectedAuth,\n type X402ExpectedAuth,\n type X402PaymentRequired,\n type X402PaymentOption,\n} from '@haven_ai/sdk'\n\n/**\n * The edge signer core.\n *\n * Holds the delegate key in this process and exposes the two signing\n * operations a hosted-MCP flow needs. It performs no network I/O and never\n * returns the key — only signatures and the standard x402 header. See\n * docs/architecture/07-edge-signer.md.\n */\nexport interface EdgeSigner {\n /** Address derived from the delegate key. */\n readonly delegateAddress: string\n /** Sign an AllowanceModule funding/transfer hash (raw ECDSA, 65 bytes). */\n signPaymentHash(hash: string): string\n /**\n * Sign a DIRECT delegation-rail payment's EIP-712 typed data (#1254) — the\n * non-x402 counterpart of `signX402FundingTypedData`. The Hybrid account\n * validates the typed data, not the bare ERC-4337 hash; raw-signing the\n * hash produced AA24 on-chain (found live, #908 mainnet canary). Signed\n * VERBATIM (#829): the exact structure the hosted result carried — and,\n * unlike a blind hash, a structure whose recipient/amount/account are\n * visible to this process's audit log.\n */\n signDelegationTypedData(typedData: Record<string, unknown>): Promise<string>\n /** Sign an x402 funding hash and remember the funded merchant-header context. */\n signX402FundingHash(hash: string, expected: X402ExpectedPayment): X402FundingSignatureResult\n /**\n * Sign a delegation-rail x402 funding intent's EIP-712 typed data (#1138) and\n * remember the funded merchant-header context, exactly as the hash path does.\n *\n * The account validates this typed data, NOT the bare ERC-4337 hash, so the\n * expected context must be v2 and commit to its digest — see\n * `assertExpectedBinding`.\n */\n signX402FundingTypedData(\n typedData: X402FundingTypedData,\n expected: X402ExpectedPayment,\n ): Promise<X402FundingSignatureResult>\n /** Build + sign the EIP-3009 X-PAYMENT header for the merchant leg of x402. */\n buildX402PaymentHeader(\n paymentRequired: X402PaymentRequired,\n x402Binding: string,\n ): Promise<X402HeaderResult>\n /**\n * Sign a Haven-prepared EIP-3009 sweep authorization (gasless USDC recovery\n * delegate → Safe). Verifies the authorization came from Haven and pays out to\n * the delegate's own Safe before signing; the relayer broadcasts it and pays\n * gas. Never broadcasts — pure signing.\n */\n signSweepAuthorization(input: SweepSignatureInput): Promise<SweepSignatureResult>\n}\n\nexport interface SweepSignatureInput {\n /** The authorization fields prepared by the backend. */\n authorization: SweepAuthorization\n /** Haven's signature over the authorization context (binding). */\n expectedAuth: SweepExpectedAuth\n /** Optional Safe address from the local credential, cross-checked against `to`. */\n expectedSafe?: string\n}\n\nexport interface SweepSignatureResult {\n /** EIP-712 signature over the TransferWithAuthorization, by the delegate key. */\n signature: string\n}\n\n/** EIP-712 payload the delegation-rail account validates (#1138). */\nexport interface X402FundingTypedData {\n domain: Record<string, unknown>\n types: Record<string, unknown>\n primaryType: string\n message: Record<string, unknown>\n}\n\nexport interface X402ExpectedPayment {\n /** Haven payment id for the funding transfer. */\n paymentId: string\n /** Funding hash this expected context authenticates. */\n payloadHash: string\n /**\n * EIP-712 digest of the typed data the account validates (#1138). Present ⇒\n * the binding is v2 and the delegation-rail typed-data path is the ONLY\n * signing path allowed for this intent.\n */\n typedDataHash?: string\n /**\n * Resource URL of the x402 payment Haven prepared. On the hosted surface\n * that is `haven_pay_x402_quote` — `buildX402SigningContext` in\n * `mcp-server/src/tools/support/mcp-context.ts` (called from the\n * `haven_pay_x402_quote` handler, which is still in `tools.ts`) relays\n * `intent.resourceUrl` here, and\n * `haven_resume_x402_payment` re-emits the same context. Checked against\n * the merchant header's resource in `assertX402MatchesExpected`.\n */\n resourceUrl: string\n /**\n * Merchant recipient of that same prepared payment (`intent.merchantTo`,\n * same source). Checked against the header's `payTo` in\n * `assertX402MatchesExpected` and, for an erc7710 settlement child,\n * against the child's payee caveat in `verifySettlementChild`.\n */\n merchantTo: string\n /** Atomic amount funded for the merchant header. */\n amount: string\n /** Token contract funded for the merchant header. */\n asset: string\n /** x402 network funded for the merchant header. */\n network: string\n /** ISO expiry for the funding/quote window. When present, the signer refuses stale merchant headers. */\n expiresAt?: 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 it is not\n * its own delegate. Inside the Haven-signed message, so it cannot be\n * stripped or forged without breaking the binding signature.\n */\n payerDelegate?: string\n /** The paying agent's id — carried for the refusal's diagnosis (#1690). */\n payerAgentId?: string\n /** Haven signature over the expected funding context. */\n auth: X402ExpectedAuth\n}\n\nexport interface X402HeaderResult {\n /** The merchant-verifiable X-PAYMENT header value. */\n paymentHeader: string\n /** The x402 option this header pays. */\n accepted: X402PaymentOption\n}\n\nexport interface X402FundingSignatureResult {\n /** Raw ECDSA signature over the Haven funding hash. */\n signature: string\n /** Opaque process-local binding for the later merchant header signing step. */\n x402Binding: string\n}\n\nexport interface EdgeSignerOptions {\n /** Address allowed to authenticate x402 expected-context messages from Haven. */\n x402BindingSigner?: string\n /**\n * This signer's OWN agent id, from the local credential (#1690). Used only\n * to make the payer-mismatch refusal name both sides; the guard itself\n * compares delegate addresses and works without it.\n */\n agentId?: string\n}\n\nexport function createEdgeSigner(\n delegateKey: string,\n options: EdgeSignerOptions = {},\n): EdgeSigner {\n let delegateAddress: string\n try {\n delegateAddress = addressFromKey(delegateKey)\n } catch (err) {\n throw new HavenSigningError(\n `Invalid delegate key: ${err instanceof Error ? err.message : String(err)}`,\n )\n }\n const x402Bindings = new Map<string, X402ExpectedPayment>()\n /**\n * #2291: why a binding this process once held is gone. A binding is\n * single-use by design and `buildX402PaymentHeader` deletes it on every exit\n * path, so a re-use and a typo previously produced the SAME refusal — and\n * they need opposite remedies: a spent binding means the header was already\n * built (use it, or re-quote), while an unknown one means the signer never\n * held it (sign first, or the signer restarted).\n *\n * The reason is recorded, not just the fact, because the exit paths are not\n * equivalent: a binding retired by the WINDOW check produced no header at\n * all, so telling that caller to \"retry with the header you already have\"\n * would be a confident lie (review finding). Three outcomes, three remedies.\n *\n * Ids only. The payment context is still deleted with the map entry, so this\n * changes nothing about what the signer retains — a retired id is an opaque\n * UUID, not payment data. Bounded so a long-lived signer cannot grow it\n * without limit; the oldest ids fall off, which degrades a stale re-use back\n * to the unknown-binding message rather than to a wrong one.\n */\n type RetiredBindingReason = 'header_built' | 'window_expired'\n const retiredX402Bindings = new Map<string, RetiredBindingReason>()\n const RETIRED_BINDING_MEMORY = 64\n function retireX402Binding(id: string, reason: RetiredBindingReason): void {\n retiredX402Bindings.set(id, reason)\n if (retiredX402Bindings.size > RETIRED_BINDING_MEMORY) {\n const oldest = retiredX402Bindings.keys().next()\n if (!oldest.done) retiredX402Bindings.delete(oldest.value)\n }\n }\n\n function signAndVerify(hash: string): string {\n const signature = signHash(delegateKey, hash)\n // Verify locally before handing the signature back, mirroring the SDK.\n if (!verifySignature(hash, signature, delegateAddress)) {\n throw new HavenSigningError(\n 'Local signature verification failed — recovered address does not match the delegate key.',\n )\n }\n return signature\n }\n\n return {\n delegateAddress,\n\n signPaymentHash(hash: string): string {\n return signAndVerify(hash)\n },\n\n async signDelegationTypedData(typedData: Record<string, unknown>): Promise<string> {\n const account = privateKeyToAccount(delegateKey as `0x${string}`)\n // Signed VERBATIM (#829/#1254): the exact structure Haven sent, never\n // one reconstructed from components — a re-derived payload is a\n // different payload, and the account validates the original.\n return account.signTypedData(typedData as Parameters<typeof account.signTypedData>[0])\n },\n\n signX402FundingHash(hash: string, expected: X402ExpectedPayment): X402FundingSignatureResult {\n assertExpectedBinding(hash, expected, options.x402BindingSigner, 'hash')\n assertPayerMatchesDelegate(expected, delegateAddress, options.agentId)\n const signature = signAndVerify(hash)\n const x402Binding = randomUUID()\n x402Bindings.set(x402Binding, { ...expected })\n return { signature, x402Binding }\n },\n\n async signX402FundingTypedData(\n typedData: X402FundingTypedData,\n expected: X402ExpectedPayment,\n ): Promise<X402FundingSignatureResult> {\n assertExpectedBinding(expected.payloadHash, expected, options.x402BindingSigner, 'typed-data')\n assertPayerMatchesDelegate(expected, delegateAddress, options.agentId)\n // Recompute the digest from the typed data actually in hand and require it\n // to equal Haven's commitment. Everything upstream is untrusted input; this\n // equality is what makes the binding cover the bytes being signed rather\n // than a hash that merely travels alongside them.\n const digest = hashTypedData(typedData as Parameters<typeof hashTypedData>[0])\n if (digest.toLowerCase() !== expected.typedDataHash?.toLowerCase()) {\n throw new HavenSigningError(\n 'x402 typed data does not match the digest Haven committed to in the expected context. ' +\n 'Refusing to sign — the payload was altered in transit or Haven declared a different one. ' +\n 'The most common cause is the typed data being truncated or reshaped while being copied ' +\n 'between tool calls (#1255): re-run the hosted quote and pass its typed_data_b64 string ' +\n 'through UNCHANGED instead of re-emitting the nested JSON.',\n )\n }\n // #1455: the digest check above proves Haven DECLARED these bytes. It\n // says nothing about what they mean. When the payload is a delegation —\n // the erc7710 settlement child, whose signature lets a merchant pull from\n // the treasury — re-derive the meaning from the caveats and refuse if it\n // disagrees with the declaration. A backend could otherwise declare one\n // payee and pin another, and the pair would bind perfectly.\n if (isSettlementChildTypedData(typedData)) {\n // A network this signer cannot map is its OWN failure, not a chain\n // mismatch. Folding it into the comparison (as `?? -1` did) refused\n // correctly but reported \"expected chain -1\", sending a reader after a\n // phantom mismatch instead of the mapping gap (#1455 second review).\n const settlementChainId = chainIdForNetwork(expected.network)\n if (settlementChainId === undefined) {\n throw new HavenSigningError(\n `Refusing to sign the x402 settlement child: this signer cannot map the network ` +\n `'${expected.network}' to a chain id, so it cannot check which chain the child is ` +\n 'scoped to. Update @haven_ai/signer.',\n )\n }\n verifySettlementChild(typedData, {\n merchantTo: expected.merchantTo,\n amount: expected.amount,\n asset: expected.asset,\n // From the SIGNED network, not the payload's own claim. Passing\n // Number(typedData.domain.chainId) here made the check compare a\n // value to itself — vacuous, and precisely the \"declared one thing,\n // signed another\" class this file exists to catch (#1455 review).\n chainId: settlementChainId,\n expiresAt: expected.expiresAt,\n })\n }\n const account = privateKeyToAccount(delegateKey as `0x${string}`)\n // Signed VERBATIM (#829): the exact structure Haven sent, never one\n // reconstructed from components — a re-derived payload is a different\n // payload, and the account validates the original.\n const signature = await account.signTypedData(\n typedData as Parameters<typeof account.signTypedData>[0],\n )\n const x402Binding = randomUUID()\n x402Bindings.set(x402Binding, { ...expected })\n return { signature, x402Binding }\n },\n\n async buildX402PaymentHeader(\n paymentRequired: X402PaymentRequired,\n x402Binding: string,\n ): Promise<X402HeaderResult> {\n const expected = x402Bindings.get(x402Binding)\n if (!expected) {\n // #2291: two different situations, two different remedies. Conflating\n // them sent a reporter hunting a binding-lookup bug that did not\n // exist — the caller HAD signed, seconds earlier, with a one-shot that\n // spends its own binding building the header inline.\n const retired = retiredX402Bindings.get(x402Binding)\n if (retired === 'header_built') {\n throw new HavenSigningError(\n 'This x402 binding was already used to build a merchant header. Bindings are ' +\n 'single-use. If you called haven_sign_x402, it already returned the ' +\n 'payment_header — retry the merchant with THAT header instead of building ' +\n 'another; haven_x402_sign_header is the follow-up to haven_sign, not to ' +\n 'haven_sign_x402. If you no longer have the header, re-run the quote tool with ' +\n 'the same idempotency_key.',\n )\n }\n if (retired === 'window_expired') {\n throw new HavenSigningError(\n 'This x402 binding was retired because its payment window closed before a merchant ' +\n 'header could be built — no header exists to retry with. Re-run the quote tool ' +\n 'with the same idempotency_key to get a fresh window, then sign again.',\n )\n }\n throw new HavenSigningError(\n 'x402 funding binding is required before signing a merchant header. Sign the ' +\n 'hosted funding hash with x402_expected first (haven_sign returns a binding this ' +\n 'tool can use). A binding is also lost when the signer process restarts, since ' +\n 'bindings live in memory only — re-sign to mint a fresh one.',\n )\n }\n try {\n assertX402PaymentWindowOpen(expected)\n } catch (err) {\n x402Bindings.delete(x402Binding)\n // No header was built on this path — the window closed first.\n retireX402Binding(x402Binding, 'window_expired')\n throw err\n }\n const option = selectStandardPaymentOption(paymentRequired.accepts)\n if (!option) {\n throw new HavenApiError(\n 'No compatible payment option found in x402 requirements. ' +\n 'Haven supports standard x402 exact payments on Base USDC.',\n 400,\n )\n }\n assertX402MatchesExpected(paymentRequired, option, expected)\n\n const account = privateKeyToAccount(delegateKey as `0x${string}`)\n const requirements = toStandardPaymentRequirements(paymentRequired, option)\n const header = await exact.evm.createPaymentHeader(\n account,\n paymentRequired.x402Version,\n requirements,\n )\n\n if (paymentRequired.x402Version < 2) {\n x402Bindings.delete(x402Binding)\n retireX402Binding(x402Binding, 'header_built')\n return { paymentHeader: header, accepted: option }\n }\n\n // Always delete the binding — even if encode/decode throws — to prevent the\n // in-process Map from accumulating stale X402ExpectedPayment entries (memory\n // leak + data-retention violation for user payment context).\n try {\n const payment = decodeBase64Json<{ payload: unknown }>(header)\n // #2361: the shared v2 envelope echoes the challenge's `resource` and\n // `extensions` verbatim when present — the extensions echo is a spec\n // MUST, and its absence was live-bisected as the CoinGecko rejection\n // cause (#2360). `paymentRequired` here is the caller's raw 402 JSON\n // (the tools layer passes it through unnormalized), so the echo is\n // byte-faithful to what the merchant advertised.\n const wrapped = encodeBase64Json(\n x402V2PaymentEnvelope(paymentRequired, option, payment.payload),\n )\n return { paymentHeader: wrapped, accepted: option }\n } finally {\n x402Bindings.delete(x402Binding)\n retireX402Binding(x402Binding, 'header_built')\n }\n },\n\n async signSweepAuthorization({\n authorization,\n expectedAuth,\n expectedSafe,\n }: SweepSignatureInput): Promise<SweepSignatureResult> {\n // 1. The authorization must have come from Haven (binding), so a malicious\n // hosted server can't get the delegate to sign a transfer to an attacker.\n assertSweepBinding(authorization, expectedAuth, options.x402BindingSigner)\n\n // 2. Funds can only leave the delegate's OWN key — that half is\n // unconditional. The DESTINATION half is not, and the difference\n // matters here more than anywhere else in this file (#2247):\n // `expectedSafe` is threaded from the local credential's account\n // address, so it is absent whenever no such address reaches this\n // process. Three ways that happens, all supported: `HAVEN_DELEGATE_KEY`\n // set without `HAVEN_ACCOUNT_ADDRESS` (the README quickstart — the\n // credential IS loaded here, it just carries no account address); a\n // credential file whose `account_address` (or the permanent\n // `safe_address` fallback) is null; or an embedder calling\n // `resolveEdgeSigner({ delegateKey })`, whose fast path returns before\n // credentials are read at all. With no local value there is nothing to\n // re-derive `to` against, so the destination rests entirely on Haven's\n // binding signature (step 1) plus the canonical-USDC token/chain\n // assertion (step 3): AUTHENTICATED, but not independently verified by\n // this signer. Supply the account address to get the local check.\n if (!sameAddress(authorization.from, delegateAddress)) {\n throw new HavenSigningError(\n 'Sweep authorization `from` does not match this delegate address.',\n )\n }\n if (expectedSafe && !sameAddress(authorization.to, expectedSafe)) {\n throw new HavenSigningError(\n 'Sweep authorization `to` does not match the Safe in the local credential.',\n )\n }\n\n // 3. Build the EIP-712 typed data (asserts token/chain are canonical USDC),\n // sign it locally, and verify the recovered signer is the delegate.\n const typedData = buildSweepTypedData(authorization)\n // The SDK keeps addresses framework-neutral (`string`); viem wants its\n // `0x`-branded template type. Narrow at the call boundary only.\n const viemTypedData = {\n domain: {\n ...typedData.domain,\n verifyingContract: typedData.domain.verifyingContract as `0x${string}`,\n },\n types: typedData.types,\n primaryType: typedData.primaryType,\n message: {\n ...typedData.message,\n from: typedData.message.from as `0x${string}`,\n to: typedData.message.to as `0x${string}`,\n nonce: typedData.message.nonce as `0x${string}`,\n },\n } as const\n const account = privateKeyToAccount(delegateKey as `0x${string}`)\n const signature = await account.signTypedData(viemTypedData)\n const recovered = await recoverTypedDataAddress({ ...viemTypedData, signature })\n if (!sameAddress(recovered, delegateAddress)) {\n throw new HavenSigningError(\n 'Local sweep signature verification failed — recovered address does not match the delegate key.',\n )\n }\n return { signature }\n },\n }\n}\n\n/**\n * Verify Haven signed the sweep authorization context. Mirrors\n * `assertExpectedBinding` for x402: re-derive the canonical message from the\n * authorization fields, require it match the binding, require the binding signer\n * be the trusted Haven address, and verify the signature. Reuses the x402\n * binding signer — the message namespace differs so the two can't cross-replay.\n */\nfunction assertSweepBinding(\n authorization: SweepAuthorization,\n expectedAuth: SweepExpectedAuth,\n trustedSigner: string | undefined,\n): void {\n if (!expectedAuth || typeof expectedAuth !== 'object') {\n throw new HavenSigningError('Sweep authorization binding is required before signing.')\n }\n if (!trustedSigner) {\n throw new HavenSigningError(\n 'Sweep binding verifier is not configured. Set HAVEN_X402_BINDING_SIGNER before signing sweep authorizations.',\n )\n }\n // Before any content comparison: an unrecognised version means we cannot\n // reason about this binding at all, so a mismatch below would be a symptom\n // reported as a cause (#1143).\n assertSupportedBindingVersion(\n expectedAuth.version,\n SUPPORTED_SWEEP_BINDING_VERSIONS,\n 'sweep authorization binding',\n )\n const message = buildSweepAuthorizationMessage(authorization)\n if (expectedAuth.message !== message) {\n throw new HavenSigningError('Sweep authorization binding does not match the authorization being signed.')\n }\n if (!sameAddress(expectedAuth.signer, trustedSigner)) {\n throw new HavenSigningError('Sweep authorization binding was not signed by the configured Haven signer.')\n }\n if (!verifySignature(hashMessage(message), expectedAuth.signature, trustedSigner)) {\n throw new HavenSigningError('Sweep authorization binding signature could not be verified.')\n }\n}\n\nexport function assertX402MatchesExpected(\n paymentRequired: X402PaymentRequired,\n option: X402PaymentOption,\n expected: X402ExpectedPayment,\n): void {\n assertExpectedShape(expected)\n const headerResource = option.resource ?? paymentRequired.resource.url\n if (headerResource !== expected.resourceUrl) {\n throw new HavenSigningError('x402 payment_required resource does not match the funded intent.')\n }\n if (!sameAddress(option.payTo, expected.merchantTo)) {\n throw new HavenSigningError('x402 merchant recipient does not match the funded intent.')\n }\n if (x402AuthorizationAmount(option) !== expected.amount) {\n throw new HavenSigningError('x402 amount does not match the funded intent.')\n }\n if (!sameAddress(option.asset, expected.asset)) {\n throw new HavenSigningError('x402 asset does not match the funded intent.')\n }\n if (option.network !== expected.network) {\n throw new HavenSigningError('x402 network does not match the funded intent.')\n }\n}\n\nfunction assertExpectedShape(expected: X402ExpectedPayment): void {\n if (!expected || typeof expected !== 'object') {\n throw new HavenSigningError('x402 expected funding context is required before signing a merchant header.')\n }\n}\n\n/**\n * Expected-context binding versions THIS signer understands (#1143).\n *\n * The backend deploys continuously from `dev`; a signer reaches users only on a\n * merge to `main` (the publish workflow). So a signer that is one release behind\n * a context bump is a structural state, not an accident, and it needs to report\n * itself as one. These sets are the signer's authority on what it will sign —\n * the tool schemas deliberately accept any positive integer so an unknown\n * version arrives *here* instead of dying at the schema boundary with a raw\n * validation string.\n *\n * **Adding a version here is not sufficient to support it.** The mode rules in\n * `assertExpectedBinding` derive the expected version from the context's\n * *contents* (`typedDataHash` present ⇒ 2), not from `auth.version`, so a v3\n * that carries anything new needs that derivation extended in the same change.\n * Widening this array alone would admit a v3 context to the v1/v2 rule set:\n * the array announces what this signer can evaluate, it does not define it.\n */\nexport const SUPPORTED_X402_EXPECTED_VERSIONS: readonly number[] = [1, 2, 3]\nexport const SUPPORTED_SWEEP_BINDING_VERSIONS: readonly number[] = [1]\n\n/**\n * Fail closed on a binding version this signer does not understand, with an\n * error that names the received version, the ceiling this signer supports, and\n * the fix — both as PROSE (`message`, unchanged since #1143) and, since #1309,\n * as MACHINE-READABLE fields on the thrown error itself\n * (`HavenUnsupportedSignerVersionError`): `code`, `supportedVersions`,\n * `receivedVersion`, `fallback`. The tool boundary (`normalizeError` in\n * `tools.ts`) relays those fields verbatim instead of leaving an agent to\n * regex-parse this prose, which is the diagnosability gap\n * `docs/operations/mcp-runtime-compatibility.md` documents.\n *\n * `supportedVersions`/`receivedVersion` are DERIVED from this call's own\n * arguments — never a second literal — so they cannot drift from\n * `SUPPORTED_X402_EXPECTED_VERSIONS` / `SUPPORTED_SWEEP_BINDING_VERSIONS`,\n * which is what the signing path always passes in.\n *\n * The version travels inside the Haven-signed binding message, so the message\n * also tells the caller not to \"fix\" it by rewriting the field — an agent that\n * does would invalidate the signature and misrepresent what Haven declared.\n * That instruction is NOT weakened by structuring the refusal: this function\n * still throws before any content check runs, and nothing is ever signed.\n *\n * #2347: that word was \"authorised\" until this change, and the reading was\n * always the correct one — Haven does sign this message. It is now \"declared\",\n * the word `settlement-child.ts` already uses for this exact binding (\"proves\n * Haven *declared* a payload … it says nothing about what the payload MEANS\"),\n * because on an agent-facing refusal inside a payment flow the broader word\n * invites the #2334 misreading that Haven is what authorises the spend. It is\n * not; the owner-signed delegation and its on-chain caveat are. The property\n * claimed is unchanged — only the verb naming it. Full argument in\n * `docs/regulatory/casp-changelog/2026-09-01-2347.md`.\n *\n * Exported so a test can pin the historical case (a v2 context against a signer\n * whose set was `{1}`) that this signer can no longer produce on its own. The\n * signing path always passes the module constants above.\n */\nexport function assertSupportedBindingVersion(\n received: number,\n supported: readonly number[],\n context: 'x402 expected context' | 'sweep authorization binding',\n): void {\n if (supported.includes(received)) return\n const highest = Math.max(...supported)\n // The else-branch (\"updating will not restore it\") assumes versions retire\n // MONOTONICALLY from the oldest end — true for how SUPPORTED_* is maintained\n // (append new, drop old). If a future change ever makes the supported set\n // non-contiguous, a gap version would hit that branch and the wording needs\n // revisiting (#1322 review).\n const outOfDate = received > highest\n const code =\n context === 'x402 expected context'\n ? SignerRefusalCode.UnsupportedExpectedContextVersion\n : SignerRefusalCode.UnsupportedSweepBindingVersion\n const ceiling = outOfDate\n ? `This signer is out of date: it supports ${context} versions up to ${highest}, ` +\n `and Haven sent version ${received}. Update @haven_ai/signer — rerun the Haven ` +\n `connector (\\`${connectorRerunCommand()}\\`), which reinstalls the pinned MCP runtime.`\n : `Unsupported ${context} version ${received}: this signer supports ` +\n `${supported.join(', ')}.`\n // Below-floor is the opposite skew (this signer is NEWER than what sent the\n // context, e.g. a retired version) — updating cannot fix it, so the shared\n // \"update the signer\" fallback would be actively wrong here. Only the\n // out-of-date branch, which is the case seen in the field (#1143), uses the\n // canonical single-source fallback shared with the hosted quote's advisory\n // signer_compatibility.fallback (#1155, #1309).\n const fallback = outOfDate\n ? SIGNER_UPDATE_FALLBACK\n : `This ${context} version (${received}) is older than what this signer enforces ` +\n `(${supported.join(', ')}) — updating @haven_ai/signer will not restore it. Nothing ` +\n 'was signed or spent; stop and tell the user rather than retrying.'\n throw new HavenUnsupportedSignerVersionError(\n `${ceiling} Nothing was signed. Do not rewrite the version field to a supported ` +\n 'value: it is part of the Haven-signed binding message, so changing it invalidates ' +\n 'the signature and would misrepresent what Haven declared.',\n code,\n supported,\n received,\n fallback,\n )\n}\n\n/**\n * Verify Haven's expected-context binding before signing anything.\n *\n * `mode` is what closes the #1138 downgrade in BOTH directions, and neither\n * half is optional:\n *\n * - `'hash'` (legacy rail, raw ECDSA) refuses a **v2** context. A v2 binding\n * means the account validates typed data; raw-signing its 4337 hash would\n * produce a signature the account rejects on-chain, after the intent is\n * claimed.\n * - `'typed-data'` (delegation rail) refuses a **v1** context. Without the\n * `typedDataHash` commitment, Haven's declaration covers only a hash that is\n * NOT what gets signed — the signer would be endorsing a payload it cannot\n * check, which is the whole property this binding exists to provide.\n *\n * The version is derived from the context inside `buildX402ExpectedMessage`, so\n * a tampered `auth.version` cannot select a different rule than the signed\n * message encodes: the recomputed message simply stops matching.\n */\nfunction assertExpectedBinding(\n payloadHash: string,\n expected: X402ExpectedPayment,\n trustedSigner: string | undefined,\n mode: 'hash' | 'typed-data' = 'hash',\n): void {\n assertExpectedShape(expected)\n if (!trustedSigner) {\n throw new HavenSigningError(\n 'x402 expected-context verifier is not configured. Set HAVEN_X402_BINDING_SIGNER before signing x402 funding hashes.',\n )\n }\n // Skew check first (#1143). Every content check below — the hash comparison,\n // the mode rules, the recomputed message — assumes we understand the context's\n // shape. Under an unknown version they are symptoms, and reporting one as the\n // cause is what sent a live debugging session after the wrong string. A missing\n // `auth` is left to the message check below, which already fails closed on it.\n if (expected.auth) {\n assertSupportedBindingVersion(\n expected.auth.version,\n SUPPORTED_X402_EXPECTED_VERSIONS,\n 'x402 expected context',\n )\n }\n if (expected.payloadHash.toLowerCase() !== payloadHash.toLowerCase()) {\n throw new HavenSigningError('x402 expected context does not match the funding hash being signed.')\n }\n if (mode === 'hash' && expected.typedDataHash) {\n throw new HavenSigningError(\n 'This x402 funding intent commits to EIP-712 typed data, so its bare hash must not be ' +\n 'raw-signed — the account would reject that signature on-chain. Sign sign_data.typed_data instead.',\n )\n }\n if (mode === 'typed-data' && !expected.typedDataHash) {\n throw new HavenSigningError(\n 'Refusing to sign typed data under an expected context that does not commit to it. ' +\n 'Haven must return a v2 x402 expected context (with typedDataHash) for a delegation-rail intent.',\n )\n }\n const message = buildX402ExpectedMessage({\n paymentId: expected.paymentId,\n payloadHash: expected.payloadHash,\n resourceUrl: expected.resourceUrl,\n merchantTo: expected.merchantTo,\n amount: expected.amount,\n asset: expected.asset,\n network: expected.network,\n expiresAt: expected.expiresAt,\n typedDataHash: expected.typedDataHash,\n payerDelegate: expected.payerDelegate,\n payerAgentId: expected.payerAgentId,\n })\n // Contents-derived, mirroring the builder (#1138, #1690): a tampered\n // auth.version cannot select a different rule than the signed message\n // encodes — the recomputed message simply stops matching.\n const expectedVersion = expected.payerDelegate ? 3 : expected.typedDataHash ? 2 : 1\n if (expected.auth?.version !== expectedVersion || expected.auth.message !== message) {\n throw new HavenSigningError('x402 expected context authentication message is invalid.')\n }\n if (!sameAddress(expected.auth.signer, trustedSigner)) {\n throw new HavenSigningError('x402 expected context was not signed by the configured Haven signer.')\n }\n if (!verifySignature(hashMessage(message), expected.auth.signature, trustedSigner)) {\n throw new HavenSigningError('x402 expected context signature could not be verified.')\n }\n}\n\n/**\n * Refuse to sign another agent's quote (#1690), mirroring the sweep guard's\n * `authorization.from` check.\n *\n * Runs only AFTER `assertExpectedBinding` has verified the Haven signature —\n * an unverified payer claim is attacker input, and refusing on it would let a\n * forged context turn the guard into a denial-of-service. And only when the\n * context CARRIES a payer claim: a v1/v2 context claims nothing, so there is\n * nothing to mismatch (the characterization suite pins that).\n *\n * The message is the point. A payer mismatch in the field means a long-lived\n * host cached one agent's wiring while the disk holds another's (#1681), and\n * before this guard the operator discovered that as an on-chain revert three\n * layers later. Naming both identities IS the diagnosis.\n */\nfunction assertPayerMatchesDelegate(\n expected: X402ExpectedPayment,\n delegateAddress: string,\n localAgentId: string | undefined,\n): void {\n if (!expected.payerDelegate) return\n if (sameAddress(expected.payerDelegate, delegateAddress)) return\n const quoteAgent = expected.payerAgentId ?? 'unknown'\n const localAgent = localAgentId ?? 'unknown'\n throw new HavenSigningError(\n `This quote belongs to a DIFFERENT agent: the quote was created for agent ${quoteAgent} ` +\n `(delegate ${expected.payerDelegate}), but this signer holds agent ${localAgent} ` +\n `(delegate ${delegateAddress}). A long-lived host is holding stale credentials — its ` +\n 'session authenticates as the old agent while the signer on disk belongs to the new ' +\n 'one. Nothing was signed. Restart the host so it re-reads its wiring, then re-quote.',\n )\n}\n\nfunction assertX402PaymentWindowOpen(expected: X402ExpectedPayment): void {\n if (!expected.expiresAt) return\n const expiresAtMs = Date.parse(expected.expiresAt)\n if (Number.isNaN(expiresAtMs)) {\n throw new HavenSigningError('x402 expected context expiresAt is not a valid ISO timestamp.')\n }\n if (expiresAtMs <= Date.now()) {\n throw new HavenError(\n 'The x402 payment window expired before the merchant header could be signed. Re-quote with haven_pay_mcp_tool using the same idempotency_key before trying again.',\n AgentPaymentFailureCode.PaymentWindowExpired,\n 410,\n expected.paymentId,\n )\n }\n}\n\nfunction sameAddress(a: string, b: string): boolean {\n return a.toLowerCase() === b.toLowerCase()\n}\n","import { connectorRerunCommand } from '@haven_ai/sdk'\nimport {\n SUPPORTED_SWEEP_BINDING_VERSIONS,\n SUPPORTED_X402_EXPECTED_VERSIONS,\n} from './core.js'\n\n/**\n * Pre-payment skew detection (#1155).\n *\n * #1143 made a stale signer say so — but only at the signing step, after the\n * agent had already quoted and was one call away from funding. This module\n * moves the same information to the `initialize` handshake, so the set of\n * expected-context versions this signer understands is observable *before* a\n * payment is attempted.\n *\n * **The check is necessarily agent-mediated.** The signer and the hosted Haven\n * MCP are two separate servers connected to the same client; neither can\n * introspect the other. The signer's single Haven call (#1263, the read-only\n * `GET /x402/:payment_id/sign-context` in `sign-context.ts`) does not help\n * here: it fetches one payment's signing bytes, not the hosted server's\n * handshake, and it happens at signing time — after the quote this module\n * exists to get ahead of. So only the agent sees both handshakes, and what\n * ships here is the *information* plus the prompt to compare it — never a\n * server-side gate. A mismatch is advisory: the enforcement point remains the\n * #1143 signing-time guard, which is unchanged.\n *\n * Everything below is DERIVED from the two constants in `core.ts` that the\n * signing path actually enforces. A second hand-maintained literal is the one\n * way this feature could become a lie, so there isn't one — including inside\n * the human-readable `instructions` string, which renders the same arrays.\n */\n\n/**\n * Vendor-prefixed key under MCP's `capabilities.experimental`.\n *\n * `experimental` rather than the newer `extensions` field deliberately: both are\n * `Record<string, object>` in `@modelcontextprotocol/sdk@1.29`, but a client on\n * an older SDK parses the `initialize` result with a `ServerCapabilities` schema\n * that has no `extensions` key, and Zod's default object behaviour would strip\n * it. `experimental` has been in the schema since the beginning, so it survives\n * an old client — which is precisely the population this feature exists for.\n */\nexport const SIGNER_CAPABILITY_KEY = 'haven/signer-compatibility'\n\nexport interface SignerCompatibility {\n /** Expected-context versions this signer will verify (`SUPPORTED_X402_EXPECTED_VERSIONS`). */\n x402_expected_context_versions: number[]\n /** Sweep-binding versions this signer will verify (`SUPPORTED_SWEEP_BINDING_VERSIONS`). */\n sweep_binding_versions: number[]\n}\n\n/** The supported sets this signer enforces, as a plain serialisable object. */\nexport function signerCompatibility(): SignerCompatibility {\n return {\n x402_expected_context_versions: [...SUPPORTED_X402_EXPECTED_VERSIONS],\n sweep_binding_versions: [...SUPPORTED_SWEEP_BINDING_VERSIONS],\n }\n}\n\n/**\n * The machine-readable half: `capabilities.experimental['haven/signer-compatibility']`,\n * returned verbatim in the `initialize` result.\n *\n * `ServerCapabilities.experimental` is typed `z.record(z.string(), <any object>)`\n * and the SDK's `mergeCapabilities` deep-merges per top-level key, so declaring\n * this at construction survives the `tools` capability `McpServer` registers\n * when the first tool is added.\n */\nexport function signerCapabilityAdvertisement(): {\n experimental: Record<string, SignerCompatibility>\n} {\n return { experimental: { [SIGNER_CAPABILITY_KEY]: signerCompatibility() } }\n}\n\n/**\n * The agent-readable half: MCP `instructions`, which clients surface to the\n * model. The machine-readable capability above is the precise statement, but\n * most agent runtimes never expose `capabilities.experimental` to the model —\n * this string is what actually reaches the reader who has to make the call.\n *\n * It names the same fix as #1143 so an agent that hits either surface — the\n * handshake here or the signing-time error there — tells the user the same\n * thing.\n */\nexport function signerInstructions(): string {\n const compatibility = signerCompatibility()\n return [\n 'Haven edge signer: sign-only tools bound to the local delegate key. It never emits the',\n 'key. Its one network capability is an authenticated READ of a signing context from',\n 'Haven by payment_id — pass payment_id to haven_sign / haven_sign_x402 (preferred for',\n 'delegation-rail x402) instead of relaying bulky typed-data payloads yourself.',\n '',\n 'Version compatibility (check this BEFORE signing, not after):',\n `- x402 expected-context versions supported: ${compatibility.x402_expected_context_versions.join(', ')}`,\n `- sweep authorization binding versions supported: ${compatibility.sweep_binding_versions.join(', ')}`,\n '',\n 'Haven quote and prepare results report the expected-context version they will emit',\n '(signer_compatibility.x402_expected_context_version). If that version is not in the list',\n 'above, this signer is out of date: STOP before signing, and tell the user to update',\n `@haven_ai/signer by rerunning \\`${connectorRerunCommand()}\\`, which reinstalls the pinned`,\n 'MCP runtime. Do not edit the version field to a supported value — it is part of the',\n 'Haven-signed binding message, so changing it invalidates the signature.',\n '',\n 'A version-mismatch refusal from haven_sign / haven_sign_x402 / haven_sign_sweep_delegate is',\n 'machine-readable, not just prose: it carries code, supported_versions, received_version, and',\n 'fallback fields alongside the message, so you can branch on it directly. Every signer',\n 'refusal also carries the next-step family: next_tool_name + next_tool_server_role when a',\n 'hosted tool follows (resolve the role against your own server names), else',\n 'next_tool_omitted_reason saying why not.',\n ].join('\\n')\n}\n","import { readFile, stat } from 'node:fs/promises'\n\n/**\n * The edge signer's own credential requires *only* `delegate_key` — unlike\n * `@haven_ai/mcp`, no `api_key` belongs in this file.\n *\n * That is a claim about this credential, not about the process, and the\n * difference matters: the sentence that used to stand here (\"it does not call\n * the Haven API\") was retired by #1263. The MCP server layer does make one\n * authenticated call — a read-only `GET /x402/:payment_id/sign-context`, see\n * `sign-context.ts` — and it reads the `api_url` / `api_key` for it from a\n * SEPARATE `identity.json` in the same directory as the credential file\n * resolved here. That is why `sourcePath` below is load-bearing rather than\n * diagnostic, and why a key supplied through `HAVEN_DELEGATE_KEY` alone (no\n * file, so no directory) leaves that path with no identity to load and the\n * process making no network calls at all. The delegate key read here is never\n * part of any request or response either way.\n */\nexport interface SignerCredentials {\n delegateKey: string\n agentId?: string\n /** The Haven account (smart account) the agent spends from. */\n accountAddress?: string\n chainId?: number\n network?: string\n x402BindingSigner?: string\n /** Absolute path the key was loaded from, if a file was used. */\n sourcePath?: string\n}\n\ninterface RawCredentialFile {\n delegate_key?: unknown\n delegateKey?: unknown\n agent_id?: unknown\n agentId?: unknown\n /** What `@haven_ai/connect` writes. */\n account_address?: unknown\n /** Pre-#2908 spelling — read PERMANENTLY (a credential file never rewrites itself), see `readAccountAddressField`. */\n safe_address?: unknown\n /** Pre-#2908 spelling — read PERMANENTLY (a credential file never rewrites itself), see `readAccountAddressField`. */\n safeAddress?: unknown\n chain_id?: unknown\n chainId?: unknown\n network?: unknown\n x402_binding_signer?: unknown\n x402BindingSigner?: unknown\n}\n\n/**\n * Resolve the delegate key for the edge signer.\n *\n * Order — earlier wins:\n * 1. Explicit `path` (e.g. `--credentials <path>`).\n * 2. `HAVEN_CREDENTIALS` env var pointing at a credential JSON file.\n * 3. `HAVEN_DELEGATE_KEY` env var.\n *\n * The same credential JSON the dashboard emits works here — we just read its\n * `delegate_key` and ignore the rest.\n */\nexport async function loadSignerCredentials(\n path: string | undefined = process.env.HAVEN_CREDENTIALS,\n): Promise<SignerCredentials> {\n if (path) return loadFromFile(path)\n\n const envKey = stringField(process.env.HAVEN_DELEGATE_KEY)\n if (envKey) {\n const accountAddress = readAccountAddressEnv(process.env)\n return {\n delegateKey: envKey,\n agentId: stringField(process.env.HAVEN_AGENT_ID),\n accountAddress,\n chainId: chainIdField(process.env.HAVEN_CHAIN_ID, 'HAVEN_CHAIN_ID'),\n network: stringField(process.env.HAVEN_NETWORK),\n x402BindingSigner: stringField(process.env.HAVEN_X402_BINDING_SIGNER),\n }\n }\n\n throw new Error(\n 'No delegate key found. Set HAVEN_DELEGATE_KEY, pass --credentials <path>, ' +\n 'or set HAVEN_CREDENTIALS to a Haven agent credential JSON file.',\n )\n}\n\nasync function loadFromFile(path: string): Promise<SignerCredentials> {\n let rawText: string\n try {\n rawText = await readFile(path, 'utf8')\n } catch (err) {\n throw new Error(\n `Could not read Haven credentials at ${path}: ${err instanceof Error ? err.message : String(err)}`,\n )\n }\n\n await warnIfCredentialFilePermissive(path)\n\n let raw: RawCredentialFile\n try {\n raw = JSON.parse(rawText) as RawCredentialFile\n } catch {\n throw new Error('Haven credentials must be JSON with a delegate_key field.')\n }\n\n const delegateKey = stringField(raw.delegate_key ?? raw.delegateKey)\n if (!delegateKey) {\n throw new Error('Haven credentials are missing delegate_key — the edge signer needs it to sign.')\n }\n\n const accountAddress = readAccountAddressField(raw)\n return {\n delegateKey,\n agentId: stringField(raw.agent_id ?? raw.agentId),\n accountAddress,\n chainId: chainIdField(raw.chain_id ?? raw.chainId, 'chain_id'),\n network: stringField(raw.network),\n x402BindingSigner: stringField(\n raw.x402_binding_signer ??\n raw.x402BindingSigner ??\n process.env.HAVEN_X402_BINDING_SIGNER,\n ),\n sourcePath: path,\n }\n}\n\n/**\n * The account address off a credential FILE: `account_address` (what\n * `@haven_ai/connect` writes from #2908 on) first, then the two pre-#2908\n * spellings.\n *\n * The two old fallbacks are PERMANENT, not part of the one-release naming\n * window (#2906, decision 2a): a credential file on disk was written once and\n * never rewrites itself, so a signer that stopped reading `safe_address`\n * would silently lose the address for every agent connected before this\n * release — the consent hash would change and the spend-context prompt would\n * say \"not provided\". Two lines, kept for as long as the file format exists.\n *\n * Exported for the mutation tests: dropping `account_address` fails the\n * new-shape test, dropping either old key fails the old-shape test.\n */\nexport function readAccountAddressField(raw: Pick<RawCredentialFile, 'account_address' | 'safe_address' | 'safeAddress'>): string | undefined {\n return stringField(raw.account_address ?? raw.safe_address ?? raw.safeAddress)\n}\n\n/**\n * The account address off the process environment: `HAVEN_ACCOUNT_ADDRESS`\n * (the survivor, decided on #2906). The two names the dashboard handoff\n * emitted before #2908 — `HAVEN_WALLET_ADDRESS` and `HAVEN_SAFE_ADDRESS` —\n * were window-scoped (unlike the credential-FILE fallbacks) and are retired\n * as of #2914.\n */\nexport function readAccountAddressEnv(env: NodeJS.ProcessEnv): string | undefined {\n const current = stringField(env.HAVEN_ACCOUNT_ADDRESS)\n\n // Retired, but REFUSED rather than ignored — the same rule the backend\n // applies to retired request names, for the same reason and with more at\n // stake. Silently dropping these would not merely leave the address unset:\n // `accountAddress` is what `haven_sign_sweep_delegate` passes as\n // `expectedSafe`, and an undefined `expectedSafe` SKIPS the check that a\n // sweep's `to` matches the account in the local credential (see\n // `core.ts`). An operator who upgrades without touching env would lose a\n // money-path cross-check and get no signal at all.\n //\n // The verdict keys on RELIANCE, not presence, so a handoff that still\n // exports both names alongside the new one keeps working:\n // retired alone -> throw\n // both, same value -> accept the new one\n // both, disagreeing -> throw\n for (const name of ['HAVEN_WALLET_ADDRESS', 'HAVEN_SAFE_ADDRESS'] as const) {\n const retired = stringField(env[name])\n if (!retired) continue\n if (!current) {\n throw new Error(\n `${name} is retired (#2906) — Haven accounts are addressed as accounts, not Safes. ` +\n 'Set HAVEN_ACCOUNT_ADDRESS to the same value. Refusing rather than ignoring it, ' +\n 'because an unset account address silently skips the sweep-destination check.',\n )\n }\n if (retired.toLowerCase() !== current.toLowerCase()) {\n throw new Error(\n `${name} and HAVEN_ACCOUNT_ADDRESS were both set to different addresses. ` +\n 'Remove the retired name, or make them match — picking one silently would hide ' +\n 'the mismatch.',\n )\n }\n }\n\n return current\n}\n\nfunction stringField(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim() ? value.trim() : undefined\n}\n\nfunction chainIdField(value: unknown, label: string): number | undefined {\n if (value === undefined || value === null) return undefined\n\n if (typeof value === 'number') {\n if (Number.isSafeInteger(value) && value > 0) return value\n throw invalidChainIdError(label)\n }\n\n if (typeof value === 'string') {\n const trimmed = value.trim()\n if (/^[1-9]\\d*$/.test(trimmed)) {\n const parsed = Number(trimmed)\n if (Number.isSafeInteger(parsed)) return parsed\n }\n throw invalidChainIdError(label)\n }\n\n throw invalidChainIdError(label)\n}\n\nfunction invalidChainIdError(label: string): Error {\n return new Error(`Haven signer credentials ${label} must be a positive integer.`)\n}\n\n/**\n * Warn (best-effort, POSIX only) when the credential file is readable beyond\n * its owner. Mirrors `@haven_ai/mcp`'s check — the delegate key is the most\n * sensitive thing on the machine.\n *\n * Exported for testing.\n */\nexport async function warnIfCredentialFilePermissive(\n path: string,\n log: (message: string) => void = (message) => process.stderr.write(`${message}\\n`),\n platform: NodeJS.Platform = process.platform,\n): Promise<void> {\n if (platform === 'win32') return\n let mode: number\n try {\n mode = (await stat(path)).mode\n } catch {\n return\n }\n if ((mode & 0o077) !== 0) {\n const octal = (mode & 0o777).toString(8).padStart(4, '0')\n log(\n `haven-signer: warning: credential file at ${path} is readable beyond the owner ` +\n `(mode ${octal}). Run: chmod 600 ${path}`,\n )\n }\n}\n","import { createHash } from 'node:crypto'\nimport { appendFile, mkdir } from 'node:fs/promises'\nimport { homedir } from 'node:os'\nimport { dirname, resolve } from 'node:path'\nimport type { SignerToolName } from './tools.js'\n\nexport interface SigningAuditEntry {\n version: 1\n timestamp: string\n tool: SignerToolName\n payload_hash: string\n delegate_address: string\n /**\n * Serialized key kept as `safe_address` deliberately (#2914 review): this\n * is a persisted JSONL field, and an audit log written by an earlier\n * release never rewrites itself — renaming the key here would fork the\n * format mid-file. `SigningAuditContext.accountAddress` (the in-memory\n * field this is built from) carries the account-vocabulary name; only the\n * on-disk spelling stays put.\n */\n safe_address?: string\n chain_id?: number\n}\n\nexport interface SigningAuditContext {\n delegateAddress: string\n accountAddress?: string\n chainId?: number\n auditPath?: string\n}\n\nexport function defaultSigningAuditPath(credentialsPath?: string): string {\n if (credentialsPath) return resolve(`${credentialsPath}.signer-audit.jsonl`)\n return resolve(homedir(), '.haven', 'signer-audit.jsonl')\n}\n\nexport async function appendSigningAuditEntry(\n entry: SigningAuditEntry,\n path: string,\n): Promise<void> {\n await mkdir(dirname(path), { recursive: true })\n await appendFile(path, `${JSON.stringify(entry)}\\n`, 'utf8')\n}\n\nexport function createSigningAuditEntry(\n tool: SignerToolName,\n payloadHash: string,\n context: SigningAuditContext,\n now: Date = new Date(),\n): SigningAuditEntry {\n const entry: SigningAuditEntry = {\n version: 1,\n timestamp: now.toISOString(),\n tool,\n payload_hash: payloadHash,\n delegate_address: context.delegateAddress,\n }\n if (context.accountAddress) entry.safe_address = context.accountAddress\n if (typeof context.chainId === 'number') entry.chain_id = context.chainId\n return entry\n}\n\nexport function hashPayloadForAudit(payload: unknown): string {\n return `0x${createHash('sha256').update(stableStringify(payload)).digest('hex')}`\n}\n\nfunction stableStringify(value: unknown): string {\n if (value === null || typeof value !== 'object') {\n const primitive = JSON.stringify(value)\n return primitive === undefined ? 'undefined' : primitive\n }\n if (Array.isArray(value)) return `[${value.map((item) => stableStringify(item)).join(',')}]`\n const object = value as Record<string, unknown>\n return `{${Object.keys(object)\n .sort()\n .map((key) => `${JSON.stringify(key)}:${stableStringify(object[key])}`)\n .join(',')}}`\n}\n","import { createNextStepBuilder, type NextStep, type NextStepHandoff, type NextStepTarget } from '@haven_ai/sdk'\nimport { z } from 'zod'\n\n/**\n * #3103 (epic #3105, slice 4/5): the signer's typed next step.\n *\n * The signer decides a `next_action` on its refusals and, until this module,\n * never said which tool to call. It cannot know the client's server names\n * (#2550), so the handoff is expressed through the role fields the SDK\n * builder renders — `next_tool_server_role: hosted`, `next_tool_name` — from\n * a bare tool name. The signer must not import the hosted server (it is an\n * npm package installed on user machines; the hosted server is a Docker\n * deployment), so the hosted tools it hands off to are DECLARED here as the\n * argument shape the signer actually emits, and `next-step-signer-parity`\n * in the hosted server's own suite pins them to the hosted schemas at test\n * time — the mirror of how the hosted server declares the signer's shapes.\n */\nexport const SIGNER_HOSTED_HANDOFF_SHAPES = {\n haven_get_payment_status: { payment_id: z.string().min(1) },\n} as const satisfies Record<string, z.ZodRawShape>\n\nfunction target<S extends z.ZodRawShape>(shape: S): NextStepTarget<z.input<z.ZodObject<S>>> {\n const schema = z.object(shape).strict()\n return {\n role: 'hosted',\n validate: (input) => {\n const r = schema.safeParse(input ?? {})\n return r.success ? null : r.error.errors.map((e) => `${e.path.join('.') || '(root)'}: ${e.message}`).join('; ')\n },\n }\n}\n\nconst SIGNER_NEXT_STEP_TARGETS = {\n haven_get_payment_status: target(SIGNER_HOSTED_HANDOFF_SHAPES.haven_get_payment_status),\n}\nexport type SignerNextStepTargets = typeof SIGNER_NEXT_STEP_TARGETS\nexport type SignerHandoff = NextStepHandoff<SignerNextStepTargets>\n\nconst nextStep = createNextStepBuilder(SIGNER_NEXT_STEP_TARGETS)\n\n/** A signer refusal's next step: a hosted tool with arguments it declares, or `null` + the reason. */\nexport function signerRefusalStep(input: { nextAction: NextStep['next_action'] } & SignerHandoff): NextStep {\n return nextStep({ ...input, safeToContinue: false, reason: '' } as Parameters<typeof nextStep>[0])\n}\n\n/** The `next_tool` family of a step, for the failure envelope (additive; `next_tool` never null). */\nexport function nextStepWireFields(step: NextStep): {\n next_tool?: string\n next_tool_server?: string\n next_tool_name?: string\n next_tool_server_role?: 'hosted' | 'signer'\n next_arguments?: Record<string, unknown>\n next_tool_omitted_reason?: string\n} {\n return {\n ...(step.next_tool ? { next_tool: step.next_tool } : {}),\n ...(step.next_tool_server ? { next_tool_server: step.next_tool_server } : {}),\n ...(step.next_tool_name ? { next_tool_name: step.next_tool_name } : {}),\n ...(step.next_tool_server_role ? { next_tool_server_role: step.next_tool_server_role } : {}),\n ...(step.next_arguments ? { next_arguments: step.next_arguments } : {}),\n ...(step.next_tool_omitted_reason ? { next_tool_omitted_reason: step.next_tool_omitted_reason } : {}),\n }\n}\n","/**\n * Byte-free signing handoff (#1263): fetch a delegation-rail x402 intent's\n * EXACT signing payload from Haven by `payment_id`, instead of asking a\n * language model to re-emit multi-KB EIP-712 bytes between tool calls (the\n * #1255 failure mode — runtimes that elide long tool results structurally\n * cannot copy them).\n *\n * Layering: this module lives in the local MCP SERVER layer, not the signer\n * core. The core (`core.ts`) remains pure and network-free; what it signs\n * still goes through the SAME digest re-derivation and Haven-binding\n * verification (#1138) whether the bytes arrived by tool argument or by this\n * fetch. The fetch is a strictly better byte source than model relay — TLS to\n * Haven versus a model's context window — and it uses the agent credential\n * (`identity.json`) the connector already stores next to the signer\n * credential. The delegate key is never sent anywhere.\n */\nimport { readFile } from 'node:fs/promises'\nimport { dirname, join } from 'node:path'\nimport { AgentPaymentNextAction, HavenSigningError } from '@haven_ai/sdk'\nimport type { NextStep } from '@haven_ai/sdk'\nimport { nextStepWireFields, signerRefusalStep } from './next-step.js'\n\nexport interface HavenIdentity {\n apiUrl: string\n apiKey: string\n}\n\n/**\n * Signer-local refusal codes for `fetchX402SignContext` (#3001). Distinct from\n * `AgentPaymentFailureCode` on purpose — these describe a signing-context FETCH\n * failure (network/timeout/backend-refusal/shape), never a payment-domain\n * outcome, and they never reach the backend's REST/OpenAPI surface, only this\n * package's MCP tool responses. Same reasoning `SignerRefusalCode` documents\n * for the version-mismatch pair.\n */\nexport type SignContextErrorCode =\n | 'SIGN_CONTEXT_TIMEOUT'\n | 'SIGN_CONTEXT_UNREACHABLE'\n | 'SIGN_CONTEXT_REFUSED'\n | 'SIGN_CONTEXT_MALFORMED'\n\n/**\n * Structured refusal for every throw site in `fetchX402SignContext` (#3001,\n * follow-up from the #2985/#2986 review). Before this, every one of these —\n * timeout, unreachable host, a non-ok backend response (404/410/…), a\n * malformed body — reached the wire as prose inside the generic\n * `{ code: 'SIGNING_ERROR' }` `HavenSigningError` produces, so an agent had to\n * parse a sentence to learn \"pass typed_data_b64 instead\". The version-mismatch\n * refusal (`HavenUnsupportedSignerVersionError`) already carries `code`,\n * `fallback`, `next_action` as DATA; this mirrors that shape for the\n * sign-context fetch.\n *\n * Extends `HavenSigningError` so every existing `instanceof HavenSigningError`\n * catch site keeps matching unchanged. `code` is inherited as `readonly` from\n * `HavenError` and hard-coded to `'SIGNING_ERROR'` by `HavenSigningError`'s own\n * constructor — TypeScript only lets the class that DECLARES a readonly\n * property assign it, so the override below goes through a narrow cast rather\n * than widening `HavenSigningError`'s constructor (these codes are\n * signer-local, not part of the shared `@haven_ai/sdk` error taxonomy, so that\n * type does not belong there).\n */\nexport class HavenSignContextError extends HavenSigningError {\n declare readonly code: SignContextErrorCode\n /**\n * #3001 / #3010 review: the recovery path, when signing OTHER bytes is\n * actually a remedy — a transport failure (timeout, unreachable) or a\n * body this signer could not read. `typed_data_b64` is NOT in the default\n * quote result since #1272: obtain it by re-running the SAME quote tool\n * with the SAME idempotency_key plus `include_signing_payload: true`.\n * Absent on a backend REFUSAL: an expired, executed or unsignable intent\n * cannot be rescued by re-signing its bytes.\n */\n readonly fallback?: 'typed_data_b64'\n /**\n * #3001: `AgentPaymentNextAction` values the signer already emits — the\n * version-mismatch refusal's `stop_and_tell_user` for the classes where\n * retrying the same call cannot help, and `payment_window_expired` (with\n * `retry_with_new_quote`) for the backend's 410 `expired`, exactly as the\n * plain `HavenError` branch already does for that code.\n */\n readonly next_action: string\n /**\n * #3103 (epic #3105, decisions 1 and 3): the typed next step beside the\n * action. A refusal Haven made (`SIGN_CONTEXT_REFUSED`, not expired) names\n * the hosted status read with the payment id; a transport failure or a\n * malformed body names no tool — the remedy is re-running the SAME quote\n * tool with `include_signing_payload: true` — and an expired window names\n * none either (which quote tool depends on the flow). Never null: a step\n * with no tool carries `next_tool_omitted_reason`. Additive: the class is\n * not exported from the package index — the published surface is the\n * `ToolFailure` envelope `tools.ts` builds from these fields — and every\n * constructor call site is in this file.\n */\n readonly next_tool?: string\n readonly next_tool_server?: string\n readonly next_tool_name?: string\n readonly next_tool_server_role?: 'hosted' | 'signer'\n readonly next_arguments?: Record<string, unknown>\n readonly next_tool_omitted_reason?: string\n readonly retry_with_new_quote?: true\n /** Present only for `SIGN_CONTEXT_REFUSED` (the backend's HTTP status). */\n readonly http_status?: number\n /** Present only for `SIGN_CONTEXT_REFUSED`: the backend's own `error_code`. */\n readonly backend_error_code?: string\n\n constructor(\n message: string,\n code: SignContextErrorCode,\n refusal: { httpStatus: number; errorCode?: string } | undefined,\n /** #3103: the payment the context was fetched for, so a refusal can name the status read. */\n paymentId: string,\n ) {\n super(message)\n ;(this as { code: string }).code = code\n this.name = 'HavenSignContextError'\n let step: NextStep\n if (code === 'SIGN_CONTEXT_REFUSED') {\n this.http_status = refusal?.httpStatus\n this.backend_error_code = refusal?.errorCode\n if (refusal?.httpStatus === 410 || refusal?.errorCode === 'expired') {\n this.next_action = AgentPaymentNextAction.PaymentWindowExpired\n this.retry_with_new_quote = true\n step = signerRefusalStep({\n nextAction: AgentPaymentNextAction.PaymentWindowExpired,\n nextTool: null,\n nextToolOmittedReason:\n 're-run the hosted quote tool you called with the same idempotency_key; which one depends on the flow',\n })\n } else {\n this.next_action = AgentPaymentNextAction.StopAndTellUser\n step = signerRefusalStep({\n nextAction: AgentPaymentNextAction.StopAndTellUser,\n nextTool: 'haven_get_payment_status',\n nextArguments: { payment_id: paymentId },\n })\n }\n } else {\n this.fallback = 'typed_data_b64'\n this.next_action = AgentPaymentNextAction.StopAndTellUser\n step = signerRefusalStep({\n nextAction: AgentPaymentNextAction.StopAndTellUser,\n nextTool: null,\n nextToolOmittedReason:\n 're-run the SAME hosted quote tool with the same idempotency_key and include_signing_payload: true, then pass its typed_data_b64 to this signer',\n })\n }\n Object.assign(this, nextStepWireFields(step))\n }\n}\n\n/**\n * Resolve the agent identity from `identity.json` in the same directory as\n * the signer credential file. Returns null (never throws) when unavailable —\n * the caller decides how to phrase the fallback.\n */\nexport async function loadHavenIdentity(\n credentialsPath: string | undefined,\n): Promise<HavenIdentity | null> {\n if (!credentialsPath) return null\n try {\n const raw = JSON.parse(\n await readFile(join(dirname(credentialsPath), 'identity.json'), 'utf8'),\n ) as Record<string, unknown>\n const apiKey = typeof raw.api_key === 'string' ? raw.api_key : undefined\n const apiUrl = typeof raw.api_url === 'string' ? raw.api_url : undefined\n if (!apiKey || !apiUrl) return null\n return { apiKey, apiUrl: apiUrl.replace(/\\/+$/, '') }\n } catch {\n return null\n }\n}\n\nexport interface FetchedSignContext {\n paymentId: string\n payloadHash: string\n typedData: Record<string, unknown>\n /** The COMPLETE snake_case expected context, verbatim from Haven. */\n x402Expected: Record<string, unknown>\n /**\n * #1355: the 402 PaymentRequired persisted at authorize time, when the\n * backend carries it — lets haven_sign_x402 build the merchant header from\n * `{ payment_id }` alone. Null on pre-#1355 backends/rows; the caller then\n * requires the agent-supplied copy. Untrusted like every other fetched\n * field: header building verifies it against the Haven-signed expected\n * context either way.\n */\n paymentRequired: Record<string, unknown> | null\n}\n\n/**\n * GET /x402/:id/sign-context. Read-only; refusals from the backend\n * (expired/executed/legacy/unknown) surface as clear signing errors that name\n * the next step. The returned payload is UNTRUSTED input exactly like a tool\n * argument would be — the signing path's binding verification and digest\n * equality are what make it safe to use, not its provenance.\n */\n/**\n * #2985: the signer's ONLY network call is bounded. Without a signal a hung\n * `/sign-context` (half-open connection, stalled backend) hung the signer\n * tool call — and so the agent — indefinitely while the funding window ran\n * out, and the `typed_data_b64` fallback the error names was unreachable\n * because the call never returned. 15 s is generous for a single\n * authenticated read and sits well under the 60 s floor of the x402\n * settlement window (`clamp(maxTimeoutSeconds, 60, 600)` backend-side).\n */\nexport const SIGN_CONTEXT_TIMEOUT_MS = 15_000\n\nexport async function fetchX402SignContext(\n identity: HavenIdentity,\n paymentId: string,\n fetchImpl: typeof fetch = fetch,\n timeoutMs: number = SIGN_CONTEXT_TIMEOUT_MS,\n): Promise<FetchedSignContext> {\n let response: Response\n try {\n response = await fetchImpl(\n `${identity.apiUrl}/x402/${encodeURIComponent(paymentId)}/sign-context`,\n {\n headers: { Authorization: `Bearer ${identity.apiKey}` },\n signal: AbortSignal.timeout(timeoutMs),\n },\n )\n } catch (err) {\n const timedOut = err instanceof Error && (err.name === 'TimeoutError' || err.name === 'AbortError')\n throw new HavenSignContextError(\n timedOut\n ? `Haven did not answer the signing-context fetch for ${paymentId} within ${timeoutMs} ms. ` +\n 'Retry, or pass typed_data_b64 from the quote result instead.'\n : `Could not reach Haven to fetch the signing context for ${paymentId}: ` +\n `${err instanceof Error ? err.message : String(err)}. ` +\n 'Retry, or pass typed_data_b64 from the quote result instead.',\n timedOut ? 'SIGN_CONTEXT_TIMEOUT' : 'SIGN_CONTEXT_UNREACHABLE',\n undefined,\n paymentId,\n )\n }\n // #2985 review: the same signal bounds the BODY read. A stalled body used\n // to be swallowed by the `.catch(() => ({}))` and misdiagnosed as a\n // malformed/older backend response — name the timeout instead.\n let body: Record<string, unknown>\n try {\n body = (await response.json()) as Record<string, unknown>\n } catch (err) {\n if (err instanceof Error && (err.name === 'TimeoutError' || err.name === 'AbortError')) {\n throw new HavenSignContextError(\n `Haven did not finish sending the signing context for ${paymentId} within ${timeoutMs} ms. ` +\n 'Retry, or pass typed_data_b64 from the quote result instead.',\n 'SIGN_CONTEXT_TIMEOUT',\n undefined,\n paymentId,\n )\n }\n body = {}\n }\n if (!response.ok) {\n const detail =\n typeof body.error === 'string' ? body.error : `HTTP ${response.status}`\n throw new HavenSignContextError(\n `Haven refused the signing-context fetch for ${paymentId}: ${detail}` +\n (response.status === 404\n ? ' — check the payment_id came from this agent’s own quote.'\n : response.status === 410\n ? ' Re-run the quote with the same idempotency key, then sign the fresh payment_id.'\n : ''),\n 'SIGN_CONTEXT_REFUSED',\n { httpStatus: response.status, errorCode: typeof body.error_code === 'string' ? body.error_code : undefined },\n paymentId,\n )\n }\n const signData = body.sign_data as Record<string, unknown> | undefined\n const x402Expected = body.x402_expected as Record<string, unknown> | undefined\n if (\n !signData ||\n typeof signData.hash !== 'string' ||\n !signData.typed_data ||\n typeof signData.typed_data !== 'object' ||\n !x402Expected\n ) {\n throw new HavenSignContextError(\n 'The Haven sign-context response is missing sign_data.typed_data or x402_expected — ' +\n 'the backend may predate #1263. Pass typed_data_b64 from the quote result instead.',\n 'SIGN_CONTEXT_MALFORMED',\n undefined,\n paymentId,\n )\n }\n const paymentRequired = body.payment_required\n return {\n paymentId: String(body.payment_id ?? paymentId),\n payloadHash: signData.hash,\n typedData: signData.typed_data as Record<string, unknown>,\n x402Expected,\n paymentRequired:\n paymentRequired && typeof paymentRequired === 'object' && !Array.isArray(paymentRequired)\n ? (paymentRequired as Record<string, unknown>)\n : null,\n }\n}\n","import {\n AgentPaymentFailureCode,\n AgentPaymentNextAction,\n HavenApiError,\n HavenError,\n HavenSigningError,\n HavenUnsupportedSignerVersionError,\n connectorRerunCommand,\n type X402PaymentRequired,\n} from '@haven_ai/sdk'\nimport { z } from 'zod/v3'\nimport { isSettlementChildTypedData } from './settlement-child.js'\nimport {\n appendSigningAuditEntry,\n createSigningAuditEntry,\n hashPayloadForAudit,\n type SigningAuditContext,\n} from './audit.js'\nimport type {\n EdgeSigner,\n X402ExpectedPayment,\n X402FundingSignatureResult,\n X402FundingTypedData,\n} from './core.js'\nimport {\n fetchX402SignContext,\n HavenSignContextError,\n type HavenIdentity,\n type FetchedSignContext,\n} from './sign-context.js'\nimport { nextStepWireFields, signerRefusalStep } from './next-step.js'\n\n/**\n * Local signer tool set. These run on the agent's machine, next to the key,\n * and pair with the hosted server's construct/relay tools (#183). They sign;\n * they never call the Haven API and never emit the key.\n */\nexport type SignerToolName =\n | 'haven_sign'\n | 'haven_x402_sign_header'\n | 'haven_sign_x402'\n | 'haven_sign_sweep_delegate'\n\nconst sweepAuthorizationSchema = z.object({\n from: z.string().regex(/^0x[0-9a-fA-F]{40}$/, 'from must be a 0x address'),\n to: z.string().regex(/^0x[0-9a-fA-F]{40}$/, 'to must be a 0x address'),\n value: z.string().regex(/^[0-9]+$/, 'value must be a decimal atomic amount'),\n validAfter: z.string().regex(/^[0-9]+$/, 'validAfter must be a decimal unix time'),\n validBefore: z.string().regex(/^[0-9]+$/, 'validBefore must be a decimal unix time'),\n nonce: z.string().regex(/^0x[0-9a-fA-F]{64}$/, 'nonce must be a 0x-prefixed 32-byte hex string'),\n token: z.string().regex(/^0x[0-9a-fA-F]{40}$/, 'token must be a 0x address'),\n chainId: z.number().int().positive(),\n})\n\n/**\n * Binding version at the tool boundary (#1143).\n *\n * Open on purpose. A literal (or literal union) here is validated by the MCP\n * server *before* any handler runs, so a signer one release behind the backend\n * rejected the payment with `Invalid literal value, expected 1 at\n * x402_expected.auth.version` — a message that names neither the cause (your\n * signer is stale) nor the fix (update it), and which no Haven code wrote.\n * Accept any positive integer here and let the signer decide semantically:\n * `SUPPORTED_X402_EXPECTED_VERSIONS` / `SUPPORTED_SWEEP_BINDING_VERSIONS` in\n * `core.ts` still fail closed on anything they do not know, so this widens the\n * *error path*, never what can be signed.\n */\nconst bindingVersionSchema = z.number().int().positive()\n\nconst sweepExpectedAuthSchema = z.object({\n version: bindingVersionSchema,\n message: z.string().min(1),\n signature: z\n .string()\n .regex(/^0x[0-9a-fA-F]+$/, 'signature must be a 0x-prefixed hex string'),\n signer: z.string().regex(/^0x[0-9a-fA-F]{40}$/, 'signer must be a 0x address'),\n})\n\nconst x402ExpectedShape = {\n payment_id: z.string().min(1),\n payload_hash: z\n .string()\n .regex(/^0x[0-9a-fA-F]+$/, 'payload_hash must be a 0x-prefixed hex string'),\n resource_url: z.string().url(),\n merchant_to: z.string().min(1),\n amount: z.string().min(1),\n asset: z.string().min(1),\n network: z.string().min(1),\n // Required: expires_at is folded into the Haven-signed binding message, so the\n // signer must receive the exact same value to reconstruct a matching message.\n // Omitting it used to fail downstream with a cryptic \"authentication message is\n // invalid\" — making it required surfaces a clear INVALID_INPUT at the boundary.\n expires_at: z.string().min(1),\n // #1138: present on a delegation-rail (v2) context. It commits to the EIP-712\n // typed data the account validates; the signer refuses to raw-sign the bare\n // hash when it is present, and refuses to sign typed data when it is absent.\n typed_data_hash: z\n .string()\n .regex(/^0x[0-9a-fA-F]+$/, 'typed_data_hash must be a 0x-prefixed hex string')\n .optional(),\n // #1690: present on a v3 context. The delegate this quote was created FOR —\n // the signer refuses to sign when it is not its own. Inside the Haven-signed\n // message, so stripping it here would only break the binding signature.\n payer_delegate: z\n .string()\n .regex(/^0x[0-9a-fA-F]{40}$/, 'payer_delegate must be a 0x-prefixed address')\n .optional(),\n payer_agent_id: z.string().min(1).optional(),\n auth: z.object({\n // Open at the boundary, enforced in the signer — see bindingVersionSchema.\n version: bindingVersionSchema,\n message: z.string().min(1),\n signature: z\n .string()\n .regex(/^0x[0-9a-fA-F]+$/, 'signature must be a 0x-prefixed hex string'),\n signer: z.string().min(1),\n }),\n}\n\nconst x402ExpectedSchema = z.object(x402ExpectedShape)\n\nexport const toolSchemas = {\n haven_sign_sweep_delegate: {\n // The authorization fields prepared by Haven's POST /sweep/prepare. Passed\n // through verbatim from the hosted haven_sweep_delegate tool — the signer\n // re-derives the binding message from these exact values.\n authorization: sweepAuthorizationSchema,\n // Haven's signature over the authorization context (the binding).\n expected_auth: sweepExpectedAuthSchema,\n },\n haven_sign: {\n // #1263: THE preferred x402 input — the signer fetches the exact signing\n // payload + expected context from Haven itself (authenticated with the\n // locally-stored agent credential), so no bulky bytes ever cross the\n // model. Pass payment_id ALONE for a delegation-rail x402 funding intent.\n payment_id: z.string().min(1).optional(),\n // The unsigned hash from haven_pay / haven_pay_x402_quote (payload_hash).\n // Optional when payment_id is supplied (the fetch carries it).\n payload_hash: z\n .string()\n .regex(/^0x[0-9a-fA-F]+$/, 'payload_hash must be a 0x-prefixed hex string')\n .optional(),\n // Pass x402.expected from hosted haven_pay_x402_quote when this hash funds\n // a standard x402 merchant retry. The signer records it locally and returns\n // an opaque x402_binding for the later header-signing step.\n x402_expected: x402ExpectedSchema.optional(),\n // #1138: delegation-rail intents sign THIS, not payload_hash. Object-typed\n // (not z.unknown()) so MCP clients embed it as JSON rather than a string.\n typed_data: z.record(z.string(), z.unknown()).optional(),\n // #1255: the same payload as ONE opaque base64 string, exactly as returned\n // by the hosted tools. Preferred over typed_data when both are present —\n // an agent re-emitting multi-KB nested JSON between tool calls is the\n // failure mode this field removes (a truncated/reshaped payload fails the\n // digest check and the payment refuses, correctly but pointlessly).\n // Bounded: a realistic redemption payload is ~10KB encoded; 256KB is\n // generous headroom while keeping the offline signer from materializing\n // arbitrarily large caller input.\n typed_data_b64: z.string().min(1).max(262144).optional(),\n },\n haven_x402_sign_header: {\n // The parsed HTTP 402 PaymentRequired from the merchant. Typed as an object\n // (not z.unknown(), which becomes empty JSON Schema `{}`) so MCP clients\n // embed it as JSON rather than serialising the object to a string.\n payment_required: z.record(z.string(), z.unknown()),\n // Opaque binding returned by haven_sign when x402_expected was supplied.\n x402_binding: z.string().min(1),\n },\n haven_sign_x402: {\n // #1263: preferred — pass payment_id (plus payment_required) and the\n // signer fetches the exact signing payload + expected context itself.\n payment_id: z.string().min(1).optional(),\n // One-shot x402 signing: funding hash + merchant header in one local call.\n // Both optional when payment_id is supplied (the fetch carries them).\n payload_hash: z\n .string()\n .regex(/^0x[0-9a-fA-F]+$/, 'payload_hash must be a 0x-prefixed hex string')\n .optional(),\n x402_expected: x402ExpectedSchema.optional(),\n // #1355: optional when payment_id is supplied — the signer's context fetch\n // carries the stored 402 PaymentRequired, so `{ payment_id }` alone is the\n // preferred call. Still required (via the runtime check in the handler)\n // for the quote-based fallback path without a payment_id.\n payment_required: z.record(z.string(), z.unknown()).optional(),\n // #1138: delegation-rail intents sign THIS, not payload_hash. Object-typed\n // (not z.unknown()) so MCP clients embed it as JSON rather than a string.\n typed_data: z.record(z.string(), z.unknown()).optional(),\n // #1255: see haven_sign.typed_data_b64 — the copy-through-safe form.\n typed_data_b64: z.string().min(1).max(262144).optional(),\n },\n// #3101: keys survive on the type (see the hosted server's contracts.ts).\n} as const satisfies Record<SignerToolName, z.ZodRawShape>\n\nconst SIGN_DESCRIPTION = [\n 'Sign an unsigned Haven payment hash with the local delegate key. The delegate key never leaves',\n 'this process. Pass the payload_hash returned by haven_pay or haven_pay_x402_quote.',\n 'For x402, also pass x402_expected from haven_pay_x402_quote; the signer records it locally',\n 'and returns { signature, x402_binding }. x402_expected includes expires_at; sign before that',\n 'window closes. DELEGATION-RAIL x402 accounts (#1263): pass payment_id ALONE (preferred) — this',\n 'signer fetches the exact signing payload and expected context from Haven itself, so nothing',\n 'bulky ever crosses your context. Fallback: pass typed_data_b64 through UNCHANGED (never re-type',\n 'the nested typed_data JSON); the account validates that EIP-712 payload, not payload_hash.',\n 'Next: call mcp__haven__haven_submit with signature, then pass x402_binding',\n 'to mcp__haven-signer__haven_x402_sign_header. For plain SafeTransfer payments, just pass payload_hash and',\n 'relay the returned signature via mcp__haven__haven_submit.',\n].join(' ')\n\nconst X402_SIGN_HEADER_DESCRIPTION = [\n 'Build and sign the EIP-3009 merchant payment header for the merchant leg of an x402 payment.',\n 'The delegate key stays local — only the signed header crosses any boundary.',\n 'Pass the payment_required from the original merchant 402 response and the x402_binding',\n 'returned by haven_sign. It must be haven_sign — NOT haven_sign_x402, which is a',\n 'one-shot that builds the header itself and spends its own binding doing so. If you called',\n 'haven_sign_x402, its result already carries payment_header; retry the merchant with that and',\n 'do not call this tool. The signer validates the merchant, amount, resource, asset, and',\n 'network against the recorded funding context before signing, checks expires_at when present,',\n 'and rejects mismatches or expired payment windows.',\n 'Returns { payment_header, accepted }. On your retry set BOTH PAYMENT-SIGNATURE (x402 v2) and',\n 'X-PAYMENT (v1) to <payment_header>; a strict v2 merchant reads only the first.',\n 'Only call after haven_submit has confirmed the funding step (nextAction=none or',\n 'the funding tx has a confirmed status). Next for paid MCP tools: call mcp__haven__haven_complete_mcp_tool.',\n].join(' ')\n\nconst SIGN_X402_DESCRIPTION = [\n 'One-shot x402 signing for the fast 3-call flow: sign the funding hash AND build the EIP-3009',\n 'merchant payment header in a single local call (equivalent to haven_sign followed by',\n 'haven_x402_sign_header). The delegate key never leaves this process. From the haven_pay_mcp_tool',\n 'result pass JUST payment_id — PREFERRED (#1263, #1355): this signer fetches the exact signing',\n 'payload, expected context, and merchant payment_required from Haven itself, so nothing bulky',\n 'crosses your context. If the signer reports the context carried no payment_required (older',\n 'backend), re-call with payment_id plus payment_required verbatim from the pay result.',\n 'Fallback for older backends: pass payload_hash, x402_expected (the nested x402.expected object —',\n 'passing the whole x402 object is also accepted and unwrapped for you), and typed_data_b64',\n 'through UNCHANGED; the signer',\n 'signs the typed data instead of payload_hash and refuses the bare hash when the context commits to typed data.',\n 'Returns',\n '{ signature, x402_binding, payment_header, accepted }; hand signature + payment_header to',\n 'mcp__haven__haven_settle_mcp_tool to fund and settle in one hosted call. The header is built now (before',\n 'funding confirms), so its short validity window starts here — call mcp__haven__haven_settle_mcp_tool promptly,',\n 'and re-run mcp__haven__haven_pay_mcp_tool with the same idempotency_key if a tool returns PAYMENT_WINDOW_EXPIRED.',\n 'The returned x402_binding is ALREADY SPENT — this tool consumed it building payment_header —',\n 'so never pass it to mcp__haven-signer__haven_x402_sign_header; that tool is the follow-up to',\n 'haven_sign, not to this one. payment_header IS the header to use.',\n 'Next: for a paid MCP tool, call mcp__haven__haven_settle_mcp_tool. For a direct plain-HTTP x402',\n 'merchant (the haven_pay_x402_quote path), relay signature via mcp__haven__haven_submit and then',\n 'retry the original merchant URL YOURSELF, setting BOTH PAYMENT-SIGNATURE (x402 v2) and',\n 'X-PAYMENT (v1) to payment_header — Haven never contacts that merchant.',\n].join(' ')\n\nconst SIGN_SWEEP_DELEGATE_DESCRIPTION = [\n 'Sign a Haven-prepared gasless USDC sweep that recovers stranded funds from the delegate',\n 'wallet back to your Haven wallet. The delegate key never leaves this process and this tool',\n 'never broadcasts — it returns only an EIP-3009 signature that Haven\\'s relayer submits and',\n 'pays gas for. Pass the authorization and expected_auth returned by the hosted',\n 'haven_sweep_delegate tool. The signer verifies Haven authored the authorization and that it',\n 'pays out to your own Safe before signing, then returns { signature } to hand back to',\n 'mcp__haven__haven_sweep_delegate to complete recovery.',\n].join(' ')\n\nexport const toolDescriptions: Record<SignerToolName, string> = {\n haven_sign: SIGN_DESCRIPTION,\n haven_x402_sign_header: X402_SIGN_HEADER_DESCRIPTION,\n haven_sign_x402: SIGN_X402_DESCRIPTION,\n haven_sign_sweep_delegate: SIGN_SWEEP_DELEGATE_DESCRIPTION,\n}\n\n/** Map the wire-shaped x402_expected (snake_case) to the EdgeSigner's camelCase context. */\n/**\n * Sign the x402 funding leg on whichever rail the Haven-signed context declares\n * (#1138).\n *\n * The **context** selects the path, never the caller's arguments: a v2 context\n * (one that commits to a typed-data digest) requires typed data, a v1 context\n * requires the bare hash, and `assertExpectedBinding` rejects the mismatch. So\n * an agent that passes `typed_data` on a legacy-rail intent — or omits it on a\n * delegation-rail one — gets a clear refusal here rather than a signature the\n * chain rejects later.\n */\nasync function signFundingLeg(\n signer: EdgeSigner,\n expected: X402ExpectedPayment,\n payloadHash: string,\n typedData: Record<string, unknown> | undefined,\n): Promise<X402FundingSignatureResult> {\n if (!expected.typedDataHash) {\n return signer.signX402FundingHash(payloadHash, expected)\n }\n if (!typedData) {\n throw new HavenSigningError(\n 'This x402 funding intent is on the delegation rail: it commits to EIP-712 typed data, ' +\n 'which was not supplied. Pass typed_data_b64 from haven_pay_mcp_tool / ' +\n 'haven_pay_x402_quote through unchanged (or typed_data verbatim) — the bare ' +\n 'payload_hash is not what the account validates.',\n )\n }\n return signer.signX402FundingTypedData(typedData as unknown as X402FundingTypedData, expected)\n}\n\nfunction toExpectedX402(raw: {\n payment_id: string\n payload_hash: string\n resource_url: string\n merchant_to: string\n amount: string\n asset: string\n network: string\n // Required at the tool boundary (see x402ExpectedSchema): it's folded into the\n // Haven-signed binding message. The EdgeSigner's internal type keeps it\n // optional because it skips the window check when absent.\n expires_at: string\n typed_data_hash?: string\n payer_delegate?: string\n payer_agent_id?: string\n auth: X402ExpectedPayment['auth']\n}): X402ExpectedPayment {\n return {\n paymentId: raw.payment_id,\n payloadHash: raw.payload_hash,\n typedDataHash: raw.typed_data_hash,\n payerDelegate: raw.payer_delegate,\n payerAgentId: raw.payer_agent_id,\n resourceUrl: raw.resource_url,\n merchantTo: raw.merchant_to,\n amount: raw.amount,\n asset: raw.asset,\n network: raw.network,\n expiresAt: raw.expires_at,\n auth: raw.auth,\n }\n}\n\n/**\n * Validate a FETCHED expected context (#1263) against the same boundary schema\n * a tool argument passes through — provenance does not skip validation. A\n * malformed response names the fallback instead of leaking a Zod stack.\n */\nfunction parseFetchedExpected(\n fetched: FetchedSignContext,\n): Parameters<typeof toExpectedX402>[0] {\n const parsed = z.object(x402ExpectedShape).safeParse(fetched.x402Expected)\n if (!parsed.success) {\n throw new HavenSigningError(\n 'The Haven sign-context response carried a malformed x402_expected — the backend may ' +\n 'predate #1263. Pass payload_hash + x402_expected from the quote result instead. ' +\n `Underlying: ${parsed.error.issues[0]?.message ?? 'schema mismatch'}`,\n )\n }\n return parsed.data as Parameters<typeof toExpectedX402>[0]\n}\n\nexport interface ToolSuccess<T> {\n success: true\n data: T\n}\n\nexport interface ToolFailure {\n success: false\n code: string\n message: string\n statusCode?: number\n paymentId?: string\n next_action?: string\n retry_with_new_quote?: boolean\n suggested_tool?: string\n /** #3101 (epic #3105, decision 7): the typed next-step family, additive; `next_tool` never null. */\n next_tool?: string\n next_tool_server?: string\n next_tool_name?: string\n next_tool_server_role?: 'hosted' | 'signer'\n next_arguments?: Record<string, unknown>\n next_tool_omitted_reason?: string\n /**\n * #1309: present on `UNSUPPORTED_EXPECTED_CONTEXT_VERSION` /\n * `UNSUPPORTED_SWEEP_BINDING_VERSION` refusals — the exact version set this\n * signer install enforces, derived from `SUPPORTED_X402_EXPECTED_VERSIONS` /\n * `SUPPORTED_SWEEP_BINDING_VERSIONS` at the throw site.\n */\n supported_versions?: number[]\n /** #1309: the version Haven sent that triggered the refusal above. */\n received_version?: number\n /**\n * #1309: precise recovery guidance as DATA, not just prose inside `message`\n * — the same text the hosted quote's advisory `signer_compatibility.fallback`\n * carries when the refusal is an out-of-date signer. #3001 reuses this same\n * field for every sign-context refusal (`'typed_data_b64'`).\n */\n fallback?: string\n /**\n * #3001: present on `SIGN_CONTEXT_REFUSED` — the HTTP status the backend\n * answered the `/x402/:id/sign-context` fetch with (404, 410, …).\n */\n http_status?: number\n /** #3001: the backend's own `error_code` on `SIGN_CONTEXT_REFUSED` (`expired`, `already_executed`, `not_signable`, `sign_context_unavailable`). */\n backend_error_code?: string\n}\n\nexport type ToolPayload<T = unknown> = ToolSuccess<T> | ToolFailure\n\nexport interface ToolHandlerOptions {\n audit?: SigningAuditContext & { auditPath: string }\n /**\n * #1263: how the payment_id signing path reaches Haven. Lives at the MCP\n * server layer (the core stays network-free); absent → payment_id calls\n * refuse with a message naming the typed_data_b64 fallback.\n */\n signContext?: {\n loadIdentity: () => Promise<HavenIdentity | null>\n fetchImpl?: typeof fetch\n }\n}\n\n/**\n * Resolve the delegation-rail signing payload from the tool arguments (#1255).\n *\n * `typed_data_b64` wins over `typed_data`: it is the copy-through-safe form —\n * one opaque string the agent relays unchanged, instead of re-emitting multi-KB\n * nested JSON (a redemption UserOp's callData) between two tool calls. The live\n * #1255 failure was exactly that: the payload arrived altered, the digest check\n * refused (correctly), and the purchase died with no defect anywhere in the\n * chain. The decoded object goes through the SAME digest verification as a\n * plain typed_data — this changes the transport, never the trust model.\n */\nfunction resolveTypedData(args: {\n typed_data?: Record<string, unknown>\n typed_data_b64?: string\n}): Record<string, unknown> | undefined {\n if (!args.typed_data_b64) return args.typed_data\n try {\n const decoded = JSON.parse(\n Buffer.from(args.typed_data_b64, 'base64').toString('utf8'),\n ) as unknown\n if (!decoded || typeof decoded !== 'object' || Array.isArray(decoded)) {\n throw new Error('decoded value is not an object')\n }\n return decoded as Record<string, unknown>\n } catch (err) {\n throw new HavenSigningError(\n 'typed_data_b64 did not decode to a JSON object. Pass the exact string returned by the ' +\n 'hosted Haven tool, unchanged — do not re-encode, trim, or reformat it. ' +\n `Underlying error: ${err instanceof Error ? err.message : String(err)}`,\n )\n }\n}\n\nexport function createToolHandlers(\n signer: EdgeSigner,\n options: ToolHandlerOptions = {},\n): Record<SignerToolName, (input: unknown) => Promise<ToolPayload>> {\n /**\n * #1263: resolve the signing inputs for a payment_id call by fetching the\n * exact bytes from Haven. Returns null when the caller did not use the\n * payment_id path. The fetched payload is untrusted input like any tool\n * argument — it still goes through the binding verification and digest\n * re-derivation downstream; this only changes HOW the bytes arrive.\n */\n async function resolveSignContext(args: {\n payment_id?: string\n payload_hash?: string\n }): Promise<FetchedSignContext | null> {\n if (!args.payment_id) return null\n const identity = (await options.signContext?.loadIdentity()) ?? null\n if (!identity) {\n throw new HavenSigningError(\n 'payment_id signing needs the agent identity (identity.json next to the signer ' +\n `credentials), which this signer could not load. Re-run \\`${connectorRerunCommand()}\\` ` +\n 'to restore it, or pass typed_data_b64 from the quote result instead.',\n )\n }\n const ctx = await fetchX402SignContext(\n identity,\n args.payment_id,\n options.signContext?.fetchImpl,\n )\n if (\n args.payload_hash &&\n args.payload_hash.toLowerCase() !== ctx.payloadHash.toLowerCase()\n ) {\n throw new HavenSigningError(\n 'The supplied payload_hash does not match the signing context Haven serves for ' +\n `payment ${args.payment_id}. Pass payment_id alone, or check which quote the ` +\n 'hash came from.',\n )\n }\n return ctx\n }\n\n return {\n haven_sign: async (input) =>\n runTool(async () => {\n const args = parse('haven_sign', coerceX402Expected(input))\n const fetched = await resolveSignContext(args)\n const typedData = fetched?.typedData ?? resolveTypedData(args)\n const payloadHash = fetched?.payloadHash ?? args.payload_hash\n if (!payloadHash) {\n throw new HavenSigningError(\n 'Pass payment_id (preferred for delegation-rail x402) or payload_hash.',\n )\n }\n const expectedRaw = fetched\n ? parseFetchedExpected(fetched)\n : args.x402_expected\n const x402Expected = expectedRaw ? toExpectedX402(expectedRaw) : null\n const result = x402Expected\n ? await signFundingLeg(signer, x402Expected, payloadHash, typedData)\n : null\n if (!result) {\n // #1254: a DIRECT delegation-rail payment carries typed_data and no\n // x402 context — the account validates the TYPED DATA, and a raw\n // signature over payload_hash is rejected on-chain (AA24, found\n // live). When typed_data is present it is what gets signed; the\n // raw-hash path below is the legacy AllowanceModule rail only.\n if (typedData) {\n // #1476: a DELEGATION payload is an authority grant to a third\n // party — the erc7710 settlement child, whose signature lets a\n // merchant's facilitator pull from the treasury. It must never be\n // signed without a Haven-signed expected context to verify against\n // (#1455), and until now nothing stopped that: whether the child\n // got verified depended on WHICH TOOL the caller happened to use,\n // which is a convention, not a boundary.\n //\n // Keyed off the payload's own shape rather than the caller's\n // choice, so #1254's direct-payment UserOp case is untouched: that\n // is the account validating its OWN operation, not a grant.\n if (isSettlementChildTypedData(typedData)) {\n throw new HavenSigningError(\n 'Refusing to sign a delegation payload with no expected context. This typed data ' +\n 'is a DELEGATION — signing it grants a third party authority to move funds — so ' +\n 'it is only ever signed against a Haven-signed context that the caveats are ' +\n 'verified against. Call this tool with { payment_id } instead (the signer then ' +\n 'fetches and verifies the context itself), or use haven_sign_x402.',\n )\n }\n const signature = await signer.signDelegationTypedData(typedData)\n await auditSigning('haven_sign', payloadHash)\n return { signature }\n }\n const signature = signer.signPaymentHash(payloadHash)\n await auditSigning('haven_sign', payloadHash)\n return { signature }\n }\n await auditSigning('haven_sign', payloadHash)\n return { signature: result.signature, x402_binding: result.x402Binding }\n }),\n\n haven_x402_sign_header: async (input) =>\n runTool(async () => {\n // Defensive: the object-typed schema makes conformant MCP clients embed\n // payment_required as JSON, but some transports still serialise it to a\n // string. Coerce it back to an object BEFORE Zod validation so the\n // tightened schema doesn't reject it (else `.accepts` would be undefined\n // → \"No compatible payment option found\").\n const args = parse('haven_x402_sign_header', coercePaymentRequired(input))\n const result = await signer.buildX402PaymentHeader(\n args.payment_required as X402PaymentRequired,\n args.x402_binding,\n )\n await auditSigning(\n 'haven_x402_sign_header',\n hashPayloadForAudit(args.payment_required),\n )\n return { payment_header: result.paymentHeader, accepted: result.accepted }\n }),\n\n haven_sign_x402: async (input) =>\n runTool(async () => {\n // Coerce a stringified payment_required (same transport guard as\n // haven_x402_sign_header) and unwrap a whole-`x402`-object x402_expected\n // before validation.\n const args = parse('haven_sign_x402', coerceX402Expected(coercePaymentRequired(input)))\n const fetched = await resolveSignContext(args)\n const payloadHash = fetched?.payloadHash ?? args.payload_hash\n const expectedRaw = fetched ? parseFetchedExpected(fetched) : args.x402_expected\n if (!payloadHash || !expectedRaw) {\n throw new HavenSigningError(\n 'Pass payment_id (preferred — the signer fetches the signing context itself) ' +\n 'or payload_hash + x402_expected from the quote result.',\n )\n }\n // 1. Sign the funding leg (records the binding + checks expiry/context).\n // Which payload that is — bare hash or the account's typed data — is\n // decided by the Haven-signed context, not by the caller (#1138).\n const funding = await signFundingLeg(\n signer,\n toExpectedX402(expectedRaw),\n payloadHash,\n fetched?.typedData ?? resolveTypedData(args),\n )\n // 2. Build the merchant EIP-3009 header against that binding — local, no network.\n // #1355: prefer the PaymentRequired the context fetch carried (same\n // Haven read the signing bytes came from — one less blob an agent\n // relays); the caller-supplied copy is the fallback for pre-#1355\n // backends. Either copy passes the SAME expected-context\n // verification inside buildX402PaymentHeader — provenance is not\n // what makes it safe (#1263 discipline).\n const paymentRequired = (fetched?.paymentRequired ?? args.payment_required) as\n | X402PaymentRequired\n | undefined\n if (!paymentRequired) {\n throw new HavenSigningError(\n fetched\n ? 'The Haven sign-context for this payment_id carried no payment_required ' +\n '(backend predates #1355). Pass payment_required from the pay result ' +\n 'explicitly, verbatim.'\n : 'payment_required is required on the quote-based path (no payment_id to fetch ' +\n 'it by). Pass it verbatim from the quote result.',\n )\n }\n const header = await signer.buildX402PaymentHeader(\n paymentRequired,\n funding.x402Binding,\n )\n // Two audit entries — one per signing operation — matching the\n // decomposed haven_sign + haven_x402_sign_header trail, so the funding\n // signature and the merchant header remain distinguishable in the log.\n await auditSigning('haven_sign_x402', payloadHash)\n await auditSigning('haven_sign_x402', hashPayloadForAudit(paymentRequired))\n return {\n signature: funding.signature,\n x402_binding: funding.x402Binding,\n payment_header: header.paymentHeader,\n accepted: header.accepted,\n }\n }),\n\n haven_sign_sweep_delegate: async (input) =>\n runTool(async () => {\n const args = parse('haven_sign_sweep_delegate', input)\n const result = await signer.signSweepAuthorization({\n authorization: args.authorization,\n expectedAuth: args.expected_auth,\n // Cross-check `to` against the Safe in the local credential when present.\n expectedSafe: options.audit?.accountAddress,\n })\n await auditSigning(\n 'haven_sign_sweep_delegate',\n hashPayloadForAudit(args.authorization),\n )\n return { signature: result.signature }\n }),\n }\n\n async function auditSigning(tool: SignerToolName, payloadHash: string): Promise<void> {\n if (!options.audit) return\n const { auditPath, ...context } = options.audit\n await appendSigningAuditEntry(\n createSigningAuditEntry(tool, payloadHash, {\n ...context,\n delegateAddress: signer.delegateAddress,\n }),\n auditPath,\n )\n }\n}\n\nfunction parse<TName extends SignerToolName>(name: TName, input: unknown): Record<string, any> {\n return z.object(toolSchemas[name]).parse(input ?? {})\n}\n\n/**\n * Tolerate the agent passing the whole `x402` object from haven_pay_mcp_tool /\n * haven_pay_x402_quote where only the nested `x402.expected` signing context is\n * wanted. The wrapper looks like `{ accepted, resource_url, merchant_to,\n * funding_to, expected: {...} }` and lacks the top-level `auth` binding the\n * schema requires — so when `x402_expected.auth` is absent but\n * `x402_expected.expected` is an object, unwrap to `.expected`. Also parses a\n * JSON-stringified value back to an object first (some transports stringify\n * object args). This removes the easiest-to-make handoff mistake without a\n * breaking parameter rename.\n */\nfunction coerceX402Expected(input: unknown): unknown {\n if (!input || typeof input !== 'object') return input\n const record = input as Record<string, unknown>\n let value: unknown = record.x402_expected\n if (typeof value === 'string') {\n try {\n value = JSON.parse(value)\n } catch {\n return input\n }\n }\n if (!value || typeof value !== 'object') return input\n const obj = value as Record<string, unknown>\n if (obj.auth === undefined && obj.expected && typeof obj.expected === 'object') {\n return { ...record, x402_expected: obj.expected }\n }\n // Parsed-from-string but already the right shape: keep the parsed object.\n if (value !== record.x402_expected) return { ...record, x402_expected: value }\n return input\n}\n\n/**\n * If a caller's transport serialised `payment_required` to a JSON string,\n * parse it back to an object before schema validation. Leaves a real object\n * (or anything that isn't valid JSON) untouched.\n */\nfunction coercePaymentRequired(input: unknown): unknown {\n if (!input || typeof input !== 'object') return input\n const record = input as Record<string, unknown>\n if (typeof record.payment_required !== 'string') return input\n try {\n return { ...record, payment_required: JSON.parse(record.payment_required) }\n } catch {\n return input\n }\n}\n\nasync function runTool<T>(fn: () => Promise<T>): Promise<ToolPayload<T>> {\n try {\n return { success: true, data: await fn() }\n } catch (err) {\n return normalizeError(err)\n }\n}\n\nfunction normalizeError(err: unknown): ToolFailure {\n if (err instanceof z.ZodError) {\n return {\n success: false,\n code: 'INVALID_INPUT',\n message: err.errors.map((e) => `${e.path.join('.') || '(root)'}: ${e.message}`).join('; '),\n statusCode: 400,\n }\n }\n if (err instanceof HavenUnsupportedSignerVersionError) {\n // #1309: the structured signer refusal. `code` is one of\n // SignerRefusalCode's two values (not the generic 'SIGNING_ERROR'\n // HavenSigningError hard-codes), so an agent can route on it directly\n // instead of matching prose. next_action reuses the EXISTING\n // AgentPaymentNextAction taxonomy (StopAndTellUser) rather than inventing\n // a parallel vocabulary — this refusal is exactly that: stop, don't retry\n // as-is, tell the user what fallback says.\n return {\n success: false,\n code: err.code,\n message: err.message,\n supported_versions: [...err.supportedVersions],\n received_version: err.receivedVersion,\n fallback: err.fallback,\n next_action: AgentPaymentNextAction.StopAndTellUser,\n // #3103: no tool can fix a version skew from inside the call.\n ...nextStepWireFields(signerRefusalStep({\n nextAction: AgentPaymentNextAction.StopAndTellUser,\n nextTool: null,\n nextToolOmittedReason: 'update @haven_ai/signer by re-running the connector, then repeat the same call',\n })),\n }\n }\n if (err instanceof HavenSignContextError) {\n // #3001: every fetchX402SignContext refusal (timeout, unreachable, a\n // non-ok backend response, a malformed body) — structured the same way as\n // the version-mismatch refusal below, instead of the generic\n // `{ code: 'SIGNING_ERROR' }` a plain HavenSigningError produces. Checked\n // BEFORE the `HavenSigningError` branch below since this class extends it.\n return {\n success: false,\n code: err.code,\n message: err.message,\n next_action: err.next_action,\n ...(err.fallback !== undefined ? { fallback: err.fallback } : {}),\n ...(err.retry_with_new_quote ? { retry_with_new_quote: true } : {}),\n ...(err.http_status !== undefined ? { http_status: err.http_status } : {}),\n ...(err.backend_error_code !== undefined ? { backend_error_code: err.backend_error_code } : {}),\n // #3103: the typed step the error decided beside its action.\n ...(err.next_tool ? { next_tool: err.next_tool } : {}),\n ...(err.next_tool_server ? { next_tool_server: err.next_tool_server } : {}),\n ...(err.next_tool_name ? { next_tool_name: err.next_tool_name } : {}),\n ...(err.next_tool_server_role ? { next_tool_server_role: err.next_tool_server_role } : {}),\n ...(err.next_arguments ? { next_arguments: err.next_arguments } : {}),\n ...(err.next_tool_omitted_reason ? { next_tool_omitted_reason: err.next_tool_omitted_reason } : {}),\n }\n }\n if (err instanceof HavenSigningError) {\n return { success: false, code: err.code, message: err.message }\n }\n if (err instanceof HavenApiError) {\n return { success: false, code: err.code, message: err.message, statusCode: err.statusCode }\n }\n if (err instanceof HavenError) {\n return {\n success: false,\n code: err.code,\n message: err.message,\n statusCode: err.statusCode,\n paymentId: err.paymentId,\n ...(err.code === AgentPaymentFailureCode.PaymentWindowExpired\n ? {\n next_action: AgentPaymentNextAction.PaymentWindowExpired,\n retry_with_new_quote: true,\n suggested_tool: 'haven_pay_mcp_tool',\n // #3103: same omission as the hosted window-expired helper.\n ...nextStepWireFields(signerRefusalStep({\n nextAction: AgentPaymentNextAction.PaymentWindowExpired,\n nextTool: null,\n nextToolOmittedReason: 're-run the hosted quote tool you called with the same idempotency_key; which one depends on the flow (suggested_tool names the MCP one)',\n })),\n }\n : {}),\n }\n }\n return {\n success: false,\n code: 'UNKNOWN_ERROR',\n message: err instanceof Error ? err.message : String(err),\n }\n}\n","import { createHash } from 'node:crypto'\nimport { mkdir, readFile, writeFile } from 'node:fs/promises'\nimport { dirname, resolve } from 'node:path'\nimport { toolDescriptions, toolSchemas, type SignerToolName } from './tools.js'\n\nexport interface SignerConsentInput {\n delegateAddress: string\n accountAddress?: string\n agentId?: string\n chainId?: number\n network?: string\n toolNames: readonly SignerToolName[]\n}\n\nexport interface SignerConsentDecision {\n ok: boolean\n hash: string\n reason:\n | 'env_var_match'\n | 'ack_file_match'\n | 'wrote_ack_file'\n | 'env_var_mismatch'\n | 'no_acknowledgement'\n}\n\nexport interface SignerConsentOptions {\n credentialsPath?: string\n writeAck?: boolean\n env?: Record<string, string | undefined>\n out?: { write: (chunk: string) => unknown }\n}\n\nexport const SIGNER_ACK_ENV = 'HAVEN_SIGNER_ACK'\n\n/**\n * The consent SURFACE version, folded into the acknowledgement hash. Bump it\n * when what the signer can DO changes in a way the consent text describes —\n * not for copy edits. Tool names alone cannot carry this: #1263 added the\n * signer's first network capability (the read-only signing-context fetch)\n * without changing any tool name, and a consent acknowledged under the old\n * \"does not call the Haven API\" text must not silently cover the new\n * behavior. Bumping this re-prompts every existing install exactly once,\n * with the corrected text.\n *\n * v2: the #1263 read-only signing-context fetch.\n */\nexport const SIGNER_CONSENT_SURFACE_VERSION = 2\n\nexport function computeSignerConsentHash(input: SignerConsentInput): string {\n const identity = [\n input.delegateAddress.toLowerCase(),\n (input.accountAddress ?? '').toLowerCase(),\n input.agentId ?? '',\n input.chainId ?? '',\n input.network ?? '',\n ].join('|')\n const toolCanonical = [...input.toolNames].sort().join(',')\n return createHash('sha256')\n .update(`${identity}\\n${toolCanonical}\\nsurface:v${SIGNER_CONSENT_SURFACE_VERSION}`)\n .digest('hex')\n .slice(0, 16)\n}\n\nexport function renderSignerConsentBlock(input: SignerConsentInput, hash: string): string {\n const lines: string[] = [\n '',\n '------------------------------------------------------------',\n 'Haven edge signer - first-launch consent',\n '------------------------------------------------------------',\n '',\n `Delegate address: ${input.delegateAddress}`,\n ]\n lines.push(`Haven wallet: ${input.accountAddress ?? 'not provided to this signer'}`)\n if (input.agentId) lines.push(`Agent ID: ${input.agentId}`)\n if (typeof input.chainId === 'number') lines.push(`Chain ID: ${input.chainId}`)\n if (input.network) lines.push(`Network: ${input.network}`)\n lines.push('')\n lines.push('This local signer holds the delegate key on this machine and signs')\n lines.push('payment payloads or x402 merchant headers for the delegate address above.')\n lines.push(\"Its one network use is a read-only fetch of a pending payment's signing\")\n lines.push('payload from Haven, authenticated with the agent credential stored next to')\n lines.push(\"this signer's key file - it never sends the key, a signature, or anything\")\n lines.push('else outbound, and it cannot show a live allowance summary.')\n lines.push('On-chain Safe rules remain the real spend gate, and the wallet owner can')\n lines.push('pause or revoke agent authority outside this signer.')\n lines.push('')\n lines.push('Tools this signer will expose to your agent runtime:')\n for (const name of input.toolNames) {\n lines.push(` - ${name}`)\n lines.push(` ${toolDescriptions[name]}`)\n }\n lines.push('')\n lines.push('A local audit entry is appended for every signing operation. Audit entries')\n lines.push('record timestamp, tool, payload hash, and delegate address; never the key,')\n lines.push('signature, or x402 payment header.')\n lines.push('')\n lines.push(`Consent hash: ${hash}`)\n lines.push('')\n lines.push('To acknowledge, EITHER:')\n lines.push(` - set ${SIGNER_ACK_ENV}=${hash} in this process's environment, OR`)\n lines.push(' - re-run with --ack to write the acknowledgement next to your')\n lines.push(' credential file (sidecar <credentials>.signer-ack.json).')\n lines.push('')\n lines.push('------------------------------------------------------------')\n lines.push('')\n return lines.join('\\n')\n}\n\nexport async function ensureSignerConsent(\n input: SignerConsentInput,\n options: SignerConsentOptions = {},\n): Promise<SignerConsentDecision> {\n const env = options.env ?? process.env\n const out = options.out ?? process.stderr\n const hash = computeSignerConsentHash(input)\n const envAck = env[SIGNER_ACK_ENV]\n\n if (typeof envAck === 'string' && envAck.length > 0) {\n if (envAck === hash) return { ok: true, hash, reason: 'env_var_match' }\n out.write(renderSignerConsentBlock(input, hash))\n out.write(\n `${SIGNER_ACK_ENV} was set but did not match the current signer consent hash.\\n` +\n `Expected: ${hash}\\n` +\n `Got: ${envAck}\\n` +\n `Re-acknowledge with the new hash above, or run with --ack.\\n\\n`,\n )\n return { ok: false, hash, reason: 'env_var_mismatch' }\n }\n\n const ackPath = sidecarPath(options.credentialsPath)\n if (ackPath) {\n const stored = await readAckFile(ackPath)\n if (stored?.ack === hash) return { ok: true, hash, reason: 'ack_file_match' }\n }\n\n if (options.writeAck && ackPath) {\n out.write(renderSignerConsentBlock(input, hash))\n await writeAckFile(ackPath, hash)\n out.write(`Wrote acknowledgement to ${ackPath}\\n\\n`)\n return { ok: true, hash, reason: 'wrote_ack_file' }\n }\n\n out.write(renderSignerConsentBlock(input, hash))\n return { ok: false, hash, reason: 'no_acknowledgement' }\n}\n\nexport function registeredSignerToolNames(): SignerToolName[] {\n return Object.keys(toolSchemas) as SignerToolName[]\n}\n\nfunction sidecarPath(credentialsPath?: string): string | null {\n if (!credentialsPath) return null\n return resolve(`${credentialsPath}.signer-ack.json`)\n}\n\nasync function readAckFile(path: string): Promise<{ ack?: string } | null> {\n try {\n const raw = await readFile(path, 'utf8')\n const parsed = JSON.parse(raw) as { ack?: unknown }\n return { ack: typeof parsed.ack === 'string' ? parsed.ack : undefined }\n } catch {\n return null\n }\n}\n\nasync function writeAckFile(path: string, hash: string): Promise<void> {\n await mkdir(dirname(path), { recursive: true })\n await writeFile(\n path,\n JSON.stringify({ ack: hash, at: new Date().toISOString() }, null, 2),\n 'utf8',\n )\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { defaultSigningAuditPath } from './audit.js'\nimport { signerCapabilityAdvertisement, signerInstructions } from './capabilities.js'\nimport {\n ensureSignerConsent,\n registeredSignerToolNames,\n type SignerConsentDecision,\n} from './consent.js'\nimport { isSupportedNodeVersion, unsupportedNodeVersionMessage } from '@haven_ai/sdk'\nimport { createEdgeSigner, type EdgeSigner } from './core.js'\nimport { loadSignerCredentials, type SignerCredentials } from './credentials.js'\nimport {\n createToolHandlers,\n toolDescriptions,\n toolSchemas,\n type SignerToolName,\n type ToolPayload,\n} from './tools.js'\nimport { loadHavenIdentity } from './sign-context.js'\n\nexport const SIGNER_NAME = '@haven_ai/signer'\nexport const SIGNER_VERSION = '0.4.0-alpha.0'\n\nexport interface SignerOptions {\n /** Path to a Haven credential JSON file (delegate_key is read from it). */\n credentialsPath?: string\n /** Pre-resolved delegate key (skips credential loading). */\n delegateKey?: string\n /** Append local signing audit entries here. Defaults to a credential sidecar or ~/.haven. */\n auditPath?: string\n /** Overridable so the Node-floor refusal is testable without spawning a Node. */\n nodeVersion?: string\n /**\n * When true, write the consent sidecar file (`<credentials>.signer-ack.json`)\n * with the current consent hash and proceed. Surfaced via the `--ack` CLI flag.\n */\n writeAck?: boolean\n /**\n * When true, skip the consent gate entirely. Reserved for tests and controlled\n * embedding — production CLIs should not set this.\n */\n skipConsent?: boolean\n /** Override consent environment lookup. Reserved for tests and controlled embedding. */\n consentEnv?: Record<string, string | undefined>\n /** Override the stream the consent block is printed to. Reserved for tests. */\n consentOut?: { write: (chunk: string) => unknown }\n /** Trusted Haven signer address for x402 expected-context bindings. */\n x402BindingSigner?: string\n}\n\nexport async function resolveEdgeSigner(options: SignerOptions = {}): Promise<EdgeSigner> {\n const { signer } = await resolveSignerRuntime(options)\n return signer\n}\n\nexport interface ResolvedSignerRuntime {\n signer: EdgeSigner\n credentials?: SignerCredentials\n}\n\nexport async function resolveSignerRuntime(\n options: SignerOptions = {},\n): Promise<ResolvedSignerRuntime> {\n // The choke point, deliberately (#1161 review). Every public way to obtain a\n // key-bound EdgeSigner from this package funnels through here —\n // `runSignerStdioServer`, `resolveEdgeSigner`, and any embedder calling it\n // directly (the `skipConsent` docs invite controlled embedding, so that is a\n // supported surface, not just a test seam). Asserting only in the stdio\n // entrypoint would have reproduced the exact bug this issue fixes: a guard\n // that exists but sits on one path while another reaches the delegate key\n // unchecked.\n //\n // First statement, before the `delegateKey` fast path and before credentials\n // are read, so an unsupported runtime never touches a key by either route.\n assertSupportedNodeVersion(options.nodeVersion)\n\n if (options.delegateKey) {\n return {\n signer: createEdgeSigner(options.delegateKey, {\n x402BindingSigner: options.x402BindingSigner ?? process.env.HAVEN_X402_BINDING_SIGNER,\n }),\n }\n }\n const creds = await loadSignerCredentials(options.credentialsPath)\n return {\n signer: createEdgeSigner(creds.delegateKey, {\n x402BindingSigner:\n options.x402BindingSigner ?? creds.x402BindingSigner ?? process.env.HAVEN_X402_BINDING_SIGNER,\n // #1690: the signer's own agent id, so a payer-mismatch refusal can name\n // both sides. The bare-delegateKey path above has no credential file and\n // therefore no agent id — the guard still works there, on addresses.\n agentId: creds.agentId,\n }),\n credentials: creds,\n }\n}\n\n/**\n * Build a local stdio MCP server exposing the sign-only tools, bound to an\n * edge signer that holds the delegate key. It exposes no construct/relay\n * tools — it only signs. Its ONE network capability (#1263) is an\n * authenticated READ: fetching a payment's exact signing context from Haven\n * by payment_id, so agents never have to relay multi-KB signing payloads\n * through a model context. The signer CORE below it stays network-free, and\n * fetched bytes pass the same verification as tool-argument bytes.\n */\nexport function buildSignerMcpServer(\n signer: EdgeSigner,\n options: Pick<SignerOptions, 'auditPath'> & { credentials?: SignerCredentials } = {},\n): McpServer {\n // #1155: the handshake states what this signer can verify, so an agent can\n // detect expected-context skew before it quotes rather than after it signs.\n // `SIGNER_VERSION` is a *package* version and nothing derives capability from\n // it — both fields below are derived from the constants the signing path\n // enforces. Advisory only: no refusal is added here, the #1143 signing-time\n // guard remains the enforcement point.\n const server = new McpServer(\n { name: SIGNER_NAME, version: SIGNER_VERSION },\n {\n capabilities: signerCapabilityAdvertisement(),\n instructions: signerInstructions(),\n },\n )\n\n const credentialsPath = options.credentials?.sourcePath\n const handlers = createToolHandlers(signer, {\n audit: {\n auditPath: options.auditPath ?? defaultSigningAuditPath(credentialsPath),\n delegateAddress: signer.delegateAddress,\n accountAddress: options.credentials?.accountAddress,\n chainId: options.credentials?.chainId,\n },\n // #1263: the payment_id signing path — the ONLY network call this server\n // can make, an authenticated read of a signing context from Haven, using\n // the agent identity the connector stores next to the signer credential.\n // The signer CORE stays network-free; fetched bytes still pass the same\n // binding verification + digest re-derivation as tool-argument bytes.\n signContext: {\n loadIdentity: () => loadHavenIdentity(credentialsPath),\n },\n })\n const registerTool = (server as unknown as {\n tool: (\n name: string,\n description: string,\n schema: unknown,\n handler: (args: unknown) => Promise<unknown>,\n ) => void\n }).tool.bind(server)\n\n for (const name of Object.keys(toolSchemas) as SignerToolName[]) {\n registerTool(name, toolDescriptions[name], toolSchemas[name], async (args: unknown) =>\n toMcpResult(await handlers[name](args)),\n )\n }\n\n return server\n}\n\n/**\n * Refuse to start on an unsupported Node (#1161).\n *\n * Asserted at STARTUP, not only at install, because the two can diverge: a user\n * upgrades Node, connects successfully, then downgrades — or a version manager\n * hands the agent runtime a different Node than the shell that ran setup. Only a\n * startup check sees the version this process is actually running on.\n *\n * This is the signer, so refusing is the conservative answer rather than the\n * aggressive one. It holds the delegate key and produces every payment\n * signature; on an unsupported runtime the plausible failure is a wrong or\n * absent signature, which is worse than not starting. The consent gate below\n * takes the same posture for the same reason.\n */\nexport function assertSupportedNodeVersion(nodeVersion: string = process.versions.node): void {\n if (isSupportedNodeVersion(nodeVersion)) return\n const err: NodeJS.ErrnoException = new Error(\n unsupportedNodeVersionMessage({ subject: 'The Haven signer', nodeVersion }),\n )\n err.code = 'HAVEN_SIGNER_UNSUPPORTED_NODE'\n throw err\n}\n\nexport async function runSignerStdioServer(options: SignerOptions = {}): Promise<void> {\n // The Node floor is asserted inside resolveSignerRuntime — the choke point\n // every key-bound path shares — so it is enforced here too, before\n // credentials are read, without a second call site to keep in sync.\n const { signer, credentials } = await resolveSignerRuntime(options)\n\n if (!options.skipConsent) {\n const decision = await runSignerConsentGate(signer, credentials, options)\n if (!decision.ok) {\n const err: NodeJS.ErrnoException = new Error(\n decision.reason === 'env_var_mismatch'\n ? 'Haven edge signer consent acknowledgement does not match the current configuration.'\n : 'Haven edge signer requires a one-time consent acknowledgement before starting.',\n )\n err.code = 'HAVEN_SIGNER_NO_CONSENT'\n throw err\n }\n }\n\n const server = buildSignerMcpServer(signer, { credentials, auditPath: options.auditPath })\n await server.connect(new StdioServerTransport())\n}\n\nexport async function runSignerConsentGate(\n signer: EdgeSigner,\n credentials: SignerCredentials | undefined,\n options: SignerOptions,\n): Promise<SignerConsentDecision> {\n return ensureSignerConsent(\n {\n delegateAddress: signer.delegateAddress,\n accountAddress: credentials?.accountAddress,\n agentId: credentials?.agentId,\n chainId: credentials?.chainId,\n network: credentials?.network,\n toolNames: registeredSignerToolNames(),\n },\n {\n credentialsPath: options.credentialsPath ?? credentials?.sourcePath,\n writeAck: options.writeAck,\n env: options.consentEnv,\n out: options.consentOut,\n },\n )\n}\n\nfunction toMcpResult(payload: ToolPayload) {\n return {\n isError: !payload.success,\n content: [{ type: 'text' as const, text: JSON.stringify(payload, null, 2) }],\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/core.ts","../src/next-step.ts","../src/sign-context.ts","../src/capabilities.ts","../src/file-mode.ts","../src/credentials.ts","../src/audit.ts","../src/bare-hash.ts","../src/tools.ts","../src/consent.ts","../src/server.ts"],"names":["addressFromKey","HavenSigningError","privateKeyToAccount","hashTypedData","isSettlementChildTypedData","chainIdForNetwork","assertOwnSettlementChild","isPackedUserOperationTypedData","assertUserOpTypedDataBinding","assertBoundDirectPaymentUserOp","assertFundingLegPaysDelegate","HavenTypedDataRefusedError","randomUUID","selectStandardPaymentOption","HavenApiError","toStandardPaymentRequirements","decodeBase64Json","encodeBase64Json","x402V2PaymentEnvelope","buildSweepTypedData","recoverTypedDataAddress","buildSweepAuthorizationMessage","verifySignature","hashMessage","x402AuthorizationAmount","SignerRefusalCode","connectorRerunCommand","SIGNER_UPDATE_FALLBACK","HavenUnsupportedSignerVersionError","buildX402ExpectedMessage","HavenError","AgentPaymentFailureCode","z","createNextStepBuilder","AgentPaymentNextAction","readFile","join","dirname","HAVEN_CLIENT_HEADER","readClientUpdate","DIRECT_SIGN_CONTEXT_VERSION","stat","lstat","chmod","resolve","homedir","path","mkdir","rename","appendFile","createHash","assertSdkBoundDirectPaymentUserOp","HavenUserOpBindingError","writeFile","McpServer","havenClientIdentity","isSupportedNodeVersion","unsupportedNodeVersionMessage","StdioServerTransport"],"mappings":"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","file":"index.cjs","sourcesContent":["import { randomUUID } from 'node:crypto'\nimport { hashMessage, hashTypedData, recoverTypedDataAddress } from 'viem'\nimport { privateKeyToAccount } from 'viem/accounts'\nimport {\n addressFromKey,\n assertBoundDirectPaymentUserOp,\n assertOwnSettlementChild,\n assertFundingLegPaysDelegate,\n assertUserOpTypedDataBinding,\n chainIdForNetwork,\n HavenTypedDataRefusedError,\n isPackedUserOperationTypedData,\n isSettlementChildTypedData,\n buildX402ExpectedMessage,\n buildSweepAuthorizationMessage,\n buildSweepTypedData,\n verifySignature,\n selectStandardPaymentOption,\n toStandardPaymentRequirements,\n x402AuthorizationAmount,\n x402V2PaymentEnvelope,\n decodeBase64Json,\n encodeBase64Json,\n AgentPaymentFailureCode,\n HavenError,\n HavenSigningError,\n HavenApiError,\n HavenUnsupportedSignerVersionError,\n SignerRefusalCode,\n SIGNER_UPDATE_FALLBACK,\n connectorRerunCommand,\n type SweepAuthorization,\n type SweepExpectedAuth,\n type X402ExpectedAuth,\n type X402PaymentRequired,\n type X402PaymentOption,\n} from '@haven_ai/sdk/edge'\n\n/**\n * The edge signer core.\n *\n * Holds the delegate key in this process and exposes the signing operations a\n * hosted-MCP flow needs — five, none of them a raw-hash primitive (#3169): each\n * takes a payload something can check — a Haven binding verified here, typed\n * data the account validates on-chain, or a sweep authorization. It performs no network I/O and never\n * returns the key — only signatures and the standard x402 header. See\n * docs/architecture/07-edge-signer.md.\n */\nexport interface EdgeSigner {\n /** Address derived from the delegate key. */\n readonly delegateAddress: string\n /**\n * Sign a DIRECT delegation-rail payment's EIP-712 typed data (#1254) — the\n * non-x402 counterpart of `signX402FundingTypedData`. The Hybrid account\n * validates the typed data, not the bare ERC-4337 hash; raw-signing the\n * hash produced AA24 on-chain (found live, #908 mainnet canary). Signed\n * VERBATIM (#829): the exact structure the hosted result carried — and,\n * unlike a blind hash, a structure whose recipient/amount/account are\n * visible to this process's audit log.\n */\n signDelegationTypedData(typedData: Record<string, unknown>): Promise<string>\n /**\n * Sign a delegation-rail x402 funding intent's EIP-712 typed data (#1138) and\n * remember the funded merchant-header context — every x402 funding intent\n * now takes this path (#3272 criterion 8: the bare-hash v1 rail is\n * retired).\n *\n * The account validates this typed data, NOT a bare hash, so the expected\n * context must be v2/v3 and commit to its digest — see\n * `assertExpectedBinding`. `typedData` is `undefined` when the caller had\n * none to supply; that is itself refused (a v1 context that needed no typed\n * data is refused earlier, by the version check).\n */\n signX402FundingTypedData(\n typedData: X402FundingTypedData | undefined,\n expected: X402ExpectedPayment,\n ): Promise<X402FundingSignatureResult>\n /** Build + sign the EIP-3009 X-PAYMENT header for the merchant leg of x402. */\n buildX402PaymentHeader(\n paymentRequired: X402PaymentRequired,\n x402Binding: string,\n ): Promise<X402HeaderResult>\n /**\n * Sign a Haven-prepared EIP-3009 sweep authorization (gasless USDC recovery\n * delegate → the agent's account (Haven wallet)). Verifies the authorization\n * came from Haven and pays out to the agent's account (Haven wallet) — the\n * account belongs to the agent, not the delegate — before signing; the\n * relayer broadcasts it and pays gas. Never broadcasts — pure signing.\n */\n signSweepAuthorization(input: SweepSignatureInput): Promise<SweepSignatureResult>\n}\n\nexport interface SweepSignatureInput {\n /** The authorization fields prepared by the backend. */\n authorization: SweepAuthorization\n /** Haven's signature over the authorization context (binding). */\n expectedAuth: SweepExpectedAuth\n /** Optional account (Haven wallet) address from the local credential, cross-checked against `to` when present. */\n expectedSafe?: string\n}\n\nexport interface SweepSignatureResult {\n /** EIP-712 signature over the TransferWithAuthorization, by the delegate key. */\n signature: string\n}\n\n/** EIP-712 payload the delegation-rail account validates (#1138). */\nexport interface X402FundingTypedData {\n domain: Record<string, unknown>\n types: Record<string, unknown>\n primaryType: string\n message: Record<string, unknown>\n}\n\nexport interface X402ExpectedPayment {\n /** Haven payment id for the funding transfer. */\n paymentId: string\n /** Funding hash this expected context authenticates. */\n payloadHash: string\n /**\n * EIP-712 digest of the typed data the account validates (#1138). Present ⇒\n * the binding is v2 and the delegation-rail typed-data path is the ONLY\n * signing path allowed for this intent.\n */\n typedDataHash?: string\n /**\n * Resource URL of the x402 payment Haven prepared. On the hosted surface\n * that is `haven_pay_x402_quote` — `buildX402SigningContext` in\n * `mcp-server/src/tools/support/mcp-context.ts` (called from the\n * `haven_pay_x402_quote` handler, which is still in `tools.ts`) relays\n * `intent.resourceUrl` here, and\n * `haven_resume_x402_payment` re-emits the same context. Checked against\n * the merchant header's resource in `assertX402MatchesExpected`.\n */\n resourceUrl: string\n /**\n * Merchant recipient of that same prepared payment (`intent.merchantTo`,\n * same source). Checked against the header's `payTo` in\n * `assertX402MatchesExpected` and, for an erc7710 settlement child,\n * against the child's payee caveat in `verifySettlementChild`.\n */\n merchantTo: string\n /** Atomic amount funded for the merchant header. */\n amount: string\n /** Token contract funded for the merchant header. */\n asset: string\n /** x402 network funded for the merchant header. */\n network: string\n /** ISO expiry for the funding/quote window. When present, the signer refuses stale merchant headers. */\n expiresAt?: 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 it is not\n * its own delegate. Inside the Haven-signed message, so it cannot be\n * stripped or forged without breaking the binding signature.\n */\n payerDelegate?: string\n /** The paying agent's id — carried for the refusal's diagnosis (#1690). */\n payerAgentId?: string\n /** Haven signature over the expected funding context. */\n auth: X402ExpectedAuth\n}\n\nexport interface X402HeaderResult {\n /** The merchant-verifiable X-PAYMENT header value. */\n paymentHeader: string\n /** The x402 option this header pays. */\n accepted: X402PaymentOption\n}\n\nexport interface X402FundingSignatureResult {\n /** EIP-712 signature over the Haven-committed funding typed data. */\n signature: string\n /** Opaque process-local binding for the later merchant header signing step. */\n x402Binding: string\n}\n\nexport interface EdgeSignerOptions {\n /** Address allowed to authenticate x402 expected-context messages from Haven. */\n x402BindingSigner?: string\n /**\n * This signer's OWN agent id, from the local credential (#1690). Used only\n * to make the payer-mismatch refusal name both sides; the guard itself\n * compares delegate addresses and works without it.\n */\n agentId?: string\n}\n\nexport function createEdgeSigner(\n delegateKey: string,\n options: EdgeSignerOptions = {},\n): EdgeSigner {\n let delegateAddress: string\n try {\n delegateAddress = addressFromKey(delegateKey)\n } catch (err) {\n throw new HavenSigningError(\n `Invalid delegate key: ${err instanceof Error ? err.message : String(err)}`,\n )\n }\n const x402Bindings = new Map<string, X402ExpectedPayment>()\n /**\n * #2291: why a binding this process once held is gone. A binding is\n * single-use by design and `buildX402PaymentHeader` deletes it on every exit\n * path, so a re-use and a typo previously produced the SAME refusal — and\n * they need opposite remedies: a spent binding means the header was already\n * built (use it, or re-quote), while an unknown one means the signer never\n * held it (sign first, or the signer restarted).\n *\n * The reason is recorded, not just the fact, because the exit paths are not\n * equivalent: a binding retired by the WINDOW check produced no header at\n * all, so telling that caller to \"retry with the header you already have\"\n * would be a confident lie (review finding). Three outcomes, three remedies.\n *\n * Ids only. The payment context is still deleted with the map entry, so this\n * changes nothing about what the signer retains — a retired id is an opaque\n * UUID, not payment data. Bounded so a long-lived signer cannot grow it\n * without limit; the oldest ids fall off, which degrades a stale re-use back\n * to the unknown-binding message rather than to a wrong one.\n */\n type RetiredBindingReason = 'header_built' | 'window_expired'\n const retiredX402Bindings = new Map<string, RetiredBindingReason>()\n const RETIRED_BINDING_MEMORY = 64\n function retireX402Binding(id: string, reason: RetiredBindingReason): void {\n retiredX402Bindings.set(id, reason)\n if (retiredX402Bindings.size > RETIRED_BINDING_MEMORY) {\n const oldest = retiredX402Bindings.keys().next()\n if (!oldest.done) retiredX402Bindings.delete(oldest.value)\n }\n }\n\n return {\n delegateAddress,\n\n async signDelegationTypedData(typedData: Record<string, unknown>): Promise<string> {\n const account = privateKeyToAccount(delegateKey as `0x${string}`)\n // Signed VERBATIM (#829/#1254): the exact structure Haven sent, never\n // one reconstructed from components — a re-derived payload is a\n // different payload, and the account validates the original.\n return account.signTypedData(typedData as Parameters<typeof account.signTypedData>[0])\n },\n\n async signX402FundingTypedData(\n typedData: X402FundingTypedData | undefined,\n expected: X402ExpectedPayment,\n ): Promise<X402FundingSignatureResult> {\n // Version skew first (#1143), independent of whether typedData was\n // supplied: a v1 context (auth.version 1, retired #3272 criterion 8)\n // must produce the STRUCTURED version-mismatch refusal, not a generic\n // \"typed data required\" message that would fire first if this ran\n // after the presence check below.\n if (expected?.auth) {\n assertSupportedBindingVersion(\n expected.auth.version,\n SUPPORTED_X402_EXPECTED_VERSIONS,\n 'x402 expected context',\n )\n }\n if (!typedData) {\n throw new HavenSigningError(\n 'This x402 funding intent is on the delegation rail: it commits to EIP-712 typed data, ' +\n 'which was not supplied. Pass typed_data_b64 from haven_pay_mcp_tool / ' +\n 'haven_pay_x402_quote through unchanged (or typed_data verbatim) — a bare ' +\n 'payload_hash is not what the account validates.',\n )\n }\n // Recompute the digest from the typed data actually in hand — everything\n // upstream is untrusted input. `assertExpectedBinding` requires this\n // EXACT digest to equal Haven's `typedDataHash` commitment. (#3272 moved\n // the digest-equality check that used to follow this call into\n // `assertExpectedBinding`, and dropped a redundant comparison of\n // `expected.payloadHash` with itself; what gets signed is unchanged.)\n const digest = hashTypedData(typedData as Parameters<typeof hashTypedData>[0])\n assertExpectedBinding(digest, expected, options.x402BindingSigner)\n assertPayerMatchesDelegate(expected, delegateAddress, options.agentId)\n // #1455: the digest check above proves Haven DECLARED these bytes. It\n // says nothing about what they mean. When the payload is a delegation —\n // the erc7710 settlement child, whose signature lets a merchant pull from\n // the treasury — re-derive the meaning from the caveats and refuse if it\n // disagrees with the declaration. A backend could otherwise declare one\n // payee and pin another, and the pair would bind perfectly.\n if (isSettlementChildTypedData(typedData)) {\n // A network this signer cannot map is its OWN failure, not a chain\n // mismatch. Folding it into the comparison (as `?? -1` did) refused\n // correctly but reported \"expected chain -1\", sending a reader after a\n // phantom mismatch instead of the mapping gap (#1455 second review).\n const settlementChainId = chainIdForNetwork(expected.network)\n if (settlementChainId === undefined) {\n throw new HavenSigningError(\n `Refusing to sign the x402 settlement child: this signer cannot map the network ` +\n `'${expected.network}' to a chain id, so it cannot check which chain the child is ` +\n 'scoped to. Update @haven_ai/signer.',\n )\n }\n // #3281: through the shared SDK wrapper, so every child refusal is\n // TYPED_DATA_NOT_ALLOWED (structured at the tool layer), like the\n // funding-leg refusals below — not a bare SIGNING_ERROR.\n assertOwnSettlementChild(typedData, {\n merchantTo: expected.merchantTo,\n amount: expected.amount,\n asset: expected.asset,\n // From the SIGNED network, not the payload's own claim. Passing\n // Number(typedData.domain.chainId) here made the check compare a\n // value to itself — vacuous, and precisely the \"declared one thing,\n // signed another\" class this file exists to catch (#1455 review).\n chainId: settlementChainId,\n expiresAt: expected.expiresAt,\n }, delegateAddress)\n // #3281 criterion 8: the wrapper also requires the child to be\n // re-delegated FROM this signer's own account, and the verifier refuses\n // a ROOT authority. The exact budget-delegation hash is not checked: it\n // is knowable here only by trusting Haven for it, and the invariant\n // does not need it — a non-ROOT authority must resolve on-chain to a\n // delegation made TO this account, which only its owner can sign.\n } else if (isPackedUserOperationTypedData(typedData)) {\n // #3281 (epic #3284): the binding above proves Haven DECLARED these\n // bytes — but a compromised binding key can declare anything. So the\n // funding leg must also be the ONE shape a funding leg is: the #3271\n // UserOp binding against the declared UserOp hash, the #3272\n // direct-payment allowlist (own account, pinned chain, a single\n // redemption of one budget delegation granted by another account),\n // and a single transfer of the quoted token and amount to THIS\n // signer's own delegate EOA — a local value no binding can rewrite.\n assertUserOpTypedDataBinding(typedData, expected.payloadHash)\n assertBoundDirectPaymentUserOp(typedData as unknown as Record<string, unknown>, delegateAddress)\n assertFundingLegPaysDelegate(typedData as unknown as Record<string, unknown>, {\n delegateAddress,\n asset: expected.asset,\n amount: expected.amount,\n })\n } else {\n // #3281 criterion 1: the x402 arm signs exactly two shapes. Anything\n // else — a TransferWithAuthorization, a Permit, an invented type —\n // is refused however validly Haven's binding key declared it.\n throw new HavenTypedDataRefusedError(\n `This signer's x402 arm signs only a funding-leg PackedUserOperation or an erc7710 ` +\n `settlement Delegation; this typed data is '${String(\n (typedData as { primaryType?: unknown }).primaryType,\n )}'. Refusing, even though its digest is bound by the expected context.`,\n )\n }\n const account = privateKeyToAccount(delegateKey as `0x${string}`)\n // Signed VERBATIM (#829): the exact structure Haven sent, never one\n // reconstructed from components — a re-derived payload is a different\n // payload, and the account validates the original.\n const signature = await account.signTypedData(\n typedData as Parameters<typeof account.signTypedData>[0],\n )\n const x402Binding = randomUUID()\n x402Bindings.set(x402Binding, { ...expected })\n return { signature, x402Binding }\n },\n\n async buildX402PaymentHeader(\n paymentRequired: X402PaymentRequired,\n x402Binding: string,\n ): Promise<X402HeaderResult> {\n const expected = x402Bindings.get(x402Binding)\n if (!expected) {\n // #2291: two different situations, two different remedies. Conflating\n // them sent a reporter hunting a binding-lookup bug that did not\n // exist — the caller HAD signed, seconds earlier, with a one-shot that\n // spends its own binding building the header inline.\n const retired = retiredX402Bindings.get(x402Binding)\n if (retired === 'header_built') {\n throw new HavenSigningError(\n 'This x402 binding was already used to build a merchant header. Bindings are ' +\n 'single-use. If you called haven_sign_x402, it already returned the ' +\n 'payment_header — retry the merchant with THAT header instead of building ' +\n 'another; haven_x402_sign_header is the follow-up to haven_sign, not to ' +\n 'haven_sign_x402. If you no longer have the header, re-run the quote tool with ' +\n 'the same idempotency_key.',\n )\n }\n if (retired === 'window_expired') {\n throw new HavenSigningError(\n 'This x402 binding was retired because its payment window closed before a merchant ' +\n 'header could be built — no header exists to retry with. Re-run the quote tool ' +\n 'with the same idempotency_key to get a fresh window, then sign again.',\n )\n }\n throw new HavenSigningError(\n 'x402 funding binding is required before signing a merchant header. Sign the ' +\n 'hosted funding payload with x402_expected first (haven_sign returns a binding this ' +\n 'tool can use). A binding is also lost when the signer process restarts, since ' +\n 'bindings live in memory only — re-sign to mint a fresh one.',\n )\n }\n // No header is built on either window path — the window closed first —\n // so the binding is retired with the precise remedy (#3173 review: the\n // post-load re-check must retire too, or the binding dangles in memory\n // holding user payment context).\n const assertWindowOpenOrRetire = (): void => {\n try {\n assertX402PaymentWindowOpen(expected)\n } catch (err) {\n x402Bindings.delete(x402Binding)\n retireX402Binding(x402Binding, 'window_expired')\n throw err\n }\n }\n assertWindowOpenOrRetire()\n const option = selectStandardPaymentOption(paymentRequired.accepts)\n if (!option) {\n throw new HavenApiError(\n 'No compatible payment option found in x402 requirements. ' +\n 'Haven supports standard x402 exact payments on Base USDC.',\n 400,\n )\n }\n assertX402MatchesExpected(paymentRequired, option, expected)\n\n const account = privateKeyToAccount(delegateKey as `0x${string}`)\n const requirements = toStandardPaymentRequirements(paymentRequired, option)\n // #3173: `x402/schemes` costs ~750 ms of module init on top of viem and\n // is needed only here, on the merchant-header leg — never at startup,\n // never for `haven_sign`'s typed-data path. Loaded on first use. A load\n // failure is a structured refusal, not UNKNOWN_ERROR: before #3173 a\n // broken x402 install failed at process start where the connector doctor\n // sees it; now it would surface here, after the funding leg was signed.\n const { exact } = await loadX402Schemes()\n // The first load in a process costs real time; re-check the window it\n // was asserted open against before building the header — retiring the\n // binding on expiry exactly as the first check does.\n assertWindowOpenOrRetire()\n const header = await exact.evm.createPaymentHeader(\n account,\n paymentRequired.x402Version,\n requirements,\n )\n\n if (paymentRequired.x402Version < 2) {\n x402Bindings.delete(x402Binding)\n retireX402Binding(x402Binding, 'header_built')\n return { paymentHeader: header, accepted: option }\n }\n\n // Always delete the binding — even if encode/decode throws — to prevent the\n // in-process Map from accumulating stale X402ExpectedPayment entries (memory\n // leak + data-retention violation for user payment context).\n try {\n const payment = decodeBase64Json<{ payload: unknown }>(header)\n // #2361: the shared v2 envelope echoes the challenge's `resource` and\n // `extensions` verbatim when present — the extensions echo is a spec\n // MUST, and its absence was live-bisected as the CoinGecko rejection\n // cause (#2360). `paymentRequired` here is the caller's raw 402 JSON\n // (the tools layer passes it through unnormalized), so the echo is\n // byte-faithful to what the merchant advertised.\n const wrapped = encodeBase64Json(\n x402V2PaymentEnvelope(paymentRequired, option, payment.payload),\n )\n return { paymentHeader: wrapped, accepted: option }\n } finally {\n x402Bindings.delete(x402Binding)\n retireX402Binding(x402Binding, 'header_built')\n }\n },\n\n async signSweepAuthorization({\n authorization,\n expectedAuth,\n expectedSafe,\n }: SweepSignatureInput): Promise<SweepSignatureResult> {\n // 1. The authorization must have come from Haven (binding), so a malicious\n // hosted server can't get the delegate to sign a transfer to an attacker.\n assertSweepBinding(authorization, expectedAuth, options.x402BindingSigner)\n\n // 2. Funds can only leave the delegate's OWN key — that half is\n // unconditional. The DESTINATION half is not, and the difference\n // matters here more than anywhere else in this file (#2247):\n // `expectedSafe` is threaded from the local credential's account\n // address, so it is absent whenever no such address reaches this\n // process. Three ways that happens, all supported: `HAVEN_DELEGATE_KEY`\n // set without `HAVEN_ACCOUNT_ADDRESS` (the README quickstart — the\n // credential IS loaded here, it just carries no account address); a\n // credential file whose `account_address` (or the permanent\n // `safe_address` fallback) is null; or an embedder calling\n // `resolveEdgeSigner({ delegateKey })`, whose fast path returns before\n // credentials are read at all. With no local value there is nothing to\n // re-derive `to` against, so the destination rests entirely on Haven's\n // binding signature (step 1) plus the canonical-USDC token/chain\n // assertion (step 3): AUTHENTICATED, but not independently verified by\n // this signer. Supply the account address to get the local check.\n if (!sameAddress(authorization.from, delegateAddress)) {\n throw new HavenSigningError(\n 'Sweep authorization `from` does not match this delegate address.',\n )\n }\n if (expectedSafe && !sameAddress(authorization.to, expectedSafe)) {\n throw new HavenSigningError(\n \"Sweep authorization `to` does not match the agent's account (Haven wallet) in the local credential.\",\n )\n }\n\n // 3. Build the EIP-712 typed data (asserts token/chain are canonical USDC),\n // sign it locally, and verify the recovered signer is the delegate.\n const typedData = buildSweepTypedData(authorization)\n // The SDK keeps addresses framework-neutral (`string`); viem wants its\n // `0x`-branded template type. Narrow at the call boundary only.\n const viemTypedData = {\n domain: {\n ...typedData.domain,\n verifyingContract: typedData.domain.verifyingContract as `0x${string}`,\n },\n types: typedData.types,\n primaryType: typedData.primaryType,\n message: {\n ...typedData.message,\n from: typedData.message.from as `0x${string}`,\n to: typedData.message.to as `0x${string}`,\n nonce: typedData.message.nonce as `0x${string}`,\n },\n } as const\n const account = privateKeyToAccount(delegateKey as `0x${string}`)\n const signature = await account.signTypedData(viemTypedData)\n const recovered = await recoverTypedDataAddress({ ...viemTypedData, signature })\n if (!sameAddress(recovered, delegateAddress)) {\n throw new HavenSigningError(\n 'Local sweep signature verification failed — recovered address does not match the delegate key.',\n )\n }\n return { signature }\n },\n }\n}\n\n/**\n * Verify Haven signed the sweep authorization context. Mirrors\n * `assertExpectedBinding` for x402: re-derive the canonical message from the\n * authorization fields, require it match the binding, require the binding signer\n * be the trusted Haven address, and verify the signature. Reuses the x402\n * binding signer — the message namespace differs so the two can't cross-replay.\n */\nfunction assertSweepBinding(\n authorization: SweepAuthorization,\n expectedAuth: SweepExpectedAuth,\n trustedSigner: string | undefined,\n): void {\n if (!expectedAuth || typeof expectedAuth !== 'object') {\n throw new HavenSigningError('Sweep authorization binding is required before signing.')\n }\n if (!trustedSigner) {\n throw new HavenSigningError(\n 'Sweep binding verifier is not configured. Set HAVEN_X402_BINDING_SIGNER before signing sweep authorizations.',\n )\n }\n // Before any content comparison: an unrecognised version means we cannot\n // reason about this binding at all, so a mismatch below would be a symptom\n // reported as a cause (#1143).\n assertSupportedBindingVersion(\n expectedAuth.version,\n SUPPORTED_SWEEP_BINDING_VERSIONS,\n 'sweep authorization binding',\n )\n const message = buildSweepAuthorizationMessage(authorization)\n if (expectedAuth.message !== message) {\n throw new HavenSigningError('Sweep authorization binding does not match the authorization being signed.')\n }\n if (!sameAddress(expectedAuth.signer, trustedSigner)) {\n throw new HavenSigningError('Sweep authorization binding was not signed by the configured Haven signer.')\n }\n if (!verifySignature(hashMessage(message), expectedAuth.signature, trustedSigner)) {\n throw new HavenSigningError('Sweep authorization binding signature could not be verified.')\n }\n}\n\nexport function assertX402MatchesExpected(\n paymentRequired: X402PaymentRequired,\n option: X402PaymentOption,\n expected: X402ExpectedPayment,\n): void {\n assertExpectedShape(expected)\n const headerResource = option.resource ?? paymentRequired.resource.url\n if (headerResource !== expected.resourceUrl) {\n throw new HavenSigningError('x402 payment_required resource does not match the funded intent.')\n }\n if (!sameAddress(option.payTo, expected.merchantTo)) {\n throw new HavenSigningError('x402 merchant recipient does not match the funded intent.')\n }\n if (x402AuthorizationAmount(option) !== expected.amount) {\n throw new HavenSigningError('x402 amount does not match the funded intent.')\n }\n if (!sameAddress(option.asset, expected.asset)) {\n throw new HavenSigningError('x402 asset does not match the funded intent.')\n }\n if (option.network !== expected.network) {\n throw new HavenSigningError('x402 network does not match the funded intent.')\n }\n}\n\nfunction assertExpectedShape(expected: X402ExpectedPayment): void {\n if (!expected || typeof expected !== 'object') {\n throw new HavenSigningError('x402 expected funding context is required before signing a merchant header.')\n }\n}\n\n/**\n * Expected-context binding versions THIS signer understands (#1143).\n *\n * The backend deploys continuously from `dev`; a signer reaches users only on a\n * merge to `main` (the publish workflow). So a signer that is one release behind\n * a context bump is a structural state, not an accident, and it needs to report\n * itself as one. These sets are the signer's authority on what it will sign —\n * the tool schemas deliberately accept any positive integer so an unknown\n * version arrives *here* instead of dying at the schema boundary with a raw\n * validation string.\n *\n * **Adding a version here is not sufficient to support it.** The rules in\n * `assertExpectedBinding` derive the expected version from the context's\n * *contents* (`payerDelegate` present ⇒ 3, else 2 — `typedDataHash` is\n * required unconditionally, #3272), not from `auth.version`, so a v4 that\n * carries anything new needs that derivation extended in the same change.\n * Widening this array alone would admit a v4 context to the v2/v3 rule set:\n * the array announces what this signer can evaluate, it does not define it.\n */\nexport const SUPPORTED_X402_EXPECTED_VERSIONS: readonly number[] = [2, 3]\nexport const SUPPORTED_SWEEP_BINDING_VERSIONS: readonly number[] = [1]\n\n/**\n * Fail closed on a binding version this signer does not understand, with an\n * error that names the received version, the ceiling this signer supports, and\n * the fix — both as PROSE (`message`, unchanged since #1143) and, since #1309,\n * as MACHINE-READABLE fields on the thrown error itself\n * (`HavenUnsupportedSignerVersionError`): `code`, `supportedVersions`,\n * `receivedVersion`, `fallback`. The tool boundary (`normalizeError` in\n * `tools.ts`) relays those fields verbatim instead of leaving an agent to\n * regex-parse this prose, which is the diagnosability gap\n * `docs/operations/mcp-runtime-compatibility.md` documents.\n *\n * `supportedVersions`/`receivedVersion` are DERIVED from this call's own\n * arguments — never a second literal — so they cannot drift from\n * `SUPPORTED_X402_EXPECTED_VERSIONS` / `SUPPORTED_SWEEP_BINDING_VERSIONS`,\n * which is what the signing path always passes in.\n *\n * The version travels inside the Haven-signed binding message, so the message\n * also tells the caller not to \"fix\" it by rewriting the field — an agent that\n * does would invalidate the signature and misrepresent what Haven declared.\n * That instruction is NOT weakened by structuring the refusal: this function\n * still throws before any content check runs, and nothing is ever signed.\n *\n * #2347: that word was \"authorised\" until this change, and the reading was\n * always the correct one — Haven does sign this message. It is now \"declared\",\n * the word the settlement-child verifier (`@haven_ai/sdk`'s `settlement-child.ts`) already uses for this exact binding (\"proves\n * Haven *declared* a payload … it says nothing about what the payload MEANS\"),\n * because on an agent-facing refusal inside a payment flow the broader word\n * invites the #2334 misreading that Haven is what authorises the spend. It is\n * not; the owner-signed delegation and its on-chain caveat are. The property\n * claimed is unchanged — only the verb naming it. Full argument in\n * `docs/regulatory/casp-changelog/2026-09-01-2347.md`.\n *\n * Exported so a test can pin the historical case (a v2 context against a signer\n * whose set was `{1}`) that this signer can no longer produce on its own. The\n * signing path always passes the module constants above.\n */\nexport function assertSupportedBindingVersion(\n received: number,\n supported: readonly number[],\n context: 'x402 expected context' | 'sweep authorization binding',\n): void {\n if (supported.includes(received)) return\n const highest = Math.max(...supported)\n // The else-branch (\"updating will not restore it\") assumes versions retire\n // MONOTONICALLY from the oldest end — true for how SUPPORTED_* is maintained\n // (append new, drop old). If a future change ever makes the supported set\n // non-contiguous, a gap version would hit that branch and the wording needs\n // revisiting (#1322 review).\n const outOfDate = received > highest\n const code =\n context === 'x402 expected context'\n ? SignerRefusalCode.UnsupportedExpectedContextVersion\n : SignerRefusalCode.UnsupportedSweepBindingVersion\n const ceiling = outOfDate\n ? `This signer is out of date: it supports ${context} versions up to ${highest}, ` +\n `and Haven sent version ${received}. Update @haven_ai/signer — rerun the Haven ` +\n `connector (\\`${connectorRerunCommand()}\\`), which reinstalls the pinned MCP runtime.`\n : `Unsupported ${context} version ${received}: this signer supports ` +\n `${supported.join(', ')}.`\n // Below-floor is the opposite skew (this signer is NEWER than what sent the\n // context, e.g. a retired version) — updating cannot fix it, so the shared\n // \"update the signer\" fallback would be actively wrong here. Only the\n // out-of-date branch, which is the case seen in the field (#1143), uses the\n // canonical single-source fallback shared with the hosted quote's advisory\n // signer_compatibility.fallback (#1155, #1309).\n const fallback = outOfDate\n ? SIGNER_UPDATE_FALLBACK\n : `This ${context} version (${received}) is older than what this signer enforces ` +\n `(${supported.join(', ')}) — updating @haven_ai/signer will not restore it. Nothing ` +\n 'was signed or spent; stop and tell the user rather than retrying.'\n throw new HavenUnsupportedSignerVersionError(\n `${ceiling} Nothing was signed. Do not rewrite the version field to a supported ` +\n 'value: it is part of the Haven-signed binding message, so changing it invalidates ' +\n 'the signature and would misrepresent what Haven declared.',\n code,\n supported,\n received,\n fallback,\n )\n}\n\n/**\n * Verify Haven's expected-context binding before signing x402 funding typed\n * data. Every x402 funding intent is now delegation-rail (#3272, criterion\n * 8): the bare-hash v1 context and its raw-ECDSA signing path are retired —\n * `SUPPORTED_X402_EXPECTED_VERSIONS` no longer admits version 1, so a v1\n * context (no `typedDataHash`) is refused below by the version-skew check,\n * exactly like any other version this signer no longer understands.\n *\n * `typedDataDigest` is the EIP-712 digest of the typed data ABOUT TO BE\n * SIGNED, recomputed by the caller from the actual bytes in hand — never a\n * value taken from `expected` itself. That equality is what makes the\n * binding cover the bytes being signed, rather than a hash that merely\n * travels alongside them. (#3272: this parameter used to be\n * `expected.payloadHash`, compared with itself — redundant, because the\n * digest-equality check that bound the typed data ran separately in\n * `signX402FundingTypedData`; that check now lives here.)\n *\n * The version is derived from the context inside `buildX402ExpectedMessage`, so\n * a tampered `auth.version` cannot select a different rule than the signed\n * message encodes: the recomputed message simply stops matching.\n */\nfunction assertExpectedBinding(\n typedDataDigest: string,\n expected: X402ExpectedPayment,\n trustedSigner: string | undefined,\n): void {\n assertExpectedShape(expected)\n if (!trustedSigner) {\n throw new HavenSigningError(\n 'x402 expected-context verifier is not configured. Set HAVEN_X402_BINDING_SIGNER before signing x402 funding payloads.',\n )\n }\n // Skew check first (#1143). Every content check below — the digest\n // comparison, the recomputed message — assumes we understand the context's\n // shape. Under an unknown version they are symptoms, and reporting one as the\n // cause is what sent a live debugging session after the wrong string. A missing\n // `auth` is left to the message check below, which already fails closed on it.\n // A v1 context (no `typedDataHash`, `auth.version` 1) is refused HERE, not by\n // a separate check: 1 is no longer in `SUPPORTED_X402_EXPECTED_VERSIONS`.\n if (expected.auth) {\n assertSupportedBindingVersion(\n expected.auth.version,\n SUPPORTED_X402_EXPECTED_VERSIONS,\n 'x402 expected context',\n )\n }\n if (!expected.typedDataHash) {\n throw new HavenSigningError(\n 'Refusing to sign typed data under an expected context that does not commit to it. ' +\n 'Haven must return a v2/v3 x402 expected context (with typedDataHash) for a ' +\n 'delegation-rail intent.',\n )\n }\n if (expected.typedDataHash.toLowerCase() !== typedDataDigest.toLowerCase()) {\n throw new HavenSigningError(\n 'x402 typed data does not match the digest Haven committed to in the expected context. ' +\n 'Refusing to sign — the payload was altered in transit or Haven declared a different one. ' +\n 'The most common cause is the typed data being truncated or reshaped while being copied ' +\n 'between tool calls (#1255): re-run the hosted quote and pass its typed_data_b64 string ' +\n 'through UNCHANGED instead of re-emitting the nested JSON.',\n )\n }\n const message = buildX402ExpectedMessage({\n paymentId: expected.paymentId,\n payloadHash: expected.payloadHash,\n resourceUrl: expected.resourceUrl,\n merchantTo: expected.merchantTo,\n amount: expected.amount,\n asset: expected.asset,\n network: expected.network,\n expiresAt: expected.expiresAt,\n typedDataHash: expected.typedDataHash,\n payerDelegate: expected.payerDelegate,\n payerAgentId: expected.payerAgentId,\n })\n // Contents-derived, mirroring the builder (#1138, #1690): a tampered\n // auth.version cannot select a different rule than the signed message\n // encodes — the recomputed message simply stops matching. No `: 1` branch:\n // `expected.typedDataHash` is unconditionally required above (#3272 —\n // v1 is retired), so it is always truthy by this line.\n const expectedVersion = expected.payerDelegate ? 3 : 2\n if (expected.auth?.version !== expectedVersion || expected.auth.message !== message) {\n throw new HavenSigningError('x402 expected context authentication message is invalid.')\n }\n if (!sameAddress(expected.auth.signer, trustedSigner)) {\n throw new HavenSigningError('x402 expected context was not signed by the configured Haven signer.')\n }\n if (!verifySignature(hashMessage(message), expected.auth.signature, trustedSigner)) {\n throw new HavenSigningError('x402 expected context signature could not be verified.')\n }\n}\n\n/**\n * Refuse to sign another agent's quote (#1690), mirroring the sweep guard's\n * `authorization.from` check.\n *\n * Runs only AFTER `assertExpectedBinding` has verified the Haven signature —\n * an unverified payer claim is attacker input, and refusing on it would let a\n * forged context turn the guard into a denial-of-service. And only when the\n * context CARRIES a payer claim: a v1/v2 context claims nothing, so there is\n * nothing to mismatch (the characterization suite pins that).\n *\n * The message is the point. A payer mismatch in the field means a long-lived\n * host cached one agent's wiring while the disk holds another's (#1681), and\n * before this guard the operator discovered that as an on-chain revert three\n * layers later. Naming both identities IS the diagnosis.\n */\nfunction assertPayerMatchesDelegate(\n expected: X402ExpectedPayment,\n delegateAddress: string,\n localAgentId: string | undefined,\n): void {\n if (!expected.payerDelegate) return\n if (sameAddress(expected.payerDelegate, delegateAddress)) return\n const quoteAgent = expected.payerAgentId ?? 'unknown'\n const localAgent = localAgentId ?? 'unknown'\n throw new HavenSigningError(\n `This quote belongs to a DIFFERENT agent: the quote was created for agent ${quoteAgent} ` +\n `(delegate ${expected.payerDelegate}), but this signer holds agent ${localAgent} ` +\n `(delegate ${delegateAddress}). A long-lived host is holding stale credentials — its ` +\n 'session authenticates as the old agent while the signer on disk belongs to the new ' +\n 'one. Nothing was signed. Restart the host so it re-reads its wiring, then re-quote.',\n )\n}\n\n/** #3173: lazy, and a load failure is a HavenSigningError with the connector-doctor remedy. */\nexport async function loadX402Schemes(): Promise<typeof import('x402/schemes')> {\n try {\n return await import('x402/schemes')\n } catch (err) {\n throw new HavenSigningError(\n 'The x402 scheme module could not be loaded, so no merchant header was built (nothing was ' +\n `sent to the merchant): ${err instanceof Error ? err.message : String(err)}. The signer's ` +\n 'runtime install is incomplete — run: npx @haven_ai/connect --doctor',\n )\n }\n}\n\nfunction assertX402PaymentWindowOpen(expected: X402ExpectedPayment): void {\n if (!expected.expiresAt) return\n const expiresAtMs = Date.parse(expected.expiresAt)\n if (Number.isNaN(expiresAtMs)) {\n throw new HavenSigningError('x402 expected context expiresAt is not a valid ISO timestamp.')\n }\n if (expiresAtMs <= Date.now()) {\n throw new HavenError(\n 'The x402 payment window expired before the merchant header could be signed. Re-quote with haven_pay_mcp_tool using the same idempotency_key before trying again.',\n AgentPaymentFailureCode.PaymentWindowExpired,\n 410,\n expected.paymentId,\n )\n }\n}\n\nfunction sameAddress(a: string, b: string): boolean {\n return a.toLowerCase() === b.toLowerCase()\n}\n","import { createNextStepBuilder, type NextStep, type NextStepHandoff, type NextStepTarget } from '@haven_ai/sdk/edge'\nimport { z } from 'zod'\n\n/**\n * #3103 (epic #3105, slice 4/5): the signer's typed next step.\n *\n * The signer decides a `next_action` on its refusals and, until this module,\n * never said which tool to call. It cannot know the client's server names\n * (#2550), so the handoff is expressed through the role fields the SDK\n * builder renders — `next_tool_server_role: hosted`, `next_tool_name` — from\n * a bare tool name. The signer must not import the hosted server (it is an\n * npm package installed on user machines; the hosted server is a Docker\n * deployment), so the hosted tools it hands off to are DECLARED here as the\n * argument shape the signer actually emits, and `next-step-signer-parity`\n * in the hosted server's own suite pins them to the hosted schemas at test\n * time — the mirror of how the hosted server declares the signer's shapes.\n */\nexport const SIGNER_HOSTED_HANDOFF_SHAPES = {\n haven_get_payment_status: { payment_id: z.string().min(1) },\n} as const satisfies Record<string, z.ZodRawShape>\n\nfunction target<S extends z.ZodRawShape>(shape: S): NextStepTarget<z.input<z.ZodObject<S>>> {\n const schema = z.object(shape).strict()\n return {\n role: 'hosted',\n validate: (input) => {\n const r = schema.safeParse(input ?? {})\n return r.success ? null : r.error.errors.map((e) => `${e.path.join('.') || '(root)'}: ${e.message}`).join('; ')\n },\n }\n}\n\nconst SIGNER_NEXT_STEP_TARGETS = {\n haven_get_payment_status: target(SIGNER_HOSTED_HANDOFF_SHAPES.haven_get_payment_status),\n}\nexport type SignerNextStepTargets = typeof SIGNER_NEXT_STEP_TARGETS\nexport type SignerHandoff = NextStepHandoff<SignerNextStepTargets>\n\nconst nextStep = createNextStepBuilder(SIGNER_NEXT_STEP_TARGETS)\n\n/** A signer refusal's next step: a hosted tool with arguments it declares, or `null` + the reason. */\nexport function signerRefusalStep(input: { nextAction: NextStep['next_action'] } & SignerHandoff): NextStep {\n return nextStep({ ...input, safeToContinue: false, reason: '' } as Parameters<typeof nextStep>[0])\n}\n\n/** The `next_tool` family of a step, for the failure envelope (additive; `next_tool` never null). */\nexport function nextStepWireFields(step: NextStep): {\n next_tool?: string\n next_tool_server?: string\n next_tool_name?: string\n next_tool_server_role?: 'hosted' | 'signer'\n next_arguments?: Record<string, unknown>\n next_tool_omitted_reason?: string\n} {\n return {\n ...(step.next_tool ? { next_tool: step.next_tool } : {}),\n ...(step.next_tool_server ? { next_tool_server: step.next_tool_server } : {}),\n ...(step.next_tool_name ? { next_tool_name: step.next_tool_name } : {}),\n ...(step.next_tool_server_role ? { next_tool_server_role: step.next_tool_server_role } : {}),\n ...(step.next_arguments ? { next_arguments: step.next_arguments } : {}),\n ...(step.next_tool_omitted_reason ? { next_tool_omitted_reason: step.next_tool_omitted_reason } : {}),\n }\n}\n","/**\n * Byte-free signing handoff (#1263): fetch a delegation-rail x402 intent's\n * EXACT signing payload from Haven by `payment_id`, instead of asking a\n * language model to re-emit multi-KB EIP-712 bytes between tool calls (the\n * #1255 failure mode — runtimes that elide long tool results structurally\n * cannot copy them).\n *\n * Layering: this module lives in the local MCP SERVER layer, not the signer\n * core. The core (`core.ts`) remains pure and network-free; what it signs\n * still goes through the SAME digest re-derivation and Haven-binding\n * verification (#1138) whether the bytes arrived by tool argument or by this\n * fetch. The fetch is a strictly better byte source than model relay — TLS to\n * Haven versus a model's context window — and it uses the agent credential\n * (`identity.json`) the connector already stores next to the signer\n * credential. The delegate key is never sent anywhere.\n */\nimport { readFile } from 'node:fs/promises'\nimport { dirname, join } from 'node:path'\nimport {\n AgentPaymentNextAction,\n DIRECT_SIGN_CONTEXT_VERSION,\n HAVEN_CLIENT_HEADER,\n HavenSigningError,\n readClientUpdate,\n} from '@haven_ai/sdk/edge'\nimport type { HavenClientUpdate, NextStep } from '@haven_ai/sdk/edge'\nimport { nextStepWireFields, signerRefusalStep } from './next-step.js'\n\nexport interface HavenIdentity {\n apiUrl: string\n apiKey: string\n}\n\n/**\n * Signer-local refusal codes for `fetchX402SignContext` (#3001). Distinct from\n * `AgentPaymentFailureCode` on purpose — these describe a signing-context FETCH\n * failure (network/timeout/backend-refusal/shape), never a payment-domain\n * outcome, and they never reach the backend's REST/OpenAPI surface, only this\n * package's MCP tool responses. Same reasoning `SignerRefusalCode` documents\n * for the version-mismatch pair.\n */\nexport type SignContextErrorCode =\n | 'SIGN_CONTEXT_TIMEOUT'\n | 'SIGN_CONTEXT_UNREACHABLE'\n | 'SIGN_CONTEXT_REFUSED'\n | 'SIGN_CONTEXT_MALFORMED'\n\n/**\n * Structured refusal for every throw site in `fetchX402SignContext` (#3001,\n * and since #3271 `fetchDirectSignContext`, via the `flow` argument;\n * follow-up from the #2985/#2986 review). Before this, every one of these —\n * timeout, unreachable host, a non-ok backend response (404/410/…), a\n * malformed body — reached the wire as prose inside the generic\n * `{ code: 'SIGNING_ERROR' }` `HavenSigningError` produces, so an agent had to\n * parse a sentence to learn \"pass typed_data_b64 instead\". The version-mismatch\n * refusal (`HavenUnsupportedSignerVersionError`) already carries `code`,\n * `fallback`, `next_action` as DATA; this mirrors that shape for the\n * sign-context fetch.\n *\n * Extends `HavenSigningError` so every existing `instanceof HavenSigningError`\n * catch site keeps matching unchanged. `code` is inherited as `readonly` from\n * `HavenError` and hard-coded to `'SIGNING_ERROR'` by `HavenSigningError`'s own\n * constructor — TypeScript only lets the class that DECLARES a readonly\n * property assign it, so the override below goes through a narrow cast rather\n * than widening `HavenSigningError`'s constructor (these codes are\n * signer-local, not part of the shared `@haven_ai/sdk` error taxonomy, so that\n * type does not belong there).\n */\n/** #3271: the relay remedy for a direct payment whose sign-context fetch failed. */\nconst DIRECT_RELAY_FALLBACK =\n 'call haven_sign with payload_hash and typed_data_b64 from the haven_send / haven_pay result, passed through unchanged'\n\nexport class HavenSignContextError extends HavenSigningError {\n declare readonly code: SignContextErrorCode\n /**\n * #3001 / #3010 review: the recovery path, when signing OTHER bytes is\n * actually a remedy — a transport failure (timeout, unreachable) or a\n * body this signer could not read. `typed_data_b64` is NOT in the default\n * quote result since #1272: obtain it by re-running the SAME quote tool\n * with the SAME idempotency_key plus `include_signing_payload: true`.\n * Absent on a backend REFUSAL (an expired, executed or unsignable intent\n * cannot be rescued by re-signing its bytes) — with one #3271 exception: a\n * 404 from the DIRECT fetch (an older backend with no direct route), where\n * the `haven_send` / `haven_pay` result's relay fields still work.\n */\n readonly fallback?: 'typed_data_b64'\n /**\n * #3001: `AgentPaymentNextAction` values the signer already emits — the\n * version-mismatch refusal's `stop_and_tell_user` for the classes where\n * retrying the same call cannot help, and `payment_window_expired` (with\n * `retry_with_new_quote`) for the x402 fetch's 410 / `expired`, exactly as\n * the plain `HavenError` branch already does for that code. On the direct\n * fetch (#3271) only `error_code: 'expired'` means an expired window, with\n * no `retry_with_new_quote`; a bare 410 there is a retired-rail tombstone.\n */\n readonly next_action: string\n /**\n * #3103 (epic #3105, decisions 1 and 3): the typed next step beside the\n * action. A refusal Haven made (`SIGN_CONTEXT_REFUSED`, not expired) names\n * the hosted status read with the payment id — except a 404 from the direct\n * fetch (#3271), which names none and points at the `typed_data_b64`\n * relay; a transport failure or a\n * malformed body names no tool — the remedy is re-running the SAME quote\n * tool with `include_signing_payload: true` (x402), or the payment\n * result's `typed_data_b64` relay (direct, #3271) — and an expired window names\n * none either (which quote tool depends on the flow). Never null: a step\n * with no tool carries `next_tool_omitted_reason`. Additive: the class is\n * not exported from the package index — the published surface is the\n * `ToolFailure` envelope `tools.ts` builds from these fields — and every\n * constructor call site is in this file.\n */\n readonly next_tool?: string\n readonly next_tool_server?: string\n readonly next_tool_name?: string\n readonly next_tool_server_role?: 'hosted' | 'signer'\n readonly next_arguments?: Record<string, unknown>\n readonly next_tool_omitted_reason?: string\n readonly retry_with_new_quote?: true\n /** Present only for `SIGN_CONTEXT_REFUSED` (the backend's HTTP status). */\n readonly http_status?: number\n /** Present only for `SIGN_CONTEXT_REFUSED`: the backend's own `error_code`. */\n readonly backend_error_code?: string\n /**\n * #3303: on a 426 `client_outdated` refusal, the backend's update hint —\n * this signer is below the minimum the deployment set, and\n * `client_update.upgrade_command` is what updates it.\n */\n readonly client_update?: HavenClientUpdate\n\n constructor(\n message: string,\n code: SignContextErrorCode,\n refusal: { httpStatus: number; errorCode?: string; clientUpdate?: HavenClientUpdate } | undefined,\n /** #3103: the payment the context was fetched for, so a refusal can name the status read. */\n paymentId: string,\n /**\n * #3271: which fetch failed. A DIRECT payment has no quote tool to re-run\n * and its result always carries `typed_data_b64`, so its remedies differ.\n */\n flow: 'x402' | 'direct' = 'x402',\n ) {\n super(message)\n ;(this as { code: string }).code = code\n this.name = 'HavenSignContextError'\n let step: NextStep\n if (code === 'SIGN_CONTEXT_REFUSED') {\n this.http_status = refusal?.httpStatus\n this.backend_error_code = refusal?.errorCode\n if (refusal?.errorCode === 'client_outdated') {\n // #3303: this signer is below the minimum the deployment set, so it is\n // refused at sign-context — nothing is signed or submitted, and the\n // prepared payment is left unsigned (owner decision 2026-09-25, #3303).\n // No retry and no other bytes can help; only an update can.\n this.client_update = refusal.clientUpdate\n this.next_action = AgentPaymentNextAction.StopAndTellUser\n step = signerRefusalStep({\n nextAction: AgentPaymentNextAction.StopAndTellUser,\n nextTool: null,\n nextToolOmittedReason:\n 'this signer is below the minimum version Haven accepts — tell the user to run ' +\n `${refusal.clientUpdate?.upgrade_command ?? 'the connector again'}, restart the agent runtime, ` +\n 'then retry the same haven_sign / haven_sign_x402 call',\n })\n } else if (flow === 'direct' && refusal?.httpStatus === 404) {\n // Either the payment is not this agent's, or the backend predates\n // #3271 and has no direct sign-context route at all (deploy skew). The\n // payment result's relay fields still work whenever the payment is real.\n this.fallback = 'typed_data_b64'\n this.next_action = AgentPaymentNextAction.StopAndTellUser\n step = signerRefusalStep({\n nextAction: AgentPaymentNextAction.StopAndTellUser,\n nextTool: null,\n nextToolOmittedReason: DIRECT_RELAY_FALLBACK,\n })\n } else if (flow === 'direct' && refusal?.errorCode === 'expired') {\n // Keyed on the backend's `expired` code, never a bare 410: the direct\n // route also answers 410 for a retired-rail row (no error_code), and a\n // re-send cannot help there, so that falls through to stop-and-tell.\n this.next_action = AgentPaymentNextAction.PaymentWindowExpired\n step = signerRefusalStep({\n nextAction: AgentPaymentNextAction.PaymentWindowExpired,\n nextTool: null,\n nextToolOmittedReason:\n 'call haven_send / haven_pay again with the same idempotency_key — the expired payment frees it',\n })\n } else if (flow === 'x402' && (refusal?.httpStatus === 410 || refusal?.errorCode === 'expired')) {\n this.next_action = AgentPaymentNextAction.PaymentWindowExpired\n this.retry_with_new_quote = true\n step = signerRefusalStep({\n nextAction: AgentPaymentNextAction.PaymentWindowExpired,\n nextTool: null,\n nextToolOmittedReason:\n 're-run the hosted quote tool you called with the same idempotency_key; which one depends on the flow',\n })\n } else {\n this.next_action = AgentPaymentNextAction.StopAndTellUser\n step = signerRefusalStep({\n nextAction: AgentPaymentNextAction.StopAndTellUser,\n nextTool: 'haven_get_payment_status',\n nextArguments: { payment_id: paymentId },\n })\n }\n } else {\n this.fallback = 'typed_data_b64'\n this.next_action = AgentPaymentNextAction.StopAndTellUser\n step = signerRefusalStep({\n nextAction: AgentPaymentNextAction.StopAndTellUser,\n nextTool: null,\n nextToolOmittedReason:\n flow === 'direct'\n ? DIRECT_RELAY_FALLBACK\n : 're-run the SAME hosted quote tool with the same idempotency_key and include_signing_payload: true, then pass its typed_data_b64 to this signer',\n })\n }\n Object.assign(this, nextStepWireFields(step))\n }\n}\n\n/**\n * Resolve the agent identity from `identity.json` in the same directory as\n * the signer credential file. Returns null (never throws) when unavailable —\n * the caller decides how to phrase the fallback.\n */\nexport async function loadHavenIdentity(\n credentialsPath: string | undefined,\n): Promise<HavenIdentity | null> {\n if (!credentialsPath) return null\n try {\n const raw = JSON.parse(\n await readFile(join(dirname(credentialsPath), 'identity.json'), 'utf8'),\n ) as Record<string, unknown>\n const apiKey = typeof raw.api_key === 'string' ? raw.api_key : undefined\n const apiUrl = typeof raw.api_url === 'string' ? raw.api_url : undefined\n if (!apiKey || !apiUrl) return null\n return { apiKey, apiUrl: apiUrl.replace(/\\/+$/, '') }\n } catch {\n return null\n }\n}\n\nexport interface FetchedSignContext {\n paymentId: string\n payloadHash: string\n typedData: Record<string, unknown>\n /** The COMPLETE snake_case expected context, verbatim from Haven. */\n x402Expected: Record<string, unknown>\n /**\n * #1355: the 402 PaymentRequired persisted at authorize time, when the\n * backend carries it — lets haven_sign_x402 build the merchant header from\n * `{ payment_id }` alone. Null on pre-#1355 backends/rows; the caller then\n * requires the agent-supplied copy. Untrusted like every other fetched\n * field: header building verifies it against the Haven-signed expected\n * context either way.\n */\n paymentRequired: Record<string, unknown> | null\n /** #3303: the backend's update hint when this signer is behind; absent when current. */\n clientUpdate?: HavenClientUpdate\n}\n\n/**\n * GET /x402/:id/sign-context. Read-only; refusals from the backend\n * (expired/executed/legacy/unknown) surface as clear signing errors that name\n * the next step. The returned payload is UNTRUSTED input exactly like a tool\n * argument would be — the signing path's binding verification and digest\n * equality are what make it safe to use, not its provenance.\n */\n/**\n * #2985: the signer's network calls (the x402 and, since #3271, the direct\n * sign-context reads) are bounded. Without a signal a hung\n * `/sign-context` (half-open connection, stalled backend) hung the signer\n * tool call — and so the agent — indefinitely while the funding window ran\n * out, and the `typed_data_b64` fallback the error names was unreachable\n * because the call never returned. 15 s is generous for a single\n * authenticated read and sits well under the 60 s floor of the x402\n * settlement window (`clamp(maxTimeoutSeconds, 60, 600)` backend-side).\n */\nexport const SIGN_CONTEXT_TIMEOUT_MS = 15_000\n\n/**\n * The sign-context request headers. `clientIdentity` is this signer's\n * `@haven_ai/signer/<version>` (#3303), passed in by the server that owns\n * `SIGNER_VERSION` — the backend refuses a signer below a minimum it has set,\n * here and nowhere else.\n */\nfunction signContextHeaders(identity: HavenIdentity, clientIdentity: string | undefined): Record<string, string> {\n return {\n Authorization: `Bearer ${identity.apiKey}`,\n ...(clientIdentity ? { [HAVEN_CLIENT_HEADER]: clientIdentity } : {}),\n }\n}\n\n/** #3303: the refusal fields a backend answer carries, `client_update` included. */\nfunction refusalOf(status: number, body: Record<string, unknown>) {\n return {\n httpStatus: status,\n errorCode: typeof body.error_code === 'string' ? body.error_code : undefined,\n clientUpdate: readClientUpdate(body.client_update),\n }\n}\n\nexport async function fetchX402SignContext(\n identity: HavenIdentity,\n paymentId: string,\n fetchImpl: typeof fetch = fetch,\n timeoutMs: number = SIGN_CONTEXT_TIMEOUT_MS,\n clientIdentity?: string,\n): Promise<FetchedSignContext> {\n let response: Response\n try {\n response = await fetchImpl(\n `${identity.apiUrl}/x402/${encodeURIComponent(paymentId)}/sign-context`,\n {\n headers: signContextHeaders(identity, clientIdentity),\n signal: AbortSignal.timeout(timeoutMs),\n },\n )\n } catch (err) {\n const timedOut = err instanceof Error && (err.name === 'TimeoutError' || err.name === 'AbortError')\n throw new HavenSignContextError(\n timedOut\n ? `Haven did not answer the signing-context fetch for ${paymentId} within ${timeoutMs} ms. ` +\n 'Retry, or pass typed_data_b64 from the quote result instead.'\n : `Could not reach Haven to fetch the signing context for ${paymentId}: ` +\n `${err instanceof Error ? err.message : String(err)}. ` +\n 'Retry, or pass typed_data_b64 from the quote result instead.',\n timedOut ? 'SIGN_CONTEXT_TIMEOUT' : 'SIGN_CONTEXT_UNREACHABLE',\n undefined,\n paymentId,\n )\n }\n // #2985 review: the same signal bounds the BODY read. A stalled body used\n // to be swallowed by the `.catch(() => ({}))` and misdiagnosed as a\n // malformed/older backend response — name the timeout instead.\n let body: Record<string, unknown>\n try {\n body = (await response.json()) as Record<string, unknown>\n } catch (err) {\n if (err instanceof Error && (err.name === 'TimeoutError' || err.name === 'AbortError')) {\n throw new HavenSignContextError(\n `Haven did not finish sending the signing context for ${paymentId} within ${timeoutMs} ms. ` +\n 'Retry, or pass typed_data_b64 from the quote result instead.',\n 'SIGN_CONTEXT_TIMEOUT',\n undefined,\n paymentId,\n )\n }\n body = {}\n }\n if (!response.ok) {\n const detail =\n typeof body.error === 'string' ? body.error : `HTTP ${response.status}`\n throw new HavenSignContextError(\n `Haven refused the signing-context fetch for ${paymentId}: ${detail}` +\n (response.status === 404\n ? ' — check the payment_id came from this agent’s own quote.'\n : response.status === 410\n ? ' Re-run the quote with the same idempotency key, then sign the fresh payment_id.'\n : ''),\n 'SIGN_CONTEXT_REFUSED',\n refusalOf(response.status, body),\n paymentId,\n )\n }\n const signData = body.sign_data as Record<string, unknown> | undefined\n const x402Expected = body.x402_expected as Record<string, unknown> | undefined\n if (\n !signData ||\n typeof signData.hash !== 'string' ||\n !signData.typed_data ||\n typeof signData.typed_data !== 'object' ||\n !x402Expected\n ) {\n throw new HavenSignContextError(\n 'The Haven sign-context response is missing sign_data.typed_data or x402_expected — ' +\n 'the backend may predate #1263. Pass typed_data_b64 from the quote result instead.',\n 'SIGN_CONTEXT_MALFORMED',\n undefined,\n paymentId,\n )\n }\n const paymentRequired = body.payment_required\n return {\n paymentId: String(body.payment_id ?? paymentId),\n payloadHash: signData.hash,\n typedData: signData.typed_data as Record<string, unknown>,\n x402Expected,\n paymentRequired:\n paymentRequired && typeof paymentRequired === 'object' && !Array.isArray(paymentRequired)\n ? (paymentRequired as Record<string, unknown>)\n : null,\n clientUpdate: readClientUpdate(body.client_update),\n }\n}\n\n/**\n * #3271: `direct_sign_context_version`s this signer install understands.\n * Derived from the SDK's `DIRECT_SIGN_CONTEXT_VERSION` — never a second\n * hand-maintained literal, exactly like `SUPPORTED_X402_EXPECTED_VERSIONS`\n * mirrors `core.ts`'s enforcement of the x402 versions.\n */\nexport const SUPPORTED_DIRECT_SIGN_CONTEXT_VERSIONS: readonly number[] = [DIRECT_SIGN_CONTEXT_VERSION]\n\n/**\n * The direct-payment counterpart of `FetchedSignContext`: a `POST /payments`\n * (`haven_send` / `haven_pay`) signing payload fetched by `payment_id`, with\n * no x402 expected context — the account is validating its OWN\n * `PackedUserOperation`, not a grant to a third party.\n */\nexport interface FetchedDirectSignContext {\n paymentId: string\n payloadHash: string\n typedData: Record<string, unknown>\n status: string\n expiresAt?: string\n /** #3303: the backend's update hint when this signer is behind; absent when current. */\n clientUpdate?: HavenClientUpdate\n}\n\n/**\n * GET /payments/:id/sign-context (#3271). The direct-payment sibling of\n * `fetchX402SignContext` — same auth header, same timeout, same\n * refusal-structuring — for a payment that carries no x402 context at all.\n * `resolveSignContext` in `tools.ts` calls this ONLY after\n * `fetchX402SignContext` refuses with the backend's 409\n * `sign_context_unavailable`, so `haven_sign_x402` (which never falls back)\n * cannot reach it.\n */\nexport async function fetchDirectSignContext(\n identity: HavenIdentity,\n paymentId: string,\n fetchImpl: typeof fetch = fetch,\n timeoutMs: number = SIGN_CONTEXT_TIMEOUT_MS,\n clientIdentity?: string,\n): Promise<FetchedDirectSignContext> {\n let response: Response\n try {\n response = await fetchImpl(\n `${identity.apiUrl}/payments/${encodeURIComponent(paymentId)}/sign-context`,\n {\n headers: signContextHeaders(identity, clientIdentity),\n signal: AbortSignal.timeout(timeoutMs),\n },\n )\n } catch (err) {\n const timedOut = err instanceof Error && (err.name === 'TimeoutError' || err.name === 'AbortError')\n throw new HavenSignContextError(\n timedOut\n ? `Haven did not answer the direct-payment signing-context fetch for ${paymentId} within ${timeoutMs} ms. ` +\n 'Retry, or pass typed_data_b64 from the payment result instead.'\n : `Could not reach Haven to fetch the direct-payment signing context for ${paymentId}: ` +\n `${err instanceof Error ? err.message : String(err)}. ` +\n 'Retry, or pass typed_data_b64 from the payment result instead.',\n timedOut ? 'SIGN_CONTEXT_TIMEOUT' : 'SIGN_CONTEXT_UNREACHABLE',\n undefined,\n paymentId,\n 'direct',\n )\n }\n let body: Record<string, unknown>\n try {\n body = (await response.json()) as Record<string, unknown>\n } catch (err) {\n if (err instanceof Error && (err.name === 'TimeoutError' || err.name === 'AbortError')) {\n throw new HavenSignContextError(\n `Haven did not finish sending the direct-payment signing context for ${paymentId} within ${timeoutMs} ms. ` +\n 'Retry, or pass typed_data_b64 from the payment result instead.',\n 'SIGN_CONTEXT_TIMEOUT',\n undefined,\n paymentId,\n 'direct',\n )\n }\n body = {}\n }\n if (!response.ok) {\n const detail =\n typeof body.error === 'string' ? body.error : `HTTP ${response.status}`\n throw new HavenSignContextError(\n `Haven refused the direct-payment signing-context fetch for ${paymentId}: ${detail}` +\n (response.status === 404\n ? ' — either the payment_id is not from this agent’s own POST /payments call, or this ' +\n 'Haven backend predates #3271. Pass payload_hash and typed_data_b64 from the ' +\n 'haven_send / haven_pay result, unchanged, instead.'\n : body.error_code === 'expired'\n ? ' The payment window has expired; call haven_send / haven_pay again with the same idempotency_key.'\n : ''),\n 'SIGN_CONTEXT_REFUSED',\n refusalOf(response.status, body),\n paymentId,\n 'direct',\n )\n }\n const signData = body.sign_data as Record<string, unknown> | undefined\n const version = body.direct_sign_context_version\n if (\n !signData ||\n typeof signData.hash !== 'string' ||\n !signData.typed_data ||\n typeof signData.typed_data !== 'object' ||\n signData.signature_scheme !== 'eip712_userop' ||\n typeof version !== 'number' ||\n !SUPPORTED_DIRECT_SIGN_CONTEXT_VERSIONS.includes(version)\n ) {\n throw new HavenSignContextError(\n typeof version === 'number' && !SUPPORTED_DIRECT_SIGN_CONTEXT_VERSIONS.includes(version)\n ? `The Haven direct-payment sign-context response is version ${version}, which this signer ` +\n `does not support (supported: ${SUPPORTED_DIRECT_SIGN_CONTEXT_VERSIONS.join(', ')}). ` +\n 'Update @haven_ai/signer.'\n : 'The Haven direct-payment sign-context response is missing sign_data.typed_data, or its ' +\n \"signature_scheme is not 'eip712_userop' — the backend may predate #3271. Pass typed_data_b64 \" +\n 'from the payment result instead.',\n 'SIGN_CONTEXT_MALFORMED',\n undefined,\n paymentId,\n 'direct',\n )\n }\n return {\n paymentId: String(body.payment_id ?? paymentId),\n payloadHash: signData.hash,\n typedData: signData.typed_data as Record<string, unknown>,\n status: typeof body.status === 'string' ? body.status : 'pending_signature',\n expiresAt: typeof body.expires_at === 'string' ? body.expires_at : undefined,\n clientUpdate: readClientUpdate(body.client_update),\n }\n}\n","import { connectorRerunCommand } from '@haven_ai/sdk/edge'\nimport {\n SUPPORTED_SWEEP_BINDING_VERSIONS,\n SUPPORTED_X402_EXPECTED_VERSIONS,\n} from './core.js'\nimport { SUPPORTED_DIRECT_SIGN_CONTEXT_VERSIONS } from './sign-context.js'\n\n/**\n * Pre-payment skew detection (#1155).\n *\n * #1143 made a stale signer say so — but only at the signing step, after the\n * agent had already quoted and was one call away from funding. This module\n * moves the same information to the `initialize` handshake, so the set of\n * expected-context versions this signer understands is observable *before* a\n * payment is attempted.\n *\n * **The check is necessarily agent-mediated.** The signer and the hosted Haven\n * MCP are two separate servers connected to the same client; neither can\n * introspect the other. The signer's Haven reads (#1263's read-only\n * `GET /x402/:payment_id/sign-context` and #3271's direct-payment\n * `GET /payments/:payment_id/sign-context`, both in `sign-context.ts`) do not help\n * here: each fetches one payment's signing bytes, not the hosted server's\n * handshake, and it happens at signing time — after the quote this module\n * exists to get ahead of. So only the agent sees both handshakes, and what\n * ships here is the *information* plus the prompt to compare it — never a\n * server-side gate. A mismatch is advisory: the enforcement point remains the\n * #1143 signing-time guard, which is unchanged.\n *\n * Everything below is DERIVED from the two constants in `core.ts` that the\n * signing path actually enforces. A second hand-maintained literal is the one\n * way this feature could become a lie, so there isn't one — including inside\n * the human-readable `instructions` string, which renders the same arrays.\n */\n\n/**\n * Vendor-prefixed key under MCP's `capabilities.experimental`.\n *\n * `experimental` rather than the newer `extensions` field deliberately: both are\n * `Record<string, object>` in `@modelcontextprotocol/sdk@1.29`, but a client on\n * an older SDK parses the `initialize` result with a `ServerCapabilities` schema\n * that has no `extensions` key, and Zod's default object behaviour would strip\n * it. `experimental` has been in the schema since the beginning, so it survives\n * an old client — which is precisely the population this feature exists for.\n */\nexport const SIGNER_CAPABILITY_KEY = 'haven/signer-compatibility'\n\nexport interface SignerCompatibility {\n /** Expected-context versions this signer will verify (`SUPPORTED_X402_EXPECTED_VERSIONS`). */\n x402_expected_context_versions: number[]\n /** Sweep-binding versions this signer will verify (`SUPPORTED_SWEEP_BINDING_VERSIONS`). */\n sweep_binding_versions: number[]\n /**\n * #3271: `direct_sign_context_version`s this signer will fetch and verify\n * from `GET /payments/:id/sign-context` — derived from the SDK's\n * `DIRECT_SIGN_CONTEXT_VERSION` via `SUPPORTED_DIRECT_SIGN_CONTEXT_VERSIONS`,\n * never a second literal.\n */\n direct_sign_context_versions: number[]\n}\n\n/** The supported sets this signer enforces, as a plain serialisable object. */\nexport function signerCompatibility(): SignerCompatibility {\n return {\n x402_expected_context_versions: [...SUPPORTED_X402_EXPECTED_VERSIONS],\n sweep_binding_versions: [...SUPPORTED_SWEEP_BINDING_VERSIONS],\n direct_sign_context_versions: [...SUPPORTED_DIRECT_SIGN_CONTEXT_VERSIONS],\n }\n}\n\n/**\n * The machine-readable half: `capabilities.experimental['haven/signer-compatibility']`,\n * returned verbatim in the `initialize` result.\n *\n * `ServerCapabilities.experimental` is typed `z.record(z.string(), <any object>)`\n * and the SDK's `mergeCapabilities` deep-merges per top-level key, so declaring\n * this at construction survives the `tools` capability `McpServer` registers\n * when the first tool is added.\n */\nexport function signerCapabilityAdvertisement(): {\n experimental: Record<string, SignerCompatibility>\n} {\n return { experimental: { [SIGNER_CAPABILITY_KEY]: signerCompatibility() } }\n}\n\n/**\n * The agent-readable half: MCP `instructions`, which clients surface to the\n * model. The machine-readable capability above is the precise statement, but\n * most agent runtimes never expose `capabilities.experimental` to the model —\n * this string is what actually reaches the reader who has to make the call.\n *\n * It names the same fix as #1143 so an agent that hits either surface — the\n * handshake here or the signing-time error there — tells the user the same\n * thing.\n */\nexport function signerInstructions(): string {\n const compatibility = signerCompatibility()\n return [\n 'Haven edge signer: sign-only tools bound to the local delegate key. It never emits the',\n 'key. Its one network capability is an authenticated READ of a signing context from',\n 'Haven by payment_id — pass payment_id to haven_sign (preferred for both a direct payment,',\n '#3271, and delegation-rail x402) or haven_sign_x402 (x402 only) instead of relaying bulky',\n 'typed-data payloads yourself.',\n '',\n 'Version compatibility (check this BEFORE signing, not after):',\n `- x402 expected-context versions supported: ${compatibility.x402_expected_context_versions.join(', ')}`,\n `- sweep authorization binding versions supported: ${compatibility.sweep_binding_versions.join(', ')}`,\n `- direct-payment (haven_send / haven_pay) sign-context versions supported: ${compatibility.direct_sign_context_versions.join(', ')} — pass payment_id alone to haven_sign; this signer fetches the exact bytes`,\n '',\n 'Haven quote and prepare results report the expected-context version they will emit',\n '(signer_compatibility.x402_expected_context_version). If that version is not in the list',\n 'above, this signer is out of date: STOP before signing, and tell the user to update',\n `@haven_ai/signer by rerunning \\`${connectorRerunCommand()}\\`, which reinstalls the pinned`,\n 'MCP runtime. Do not edit the version field to a supported value — it is part of the',\n 'Haven-signed binding message, so changing it invalidates the signature.',\n '',\n 'A version-mismatch refusal from haven_sign / haven_sign_x402 / haven_sign_sweep_delegate is',\n 'machine-readable, not just prose: it carries code, supported_versions, received_version, and',\n 'fallback fields alongside the message, so you can branch on it directly. Every signer',\n 'refusal also carries the next-step family: next_tool_name + next_tool_server_role when a',\n 'hosted tool follows (resolve the role against your own server names), else',\n 'next_tool_omitted_reason saying why not.',\n ].join('\\n')\n}\n","import type { Stats } from 'node:fs'\nimport { chmod, lstat, stat } from 'node:fs/promises'\n\n/** Owner-only: the mode every file this package writes beside a credential gets. */\nexport const OWNER_ONLY_MODE = 0o600\n\nexport type PermissionLog = (message: string) => void\n\nconst defaultLog: PermissionLog = (message) => process.stderr.write(`${message}\\n`)\n\nexport interface PermissiveFile {\n /** The offending mode, e.g. `0644`. */\n octal: string\n /** False for a symlink, directory or device at that path — never chmod those. */\n regular: boolean\n}\n\n/**\n * Is this path readable, writable or executable by anyone but its owner?\n * Returns null when the path cannot be stat'ed or is owner-only, and on\n * Windows where POSIX mode bits do not map cleanly (the same carve-out\n * `@haven_ai/mcp` makes). Pass `stats` to reuse a stat the caller took\n * IMMEDIATELY before — with `stats` the path is not touched, so a cached\n * `Stats` would be trusted over the disk. `follow` decides what a symlink at the path means: a file the signer\n * only READS (the credential) is judged by its target, which is what the\n * content protection is about and what the pre-#3172 `stat` did; a file the\n * signer is about to CHMOD (the audit sidecar) is judged as the link, so a\n * planted symlink is never chmod-ed through (#3172 review).\n */\nexport async function permissiveMode(\n path: string,\n platform: NodeJS.Platform = process.platform,\n stats?: Stats,\n follow: 'follow' | 'nofollow' = 'nofollow',\n): Promise<PermissiveFile | null> {\n if (platform === 'win32') return null\n let info: Stats\n try {\n info = stats ?? (follow === 'follow' ? await stat(path) : await lstat(path))\n } catch {\n return null\n }\n if ((info.mode & 0o077) === 0) return null\n return { octal: (info.mode & 0o777).toString(8).padStart(4, '0'), regular: info.isFile() }\n}\n\n/**\n * Warn (best-effort, POSIX only) when a file this signer READS is readable\n * beyond its owner. The signer does not own the credential, so it tells the\n * operator what to run rather than changing a file it was handed. Follows a\n * symlink, as the pre-#3172 `stat` did: a link to a 0600 credential is fine.\n */\nexport async function warnIfFilePermissive(\n kind: string,\n path: string,\n log: PermissionLog = defaultLog,\n platform: NodeJS.Platform = process.platform,\n): Promise<void> {\n const found = await permissiveMode(path, platform, undefined, 'follow')\n if (found === null) return\n log(\n `haven-signer: warning: ${kind} at ${path} is readable beyond the owner ` +\n `(mode ${found.octal}). Run: chmod 600 ${path}`,\n )\n}\n\nexport type TightenOutcome = 'owner-only' | 'tightened' | 'warned' | 'skipped'\n\n/**\n * Tighten a file this signer WRITES to owner-only when it finds it\n * permissive (#3172): the audit sidecar was created with the default mode\n * (0644 under the usual umask 022) by every release before this one, so an\n * existing sidecar is fixed in place rather than warned about. Judged with\n * `lstat`. Falls back to the warning when the path is not a regular file (a\n * symlink would make chmod hit whatever it points at) or when chmod is\n * refused (a file owned by another user). Outcomes: `tightened` / `warned`\n * as above; `owner-only` when there is nothing to tighten (owner-only file,\n * or no file at that path); `skipped` on Windows only.\n */\nexport async function tightenIfFilePermissive(\n kind: string,\n path: string,\n log: PermissionLog = defaultLog,\n platform: NodeJS.Platform = process.platform,\n stats?: Stats,\n): Promise<TightenOutcome> {\n if (platform === 'win32') return 'skipped'\n let info: Stats | null = stats ?? null\n if (!info) {\n try {\n info = await lstat(path)\n } catch {\n return 'owner-only'\n }\n }\n if (!info.isFile()) {\n // A symlink (or device, or directory) at the sidecar path: chmod would\n // follow it to whatever it points at, and `appendFile` already writes\n // the audit rows through it. Judged BEFORE the mode — a link's own mode\n // bits mean nothing and vary with umask (0755 under 022, 0700 under 077),\n // so they neither gate this warning nor appear in it. The remedy is to\n // remove the link, not to chmod its target.\n log(\n `haven-signer: warning: ${kind} at ${path} is not a regular file (a symlink or similar); ` +\n `audit rows are being written through it and it was not tightened. Remove it: rm ${path}`,\n )\n return 'warned'\n }\n const found = await permissiveMode(path, platform, info)\n if (found === null) return 'owner-only'\n {\n try {\n await chmod(path, OWNER_ONLY_MODE)\n log(\n `haven-signer: ${kind} at ${path} was readable beyond the owner (mode ${found.octal}); ` +\n `tightened to 0600.`,\n )\n return 'tightened'\n } catch {\n // fall through to the warning\n }\n }\n log(\n `haven-signer: warning: ${kind} at ${path} is readable beyond the owner ` +\n `(mode ${found.octal}) and could not be tightened. Run: chmod 600 ${path}`,\n )\n return 'warned'\n}\n","import { readFile } from 'node:fs/promises'\nimport { warnIfFilePermissive } from './file-mode.js'\n\n/**\n * The edge signer's own credential requires *only* `delegate_key` — unlike\n * `@haven_ai/mcp`, no `api_key` belongs in this file.\n *\n * That is a claim about this credential, not about the process, and the\n * difference matters: the sentence that used to stand here (\"it does not call\n * the Haven API\") was retired by #1263. The MCP server layer does make at\n * most two authenticated reads per signing call — a read-only\n * `GET /x402/:payment_id/sign-context` and, for a direct payment via\n * `haven_sign` since #3271, then `GET /payments/:payment_id/sign-context`, see\n * `sign-context.ts` — and it reads the `api_url` / `api_key` for them from a\n * SEPARATE `identity.json` in the same directory as the credential file\n * resolved here. That is why `sourcePath` below is load-bearing rather than\n * diagnostic, and why a key supplied through `HAVEN_DELEGATE_KEY` alone (no\n * file, so no directory) leaves that path with no identity to load and the\n * process making no network calls at all. The delegate key read here is never\n * part of any request or response either way.\n */\nexport interface SignerCredentials {\n delegateKey: string\n agentId?: string\n /** The Haven account (smart account) the agent spends from. */\n accountAddress?: string\n chainId?: number\n network?: string\n x402BindingSigner?: string\n /** Absolute path the key was loaded from, if a file was used. */\n sourcePath?: string\n}\n\ninterface RawCredentialFile {\n delegate_key?: unknown\n delegateKey?: unknown\n agent_id?: unknown\n agentId?: unknown\n /** What `@haven_ai/connect` writes. */\n account_address?: unknown\n /** Pre-#2908 spelling — read PERMANENTLY (a credential file never rewrites itself), see `readAccountAddressField`. */\n safe_address?: unknown\n /** Pre-#2908 spelling — read PERMANENTLY (a credential file never rewrites itself), see `readAccountAddressField`. */\n safeAddress?: unknown\n chain_id?: unknown\n chainId?: unknown\n network?: unknown\n x402_binding_signer?: unknown\n x402BindingSigner?: unknown\n}\n\n/**\n * Resolve the delegate key for the edge signer.\n *\n * Order — earlier wins:\n * 1. Explicit `path` (e.g. `--credentials <path>`).\n * 2. `HAVEN_CREDENTIALS` env var pointing at a credential JSON file.\n * 3. `HAVEN_DELEGATE_KEY` env var.\n *\n * The same credential JSON the dashboard emits works here — we just read its\n * `delegate_key` and ignore the rest.\n */\nexport async function loadSignerCredentials(\n path: string | undefined = process.env.HAVEN_CREDENTIALS,\n): Promise<SignerCredentials> {\n if (path) return loadFromFile(path)\n\n const envKey = stringField(process.env.HAVEN_DELEGATE_KEY)\n if (envKey) {\n const accountAddress = readAccountAddressEnv(process.env)\n return {\n delegateKey: envKey,\n agentId: stringField(process.env.HAVEN_AGENT_ID),\n accountAddress,\n chainId: chainIdField(process.env.HAVEN_CHAIN_ID, 'HAVEN_CHAIN_ID'),\n network: stringField(process.env.HAVEN_NETWORK),\n x402BindingSigner: stringField(process.env.HAVEN_X402_BINDING_SIGNER),\n }\n }\n\n throw new Error(\n 'No delegate key found. Set HAVEN_DELEGATE_KEY, pass --credentials <path>, ' +\n 'or set HAVEN_CREDENTIALS to a Haven agent credential JSON file.',\n )\n}\n\nasync function loadFromFile(path: string): Promise<SignerCredentials> {\n let rawText: string\n try {\n rawText = await readFile(path, 'utf8')\n } catch (err) {\n throw new Error(\n `Could not read Haven credentials at ${path}: ${err instanceof Error ? err.message : String(err)}`,\n )\n }\n\n await warnIfCredentialFilePermissive(path)\n\n let raw: RawCredentialFile\n try {\n raw = JSON.parse(rawText) as RawCredentialFile\n } catch {\n throw new Error('Haven credentials must be JSON with a delegate_key field.')\n }\n\n const delegateKey = stringField(raw.delegate_key ?? raw.delegateKey)\n if (!delegateKey) {\n throw new Error('Haven credentials are missing delegate_key — the edge signer needs it to sign.')\n }\n\n const accountAddress = readAccountAddressField(raw)\n return {\n delegateKey,\n agentId: stringField(raw.agent_id ?? raw.agentId),\n accountAddress,\n chainId: chainIdField(raw.chain_id ?? raw.chainId, 'chain_id'),\n network: stringField(raw.network),\n x402BindingSigner: stringField(\n raw.x402_binding_signer ??\n raw.x402BindingSigner ??\n process.env.HAVEN_X402_BINDING_SIGNER,\n ),\n sourcePath: path,\n }\n}\n\n/**\n * The account address off a credential FILE: `account_address` (what\n * `@haven_ai/connect` writes from #2908 on) first, then the two pre-#2908\n * spellings.\n *\n * The two old fallbacks are PERMANENT, not part of the one-release naming\n * window (#2906, decision 2a): a credential file on disk was written once and\n * never rewrites itself, so a signer that stopped reading `safe_address`\n * would silently lose the address for every agent connected before this\n * release — the consent hash would change and the spend-context prompt would\n * say \"not provided\". Two lines, kept for as long as the file format exists.\n *\n * Exported for the mutation tests: dropping `account_address` fails the\n * new-shape test, dropping either old key fails the old-shape test.\n */\nexport function readAccountAddressField(raw: Pick<RawCredentialFile, 'account_address' | 'safe_address' | 'safeAddress'>): string | undefined {\n return stringField(raw.account_address ?? raw.safe_address ?? raw.safeAddress)\n}\n\n/**\n * The account address off the process environment: `HAVEN_ACCOUNT_ADDRESS`\n * (the survivor, decided on #2906). The two names the dashboard handoff\n * emitted before #2908 — `HAVEN_WALLET_ADDRESS` and `HAVEN_SAFE_ADDRESS` —\n * were window-scoped (unlike the credential-FILE fallbacks) and are retired\n * as of #2914.\n */\nexport function readAccountAddressEnv(env: NodeJS.ProcessEnv): string | undefined {\n const current = stringField(env.HAVEN_ACCOUNT_ADDRESS)\n\n // Retired, but REFUSED rather than ignored — the same rule the backend\n // applies to retired request names, for the same reason and with more at\n // stake. Silently dropping these would not merely leave the address unset:\n // `accountAddress` is what `haven_sign_sweep_delegate` passes as\n // `expectedSafe`, and an undefined `expectedSafe` SKIPS the check that a\n // sweep's `to` matches the account in the local credential (see\n // `core.ts`). An operator who upgrades without touching env would lose a\n // money-path cross-check and get no signal at all.\n //\n // The verdict keys on RELIANCE, not presence, so a handoff that still\n // exports both names alongside the new one keeps working:\n // retired alone -> throw\n // both, same value -> accept the new one\n // both, disagreeing -> throw\n for (const name of ['HAVEN_WALLET_ADDRESS', 'HAVEN_SAFE_ADDRESS'] as const) {\n const retired = stringField(env[name])\n if (!retired) continue\n if (!current) {\n throw new Error(\n `${name} is retired (#2906) — Haven accounts are addressed as accounts, not Safes. ` +\n 'Set HAVEN_ACCOUNT_ADDRESS to the same value. Refusing rather than ignoring it, ' +\n 'because an unset account address silently skips the sweep-destination check.',\n )\n }\n if (retired.toLowerCase() !== current.toLowerCase()) {\n throw new Error(\n `${name} and HAVEN_ACCOUNT_ADDRESS were both set to different addresses. ` +\n 'Remove the retired name, or make them match — picking one silently would hide ' +\n 'the mismatch.',\n )\n }\n }\n\n return current\n}\n\nfunction stringField(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim() ? value.trim() : undefined\n}\n\nfunction chainIdField(value: unknown, label: string): number | undefined {\n if (value === undefined || value === null) return undefined\n\n if (typeof value === 'number') {\n if (Number.isSafeInteger(value) && value > 0) return value\n throw invalidChainIdError(label)\n }\n\n if (typeof value === 'string') {\n const trimmed = value.trim()\n if (/^[1-9]\\d*$/.test(trimmed)) {\n const parsed = Number(trimmed)\n if (Number.isSafeInteger(parsed)) return parsed\n }\n throw invalidChainIdError(label)\n }\n\n throw invalidChainIdError(label)\n}\n\nfunction invalidChainIdError(label: string): Error {\n return new Error(`Haven signer credentials ${label} must be a positive integer.`)\n}\n\n/**\n * Warn (best-effort, POSIX only) when the credential file is readable beyond\n * its owner. Mirrors `@haven_ai/mcp`'s check — the delegate key is the most\n * sensitive thing on the machine.\n *\n * Exported for testing.\n */\nexport async function warnIfCredentialFilePermissive(\n path: string,\n log: (message: string) => void = (message) => process.stderr.write(`${message}\\n`),\n platform: NodeJS.Platform = process.platform,\n): Promise<void> {\n await warnIfFilePermissive('credential file', path, log, platform)\n}\n","import { createHash } from 'node:crypto'\nimport { appendFile, lstat, mkdir, rename } from 'node:fs/promises'\nimport { homedir } from 'node:os'\nimport { dirname, resolve } from 'node:path'\nimport { OWNER_ONLY_MODE, tightenIfFilePermissive, type PermissionLog } from './file-mode.js'\nimport type { SignerToolName } from './tools.js'\n\n/**\n * #3172: the sidecar is bounded. When it reaches this size the current file is\n * renamed to `<path>.1` (replacing the previous `.1`) and a fresh file starts,\n * so at most two generations — the live file and one predecessor — ever exist.\n * 8 MiB is roughly 30 000 entries at the ~270-byte row size; nothing in the\n * signer reads the file back, so the bound protects the disk and the reader's\n * patience, never a signing decision.\n */\nexport const AUDIT_ROTATE_BYTES = 8 * 1024 * 1024\n\nexport interface AppendAuditOptions {\n /** Where permission notices go; defaults to stderr. */\n log?: PermissionLog\n /** Rotation threshold in bytes; exported default `AUDIT_ROTATE_BYTES`. */\n rotateAtBytes?: number\n platform?: NodeJS.Platform\n}\n\n\nexport interface SigningAuditEntry {\n version: 1\n timestamp: string\n tool: SignerToolName\n payload_hash: string\n delegate_address: string\n /**\n * Serialized key kept as `safe_address` deliberately (#2914 review): this\n * is a persisted JSONL field, and an audit log written by an earlier\n * release never rewrites itself — renaming the key here would fork the\n * format mid-file. `SigningAuditContext.accountAddress` (the in-memory\n * field this is built from) carries the account-vocabulary name; only the\n * on-disk spelling stays put.\n */\n safe_address?: string\n chain_id?: number\n}\n\nexport interface SigningAuditContext {\n delegateAddress: string\n accountAddress?: string\n chainId?: number\n auditPath?: string\n}\n\nexport function defaultSigningAuditPath(credentialsPath?: string): string {\n if (credentialsPath) return resolve(`${credentialsPath}.signer-audit.jsonl`)\n return resolve(homedir(), '.haven', 'signer-audit.jsonl')\n}\n\nexport async function appendSigningAuditEntry(\n entry: SigningAuditEntry,\n path: string,\n options: AppendAuditOptions = {},\n): Promise<void> {\n await mkdir(dirname(path), { recursive: true })\n const rotateAt = options.rotateAtBytes ?? AUDIT_ROTATE_BYTES\n const existing = await lstat(path).catch(() => null)\n if (existing) {\n // Tighten BEFORE rotating, on every append (the lstat above is the only\n // cost, and it is already paid): a pre-#3172 0644 sidecar is fixed in\n // place, and if it rotates next, `rename` carries 0600 into `.1` — the\n // history is never left world-readable. Idempotent, so the notice fires\n // once per permissive occurrence, not once per process (#3172 review).\n await tightenIfFilePermissive('audit sidecar', path, options.log, options.platform, existing)\n if (existing.size >= rotateAt) {\n // Rotate BEFORE appending so the live file never exceeds the bound by\n // more than one row. `rename` replaces the previous `.1` atomically, but\n // the decision to rotate is not: two signer PROCESSES at the bound can\n // both pass the size check, and the slower one may rename the faster\n // one's fresh live file over `.1`, discarding the predecessor\n // generation. The current entry is never lost (appendFile re-creates\n // the live file), only older history, and this is an advisory log —\n // so the loser's ENOENT is swallowed and a produced signature is never\n // thrown away over it. Two processes on one credential is the #1694\n // multi-agent shape; the loss needs one of them a full cycle behind.\n await rename(path, `${path}.1`).catch(() => {})\n }\n }\n // `mode` applies only when the file is created: a new sidecar is owner-only\n // from its first byte, like the credential it sits beside (#3172).\n await appendFile(path, `${JSON.stringify(entry)}\\n`, { encoding: 'utf8', mode: OWNER_ONLY_MODE })\n}\n\nexport function createSigningAuditEntry(\n tool: SignerToolName,\n payloadHash: string,\n context: SigningAuditContext,\n now: Date = new Date(),\n): SigningAuditEntry {\n const entry: SigningAuditEntry = {\n version: 1,\n timestamp: now.toISOString(),\n tool,\n payload_hash: payloadHash,\n delegate_address: context.delegateAddress,\n }\n if (context.accountAddress) entry.safe_address = context.accountAddress\n if (typeof context.chainId === 'number') entry.chain_id = context.chainId\n return entry\n}\n\nexport function hashPayloadForAudit(payload: unknown): string {\n return `0x${createHash('sha256').update(stableStringify(payload)).digest('hex')}`\n}\n\nfunction stableStringify(value: unknown): string {\n if (value === null || typeof value !== 'object') {\n const primitive = JSON.stringify(value)\n return primitive === undefined ? 'undefined' : primitive\n }\n if (Array.isArray(value)) return `[${value.map((item) => stableStringify(item)).join(',')}]`\n const object = value as Record<string, unknown>\n return `{${Object.keys(object)\n .sort()\n .map((key) => `${JSON.stringify(key)}:${stableStringify(object[key])}`)\n .join(',')}}`\n}\n","import { AgentPaymentNextAction, HavenSigningError, type NextStep } from '@haven_ai/sdk/edge'\nimport { signerRefusalStep } from './next-step.js'\n\n/**\n * #3169: `haven_sign` called with a bare `payload_hash` — no `payment_id`, no\n * `typed_data` / `typed_data_b64`, no `x402_expected` — is refused, always.\n *\n * Until #3169 that arm was `signPaymentHash`: raw secp256k1 over caller-supplied\n * bytes with no Haven binding, no amount, no merchant, no shape check and no\n * domain separation — a blind-signing oracle for the delegate key. A digest of\n * an EIP-3009 `TransferWithAuthorization` from the delegate wallet signed that\n * way is a valid transfer; a digest of a MetaMask `Delegation` signed that way\n * bypasses the #1476 refusal, which keys on the payload's SHAPE and a hash has\n * none. The arm's only legitimate caller was the AllowanceModule rail, which\n * #1986 retired (`execution-rail.ts` resolves to `delegation | retired_session\n * | retired_allowance`); the surviving rail validates typed data and rejects a\n * raw hash on-chain (AA24, #1254).\n *\n * Structured like the other signer refusals (#3001/#3103): a named code an\n * agent can route on, a `next_action`, and a typed next step. No tool can fix\n * this from inside the call — the remedy is calling THIS tool with an input\n * the signer can verify — so the step names none and says why.\n */\nexport const BARE_HASH_REFUSED = 'BARE_HASH_REFUSED' as const\n\nexport class HavenBareHashRefusedError extends HavenSigningError {\n declare readonly code: typeof BARE_HASH_REFUSED\n readonly next_action = AgentPaymentNextAction.StopAndTellUser\n readonly step: NextStep\n\n constructor() {\n super(\n 'Refusing to sign a bare payload_hash. A hash carries no shape, amount, merchant or ' +\n 'binding, so this signer cannot tell a Haven payment from a transfer out of the delegate ' +\n 'wallet or a delegation of its authority — and the only rail that ever validated a raw ' +\n 'hash signature is retired. Call this tool with { payment_id } (the signer fetches and ' +\n 'verifies the Haven-signed context itself), or with typed_data / typed_data_b64 (the ' +\n 'account validates that EIP-712 payload), or with x402_expected for an x402 funding leg.',\n )\n ;(this as { code: string }).code = BARE_HASH_REFUSED\n this.name = 'HavenBareHashRefusedError'\n this.step = signerRefusalStep({\n nextAction: AgentPaymentNextAction.StopAndTellUser,\n nextTool: null,\n nextToolOmittedReason:\n 'call haven_sign again with payment_id (preferred), typed_data / typed_data_b64, or x402_expected — a bare payload_hash is never signed',\n })\n }\n}\n","import {\n AgentPaymentFailureCode,\n AgentPaymentNextAction,\n HavenApiError,\n HavenError,\n HavenSigningError,\n HavenUnsupportedSignerVersionError,\n HavenUserOpBindingError,\n assertUserOpTypedDataBinding,\n connectorRerunCommand,\n isPackedUserOperationTypedData,\n HavenTypedDataRefusedError,\n TYPED_DATA_NOT_ALLOWED,\n assertBoundDirectPaymentUserOp as assertSdkBoundDirectPaymentUserOp,\n isSettlementChildTypedData,\n type HavenClientUpdate,\n type X402PaymentRequired,\n} from '@haven_ai/sdk/edge'\nimport { hashTypedData } from 'viem'\nimport { z } from 'zod/v3'\nimport { HavenBareHashRefusedError } from './bare-hash.js'\nimport {\n appendSigningAuditEntry,\n createSigningAuditEntry,\n hashPayloadForAudit,\n type SigningAuditContext,\n} from './audit.js'\nimport type {\n EdgeSigner,\n X402ExpectedPayment,\n X402FundingSignatureResult,\n X402FundingTypedData,\n} from './core.js'\nimport {\n fetchDirectSignContext,\n fetchX402SignContext,\n HavenSignContextError,\n type HavenIdentity,\n type FetchedDirectSignContext,\n type FetchedSignContext,\n} from './sign-context.js'\nimport { nextStepWireFields, signerRefusalStep } from './next-step.js'\n\n/**\n * #3271: structured refusal for a direct-payment `PackedUserOperation` whose\n * typed data does not recompute to its own `payload_hash` — the payload was\n * altered between the Haven result and this call (a language model relaying\n * multi-KB typed data by hand is the observed cause; #3271 was found live as\n * an `AA24 signature error` from the bundler, after a bad signature was\n * already produced). Modelled on `HavenBareHashRefusedError` (#3169) and the\n * `HavenSignContextError` family (#3001): a named `code`, a `next_action`,\n * and a typed next step. No tool can fix this from inside the call — the\n * remedy is signing by `payment_id` (this signer then fetches the exact\n * bytes) or passing the result's typed data unchanged — so the step names\n * none and says why. Never reaches `signer.signDelegationTypedData` and is\n * never audited: nothing was signed.\n */\nexport const USEROP_BINDING_MISMATCH = 'USEROP_BINDING_MISMATCH' as const\n\nexport class HavenUserOpBindingRefusedError extends HavenSigningError {\n declare readonly code: typeof USEROP_BINDING_MISMATCH\n readonly next_action = AgentPaymentNextAction.StopAndTellUser\n readonly step: ReturnType<typeof signerRefusalStep>\n\n /** `message`: the SDK's `HavenUserOpBindingError.message` verbatim — it already names the mismatch and the remedy. */\n constructor(message: string) {\n super(message)\n ;(this as { code: string }).code = USEROP_BINDING_MISMATCH\n this.name = 'HavenUserOpBindingRefusedError'\n this.step = signerRefusalStep({\n nextAction: AgentPaymentNextAction.StopAndTellUser,\n nextTool: null,\n nextToolOmittedReason:\n 'call haven_sign again with payment_id alone (preferred), or with typed_data copied unchanged from the payment result',\n })\n }\n}\n\n/**\n * #3272: the unbound branch's allowlist. `assertUserOpTypedDataBinding`\n * (#3271) proves the typed data and its `payload_hash` describe the SAME\n * operation — necessary, never sufficient, because the caller supplies both\n * values, so a self-consistent forgery binds perfectly to itself. This is\n * the rest of the property: the operation described is the ONE shape this\n * branch may ever sign — a direct payment that redeems the agent's own\n * budget delegation, for its own account, on a chain the delegation rail\n * runs on. Everything else (another agent's account, a self-call such as\n * `transferOwnership`, a batch `execute`, a call to any contract other than\n * the DelegationManager) is refused here, before\n * `signer.signDelegationTypedData` ever sees it. Modelled on\n * `HavenUserOpBindingRefusedError`: no signature, no audit entry, ever, for\n * any refusal from this function.\n */\nexport { TYPED_DATA_NOT_ALLOWED }\n\n/**\n * The signer's structured form of the SDK's `HavenTypedDataRefusedError`\n * (#3283 moved the allowlist into `@haven_ai/sdk` so `HavenClient.signForData`\n * runs the same check): same `code`, plus the MCP next step.\n */\nexport class HavenTypedDataNotAllowedError extends HavenTypedDataRefusedError {\n readonly next_action = AgentPaymentNextAction.StopAndTellUser\n readonly step: ReturnType<typeof signerRefusalStep>\n\n constructor(message: string) {\n super(message)\n this.name = 'HavenTypedDataNotAllowedError'\n this.step = signerRefusalStep({\n nextAction: AgentPaymentNextAction.StopAndTellUser,\n nextTool: null,\n nextToolOmittedReason:\n 'sign only Haven-prepared payloads: call haven_sign with payment_id (preferred), or pass ' +\n 'typed_data / typed_data_b64 copied unchanged from a haven_send / haven_pay result, or ' +\n 'x402_expected from a Haven quote',\n })\n }\n}\n\n/**\n * #3272's content + provenance allowlist, which #3283 moved into\n * `@haven_ai/sdk` (`assertBoundDirectPaymentUserOp`) so the signer and\n * `HavenClient.signForData` run ONE implementation. Converts the SDK's\n * refusal into this signer's structured error — same code and message, plus\n * the next step.\n */\nfunction assertBoundDirectPaymentUserOp(\n typedData: Record<string, unknown>,\n delegateAddress: string,\n): void {\n try {\n assertSdkBoundDirectPaymentUserOp(typedData, delegateAddress)\n } catch (err) {\n if (err instanceof HavenTypedDataRefusedError && !(err instanceof HavenTypedDataNotAllowedError)) {\n throw new HavenTypedDataNotAllowedError(err.message)\n }\n throw err\n }\n}\n\n/**\n * Local signer tool set. These run on the agent's machine, next to the key,\n * and pair with the hosted server's construct/relay tools (#183). They sign;\n * they never call the Haven API and never emit the key.\n */\nexport type SignerToolName =\n | 'haven_sign'\n | 'haven_x402_sign_header'\n | 'haven_sign_x402'\n | 'haven_sign_sweep_delegate'\n\nconst sweepAuthorizationSchema = z.object({\n from: z.string().regex(/^0x[0-9a-fA-F]{40}$/, 'from must be a 0x address'),\n to: z.string().regex(/^0x[0-9a-fA-F]{40}$/, 'to must be a 0x address'),\n value: z.string().regex(/^[0-9]+$/, 'value must be a decimal atomic amount'),\n validAfter: z.string().regex(/^[0-9]+$/, 'validAfter must be a decimal unix time'),\n validBefore: z.string().regex(/^[0-9]+$/, 'validBefore must be a decimal unix time'),\n nonce: z.string().regex(/^0x[0-9a-fA-F]{64}$/, 'nonce must be a 0x-prefixed 32-byte hex string'),\n token: z.string().regex(/^0x[0-9a-fA-F]{40}$/, 'token must be a 0x address'),\n chainId: z.number().int().positive(),\n})\n\n/**\n * Binding version at the tool boundary (#1143).\n *\n * Open on purpose. A literal (or literal union) here is validated by the MCP\n * server *before* any handler runs, so a signer one release behind the backend\n * rejected the payment with `Invalid literal value, expected 1 at\n * x402_expected.auth.version` — a message that names neither the cause (your\n * signer is stale) nor the fix (update it), and which no Haven code wrote.\n * Accept any positive integer here and let the signer decide semantically:\n * `SUPPORTED_X402_EXPECTED_VERSIONS` / `SUPPORTED_SWEEP_BINDING_VERSIONS` in\n * `core.ts` still fail closed on anything they do not know, so this widens the\n * *error path*, never what can be signed.\n */\nconst bindingVersionSchema = z.number().int().positive()\n\nconst sweepExpectedAuthSchema = z.object({\n version: bindingVersionSchema,\n message: z.string().min(1),\n signature: z\n .string()\n .regex(/^0x[0-9a-fA-F]+$/, 'signature must be a 0x-prefixed hex string'),\n signer: z.string().regex(/^0x[0-9a-fA-F]{40}$/, 'signer must be a 0x address'),\n})\n\nconst x402ExpectedShape = {\n payment_id: z.string().min(1),\n payload_hash: z\n .string()\n .regex(/^0x[0-9a-fA-F]{64}$/, 'payload_hash must be a 0x-prefixed 32-byte hex string'),\n resource_url: z.string().url(),\n merchant_to: z.string().min(1),\n amount: z.string().min(1),\n asset: z.string().min(1),\n network: z.string().min(1),\n // Required: expires_at is folded into the Haven-signed binding message, so the\n // signer must receive the exact same value to reconstruct a matching message.\n // Omitting it used to fail downstream with a cryptic \"authentication message is\n // invalid\" — making it required surfaces a clear INVALID_INPUT at the boundary.\n expires_at: z.string().min(1),\n // #1138: present on a delegation-rail (v2) context. It commits to the EIP-712\n // typed data the account validates; the signer refuses to raw-sign the bare\n // hash when it is present, and refuses to sign typed data when it is absent.\n typed_data_hash: z\n .string()\n .regex(/^0x[0-9a-fA-F]{64}$/, 'typed_data_hash must be a 0x-prefixed 32-byte hex string')\n .optional(),\n // #1690: present on a v3 context. The delegate this quote was created FOR —\n // the signer refuses to sign when it is not its own. Inside the Haven-signed\n // message, so stripping it here would only break the binding signature.\n payer_delegate: z\n .string()\n .regex(/^0x[0-9a-fA-F]{40}$/, 'payer_delegate must be a 0x-prefixed address')\n .optional(),\n payer_agent_id: z.string().min(1).optional(),\n auth: z.object({\n // Open at the boundary, enforced in the signer — see bindingVersionSchema.\n version: bindingVersionSchema,\n message: z.string().min(1),\n signature: z\n .string()\n .regex(/^0x[0-9a-fA-F]+$/, 'signature must be a 0x-prefixed hex string'),\n signer: z.string().min(1),\n }),\n}\n\nconst x402ExpectedSchema = z.object(x402ExpectedShape)\n\nexport const toolSchemas = {\n haven_sign_sweep_delegate: {\n // The authorization fields prepared by Haven's POST /sweep/prepare. Passed\n // through verbatim from the hosted haven_sweep_delegate tool — the signer\n // re-derives the binding message from these exact values.\n authorization: sweepAuthorizationSchema,\n // Haven's signature over the authorization context (the binding).\n expected_auth: sweepExpectedAuthSchema,\n },\n haven_sign: {\n // #1263: THE preferred x402 input — the signer fetches the exact signing\n // payload + expected context from Haven itself (authenticated with the\n // locally-stored agent credential), so no bulky bytes ever cross the\n // model. Pass payment_id ALONE for a delegation-rail x402 funding intent.\n payment_id: z.string().min(1).optional(),\n // The unsigned hash from haven_pay / haven_pay_x402_quote (payload_hash).\n // Optional when payment_id is supplied (the fetch carries it).\n payload_hash: z\n .string()\n .regex(/^0x[0-9a-fA-F]{64}$/, 'payload_hash must be a 0x-prefixed 32-byte hex string')\n .optional(),\n // Pass x402.expected from hosted haven_pay_x402_quote when this hash funds\n // a standard x402 merchant retry. The signer records it locally and returns\n // an opaque x402_binding for the later header-signing step.\n x402_expected: x402ExpectedSchema.optional(),\n // #1138: delegation-rail intents sign THIS, not payload_hash. Object-typed\n // (not z.unknown()) so MCP clients embed it as JSON rather than a string.\n typed_data: z.record(z.string(), z.unknown()).optional(),\n // #1255: the same payload as ONE opaque base64 string, exactly as returned\n // by the hosted tools. Preferred over typed_data when both are present —\n // an agent re-emitting multi-KB nested JSON between tool calls is the\n // failure mode this field removes (a truncated/reshaped payload fails the\n // digest check and the payment refuses, correctly but pointlessly).\n // Bounded: a realistic redemption payload is ~10KB encoded; 256KB is\n // generous headroom while keeping the offline signer from materializing\n // arbitrarily large caller input.\n typed_data_b64: z.string().min(1).max(262144).optional(),\n },\n haven_x402_sign_header: {\n // The parsed HTTP 402 PaymentRequired from the merchant. Typed as an object\n // (not z.unknown(), which becomes empty JSON Schema `{}`) so MCP clients\n // embed it as JSON rather than serialising the object to a string.\n payment_required: z.record(z.string(), z.unknown()),\n // Opaque binding returned by haven_sign when x402_expected was supplied.\n x402_binding: z.string().min(1),\n },\n haven_sign_x402: {\n // #1263: preferred — pass payment_id (plus payment_required) and the\n // signer fetches the exact signing payload + expected context itself.\n payment_id: z.string().min(1).optional(),\n // One-shot x402 signing: funding hash + merchant header in one local call.\n // Both optional when payment_id is supplied (the fetch carries them).\n payload_hash: z\n .string()\n .regex(/^0x[0-9a-fA-F]{64}$/, 'payload_hash must be a 0x-prefixed 32-byte hex string')\n .optional(),\n x402_expected: x402ExpectedSchema.optional(),\n // #1355: optional when payment_id is supplied — the signer's context fetch\n // carries the stored 402 PaymentRequired, so `{ payment_id }` alone is the\n // preferred call. Still required (via the runtime check in the handler)\n // for the quote-based fallback path without a payment_id.\n payment_required: z.record(z.string(), z.unknown()).optional(),\n // #1138: delegation-rail intents sign THIS, not payload_hash. Object-typed\n // (not z.unknown()) so MCP clients embed it as JSON rather than a string.\n typed_data: z.record(z.string(), z.unknown()).optional(),\n // #1255: see haven_sign.typed_data_b64 — the copy-through-safe form.\n typed_data_b64: z.string().min(1).max(262144).optional(),\n },\n// #3101: keys survive on the type (see the hosted server's contracts.ts).\n} as const satisfies Record<SignerToolName, z.ZodRawShape>\n\nconst SIGN_DESCRIPTION = [\n 'Sign an unsigned Haven payment with the local delegate key. The delegate key never leaves',\n 'this process. Pass payment_id (preferred), or the payload_hash from haven_pay / haven_pay_x402_quote',\n 'TOGETHER WITH typed_data / typed_data_b64 or x402_expected — never a payload_hash alone.',\n 'For x402, also pass x402_expected from haven_pay_x402_quote; the signer records it locally',\n 'and returns { signature, x402_binding }. x402_expected includes expires_at; sign before that',\n 'window closes. DELEGATION-RAIL x402 accounts (#1263): pass payment_id ALONE (preferred) — this',\n 'signer fetches the exact signing payload and expected context from Haven itself, so nothing',\n 'bulky ever crosses your context. DIRECT payments (#3271, haven_send / haven_pay): payment_id',\n 'ALONE also works here — the signer fetches the exact PackedUserOperation typed data and its',\n 'payload_hash from Haven and checks them against each other before signing, so a payload corrupted',\n 'in transit is refused (USEROP_BINDING_MISMATCH) instead of producing a bad signature. Fallback for',\n 'either flow: pass typed_data_b64 through UNCHANGED (never re-type the nested typed_data JSON); the',\n 'account validates that EIP-712 payload, not payload_hash. On a direct payment the same binding',\n 'check runs on the relayed payload too. This tool signs ONLY Haven-prepared payloads (#3272): a',\n 'direct-payment UserOp from your own account that redeems a delegation granted to it, or an x402',\n 'intent against a Haven-signed context — never an arbitrary typed_data payload, however it is shaped.',\n 'Next: call mcp__haven__haven_submit with signature, then pass x402_binding',\n 'to mcp__haven-signer__haven_x402_sign_header. A bare payload_hash with no payment_id, typed_data',\n 'or x402_expected is REFUSED (BARE_HASH_REFUSED): a hash carries nothing this signer can verify.',\n].join(' ')\n\nconst X402_SIGN_HEADER_DESCRIPTION = [\n 'Build and sign the EIP-3009 merchant payment header for the merchant leg of an x402 payment.',\n 'The delegate key stays local — only the signed header crosses any boundary.',\n 'Pass the payment_required from the original merchant 402 response and the x402_binding',\n 'returned by haven_sign. It must be haven_sign — NOT haven_sign_x402, which is a',\n 'one-shot that builds the header itself and spends its own binding doing so. If you called',\n 'haven_sign_x402, its result already carries payment_header; retry the merchant with that and',\n 'do not call this tool. The signer validates the merchant, amount, resource, asset, and',\n 'network against the recorded funding context before signing, checks expires_at when present,',\n 'and rejects mismatches or expired payment windows.',\n 'Returns { payment_header, accepted }. On your retry set BOTH PAYMENT-SIGNATURE (x402 v2) and',\n 'X-PAYMENT (v1) to <payment_header>; a strict v2 merchant reads only the first.',\n 'Only call after haven_submit has confirmed the funding step (nextAction=none or',\n 'the funding tx has a confirmed status). Next for paid MCP tools: call mcp__haven__haven_complete_mcp_tool.',\n].join(' ')\n\nconst SIGN_X402_DESCRIPTION = [\n 'One-shot x402 signing for the fast 3-call flow: sign the funding payload AND build the EIP-3009',\n 'merchant payment header in a single local call (equivalent to haven_sign followed by',\n 'haven_x402_sign_header). The delegate key never leaves this process. From the haven_pay_mcp_tool',\n 'result pass JUST payment_id — PREFERRED (#1263, #1355): this signer fetches the exact signing',\n 'payload, expected context, and merchant payment_required from Haven itself, so nothing bulky',\n 'crosses your context. If the signer reports the context carried no payment_required (older',\n 'backend), re-call with payment_id plus payment_required verbatim from the pay result.',\n 'Fallback for older backends: pass payload_hash, x402_expected (the nested x402.expected object —',\n 'passing the whole x402 object is also accepted and unwrapped for you), and typed_data_b64',\n 'through UNCHANGED; the signer',\n 'signs the typed data instead of payload_hash and refuses the bare hash when the context commits to typed data.',\n 'Returns',\n '{ signature, x402_binding, payment_header, accepted }; hand signature + payment_header to',\n 'mcp__haven__haven_settle_mcp_tool to fund and settle in one hosted call. The header is built now (before',\n 'funding confirms), so its short validity window starts here — call mcp__haven__haven_settle_mcp_tool promptly,',\n 'and re-run mcp__haven__haven_pay_mcp_tool with the same idempotency_key if a tool returns PAYMENT_WINDOW_EXPIRED.',\n 'The returned x402_binding is ALREADY SPENT — this tool consumed it building payment_header —',\n 'so never pass it to mcp__haven-signer__haven_x402_sign_header; that tool is the follow-up to',\n 'haven_sign, not to this one. payment_header IS the header to use.',\n 'Next: for a paid MCP tool, call mcp__haven__haven_settle_mcp_tool. For a direct plain-HTTP x402',\n 'merchant (the haven_pay_x402_quote path), relay signature via mcp__haven__haven_submit and then',\n 'retry the original merchant URL YOURSELF, setting BOTH PAYMENT-SIGNATURE (x402 v2) and',\n 'X-PAYMENT (v1) to payment_header — Haven never contacts that merchant.',\n].join(' ')\n\nconst SIGN_SWEEP_DELEGATE_DESCRIPTION = [\n 'Sign a Haven-prepared gasless USDC sweep that recovers stranded funds from the delegate',\n \"wallet back to the agent's account (Haven wallet). The delegate key never leaves this process and this\",\n \"tool never broadcasts — it returns only an EIP-3009 signature that Haven's relayer submits and\",\n 'pays gas for. Pass the authorization and expected_auth returned by the hosted',\n 'haven_sweep_delegate tool. The signer verifies Haven authored the authorization; the',\n \"destination is checked against the agent's account (Haven wallet) from the local credential\",\n \"when the credential carries one, and otherwise rests on Haven's binding signature. Then it\",\n 'returns { signature } to hand back to mcp__haven__haven_sweep_delegate to complete recovery.',\n].join(' ')\n\nexport const toolDescriptions: Record<SignerToolName, string> = {\n haven_sign: SIGN_DESCRIPTION,\n haven_x402_sign_header: X402_SIGN_HEADER_DESCRIPTION,\n haven_sign_x402: SIGN_X402_DESCRIPTION,\n haven_sign_sweep_delegate: SIGN_SWEEP_DELEGATE_DESCRIPTION,\n}\n\n/** Map the wire-shaped x402_expected (snake_case) to the EdgeSigner's camelCase context. */\n/**\n * Sign the x402 funding leg (#1138). Every x402 funding intent is now\n * delegation-rail typed data (#3272 criterion 8: the bare-hash v1 rail and\n * `signX402FundingHash` are retired) — `signX402FundingTypedData` itself\n * refuses a v1 context (no `typedDataHash`) with the structured\n * version-mismatch error, whether or not `typedData` was supplied, so this\n * function does no rail selection of its own.\n */\nasync function signFundingLeg(\n signer: EdgeSigner,\n expected: X402ExpectedPayment,\n typedData: Record<string, unknown> | undefined,\n): Promise<X402FundingSignatureResult> {\n try {\n return await signer.signX402FundingTypedData(typedData as unknown as X402FundingTypedData | undefined, expected)\n } catch (err) {\n // #3281: the x402 arm's shape refusals come from the shared SDK guard;\n // give them the same structured envelopes the unbound branch uses.\n if (err instanceof HavenTypedDataRefusedError && !(err instanceof HavenTypedDataNotAllowedError)) {\n throw new HavenTypedDataNotAllowedError(err.message)\n }\n if (err instanceof HavenUserOpBindingError) {\n throw new HavenUserOpBindingRefusedError(err.message)\n }\n throw err\n }\n}\n\nfunction toExpectedX402(raw: {\n payment_id: string\n payload_hash: string\n resource_url: string\n merchant_to: string\n amount: string\n asset: string\n network: string\n // Required at the tool boundary (see x402ExpectedSchema): it's folded into the\n // Haven-signed binding message. The EdgeSigner's internal type keeps it\n // optional because it skips the window check when absent.\n expires_at: string\n typed_data_hash?: string\n payer_delegate?: string\n payer_agent_id?: string\n auth: X402ExpectedPayment['auth']\n}): X402ExpectedPayment {\n return {\n paymentId: raw.payment_id,\n payloadHash: raw.payload_hash,\n typedDataHash: raw.typed_data_hash,\n payerDelegate: raw.payer_delegate,\n payerAgentId: raw.payer_agent_id,\n resourceUrl: raw.resource_url,\n merchantTo: raw.merchant_to,\n amount: raw.amount,\n asset: raw.asset,\n network: raw.network,\n expiresAt: raw.expires_at,\n auth: raw.auth,\n }\n}\n\n/**\n * Validate a FETCHED expected context (#1263) against the same boundary schema\n * a tool argument passes through — provenance does not skip validation. A\n * malformed response names the fallback instead of leaking a Zod stack.\n */\nfunction parseFetchedExpected(\n fetched: FetchedSignContext,\n): Parameters<typeof toExpectedX402>[0] {\n const parsed = z.object(x402ExpectedShape).safeParse(fetched.x402Expected)\n if (!parsed.success) {\n throw new HavenSigningError(\n 'The Haven sign-context response carried a malformed x402_expected — the backend may ' +\n 'predate #1263. Pass payload_hash + x402_expected from the quote result instead. ' +\n `Underlying: ${parsed.error.issues[0]?.message ?? 'schema mismatch'}`,\n )\n }\n return parsed.data as Parameters<typeof toExpectedX402>[0]\n}\n\nexport interface ToolSuccess<T> {\n success: true\n data: T\n}\n\nexport interface ToolFailure {\n success: false\n code: string\n message: string\n statusCode?: number\n paymentId?: string\n next_action?: string\n retry_with_new_quote?: boolean\n suggested_tool?: string\n /** #3101 (epic #3105, decision 7): the typed next-step family, additive; `next_tool` never null. */\n next_tool?: string\n next_tool_server?: string\n next_tool_name?: string\n next_tool_server_role?: 'hosted' | 'signer'\n next_arguments?: Record<string, unknown>\n next_tool_omitted_reason?: string\n /**\n * #1309: present on `UNSUPPORTED_EXPECTED_CONTEXT_VERSION` /\n * `UNSUPPORTED_SWEEP_BINDING_VERSION` refusals — the exact version set this\n * signer install enforces, derived from `SUPPORTED_X402_EXPECTED_VERSIONS` /\n * `SUPPORTED_SWEEP_BINDING_VERSIONS` at the throw site.\n */\n supported_versions?: number[]\n /** #1309: the version Haven sent that triggered the refusal above. */\n received_version?: number\n /**\n * #1309: precise recovery guidance as DATA, not just prose inside `message`\n * — the same text the hosted quote's advisory `signer_compatibility.fallback`\n * carries when the refusal is an out-of-date signer. #3001 reuses this same\n * field for every sign-context refusal (`'typed_data_b64'`).\n */\n fallback?: string\n /**\n * #3001: present on `SIGN_CONTEXT_REFUSED` — the HTTP status the backend\n * answered the sign-context fetch with (404, 410, …) — the x402 fetch, or\n * the direct `/payments/:id/sign-context` fetch since #3271.\n */\n http_status?: number\n /** #3001: the backend's own `error_code` on `SIGN_CONTEXT_REFUSED` (`expired`, `already_executed`, `not_signable`, `sign_context_unavailable`, and since #3303 `client_outdated`). */\n backend_error_code?: string\n /** #3303: on `client_outdated`, the backend's update hint — `upgrade_command` is what updates this signer. */\n client_update?: HavenClientUpdate\n}\n\nexport type ToolPayload<T = unknown> = ToolSuccess<T> | ToolFailure\n\n/**\n * #3303: the backend's update hint from a successful sign-context read, carried\n * onto the signing result so an agent on an outdated signer reads the update\n * command on the call it made. Empty when the signer is current.\n */\nfunction clientUpdateField(\n resolved: { ctx: { clientUpdate?: HavenClientUpdate } } | null,\n): { client_update?: HavenClientUpdate } {\n return resolved?.ctx.clientUpdate ? { client_update: resolved.ctx.clientUpdate } : {}\n}\n\nexport interface ToolHandlerOptions {\n audit?: SigningAuditContext & { auditPath: string }\n /**\n * #1263: how the payment_id signing path reaches Haven. Lives at the MCP\n * server layer (the core stays network-free); absent → payment_id calls\n * refuse with a message naming the typed_data_b64 fallback.\n */\n signContext?: {\n loadIdentity: () => Promise<HavenIdentity | null>\n fetchImpl?: typeof fetch\n /** #3303: `@haven_ai/signer/<version>`, sent as `X-Haven-Client` on every sign-context read. */\n clientIdentity?: string\n }\n}\n\n/**\n * Resolve the delegation-rail signing payload from the tool arguments (#1255).\n *\n * `typed_data_b64` wins over `typed_data`: it is the copy-through-safe form —\n * one opaque string the agent relays unchanged, instead of re-emitting multi-KB\n * nested JSON (a redemption UserOp's callData) between two tool calls. The live\n * #1255 failure was exactly that: the payload arrived altered, the x402 digest\n * check refused it (correctly), and the purchase died with no defect anywhere\n * in the chain. The decoded object goes through the SAME verification as a\n * plain typed_data downstream — this changes the transport, never the trust\n * model. On the x402 funding leg that verification was already a digest check\n * against the Haven-signed expected context (#1138); on the DIRECT-payment\n * `PackedUserOperation` path it is #3271's binding check against the payment's\n * own `payload_hash` — before #3271 that path had no digest check at all, so\n * an altered direct-payment payload signed silently instead of refusing.\n */\nfunction resolveTypedData(args: {\n typed_data?: Record<string, unknown>\n typed_data_b64?: string\n}): Record<string, unknown> | undefined {\n if (!args.typed_data_b64) return args.typed_data\n try {\n const decoded = JSON.parse(\n Buffer.from(args.typed_data_b64, 'base64').toString('utf8'),\n ) as unknown\n if (!decoded || typeof decoded !== 'object' || Array.isArray(decoded)) {\n throw new Error('decoded value is not an object')\n }\n return decoded as Record<string, unknown>\n } catch (err) {\n throw new HavenSigningError(\n 'typed_data_b64 did not decode to a JSON object. Pass the exact string returned by the ' +\n 'hosted Haven tool, unchanged — do not re-encode, trim, or reformat it. ' +\n `Underlying error: ${err instanceof Error ? err.message : String(err)}`,\n )\n }\n}\n\nexport function createToolHandlers(\n signer: EdgeSigner,\n options: ToolHandlerOptions = {},\n): Record<SignerToolName, (input: unknown) => Promise<ToolPayload>> {\n function checkPayloadHashMatch(\n suppliedHash: string | undefined,\n fetchedHash: string,\n paymentId: string,\n ): void {\n if (suppliedHash && suppliedHash.toLowerCase() !== fetchedHash.toLowerCase()) {\n throw new HavenSigningError(\n 'The supplied payload_hash does not match the signing context Haven serves for ' +\n `payment ${paymentId}. Pass payment_id alone, or check which quote the ` +\n 'hash came from.',\n )\n }\n }\n\n /**\n * #1263 / #3271: resolve the signing inputs for a payment_id call by\n * fetching the exact bytes from Haven. Returns null when the caller did not\n * use the payment_id path. The fetched payload is untrusted input like any\n * tool argument — it still goes through the binding verification and digest\n * re-derivation downstream; this only changes HOW the bytes arrive.\n *\n * Tries the x402 sign-context first, always — x402 behaviour is unchanged.\n * `haven_sign` (never `haven_sign_x402`) additionally falls back to the\n * direct-payment sign-context (`GET /payments/:id/sign-context`) when the\n * backend refuses the x402 fetch with its 409 `sign_context_unavailable` —\n * the shape this payment_id names a direct payment, not an x402 intent.\n */\n async function resolveSignContext(\n args: { payment_id?: string; payload_hash?: string },\n opts: { allowDirectFallback: boolean },\n ): Promise<\n | { kind: 'x402'; ctx: FetchedSignContext }\n | { kind: 'direct'; ctx: FetchedDirectSignContext }\n | null\n > {\n if (!args.payment_id) return null\n const identity = (await options.signContext?.loadIdentity()) ?? null\n if (!identity) {\n throw new HavenSigningError(\n 'payment_id signing needs the agent identity (identity.json next to the signer ' +\n `credentials), which this signer could not load. Re-run \\`${connectorRerunCommand()}\\` ` +\n 'to restore it, or pass typed_data_b64 from the quote result instead.',\n )\n }\n try {\n const ctx = await fetchX402SignContext(\n identity,\n args.payment_id,\n options.signContext?.fetchImpl,\n undefined,\n options.signContext?.clientIdentity,\n )\n checkPayloadHashMatch(args.payload_hash, ctx.payloadHash, args.payment_id)\n return { kind: 'x402', ctx }\n } catch (err) {\n if (\n opts.allowDirectFallback &&\n err instanceof HavenSignContextError &&\n err.http_status === 409 &&\n err.backend_error_code === 'sign_context_unavailable'\n ) {\n let ctx: FetchedDirectSignContext\n try {\n ctx = await fetchDirectSignContext(\n identity,\n args.payment_id,\n options.signContext?.fetchImpl,\n undefined,\n options.signContext?.clientIdentity,\n )\n } catch (directErr) {\n // The x402 route also answers 409 `sign_context_unavailable` for an\n // x402 row it cannot serve (legacy rail). The direct route then\n // 409s back with the same code, pointing at the x402 route: the\n // x402 refusal is the real reason, so surface that one.\n if (\n directErr instanceof HavenSignContextError &&\n directErr.http_status === 409 &&\n directErr.backend_error_code === 'sign_context_unavailable'\n ) {\n throw err\n }\n throw directErr\n }\n checkPayloadHashMatch(args.payload_hash, ctx.payloadHash, args.payment_id)\n return { kind: 'direct', ctx }\n }\n throw err\n }\n }\n\n return {\n haven_sign: async (input) =>\n runTool(async () => {\n const args = parse('haven_sign', coerceX402Expected(input))\n // #3271: only haven_sign falls back to the direct-payment\n // sign-context; haven_sign_x402 never does (below).\n const resolved = await resolveSignContext(args, { allowDirectFallback: true })\n const typedData = resolved?.ctx.typedData ?? resolveTypedData(args)\n const payloadHash = resolved?.ctx.payloadHash ?? args.payload_hash\n if (!payloadHash) {\n throw new HavenSigningError(\n 'Pass payment_id (preferred for delegation-rail x402 or direct payments) or payload_hash.',\n )\n }\n // A direct-payment fetch (`resolved.kind === 'direct'`) carries no\n // x402 expected context at all — it must not reach\n // parseFetchedExpected, which assumes the x402 shape.\n const expectedRaw =\n resolved?.kind === 'x402'\n ? parseFetchedExpected(resolved.ctx)\n : resolved?.kind === 'direct'\n ? null\n : args.x402_expected\n const x402Expected = expectedRaw ? toExpectedX402(expectedRaw) : null\n const result = x402Expected\n ? await signFundingLeg(signer, x402Expected, typedData)\n : null\n if (!result) {\n // #1254: a DIRECT delegation-rail payment carries typed_data and no\n // x402 context — the account validates the TYPED DATA, and a raw\n // signature over payload_hash is rejected on-chain (AA24, found\n // live). When typed_data is present it is what gets signed. There is\n // no raw-hash path any more (#3169): the AllowanceModule rail it\n // served is retired, and signing caller-supplied bytes with no\n // shape to inspect was a blind-signing oracle for the delegate key.\n if (typedData) {\n // #1476: a DELEGATION payload is an authority grant to a third\n // party — the erc7710 settlement child, whose signature lets a\n // merchant's facilitator pull from the treasury. It must never be\n // signed without a Haven-signed expected context to verify against\n // (#1455), and until now nothing stopped that: whether the child\n // got verified depended on WHICH TOOL the caller happened to use,\n // which is a convention, not a boundary.\n //\n // Keyed off the payload's own shape rather than the caller's\n // choice, so #1254's direct-payment UserOp case is untouched: that\n // is the account validating its OWN operation, not a grant.\n if (isSettlementChildTypedData(typedData)) {\n throw new HavenSigningError(\n 'Refusing to sign a delegation payload with no expected context. This typed data ' +\n 'is a DELEGATION — signing it grants a third party authority to move funds — so ' +\n 'it is only ever signed against a Haven-signed context that the caveats are ' +\n 'verified against. Call this tool with { payment_id } instead (the signer then ' +\n 'fetches and verifies the context itself), or use haven_sign_x402.',\n )\n }\n // #3272: the allowlist. This branch signs EXACTLY ONE shape — a\n // direct-payment PackedUserOperation — and nothing else, however\n // it is dressed up (a probe with an invented domain, a delegate\n // TransferWithAuthorization, a USDC Permit, …). Everything that\n // is not that shape is refused before either check below runs.\n if (resolved?.kind !== 'direct' && !isPackedUserOperationTypedData(typedData)) {\n throw new HavenTypedDataNotAllowedError(\n 'This signer signs only Haven-prepared payloads: a direct-payment ' +\n 'PackedUserOperation from your own account that redeems a delegation granted to it, ' +\n 'or a Haven-signed x402 context. Call haven_sign with payment_id ' +\n '(preferred), or pass x402_expected for an x402 funding leg.',\n )\n }\n // #3271: the digest check that binds this exact typed data to its\n // own payload_hash, in the HybridDeleGator domain of its own\n // sender, against the v0.7 EntryPoint. Runs whether the bytes\n // arrived by tool argument or by the payment_id fetch above; a\n // corrupted payload is refused here, before a signature over the\n // wrong digest is produced. Necessary, never sufficient — a\n // self-consistent forgery binds perfectly to itself, which is\n // exactly what #3272's allowlist below closes.\n try {\n assertUserOpTypedDataBinding(typedData, payloadHash)\n } catch (err) {\n if (err instanceof HavenUserOpBindingError) {\n throw new HavenUserOpBindingRefusedError(err.message)\n }\n throw err\n }\n // #3272: content + provenance — the ONE operation this branch may\n // ever sign: redeeming a single delegation granted to the agent's\n // own account, from that account, on a chain the delegation rail runs on.\n assertBoundDirectPaymentUserOp(typedData, signer.delegateAddress)\n const signature = await signer.signDelegationTypedData(typedData)\n // #3272 (criterion 4): audit the digest actually signed — the\n // EIP-712 hash of this typed data — never the caller-supplied\n // payload_hash (the ERC-4337 UserOp hash, a DIFFERENT value the\n // #3271 check above merely cross-checked this typed data against).\n await auditSigning('haven_sign', hashTypedData(typedData as Parameters<typeof hashTypedData>[0]))\n return { signature, ...clientUpdateField(resolved) }\n }\n // #3169: bare hash, nothing to verify against — refused, never signed.\n // Not audited as a signing operation: nothing was signed.\n throw new HavenBareHashRefusedError()\n }\n // #3272 (criterion 4): audit the digest actually signed. `result`\n // only exists here because signFundingLeg succeeded, which requires\n // `typedData` to be present and hashed — never the caller-supplied\n // payload_hash, a different value the expected-context binding\n // merely cross-checks this typed data against.\n await auditSigning('haven_sign', hashTypedData(typedData as Parameters<typeof hashTypedData>[0]))\n return { signature: result.signature, x402_binding: result.x402Binding, ...clientUpdateField(resolved) }\n }),\n\n haven_x402_sign_header: async (input) =>\n runTool(async () => {\n // Defensive: the object-typed schema makes conformant MCP clients embed\n // payment_required as JSON, but some transports still serialise it to a\n // string. Coerce it back to an object BEFORE Zod validation so the\n // tightened schema doesn't reject it (else `.accepts` would be undefined\n // → \"No compatible payment option found\").\n const args = parse('haven_x402_sign_header', coercePaymentRequired(input))\n const result = await signer.buildX402PaymentHeader(\n args.payment_required as X402PaymentRequired,\n args.x402_binding,\n )\n await auditSigning(\n 'haven_x402_sign_header',\n hashPayloadForAudit(args.payment_required),\n )\n return { payment_header: result.paymentHeader, accepted: result.accepted }\n }),\n\n haven_sign_x402: async (input) =>\n runTool(async () => {\n // Coerce a stringified payment_required (same transport guard as\n // haven_x402_sign_header) and unwrap a whole-`x402`-object x402_expected\n // before validation.\n const args = parse('haven_sign_x402', coerceX402Expected(coercePaymentRequired(input)))\n // #3271: haven_sign_x402 NEVER falls back to the direct-payment\n // sign-context — a payment_id that names a direct payment has no\n // x402 context to fund a merchant retry with, so it is refused here\n // exactly as an unreachable/malformed fetch already was.\n const resolved = await resolveSignContext(args, { allowDirectFallback: false })\n const fetched = resolved?.kind === 'x402' ? resolved.ctx : undefined\n const payloadHash = fetched?.payloadHash ?? args.payload_hash\n const expectedRaw = fetched ? parseFetchedExpected(fetched) : args.x402_expected\n if (!payloadHash || !expectedRaw) {\n throw new HavenSigningError(\n 'Pass payment_id (preferred — the signer fetches the signing context itself) ' +\n 'or payload_hash + x402_expected from the quote result.',\n )\n }\n // 1. Sign the funding leg (records the binding + checks expiry/context).\n const fundingTypedData = fetched?.typedData ?? resolveTypedData(args)\n const funding = await signFundingLeg(signer, toExpectedX402(expectedRaw), fundingTypedData)\n // 2. Build the merchant EIP-3009 header against that binding — local, no network.\n // #1355: prefer the PaymentRequired the context fetch carried (same\n // Haven read the signing bytes came from — one less blob an agent\n // relays); the caller-supplied copy is the fallback for pre-#1355\n // backends. Either copy passes the SAME expected-context\n // verification inside buildX402PaymentHeader — provenance is not\n // what makes it safe (#1263 discipline).\n const paymentRequired = (fetched?.paymentRequired ?? args.payment_required) as\n | X402PaymentRequired\n | undefined\n if (!paymentRequired) {\n throw new HavenSigningError(\n fetched\n ? 'The Haven sign-context for this payment_id carried no payment_required ' +\n '(backend predates #1355). Pass payment_required from the pay result ' +\n 'explicitly, verbatim.'\n : 'payment_required is required on the quote-based path (no payment_id to fetch ' +\n 'it by). Pass it verbatim from the quote result.',\n )\n }\n const header = await signer.buildX402PaymentHeader(\n paymentRequired,\n funding.x402Binding,\n )\n // Two audit entries — one per signing operation — matching the\n // decomposed haven_sign + haven_x402_sign_header trail, so the funding\n // signature and the merchant header remain distinguishable in the log.\n // #3272 (criterion 4): the funding entry records the digest actually\n // signed — `fundingTypedData` is guaranteed present here, since\n // `signFundingLeg` above would otherwise have refused.\n await auditSigning(\n 'haven_sign_x402',\n hashTypedData(fundingTypedData as Parameters<typeof hashTypedData>[0]),\n )\n await auditSigning('haven_sign_x402', hashPayloadForAudit(paymentRequired))\n return {\n signature: funding.signature,\n x402_binding: funding.x402Binding,\n payment_header: header.paymentHeader,\n accepted: header.accepted,\n ...clientUpdateField(resolved),\n }\n }),\n\n haven_sign_sweep_delegate: async (input) =>\n runTool(async () => {\n const args = parse('haven_sign_sweep_delegate', input)\n const result = await signer.signSweepAuthorization({\n authorization: args.authorization,\n expectedAuth: args.expected_auth,\n // Cross-check `to` against the agent's account (Haven wallet) from the\n // local credential, when the credential carries one.\n expectedSafe: options.audit?.accountAddress,\n })\n await auditSigning(\n 'haven_sign_sweep_delegate',\n hashPayloadForAudit(args.authorization),\n )\n return { signature: result.signature }\n }),\n }\n\n async function auditSigning(tool: SignerToolName, payloadHash: string): Promise<void> {\n if (!options.audit) return\n const { auditPath, ...context } = options.audit\n try {\n await appendSigningAuditEntry(\n createSigningAuditEntry(tool, payloadHash, {\n ...context,\n delegateAddress: signer.delegateAddress,\n }),\n auditPath,\n )\n } catch (err) {\n // #3172 review: the audit is written AFTER the key has signed. A\n // filesystem failure here (disk full, read-only, a rotation race) must\n // not turn a produced signature into a failed tool call — the agent\n // would re-quote and re-sign for nothing. Say so on stderr instead.\n const message = err instanceof Error ? err.message : String(err)\n process.stderr.write(`haven-signer: warning: audit entry for ${tool} could not be written to ${auditPath}: ${message}\\n`)\n }\n }\n}\n\nfunction parse<TName extends SignerToolName>(name: TName, input: unknown): Record<string, any> {\n return z.object(toolSchemas[name]).parse(input ?? {})\n}\n\n/**\n * Tolerate the agent passing the whole `x402` object from haven_pay_mcp_tool /\n * haven_pay_x402_quote where only the nested `x402.expected` signing context is\n * wanted. The wrapper looks like `{ accepted, resource_url, merchant_to,\n * funding_to, expected: {...} }` and lacks the top-level `auth` binding the\n * schema requires — so when `x402_expected.auth` is absent but\n * `x402_expected.expected` is an object, unwrap to `.expected`. Also parses a\n * JSON-stringified value back to an object first (some transports stringify\n * object args). This removes the easiest-to-make handoff mistake without a\n * breaking parameter rename.\n */\nfunction coerceX402Expected(input: unknown): unknown {\n if (!input || typeof input !== 'object') return input\n const record = input as Record<string, unknown>\n let value: unknown = record.x402_expected\n if (typeof value === 'string') {\n try {\n value = JSON.parse(value)\n } catch {\n return input\n }\n }\n if (!value || typeof value !== 'object') return input\n const obj = value as Record<string, unknown>\n if (obj.auth === undefined && obj.expected && typeof obj.expected === 'object') {\n return { ...record, x402_expected: obj.expected }\n }\n // Parsed-from-string but already the right shape: keep the parsed object.\n if (value !== record.x402_expected) return { ...record, x402_expected: value }\n return input\n}\n\n/**\n * If a caller's transport serialised `payment_required` to a JSON string,\n * parse it back to an object before schema validation. Leaves a real object\n * (or anything that isn't valid JSON) untouched.\n */\nfunction coercePaymentRequired(input: unknown): unknown {\n if (!input || typeof input !== 'object') return input\n const record = input as Record<string, unknown>\n if (typeof record.payment_required !== 'string') return input\n try {\n return { ...record, payment_required: JSON.parse(record.payment_required) }\n } catch {\n return input\n }\n}\n\nasync function runTool<T>(fn: () => Promise<T>): Promise<ToolPayload<T>> {\n try {\n return { success: true, data: await fn() }\n } catch (err) {\n return normalizeError(err)\n }\n}\n\nfunction normalizeError(err: unknown): ToolFailure {\n if (err instanceof z.ZodError) {\n return {\n success: false,\n code: 'INVALID_INPUT',\n message: err.errors.map((e) => `${e.path.join('.') || '(root)'}: ${e.message}`).join('; '),\n statusCode: 400,\n }\n }\n if (err instanceof HavenUnsupportedSignerVersionError) {\n // #1309: the structured signer refusal. `code` is one of\n // SignerRefusalCode's two values (not the generic 'SIGNING_ERROR'\n // HavenSigningError hard-codes), so an agent can route on it directly\n // instead of matching prose. next_action reuses the EXISTING\n // AgentPaymentNextAction taxonomy (StopAndTellUser) rather than inventing\n // a parallel vocabulary — this refusal is exactly that: stop, don't retry\n // as-is, tell the user what fallback says.\n return {\n success: false,\n code: err.code,\n message: err.message,\n supported_versions: [...err.supportedVersions],\n received_version: err.receivedVersion,\n fallback: err.fallback,\n next_action: AgentPaymentNextAction.StopAndTellUser,\n // #3103: no tool can fix a version skew from inside the call.\n ...nextStepWireFields(signerRefusalStep({\n nextAction: AgentPaymentNextAction.StopAndTellUser,\n nextTool: null,\n nextToolOmittedReason: 'update @haven_ai/signer by re-running the connector, then repeat the same call',\n })),\n }\n }\n if (err instanceof HavenBareHashRefusedError) {\n // #3169: the bare-hash refusal, structured like the others. Checked BEFORE\n // the `HavenSigningError` branch below since this class extends it.\n return {\n success: false,\n code: err.code,\n message: err.message,\n next_action: err.next_action,\n ...nextStepWireFields(err.step),\n }\n }\n if (err instanceof HavenUserOpBindingRefusedError) {\n // #3271: the UserOp binding-mismatch refusal, structured like the others.\n // Checked BEFORE the `HavenSigningError` branch below since this class\n // extends it.\n return {\n success: false,\n code: err.code,\n message: err.message,\n next_action: err.next_action,\n ...nextStepWireFields(err.step),\n }\n }\n if (err instanceof HavenTypedDataNotAllowedError) {\n // #3272: the unbound-branch allowlist refusal, structured like the\n // others. Checked BEFORE the `HavenSigningError` branch below since this\n // class extends it.\n return {\n success: false,\n code: err.code,\n message: err.message,\n next_action: err.next_action,\n ...nextStepWireFields(err.step),\n }\n }\n if (err instanceof HavenSignContextError) {\n // #3001: every fetchX402SignContext refusal (timeout, unreachable, a\n // non-ok backend response, a malformed body) — structured the same way as\n // the version-mismatch refusal below, instead of the generic\n // `{ code: 'SIGNING_ERROR' }` a plain HavenSigningError produces. Checked\n // BEFORE the `HavenSigningError` branch below since this class extends it.\n return {\n success: false,\n code: err.code,\n message: err.message,\n next_action: err.next_action,\n ...(err.fallback !== undefined ? { fallback: err.fallback } : {}),\n ...(err.retry_with_new_quote ? { retry_with_new_quote: true } : {}),\n ...(err.http_status !== undefined ? { http_status: err.http_status } : {}),\n ...(err.backend_error_code !== undefined ? { backend_error_code: err.backend_error_code } : {}),\n ...(err.client_update ? { client_update: err.client_update } : {}),\n // #3103: the typed step the error decided beside its action.\n ...(err.next_tool ? { next_tool: err.next_tool } : {}),\n ...(err.next_tool_server ? { next_tool_server: err.next_tool_server } : {}),\n ...(err.next_tool_name ? { next_tool_name: err.next_tool_name } : {}),\n ...(err.next_tool_server_role ? { next_tool_server_role: err.next_tool_server_role } : {}),\n ...(err.next_arguments ? { next_arguments: err.next_arguments } : {}),\n ...(err.next_tool_omitted_reason ? { next_tool_omitted_reason: err.next_tool_omitted_reason } : {}),\n }\n }\n if (err instanceof HavenSigningError) {\n return { success: false, code: err.code, message: err.message }\n }\n if (err instanceof HavenApiError) {\n return { success: false, code: err.code, message: err.message, statusCode: err.statusCode }\n }\n if (err instanceof HavenError) {\n return {\n success: false,\n code: err.code,\n message: err.message,\n statusCode: err.statusCode,\n paymentId: err.paymentId,\n ...(err.code === AgentPaymentFailureCode.PaymentWindowExpired\n ? {\n next_action: AgentPaymentNextAction.PaymentWindowExpired,\n retry_with_new_quote: true,\n suggested_tool: 'haven_pay_mcp_tool',\n // #3103: same omission as the hosted window-expired helper.\n ...nextStepWireFields(signerRefusalStep({\n nextAction: AgentPaymentNextAction.PaymentWindowExpired,\n nextTool: null,\n nextToolOmittedReason: 're-run the hosted quote tool you called with the same idempotency_key; which one depends on the flow (suggested_tool names the MCP one)',\n })),\n }\n : {}),\n }\n }\n return {\n success: false,\n code: 'UNKNOWN_ERROR',\n message: err instanceof Error ? err.message : String(err),\n }\n}\n","import { createHash } from 'node:crypto'\nimport { mkdir, readFile, writeFile } from 'node:fs/promises'\nimport { dirname, resolve } from 'node:path'\nimport { toolSchemas, type SignerToolName } from './tools.js'\n\n/**\n * #3173: one human-sized line per tool for the consent block. The full\n * `toolDescriptions` are LLM-addressed operating instructions (~4.8 KB across\n * the four) and were rendered verbatim into what is a person's one-time\n * approval screen. These summarise WHAT each tool signs; the descriptions stay\n * the agent's. Not part of the consent hash (which covers tool NAMES), so\n * editing a summary never re-prompts anyone. `consent.test.ts` pins that every\n * registered tool has one.\n */\nexport const toolSummaries: Record<SignerToolName, string> = {\n haven_sign: 'signs one Haven-prepared payment (a direct-payment UserOp from your own account whose only call redeems a delegation made to it, or an x402 funding intent against a Haven-signed context)',\n haven_x402_sign_header: 'builds and signs the EIP-3009 merchant payment header for an x402 payment',\n haven_sign_x402: 'the two above in one call: funding payload + merchant header',\n haven_sign_sweep_delegate: 'signs a Haven-prepared gasless sweep of stranded funds back to your own account',\n}\n\n/** #3173: what an operator who was wired by the connector should run when this signer refuses. */\nexport const CONNECTOR_DOCTOR_HINT = [\n 'Wired by the Haven connector (Claude Desktop, Codex, ...)? Diagnose and repair with: npx @haven_ai/connect --doctor',\n \" (the doctor shows this as a failed 'Signer stdio handshake' check; the connector's setup outcome reports it as\",\n \" local_signer_ack_required; the repair is the connector's --ack-local-tools).\",\n].join('\\n')\n\nexport interface SignerConsentInput {\n delegateAddress: string\n accountAddress?: string\n agentId?: string\n chainId?: number\n network?: string\n toolNames: readonly SignerToolName[]\n}\n\nexport interface SignerConsentDecision {\n ok: boolean\n hash: string\n reason:\n | 'env_var_match'\n | 'ack_file_match'\n | 'wrote_ack_file'\n | 'env_var_mismatch'\n | 'no_acknowledgement'\n}\n\nexport interface SignerConsentOptions {\n credentialsPath?: string\n writeAck?: boolean\n env?: Record<string, string | undefined>\n out?: { write: (chunk: string) => unknown }\n}\n\nexport const SIGNER_ACK_ENV = 'HAVEN_SIGNER_ACK'\n\n/**\n * The consent SURFACE version, folded into the acknowledgement hash. Bump it\n * when what the signer can DO changes in a way the consent text describes —\n * not for copy edits. Tool names alone cannot carry this: #1263 added the\n * signer's first network capability (the read-only signing-context fetch)\n * without changing any tool name, and a consent acknowledged under the old\n * \"does not call the Haven API\" text must not silently cover the new\n * behavior. Bumping this re-prompts every existing install exactly once,\n * with the corrected text.\n *\n * v2: the #1263 read-only signing-context fetch.\n */\nexport const SIGNER_CONSENT_SURFACE_VERSION = 2\n\nexport function computeSignerConsentHash(input: SignerConsentInput): string {\n const identity = [\n input.delegateAddress.toLowerCase(),\n (input.accountAddress ?? '').toLowerCase(),\n input.agentId ?? '',\n input.chainId ?? '',\n input.network ?? '',\n ].join('|')\n const toolCanonical = [...input.toolNames].sort().join(',')\n return createHash('sha256')\n .update(`${identity}\\n${toolCanonical}\\nsurface:v${SIGNER_CONSENT_SURFACE_VERSION}`)\n .digest('hex')\n .slice(0, 16)\n}\n\nexport function renderSignerConsentBlock(input: SignerConsentInput, hash: string): string {\n const lines: string[] = [\n '',\n '------------------------------------------------------------',\n 'Haven edge signer - first-launch consent',\n '------------------------------------------------------------',\n '',\n `Delegate address: ${input.delegateAddress}`,\n ]\n lines.push(`Haven wallet: ${input.accountAddress ?? 'not provided to this signer'}`)\n if (input.agentId) lines.push(`Agent ID: ${input.agentId}`)\n if (typeof input.chainId === 'number') lines.push(`Chain ID: ${input.chainId}`)\n if (input.network) lines.push(`Network: ${input.network}`)\n lines.push('')\n lines.push('This local signer holds the delegate key on this machine and signs')\n lines.push('payment payloads or x402 merchant headers for the delegate address above.')\n lines.push(\"Its one network use is a read-only fetch of a pending payment's signing\")\n lines.push('payload from Haven, authenticated with the agent credential stored next to')\n lines.push(\"this signer's key file - it never sends the key, a signature, or anything\")\n lines.push('else outbound, and it cannot show a live allowance summary.')\n lines.push(\"The agent's signed budget delegation is the real spend gate, and the wallet\")\n lines.push('owner can pause or revoke agent authority outside this signer.')\n lines.push('')\n lines.push('Tools this signer will expose to your agent runtime (one line each; the')\n lines.push('full agent-facing descriptions are what the runtime sees):')\n for (const name of input.toolNames) {\n lines.push(` - ${name}: ${toolSummaries[name]}`)\n }\n lines.push('')\n lines.push('A local audit entry is appended for every signing operation. Audit entries')\n lines.push('record timestamp, tool, payload hash, and delegate address; never the key,')\n lines.push('signature, or x402 payment header.')\n lines.push('')\n lines.push(`Consent hash: ${hash}`)\n lines.push('')\n lines.push('To acknowledge, EITHER:')\n lines.push(` - set ${SIGNER_ACK_ENV}=${hash} in this process's environment, OR`)\n lines.push(' - re-run with --ack to write the acknowledgement next to your')\n lines.push(' credential file (sidecar <credentials>.signer-ack.json).')\n lines.push('')\n lines.push(CONNECTOR_DOCTOR_HINT)\n lines.push('')\n lines.push('------------------------------------------------------------')\n lines.push('')\n return lines.join('\\n')\n}\n\nexport async function ensureSignerConsent(\n input: SignerConsentInput,\n options: SignerConsentOptions = {},\n): Promise<SignerConsentDecision> {\n const env = options.env ?? process.env\n const out = options.out ?? process.stderr\n const hash = computeSignerConsentHash(input)\n const envAck = env[SIGNER_ACK_ENV]\n\n if (typeof envAck === 'string' && envAck.length > 0) {\n if (envAck === hash) return { ok: true, hash, reason: 'env_var_match' }\n out.write(renderSignerConsentBlock(input, hash))\n out.write(\n `${SIGNER_ACK_ENV} was set but did not match the current signer consent hash.\\n` +\n `Expected: ${hash}\\n` +\n `Got: ${envAck}\\n` +\n `Re-acknowledge with the new hash above, or run with --ack.\\n\\n`,\n )\n return { ok: false, hash, reason: 'env_var_mismatch' }\n }\n\n const ackPath = sidecarPath(options.credentialsPath)\n if (ackPath) {\n const stored = await readAckFile(ackPath)\n if (stored?.ack === hash) return { ok: true, hash, reason: 'ack_file_match' }\n }\n\n if (options.writeAck && ackPath) {\n out.write(renderSignerConsentBlock(input, hash))\n await writeAckFile(ackPath, hash)\n out.write(`Wrote acknowledgement to ${ackPath}\\n\\n`)\n return { ok: true, hash, reason: 'wrote_ack_file' }\n }\n\n out.write(renderSignerConsentBlock(input, hash))\n return { ok: false, hash, reason: 'no_acknowledgement' }\n}\n\nexport function registeredSignerToolNames(): SignerToolName[] {\n return Object.keys(toolSchemas) as SignerToolName[]\n}\n\nfunction sidecarPath(credentialsPath?: string): string | null {\n if (!credentialsPath) return null\n return resolve(`${credentialsPath}.signer-ack.json`)\n}\n\nasync function readAckFile(path: string): Promise<{ ack?: string } | null> {\n try {\n const raw = await readFile(path, 'utf8')\n const parsed = JSON.parse(raw) as { ack?: unknown }\n return { ack: typeof parsed.ack === 'string' ? parsed.ack : undefined }\n } catch {\n return null\n }\n}\n\nasync function writeAckFile(path: string, hash: string): Promise<void> {\n await mkdir(dirname(path), { recursive: true })\n await writeFile(\n path,\n JSON.stringify({ ack: hash, at: new Date().toISOString() }, null, 2),\n 'utf8',\n )\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { defaultSigningAuditPath } from './audit.js'\nimport { signerCapabilityAdvertisement, signerInstructions } from './capabilities.js'\nimport {\n ensureSignerConsent,\n registeredSignerToolNames,\n type SignerConsentDecision,\n} from './consent.js'\nimport { havenClientIdentity, isSupportedNodeVersion, unsupportedNodeVersionMessage } from '@haven_ai/sdk/edge'\nimport { createEdgeSigner, type EdgeSigner } from './core.js'\nimport { loadSignerCredentials, type SignerCredentials } from './credentials.js'\nimport {\n createToolHandlers,\n toolDescriptions,\n toolSchemas,\n type SignerToolName,\n type ToolPayload,\n} from './tools.js'\nimport { loadHavenIdentity } from './sign-context.js'\n\nexport const SIGNER_NAME = '@haven_ai/signer'\nexport const SIGNER_VERSION = '0.5.0-alpha.1'\n\nexport interface SignerOptions {\n /** Path to a Haven credential JSON file (delegate_key is read from it). */\n credentialsPath?: string\n /** Pre-resolved delegate key (skips credential loading). */\n delegateKey?: string\n /** Append local signing audit entries here. Defaults to a credential sidecar or ~/.haven. */\n auditPath?: string\n /** Overridable so the Node-floor refusal is testable without spawning a Node. */\n nodeVersion?: string\n /**\n * When true, write the consent sidecar file (`<credentials>.signer-ack.json`)\n * with the current consent hash and proceed. Surfaced via the `--ack` CLI flag.\n */\n writeAck?: boolean\n /**\n * When true, skip the consent gate entirely. Reserved for tests and controlled\n * embedding — production CLIs should not set this.\n */\n skipConsent?: boolean\n /** Override consent environment lookup. Reserved for tests and controlled embedding. */\n consentEnv?: Record<string, string | undefined>\n /** Override the stream the consent block is printed to. Reserved for tests. */\n consentOut?: { write: (chunk: string) => unknown }\n /** Trusted Haven signer address for x402 expected-context bindings. */\n x402BindingSigner?: string\n}\n\nexport async function resolveEdgeSigner(options: SignerOptions = {}): Promise<EdgeSigner> {\n const { signer } = await resolveSignerRuntime(options)\n return signer\n}\n\nexport interface ResolvedSignerRuntime {\n signer: EdgeSigner\n credentials?: SignerCredentials\n}\n\nexport async function resolveSignerRuntime(\n options: SignerOptions = {},\n): Promise<ResolvedSignerRuntime> {\n // The choke point, deliberately (#1161 review). Every public way to obtain a\n // key-bound EdgeSigner from this package funnels through here —\n // `runSignerStdioServer`, `resolveEdgeSigner`, and any embedder calling it\n // directly (the `skipConsent` docs invite controlled embedding, so that is a\n // supported surface, not just a test seam). Asserting only in the stdio\n // entrypoint would have reproduced the exact bug this issue fixes: a guard\n // that exists but sits on one path while another reaches the delegate key\n // unchecked.\n //\n // First statement, before the `delegateKey` fast path and before credentials\n // are read, so an unsupported runtime never touches a key by either route.\n assertSupportedNodeVersion(options.nodeVersion)\n\n if (options.delegateKey) {\n return {\n signer: createEdgeSigner(options.delegateKey, {\n x402BindingSigner: options.x402BindingSigner ?? process.env.HAVEN_X402_BINDING_SIGNER,\n }),\n }\n }\n const creds = await loadSignerCredentials(options.credentialsPath)\n return {\n signer: createEdgeSigner(creds.delegateKey, {\n x402BindingSigner:\n options.x402BindingSigner ?? creds.x402BindingSigner ?? process.env.HAVEN_X402_BINDING_SIGNER,\n // #1690: the signer's own agent id, so a payer-mismatch refusal can name\n // both sides. The bare-delegateKey path above has no credential file and\n // therefore no agent id — the guard still works there, on addresses.\n agentId: creds.agentId,\n }),\n credentials: creds,\n }\n}\n\n/**\n * Build a local stdio MCP server exposing the sign-only tools, bound to an\n * edge signer that holds the delegate key. It exposes no construct/relay\n * tools — it only signs. Its ONE network capability (#1263) is an\n * authenticated READ: fetching a payment's exact signing context from Haven\n * by payment_id, so agents never have to relay multi-KB signing payloads\n * through a model context. The signer CORE below it stays network-free, and\n * fetched bytes pass the same verification as tool-argument bytes.\n */\nexport function buildSignerMcpServer(\n signer: EdgeSigner,\n options: Pick<SignerOptions, 'auditPath'> & { credentials?: SignerCredentials } = {},\n): McpServer {\n // #1155: the handshake states what this signer can verify, so an agent can\n // detect expected-context skew before it quotes rather than after it signs.\n // `SIGNER_VERSION` is a *package* version and nothing derives capability from\n // it — both fields below are derived from the constants the signing path\n // enforces. Advisory only: no refusal is added here, the #1143 signing-time\n // guard remains the enforcement point.\n const server = new McpServer(\n { name: SIGNER_NAME, version: SIGNER_VERSION },\n {\n capabilities: signerCapabilityAdvertisement(),\n instructions: signerInstructions(),\n },\n )\n\n const credentialsPath = options.credentials?.sourcePath\n const handlers = createToolHandlers(signer, {\n audit: {\n auditPath: options.auditPath ?? defaultSigningAuditPath(credentialsPath),\n delegateAddress: signer.delegateAddress,\n accountAddress: options.credentials?.accountAddress,\n chainId: options.credentials?.chainId,\n },\n // #1263: the payment_id signing path — the ONLY network path this server\n // has: up to two authenticated reads of a signing context from Haven (x402,\n // then direct for haven_sign, #3271), using\n // the agent identity the connector stores next to the signer credential.\n // The signer CORE stays network-free; fetched bytes still pass the same\n // binding verification + digest re-derivation as tool-argument bytes.\n signContext: {\n loadIdentity: () => loadHavenIdentity(credentialsPath),\n // #3303: the backend refuses a signer below a minimum it has set, at\n // sign-context — the one place this signer meets it.\n clientIdentity: havenClientIdentity(SIGNER_NAME, SIGNER_VERSION),\n },\n })\n const registerTool = (server as unknown as {\n tool: (\n name: string,\n description: string,\n schema: unknown,\n handler: (args: unknown) => Promise<unknown>,\n ) => void\n }).tool.bind(server)\n\n for (const name of Object.keys(toolSchemas) as SignerToolName[]) {\n registerTool(name, toolDescriptions[name], toolSchemas[name], async (args: unknown) =>\n toMcpResult(await handlers[name](args)),\n )\n }\n\n return server\n}\n\n/**\n * Refuse to start on an unsupported Node (#1161).\n *\n * Asserted at STARTUP, not only at install, because the two can diverge: a user\n * upgrades Node, connects successfully, then downgrades — or a version manager\n * hands the agent runtime a different Node than the shell that ran setup. Only a\n * startup check sees the version this process is actually running on.\n *\n * This is the signer, so refusing is the conservative answer rather than the\n * aggressive one. It holds the delegate key and produces every payment\n * signature; on an unsupported runtime the plausible failure is a wrong or\n * absent signature, which is worse than not starting. The consent gate below\n * takes the same posture for the same reason.\n */\nexport function assertSupportedNodeVersion(nodeVersion: string = process.versions.node): void {\n if (isSupportedNodeVersion(nodeVersion)) return\n const err: NodeJS.ErrnoException = new Error(\n unsupportedNodeVersionMessage({ subject: 'The Haven signer', nodeVersion }),\n )\n err.code = 'HAVEN_SIGNER_UNSUPPORTED_NODE'\n throw err\n}\n\nexport async function runSignerStdioServer(options: SignerOptions = {}): Promise<void> {\n // The Node floor is asserted inside resolveSignerRuntime — the choke point\n // every key-bound path shares — so it is enforced here too, before\n // credentials are read, without a second call site to keep in sync.\n const { signer, credentials } = await resolveSignerRuntime(options)\n\n if (!options.skipConsent) {\n const decision = await runSignerConsentGate(signer, credentials, options)\n if (!decision.ok) {\n // #3173: an MCP host shows only this message (and \"Connection closed\");\n // the consent block above went to stderr. Name the connector's doctor,\n // which diagnoses exactly this state, so the operator has a next step.\n const err: NodeJS.ErrnoException = new Error(\n (decision.reason === 'env_var_mismatch'\n ? 'Haven edge signer consent acknowledgement does not match the current configuration.'\n : 'Haven edge signer requires a one-time consent acknowledgement before starting.') +\n ' See the consent block above; if the Haven connector wired this signer, run: npx @haven_ai/connect --doctor',\n )\n err.code = 'HAVEN_SIGNER_NO_CONSENT'\n throw err\n }\n }\n\n const server = buildSignerMcpServer(signer, { credentials, auditPath: options.auditPath })\n await server.connect(new StdioServerTransport())\n}\n\nexport async function runSignerConsentGate(\n signer: EdgeSigner,\n credentials: SignerCredentials | undefined,\n options: SignerOptions,\n): Promise<SignerConsentDecision> {\n return ensureSignerConsent(\n {\n delegateAddress: signer.delegateAddress,\n accountAddress: credentials?.accountAddress,\n agentId: credentials?.agentId,\n chainId: credentials?.chainId,\n network: credentials?.network,\n toolNames: registeredSignerToolNames(),\n },\n {\n credentialsPath: options.credentialsPath ?? credentials?.sourcePath,\n writeAck: options.writeAck,\n env: options.consentEnv,\n out: options.consentOut,\n },\n )\n}\n\nfunction toMcpResult(payload: ToolPayload) {\n return {\n isError: !payload.success,\n content: [{ type: 'text' as const, text: JSON.stringify(payload, null, 2) }],\n }\n}\n"]}
|