@0xsequence/wallet-primitives 0.0.0-20250520201059

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 (96) hide show
  1. package/.turbo/turbo-build.log +5 -0
  2. package/CHANGELOG.md +7 -0
  3. package/LICENSE +202 -0
  4. package/dist/address.d.ts +5 -0
  5. package/dist/address.d.ts.map +1 -0
  6. package/dist/address.js +7 -0
  7. package/dist/address.js.map +1 -0
  8. package/dist/attestation.d.ts +24 -0
  9. package/dist/attestation.d.ts.map +1 -0
  10. package/dist/attestation.js +77 -0
  11. package/dist/attestation.js.map +1 -0
  12. package/dist/config.d.ts +85 -0
  13. package/dist/config.d.ts.map +1 -0
  14. package/dist/config.js +381 -0
  15. package/dist/config.js.map +1 -0
  16. package/dist/constants.d.ts +173 -0
  17. package/dist/constants.d.ts.map +1 -0
  18. package/dist/constants.js +31 -0
  19. package/dist/constants.js.map +1 -0
  20. package/dist/context.d.ts +9 -0
  21. package/dist/context.d.ts.map +1 -0
  22. package/dist/context.js +8 -0
  23. package/dist/context.js.map +1 -0
  24. package/dist/erc-6492.d.ts +19 -0
  25. package/dist/erc-6492.d.ts.map +1 -0
  26. package/dist/erc-6492.js +64 -0
  27. package/dist/erc-6492.js.map +1 -0
  28. package/dist/extensions/index.d.ts +9 -0
  29. package/dist/extensions/index.d.ts.map +1 -0
  30. package/dist/extensions/index.js +7 -0
  31. package/dist/extensions/index.js.map +1 -0
  32. package/dist/extensions/passkeys.d.ts +31 -0
  33. package/dist/extensions/passkeys.d.ts.map +1 -0
  34. package/dist/extensions/passkeys.js +224 -0
  35. package/dist/extensions/passkeys.js.map +1 -0
  36. package/dist/extensions/recovery.d.ts +310 -0
  37. package/dist/extensions/recovery.d.ts.map +1 -0
  38. package/dist/extensions/recovery.js +444 -0
  39. package/dist/extensions/recovery.js.map +1 -0
  40. package/dist/generic-tree.d.ts +14 -0
  41. package/dist/generic-tree.d.ts.map +1 -0
  42. package/dist/generic-tree.js +34 -0
  43. package/dist/generic-tree.js.map +1 -0
  44. package/dist/index.d.ts +16 -0
  45. package/dist/index.d.ts.map +1 -0
  46. package/dist/index.js +16 -0
  47. package/dist/index.js.map +1 -0
  48. package/dist/network.d.ts +15 -0
  49. package/dist/network.d.ts.map +1 -0
  50. package/dist/network.js +24 -0
  51. package/dist/network.js.map +1 -0
  52. package/dist/payload.d.ts +108 -0
  53. package/dist/payload.d.ts.map +1 -0
  54. package/dist/payload.js +627 -0
  55. package/dist/payload.js.map +1 -0
  56. package/dist/permission.d.ts +73 -0
  57. package/dist/permission.d.ts.map +1 -0
  58. package/dist/permission.js +188 -0
  59. package/dist/permission.js.map +1 -0
  60. package/dist/session-config.d.ts +113 -0
  61. package/dist/session-config.d.ts.map +1 -0
  62. package/dist/session-config.js +554 -0
  63. package/dist/session-config.js.map +1 -0
  64. package/dist/session-signature.d.ts +24 -0
  65. package/dist/session-signature.d.ts.map +1 -0
  66. package/dist/session-signature.js +141 -0
  67. package/dist/session-signature.js.map +1 -0
  68. package/dist/signature.d.ts +108 -0
  69. package/dist/signature.d.ts.map +1 -0
  70. package/dist/signature.js +1079 -0
  71. package/dist/signature.js.map +1 -0
  72. package/dist/utils.d.ts +45 -0
  73. package/dist/utils.d.ts.map +1 -0
  74. package/dist/utils.js +100 -0
  75. package/dist/utils.js.map +1 -0
  76. package/eslint.config.mjs +4 -0
  77. package/package.json +27 -0
  78. package/src/address.ts +19 -0
  79. package/src/attestation.ts +114 -0
  80. package/src/config.ts +521 -0
  81. package/src/constants.ts +39 -0
  82. package/src/context.ts +16 -0
  83. package/src/erc-6492.ts +97 -0
  84. package/src/extensions/index.ts +14 -0
  85. package/src/extensions/passkeys.ts +283 -0
  86. package/src/extensions/recovery.ts +542 -0
  87. package/src/generic-tree.ts +55 -0
  88. package/src/index.ts +15 -0
  89. package/src/network.ts +37 -0
  90. package/src/payload.ts +825 -0
  91. package/src/permission.ts +252 -0
  92. package/src/session-config.ts +681 -0
  93. package/src/session-signature.ts +197 -0
  94. package/src/signature.ts +1398 -0
  95. package/src/utils.ts +114 -0
  96. package/tsconfig.json +10 -0
@@ -0,0 +1,310 @@
1
+ import { Address, Bytes, Hex, Provider } from 'ox';
2
+ import * as Payload from '../payload.js';
3
+ import * as GenericTree from '../generic-tree.js';
4
+ import { Signature } from '../index.js';
5
+ export declare const FLAG_RECOVERY_LEAF = 1;
6
+ export declare const FLAG_NODE = 3;
7
+ export declare const FLAG_BRANCH = 4;
8
+ export declare const QUEUE_PAYLOAD: {
9
+ readonly name: "queuePayload";
10
+ readonly type: "function";
11
+ readonly stateMutability: "nonpayable";
12
+ readonly inputs: readonly [{
13
+ readonly type: "address";
14
+ readonly name: "_wallet";
15
+ }, {
16
+ readonly type: "address";
17
+ readonly name: "_signer";
18
+ }, {
19
+ readonly type: "tuple";
20
+ readonly components: readonly [{
21
+ readonly type: "uint8";
22
+ readonly name: "kind";
23
+ }, {
24
+ readonly type: "bool";
25
+ readonly name: "noChainId";
26
+ }, {
27
+ readonly type: "tuple[]";
28
+ readonly components: readonly [{
29
+ readonly type: "address";
30
+ readonly name: "to";
31
+ }, {
32
+ readonly type: "uint256";
33
+ readonly name: "value";
34
+ }, {
35
+ readonly type: "bytes";
36
+ readonly name: "data";
37
+ }, {
38
+ readonly type: "uint256";
39
+ readonly name: "gasLimit";
40
+ }, {
41
+ readonly type: "bool";
42
+ readonly name: "delegateCall";
43
+ }, {
44
+ readonly type: "bool";
45
+ readonly name: "onlyFallback";
46
+ }, {
47
+ readonly type: "uint256";
48
+ readonly name: "behaviorOnError";
49
+ }];
50
+ readonly name: "calls";
51
+ }, {
52
+ readonly type: "uint256";
53
+ readonly name: "space";
54
+ }, {
55
+ readonly type: "uint256";
56
+ readonly name: "nonce";
57
+ }, {
58
+ readonly type: "bytes";
59
+ readonly name: "message";
60
+ }, {
61
+ readonly type: "bytes32";
62
+ readonly name: "imageHash";
63
+ }, {
64
+ readonly type: "bytes32";
65
+ readonly name: "digest";
66
+ }, {
67
+ readonly type: "address[]";
68
+ readonly name: "parentWallets";
69
+ }];
70
+ readonly name: "_payload";
71
+ }, {
72
+ readonly type: "bytes";
73
+ readonly name: "_signature";
74
+ }];
75
+ readonly outputs: readonly [];
76
+ };
77
+ export declare const TIMESTAMP_FOR_QUEUED_PAYLOAD: {
78
+ readonly name: "timestampForQueuedPayload";
79
+ readonly type: "function";
80
+ readonly stateMutability: "view";
81
+ readonly inputs: readonly [{
82
+ readonly type: "address";
83
+ readonly name: "_wallet";
84
+ }, {
85
+ readonly type: "address";
86
+ readonly name: "_signer";
87
+ }, {
88
+ readonly type: "bytes32";
89
+ readonly name: "_payloadHash";
90
+ }];
91
+ readonly outputs: readonly [{
92
+ readonly type: "uint256";
93
+ }];
94
+ };
95
+ export declare const QUEUED_PAYLOAD_HASHES: {
96
+ readonly name: "queuedPayloadHashes";
97
+ readonly type: "function";
98
+ readonly stateMutability: "view";
99
+ readonly inputs: readonly [{
100
+ readonly type: "address";
101
+ readonly name: "_wallet";
102
+ }, {
103
+ readonly type: "address";
104
+ readonly name: "_signer";
105
+ }, {
106
+ readonly type: "uint256";
107
+ readonly name: "_index";
108
+ }];
109
+ readonly outputs: readonly [{
110
+ readonly type: "bytes32";
111
+ }];
112
+ };
113
+ export declare const TOTAL_QUEUED_PAYLOADS: {
114
+ readonly name: "totalQueuedPayloads";
115
+ readonly type: "function";
116
+ readonly stateMutability: "view";
117
+ readonly inputs: readonly [{
118
+ readonly type: "address";
119
+ readonly name: "_wallet";
120
+ }, {
121
+ readonly type: "address";
122
+ readonly name: "_signer";
123
+ }];
124
+ readonly outputs: readonly [{
125
+ readonly type: "uint256";
126
+ }];
127
+ };
128
+ /**
129
+ * A leaf in the Recovery tree, storing:
130
+ * - signer who can queue a payload
131
+ * - requiredDeltaTime how many seconds must pass since the payload is queued
132
+ * - minTimestamp a minimal timestamp that must be at or below the queueing time
133
+ */
134
+ export type RecoveryLeaf = {
135
+ type: 'leaf';
136
+ signer: Address.Address;
137
+ requiredDeltaTime: bigint;
138
+ minTimestamp: bigint;
139
+ };
140
+ /**
141
+ * A branch is a list of subtrees (≥2 in length).
142
+ */
143
+ export type Branch = [Tree, Tree];
144
+ /**
145
+ * The topology of a recovery tree can be either:
146
+ * - A node (pair of subtrees)
147
+ * - A node leaf (32-byte hash)
148
+ * - A recovery leaf (signer with timing constraints)
149
+ */
150
+ export type Tree = Branch | GenericTree.Node | RecoveryLeaf;
151
+ /**
152
+ * Type guard to check if a value is a RecoveryLeaf
153
+ */
154
+ export declare function isRecoveryLeaf(cand: any): cand is RecoveryLeaf;
155
+ /**
156
+ * Type guard to check if a value is a Node (pair of subtrees)
157
+ */
158
+ export declare function isBranch(cand: any): cand is Branch;
159
+ /**
160
+ * Type guard to check if a value is a Topology
161
+ */
162
+ export declare function isTree(cand: any): cand is Tree;
163
+ /**
164
+ * EIP-712 domain parameters for "Sequence Wallet - Recovery Mode"
165
+ */
166
+ export declare const DOMAIN_NAME = "Sequence Wallet - Recovery Mode";
167
+ export declare const DOMAIN_VERSION = "1";
168
+ /**
169
+ * Recursively computes the root hash of a RecoveryTree,
170
+ * consistent with the contract's fkeccak256 usage for (root, node).
171
+ *
172
+ * For recovery leaves, it hashes the leaf data with a prefix.
173
+ * For node leaves, it returns the hash directly.
174
+ * For nodes, it hashes the concatenation of the hashes of both subtrees.
175
+ */
176
+ export declare function hashConfiguration(topology: Tree): Hex.Hex;
177
+ /**
178
+ * Flatten a RecoveryTree into an array of just the leaves.
179
+ * Ignores branch boundaries or node references.
180
+ *
181
+ * @returns Object containing:
182
+ * - leaves: Array of RecoveryLeaf nodes
183
+ * - isComplete: boolean indicating if all leaves are present (no node references)
184
+ */
185
+ export declare function getRecoveryLeaves(topology: Tree): {
186
+ leaves: RecoveryLeaf[];
187
+ isComplete: boolean;
188
+ };
189
+ /**
190
+ * Decode a binary encoded topology into a Topology object
191
+ *
192
+ * @param encoded - The binary encoded topology
193
+ * @returns The decoded Topology object
194
+ * @throws Error if the encoding is invalid
195
+ */
196
+ export declare function decodeTopology(encoded: Bytes.Bytes): Tree;
197
+ /**
198
+ * Parse a branch of the topology from binary encoding
199
+ *
200
+ * @param encoded - The binary encoded branch
201
+ * @returns Object containing:
202
+ * - nodes: Array of parsed Topology nodes
203
+ * - leftover: Any remaining unparsed bytes
204
+ * @throws Error if the encoding is invalid
205
+ */
206
+ export declare function parseBranch(encoded: Bytes.Bytes): {
207
+ nodes: Tree[];
208
+ leftover: Bytes.Bytes;
209
+ };
210
+ /**
211
+ * Trim a topology tree to only include leaves for a specific signer.
212
+ * All other leaves are replaced with their hashes.
213
+ *
214
+ * @param topology - The topology to trim
215
+ * @param signer - The signer address to keep
216
+ * @returns The trimmed topology
217
+ */
218
+ export declare function trimTopology(topology: Tree, signer: Address.Address): Tree;
219
+ /**
220
+ * Encode a topology into its binary representation
221
+ *
222
+ * @param topology - The topology to encode
223
+ * @returns The binary encoded topology
224
+ * @throws Error if the topology is invalid
225
+ */
226
+ export declare function encodeTopology(topology: Tree): Bytes.Bytes;
227
+ /**
228
+ * Build a RecoveryTree from an array of leaves, making a minimal branch structure.
229
+ * If there's exactly one leaf, we return that leaf. If there's more than one, we
230
+ * build a branch of them in pairs.
231
+ *
232
+ * @param leaves - Array of recovery leaves
233
+ * @returns A topology tree structure
234
+ * @throws Error if the leaves array is empty
235
+ */
236
+ export declare function fromRecoveryLeaves(leaves: RecoveryLeaf[]): Tree;
237
+ /**
238
+ * Produces an EIP-712 typed data hash for a "recovery mode" payload,
239
+ * matching the logic in Recovery.sol:
240
+ *
241
+ * keccak256(
242
+ * "\x19\x01",
243
+ * domainSeparator(noChainId, wallet),
244
+ * Payload.toEIP712(payload)
245
+ * )
246
+ *
247
+ * @param payload - The payload to hash
248
+ * @param wallet - The wallet address
249
+ * @param chainId - The chain ID
250
+ * @param noChainId - Whether to omit the chain ID from the domain separator
251
+ * @returns The payload hash
252
+ */
253
+ export declare function hashRecoveryPayload(payload: Payload.MayRecoveryPayload, wallet: Address.Address, chainId: bigint, noChainId: boolean): Hex.Hex;
254
+ /**
255
+ * Convert a RecoveryTree topology to a generic tree format
256
+ *
257
+ * @param topology - The recovery tree topology to convert
258
+ * @returns A generic tree that produces the same root hash
259
+ */
260
+ export declare function toGenericTree(topology: Tree): GenericTree.Tree;
261
+ /**
262
+ * Convert a generic tree back to a RecoveryTree topology
263
+ *
264
+ * @param tree - The generic tree to convert
265
+ * @returns A recovery tree topology that produces the same root hash
266
+ */
267
+ export declare function fromGenericTree(tree: GenericTree.Tree): Tree;
268
+ /**
269
+ * Encodes the calldata for queueing a recovery payload on the recovery extension
270
+ *
271
+ * @param wallet - The wallet address that owns the recovery configuration
272
+ * @param payload - The recovery payload to queue for execution
273
+ * @param signer - The recovery signer address that is queueing the payload
274
+ * @param signature - The signature from the recovery signer authorizing the payload
275
+ * @returns The encoded calldata for the queuePayload function on the recovery extension
276
+ */
277
+ export declare function encodeCalldata(wallet: Address.Address, payload: Payload.Recovery<any>, signer: Address.Address, signature: Signature.SignatureOfSignerLeaf): `0x${string}`;
278
+ /**
279
+ * Gets the total number of payloads queued by a recovery signer for a wallet
280
+ *
281
+ * @param provider - The provider to use for making the eth_call
282
+ * @param extension - The address of the recovery extension contract
283
+ * @param wallet - The wallet address to check queued payloads for
284
+ * @param signer - The recovery signer address to check queued payloads for
285
+ * @returns The total number of payloads queued by this signer for this wallet
286
+ */
287
+ export declare function totalQueuedPayloads(provider: Provider.Provider, extension: Address.Address, wallet: Address.Address, signer: Address.Address): Promise<bigint>;
288
+ /**
289
+ * Gets the hash of a queued payload at a specific index
290
+ *
291
+ * @param provider - The provider to use for making the eth_call
292
+ * @param extension - The address of the recovery extension contract
293
+ * @param wallet - The wallet address to get the queued payload for
294
+ * @param signer - The recovery signer address that queued the payload
295
+ * @param index - The index of the queued payload to get the hash for
296
+ * @returns The hash of the queued payload at the specified index
297
+ */
298
+ export declare function queuedPayloadHashOf(provider: Provider.Provider, extension: Address.Address, wallet: Address.Address, signer: Address.Address, index: bigint): Promise<Hex.Hex>;
299
+ /**
300
+ * Gets the timestamp when a specific payload was queued
301
+ *
302
+ * @param provider - The provider to use for making the eth_call
303
+ * @param extension - The address of the recovery extension contract
304
+ * @param wallet - The wallet address the payload was queued for
305
+ * @param signer - The recovery signer address that queued the payload
306
+ * @param payloadHash - The hash of the queued payload to get the timestamp for
307
+ * @returns The timestamp when the payload was queued, or 0 if not found
308
+ */
309
+ export declare function timestampForQueuedPayload(provider: Provider.Provider, extension: Address.Address, wallet: Address.Address, signer: Address.Address, payloadHash: Hex.Hex): Promise<bigint>;
310
+ //# sourceMappingURL=recovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recovery.d.ts","sourceRoot":"","sources":["../../src/extensions/recovery.ts"],"names":[],"mappings":"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"}