@haven_ai/signer 0.1.15-alpha.0 → 0.1.17-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.cjs CHANGED
@@ -70,7 +70,11 @@ var x402ExpectedSchema = v3.z.object({
70
70
  amount: v3.z.string().min(1),
71
71
  asset: v3.z.string().min(1),
72
72
  network: v3.z.string().min(1),
73
- expires_at: v3.z.string().min(1).optional(),
73
+ // Required: expires_at is folded into the Haven-signed binding message, so the
74
+ // signer must receive the exact same value to reconstruct a matching message.
75
+ // Omitting it used to fail downstream with a cryptic "authentication message is
76
+ // invalid" — making it required surfaces a clear INVALID_INPUT at the boundary.
77
+ expires_at: v3.z.string().min(1),
74
78
  auth: v3.z.object({
75
79
  version: v3.z.literal(1),
76
80
  message: v3.z.string().min(1),
@@ -134,8 +138,8 @@ var SIGN_X402_DESCRIPTION = [
134
138
  "One-shot x402 signing for the fast 3-call flow: sign the funding hash AND build the EIP-3009",
135
139
  "X-PAYMENT header in a single local call (equivalent to haven_sign followed by",
136
140
  "haven_x402_sign_header). The delegate key never leaves this process. From the haven_pay_mcp_tool",
137
- "result pass payload_hash, x402_expected (the nested x402.expected object, not a top-level field),",
138
- "and payment_required (verbatim). Returns",
141
+ "result pass payload_hash, x402_expected (the nested x402.expected object \u2014 passing the whole x402",
142
+ "object is also accepted and unwrapped for you), and payment_required (verbatim). Returns",
139
143
  "{ signature, x402_binding, payment_header, accepted }; hand signature + payment_header to",
140
144
  "mcp__haven__haven_settle_mcp_tool to fund and settle in one hosted call. The header is built now (before",
141
145
  "funding confirms), so its short validity window starts here \u2014 call mcp__haven__haven_settle_mcp_tool promptly,",
@@ -173,7 +177,7 @@ function toExpectedX402(raw) {
173
177
  function createToolHandlers(signer, options = {}) {
174
178
  return {
175
179
  haven_sign: async (input) => runTool(async () => {
176
- const args = parse("haven_sign", input);
180
+ const args = parse("haven_sign", coerceX402Expected(input));
177
181
  const x402Expected = args.x402_expected ? toExpectedX402(args.x402_expected) : null;
178
182
  const result = x402Expected ? signer.signX402FundingHash(args.payload_hash, x402Expected) : null;
179
183
  if (!result) {
@@ -197,7 +201,7 @@ function createToolHandlers(signer, options = {}) {
197
201
  return { payment_header: result.paymentHeader, accepted: result.accepted };
198
202
  }),
199
203
  haven_sign_x402: async (input) => runTool(async () => {
200
- const args = parse("haven_sign_x402", coercePaymentRequired(input));
204
+ const args = parse("haven_sign_x402", coerceX402Expected(coercePaymentRequired(input)));
201
205
  const funding = signer.signX402FundingHash(args.payload_hash, toExpectedX402(args.x402_expected));
202
206
  const header = await signer.buildX402PaymentHeader(
203
207
  args.payment_required,
@@ -242,6 +246,25 @@ function createToolHandlers(signer, options = {}) {
242
246
  function parse(name, input) {
243
247
  return v3.z.object(toolSchemas[name]).parse(input ?? {});
244
248
  }
249
+ function coerceX402Expected(input) {
250
+ if (!input || typeof input !== "object") return input;
251
+ const record = input;
252
+ let value = record.x402_expected;
253
+ if (typeof value === "string") {
254
+ try {
255
+ value = JSON.parse(value);
256
+ } catch {
257
+ return input;
258
+ }
259
+ }
260
+ if (!value || typeof value !== "object") return input;
261
+ const obj = value;
262
+ if (obj.auth === void 0 && obj.expected && typeof obj.expected === "object") {
263
+ return { ...record, x402_expected: obj.expected };
264
+ }
265
+ if (value !== record.x402_expected) return { ...record, x402_expected: value };
266
+ return input;
267
+ }
245
268
  function coercePaymentRequired(input) {
246
269
  if (!input || typeof input !== "object") return input;
247
270
  const record = input;
@@ -708,7 +731,7 @@ async function warnIfCredentialFilePermissive(path, log = (message) => process.s
708
731
 
709
732
  // src/server.ts
710
733
  var SIGNER_NAME = "@haven_ai/signer";
711
- var SIGNER_VERSION = "0.1.15-alpha.0";
734
+ var SIGNER_VERSION = "0.1.17-alpha.0";
712
735
  async function resolveSignerRuntime(options = {}) {
713
736
  if (options.delegateKey) {
714
737
  return {
package/dist/cli.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/audit.ts","../src/tools.ts","../src/consent.ts","../src/core.ts","../src/credentials.ts","../src/server.ts","../src/cli.ts"],"names":["resolve","homedir","path","mkdir","dirname","appendFile","createHash","z","HavenSigningError","HavenApiError","HavenError","AgentPaymentFailureCode","AgentPaymentNextAction","readFile","writeFile","addressFromKey","signHash","verifySignature","randomUUID","selectStandardPaymentOption","privateKeyToAccount","toStandardPaymentRequirements","exact","decodeBase64Json","encodeBase64Json","buildSweepTypedData","recoverTypedDataAddress","buildSweepAuthorizationMessage","hashMessage","x402AuthorizationAmount","buildX402ExpectedMessage","stat","McpServer","StdioServerTransport"],"mappings":"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","file":"cli.cjs","sourcesContent":["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 safe_address?: string\n chain_id?: number\n}\n\nexport interface SigningAuditContext {\n delegateAddress: string\n safeAddress?: 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.safeAddress) entry.safe_address = context.safeAddress\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 {\n AgentPaymentFailureCode,\n AgentPaymentNextAction,\n HavenApiError,\n HavenError,\n HavenSigningError,\n type X402PaymentRequired,\n} from '@haven_ai/sdk'\nimport { z } from 'zod/v3'\nimport {\n appendSigningAuditEntry,\n createSigningAuditEntry,\n hashPayloadForAudit,\n type SigningAuditContext,\n} from './audit.js'\nimport type { EdgeSigner, X402ExpectedPayment } from './core.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\nconst sweepExpectedAuthSchema = z.object({\n version: z.literal(1),\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 x402ExpectedSchema = z.object({\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 expires_at: z.string().min(1).optional(),\n auth: z.object({\n version: z.literal(1),\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\nexport const toolSchemas: Record<SignerToolName, z.ZodRawShape> = {\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 // The unsigned hash from haven_pay / haven_pay_x402_quote (payload_hash).\n payload_hash: z\n .string()\n .regex(/^0x[0-9a-fA-F]+$/, 'payload_hash must be a 0x-prefixed hex string'),\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 },\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 // One-shot x402 signing: funding hash + merchant header in one local call.\n payload_hash: z\n .string()\n .regex(/^0x[0-9a-fA-F]+$/, 'payload_hash must be a 0x-prefixed hex string'),\n x402_expected: x402ExpectedSchema,\n payment_required: z.record(z.string(), z.unknown()),\n },\n}\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. 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 X-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. 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 }. Set X-PAYMENT: <payment_header> on your retry to the',\n 'merchant. 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 'X-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 payload_hash, x402_expected (the nested x402.expected object, not a top-level field),',\n 'and payment_required (verbatim). 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 'Next: call mcp__haven__haven_settle_mcp_tool.',\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. */\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 expires_at?: string\n auth: X402ExpectedPayment['auth']\n}): X402ExpectedPayment {\n return {\n paymentId: raw.payment_id,\n payloadHash: raw.payload_hash,\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\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}\n\nexport type ToolPayload<T = unknown> = ToolSuccess<T> | ToolFailure\n\nexport interface ToolHandlerOptions {\n audit?: SigningAuditContext & { auditPath: string }\n}\n\nexport function createToolHandlers(\n signer: EdgeSigner,\n options: ToolHandlerOptions = {},\n): Record<SignerToolName, (input: unknown) => Promise<ToolPayload>> {\n return {\n haven_sign: async (input) =>\n runTool(async () => {\n const args = parse('haven_sign', input)\n const x402Expected = args.x402_expected ? toExpectedX402(args.x402_expected) : null\n const result = x402Expected\n ? signer.signX402FundingHash(args.payload_hash, x402Expected)\n : null\n if (!result) {\n const signature = signer.signPaymentHash(args.payload_hash)\n await auditSigning('haven_sign', args.payload_hash)\n return { signature }\n }\n await auditSigning('haven_sign', args.payload_hash)\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) before validation.\n const args = parse('haven_sign_x402', coercePaymentRequired(input))\n // 1. Sign the funding hash (records the binding + checks expiry/context).\n const funding = signer.signX402FundingHash(args.payload_hash, toExpectedX402(args.x402_expected))\n // 2. Build the merchant EIP-3009 header against that binding — local, no network.\n const header = await signer.buildX402PaymentHeader(\n args.payment_required as X402PaymentRequired,\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', args.payload_hash)\n await auditSigning('haven_sign_x402', hashPayloadForAudit(args.payment_required))\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?.safeAddress,\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 * 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 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 }\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 safeAddress?: 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\nexport function computeSignerConsentHash(input: SignerConsentInput): string {\n const identity = [\n input.delegateAddress.toLowerCase(),\n (input.safeAddress ?? '').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}`)\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.safeAddress ?? '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('It does not call the Haven API, so 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 { randomUUID } from 'node:crypto'\nimport { hashMessage, recoverTypedDataAddress } from 'viem'\nimport { privateKeyToAccount } from 'viem/accounts'\nimport { exact } from 'x402/schemes'\nimport {\n addressFromKey,\n buildX402ExpectedMessage,\n buildSweepAuthorizationMessage,\n buildSweepTypedData,\n signHash,\n verifySignature,\n selectStandardPaymentOption,\n toStandardPaymentRequirements,\n x402AuthorizationAmount,\n decodeBase64Json,\n encodeBase64Json,\n AgentPaymentFailureCode,\n HavenError,\n HavenSigningError,\n HavenApiError,\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 /** Sign an x402 funding hash and remember the funded merchant-header context. */\n signX402FundingHash(hash: string, expected: X402ExpectedPayment): 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\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 /** Resource URL that was funded by hosted haven_x402_authorize. */\n resourceUrl: string\n /** Merchant recipient that was funded by hosted haven_x402_authorize. */\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 /** 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\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 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 signX402FundingHash(hash: string, expected: X402ExpectedPayment): X402FundingSignatureResult {\n assertExpectedBinding(hash, expected, options.x402BindingSigner)\n const signature = signAndVerify(hash)\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 throw new HavenSigningError(\n 'x402 funding binding is required before signing a merchant header. Sign the hosted funding hash with x402_expected first.',\n )\n }\n try {\n assertX402PaymentWindowOpen(expected)\n } catch (err) {\n x402Bindings.delete(x402Binding)\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 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 const wrapped = encodeBase64Json({\n x402Version: paymentRequired.x402Version,\n accepted: option,\n payload: payment.payload,\n })\n return { paymentHeader: wrapped, accepted: option }\n } finally {\n x402Bindings.delete(x402Binding)\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, and only to its own Safe.\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 const message = buildSweepAuthorizationMessage(authorization)\n if (expectedAuth.version !== 1 || 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\nfunction assertExpectedBinding(\n payloadHash: 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 hashes.',\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 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 })\n if (expected.auth?.version !== 1 || 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\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 { readFile, stat } from 'node:fs/promises'\n\n/**\n * The edge signer only needs the delegate key — it signs, it does not call the\n * Haven API. Identity (the `api_key`) lives with the hosted MCP connection, not\n * here. So unlike `@haven_ai/mcp`, this loader requires *only* `delegate_key`.\n */\nexport interface SignerCredentials {\n delegateKey: string\n agentId?: string\n safeAddress?: 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 safe_address?: unknown\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 return {\n delegateKey: envKey,\n agentId: stringField(process.env.HAVEN_AGENT_ID),\n safeAddress: stringField(process.env.HAVEN_SAFE_ADDRESS),\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 return {\n delegateKey,\n agentId: stringField(raw.agent_id ?? raw.agentId),\n safeAddress: stringField(raw.safe_address ?? raw.safeAddress),\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\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 { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { defaultSigningAuditPath } from './audit.js'\nimport {\n ensureSignerConsent,\n registeredSignerToolNames,\n type SignerConsentDecision,\n} from './consent.js'\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'\n\nexport const SIGNER_NAME = '@haven_ai/signer'\nexport const SIGNER_VERSION = '0.1.15-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 /**\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 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 }),\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. This server performs no network\n * I/O and exposes no construct/relay tools — it only signs.\n */\nexport function buildSignerMcpServer(\n signer: EdgeSigner,\n options: Pick<SignerOptions, 'auditPath'> & { credentials?: SignerCredentials } = {},\n): McpServer {\n const server = new McpServer({ name: SIGNER_NAME, version: SIGNER_VERSION })\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 safeAddress: options.credentials?.safeAddress,\n chainId: options.credentials?.chainId,\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\nexport async function runSignerStdioServer(options: SignerOptions = {}): Promise<void> {\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 safeAddress: credentials?.safeAddress,\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","#!/usr/bin/env node\n\nimport { runSignerStdioServer, type SignerOptions } from './server.js'\n\nfunction parseArgs(argv: string[]): SignerOptions {\n const options: SignerOptions = {}\n for (let i = 0; i < argv.length; i += 1) {\n const arg = argv[i]\n if (arg === '--credentials' || arg === '--credentials-path') {\n options.credentialsPath = argv[i + 1]\n i += 1\n } else if (arg === '--ack') {\n options.writeAck = true\n } else if (arg === '--help' || arg === '-h') {\n process.stdout.write(\n [\n 'Haven edge signer (local, holds the delegate key)',\n '',\n 'Runs a local stdio MCP server exposing sign-only tools (haven_sign,',\n 'haven_x402_sign_header). Pair it with the hosted, keyless Haven MCP',\n 'server: the hosted server constructs and relays, this one signs.',\n '',\n 'Usage:',\n ' npx @haven_ai/signer --credentials /path/to/agent.json',\n '',\n 'Options:',\n ' --credentials <path> Haven credential JSON (delegate_key is read from it).',\n ' Also supported: HAVEN_CREDENTIALS, or HAVEN_DELEGATE_KEY.',\n ' --ack Acknowledge the first-launch consent block and write',\n ' a signer sidecar acknowledgement next to the credential.',\n '',\n 'Consent:',\n ' On first launch the signer prints the sign-only tool list and delegate',\n ' address, then refuses to start unless acknowledged. It has no API access,',\n ' so it cannot show a live allowance summary.',\n ' Acknowledge with EITHER --ack OR HAVEN_SIGNER_ACK=<hash> in your environment.',\n '',\n ].join('\\n'),\n )\n process.exit(0)\n }\n }\n return options\n}\n\nasync function main(): Promise<void> {\n await runSignerStdioServer(parseArgs(process.argv.slice(2)))\n}\n\nmain().catch((err) => {\n process.stderr.write(`${err instanceof Error ? err.message : String(err)}\\n`)\n process.exit(1)\n})\n"]}
1
+ {"version":3,"sources":["../src/audit.ts","../src/tools.ts","../src/consent.ts","../src/core.ts","../src/credentials.ts","../src/server.ts","../src/cli.ts"],"names":["resolve","homedir","path","mkdir","dirname","appendFile","createHash","z","HavenSigningError","HavenApiError","HavenError","AgentPaymentFailureCode","AgentPaymentNextAction","readFile","writeFile","addressFromKey","signHash","verifySignature","randomUUID","selectStandardPaymentOption","privateKeyToAccount","toStandardPaymentRequirements","exact","decodeBase64Json","encodeBase64Json","buildSweepTypedData","recoverTypedDataAddress","buildSweepAuthorizationMessage","hashMessage","x402AuthorizationAmount","buildX402ExpectedMessage","stat","McpServer","StdioServerTransport"],"mappings":"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","file":"cli.cjs","sourcesContent":["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 safe_address?: string\n chain_id?: number\n}\n\nexport interface SigningAuditContext {\n delegateAddress: string\n safeAddress?: 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.safeAddress) entry.safe_address = context.safeAddress\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 {\n AgentPaymentFailureCode,\n AgentPaymentNextAction,\n HavenApiError,\n HavenError,\n HavenSigningError,\n type X402PaymentRequired,\n} from '@haven_ai/sdk'\nimport { z } from 'zod/v3'\nimport {\n appendSigningAuditEntry,\n createSigningAuditEntry,\n hashPayloadForAudit,\n type SigningAuditContext,\n} from './audit.js'\nimport type { EdgeSigner, X402ExpectedPayment } from './core.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\nconst sweepExpectedAuthSchema = z.object({\n version: z.literal(1),\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 x402ExpectedSchema = z.object({\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 auth: z.object({\n version: z.literal(1),\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\nexport const toolSchemas: Record<SignerToolName, z.ZodRawShape> = {\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 // The unsigned hash from haven_pay / haven_pay_x402_quote (payload_hash).\n payload_hash: z\n .string()\n .regex(/^0x[0-9a-fA-F]+$/, 'payload_hash must be a 0x-prefixed hex string'),\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 },\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 // One-shot x402 signing: funding hash + merchant header in one local call.\n payload_hash: z\n .string()\n .regex(/^0x[0-9a-fA-F]+$/, 'payload_hash must be a 0x-prefixed hex string'),\n x402_expected: x402ExpectedSchema,\n payment_required: z.record(z.string(), z.unknown()),\n },\n}\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. 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 X-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. 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 }. Set X-PAYMENT: <payment_header> on your retry to the',\n 'merchant. 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 'X-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 payload_hash, x402_expected (the nested x402.expected object — passing the whole x402',\n 'object is also accepted and unwrapped for you), and payment_required (verbatim). 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 'Next: call mcp__haven__haven_settle_mcp_tool.',\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. */\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 auth: X402ExpectedPayment['auth']\n}): X402ExpectedPayment {\n return {\n paymentId: raw.payment_id,\n payloadHash: raw.payload_hash,\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\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}\n\nexport type ToolPayload<T = unknown> = ToolSuccess<T> | ToolFailure\n\nexport interface ToolHandlerOptions {\n audit?: SigningAuditContext & { auditPath: string }\n}\n\nexport function createToolHandlers(\n signer: EdgeSigner,\n options: ToolHandlerOptions = {},\n): Record<SignerToolName, (input: unknown) => Promise<ToolPayload>> {\n return {\n haven_sign: async (input) =>\n runTool(async () => {\n const args = parse('haven_sign', coerceX402Expected(input))\n const x402Expected = args.x402_expected ? toExpectedX402(args.x402_expected) : null\n const result = x402Expected\n ? signer.signX402FundingHash(args.payload_hash, x402Expected)\n : null\n if (!result) {\n const signature = signer.signPaymentHash(args.payload_hash)\n await auditSigning('haven_sign', args.payload_hash)\n return { signature }\n }\n await auditSigning('haven_sign', args.payload_hash)\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 // 1. Sign the funding hash (records the binding + checks expiry/context).\n const funding = signer.signX402FundingHash(args.payload_hash, toExpectedX402(args.x402_expected))\n // 2. Build the merchant EIP-3009 header against that binding — local, no network.\n const header = await signer.buildX402PaymentHeader(\n args.payment_required as X402PaymentRequired,\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', args.payload_hash)\n await auditSigning('haven_sign_x402', hashPayloadForAudit(args.payment_required))\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?.safeAddress,\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 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 }\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 safeAddress?: 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\nexport function computeSignerConsentHash(input: SignerConsentInput): string {\n const identity = [\n input.delegateAddress.toLowerCase(),\n (input.safeAddress ?? '').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}`)\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.safeAddress ?? '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('It does not call the Haven API, so 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 { randomUUID } from 'node:crypto'\nimport { hashMessage, recoverTypedDataAddress } from 'viem'\nimport { privateKeyToAccount } from 'viem/accounts'\nimport { exact } from 'x402/schemes'\nimport {\n addressFromKey,\n buildX402ExpectedMessage,\n buildSweepAuthorizationMessage,\n buildSweepTypedData,\n signHash,\n verifySignature,\n selectStandardPaymentOption,\n toStandardPaymentRequirements,\n x402AuthorizationAmount,\n decodeBase64Json,\n encodeBase64Json,\n AgentPaymentFailureCode,\n HavenError,\n HavenSigningError,\n HavenApiError,\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 /** Sign an x402 funding hash and remember the funded merchant-header context. */\n signX402FundingHash(hash: string, expected: X402ExpectedPayment): 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\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 /** Resource URL that was funded by hosted haven_x402_authorize. */\n resourceUrl: string\n /** Merchant recipient that was funded by hosted haven_x402_authorize. */\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 /** 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\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 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 signX402FundingHash(hash: string, expected: X402ExpectedPayment): X402FundingSignatureResult {\n assertExpectedBinding(hash, expected, options.x402BindingSigner)\n const signature = signAndVerify(hash)\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 throw new HavenSigningError(\n 'x402 funding binding is required before signing a merchant header. Sign the hosted funding hash with x402_expected first.',\n )\n }\n try {\n assertX402PaymentWindowOpen(expected)\n } catch (err) {\n x402Bindings.delete(x402Binding)\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 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 const wrapped = encodeBase64Json({\n x402Version: paymentRequired.x402Version,\n accepted: option,\n payload: payment.payload,\n })\n return { paymentHeader: wrapped, accepted: option }\n } finally {\n x402Bindings.delete(x402Binding)\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, and only to its own Safe.\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 const message = buildSweepAuthorizationMessage(authorization)\n if (expectedAuth.version !== 1 || 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\nfunction assertExpectedBinding(\n payloadHash: 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 hashes.',\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 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 })\n if (expected.auth?.version !== 1 || 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\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 { readFile, stat } from 'node:fs/promises'\n\n/**\n * The edge signer only needs the delegate key — it signs, it does not call the\n * Haven API. Identity (the `api_key`) lives with the hosted MCP connection, not\n * here. So unlike `@haven_ai/mcp`, this loader requires *only* `delegate_key`.\n */\nexport interface SignerCredentials {\n delegateKey: string\n agentId?: string\n safeAddress?: 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 safe_address?: unknown\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 return {\n delegateKey: envKey,\n agentId: stringField(process.env.HAVEN_AGENT_ID),\n safeAddress: stringField(process.env.HAVEN_SAFE_ADDRESS),\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 return {\n delegateKey,\n agentId: stringField(raw.agent_id ?? raw.agentId),\n safeAddress: stringField(raw.safe_address ?? raw.safeAddress),\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\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 { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { defaultSigningAuditPath } from './audit.js'\nimport {\n ensureSignerConsent,\n registeredSignerToolNames,\n type SignerConsentDecision,\n} from './consent.js'\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'\n\nexport const SIGNER_NAME = '@haven_ai/signer'\nexport const SIGNER_VERSION = '0.1.17-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 /**\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 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 }),\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. This server performs no network\n * I/O and exposes no construct/relay tools — it only signs.\n */\nexport function buildSignerMcpServer(\n signer: EdgeSigner,\n options: Pick<SignerOptions, 'auditPath'> & { credentials?: SignerCredentials } = {},\n): McpServer {\n const server = new McpServer({ name: SIGNER_NAME, version: SIGNER_VERSION })\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 safeAddress: options.credentials?.safeAddress,\n chainId: options.credentials?.chainId,\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\nexport async function runSignerStdioServer(options: SignerOptions = {}): Promise<void> {\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 safeAddress: credentials?.safeAddress,\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","#!/usr/bin/env node\n\nimport { runSignerStdioServer, type SignerOptions } from './server.js'\n\nfunction parseArgs(argv: string[]): SignerOptions {\n const options: SignerOptions = {}\n for (let i = 0; i < argv.length; i += 1) {\n const arg = argv[i]\n if (arg === '--credentials' || arg === '--credentials-path') {\n options.credentialsPath = argv[i + 1]\n i += 1\n } else if (arg === '--ack') {\n options.writeAck = true\n } else if (arg === '--help' || arg === '-h') {\n process.stdout.write(\n [\n 'Haven edge signer (local, holds the delegate key)',\n '',\n 'Runs a local stdio MCP server exposing sign-only tools (haven_sign,',\n 'haven_x402_sign_header). Pair it with the hosted, keyless Haven MCP',\n 'server: the hosted server constructs and relays, this one signs.',\n '',\n 'Usage:',\n ' npx @haven_ai/signer --credentials /path/to/agent.json',\n '',\n 'Options:',\n ' --credentials <path> Haven credential JSON (delegate_key is read from it).',\n ' Also supported: HAVEN_CREDENTIALS, or HAVEN_DELEGATE_KEY.',\n ' --ack Acknowledge the first-launch consent block and write',\n ' a signer sidecar acknowledgement next to the credential.',\n '',\n 'Consent:',\n ' On first launch the signer prints the sign-only tool list and delegate',\n ' address, then refuses to start unless acknowledged. It has no API access,',\n ' so it cannot show a live allowance summary.',\n ' Acknowledge with EITHER --ack OR HAVEN_SIGNER_ACK=<hash> in your environment.',\n '',\n ].join('\\n'),\n )\n process.exit(0)\n }\n }\n return options\n}\n\nasync function main(): Promise<void> {\n await runSignerStdioServer(parseArgs(process.argv.slice(2)))\n}\n\nmain().catch((err) => {\n process.stderr.write(`${err instanceof Error ? err.message : String(err)}\\n`)\n process.exit(1)\n})\n"]}
package/dist/cli.js CHANGED
@@ -68,7 +68,11 @@ var x402ExpectedSchema = z.object({
68
68
  amount: z.string().min(1),
69
69
  asset: z.string().min(1),
70
70
  network: z.string().min(1),
71
- expires_at: z.string().min(1).optional(),
71
+ // Required: expires_at is folded into the Haven-signed binding message, so the
72
+ // signer must receive the exact same value to reconstruct a matching message.
73
+ // Omitting it used to fail downstream with a cryptic "authentication message is
74
+ // invalid" — making it required surfaces a clear INVALID_INPUT at the boundary.
75
+ expires_at: z.string().min(1),
72
76
  auth: z.object({
73
77
  version: z.literal(1),
74
78
  message: z.string().min(1),
@@ -132,8 +136,8 @@ var SIGN_X402_DESCRIPTION = [
132
136
  "One-shot x402 signing for the fast 3-call flow: sign the funding hash AND build the EIP-3009",
133
137
  "X-PAYMENT header in a single local call (equivalent to haven_sign followed by",
134
138
  "haven_x402_sign_header). The delegate key never leaves this process. From the haven_pay_mcp_tool",
135
- "result pass payload_hash, x402_expected (the nested x402.expected object, not a top-level field),",
136
- "and payment_required (verbatim). Returns",
139
+ "result pass payload_hash, x402_expected (the nested x402.expected object \u2014 passing the whole x402",
140
+ "object is also accepted and unwrapped for you), and payment_required (verbatim). Returns",
137
141
  "{ signature, x402_binding, payment_header, accepted }; hand signature + payment_header to",
138
142
  "mcp__haven__haven_settle_mcp_tool to fund and settle in one hosted call. The header is built now (before",
139
143
  "funding confirms), so its short validity window starts here \u2014 call mcp__haven__haven_settle_mcp_tool promptly,",
@@ -171,7 +175,7 @@ function toExpectedX402(raw) {
171
175
  function createToolHandlers(signer, options = {}) {
172
176
  return {
173
177
  haven_sign: async (input) => runTool(async () => {
174
- const args = parse("haven_sign", input);
178
+ const args = parse("haven_sign", coerceX402Expected(input));
175
179
  const x402Expected = args.x402_expected ? toExpectedX402(args.x402_expected) : null;
176
180
  const result = x402Expected ? signer.signX402FundingHash(args.payload_hash, x402Expected) : null;
177
181
  if (!result) {
@@ -195,7 +199,7 @@ function createToolHandlers(signer, options = {}) {
195
199
  return { payment_header: result.paymentHeader, accepted: result.accepted };
196
200
  }),
197
201
  haven_sign_x402: async (input) => runTool(async () => {
198
- const args = parse("haven_sign_x402", coercePaymentRequired(input));
202
+ const args = parse("haven_sign_x402", coerceX402Expected(coercePaymentRequired(input)));
199
203
  const funding = signer.signX402FundingHash(args.payload_hash, toExpectedX402(args.x402_expected));
200
204
  const header = await signer.buildX402PaymentHeader(
201
205
  args.payment_required,
@@ -240,6 +244,25 @@ function createToolHandlers(signer, options = {}) {
240
244
  function parse(name, input) {
241
245
  return z.object(toolSchemas[name]).parse(input ?? {});
242
246
  }
247
+ function coerceX402Expected(input) {
248
+ if (!input || typeof input !== "object") return input;
249
+ const record = input;
250
+ let value = record.x402_expected;
251
+ if (typeof value === "string") {
252
+ try {
253
+ value = JSON.parse(value);
254
+ } catch {
255
+ return input;
256
+ }
257
+ }
258
+ if (!value || typeof value !== "object") return input;
259
+ const obj = value;
260
+ if (obj.auth === void 0 && obj.expected && typeof obj.expected === "object") {
261
+ return { ...record, x402_expected: obj.expected };
262
+ }
263
+ if (value !== record.x402_expected) return { ...record, x402_expected: value };
264
+ return input;
265
+ }
243
266
  function coercePaymentRequired(input) {
244
267
  if (!input || typeof input !== "object") return input;
245
268
  const record = input;
@@ -706,7 +729,7 @@ async function warnIfCredentialFilePermissive(path, log = (message) => process.s
706
729
 
707
730
  // src/server.ts
708
731
  var SIGNER_NAME = "@haven_ai/signer";
709
- var SIGNER_VERSION = "0.1.15-alpha.0";
732
+ var SIGNER_VERSION = "0.1.17-alpha.0";
710
733
  async function resolveSignerRuntime(options = {}) {
711
734
  if (options.delegateKey) {
712
735
  return {