@rhinestone/sdk 1.4.2 → 2.0.0-beta.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 (202) hide show
  1. package/README.md +89 -1
  2. package/dist/src/accounts/error.d.ts +1 -1
  3. package/dist/src/accounts/error.js +1 -19
  4. package/dist/src/accounts/index.d.ts +5 -5
  5. package/dist/src/accounts/index.js +121 -157
  6. package/dist/src/accounts/json-rpc/index.d.ts +1 -1
  7. package/dist/src/accounts/json-rpc/index.js +8 -10
  8. package/dist/src/accounts/json-rpc/providers.d.ts +1 -1
  9. package/dist/src/accounts/json-rpc/providers.js +4 -7
  10. package/dist/src/accounts/kernel.d.ts +3 -3
  11. package/dist/src/accounts/kernel.js +66 -75
  12. package/dist/src/accounts/nexus.d.ts +3 -3
  13. package/dist/src/accounts/nexus.js +62 -73
  14. package/dist/src/accounts/passport.d.ts +3 -3
  15. package/dist/src/accounts/passport.js +9 -13
  16. package/dist/src/accounts/safe.d.ts +3 -3
  17. package/dist/src/accounts/safe.js +54 -63
  18. package/dist/src/accounts/signing/common.d.ts +10 -4
  19. package/dist/src/accounts/signing/common.d.ts.map +1 -1
  20. package/dist/src/accounts/signing/common.js +30 -36
  21. package/dist/src/accounts/signing/message.d.ts +2 -2
  22. package/dist/src/accounts/signing/message.js +10 -12
  23. package/dist/src/accounts/signing/passkeys.js +11 -17
  24. package/dist/src/accounts/signing/typedData.d.ts +1 -1
  25. package/dist/src/accounts/signing/typedData.js +6 -8
  26. package/dist/src/accounts/startale.d.ts +3 -3
  27. package/dist/src/accounts/startale.js +37 -47
  28. package/dist/src/accounts/utils.d.ts +2 -2
  29. package/dist/src/accounts/utils.js +22 -28
  30. package/dist/src/accounts/walletClient.js +4 -8
  31. package/dist/src/actions/compact.d.ts +1 -1
  32. package/dist/src/actions/compact.js +22 -35
  33. package/dist/src/actions/deployment.d.ts +1 -1
  34. package/dist/src/actions/deployment.js +11 -13
  35. package/dist/src/actions/ecdsa.d.ts +1 -1
  36. package/dist/src/actions/ecdsa.js +14 -20
  37. package/dist/src/actions/index.d.ts +2 -2
  38. package/dist/src/actions/index.js +6 -10
  39. package/dist/src/actions/mfa.d.ts +1 -1
  40. package/dist/src/actions/mfa.js +18 -24
  41. package/dist/src/actions/passkeys.d.ts +2 -2
  42. package/dist/src/actions/passkeys.js +14 -20
  43. package/dist/src/actions/recovery.d.ts +1 -1
  44. package/dist/src/actions/recovery.js +25 -29
  45. package/dist/src/actions/smart-sessions.d.ts +1 -1
  46. package/dist/src/actions/smart-sessions.js +8 -12
  47. package/dist/src/auth/provider.d.ts +7 -0
  48. package/dist/src/auth/provider.d.ts.map +1 -0
  49. package/dist/src/auth/provider.js +38 -0
  50. package/dist/src/errors/index.d.ts +3 -3
  51. package/dist/src/errors/index.js +10 -54
  52. package/dist/src/execution/compact.d.ts +3 -3
  53. package/dist/src/execution/compact.js +10 -18
  54. package/dist/src/execution/error.js +1 -11
  55. package/dist/src/execution/index.d.ts +9 -8
  56. package/dist/src/execution/index.d.ts.map +1 -1
  57. package/dist/src/execution/index.js +54 -67
  58. package/dist/src/execution/permit2.d.ts +5 -5
  59. package/dist/src/execution/permit2.js +8 -13
  60. package/dist/src/execution/singleChainOps.d.ts +2 -2
  61. package/dist/src/execution/singleChainOps.js +1 -3
  62. package/dist/src/execution/types.d.ts +1 -1
  63. package/dist/src/execution/types.js +1 -2
  64. package/dist/src/execution/utils.d.ts +10 -6
  65. package/dist/src/execution/utils.d.ts.map +1 -1
  66. package/dist/src/execution/utils.js +159 -162
  67. package/dist/src/index.d.ts +10 -10
  68. package/dist/src/index.d.ts.map +1 -1
  69. package/dist/src/index.js +57 -67
  70. package/dist/src/jwt-server/digest.d.ts +11 -0
  71. package/dist/src/jwt-server/digest.d.ts.map +1 -0
  72. package/dist/src/jwt-server/digest.js +19 -0
  73. package/dist/src/jwt-server/express.d.ts +16 -0
  74. package/dist/src/jwt-server/express.d.ts.map +1 -0
  75. package/dist/src/jwt-server/express.js +23 -0
  76. package/dist/src/jwt-server/handlers.d.ts +10 -0
  77. package/dist/src/jwt-server/handlers.d.ts.map +1 -0
  78. package/dist/src/jwt-server/handlers.js +37 -0
  79. package/dist/src/jwt-server/index.d.ts +8 -0
  80. package/dist/src/jwt-server/index.d.ts.map +1 -0
  81. package/dist/src/jwt-server/index.js +7 -0
  82. package/dist/src/jwt-server/jcs.d.ts +12 -0
  83. package/dist/src/jwt-server/jcs.d.ts.map +1 -0
  84. package/dist/src/jwt-server/jcs.js +57 -0
  85. package/dist/src/jwt-server/signer.d.ts +18 -0
  86. package/dist/src/jwt-server/signer.d.ts.map +1 -0
  87. package/dist/src/jwt-server/signer.js +68 -0
  88. package/dist/src/jwt-server/sponsorship.d.ts +19 -0
  89. package/dist/src/jwt-server/sponsorship.d.ts.map +1 -0
  90. package/dist/src/jwt-server/sponsorship.js +51 -0
  91. package/dist/src/jwt-server/web.d.ts +4 -0
  92. package/dist/src/jwt-server/web.d.ts.map +1 -0
  93. package/dist/src/jwt-server/web.js +23 -0
  94. package/dist/src/modules/abi/smart-session-emissary.js +1 -3
  95. package/dist/src/modules/abi/smart-sessions.js +1 -4
  96. package/dist/src/modules/chain-abstraction.js +1 -5
  97. package/dist/src/modules/common.d.ts +1 -1
  98. package/dist/src/modules/common.js +1 -13
  99. package/dist/src/modules/index.d.ts +5 -5
  100. package/dist/src/modules/index.js +35 -50
  101. package/dist/src/modules/legacy.d.ts +2 -2
  102. package/dist/src/modules/legacy.js +11 -14
  103. package/dist/src/modules/read.d.ts +1 -1
  104. package/dist/src/modules/read.js +11 -15
  105. package/dist/src/modules/validators/core.d.ts +2 -2
  106. package/dist/src/modules/validators/core.js +26 -44
  107. package/dist/src/modules/validators/index.d.ts +2 -2
  108. package/dist/src/modules/validators/index.js +3 -19
  109. package/dist/src/modules/validators/policies/claim/permit2.d.ts +1 -1
  110. package/dist/src/modules/validators/policies/claim/permit2.js +39 -44
  111. package/dist/src/modules/validators/policies/claim/types.js +11 -14
  112. package/dist/src/modules/validators/smart-sessions.d.ts +4 -4
  113. package/dist/src/modules/validators/smart-sessions.d.ts.map +1 -1
  114. package/dist/src/modules/validators/smart-sessions.js +77 -97
  115. package/dist/src/orchestrator/client.d.ts +10 -5
  116. package/dist/src/orchestrator/client.d.ts.map +1 -1
  117. package/dist/src/orchestrator/client.js +73 -66
  118. package/dist/src/orchestrator/consts.d.ts +1 -1
  119. package/dist/src/orchestrator/consts.d.ts.map +1 -1
  120. package/dist/src/orchestrator/consts.js +2 -8
  121. package/dist/src/orchestrator/error.js +1 -33
  122. package/dist/src/orchestrator/index.d.ts +8 -7
  123. package/dist/src/orchestrator/index.d.ts.map +1 -1
  124. package/dist/src/orchestrator/index.js +8 -57
  125. package/dist/src/orchestrator/registry.d.ts +2 -2
  126. package/dist/src/orchestrator/registry.js +19 -33
  127. package/dist/src/orchestrator/types.d.ts +5 -1
  128. package/dist/src/orchestrator/types.d.ts.map +1 -1
  129. package/dist/src/orchestrator/types.js +1 -17
  130. package/dist/src/orchestrator/utils.js +1 -3
  131. package/dist/src/types.d.ts +29 -5
  132. package/dist/src/types.d.ts.map +1 -1
  133. package/dist/src/types.js +1 -2
  134. package/dist/src/utils/index.d.ts +2 -2
  135. package/dist/src/utils/index.js +9 -15
  136. package/package.json +29 -98
  137. package/dist/src/accounts/index.test.d.ts +0 -2
  138. package/dist/src/accounts/index.test.d.ts.map +0 -1
  139. package/dist/src/accounts/index.test.js +0 -33
  140. package/dist/src/accounts/json-rpc/index.test.d.ts +0 -2
  141. package/dist/src/accounts/json-rpc/index.test.d.ts.map +0 -1
  142. package/dist/src/accounts/json-rpc/index.test.js +0 -35
  143. package/dist/src/accounts/json-rpc/providers.test.d.ts +0 -2
  144. package/dist/src/accounts/json-rpc/providers.test.d.ts.map +0 -1
  145. package/dist/src/accounts/json-rpc/providers.test.js +0 -43
  146. package/dist/src/accounts/kernel.test.d.ts +0 -2
  147. package/dist/src/accounts/kernel.test.d.ts.map +0 -1
  148. package/dist/src/accounts/kernel.test.js +0 -132
  149. package/dist/src/accounts/nexus.test.d.ts +0 -2
  150. package/dist/src/accounts/nexus.test.d.ts.map +0 -1
  151. package/dist/src/accounts/nexus.test.js +0 -118
  152. package/dist/src/accounts/safe.test.d.ts +0 -2
  153. package/dist/src/accounts/safe.test.d.ts.map +0 -1
  154. package/dist/src/accounts/safe.test.js +0 -168
  155. package/dist/src/accounts/signing/passkeys.test.d.ts +0 -2
  156. package/dist/src/accounts/signing/passkeys.test.d.ts.map +0 -1
  157. package/dist/src/accounts/signing/passkeys.test.js +0 -88
  158. package/dist/src/accounts/startale.test.d.ts +0 -2
  159. package/dist/src/accounts/startale.test.d.ts.map +0 -1
  160. package/dist/src/accounts/startale.test.js +0 -189
  161. package/dist/src/accounts/utils.test.d.ts +0 -2
  162. package/dist/src/accounts/utils.test.d.ts.map +0 -1
  163. package/dist/src/accounts/utils.test.js +0 -49
  164. package/dist/src/actions/ecdsa.test.d.ts +0 -2
  165. package/dist/src/actions/ecdsa.test.d.ts.map +0 -1
  166. package/dist/src/actions/ecdsa.test.js +0 -99
  167. package/dist/src/actions/passkeys.test.d.ts +0 -2
  168. package/dist/src/actions/passkeys.test.d.ts.map +0 -1
  169. package/dist/src/actions/passkeys.test.js +0 -54
  170. package/dist/src/actions/recovery.test.d.ts +0 -2
  171. package/dist/src/actions/recovery.test.d.ts.map +0 -1
  172. package/dist/src/actions/recovery.test.js +0 -168
  173. package/dist/src/execution/signing.test.d.ts +0 -2
  174. package/dist/src/execution/signing.test.d.ts.map +0 -1
  175. package/dist/src/execution/signing.test.js +0 -465
  176. package/dist/src/execution/utils.test.d.ts +0 -2
  177. package/dist/src/execution/utils.test.d.ts.map +0 -1
  178. package/dist/src/execution/utils.test.js +0 -388
  179. package/dist/src/modules/index.test.d.ts +0 -2
  180. package/dist/src/modules/index.test.d.ts.map +0 -1
  181. package/dist/src/modules/index.test.js +0 -81
  182. package/dist/src/modules/validators/core.test.d.ts +0 -2
  183. package/dist/src/modules/validators/core.test.d.ts.map +0 -1
  184. package/dist/src/modules/validators/core.test.js +0 -101
  185. package/dist/src/modules/validators/policies/claim/permit2.test.d.ts +0 -2
  186. package/dist/src/modules/validators/policies/claim/permit2.test.d.ts.map +0 -1
  187. package/dist/src/modules/validators/policies/claim/permit2.test.js +0 -519
  188. package/dist/src/modules/validators/smart-sessions.test.d.ts +0 -2
  189. package/dist/src/modules/validators/smart-sessions.test.d.ts.map +0 -1
  190. package/dist/src/modules/validators/smart-sessions.test.js +0 -311
  191. package/dist/src/orchestrator/registry.test.d.ts +0 -2
  192. package/dist/src/orchestrator/registry.test.d.ts.map +0 -1
  193. package/dist/src/orchestrator/registry.test.js +0 -154
  194. package/dist/src/utils/index.test.d.ts +0 -2
  195. package/dist/src/utils/index.test.d.ts.map +0 -1
  196. package/dist/src/utils/index.test.js +0 -42
  197. package/dist/test/consts.d.ts +0 -10
  198. package/dist/test/consts.d.ts.map +0 -1
  199. package/dist/test/consts.js +0 -22
  200. package/dist/test/utils/utils.d.ts +0 -5
  201. package/dist/test/utils/utils.d.ts.map +0 -1
  202. package/dist/test/utils/utils.js +0 -20
@@ -1,519 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const viem_1 = require("viem");
4
- const vitest_1 = require("vitest");
5
- const permit2_1 = require("./permit2");
6
- const types_1 = require("./types");
7
- // ---------------------------------------------------------------------------
8
- // Shared fixtures
9
- // ---------------------------------------------------------------------------
10
- const TOKEN_A = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'; // USDC
11
- const TOKEN_B = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'; // WETH
12
- const ARBITER = '0x1234567890123456789012345678901234567890';
13
- /** Zero-value Op struct (vt is bytes32, empty ops) */
14
- const EMPTY_OP = {
15
- vt: viem_1.zeroHash,
16
- ops: [],
17
- };
18
- /** A simple message with one permitted token and no mandate ops */
19
- const baseMessage = {
20
- permitted: [{ token: TOKEN_A, amount: 1000n }],
21
- spender: ARBITER,
22
- nonce: 42n,
23
- deadline: 9999999n,
24
- mandate: {
25
- target: {
26
- recipient: ARBITER,
27
- tokenOut: [{ token: TOKEN_B, amount: 500n }],
28
- targetChain: 8453n,
29
- fillExpiry: 888888n,
30
- },
31
- minGas: 100000n,
32
- originOps: EMPTY_OP,
33
- destOps: EMPTY_OP,
34
- q: (0, viem_1.keccak256)('0x'),
35
- },
36
- };
37
- // ---------------------------------------------------------------------------
38
- // Hash helpers (mirror of the private functions in permit2.ts)
39
- // ---------------------------------------------------------------------------
40
- const TYPEHASH_PERMIT2_TOKEN = '0x618358ac3db8dc274f0cd8829da7e234bd48cd73c4a740aede1adec9846d06a1';
41
- const TYPEHASH_TOKENOUT = '0x55550a068ac7a6c7ce02eac46ebe7c7b964dd10d7800455df1c5bc5a6685a42c';
42
- const TYPEHASH_TARGET = '0xf72802bb5695954ab337feb3d113d61f4206cfaef3987552df2b2b47477db74b';
43
- const TYPEHASH_OPS = '0x09b0a32e9842b65559835c235891737e06927d59e48a6f0e0512e136a513a9e4';
44
- const TYPEHASH_OP = '0xdbc520cb50a8aaf3fa06ea43dc3d59d248e52ae638476e3268a1e6e36bffe196';
45
- const TYPEHASH_MANDATE = '0xc988b4da10503879cf4b893fed09620229f5ade301ef5e4af6124b22823627dc';
46
- function hashArray(hashes) {
47
- return (0, viem_1.keccak256)(hashes.length > 0 ? (0, viem_1.concat)(hashes) : '0x');
48
- }
49
- function hashToken(token, amount, typehash) {
50
- return (0, viem_1.keccak256)((0, viem_1.encodeAbiParameters)([{ type: 'bytes32' }, { type: 'address' }, { type: 'uint256' }], [typehash, token, amount]));
51
- }
52
- function hashOp(op) {
53
- const execHashes = Array.from(op.ops).map((e) => (0, viem_1.keccak256)((0, viem_1.encodeAbiParameters)([
54
- { type: 'bytes32' },
55
- { type: 'address' },
56
- { type: 'uint256' },
57
- { type: 'bytes32' },
58
- ], [TYPEHASH_OPS, e.to, e.value, (0, viem_1.keccak256)(e.data)])));
59
- return (0, viem_1.keccak256)((0, viem_1.encodeAbiParameters)([{ type: 'bytes32' }, { type: 'bytes32' }, { type: 'bytes32' }], [TYPEHASH_OP, op.vt, hashArray(execHashes)]));
60
- }
61
- function hashTarget(recipient, tokenOutHash, targetChain, fillExpiry) {
62
- return (0, viem_1.keccak256)((0, viem_1.encodeAbiParameters)([
63
- { type: 'bytes32' },
64
- { type: 'address' },
65
- { type: 'bytes32' },
66
- { type: 'uint256' },
67
- { type: 'uint256' },
68
- ], [TYPEHASH_TARGET, recipient, tokenOutHash, targetChain, fillExpiry]));
69
- }
70
- function hashMandate(targetHash, minGas, originOpsHash, destOpsHash, q) {
71
- return (0, viem_1.keccak256)((0, viem_1.encodeAbiParameters)([
72
- { type: 'bytes32' },
73
- { type: 'bytes32' },
74
- { type: 'uint128' },
75
- { type: 'bytes32' },
76
- { type: 'bytes32' },
77
- { type: 'bytes32' },
78
- ], [TYPEHASH_MANDATE, targetHash, minGas, originOpsHash, destOpsHash, q]));
79
- }
80
- // ---------------------------------------------------------------------------
81
- // Tests
82
- // ---------------------------------------------------------------------------
83
- (0, vitest_1.describe)('buildPermit2ClaimPolicyCalldata', () => {
84
- (0, vitest_1.describe)('header', () => {
85
- (0, vitest_1.test)('always starts with [spender:20][nonce:32][deadline:32]', () => {
86
- const policy = { type: 'permit2-claim' };
87
- const result = (0, permit2_1.buildPermit2ClaimPolicyCalldata)(policy, baseMessage);
88
- const expectedHeader = (0, viem_1.encodePacked)(['address', 'uint256', 'uint256'], [baseMessage.spender, baseMessage.nonce, baseMessage.deadline]);
89
- // Header is 84 bytes (20 + 32 + 32)
90
- (0, vitest_1.expect)(result.slice(0, 2 + 84 * 2)).toBe(expectedHeader);
91
- });
92
- });
93
- (0, vitest_1.describe)('tokenIn — hash-only mode (no tokensIn policy)', () => {
94
- (0, vitest_1.test)('inserts keccak256 of token permissions array', () => {
95
- const policy = { type: 'permit2-claim' };
96
- const result = (0, permit2_1.buildPermit2ClaimPolicyCalldata)(policy, baseMessage);
97
- const tokenHash = hashArray(baseMessage.permitted.map(({ token, amount }) => hashToken(token, amount, TYPEHASH_PERMIT2_TOKEN)));
98
- // Header = 84 bytes, then 32 bytes of tokenPermissionsHash
99
- const tokenHashInResult = `0x${result.slice(2 + 84 * 2, 2 + 84 * 2 + 64)}`;
100
- (0, vitest_1.expect)(tokenHashInResult).toBe(tokenHash);
101
- });
102
- });
103
- (0, vitest_1.describe)('tokenIn — expanded mode (tokensIn policy set)', () => {
104
- (0, vitest_1.test)('writes [count:1][token_uint256:32][amount:32] per permitted token', () => {
105
- const policy = {
106
- type: 'permit2-claim',
107
- tokensIn: [{ chainId: 1, token: TOKEN_A }],
108
- };
109
- const result = (0, permit2_1.buildPermit2ClaimPolicyCalldata)(policy, baseMessage);
110
- const headerLen = 84;
111
- const offset = 2 + headerLen * 2;
112
- // count byte
113
- (0, vitest_1.expect)(result.slice(offset, offset + 2)).toBe((0, viem_1.toHex)(baseMessage.permitted.length, { size: 1 }).slice(2));
114
- // token entry: address abi-encoded as uint256 (left-padded) + amount
115
- const { token, amount } = baseMessage.permitted[0];
116
- const expectedEntry = (0, viem_1.encodeAbiParameters)([{ type: 'address' }, { type: 'uint256' }], [token, amount]);
117
- (0, vitest_1.expect)(result.slice(offset + 2, offset + 2 + 128)).toBe(expectedEntry.slice(2));
118
- });
119
- (0, vitest_1.test)('length increases with each permitted token', () => {
120
- const policy = {
121
- type: 'permit2-claim',
122
- tokensIn: [{ chainId: 1, token: TOKEN_A }],
123
- };
124
- const msg2 = {
125
- ...baseMessage,
126
- permitted: [
127
- { token: TOKEN_A, amount: 1000n },
128
- { token: TOKEN_B, amount: 2000n },
129
- ],
130
- };
131
- const r1 = (0, permit2_1.buildPermit2ClaimPolicyCalldata)(policy, baseMessage);
132
- const r2 = (0, permit2_1.buildPermit2ClaimPolicyCalldata)(policy, msg2);
133
- // r2 should be 64 bytes (one extra token entry) longer than r1
134
- (0, vitest_1.expect)((r2.length - r1.length) / 2).toBe(64);
135
- });
136
- });
137
- (0, vitest_1.describe)('mandate — hash-only mode (no target checks)', () => {
138
- (0, vitest_1.test)('inserts pre-computed mandateHash when no target checks enabled', () => {
139
- const policy = { type: 'permit2-claim' };
140
- const result = (0, permit2_1.buildPermit2ClaimPolicyCalldata)(policy, baseMessage);
141
- const m = baseMessage.mandate;
142
- const tokenOutHash = hashArray(m.target.tokenOut.map(({ token, amount }) => hashToken(token, amount, TYPEHASH_TOKENOUT)));
143
- const targetHash = hashTarget(m.target.recipient, tokenOutHash, m.target.targetChain, m.target.fillExpiry);
144
- const expectedMandateHash = hashMandate(targetHash, m.minGas, hashOp(m.originOps), hashOp(m.destOps), m.q);
145
- // Hash-only: header(84) + tokenPermissionsHash(32) + mandateHash(32) = 148 bytes
146
- (0, vitest_1.expect)((result.length - 2) / 2).toBe(148);
147
- const mandateHashInResult = `0x${result.slice(2 + (84 + 32) * 2)}`;
148
- (0, vitest_1.expect)(mandateHashInResult).toBe(expectedMandateHash);
149
- });
150
- });
151
- (0, vitest_1.describe)('mandate — expanded mode (target checks enabled)', () => {
152
- (0, vitest_1.test)('tokenOut policy: expands target with [count:1][token:32][amount:32]...', () => {
153
- const policy = {
154
- type: 'permit2-claim',
155
- tokensOut: [{ chainId: 8453, token: TOKEN_B }],
156
- };
157
- const result = (0, permit2_1.buildPermit2ClaimPolicyCalldata)(policy, baseMessage);
158
- // Expanded: header(84) + tokenPermissionsHash(32) + target[recipient:20,targetChain:32,fillExpiry:32]
159
- // + tokenOut[count:1, entry:64] + minGas(16) + originOpsHash(32) + destOpsHash(32) + q(32)
160
- // = 84 + 32 + 84 + 1 + 64 + 16 + 32 + 32 + 32 = 377 bytes
161
- (0, vitest_1.expect)((result.length - 2) / 2).toBe(377);
162
- });
163
- (0, vitest_1.test)('recipient policy: expands target, tokenOut is hashed', () => {
164
- const policy = {
165
- type: 'permit2-claim',
166
- recipients: [{ chainId: 8453, recipient: ARBITER }],
167
- };
168
- const result = (0, permit2_1.buildPermit2ClaimPolicyCalldata)(policy, baseMessage);
169
- // Expanded: header(84) + tokenPermissionsHash(32) + target header(84)
170
- // + tokenOutHash(32) + minGas(16) + originOpsHash(32) + destOpsHash(32) + q(32) = 344 bytes
171
- (0, vitest_1.expect)((result.length - 2) / 2).toBe(344);
172
- });
173
- (0, vitest_1.test)('fillExpiry policy: expands target, tokenOut is hashed', () => {
174
- const policy = {
175
- type: 'permit2-claim',
176
- fillExpiryBounds: [{ chainId: 8453 }],
177
- };
178
- const result = (0, permit2_1.buildPermit2ClaimPolicyCalldata)(policy, baseMessage);
179
- (0, vitest_1.expect)((result.length - 2) / 2).toBe(344);
180
- });
181
- (0, vitest_1.test)('recipientIsSponsor: expands target, tokenOut is hashed', () => {
182
- const policy = {
183
- type: 'permit2-claim',
184
- recipientIsSponsor: true,
185
- };
186
- const result = (0, permit2_1.buildPermit2ClaimPolicyCalldata)(policy, baseMessage);
187
- (0, vitest_1.expect)((result.length - 2) / 2).toBe(344);
188
- });
189
- (0, vitest_1.test)('expanded target starts with [recipient:20][targetChain:32][fillExpiry:32]', () => {
190
- const policy = {
191
- type: 'permit2-claim',
192
- recipients: [{ chainId: 8453, recipient: ARBITER }],
193
- };
194
- const result = (0, permit2_1.buildPermit2ClaimPolicyCalldata)(policy, baseMessage);
195
- const { target } = baseMessage.mandate;
196
- const expectedTargetHeader = (0, viem_1.encodePacked)(['address', 'uint256', 'uint256'], [target.recipient, target.targetChain, target.fillExpiry]);
197
- // tokenPermissionsHash ends at offset 84+32=116 bytes from start
198
- const targetStart = 2 + (84 + 32) * 2;
199
- (0, vitest_1.expect)(result.slice(targetStart, targetStart + expectedTargetHeader.length - 2)).toBe(expectedTargetHeader.slice(2));
200
- });
201
- (0, vitest_1.test)('q is appended verbatim at the end', () => {
202
- const policy = {
203
- type: 'permit2-claim',
204
- recipients: [{ chainId: 8453, recipient: ARBITER }],
205
- };
206
- const result = (0, permit2_1.buildPermit2ClaimPolicyCalldata)(policy, baseMessage);
207
- // q is always the last 32 bytes
208
- const qInResult = `0x${result.slice(result.length - 64)}`;
209
- (0, vitest_1.expect)(qInResult).toBe(baseMessage.mandate.q);
210
- });
211
- });
212
- (0, vitest_1.describe)('determinism', () => {
213
- (0, vitest_1.test)('same inputs always produce same output', () => {
214
- const policy = {
215
- type: 'permit2-claim',
216
- tokensIn: [{ chainId: 1, token: TOKEN_A }],
217
- tokensOut: [{ chainId: 8453, token: TOKEN_B }],
218
- };
219
- const r1 = (0, permit2_1.buildPermit2ClaimPolicyCalldata)(policy, baseMessage);
220
- const r2 = (0, permit2_1.buildPermit2ClaimPolicyCalldata)(policy, baseMessage);
221
- (0, vitest_1.expect)(r1).toBe(r2);
222
- });
223
- (0, vitest_1.test)('hash-only and expanded modes produce different output', () => {
224
- const hashOnlyPolicy = { type: 'permit2-claim' };
225
- const expandedPolicy = {
226
- type: 'permit2-claim',
227
- tokensOut: [{ chainId: 8453, token: TOKEN_B }],
228
- };
229
- const r1 = (0, permit2_1.buildPermit2ClaimPolicyCalldata)(hashOnlyPolicy, baseMessage);
230
- const r2 = (0, permit2_1.buildPermit2ClaimPolicyCalldata)(expandedPolicy, baseMessage);
231
- (0, vitest_1.expect)(r1).not.toBe(r2);
232
- (0, vitest_1.expect)(r1.length).toBeLessThan(r2.length);
233
- });
234
- });
235
- (0, vitest_1.describe)('empty arrays', () => {
236
- (0, vitest_1.test)('empty permitted array hashes to keccak256 of empty bytes', () => {
237
- const policy = { type: 'permit2-claim' };
238
- const msgEmpty = { ...baseMessage, permitted: [] };
239
- const result = (0, permit2_1.buildPermit2ClaimPolicyCalldata)(policy, msgEmpty);
240
- const emptyHash = (0, viem_1.keccak256)('0x');
241
- const tokenHashInResult = `0x${result.slice(2 + 84 * 2, 2 + 84 * 2 + 64)}`;
242
- (0, vitest_1.expect)(tokenHashInResult).toBe(emptyHash);
243
- });
244
- (0, vitest_1.test)('empty tokenOut array hashes to keccak256 of empty bytes in hash-only mode', () => {
245
- const policy = { type: 'permit2-claim' };
246
- const msgNoOut = {
247
- ...baseMessage,
248
- mandate: {
249
- ...baseMessage.mandate,
250
- target: { ...baseMessage.mandate.target, tokenOut: [] },
251
- },
252
- };
253
- const r1 = (0, permit2_1.buildPermit2ClaimPolicyCalldata)(policy, msgNoOut);
254
- // Should succeed without errors and be deterministic
255
- const r2 = (0, permit2_1.buildPermit2ClaimPolicyCalldata)(policy, msgNoOut);
256
- (0, vitest_1.expect)(r1).toBe(r2);
257
- });
258
- });
259
- });
260
- // ---------------------------------------------------------------------------
261
- // Op hashing — non-empty ops and non-zero vt (as the orchestrator sends them)
262
- // ---------------------------------------------------------------------------
263
- (0, vitest_1.describe)('Op hashing with real orchestrator data shapes', () => {
264
- const policy = { type: 'permit2-claim' };
265
- // vt as the orchestrator produces it: bytes32(bytes2([execType, sigMode]))
266
- // e.g. execType=0x04 (ERC7579), sigMode=0x01 (EMISSARY) → 0x0401 in first 2 bytes
267
- const REAL_VT = `0x0401${'00'.repeat(30)}`;
268
- const EXEC_A = {
269
- to: TOKEN_A,
270
- value: 0n,
271
- data: '0xdeadbeef',
272
- };
273
- const EXEC_B = {
274
- to: TOKEN_B,
275
- value: 1000n,
276
- data: '0x',
277
- };
278
- (0, vitest_1.test)('non-zero vt produces different hash than zero vt', () => {
279
- const opZeroVt = { vt: viem_1.zeroHash, ops: [EXEC_A] };
280
- const opRealVt = { vt: REAL_VT, ops: [EXEC_A] };
281
- // Use hash-only mandate mode so ops hash is visible in output
282
- const msgZeroVt = {
283
- ...baseMessage,
284
- mandate: { ...baseMessage.mandate, originOps: opZeroVt },
285
- };
286
- const msgRealVt = {
287
- ...baseMessage,
288
- mandate: { ...baseMessage.mandate, originOps: opRealVt },
289
- };
290
- const r1 = (0, permit2_1.buildPermit2ClaimPolicyCalldata)(policy, msgZeroVt);
291
- const r2 = (0, permit2_1.buildPermit2ClaimPolicyCalldata)(policy, msgRealVt);
292
- (0, vitest_1.expect)(r1).not.toBe(r2);
293
- });
294
- (0, vitest_1.test)('non-empty ops array produces different hash than empty ops', () => {
295
- const opEmpty = { vt: REAL_VT, ops: [] };
296
- const opWithExec = { vt: REAL_VT, ops: [EXEC_A] };
297
- const msgEmpty = {
298
- ...baseMessage,
299
- mandate: { ...baseMessage.mandate, originOps: opEmpty },
300
- };
301
- const msgWithExec = {
302
- ...baseMessage,
303
- mandate: { ...baseMessage.mandate, originOps: opWithExec },
304
- };
305
- const r1 = (0, permit2_1.buildPermit2ClaimPolicyCalldata)(policy, msgEmpty);
306
- const r2 = (0, permit2_1.buildPermit2ClaimPolicyCalldata)(policy, msgWithExec);
307
- (0, vitest_1.expect)(r1).not.toBe(r2);
308
- });
309
- (0, vitest_1.test)('ops order matters — different order produces different hash', () => {
310
- const opAB = { vt: REAL_VT, ops: [EXEC_A, EXEC_B] };
311
- const opBA = { vt: REAL_VT, ops: [EXEC_B, EXEC_A] };
312
- const msgAB = {
313
- ...baseMessage,
314
- mandate: { ...baseMessage.mandate, originOps: opAB },
315
- };
316
- const msgBA = {
317
- ...baseMessage,
318
- mandate: { ...baseMessage.mandate, originOps: opBA },
319
- };
320
- const r1 = (0, permit2_1.buildPermit2ClaimPolicyCalldata)(policy, msgAB);
321
- const r2 = (0, permit2_1.buildPermit2ClaimPolicyCalldata)(policy, msgBA);
322
- (0, vitest_1.expect)(r1).not.toBe(r2);
323
- });
324
- (0, vitest_1.test)('ops hash matches manual computation (bytes32 vt encoding)', () => {
325
- const op = { vt: REAL_VT, ops: [EXEC_A, EXEC_B] };
326
- const msg = {
327
- ...baseMessage,
328
- mandate: { ...baseMessage.mandate, originOps: op, destOps: EMPTY_OP },
329
- };
330
- const result = (0, permit2_1.buildPermit2ClaimPolicyCalldata)(policy, msg);
331
- // Manually compute expected mandate hash
332
- const execHashA = (0, viem_1.keccak256)((0, viem_1.encodeAbiParameters)([
333
- { type: 'bytes32' },
334
- { type: 'address' },
335
- { type: 'uint256' },
336
- { type: 'bytes32' },
337
- ], [TYPEHASH_OPS, EXEC_A.to, EXEC_A.value, (0, viem_1.keccak256)(EXEC_A.data)]));
338
- const execHashB = (0, viem_1.keccak256)((0, viem_1.encodeAbiParameters)([
339
- { type: 'bytes32' },
340
- { type: 'address' },
341
- { type: 'uint256' },
342
- { type: 'bytes32' },
343
- ], [TYPEHASH_OPS, EXEC_B.to, EXEC_B.value, (0, viem_1.keccak256)(EXEC_B.data)]));
344
- const opsArrayHash = (0, viem_1.keccak256)((0, viem_1.concat)([execHashA, execHashB]));
345
- const expectedOriginOpsHash = (0, viem_1.keccak256)((0, viem_1.encodeAbiParameters)([{ type: 'bytes32' }, { type: 'bytes32' }, { type: 'bytes32' }], [TYPEHASH_OP, REAL_VT, opsArrayHash]));
346
- const tokenOutHash = hashArray(msg.mandate.target.tokenOut.map(({ token, amount }) => hashToken(token, amount, TYPEHASH_TOKENOUT)));
347
- const targetHash = hashTarget(msg.mandate.target.recipient, tokenOutHash, msg.mandate.target.targetChain, msg.mandate.target.fillExpiry);
348
- const expectedMandateHash = (0, viem_1.keccak256)((0, viem_1.encodeAbiParameters)([
349
- { type: 'bytes32' },
350
- { type: 'bytes32' },
351
- { type: 'uint128' },
352
- { type: 'bytes32' },
353
- { type: 'bytes32' },
354
- { type: 'bytes32' },
355
- ], [
356
- TYPEHASH_MANDATE,
357
- targetHash,
358
- msg.mandate.minGas,
359
- expectedOriginOpsHash,
360
- hashOp(EMPTY_OP),
361
- msg.mandate.q,
362
- ]));
363
- // mandate hash is the last 32 bytes in hash-only mode
364
- const mandateHashInResult = `0x${result.slice(result.length - 64)}`;
365
- (0, vitest_1.expect)(mandateHashInResult).toBe(expectedMandateHash);
366
- });
367
- (0, vitest_1.test)('message shape matching getTypedData output: vt as 32-byte hex from orchestrator', () => {
368
- // Simulates what getTypedData in execution/permit2.ts produces:
369
- // mandate.preClaimOps = { vt: <32-byte hex>, ops: Execution[] }
370
- const orchestratorStyleMessage = {
371
- permitted: [{ token: TOKEN_A, amount: 500000n }],
372
- spender: ARBITER,
373
- nonce: 1n,
374
- deadline: 2000000000n,
375
- mandate: {
376
- target: {
377
- recipient: ARBITER,
378
- tokenOut: [{ token: TOKEN_B, amount: 250000n }],
379
- targetChain: 8453n,
380
- fillExpiry: 1999999999n,
381
- },
382
- minGas: 200000n,
383
- // vt as bytes32 with execType=0x04 (ERC7579), sigMode=0x01 (EMISSARY)
384
- originOps: { vt: `0x0401${'00'.repeat(30)}`, ops: [] },
385
- destOps: { vt: `0x0401${'00'.repeat(30)}`, ops: [] },
386
- q: (0, viem_1.keccak256)('0xabcdef'),
387
- },
388
- };
389
- const result = (0, permit2_1.buildPermit2ClaimPolicyCalldata)({ type: 'permit2-claim' }, orchestratorStyleMessage);
390
- // Should produce a deterministic 148-byte output (all hash-only mode)
391
- (0, vitest_1.expect)((result.length - 2) / 2).toBe(148);
392
- // Should be deterministic
393
- (0, vitest_1.expect)((0, permit2_1.buildPermit2ClaimPolicyCalldata)({ type: 'permit2-claim' }, orchestratorStyleMessage)).toBe(result);
394
- });
395
- });
396
- // ---------------------------------------------------------------------------
397
- // encodePermit2ClaimPolicyInitData
398
- // ---------------------------------------------------------------------------
399
- (0, vitest_1.describe)('encodePermit2ClaimPolicyInitData', () => {
400
- function modeConfigBit(fieldId) {
401
- return types_1.MODE_CHECK_STORAGE << (fieldId * 2);
402
- }
403
- function readModeConfig(initData) {
404
- return Number(BigInt(`0x${initData.slice(2, 10)}`));
405
- }
406
- (0, vitest_1.test)('empty policy: modeConfig=0, only 4-byte header', () => {
407
- const result = (0, permit2_1.encodePermit2ClaimPolicyInitData)({ type: 'permit2-claim' });
408
- // 4 bytes = 8 hex chars + '0x'
409
- (0, vitest_1.expect)(result).toBe('0x00000000');
410
- });
411
- (0, vitest_1.test)('arbiters: sets FIELD_ARBITER mode bit and encodes [count:1][address...]', () => {
412
- const policy = {
413
- type: 'permit2-claim',
414
- arbiters: [ARBITER],
415
- };
416
- const result = (0, permit2_1.encodePermit2ClaimPolicyInitData)(policy);
417
- (0, vitest_1.expect)(readModeConfig(result) & modeConfigBit(types_1.FIELD_ARBITER)).toBeTruthy();
418
- // After 4-byte modeConfig: count(1) + address(20) = 21 bytes
419
- const expected = (0, viem_1.concat)([
420
- (0, viem_1.toHex)(modeConfigBit(types_1.FIELD_ARBITER), { size: 4 }),
421
- (0, viem_1.encodePacked)(['uint8', 'address'], [1, ARBITER]),
422
- ]);
423
- (0, vitest_1.expect)(result).toBe(expected);
424
- });
425
- (0, vitest_1.test)('expiryBounds: sets FIELD_EXPIRY bit and encodes max<<128|min as uint256', () => {
426
- const min = 1000n;
427
- const max = 9999999n;
428
- const policy = {
429
- type: 'permit2-claim',
430
- expiryBounds: { min, max },
431
- };
432
- const result = (0, permit2_1.encodePermit2ClaimPolicyInitData)(policy);
433
- (0, vitest_1.expect)(readModeConfig(result) & modeConfigBit(types_1.FIELD_EXPIRY)).toBeTruthy();
434
- const packed = (min & ((1n << 128n) - 1n)) | (max << 128n);
435
- const expected = (0, viem_1.concat)([
436
- (0, viem_1.toHex)(modeConfigBit(types_1.FIELD_EXPIRY), { size: 4 }),
437
- (0, viem_1.toHex)(packed, { size: 32 }),
438
- ]);
439
- (0, vitest_1.expect)(result).toBe(expected);
440
- });
441
- (0, vitest_1.test)('tokensIn: sets FIELD_TOKEN_IN bit and encodes [count:1][chainId:32][token:20]...', () => {
442
- const policy = {
443
- type: 'permit2-claim',
444
- tokensIn: [{ chainId: 1, token: TOKEN_A }],
445
- };
446
- const result = (0, permit2_1.encodePermit2ClaimPolicyInitData)(policy);
447
- (0, vitest_1.expect)(readModeConfig(result) & modeConfigBit(types_1.FIELD_TOKEN_IN)).toBeTruthy();
448
- const expected = (0, viem_1.concat)([
449
- (0, viem_1.toHex)(modeConfigBit(types_1.FIELD_TOKEN_IN), { size: 4 }),
450
- (0, viem_1.toHex)(1, { size: 1 }),
451
- (0, viem_1.encodePacked)(['uint256', 'address'], [1n, TOKEN_A]),
452
- ]);
453
- (0, vitest_1.expect)(result).toBe(expected);
454
- });
455
- (0, vitest_1.test)('recipients: uses ANY_ADDRESS sentinel for "any"', () => {
456
- const policy = {
457
- type: 'permit2-claim',
458
- recipients: [
459
- { chainId: 8453, recipient: 'any' },
460
- { chainId: 1, recipient: ARBITER },
461
- ],
462
- };
463
- const result = (0, permit2_1.encodePermit2ClaimPolicyInitData)(policy);
464
- (0, vitest_1.expect)(readModeConfig(result) & modeConfigBit(types_1.FIELD_RECIPIENT)).toBeTruthy();
465
- const expected = (0, viem_1.concat)([
466
- (0, viem_1.toHex)(modeConfigBit(types_1.FIELD_RECIPIENT), { size: 4 }),
467
- (0, viem_1.toHex)(2, { size: 1 }),
468
- (0, viem_1.encodePacked)(['uint256', 'address'], [8453n, types_1.ANY_ADDRESS]),
469
- (0, viem_1.encodePacked)(['uint256', 'address'], [1n, ARBITER]),
470
- ]);
471
- (0, vitest_1.expect)(result).toBe(expected);
472
- });
473
- (0, vitest_1.test)('fillExpiryBounds: sets FIELD_FILL_EXPIRY bit and encodes [count:1][chainId:32][packed:32]...', () => {
474
- const policy = {
475
- type: 'permit2-claim',
476
- fillExpiryBounds: [{ chainId: 8453, min: 100n, max: 9000n }],
477
- };
478
- const result = (0, permit2_1.encodePermit2ClaimPolicyInitData)(policy);
479
- (0, vitest_1.expect)(readModeConfig(result) & modeConfigBit(types_1.FIELD_FILL_EXPIRY)).toBeTruthy();
480
- const packed = (100n & ((1n << 128n) - 1n)) | (9000n << 128n);
481
- const expected = (0, viem_1.concat)([
482
- (0, viem_1.toHex)(modeConfigBit(types_1.FIELD_FILL_EXPIRY), { size: 4 }),
483
- (0, viem_1.toHex)(1, { size: 1 }),
484
- (0, viem_1.encodePacked)(['uint256', 'uint256'], [8453n, packed]),
485
- ]);
486
- (0, vitest_1.expect)(result).toBe(expected);
487
- });
488
- (0, vitest_1.test)('tokensOut: sets FIELD_TOKEN_OUT bit', () => {
489
- const policy = {
490
- type: 'permit2-claim',
491
- tokensOut: [{ chainId: 8453, token: TOKEN_B }],
492
- };
493
- const result = (0, permit2_1.encodePermit2ClaimPolicyInitData)(policy);
494
- (0, vitest_1.expect)(readModeConfig(result) & modeConfigBit(types_1.FIELD_TOKEN_OUT)).toBeTruthy();
495
- });
496
- (0, vitest_1.test)('recipientIsSponsor: sets FIELD_RECIPIENT_IS_SPONSOR bit, no extra bytes', () => {
497
- const policy = {
498
- type: 'permit2-claim',
499
- recipientIsSponsor: true,
500
- };
501
- const result = (0, permit2_1.encodePermit2ClaimPolicyInitData)(policy);
502
- (0, vitest_1.expect)(readModeConfig(result) & modeConfigBit(types_1.FIELD_RECIPIENT_IS_SPONSOR)).toBeTruthy();
503
- // Only modeConfig bytes — no additional payload
504
- (0, vitest_1.expect)(result).toBe((0, viem_1.toHex)(modeConfigBit(types_1.FIELD_RECIPIENT_IS_SPONSOR), { size: 4 }));
505
- });
506
- (0, vitest_1.test)('multiple fields: all mode bits are combined correctly', () => {
507
- const policy = {
508
- type: 'permit2-claim',
509
- arbiters: [ARBITER],
510
- tokensIn: [{ chainId: 1, token: TOKEN_A }],
511
- tokensOut: [{ chainId: 8453, token: TOKEN_B }],
512
- };
513
- const result = (0, permit2_1.encodePermit2ClaimPolicyInitData)(policy);
514
- const expectedMode = modeConfigBit(types_1.FIELD_ARBITER) |
515
- modeConfigBit(types_1.FIELD_TOKEN_IN) |
516
- modeConfigBit(types_1.FIELD_TOKEN_OUT);
517
- (0, vitest_1.expect)(readModeConfig(result)).toBe(expectedMode);
518
- });
519
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=smart-sessions.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"smart-sessions.test.d.ts","sourceRoot":"","sources":["../../../../modules/validators/smart-sessions.test.ts"],"names":[],"mappings":""}