@haven_ai/sdk 0.12.0-alpha.0 → 0.13.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/{base64-COaV1Sis.d.cts → base64-C3mJNLYR.d.cts} +2 -2
  2. package/dist/{base64-C5OrJLij.d.ts → base64-CxzIc3KH.d.ts} +2 -2
  3. package/dist/{chunk-V2ODMLDD.cjs → chunk-4Z7PKLFD.cjs} +35 -35
  4. package/dist/{chunk-V2ODMLDD.cjs.map → chunk-4Z7PKLFD.cjs.map} +1 -1
  5. package/dist/{chunk-WFTGZS24.js → chunk-CK6VRIPR.js} +3 -3
  6. package/dist/{chunk-WFTGZS24.js.map → chunk-CK6VRIPR.js.map} +1 -1
  7. package/dist/{chunk-7M3CIW7W.js → chunk-CXQ42FOA.js} +4 -4
  8. package/dist/{chunk-7M3CIW7W.js.map → chunk-CXQ42FOA.js.map} +1 -1
  9. package/dist/{chunk-ZA3NOSO2.cjs → chunk-LZHCIK7L.cjs} +2 -2
  10. package/dist/chunk-LZHCIK7L.cjs.map +1 -0
  11. package/dist/{chunk-UPEDQLAL.js → chunk-MI7LVP56.js} +2 -2
  12. package/dist/chunk-MI7LVP56.js.map +1 -0
  13. package/dist/{chunk-4JTLJVBS.cjs → chunk-Z5MTKU6O.cjs} +4 -4
  14. package/dist/{chunk-4JTLJVBS.cjs.map → chunk-Z5MTKU6O.cjs.map} +1 -1
  15. package/dist/edge.cjs +93 -93
  16. package/dist/edge.d.cts +4 -4
  17. package/dist/edge.d.ts +4 -4
  18. package/dist/edge.js +4 -4
  19. package/dist/index.cjs +347 -333
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.d.cts +10 -6
  22. package/dist/index.d.ts +10 -6
  23. package/dist/index.js +21 -7
  24. package/dist/index.js.map +1 -1
  25. package/dist/{receipt-DyUInpvF.d.ts → receipt-CTOPh2fm.d.ts} +1 -1
  26. package/dist/{receipt-Dy77vCea.d.cts → receipt-DwRqGjGb.d.cts} +1 -1
  27. package/dist/test-support.cjs +58 -21
  28. package/dist/test-support.cjs.map +1 -1
  29. package/dist/test-support.d.cts +47 -3
  30. package/dist/test-support.d.ts +47 -3
  31. package/dist/test-support.js +37 -3
  32. package/dist/test-support.js.map +1 -1
  33. package/dist/{types-CAvsjRKi.d.ts → types-3vUBmumz.d.cts} +19 -0
  34. package/dist/{types-CAvsjRKi.d.cts → types-3vUBmumz.d.ts} +19 -0
  35. package/package.json +2 -2
  36. package/dist/chunk-UPEDQLAL.js.map +0 -1
  37. package/dist/chunk-ZA3NOSO2.cjs.map +0 -1
@@ -1,4 +1,4 @@
1
- import { aZ as RawPaymentParties } from './types-CAvsjRKi.js';
1
+ import { aZ as RawPaymentParties } from './types-3vUBmumz.js';
2
2
 
3
3
  /**
4
4
  * Verifiable payment receipts.
@@ -1,4 +1,4 @@
1
- import { aZ as RawPaymentParties } from './types-CAvsjRKi.cjs';
1
+ import { aZ as RawPaymentParties } from './types-3vUBmumz.cjs';
2
2
 
3
3
  /**
4
4
  * Verifiable payment receipts.
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var chunk4JTLJVBS_cjs = require('./chunk-4JTLJVBS.cjs');
4
- var chunkZA3NOSO2_cjs = require('./chunk-ZA3NOSO2.cjs');
3
+ var chunkZ5MTKU6O_cjs = require('./chunk-Z5MTKU6O.cjs');
4
+ var chunkLZHCIK7L_cjs = require('./chunk-LZHCIK7L.cjs');
5
5
  var viem = require('viem');
6
6
  var ethers = require('ethers');
7
7
 
@@ -9,7 +9,7 @@ var ZERO_BYTES32 = `0x${"00".repeat(32)}`;
9
9
  var ROOT_AUTHORITY = `0x${"ff".repeat(32)}`;
10
10
  var DEFAULT_DELEGATOR = "0x98989898989898989898989898989898989898De";
11
11
  var DELEGATION_ARRAY_PARAM = [
12
- { type: "tuple[]", components: chunkZA3NOSO2_cjs.DELEGATION_TUPLE_COMPONENTS }
12
+ { type: "tuple[]", components: chunkLZHCIK7L_cjs.DELEGATION_TUPLE_COMPONENTS }
13
13
  ];
14
14
  var EXECUTE_ABI = [
15
15
  {
@@ -85,16 +85,16 @@ function buildBoundRedeemDelegationsCallData(options) {
85
85
  10000n
86
86
  );
87
87
  return viem.encodeFunctionData({
88
- abi: chunkZA3NOSO2_cjs.REDEEM_DELEGATIONS_ABI,
88
+ abi: chunkLZHCIK7L_cjs.REDEEM_DELEGATIONS_ABI,
89
89
  functionName: "redeemDelegations",
90
- args: [[permissionContext], [chunkZA3NOSO2_cjs.SINGLE_DEFAULT_MODE], [executionCallData]]
90
+ args: [[permissionContext], [chunkLZHCIK7L_cjs.SINGLE_DEFAULT_MODE], [executionCallData]]
91
91
  });
92
92
  }
93
93
  function buildEmptyPermissionContextRedemption(selfCallCallData) {
94
94
  return viem.encodeFunctionData({
95
- abi: chunkZA3NOSO2_cjs.REDEEM_DELEGATIONS_ABI,
95
+ abi: chunkLZHCIK7L_cjs.REDEEM_DELEGATIONS_ABI,
96
96
  functionName: "redeemDelegations",
97
- args: [[buildEmptyPermissionContext()], [chunkZA3NOSO2_cjs.SINGLE_DEFAULT_MODE], [selfCallCallData]]
97
+ args: [[buildEmptyPermissionContext()], [chunkLZHCIK7L_cjs.SINGLE_DEFAULT_MODE], [selfCallCallData]]
98
98
  });
99
99
  }
100
100
  function buildExecuteCallData(target, value, innerCallData) {
@@ -106,20 +106,20 @@ function buildExecuteCallData(target, value, innerCallData) {
106
106
  }
107
107
  function buildBoundDirectUserOp(options) {
108
108
  const chainId = options.chainId ?? 84532;
109
- const sender = options.sender ?? chunkZA3NOSO2_cjs.deriveDelegateAccountAddress(options.delegate);
109
+ const sender = options.sender ?? chunkLZHCIK7L_cjs.deriveDelegateAccountAddress(options.delegate);
110
110
  const callData = options.callData ?? buildExecuteCallData(
111
- options.target ?? chunkZA3NOSO2_cjs.DELEGATION_MANAGER,
111
+ options.target ?? chunkLZHCIK7L_cjs.DELEGATION_MANAGER,
112
112
  options.value ?? 0n,
113
113
  buildBoundRedeemDelegationsCallData({ delegate: sender, delegator: options.delegator })
114
114
  );
115
115
  const typedData = {
116
116
  domain: {
117
- name: chunkZA3NOSO2_cjs.HYBRID_DELEGATOR_DOMAIN_NAME,
118
- version: chunkZA3NOSO2_cjs.HYBRID_DELEGATOR_DOMAIN_VERSION,
117
+ name: chunkLZHCIK7L_cjs.HYBRID_DELEGATOR_DOMAIN_NAME,
118
+ version: chunkLZHCIK7L_cjs.HYBRID_DELEGATOR_DOMAIN_VERSION,
119
119
  chainId,
120
120
  verifyingContract: sender
121
121
  },
122
- types: { PackedUserOperation: chunkZA3NOSO2_cjs.PACKED_USER_OPERATION_FIELDS.map((field) => ({ ...field })) },
122
+ types: { PackedUserOperation: chunkLZHCIK7L_cjs.PACKED_USER_OPERATION_FIELDS.map((field) => ({ ...field })) },
123
123
  primaryType: "PackedUserOperation",
124
124
  message: {
125
125
  sender,
@@ -130,10 +130,10 @@ function buildBoundDirectUserOp(options) {
130
130
  preVerificationGas: "0",
131
131
  gasFees: ZERO_BYTES32,
132
132
  paymasterAndData: "0x",
133
- entryPoint: chunkZA3NOSO2_cjs.ENTRY_POINT_V07
133
+ entryPoint: chunkLZHCIK7L_cjs.ENTRY_POINT_V07
134
134
  }
135
135
  };
136
- const payloadHash = chunkZA3NOSO2_cjs.packedUserOperationHash(typedData);
136
+ const payloadHash = chunkLZHCIK7L_cjs.packedUserOperationHash(typedData);
137
137
  return { typedData, payloadHash, sender };
138
138
  }
139
139
  function buildSelfCallCallData(sender) {
@@ -151,7 +151,7 @@ function rebuildDirectUserOpForSender(fixtureTypedData, newSender) {
151
151
  const originalCallData = fixtureTypedData.message.callData;
152
152
  const { args: executeArgs } = viem.decodeFunctionData({ abi: EXECUTE_ABI, data: originalCallData });
153
153
  const execution = executeArgs[0];
154
- const { args: redeemArgs } = viem.decodeFunctionData({ abi: chunkZA3NOSO2_cjs.REDEEM_DELEGATIONS_ABI, data: execution.callData });
154
+ const { args: redeemArgs } = viem.decodeFunctionData({ abi: chunkLZHCIK7L_cjs.REDEEM_DELEGATIONS_ABI, data: execution.callData });
155
155
  const [permissionContexts, modes, executionCallDatas] = redeemArgs;
156
156
  const [delegations] = viem.decodeAbiParameters(DELEGATION_ARRAY_PARAM, permissionContexts[0]);
157
157
  const adjustedDelegations = delegations.map(
@@ -159,7 +159,7 @@ function rebuildDirectUserOpForSender(fixtureTypedData, newSender) {
159
159
  );
160
160
  const adjustedPermissionContext = viem.encodeAbiParameters(DELEGATION_ARRAY_PARAM, [adjustedDelegations]);
161
161
  const adjustedRedeemCallData = viem.encodeFunctionData({
162
- abi: chunkZA3NOSO2_cjs.REDEEM_DELEGATIONS_ABI,
162
+ abi: chunkLZHCIK7L_cjs.REDEEM_DELEGATIONS_ABI,
163
163
  functionName: "redeemDelegations",
164
164
  args: [[adjustedPermissionContext], modes, executionCallDatas]
165
165
  });
@@ -173,13 +173,13 @@ function rebuildDirectUserOpForSender(fixtureTypedData, newSender) {
173
173
  domain: { ...fixtureTypedData.domain, verifyingContract: newSender },
174
174
  message: { ...fixtureTypedData.message, sender: newSender, callData: adjustedCallData }
175
175
  };
176
- const payloadHash = chunkZA3NOSO2_cjs.packedUserOperationHash(typedData);
176
+ const payloadHash = chunkLZHCIK7L_cjs.packedUserOperationHash(typedData);
177
177
  return { typedData, payloadHash };
178
178
  }
179
179
  function buildFundingLegUserOp(options) {
180
- const sender = chunkZA3NOSO2_cjs.deriveDelegateAccountAddress(options.delegate);
180
+ const sender = chunkLZHCIK7L_cjs.deriveDelegateAccountAddress(options.delegate);
181
181
  const callData = buildExecuteCallData(
182
- chunkZA3NOSO2_cjs.DELEGATION_MANAGER,
182
+ chunkLZHCIK7L_cjs.DELEGATION_MANAGER,
183
183
  0n,
184
184
  buildBoundRedeemDelegationsCallData({
185
185
  delegate: sender,
@@ -212,7 +212,7 @@ function delegationDigest(signHash, chainId) {
212
212
  viem.keccak256(viem.toBytes("DelegationManager")),
213
213
  viem.keccak256(viem.toBytes("1")),
214
214
  BigInt(chainId),
215
- chunkZA3NOSO2_cjs.DELEGATION_MANAGER
215
+ chunkLZHCIK7L_cjs.DELEGATION_MANAGER
216
216
  ]
217
217
  )
218
218
  );
@@ -224,7 +224,7 @@ function signedErc7710Receipt(options = {}) {
224
224
  const delegate = new ethers.Wallet(options.delegateKey ?? RECEIPT_DELEGATE_KEY);
225
225
  const signature = delegate.signingKey.sign(delegationDigest(signHash, chainId)).serialized;
226
226
  return {
227
- version: chunk4JTLJVBS_cjs.RECEIPT_VERSION,
227
+ version: chunkZ5MTKU6O_cjs.RECEIPT_VERSION,
228
228
  paymentId: options.paymentId ?? "pay_3723",
229
229
  payment: {
230
230
  token: "USDC",
@@ -247,9 +247,45 @@ function signedErc7710Receipt(options = {}) {
247
247
  };
248
248
  }
249
249
 
250
+ // src/test-support/low-s.ts
251
+ var SECP256K1_HALF_N = 0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0n;
252
+ function parseEcdsaSignature(signature) {
253
+ if (!/^0x[0-9a-fA-F]*$/.test(signature)) {
254
+ throw new Error(`signature is not 0x-prefixed hex: ${signature.slice(0, 20)}\u2026`);
255
+ }
256
+ const hex = signature.slice(2);
257
+ if (hex.length % 2 !== 0) {
258
+ throw new Error(`signature has an odd number of hex digits (${hex.length})`);
259
+ }
260
+ const length = hex.length / 2;
261
+ if (length !== 65) {
262
+ throw new Error(`signature must be 65 bytes, got ${length}`);
263
+ }
264
+ return {
265
+ r: BigInt(`0x${hex.slice(0, 64)}`),
266
+ s: BigInt(`0x${hex.slice(64, 128)}`),
267
+ v: Number.parseInt(hex.slice(128, 130), 16),
268
+ length
269
+ };
270
+ }
271
+ function assertLowSSignature(signature) {
272
+ const parts = parseEcdsaSignature(signature);
273
+ if (parts.v !== 27 && parts.v !== 28) {
274
+ throw new Error(`signature v must be 27 or 28, got ${parts.v}`);
275
+ }
276
+ if (parts.s > SECP256K1_HALF_N) {
277
+ throw new Error(
278
+ `signature is high-s (malleable): s=0x${parts.s.toString(16)} exceeds n/2=0x${SECP256K1_HALF_N.toString(16)}`
279
+ );
280
+ }
281
+ return parts;
282
+ }
283
+
250
284
  exports.DEFAULT_DELEGATOR = DEFAULT_DELEGATOR;
251
285
  exports.OTHER_RECEIPT_KEY = OTHER_RECEIPT_KEY;
252
286
  exports.RECEIPT_DELEGATE_KEY = RECEIPT_DELEGATE_KEY;
287
+ exports.SECP256K1_HALF_N = SECP256K1_HALF_N;
288
+ exports.assertLowSSignature = assertLowSSignature;
253
289
  exports.buildBoundDirectUserOp = buildBoundDirectUserOp;
254
290
  exports.buildBoundRedeemDelegationsCallData = buildBoundRedeemDelegationsCallData;
255
291
  exports.buildChainPermissionContext = buildChainPermissionContext;
@@ -262,6 +298,7 @@ exports.buildPermissionContext = buildPermissionContext;
262
298
  exports.buildSelfCallCallData = buildSelfCallCallData;
263
299
  exports.buildSingleExecutionCallData = buildSingleExecutionCallData;
264
300
  exports.buildTransferExecutionCallData = buildTransferExecutionCallData;
301
+ exports.parseEcdsaSignature = parseEcdsaSignature;
265
302
  exports.rebuildDirectUserOpForSender = rebuildDirectUserOpForSender;
266
303
  exports.signedErc7710Receipt = signedErc7710Receipt;
267
304
  //# sourceMappingURL=test-support.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/test-support/direct-userop.ts","../src/test-support/signed-receipt.ts"],"names":["DELEGATION_TUPLE_COMPONENTS","encodeAbiParameters","encodePacked","encodeFunctionData","REDEEM_DELEGATIONS_ABI","SINGLE_DEFAULT_MODE","deriveDelegateAccountAddress","DELEGATION_MANAGER","HYBRID_DELEGATOR_DOMAIN_NAME","HYBRID_DELEGATOR_DOMAIN_VERSION","PACKED_USER_OPERATION_FIELDS","ENTRY_POINT_V07","packedUserOperationHash","decodeFunctionData","decodeAbiParameters","hashTypedData","keccak256","toBytes","concatHex","Wallet","RECEIPT_VERSION"],"mappings":"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","file":"test-support.cjs","sourcesContent":["/**\n * #3272 — a real-shaped, BOUND direct-payment `PackedUserOperation` for\n * signer tests: `sender` is the counterfactual delegate account for a given\n * owner EOA, and `callData` is `execute(DelegationManager, 0,\n * redeemDelegations(...))` with a REAL redemption shape — one non-empty\n * `Delegation`, `delegate` = the signer's own account, `delegator` = a\n * distinct treasury address, `ExecutionMode.SingleDefault`, an\n * `encodePacked(target,value,callData)` execution — mirroring\n * `packages/backend/src/rails/delegation-rail.ts`'s `prepareRedemption`.\n * Replaces the toy 2-field / empty-callData / empty-arrays fixtures the\n * allowlist correctly refuses (including the B1 empty-permission-context\n * bypass, `buildEmptyPermissionContextRedemption` below, kept ONLY to\n * reproduce that exact refusal in a test).\n *\n * Moved here from `@haven_ai/signer` by #3283 so the SDK, the signer,\n * `@haven_ai/mcp` and `mcp-server` share ONE guard-valid builder. Published\n * as the `@haven_ai/sdk/test-support` subpath only because a sibling\n * package's tests cannot import this file by relative path (each package's\n * `tsc` `rootDir` is its own `src`). Test fixtures, not a signing API:\n * nothing here signs, and nothing the SDK or signer runs imports it.\n */\nimport {\n decodeAbiParameters,\n decodeFunctionData,\n encodeAbiParameters,\n encodeFunctionData,\n encodePacked,\n hashTypedData,\n type Address,\n type Hex,\n} from 'viem'\nimport {\n ENTRY_POINT_V07,\n HYBRID_DELEGATOR_DOMAIN_NAME,\n HYBRID_DELEGATOR_DOMAIN_VERSION,\n PACKED_USER_OPERATION_FIELDS,\n packedUserOperationHash,\n} from '../userop-binding.js'\nimport { DELEGATION_MANAGER } from '../settlement-child.js'\nimport { deriveDelegateAccountAddress } from '../delegate-account.js'\nimport { DELEGATION_TUPLE_COMPONENTS, REDEEM_DELEGATIONS_ABI, SINGLE_DEFAULT_MODE } from '../redemption-guard.js'\n\nconst ZERO_BYTES32 = `0x${'00'.repeat(32)}` as const\n\n/** `Delegation.authority` sentinel for a root (unchained) delegation — `@metamask/delegation-core`'s `ROOT_AUTHORITY`. */\nconst ROOT_AUTHORITY: Hex = `0x${'ff'.repeat(32)}`\n\n/** Stand-in treasury address — distinct from any derived signer account, matching the real fixture's `delegator`. */\nexport const DEFAULT_DELEGATOR: Address = '0x98989898989898989898989898989898989898De' as Address\n\nconst DELEGATION_ARRAY_PARAM = [\n { type: 'tuple[]', components: DELEGATION_TUPLE_COMPONENTS },\n] as const\n\nconst EXECUTE_ABI = [\n {\n type: 'function',\n name: 'execute',\n inputs: [\n {\n name: '_execution',\n type: 'tuple',\n components: [\n { name: 'target', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'callData', type: 'bytes' },\n ],\n },\n ],\n outputs: [],\n stateMutability: 'payable',\n },\n] as const\n\nconst TRANSFER_ABI = [\n {\n type: 'function',\n name: 'transfer',\n inputs: [\n { name: 'to', type: 'address' },\n { name: 'amount', type: 'uint256' },\n ],\n outputs: [{ type: 'bool' }],\n stateMutability: 'nonpayable',\n },\n] as const\n\nexport interface DelegationOverrides {\n /** The redeemer this delegation authorises — normally the signer's own derived account. */\n delegate: Address\n /** Who granted it — must differ from `delegate` for a real (non-self) delegation. */\n delegator?: Address\n authority?: Hex\n caveats?: Array<{ enforcer: Address; terms: Hex; args: Hex }>\n salt?: bigint\n signature?: Hex\n}\n\n/** A single, well-formed `Delegation` tuple — the ONE-link chain Haven's backend redeems (`delegations: [[delegation]]`). */\nexport function buildDelegation(overrides: DelegationOverrides) {\n return {\n delegate: overrides.delegate,\n delegator: overrides.delegator ?? DEFAULT_DELEGATOR,\n authority: overrides.authority ?? ROOT_AUTHORITY,\n caveats: overrides.caveats ?? [\n // A real-shaped (if inert for test purposes) TimestampEnforcer term —\n // real budget delegations always carry at least one caveat.\n { enforcer: '0x1046bb45C8d673d4ea75321280DB34899413c069' as Address, terms: `0x${'00'.repeat(32)}` as Hex, args: '0x' as Hex },\n ],\n salt: overrides.salt ?? 1n,\n signature: overrides.signature ?? (`0x${'ab'.repeat(65)}` as Hex),\n }\n}\n\n/** `abi.encode(Delegation[])` for a ONE-delegation chain — a Haven-shaped permission context. */\nexport function buildPermissionContext(delegation: ReturnType<typeof buildDelegation>): Hex {\n return encodeAbiParameters(DELEGATION_ARRAY_PARAM, [[delegation]])\n}\n\n/** `abi.encode(Delegation[])` for a MULTI-link chain (leaf first) — never emitted by Haven. */\nexport function buildChainPermissionContext(chain: ReturnType<typeof buildDelegation>[]): Hex {\n return encodeAbiParameters(DELEGATION_ARRAY_PARAM, [chain])\n}\n\n/** `abi.encode(Delegation[])` for an EMPTY chain — the exact B1 bypass shape MetaMask's DelegationManager treats as self-authorised. */\nexport function buildEmptyPermissionContext(): Hex {\n return encodeAbiParameters(DELEGATION_ARRAY_PARAM, [[]])\n}\n\n/** `encodePacked(address,uint256,bytes)` — the single-execution calldata `ExecutionMode.SingleDefault` expects. */\nexport function buildSingleExecutionCallData(target: Address, value: bigint, innerCallData: Hex): Hex {\n return encodePacked(['address', 'uint256', 'bytes'], [target, value, innerCallData])\n}\n\n/** A real-shaped ERC-20 `transfer(to, amount)` execution — what a budget redemption actually spends. */\nexport function buildTransferExecutionCallData(token: Address, to: Address, amount: bigint): Hex {\n return buildSingleExecutionCallData(\n token,\n 0n,\n encodeFunctionData({ abi: TRANSFER_ABI, functionName: 'transfer', args: [to, amount] }),\n )\n}\n\nexport interface BoundRedeemDelegationsOptions {\n /** The redeemer — normally the signer's own derived account (matches the UserOp's `sender`). */\n delegate: Address\n delegator?: Address\n caveats?: DelegationOverrides['caveats']\n /** Override the single execution's calldata entirely (default: a real-shaped ERC-20 transfer). */\n executionCallData?: Hex\n}\n\n/** `redeemDelegations([permissionContext], [SingleDefault], [executionCallData])` — the REAL, bound shape. */\nexport function buildBoundRedeemDelegationsCallData(options: BoundRedeemDelegationsOptions): Hex {\n const delegation = buildDelegation({ delegate: options.delegate, delegator: options.delegator, caveats: options.caveats })\n const permissionContext = buildPermissionContext(delegation)\n const executionCallData =\n options.executionCallData ??\n buildTransferExecutionCallData(\n '0x036CbD53842c5426634e7929541eC2318f3dCF7e' as Address, // Base Sepolia USDC, matches the real captured fixture\n '0x98ffBf30459a98FD80fAce18f519967769641F76' as Address,\n 10000n,\n )\n return encodeFunctionData({\n abi: REDEEM_DELEGATIONS_ABI,\n functionName: 'redeemDelegations',\n args: [[permissionContext], [SINGLE_DEFAULT_MODE], [executionCallData]],\n })\n}\n\n/**\n * #3272 (B1 regression): `redeemDelegations([emptyPermissionContext],\n * [SingleDefault], [selfCallCallData])` — one permission context whose\n * `Delegation[]` decodes EMPTY, paired with a self-call execution. This is\n * the exact live bypass: MetaMask's DelegationManager treats an empty chain\n * as self-authorised and runs `selfCallCallData` AS the account. Exists only\n * so a test can assert this is refused, never to build a shape any code path\n * signs.\n */\nexport function buildEmptyPermissionContextRedemption(selfCallCallData: Hex): Hex {\n return encodeFunctionData({\n abi: REDEEM_DELEGATIONS_ABI,\n functionName: 'redeemDelegations',\n args: [[buildEmptyPermissionContext()], [SINGLE_DEFAULT_MODE], [selfCallCallData]],\n })\n}\n\n/** `execute((address,uint256,bytes))` — selector `0x5c1c6dcd`. */\nexport function buildExecuteCallData(target: Address, value: bigint, innerCallData: Hex): Hex {\n return encodeFunctionData({\n abi: EXECUTE_ABI,\n functionName: 'execute',\n args: [{ target, value, callData: innerCallData }],\n })\n}\n\nexport interface BoundDirectUserOpOptions {\n /** The delegate EOA (`signer.delegateAddress`) that owns the account `sender` derives from. */\n delegate: Address\n chainId?: number | bigint | string\n /** Override the execute() target — default DELEGATION_MANAGER (the bound shape). */\n target?: Address\n /** Override the execute() value — default 0n. */\n value?: bigint\n /** Override the full message.callData (bypasses target/value/redeemDelegations construction). */\n callData?: Hex\n /** Override sender/verifyingContract directly instead of deriving it from `delegate`. */\n sender?: Address\n /** Override the redemption's delegator (default: a distinct treasury address). */\n delegator?: Address\n}\n\nexport interface BoundDirectUserOp {\n typedData: {\n domain: { name: string; version: string; chainId: number | bigint | string; verifyingContract: Address }\n types: { PackedUserOperation: Array<{ name: string; type: string }> }\n primaryType: 'PackedUserOperation'\n message: Record<string, unknown>\n }\n payloadHash: Hex\n sender: Address\n}\n\n/**\n * A real-shaped, self-consistent (correct v0.7 hash) `PackedUserOperation`.\n * By default it is fully BOUND per #3272's allowlist: `sender` is the\n * counterfactual account for `delegate`, and `callData` redeems ONE real\n * delegation (delegate = `sender`, delegator = a distinct treasury address)\n * through the DelegationManager. Override `target` / `callData` / `sender` /\n * `delegator` to build the negative-test shapes the allowlist must refuse.\n */\nexport function buildBoundDirectUserOp(options: BoundDirectUserOpOptions): BoundDirectUserOp {\n const chainId = options.chainId ?? 84532\n const sender = options.sender ?? deriveDelegateAccountAddress(options.delegate)\n const callData =\n options.callData ??\n buildExecuteCallData(\n options.target ?? (DELEGATION_MANAGER as Address),\n options.value ?? 0n,\n buildBoundRedeemDelegationsCallData({ delegate: sender, delegator: options.delegator }),\n )\n const typedData = {\n domain: {\n name: HYBRID_DELEGATOR_DOMAIN_NAME,\n version: HYBRID_DELEGATOR_DOMAIN_VERSION,\n chainId,\n verifyingContract: sender,\n },\n types: { PackedUserOperation: PACKED_USER_OPERATION_FIELDS.map((field) => ({ ...field })) },\n primaryType: 'PackedUserOperation' as const,\n message: {\n sender,\n nonce: '0',\n initCode: '0x',\n callData,\n accountGasLimits: ZERO_BYTES32,\n preVerificationGas: '0',\n gasFees: ZERO_BYTES32,\n paymasterAndData: '0x',\n entryPoint: ENTRY_POINT_V07,\n },\n }\n const payloadHash = packedUserOperationHash(typedData)\n return { typedData, payloadHash, sender }\n}\n\n/** A well-formed `execute()` self-call — `target === sender` — for the (d)/self-call negative tests. */\nexport function buildSelfCallCallData(sender: Address): Hex {\n const TRANSFER_OWNERSHIP_ABI = [\n { type: 'function', name: 'transferOwnership', inputs: [{ name: 'newOwner', type: 'address' }], outputs: [], stateMutability: 'nonpayable' },\n ] as const\n const inner = encodeFunctionData({\n abi: TRANSFER_OWNERSHIP_ABI,\n functionName: 'transferOwnership',\n args: ['0x000000000000000000000000000000000000dEaD' as Address],\n })\n return buildExecuteCallData(sender, 0n, inner)\n}\n\n/**\n * Re-target a REAL captured direct-payment UserOp (for example\n * `__fixtures__/direct-payment-userop.json`) at `newSender`: the UserOp's\n * `sender` / `verifyingContract` and the redeemed delegation's `delegate`\n * become `newSender`; the delegator, caveats, mode and execution stay the\n * production bytes. The captured fixture is bound to a delegate whose key is\n * not in the repository, so a test signs this rebuilt copy with a test key\n * whose derived account is `newSender` — proving the guard accepts the actual\n * production shape, not only this file's synthetic one.\n */\nexport function rebuildDirectUserOpForSender(\n fixtureTypedData: {\n domain: Record<string, unknown>\n types: Record<string, unknown>\n primaryType: string\n message: Record<string, unknown>\n },\n newSender: Address,\n) {\n const originalCallData = fixtureTypedData.message.callData as Hex\n const { args: executeArgs } = decodeFunctionData({ abi: EXECUTE_ABI, data: originalCallData })\n const execution = executeArgs[0] as { target: Address; value: bigint; callData: Hex }\n const { args: redeemArgs } = decodeFunctionData({ abi: REDEEM_DELEGATIONS_ABI, data: execution.callData })\n const [permissionContexts, modes, executionCallDatas] = redeemArgs as unknown as [\n readonly Hex[],\n readonly Hex[],\n readonly Hex[],\n ]\n const [delegations] = decodeAbiParameters(DELEGATION_ARRAY_PARAM, permissionContexts[0])\n const adjustedDelegations = (delegations as unknown as Array<Record<string, unknown>>).map((d, i) =>\n i === 0 ? { ...d, delegate: newSender } : d,\n )\n const adjustedPermissionContext = encodeAbiParameters(DELEGATION_ARRAY_PARAM, [adjustedDelegations as never])\n const adjustedRedeemCallData = encodeFunctionData({\n abi: REDEEM_DELEGATIONS_ABI,\n functionName: 'redeemDelegations',\n args: [[adjustedPermissionContext], modes as Hex[], executionCallDatas as Hex[]],\n })\n const adjustedCallData = encodeFunctionData({\n abi: EXECUTE_ABI,\n functionName: 'execute',\n args: [{ target: execution.target, value: execution.value, callData: adjustedRedeemCallData }],\n })\n const typedData = {\n ...fixtureTypedData,\n domain: { ...fixtureTypedData.domain, verifyingContract: newSender },\n message: { ...fixtureTypedData.message, sender: newSender, callData: adjustedCallData },\n }\n const payloadHash = packedUserOperationHash(typedData as never) as Hex\n return { typedData, payloadHash }\n}\n\nexport interface FundingLegUserOpOptions {\n /** The delegate EOA (`signer.delegateAddress`): the account is derived from it AND it is the transfer's recipient. */\n delegate: Address\n /** The quoted token (the expected context's `asset`). */\n asset: Address\n /** The quoted atomic amount (the expected context's `amount`). */\n amount: bigint | string\n chainId?: number\n /** Override the transfer recipient (default: `delegate`) — for the recipient-pin negative test. */\n recipient?: Address\n /** Override the budget delegation's caveats (e.g. a multi-KB term, for relay-size tests). */\n caveats?: DelegationOverrides['caveats']\n}\n\n/**\n * #3281: an x402 EIP-3009 bridge FUNDING LEG exactly as the backend builds it\n * (`delegation-authorize.ts` → `prepareDelegationPayment(agent, token,\n * payTo = the delegate EOA, amountRaw)` → `prepareRedemption`): the\n * direct-payment shape, whose single execution is\n * `transfer(<delegate EOA>, <amount>)` on the quoted token. Returns the typed\n * data, its v0.7 UserOp hash (the expected context's `payloadHash`) and its\n * EIP-712 digest (the expected context's `typedDataHash`).\n */\nexport function buildFundingLegUserOp(options: FundingLegUserOpOptions) {\n const sender = deriveDelegateAccountAddress(options.delegate)\n const callData = buildExecuteCallData(\n DELEGATION_MANAGER as Address,\n 0n,\n buildBoundRedeemDelegationsCallData({\n delegate: sender,\n caveats: options.caveats,\n executionCallData: buildTransferExecutionCallData(\n options.asset,\n options.recipient ?? options.delegate,\n BigInt(options.amount),\n ),\n }),\n )\n const { typedData, payloadHash } = buildBoundDirectUserOp({\n delegate: options.delegate,\n chainId: options.chainId ?? 84532,\n callData,\n })\n return { typedData, payloadHash, digest: hashTypedData(typedData as never) }\n}\n","/**\n * #3723 — a REAL signed erc7710 receipt bundle for handler-level tests: the\n * delegate key signs the DelegationManager EIP-712 digest rebuilt from the\n * bundle's own `signHash` + `onChain.chainId`, exactly the math\n * `verifyPaymentReceipt` performs. So `verifyPaymentReceipt(bundle)` returns\n * `{ verified: true, verifiedOver: 'delegation_digest' }` with the DEFAULT\n * ECDSA recovery — the first positive handler-level verify fixture on the\n * MCP runtimes (no stdio-originated payment is erc7710 live: `haven_send` is\n * direct and the stdio x402 path is the eip3009 bridge).\n *\n * Published on the `@haven_ai/sdk/test-support` subpath like the UserOp\n * builder: a sibling package's tests cannot import this file by relative\n * path. Test fixtures, not a signing API: nothing the SDK or signer runs\n * imports it.\n */\nimport { Wallet } from 'ethers'\nimport { concatHex, encodeAbiParameters, keccak256, toBytes, type Hex } from 'viem'\nimport { DELEGATION_MANAGER } from '../settlement-child.js'\nimport { RECEIPT_VERSION, type PaymentReceipt } from '../receipt.js'\n\n/** A fixed delegate key so fixtures are deterministic across runs. */\nexport const RECEIPT_DELEGATE_KEY = `0x${'77'.repeat(32)}` as const\n/** A distinct key, for signer_mismatch fixtures. */\nexport const OTHER_RECEIPT_KEY = `0x${'88'.repeat(32)}` as const\n\nconst EIP712_DOMAIN_TYPEHASH = keccak256(\n toBytes('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'),\n)\n\n/** Same rebuild the verifier does — mirrored here so drift turns the positive test red. */\nfunction delegationDigest(signHash: string, chainId: number): Hex {\n const domainSeparator = keccak256(\n encodeAbiParameters(\n [{ type: 'bytes32' }, { type: 'bytes32' }, { type: 'bytes32' }, { type: 'uint256' }, { type: 'address' }],\n [\n EIP712_DOMAIN_TYPEHASH,\n keccak256(toBytes('DelegationManager')),\n keccak256(toBytes('1')),\n BigInt(chainId),\n DELEGATION_MANAGER as Hex,\n ],\n ),\n )\n return keccak256(concatHex(['0x1901', domainSeparator, signHash as Hex]))\n}\n\nexport interface SignedErc7710Options {\n /** Defaults to `RECEIPT_DELEGATE_KEY`; pass `OTHER_RECEIPT_KEY` for a forged bundle. */\n delegateKey?: string\n signHash?: string\n chainId?: number\n paymentId?: string\n}\n\n/**\n * A signed erc7710 bundle whose `authorization.signature` recovers to the\n * delegate over the delegation digest — `verifyPaymentReceipt` verifies it\n * offline with the default recovery.\n */\nexport function signedErc7710Receipt(options: SignedErc7710Options = {}): PaymentReceipt {\n const chainId = options.chainId ?? 84532 // Base Sepolia — a chain the SDK pins\n const signHash = options.signHash ?? (`0x${'5e'.repeat(32)}` as const)\n const delegate = new Wallet(options.delegateKey ?? RECEIPT_DELEGATE_KEY)\n const signature = delegate.signingKey.sign(delegationDigest(signHash, chainId)).serialized\n return {\n version: RECEIPT_VERSION,\n paymentId: options.paymentId ?? 'pay_3723',\n payment: {\n token: 'USDC',\n tokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n amount: '0.50',\n amountSek: '5.25',\n recipient: '0x15179876c595922999C2d5DC7c23Cc7711fE799a',\n account: '0x135a9215604711AC70d970e12Caa812c53537EF4',\n chainId,\n settledAt: '2026-10-07T10:00:00.000Z',\n resourceUrl: 'https://merchant.example/resource',\n },\n authorization: {\n delegate: delegate.address,\n signHash,\n signature,\n signatureScheme: 'eip712_delegation',\n },\n onChain: { txHash: `0x${'cd'.repeat(32)}`, chainId },\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/test-support/direct-userop.ts","../src/test-support/signed-receipt.ts","../src/test-support/low-s.ts"],"names":["DELEGATION_TUPLE_COMPONENTS","encodeAbiParameters","encodePacked","encodeFunctionData","REDEEM_DELEGATIONS_ABI","SINGLE_DEFAULT_MODE","deriveDelegateAccountAddress","DELEGATION_MANAGER","HYBRID_DELEGATOR_DOMAIN_NAME","HYBRID_DELEGATOR_DOMAIN_VERSION","PACKED_USER_OPERATION_FIELDS","ENTRY_POINT_V07","packedUserOperationHash","decodeFunctionData","decodeAbiParameters","hashTypedData","keccak256","toBytes","concatHex","Wallet","RECEIPT_VERSION"],"mappings":"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","file":"test-support.cjs","sourcesContent":["/**\n * #3272 — a real-shaped, BOUND direct-payment `PackedUserOperation` for\n * signer tests: `sender` is the counterfactual delegate account for a given\n * owner EOA, and `callData` is `execute(DelegationManager, 0,\n * redeemDelegations(...))` with a REAL redemption shape — one non-empty\n * `Delegation`, `delegate` = the signer's own account, `delegator` = a\n * distinct treasury address, `ExecutionMode.SingleDefault`, an\n * `encodePacked(target,value,callData)` execution — mirroring\n * `packages/backend/src/rails/delegation-rail.ts`'s `prepareRedemption`.\n * Replaces the toy 2-field / empty-callData / empty-arrays fixtures the\n * allowlist correctly refuses (including the B1 empty-permission-context\n * bypass, `buildEmptyPermissionContextRedemption` below, kept ONLY to\n * reproduce that exact refusal in a test).\n *\n * Moved here from `@haven_ai/signer` by #3283 so the SDK, the signer,\n * `@haven_ai/mcp` and `mcp-server` share ONE guard-valid builder. Published\n * as the `@haven_ai/sdk/test-support` subpath only because a sibling\n * package's tests cannot import this file by relative path (each package's\n * `tsc` `rootDir` is its own `src`). Test fixtures, not a signing API:\n * nothing here signs, and nothing the SDK or signer runs imports it.\n */\nimport {\n decodeAbiParameters,\n decodeFunctionData,\n encodeAbiParameters,\n encodeFunctionData,\n encodePacked,\n hashTypedData,\n type Address,\n type Hex,\n} from 'viem'\nimport {\n ENTRY_POINT_V07,\n HYBRID_DELEGATOR_DOMAIN_NAME,\n HYBRID_DELEGATOR_DOMAIN_VERSION,\n PACKED_USER_OPERATION_FIELDS,\n packedUserOperationHash,\n} from '../userop-binding.js'\nimport { DELEGATION_MANAGER } from '../settlement-child.js'\nimport { deriveDelegateAccountAddress } from '../delegate-account.js'\nimport { DELEGATION_TUPLE_COMPONENTS, REDEEM_DELEGATIONS_ABI, SINGLE_DEFAULT_MODE } from '../redemption-guard.js'\n\nconst ZERO_BYTES32 = `0x${'00'.repeat(32)}` as const\n\n/** `Delegation.authority` sentinel for a root (unchained) delegation — `@metamask/delegation-core`'s `ROOT_AUTHORITY`. */\nconst ROOT_AUTHORITY: Hex = `0x${'ff'.repeat(32)}`\n\n/** Stand-in treasury address — distinct from any derived signer account, matching the real fixture's `delegator`. */\nexport const DEFAULT_DELEGATOR: Address = '0x98989898989898989898989898989898989898De' as Address\n\nconst DELEGATION_ARRAY_PARAM = [\n { type: 'tuple[]', components: DELEGATION_TUPLE_COMPONENTS },\n] as const\n\nconst EXECUTE_ABI = [\n {\n type: 'function',\n name: 'execute',\n inputs: [\n {\n name: '_execution',\n type: 'tuple',\n components: [\n { name: 'target', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'callData', type: 'bytes' },\n ],\n },\n ],\n outputs: [],\n stateMutability: 'payable',\n },\n] as const\n\nconst TRANSFER_ABI = [\n {\n type: 'function',\n name: 'transfer',\n inputs: [\n { name: 'to', type: 'address' },\n { name: 'amount', type: 'uint256' },\n ],\n outputs: [{ type: 'bool' }],\n stateMutability: 'nonpayable',\n },\n] as const\n\nexport interface DelegationOverrides {\n /** The redeemer this delegation authorises — normally the signer's own derived account. */\n delegate: Address\n /** Who granted it — must differ from `delegate` for a real (non-self) delegation. */\n delegator?: Address\n authority?: Hex\n caveats?: Array<{ enforcer: Address; terms: Hex; args: Hex }>\n salt?: bigint\n signature?: Hex\n}\n\n/** A single, well-formed `Delegation` tuple — the ONE-link chain Haven's backend redeems (`delegations: [[delegation]]`). */\nexport function buildDelegation(overrides: DelegationOverrides) {\n return {\n delegate: overrides.delegate,\n delegator: overrides.delegator ?? DEFAULT_DELEGATOR,\n authority: overrides.authority ?? ROOT_AUTHORITY,\n caveats: overrides.caveats ?? [\n // A real-shaped (if inert for test purposes) TimestampEnforcer term —\n // real budget delegations always carry at least one caveat.\n { enforcer: '0x1046bb45C8d673d4ea75321280DB34899413c069' as Address, terms: `0x${'00'.repeat(32)}` as Hex, args: '0x' as Hex },\n ],\n salt: overrides.salt ?? 1n,\n signature: overrides.signature ?? (`0x${'ab'.repeat(65)}` as Hex),\n }\n}\n\n/** `abi.encode(Delegation[])` for a ONE-delegation chain — a Haven-shaped permission context. */\nexport function buildPermissionContext(delegation: ReturnType<typeof buildDelegation>): Hex {\n return encodeAbiParameters(DELEGATION_ARRAY_PARAM, [[delegation]])\n}\n\n/** `abi.encode(Delegation[])` for a MULTI-link chain (leaf first) — never emitted by Haven. */\nexport function buildChainPermissionContext(chain: ReturnType<typeof buildDelegation>[]): Hex {\n return encodeAbiParameters(DELEGATION_ARRAY_PARAM, [chain])\n}\n\n/** `abi.encode(Delegation[])` for an EMPTY chain — the exact B1 bypass shape MetaMask's DelegationManager treats as self-authorised. */\nexport function buildEmptyPermissionContext(): Hex {\n return encodeAbiParameters(DELEGATION_ARRAY_PARAM, [[]])\n}\n\n/** `encodePacked(address,uint256,bytes)` — the single-execution calldata `ExecutionMode.SingleDefault` expects. */\nexport function buildSingleExecutionCallData(target: Address, value: bigint, innerCallData: Hex): Hex {\n return encodePacked(['address', 'uint256', 'bytes'], [target, value, innerCallData])\n}\n\n/** A real-shaped ERC-20 `transfer(to, amount)` execution — what a budget redemption actually spends. */\nexport function buildTransferExecutionCallData(token: Address, to: Address, amount: bigint): Hex {\n return buildSingleExecutionCallData(\n token,\n 0n,\n encodeFunctionData({ abi: TRANSFER_ABI, functionName: 'transfer', args: [to, amount] }),\n )\n}\n\nexport interface BoundRedeemDelegationsOptions {\n /** The redeemer — normally the signer's own derived account (matches the UserOp's `sender`). */\n delegate: Address\n delegator?: Address\n caveats?: DelegationOverrides['caveats']\n /** Override the single execution's calldata entirely (default: a real-shaped ERC-20 transfer). */\n executionCallData?: Hex\n}\n\n/** `redeemDelegations([permissionContext], [SingleDefault], [executionCallData])` — the REAL, bound shape. */\nexport function buildBoundRedeemDelegationsCallData(options: BoundRedeemDelegationsOptions): Hex {\n const delegation = buildDelegation({ delegate: options.delegate, delegator: options.delegator, caveats: options.caveats })\n const permissionContext = buildPermissionContext(delegation)\n const executionCallData =\n options.executionCallData ??\n buildTransferExecutionCallData(\n '0x036CbD53842c5426634e7929541eC2318f3dCF7e' as Address, // Base Sepolia USDC, matches the real captured fixture\n '0x98ffBf30459a98FD80fAce18f519967769641F76' as Address,\n 10000n,\n )\n return encodeFunctionData({\n abi: REDEEM_DELEGATIONS_ABI,\n functionName: 'redeemDelegations',\n args: [[permissionContext], [SINGLE_DEFAULT_MODE], [executionCallData]],\n })\n}\n\n/**\n * #3272 (B1 regression): `redeemDelegations([emptyPermissionContext],\n * [SingleDefault], [selfCallCallData])` — one permission context whose\n * `Delegation[]` decodes EMPTY, paired with a self-call execution. This is\n * the exact live bypass: MetaMask's DelegationManager treats an empty chain\n * as self-authorised and runs `selfCallCallData` AS the account. Exists only\n * so a test can assert this is refused, never to build a shape any code path\n * signs.\n */\nexport function buildEmptyPermissionContextRedemption(selfCallCallData: Hex): Hex {\n return encodeFunctionData({\n abi: REDEEM_DELEGATIONS_ABI,\n functionName: 'redeemDelegations',\n args: [[buildEmptyPermissionContext()], [SINGLE_DEFAULT_MODE], [selfCallCallData]],\n })\n}\n\n/** `execute((address,uint256,bytes))` — selector `0x5c1c6dcd`. */\nexport function buildExecuteCallData(target: Address, value: bigint, innerCallData: Hex): Hex {\n return encodeFunctionData({\n abi: EXECUTE_ABI,\n functionName: 'execute',\n args: [{ target, value, callData: innerCallData }],\n })\n}\n\nexport interface BoundDirectUserOpOptions {\n /** The delegate EOA (`signer.delegateAddress`) that owns the account `sender` derives from. */\n delegate: Address\n chainId?: number | bigint | string\n /** Override the execute() target — default DELEGATION_MANAGER (the bound shape). */\n target?: Address\n /** Override the execute() value — default 0n. */\n value?: bigint\n /** Override the full message.callData (bypasses target/value/redeemDelegations construction). */\n callData?: Hex\n /** Override sender/verifyingContract directly instead of deriving it from `delegate`. */\n sender?: Address\n /** Override the redemption's delegator (default: a distinct treasury address). */\n delegator?: Address\n}\n\nexport interface BoundDirectUserOp {\n typedData: {\n domain: { name: string; version: string; chainId: number | bigint | string; verifyingContract: Address }\n types: { PackedUserOperation: Array<{ name: string; type: string }> }\n primaryType: 'PackedUserOperation'\n message: Record<string, unknown>\n }\n payloadHash: Hex\n sender: Address\n}\n\n/**\n * A real-shaped, self-consistent (correct v0.7 hash) `PackedUserOperation`.\n * By default it is fully BOUND per #3272's allowlist: `sender` is the\n * counterfactual account for `delegate`, and `callData` redeems ONE real\n * delegation (delegate = `sender`, delegator = a distinct treasury address)\n * through the DelegationManager. Override `target` / `callData` / `sender` /\n * `delegator` to build the negative-test shapes the allowlist must refuse.\n */\nexport function buildBoundDirectUserOp(options: BoundDirectUserOpOptions): BoundDirectUserOp {\n const chainId = options.chainId ?? 84532\n const sender = options.sender ?? deriveDelegateAccountAddress(options.delegate)\n const callData =\n options.callData ??\n buildExecuteCallData(\n options.target ?? (DELEGATION_MANAGER as Address),\n options.value ?? 0n,\n buildBoundRedeemDelegationsCallData({ delegate: sender, delegator: options.delegator }),\n )\n const typedData = {\n domain: {\n name: HYBRID_DELEGATOR_DOMAIN_NAME,\n version: HYBRID_DELEGATOR_DOMAIN_VERSION,\n chainId,\n verifyingContract: sender,\n },\n types: { PackedUserOperation: PACKED_USER_OPERATION_FIELDS.map((field) => ({ ...field })) },\n primaryType: 'PackedUserOperation' as const,\n message: {\n sender,\n nonce: '0',\n initCode: '0x',\n callData,\n accountGasLimits: ZERO_BYTES32,\n preVerificationGas: '0',\n gasFees: ZERO_BYTES32,\n paymasterAndData: '0x',\n entryPoint: ENTRY_POINT_V07,\n },\n }\n const payloadHash = packedUserOperationHash(typedData)\n return { typedData, payloadHash, sender }\n}\n\n/** A well-formed `execute()` self-call — `target === sender` — for the (d)/self-call negative tests. */\nexport function buildSelfCallCallData(sender: Address): Hex {\n const TRANSFER_OWNERSHIP_ABI = [\n { type: 'function', name: 'transferOwnership', inputs: [{ name: 'newOwner', type: 'address' }], outputs: [], stateMutability: 'nonpayable' },\n ] as const\n const inner = encodeFunctionData({\n abi: TRANSFER_OWNERSHIP_ABI,\n functionName: 'transferOwnership',\n args: ['0x000000000000000000000000000000000000dEaD' as Address],\n })\n return buildExecuteCallData(sender, 0n, inner)\n}\n\n/**\n * Re-target a REAL captured direct-payment UserOp (for example\n * `__fixtures__/direct-payment-userop.json`) at `newSender`: the UserOp's\n * `sender` / `verifyingContract` and the redeemed delegation's `delegate`\n * become `newSender`; the delegator, caveats, mode and execution stay the\n * production bytes. The captured fixture is bound to a delegate whose key is\n * not in the repository, so a test signs this rebuilt copy with a test key\n * whose derived account is `newSender` — proving the guard accepts the actual\n * production shape, not only this file's synthetic one.\n */\nexport function rebuildDirectUserOpForSender(\n fixtureTypedData: {\n domain: Record<string, unknown>\n types: Record<string, unknown>\n primaryType: string\n message: Record<string, unknown>\n },\n newSender: Address,\n) {\n const originalCallData = fixtureTypedData.message.callData as Hex\n const { args: executeArgs } = decodeFunctionData({ abi: EXECUTE_ABI, data: originalCallData })\n const execution = executeArgs[0] as { target: Address; value: bigint; callData: Hex }\n const { args: redeemArgs } = decodeFunctionData({ abi: REDEEM_DELEGATIONS_ABI, data: execution.callData })\n const [permissionContexts, modes, executionCallDatas] = redeemArgs as unknown as [\n readonly Hex[],\n readonly Hex[],\n readonly Hex[],\n ]\n const [delegations] = decodeAbiParameters(DELEGATION_ARRAY_PARAM, permissionContexts[0])\n const adjustedDelegations = (delegations as unknown as Array<Record<string, unknown>>).map((d, i) =>\n i === 0 ? { ...d, delegate: newSender } : d,\n )\n const adjustedPermissionContext = encodeAbiParameters(DELEGATION_ARRAY_PARAM, [adjustedDelegations as never])\n const adjustedRedeemCallData = encodeFunctionData({\n abi: REDEEM_DELEGATIONS_ABI,\n functionName: 'redeemDelegations',\n args: [[adjustedPermissionContext], modes as Hex[], executionCallDatas as Hex[]],\n })\n const adjustedCallData = encodeFunctionData({\n abi: EXECUTE_ABI,\n functionName: 'execute',\n args: [{ target: execution.target, value: execution.value, callData: adjustedRedeemCallData }],\n })\n const typedData = {\n ...fixtureTypedData,\n domain: { ...fixtureTypedData.domain, verifyingContract: newSender },\n message: { ...fixtureTypedData.message, sender: newSender, callData: adjustedCallData },\n }\n const payloadHash = packedUserOperationHash(typedData as never) as Hex\n return { typedData, payloadHash }\n}\n\nexport interface FundingLegUserOpOptions {\n /** The delegate EOA (`signer.delegateAddress`): the account is derived from it AND it is the transfer's recipient. */\n delegate: Address\n /** The quoted token (the expected context's `asset`). */\n asset: Address\n /** The quoted atomic amount (the expected context's `amount`). */\n amount: bigint | string\n chainId?: number\n /** Override the transfer recipient (default: `delegate`) — for the recipient-pin negative test. */\n recipient?: Address\n /** Override the budget delegation's caveats (e.g. a multi-KB term, for relay-size tests). */\n caveats?: DelegationOverrides['caveats']\n}\n\n/**\n * #3281: an x402 EIP-3009 bridge FUNDING LEG exactly as the backend builds it\n * (`delegation-authorize.ts` → `prepareDelegationPayment(agent, token,\n * payTo = the delegate EOA, amountRaw)` → `prepareRedemption`): the\n * direct-payment shape, whose single execution is\n * `transfer(<delegate EOA>, <amount>)` on the quoted token. Returns the typed\n * data, its v0.7 UserOp hash (the expected context's `payloadHash`) and its\n * EIP-712 digest (the expected context's `typedDataHash`).\n */\nexport function buildFundingLegUserOp(options: FundingLegUserOpOptions) {\n const sender = deriveDelegateAccountAddress(options.delegate)\n const callData = buildExecuteCallData(\n DELEGATION_MANAGER as Address,\n 0n,\n buildBoundRedeemDelegationsCallData({\n delegate: sender,\n caveats: options.caveats,\n executionCallData: buildTransferExecutionCallData(\n options.asset,\n options.recipient ?? options.delegate,\n BigInt(options.amount),\n ),\n }),\n )\n const { typedData, payloadHash } = buildBoundDirectUserOp({\n delegate: options.delegate,\n chainId: options.chainId ?? 84532,\n callData,\n })\n return { typedData, payloadHash, digest: hashTypedData(typedData as never) }\n}\n","/**\n * #3723 — a REAL signed erc7710 receipt bundle for handler-level tests: the\n * delegate key signs the DelegationManager EIP-712 digest rebuilt from the\n * bundle's own `signHash` + `onChain.chainId`, exactly the math\n * `verifyPaymentReceipt` performs. So `verifyPaymentReceipt(bundle)` returns\n * `{ verified: true, verifiedOver: 'delegation_digest' }` with the DEFAULT\n * ECDSA recovery — the first positive handler-level verify fixture on the\n * MCP runtimes (no stdio-originated payment is erc7710 live: `haven_send` is\n * direct and the stdio x402 path is the eip3009 bridge).\n *\n * Published on the `@haven_ai/sdk/test-support` subpath like the UserOp\n * builder: a sibling package's tests cannot import this file by relative\n * path. Test fixtures, not a signing API: nothing the SDK or signer runs\n * imports it.\n */\nimport { Wallet } from 'ethers'\nimport { concatHex, encodeAbiParameters, keccak256, toBytes, type Hex } from 'viem'\nimport { DELEGATION_MANAGER } from '../settlement-child.js'\nimport { RECEIPT_VERSION, type PaymentReceipt } from '../receipt.js'\n\n/** A fixed delegate key so fixtures are deterministic across runs. */\nexport const RECEIPT_DELEGATE_KEY = `0x${'77'.repeat(32)}` as const\n/** A distinct key, for signer_mismatch fixtures. */\nexport const OTHER_RECEIPT_KEY = `0x${'88'.repeat(32)}` as const\n\nconst EIP712_DOMAIN_TYPEHASH = keccak256(\n toBytes('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'),\n)\n\n/** Same rebuild the verifier does — mirrored here so drift turns the positive test red. */\nfunction delegationDigest(signHash: string, chainId: number): Hex {\n const domainSeparator = keccak256(\n encodeAbiParameters(\n [{ type: 'bytes32' }, { type: 'bytes32' }, { type: 'bytes32' }, { type: 'uint256' }, { type: 'address' }],\n [\n EIP712_DOMAIN_TYPEHASH,\n keccak256(toBytes('DelegationManager')),\n keccak256(toBytes('1')),\n BigInt(chainId),\n DELEGATION_MANAGER as Hex,\n ],\n ),\n )\n return keccak256(concatHex(['0x1901', domainSeparator, signHash as Hex]))\n}\n\nexport interface SignedErc7710Options {\n /** Defaults to `RECEIPT_DELEGATE_KEY`; pass `OTHER_RECEIPT_KEY` for a forged bundle. */\n delegateKey?: string\n signHash?: string\n chainId?: number\n paymentId?: string\n}\n\n/**\n * A signed erc7710 bundle whose `authorization.signature` recovers to the\n * delegate over the delegation digest — `verifyPaymentReceipt` verifies it\n * offline with the default recovery.\n */\nexport function signedErc7710Receipt(options: SignedErc7710Options = {}): PaymentReceipt {\n const chainId = options.chainId ?? 84532 // Base Sepolia — a chain the SDK pins\n const signHash = options.signHash ?? (`0x${'5e'.repeat(32)}` as const)\n const delegate = new Wallet(options.delegateKey ?? RECEIPT_DELEGATE_KEY)\n const signature = delegate.signingKey.sign(delegationDigest(signHash, chainId)).serialized\n return {\n version: RECEIPT_VERSION,\n paymentId: options.paymentId ?? 'pay_3723',\n payment: {\n token: 'USDC',\n tokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n amount: '0.50',\n amountSek: '5.25',\n recipient: '0x15179876c595922999C2d5DC7c23Cc7711fE799a',\n account: '0x135a9215604711AC70d970e12Caa812c53537EF4',\n chainId,\n settledAt: '2026-10-07T10:00:00.000Z',\n resourceUrl: 'https://merchant.example/resource',\n },\n authorization: {\n delegate: delegate.address,\n signHash,\n signature,\n signatureScheme: 'eip712_delegation',\n },\n onChain: { txHash: `0x${'cd'.repeat(32)}`, chainId },\n }\n}\n","/**\n * Canonical (low-s) ECDSA signature assertions for the EIP-3009 bridge (#4550).\n *\n * x402 facilitators reject a non-canonical (high-s) 65-byte EOA signature in\n * `exact` EIP-3009 verify, before settlement (x402-foundation/x402#2728,\n * aligned across SDKs in x402-foundation/x402#3964; wire reason\n * `invalid_exact_evm_non_canonical_signature`). Haven's bridge complies today\n * only because viem's `privateKeyToAccount().sign()` passes `lowS: true` to\n * noble secp256k1 — nothing in Haven checks it. Swapping the signing account\n * (a KMS signer, a hardware key, a different library) could ship high-s\n * headers that every facilitator rejects.\n *\n * The malleable twin `(r, n - s, v ^ 1)` recovers to the SAME address, so a\n * recovery-only test cannot catch it. These helpers assert the wire bytes.\n *\n * Test fixtures only: nothing the SDK or signer runs imports this entry.\n */\n\n/** secp256k1 group order divided by two — the canonical low-s ceiling. */\nexport const SECP256K1_HALF_N =\n 0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0n\n\nexport interface EcdsaSignatureParts {\n /** 32-byte `r`, big-endian. */\n r: bigint\n /** 32-byte `s`, big-endian. */\n s: bigint\n /** Recovery id as it appears on the wire: 27 or 28. */\n v: number\n /** Total signature length in bytes (65 for an EOA signature). */\n length: number\n}\n\n/**\n * Split a 65-byte `0x`-prefixed EOA signature into r/s/v.\n *\n * Throws on anything that is not exactly 65 bytes: a compact (64-byte) or\n * EIP-2098 signature is a different wire shape, and a low-s assertion that\n * silently accepted it would not be pinning the bytes the facilitator reads.\n */\nexport function parseEcdsaSignature(signature: string): EcdsaSignatureParts {\n if (!/^0x[0-9a-fA-F]*$/.test(signature)) {\n throw new Error(`signature is not 0x-prefixed hex: ${signature.slice(0, 20)}…`)\n }\n const hex = signature.slice(2)\n if (hex.length % 2 !== 0) {\n throw new Error(`signature has an odd number of hex digits (${hex.length})`)\n }\n const length = hex.length / 2\n if (length !== 65) {\n throw new Error(`signature must be 65 bytes, got ${length}`)\n }\n return {\n r: BigInt(`0x${hex.slice(0, 64)}`),\n s: BigInt(`0x${hex.slice(64, 128)}`),\n v: Number.parseInt(hex.slice(128, 130), 16),\n length,\n }\n}\n\n/**\n * Assert a wire signature is canonical low-s: 65 bytes, `v ∈ {27, 28}`,\n * `s ≤ n/2`. Throws with the offending value so a prove-red run names the\n * exact branch that regressed.\n */\nexport function assertLowSSignature(signature: string): EcdsaSignatureParts {\n const parts = parseEcdsaSignature(signature)\n if (parts.v !== 27 && parts.v !== 28) {\n throw new Error(`signature v must be 27 or 28, got ${parts.v}`)\n }\n if (parts.s > SECP256K1_HALF_N) {\n throw new Error(\n `signature is high-s (malleable): s=0x${parts.s.toString(16)} exceeds ` +\n `n/2=0x${SECP256K1_HALF_N.toString(16)}`,\n )\n }\n return parts\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import { Address, Hex } from 'viem';
2
- import { P as PaymentReceipt } from './receipt-Dy77vCea.cjs';
3
- import './types-CAvsjRKi.cjs';
2
+ import { P as PaymentReceipt } from './receipt-DwRqGjGb.cjs';
3
+ import './types-3vUBmumz.cjs';
4
4
 
5
5
  /**
6
6
  * #3272 — a real-shaped, BOUND direct-payment `PackedUserOperation` for
@@ -221,4 +221,48 @@ interface SignedErc7710Options {
221
221
  */
222
222
  declare function signedErc7710Receipt(options?: SignedErc7710Options): PaymentReceipt;
223
223
 
224
- export { type BoundDirectUserOp, type BoundDirectUserOpOptions, type BoundRedeemDelegationsOptions, DEFAULT_DELEGATOR, type DelegationOverrides, type FundingLegUserOpOptions, OTHER_RECEIPT_KEY, RECEIPT_DELEGATE_KEY, type SignedErc7710Options, buildBoundDirectUserOp, buildBoundRedeemDelegationsCallData, buildChainPermissionContext, buildDelegation, buildEmptyPermissionContext, buildEmptyPermissionContextRedemption, buildExecuteCallData, buildFundingLegUserOp, buildPermissionContext, buildSelfCallCallData, buildSingleExecutionCallData, buildTransferExecutionCallData, rebuildDirectUserOpForSender, signedErc7710Receipt };
224
+ /**
225
+ * Canonical (low-s) ECDSA signature assertions for the EIP-3009 bridge (#4550).
226
+ *
227
+ * x402 facilitators reject a non-canonical (high-s) 65-byte EOA signature in
228
+ * `exact` EIP-3009 verify, before settlement (x402-foundation/x402#2728,
229
+ * aligned across SDKs in x402-foundation/x402#3964; wire reason
230
+ * `invalid_exact_evm_non_canonical_signature`). Haven's bridge complies today
231
+ * only because viem's `privateKeyToAccount().sign()` passes `lowS: true` to
232
+ * noble secp256k1 — nothing in Haven checks it. Swapping the signing account
233
+ * (a KMS signer, a hardware key, a different library) could ship high-s
234
+ * headers that every facilitator rejects.
235
+ *
236
+ * The malleable twin `(r, n - s, v ^ 1)` recovers to the SAME address, so a
237
+ * recovery-only test cannot catch it. These helpers assert the wire bytes.
238
+ *
239
+ * Test fixtures only: nothing the SDK or signer runs imports this entry.
240
+ */
241
+ /** secp256k1 group order divided by two — the canonical low-s ceiling. */
242
+ declare const SECP256K1_HALF_N = 57896044618658097711785492504343953926418782139537452191302581570759080747168n;
243
+ interface EcdsaSignatureParts {
244
+ /** 32-byte `r`, big-endian. */
245
+ r: bigint;
246
+ /** 32-byte `s`, big-endian. */
247
+ s: bigint;
248
+ /** Recovery id as it appears on the wire: 27 or 28. */
249
+ v: number;
250
+ /** Total signature length in bytes (65 for an EOA signature). */
251
+ length: number;
252
+ }
253
+ /**
254
+ * Split a 65-byte `0x`-prefixed EOA signature into r/s/v.
255
+ *
256
+ * Throws on anything that is not exactly 65 bytes: a compact (64-byte) or
257
+ * EIP-2098 signature is a different wire shape, and a low-s assertion that
258
+ * silently accepted it would not be pinning the bytes the facilitator reads.
259
+ */
260
+ declare function parseEcdsaSignature(signature: string): EcdsaSignatureParts;
261
+ /**
262
+ * Assert a wire signature is canonical low-s: 65 bytes, `v ∈ {27, 28}`,
263
+ * `s ≤ n/2`. Throws with the offending value so a prove-red run names the
264
+ * exact branch that regressed.
265
+ */
266
+ declare function assertLowSSignature(signature: string): EcdsaSignatureParts;
267
+
268
+ export { type BoundDirectUserOp, type BoundDirectUserOpOptions, type BoundRedeemDelegationsOptions, DEFAULT_DELEGATOR, type DelegationOverrides, type EcdsaSignatureParts, type FundingLegUserOpOptions, OTHER_RECEIPT_KEY, RECEIPT_DELEGATE_KEY, SECP256K1_HALF_N, type SignedErc7710Options, assertLowSSignature, buildBoundDirectUserOp, buildBoundRedeemDelegationsCallData, buildChainPermissionContext, buildDelegation, buildEmptyPermissionContext, buildEmptyPermissionContextRedemption, buildExecuteCallData, buildFundingLegUserOp, buildPermissionContext, buildSelfCallCallData, buildSingleExecutionCallData, buildTransferExecutionCallData, parseEcdsaSignature, rebuildDirectUserOpForSender, signedErc7710Receipt };
@@ -1,6 +1,6 @@
1
1
  import { Address, Hex } from 'viem';
2
- import { P as PaymentReceipt } from './receipt-DyUInpvF.js';
3
- import './types-CAvsjRKi.js';
2
+ import { P as PaymentReceipt } from './receipt-CTOPh2fm.js';
3
+ import './types-3vUBmumz.js';
4
4
 
5
5
  /**
6
6
  * #3272 — a real-shaped, BOUND direct-payment `PackedUserOperation` for
@@ -221,4 +221,48 @@ interface SignedErc7710Options {
221
221
  */
222
222
  declare function signedErc7710Receipt(options?: SignedErc7710Options): PaymentReceipt;
223
223
 
224
- export { type BoundDirectUserOp, type BoundDirectUserOpOptions, type BoundRedeemDelegationsOptions, DEFAULT_DELEGATOR, type DelegationOverrides, type FundingLegUserOpOptions, OTHER_RECEIPT_KEY, RECEIPT_DELEGATE_KEY, type SignedErc7710Options, buildBoundDirectUserOp, buildBoundRedeemDelegationsCallData, buildChainPermissionContext, buildDelegation, buildEmptyPermissionContext, buildEmptyPermissionContextRedemption, buildExecuteCallData, buildFundingLegUserOp, buildPermissionContext, buildSelfCallCallData, buildSingleExecutionCallData, buildTransferExecutionCallData, rebuildDirectUserOpForSender, signedErc7710Receipt };
224
+ /**
225
+ * Canonical (low-s) ECDSA signature assertions for the EIP-3009 bridge (#4550).
226
+ *
227
+ * x402 facilitators reject a non-canonical (high-s) 65-byte EOA signature in
228
+ * `exact` EIP-3009 verify, before settlement (x402-foundation/x402#2728,
229
+ * aligned across SDKs in x402-foundation/x402#3964; wire reason
230
+ * `invalid_exact_evm_non_canonical_signature`). Haven's bridge complies today
231
+ * only because viem's `privateKeyToAccount().sign()` passes `lowS: true` to
232
+ * noble secp256k1 — nothing in Haven checks it. Swapping the signing account
233
+ * (a KMS signer, a hardware key, a different library) could ship high-s
234
+ * headers that every facilitator rejects.
235
+ *
236
+ * The malleable twin `(r, n - s, v ^ 1)` recovers to the SAME address, so a
237
+ * recovery-only test cannot catch it. These helpers assert the wire bytes.
238
+ *
239
+ * Test fixtures only: nothing the SDK or signer runs imports this entry.
240
+ */
241
+ /** secp256k1 group order divided by two — the canonical low-s ceiling. */
242
+ declare const SECP256K1_HALF_N = 57896044618658097711785492504343953926418782139537452191302581570759080747168n;
243
+ interface EcdsaSignatureParts {
244
+ /** 32-byte `r`, big-endian. */
245
+ r: bigint;
246
+ /** 32-byte `s`, big-endian. */
247
+ s: bigint;
248
+ /** Recovery id as it appears on the wire: 27 or 28. */
249
+ v: number;
250
+ /** Total signature length in bytes (65 for an EOA signature). */
251
+ length: number;
252
+ }
253
+ /**
254
+ * Split a 65-byte `0x`-prefixed EOA signature into r/s/v.
255
+ *
256
+ * Throws on anything that is not exactly 65 bytes: a compact (64-byte) or
257
+ * EIP-2098 signature is a different wire shape, and a low-s assertion that
258
+ * silently accepted it would not be pinning the bytes the facilitator reads.
259
+ */
260
+ declare function parseEcdsaSignature(signature: string): EcdsaSignatureParts;
261
+ /**
262
+ * Assert a wire signature is canonical low-s: 65 bytes, `v ∈ {27, 28}`,
263
+ * `s ≤ n/2`. Throws with the offending value so a prove-red run names the
264
+ * exact branch that regressed.
265
+ */
266
+ declare function assertLowSSignature(signature: string): EcdsaSignatureParts;
267
+
268
+ export { type BoundDirectUserOp, type BoundDirectUserOpOptions, type BoundRedeemDelegationsOptions, DEFAULT_DELEGATOR, type DelegationOverrides, type EcdsaSignatureParts, type FundingLegUserOpOptions, OTHER_RECEIPT_KEY, RECEIPT_DELEGATE_KEY, SECP256K1_HALF_N, type SignedErc7710Options, assertLowSSignature, buildBoundDirectUserOp, buildBoundRedeemDelegationsCallData, buildChainPermissionContext, buildDelegation, buildEmptyPermissionContext, buildEmptyPermissionContextRedemption, buildExecuteCallData, buildFundingLegUserOp, buildPermissionContext, buildSelfCallCallData, buildSingleExecutionCallData, buildTransferExecutionCallData, parseEcdsaSignature, rebuildDirectUserOpForSender, signedErc7710Receipt };
@@ -1,5 +1,5 @@
1
- import { RECEIPT_VERSION } from './chunk-WFTGZS24.js';
2
- import { DELEGATION_TUPLE_COMPONENTS, SINGLE_DEFAULT_MODE, REDEEM_DELEGATIONS_ABI, deriveDelegateAccountAddress, DELEGATION_MANAGER, PACKED_USER_OPERATION_FIELDS, packedUserOperationHash, ENTRY_POINT_V07, HYBRID_DELEGATOR_DOMAIN_VERSION, HYBRID_DELEGATOR_DOMAIN_NAME } from './chunk-UPEDQLAL.js';
1
+ import { RECEIPT_VERSION } from './chunk-CK6VRIPR.js';
2
+ import { DELEGATION_TUPLE_COMPONENTS, SINGLE_DEFAULT_MODE, REDEEM_DELEGATIONS_ABI, deriveDelegateAccountAddress, DELEGATION_MANAGER, PACKED_USER_OPERATION_FIELDS, packedUserOperationHash, ENTRY_POINT_V07, HYBRID_DELEGATOR_DOMAIN_VERSION, HYBRID_DELEGATOR_DOMAIN_NAME } from './chunk-MI7LVP56.js';
3
3
  import { keccak256, toBytes, encodeAbiParameters, encodePacked, encodeFunctionData, decodeFunctionData, decodeAbiParameters, hashTypedData, concatHex } from 'viem';
4
4
  import { Wallet } from 'ethers';
5
5
 
@@ -245,6 +245,40 @@ function signedErc7710Receipt(options = {}) {
245
245
  };
246
246
  }
247
247
 
248
- export { DEFAULT_DELEGATOR, OTHER_RECEIPT_KEY, RECEIPT_DELEGATE_KEY, buildBoundDirectUserOp, buildBoundRedeemDelegationsCallData, buildChainPermissionContext, buildDelegation, buildEmptyPermissionContext, buildEmptyPermissionContextRedemption, buildExecuteCallData, buildFundingLegUserOp, buildPermissionContext, buildSelfCallCallData, buildSingleExecutionCallData, buildTransferExecutionCallData, rebuildDirectUserOpForSender, signedErc7710Receipt };
248
+ // src/test-support/low-s.ts
249
+ var SECP256K1_HALF_N = 0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0n;
250
+ function parseEcdsaSignature(signature) {
251
+ if (!/^0x[0-9a-fA-F]*$/.test(signature)) {
252
+ throw new Error(`signature is not 0x-prefixed hex: ${signature.slice(0, 20)}\u2026`);
253
+ }
254
+ const hex = signature.slice(2);
255
+ if (hex.length % 2 !== 0) {
256
+ throw new Error(`signature has an odd number of hex digits (${hex.length})`);
257
+ }
258
+ const length = hex.length / 2;
259
+ if (length !== 65) {
260
+ throw new Error(`signature must be 65 bytes, got ${length}`);
261
+ }
262
+ return {
263
+ r: BigInt(`0x${hex.slice(0, 64)}`),
264
+ s: BigInt(`0x${hex.slice(64, 128)}`),
265
+ v: Number.parseInt(hex.slice(128, 130), 16),
266
+ length
267
+ };
268
+ }
269
+ function assertLowSSignature(signature) {
270
+ const parts = parseEcdsaSignature(signature);
271
+ if (parts.v !== 27 && parts.v !== 28) {
272
+ throw new Error(`signature v must be 27 or 28, got ${parts.v}`);
273
+ }
274
+ if (parts.s > SECP256K1_HALF_N) {
275
+ throw new Error(
276
+ `signature is high-s (malleable): s=0x${parts.s.toString(16)} exceeds n/2=0x${SECP256K1_HALF_N.toString(16)}`
277
+ );
278
+ }
279
+ return parts;
280
+ }
281
+
282
+ export { DEFAULT_DELEGATOR, OTHER_RECEIPT_KEY, RECEIPT_DELEGATE_KEY, SECP256K1_HALF_N, assertLowSSignature, buildBoundDirectUserOp, buildBoundRedeemDelegationsCallData, buildChainPermissionContext, buildDelegation, buildEmptyPermissionContext, buildEmptyPermissionContextRedemption, buildExecuteCallData, buildFundingLegUserOp, buildPermissionContext, buildSelfCallCallData, buildSingleExecutionCallData, buildTransferExecutionCallData, parseEcdsaSignature, rebuildDirectUserOpForSender, signedErc7710Receipt };
249
283
  //# sourceMappingURL=test-support.js.map
250
284
  //# sourceMappingURL=test-support.js.map