ox 1.7.4 → 1.8.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 (237) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/core/AbiEvent.d.ts.map +1 -1
  3. package/dist/core/AbiEvent.js +10 -9
  4. package/dist/core/AbiEvent.js.map +1 -1
  5. package/dist/core/Blobs.d.ts.map +1 -1
  6. package/dist/core/Blobs.js +6 -2
  7. package/dist/core/Blobs.js.map +1 -1
  8. package/dist/core/Frame.d.ts +290 -0
  9. package/dist/core/Frame.d.ts.map +1 -0
  10. package/dist/core/Frame.js +306 -0
  11. package/dist/core/Frame.js.map +1 -0
  12. package/dist/core/FrameReceipt.d.ts +92 -0
  13. package/dist/core/FrameReceipt.d.ts.map +1 -0
  14. package/dist/core/FrameReceipt.js +72 -0
  15. package/dist/core/FrameReceipt.js.map +1 -0
  16. package/dist/core/FrameSignature.d.ts +357 -0
  17. package/dist/core/FrameSignature.d.ts.map +1 -0
  18. package/dist/core/FrameSignature.js +411 -0
  19. package/dist/core/FrameSignature.js.map +1 -0
  20. package/dist/core/Signature.d.ts +6 -5
  21. package/dist/core/Signature.d.ts.map +1 -1
  22. package/dist/core/Signature.js +17 -7
  23. package/dist/core/Signature.js.map +1 -1
  24. package/dist/core/Siwe.d.ts.map +1 -1
  25. package/dist/core/Siwe.js +21 -1
  26. package/dist/core/Siwe.js.map +1 -1
  27. package/dist/core/Transaction.d.ts +29 -4
  28. package/dist/core/Transaction.d.ts.map +1 -1
  29. package/dist/core/Transaction.js +25 -4
  30. package/dist/core/Transaction.js.map +1 -1
  31. package/dist/core/TransactionReceipt.d.ts +13 -4
  32. package/dist/core/TransactionReceipt.d.ts.map +1 -1
  33. package/dist/core/TransactionReceipt.js +14 -0
  34. package/dist/core/TransactionReceipt.js.map +1 -1
  35. package/dist/core/TransactionRequest.d.ts +15 -7
  36. package/dist/core/TransactionRequest.d.ts.map +1 -1
  37. package/dist/core/TransactionRequest.js +47 -1
  38. package/dist/core/TransactionRequest.js.map +1 -1
  39. package/dist/core/TxEnvelope.d.ts +35 -21
  40. package/dist/core/TxEnvelope.d.ts.map +1 -1
  41. package/dist/core/TxEnvelope.js +46 -6
  42. package/dist/core/TxEnvelope.js.map +1 -1
  43. package/dist/core/TxEnvelopeEip8141.d.ts +341 -0
  44. package/dist/core/TxEnvelopeEip8141.d.ts.map +1 -0
  45. package/dist/core/TxEnvelopeEip8141.js +485 -0
  46. package/dist/core/TxEnvelopeEip8141.js.map +1 -0
  47. package/dist/core/internal/curves.d.ts +2 -0
  48. package/dist/core/internal/curves.d.ts.map +1 -1
  49. package/dist/core/internal/curves.js +2 -0
  50. package/dist/core/internal/curves.js.map +1 -1
  51. package/dist/index.d.ts +73 -0
  52. package/dist/index.d.ts.map +1 -1
  53. package/dist/index.js +73 -0
  54. package/dist/index.js.map +1 -1
  55. package/dist/tempo/KeyAuthorization.d.ts +42 -38
  56. package/dist/tempo/KeyAuthorization.d.ts.map +1 -1
  57. package/dist/tempo/KeyAuthorization.js +24 -4
  58. package/dist/tempo/KeyAuthorization.js.map +1 -1
  59. package/dist/tempo/MultisigConfig.d.ts +18 -15
  60. package/dist/tempo/MultisigConfig.d.ts.map +1 -1
  61. package/dist/tempo/MultisigConfig.js +49 -20
  62. package/dist/tempo/MultisigConfig.js.map +1 -1
  63. package/dist/tempo/MultisigOperation.d.ts +3 -2
  64. package/dist/tempo/MultisigOperation.d.ts.map +1 -1
  65. package/dist/tempo/MultisigOperation.js +20 -100
  66. package/dist/tempo/MultisigOperation.js.map +1 -1
  67. package/dist/tempo/MultisigSimulation.d.ts +2 -49
  68. package/dist/tempo/MultisigSimulation.d.ts.map +1 -1
  69. package/dist/tempo/MultisigSimulation.js +18 -46
  70. package/dist/tempo/MultisigSimulation.js.map +1 -1
  71. package/dist/tempo/SignatureEnvelope.d.ts +72 -140
  72. package/dist/tempo/SignatureEnvelope.d.ts.map +1 -1
  73. package/dist/tempo/SignatureEnvelope.js +130 -181
  74. package/dist/tempo/SignatureEnvelope.js.map +1 -1
  75. package/dist/tempo/Transaction.d.ts +2 -0
  76. package/dist/tempo/Transaction.d.ts.map +1 -1
  77. package/dist/tempo/TransactionReceipt.d.ts +2 -0
  78. package/dist/tempo/TransactionReceipt.d.ts.map +1 -1
  79. package/dist/tempo/TransactionRequest.d.ts +4 -2
  80. package/dist/tempo/TransactionRequest.d.ts.map +1 -1
  81. package/dist/tempo/TransactionRequest.js +6 -1
  82. package/dist/tempo/TransactionRequest.js.map +1 -1
  83. package/dist/tempo/index.d.ts +3 -1
  84. package/dist/tempo/index.d.ts.map +1 -1
  85. package/dist/tempo/index.js +3 -1
  86. package/dist/tempo/index.js.map +1 -1
  87. package/dist/zod/Block.d.ts +123 -0
  88. package/dist/zod/Block.d.ts.map +1 -1
  89. package/dist/zod/Frame.d.ts +73 -0
  90. package/dist/zod/Frame.d.ts.map +1 -0
  91. package/dist/zod/Frame.js +74 -0
  92. package/dist/zod/Frame.js.map +1 -0
  93. package/dist/zod/FrameReceipt.d.ts +50 -0
  94. package/dist/zod/FrameReceipt.d.ts.map +1 -0
  95. package/dist/zod/FrameReceipt.js +37 -0
  96. package/dist/zod/FrameReceipt.js.map +1 -0
  97. package/dist/zod/FrameSignature.d.ts +63 -0
  98. package/dist/zod/FrameSignature.d.ts.map +1 -0
  99. package/dist/zod/FrameSignature.js +66 -0
  100. package/dist/zod/FrameSignature.js.map +1 -0
  101. package/dist/zod/RpcSchema.d.ts +806 -11
  102. package/dist/zod/RpcSchema.d.ts.map +1 -1
  103. package/dist/zod/Transaction.d.ts +252 -0
  104. package/dist/zod/Transaction.d.ts.map +1 -1
  105. package/dist/zod/Transaction.js +54 -0
  106. package/dist/zod/Transaction.js.map +1 -1
  107. package/dist/zod/TransactionEnvelope.d.ts +233 -4
  108. package/dist/zod/TransactionEnvelope.d.ts.map +1 -1
  109. package/dist/zod/TransactionEnvelope.js +9 -0
  110. package/dist/zod/TransactionEnvelope.js.map +1 -1
  111. package/dist/zod/TransactionReceipt.d.ts +48 -0
  112. package/dist/zod/TransactionReceipt.d.ts.map +1 -1
  113. package/dist/zod/TransactionReceipt.js +8 -3
  114. package/dist/zod/TransactionReceipt.js.map +1 -1
  115. package/dist/zod/TransactionRequest.d.ts +50 -2
  116. package/dist/zod/TransactionRequest.d.ts.map +1 -1
  117. package/dist/zod/TransactionRequest.js +10 -4
  118. package/dist/zod/TransactionRequest.js.map +1 -1
  119. package/dist/zod/TxEnvelopeEip8141.d.ts +166 -0
  120. package/dist/zod/TxEnvelopeEip8141.d.ts.map +1 -0
  121. package/dist/zod/TxEnvelopeEip8141.js +76 -0
  122. package/dist/zod/TxEnvelopeEip8141.js.map +1 -0
  123. package/dist/zod/internal/Frame.d.ts +4 -0
  124. package/dist/zod/internal/Frame.d.ts.map +1 -0
  125. package/dist/zod/internal/Frame.js +17 -0
  126. package/dist/zod/internal/Frame.js.map +1 -0
  127. package/dist/zod/internal/rpcSchemas/Eth.d.ts +842 -11
  128. package/dist/zod/internal/rpcSchemas/Eth.d.ts.map +1 -1
  129. package/dist/zod/internal/rpcSchemas/Wallet.d.ts +56 -2
  130. package/dist/zod/internal/rpcSchemas/Wallet.d.ts.map +1 -1
  131. package/dist/zod/tempo/AuthorizationTempo.d.ts +350 -10
  132. package/dist/zod/tempo/AuthorizationTempo.d.ts.map +1 -1
  133. package/dist/zod/tempo/KeyAuthorization.d.ts +242 -422
  134. package/dist/zod/tempo/KeyAuthorization.d.ts.map +1 -1
  135. package/dist/zod/tempo/KeyAuthorization.js +29 -31
  136. package/dist/zod/tempo/KeyAuthorization.js.map +1 -1
  137. package/dist/zod/tempo/MultisigSimulation.d.ts +8 -76
  138. package/dist/zod/tempo/MultisigSimulation.d.ts.map +1 -1
  139. package/dist/zod/tempo/MultisigSimulation.js +3 -37
  140. package/dist/zod/tempo/MultisigSimulation.js.map +1 -1
  141. package/dist/zod/tempo/RpcSchemaTempo.d.ts +424 -228
  142. package/dist/zod/tempo/RpcSchemaTempo.d.ts.map +1 -1
  143. package/dist/zod/tempo/SignatureEnvelope.d.ts +105 -3
  144. package/dist/zod/tempo/SignatureEnvelope.d.ts.map +1 -1
  145. package/dist/zod/tempo/SignatureEnvelope.js +21 -9
  146. package/dist/zod/tempo/SignatureEnvelope.js.map +1 -1
  147. package/dist/zod/tempo/Transaction.d.ts +783 -432
  148. package/dist/zod/tempo/Transaction.d.ts.map +1 -1
  149. package/dist/zod/tempo/TransactionRequest.d.ts +590 -473
  150. package/dist/zod/tempo/TransactionRequest.d.ts.map +1 -1
  151. package/dist/zod/tempo/TransactionRequest.js +8 -0
  152. package/dist/zod/tempo/TransactionRequest.js.map +1 -1
  153. package/dist/zod/tempo/TxEnvelopeTempo.d.ts +327 -213
  154. package/dist/zod/tempo/TxEnvelopeTempo.d.ts.map +1 -1
  155. package/dist/zod/tempo/ZoneRpcAuthentication.d.ts +105 -3
  156. package/dist/zod/tempo/ZoneRpcAuthentication.d.ts.map +1 -1
  157. package/dist/zod/z.d.ts +4 -0
  158. package/dist/zod/z.d.ts.map +1 -1
  159. package/dist/zod/z.js +4 -0
  160. package/dist/zod/z.js.map +1 -1
  161. package/package.json +41 -1
  162. package/src/core/AbiEvent.ts +11 -9
  163. package/src/core/Blobs.ts +6 -2
  164. package/src/core/Frame.ts +443 -0
  165. package/src/core/FrameReceipt.ts +117 -0
  166. package/src/core/FrameSignature.ts +593 -0
  167. package/src/core/Signature.ts +41 -11
  168. package/src/core/Siwe.ts +20 -1
  169. package/src/core/Transaction.ts +82 -5
  170. package/src/core/TransactionReceipt.ts +41 -3
  171. package/src/core/TransactionRequest.ts +71 -4
  172. package/src/core/TxEnvelope.ts +159 -90
  173. package/src/core/TxEnvelopeEip8141.ts +715 -0
  174. package/src/core/_test/AbiEvent.test.ts +45 -0
  175. package/src/core/_test/Blobs.test.ts +22 -0
  176. package/src/core/_test/Frame.test-d.ts +96 -0
  177. package/src/core/_test/Frame.test.ts +267 -0
  178. package/src/core/_test/FrameReceipt.test.ts +86 -0
  179. package/src/core/_test/FrameSignature.test-d.ts +93 -0
  180. package/src/core/_test/FrameSignature.test.ts +554 -0
  181. package/src/core/_test/Signature.test.ts +166 -0
  182. package/src/core/_test/Siwe.test.ts +100 -1
  183. package/src/core/_test/Transaction.test.ts +33 -0
  184. package/src/core/_test/TransactionEnvelope.test-d.ts +74 -0
  185. package/src/core/_test/TransactionEnvelope.test.ts +107 -0
  186. package/src/core/_test/TransactionReceipt.test.ts +59 -0
  187. package/src/core/_test/TransactionRequest.test-d.ts +50 -0
  188. package/src/core/_test/TransactionRequest.test.ts +88 -1
  189. package/src/core/_test/TxEnvelopeEip8141.test-d.ts +44 -0
  190. package/src/core/_test/TxEnvelopeEip8141.test.ts +1775 -0
  191. package/src/core/_test/curves.test.ts +6 -1
  192. package/src/core/_test/index.test.ts +4 -0
  193. package/src/core/internal/curves.ts +4 -0
  194. package/src/index.ts +77 -0
  195. package/src/tempo/AuthorizationTempo.test.ts +8 -4
  196. package/src/tempo/KeyAuthorization.test-d.ts +16 -63
  197. package/src/tempo/KeyAuthorization.test.ts +69 -11
  198. package/src/tempo/KeyAuthorization.ts +107 -63
  199. package/src/tempo/MultisigConfig.test.ts +44 -20
  200. package/src/tempo/MultisigConfig.ts +65 -23
  201. package/src/tempo/MultisigOperation.test.ts +79 -550
  202. package/src/tempo/MultisigOperation.ts +31 -146
  203. package/src/tempo/MultisigSimulation.test-d.ts +2 -2
  204. package/src/tempo/MultisigSimulation.test.ts +21 -110
  205. package/src/tempo/MultisigSimulation.ts +25 -99
  206. package/src/tempo/SignatureEnvelope.test-d.ts +29 -47
  207. package/src/tempo/SignatureEnvelope.test.ts +328 -541
  208. package/src/tempo/SignatureEnvelope.ts +196 -291
  209. package/src/tempo/Transaction.test.ts +4 -4
  210. package/src/tempo/TransactionRequest.test.ts +17 -80
  211. package/src/tempo/TransactionRequest.ts +19 -2
  212. package/src/tempo/index.ts +3 -1
  213. package/src/tempo/multisig.e2e.test.ts +321 -860
  214. package/src/version.ts +1 -1
  215. package/src/zod/Frame.ts +82 -0
  216. package/src/zod/FrameReceipt.ts +48 -0
  217. package/src/zod/FrameSignature.ts +78 -0
  218. package/src/zod/Transaction.ts +63 -0
  219. package/src/zod/TransactionEnvelope.ts +33 -0
  220. package/src/zod/TransactionReceipt.ts +14 -3
  221. package/src/zod/TransactionRequest.ts +18 -3
  222. package/src/zod/TxEnvelopeEip8141.ts +102 -0
  223. package/src/zod/_test/Frame.test-d.ts +41 -0
  224. package/src/zod/_test/Frame.test.ts +54 -0
  225. package/src/zod/_test/FrameReceipt.test.ts +75 -0
  226. package/src/zod/_test/FrameSignature.test.ts +94 -0
  227. package/src/zod/_test/TxEnvelopeEip8141.test.ts +116 -0
  228. package/src/zod/internal/Frame.ts +26 -0
  229. package/src/zod/tempo/KeyAuthorization.ts +50 -39
  230. package/src/zod/tempo/MultisigSimulation.ts +3 -48
  231. package/src/zod/tempo/SignatureEnvelope.ts +46 -35
  232. package/src/zod/tempo/TransactionRequest.ts +14 -0
  233. package/src/zod/tempo/_test/KeyAuthorization.test.ts +69 -20
  234. package/src/zod/tempo/_test/MultisigSimulation.test.ts +6 -31
  235. package/src/zod/tempo/_test/SignatureEnvelope.test.ts +118 -85
  236. package/src/zod/tempo/_test/TransactionRequest.test.ts +9 -19
  237. package/src/zod/z.ts +4 -0
@@ -1,7 +1,12 @@
1
+ import { secp256k1 } from '@noble/curves/secp256k1.js'
1
2
  import { p256 } from '@noble/curves/nist.js'
2
3
  import { expect, test } from 'vp/test'
3
- import { p256N } from '../internal/curves.js'
4
+ import { p256N, secp256k1N } from '../internal/curves.js'
4
5
 
5
6
  test('p256N matches @noble/curves', () => {
6
7
  expect(p256N).toEqual(p256.Point.CURVE().n)
7
8
  })
9
+
10
+ test('secp256k1N matches @noble/curves', () => {
11
+ expect(secp256k1N).toEqual(secp256k1.Point.Fn.ORDER)
12
+ })
@@ -41,6 +41,9 @@ test('exports', () => {
41
41
  "Errors",
42
42
  "Fee",
43
43
  "Filter",
44
+ "Frame",
45
+ "FrameReceipt",
46
+ "FrameSignature",
44
47
  "Hash",
45
48
  "HdKey",
46
49
  "Hex",
@@ -73,6 +76,7 @@ test('exports', () => {
73
76
  "TxEnvelopeEip2930",
74
77
  "TxEnvelopeEip4844",
75
78
  "TxEnvelopeEip7702",
79
+ "TxEnvelopeEip8141",
76
80
  "TxEnvelopeLegacy",
77
81
  "TypedData",
78
82
  "ValidatorData",
@@ -16,3 +16,7 @@
16
16
  */
17
17
  export const p256N =
18
18
  0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551n
19
+
20
+ /** Order of the secp256k1 curve. @internal */
21
+ export const secp256k1N =
22
+ 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141n
package/src/index.ts CHANGED
@@ -1603,6 +1603,63 @@ export * as Fee from './core/Fee.js'
1603
1603
  * @category Execution Spec
1604
1604
  */
1605
1605
  export * as Filter from './core/Filter.js'
1606
+ /**
1607
+ * Utilities for constructing, validating, and encoding [EIP-8141](https://eips.ethereum.org/EIPS/eip-8141) call frames.
1608
+ *
1609
+ * A {@link ox#Frame.Frame} describes a call with an execution mode, approval flags,
1610
+ * and separate execution and state gas limits.
1611
+ *
1612
+ * @example
1613
+ * ### Creating Frames
1614
+ *
1615
+ * Use {@link ox#Frame.(from:function)} to construct a frame with named mode and flags.
1616
+ *
1617
+ * ```ts twoslash
1618
+ * import { Frame } from 'ox'
1619
+ *
1620
+ * const frame = Frame.from({
1621
+ * flags: 'approveExecutionAndPayment',
1622
+ * gas: 50_000n,
1623
+ * mode: 'verify'
1624
+ * })
1625
+ * ```
1626
+ *
1627
+ * @category Transaction Envelopes
1628
+ */
1629
+ export * as Frame from './core/Frame.js'
1630
+
1631
+ /**
1632
+ * Utilities for converting EIP-8141 frame receipts between RPC and decoded forms.
1633
+ *
1634
+ * Frame receipts include execution gas, state gas, logs, and execution status.
1635
+ *
1636
+ * @category Execution Spec
1637
+ */
1638
+ export * as FrameReceipt from './core/FrameReceipt.js'
1639
+
1640
+ /**
1641
+ * Utilities for constructing, validating, and encoding [EIP-8141](https://eips.ethereum.org/EIPS/eip-8141) signature entries.
1642
+ *
1643
+ * Supports {@link ox#FrameSignature.Arbitrary}, {@link ox#FrameSignature.Secp256k1},
1644
+ * and {@link ox#FrameSignature.P256} entries. An empty payload selects the canonical
1645
+ * transaction signing hash.
1646
+ *
1647
+ * @example
1648
+ * ### Creating Signature Entries
1649
+ *
1650
+ * Use {@link ox#FrameSignature.(from:function)} to wrap arbitrary witness bytes.
1651
+ *
1652
+ * ```ts twoslash
1653
+ * import { FrameSignature } from 'ox'
1654
+ *
1655
+ * const entry = FrameSignature.from('0xaabb')
1656
+ * // @log: { payload: '0x', scheme: 'arbitrary', signature: '0xaabb' }
1657
+ * ```
1658
+ *
1659
+ * @category Transaction Envelopes
1660
+ */
1661
+ export * as FrameSignature from './core/FrameSignature.js'
1662
+
1606
1663
  /**
1607
1664
  * Utility functions for hashing (keccak256, sha256, etc).
1608
1665
  *
@@ -3511,6 +3568,26 @@ export * as TxEnvelopeEip4844 from './core/TxEnvelopeEip4844.js'
3511
3568
  * @category Transaction Envelopes
3512
3569
  */
3513
3570
  export * as TxEnvelopeEip7702 from './core/TxEnvelopeEip7702.js'
3571
+
3572
+ /**
3573
+ * Utilities for constructing, signing, and encoding EIP-8141 frame transactions.
3574
+ *
3575
+ * @example
3576
+ * ### Basic Usage
3577
+ *
3578
+ * ```ts twoslash
3579
+ * import { TxEnvelopeEip8141 } from 'ox'
3580
+ *
3581
+ * const envelope = TxEnvelopeEip8141.from({
3582
+ * chainId: 1,
3583
+ * frames: [{ gas: 50_000n, mode: 'sender' }],
3584
+ * sender: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8'
3585
+ * })
3586
+ * ```
3587
+ *
3588
+ * @category Transaction Envelopes
3589
+ */
3590
+ export * as TxEnvelopeEip8141 from './core/TxEnvelopeEip8141.js'
3514
3591
  /**
3515
3592
  * Utility functions for working
3516
3593
  * with **Legacy Transaction Envelopes**.
@@ -348,7 +348,8 @@ describe('fromRpc', () => {
348
348
  type: 'p256',
349
349
  },
350
350
  })
351
- if (typeof result.signature === 'string') throw new Error('unreachable')
351
+ if (typeof result.signature === 'string')
352
+ throw new Error('Expected structured primitive signature')
352
353
  expect(result.signature.type).toBe('p256')
353
354
  expect(result.signature).toHaveProperty('prehash', true)
354
355
  expect(result.signature).toHaveProperty('publicKey')
@@ -371,7 +372,8 @@ describe('fromRpc', () => {
371
372
  '0x49960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d976305000000007b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a22222c226f726967696e223a2268747470733a2f2f6578616d706c652e636f6d222c2263726f73734f726967696e223a66616c73657d',
372
373
  },
373
374
  })
374
- if (typeof result.signature === 'string') throw new Error('unreachable')
375
+ if (typeof result.signature === 'string')
376
+ throw new Error('Expected structured primitive signature')
375
377
  expect(result.signature.type).toBe('webAuthn')
376
378
  expect(result.signature).toHaveProperty('metadata')
377
379
  expect(result.signature).toHaveProperty('publicKey')
@@ -996,7 +998,8 @@ describe('toRpc', () => {
996
998
  type: 'p256',
997
999
  },
998
1000
  })
999
- if (typeof result.signature === 'string') throw new Error('unreachable')
1001
+ if (typeof result.signature === 'string')
1002
+ throw new Error('Expected structured primitive signature')
1000
1003
  expect(result.signature.type).toBe('p256')
1001
1004
  })
1002
1005
 
@@ -1022,7 +1025,8 @@ describe('toRpc', () => {
1022
1025
  type: 'webAuthn',
1023
1026
  },
1024
1027
  })
1025
- if (typeof result.signature === 'string') throw new Error('unreachable')
1028
+ if (typeof result.signature === 'string')
1029
+ throw new Error('Expected structured primitive signature')
1026
1030
  expect(result.signature.type).toBe('webAuthn')
1027
1031
  })
1028
1032
  })
@@ -1,7 +1,6 @@
1
1
  import { expectTypeOf, test } from 'vp/test'
2
2
  import * as KeyAuthorization from './KeyAuthorization.js'
3
- import * as MultisigConfig from './MultisigConfig.js'
4
- import type * as SignatureEnvelope from './SignatureEnvelope.js'
3
+ import * as SignatureEnvelope from './SignatureEnvelope.js'
5
4
 
6
5
  const authorization = {
7
6
  address: '0x1111111111111111111111111111111111111111',
@@ -20,26 +19,18 @@ const signature = {
20
19
 
21
20
  const multisig = {
22
21
  account: '0x2222222222222222222222222222222222222222',
23
- config: MultisigConfig.from({
22
+ config: {
23
+ salt: `0x${'00'.repeat(32)}`,
24
+ version: 0n,
25
+ threshold: 1,
24
26
  owners: [
25
- {
26
- owner: '0x1111111111111111111111111111111111111111',
27
- weight: 1,
28
- },
27
+ { owner: '0x1111111111111111111111111111111111111111', weight: 1 },
29
28
  ],
30
- threshold: 1,
31
- version: 1n,
32
- }),
29
+ },
33
30
  signatures: [signature],
34
31
  type: 'multisig',
35
32
  } as const satisfies SignatureEnvelope.Multisig
36
33
 
37
- const keychain = {
38
- inner: signature,
39
- type: 'keychain',
40
- userAddress: authorization.address,
41
- } as const satisfies SignatureEnvelope.Keychain
42
-
43
34
  test('accepts primitive signatures', () => {
44
35
  const signed = KeyAuthorization.from(authorization, { signature })
45
36
 
@@ -48,51 +39,13 @@ test('accepts primitive signatures', () => {
48
39
  >()
49
40
  })
50
41
 
51
- test('accepts multisig signatures', () => {
52
- const signed = KeyAuthorization.from(authorization, { signature: multisig })
53
-
54
- expectTypeOf(signed.signature).toMatchTypeOf<
55
- KeyAuthorization.Signed['signature']
56
- >()
57
-
58
- const multisigRpc = '0xf8' as const satisfies SignatureEnvelope.MultisigRpc
59
-
60
- const rpc: KeyAuthorization.Rpc = {
61
- chainId: '0x1',
62
- expiry: null,
63
- keyId: authorization.address,
64
- keyType: authorization.type,
65
- signature: multisigRpc,
66
- }
67
-
68
- expectTypeOf(rpc).toEqualTypeOf<KeyAuthorization.Rpc>()
69
- })
70
-
71
- test('rejects keychain signatures', () => {
72
- KeyAuthorization.from(authorization, {
73
- // @ts-expect-error Key authorizations do not accept keychain signatures.
74
- signature: keychain,
75
- })
76
-
77
- const keychainRpc = {
78
- signature: {
79
- r: '0x01',
80
- s: '0x02',
81
- type: 'secp256k1',
82
- yParity: '0x0',
83
- },
84
- type: 'keychain',
85
- userAddress: authorization.address,
86
- } as const satisfies SignatureEnvelope.KeychainRpc
87
-
88
- const rpc: KeyAuthorization.Rpc = {
89
- chainId: '0x1',
90
- expiry: null,
91
- keyId: authorization.address,
92
- keyType: authorization.type,
93
- // @ts-expect-error Key authorizations do not accept keychain RPC signatures.
94
- signature: keychainRpc,
95
- }
96
-
97
- expectTypeOf(rpc).toEqualTypeOf<KeyAuthorization.Rpc>()
42
+ test('accepts multisig signatures and account-bound grants', () => {
43
+ const signed = KeyAuthorization.from(
44
+ { ...authorization, account: multisig.account, type: 'multisig' },
45
+ { signature: multisig },
46
+ )
47
+ expectTypeOf(signed).toMatchTypeOf<KeyAuthorization.Signed>()
48
+ expectTypeOf(
49
+ KeyAuthorization.toRpc(signed),
50
+ ).toMatchTypeOf<KeyAuthorization.Rpc>()
98
51
  })
@@ -78,7 +78,66 @@ const signature_keychain = {
78
78
  userAddress: address,
79
79
  } as const satisfies SignatureEnvelope.Keychain
80
80
 
81
+ describe('multisig account binding', () => {
82
+ test('rejects unbound grants before signing or encoding', () => {
83
+ const authorization = { address, chainId: 1n, type: 'multisig' } as const
84
+ const signed = {
85
+ ...authorization,
86
+ signature: SignatureEnvelope.from(signature_secp256k1),
87
+ }
88
+ for (const encode of [
89
+ () => KeyAuthorization.from(authorization),
90
+ () => KeyAuthorization.toTuple(authorization),
91
+ () => KeyAuthorization.getSignPayload(authorization),
92
+ () => KeyAuthorization.serialize(authorization),
93
+ () => KeyAuthorization.toRpc(signed),
94
+ ])
95
+ expect(encode).toThrowErrorMatchingInlineSnapshot(
96
+ `[KeyAuthorization.MissingAccountError: Multisig key grants require a parent account binding.]`,
97
+ )
98
+ })
99
+
100
+ test('rejects unbound RPC and RLP grants', () => {
101
+ const signed = KeyAuthorization.from(
102
+ { account: address, address, chainId: 1n, type: 'multisig' },
103
+ { signature: signature_secp256k1 },
104
+ )
105
+ const rpc = KeyAuthorization.toRpc(signed)
106
+ for (const account of [undefined, null])
107
+ expect(() => KeyAuthorization.fromRpc({ ...rpc, account })).toThrowError(
108
+ KeyAuthorization.MissingAccountError,
109
+ )
110
+ expect(() =>
111
+ KeyAuthorization.fromTuple([['0x01', '0x03', address]]),
112
+ ).toThrowError(KeyAuthorization.MissingAccountError)
113
+ expect(KeyAuthorization.fromRpc(rpc).account).toBe(address)
114
+ expect(
115
+ KeyAuthorization.deserialize(KeyAuthorization.serialize(signed)).account,
116
+ ).toBe(address)
117
+ })
118
+ })
119
+
81
120
  describe('from', () => {
121
+ test('accepts multisig grants and delegates', () => {
122
+ const signed = KeyAuthorization.from(
123
+ {
124
+ address,
125
+ chainId: 1n,
126
+ type: 'multisig',
127
+ account: signature_multisig.account,
128
+ },
129
+ { signature: signature_multisig },
130
+ )
131
+ expect(
132
+ KeyAuthorization.deserialize(KeyAuthorization.serialize(signed)),
133
+ ).toEqual(signed)
134
+ expect(KeyAuthorization.fromRpc(KeyAuthorization.toRpc(signed))).toEqual(
135
+ signed,
136
+ )
137
+ })
138
+ })
139
+
140
+ describe('fromRpc', () => {
82
141
  test('default', () => {
83
142
  const authorization = KeyAuthorization.from({
84
143
  address,
@@ -1112,17 +1171,16 @@ describe('getSignPayload', () => {
1112
1171
  describe('deserialize', () => {
1113
1172
  test('example: matches the frozen multisig witness vector', () => {
1114
1173
  const serialized =
1115
- '0xf8f1f85382107980941eff47bc3a10a45d4b230b5d10e37751fe6aa718808080a0535353535353535353535353535353535353535353535353535353535353535380949dba7f426b711d4893c11611eacf7cc334e7146bb89a05f897949dba7f426b711d4893c11611eacf7cc334e7146bf83ba000000000000000000000000000000000000000000000000000000000000000008001d7d6947e5f4552091a69125d5dfcb7b8c2659029395bdf01f843b8412cfed9350faf80e4115e3c4c967356b80a8e6ee42e4a49ab953c8c8a3537d8d8359bf035a9bea18f32b0da7129cdce3ce701abc09ad8919b93da21a0d57e21451b' as const
1174
+ '0xf8f1f85382107980941eff47bc3a10a45d4b230b5d10e37751fe6aa718808080a053535353535353535353535353535353535353535353535353535353535353538094c4a590afa7337e5cd5eb3aa60cacf91c5400044bb89a05f89794c4a590afa7337e5cd5eb3aa60cacf91c5400044bf83ba000000000000000000000000000000000000000000000000000000000000000008001d7d6947e5f4552091a69125d5dfcb7b8c2659029395bdf01f843b8412cfed9350faf80e4115e3c4c967356b80a8e6ee42e4a49ab953c8c8a3537d8d8359bf035a9bea18f32b0da7129cdce3ce701abc09ad8919b93da21a0d57e21451b' as const
1116
1175
  const authorization = KeyAuthorization.deserialize(serialized)
1117
1176
 
1118
1177
  expect(authorization).toMatchInlineSnapshot(`
1119
1178
  {
1120
- "account": "0x9dba7f426b711d4893c11611eacf7cc334e7146b",
1179
+ "account": "0xc4a590afa7337e5cd5eb3aa60cacf91c5400044b",
1121
1180
  "address": "0x1eff47bc3a10a45d4b230b5d10e37751fe6aa718",
1122
1181
  "chainId": 4217n,
1123
- "isAdmin": false,
1124
1182
  "signature": {
1125
- "account": "0x9dba7f426b711d4893c11611eacf7cc334e7146b",
1183
+ "account": "0xc4a590afa7337e5cd5eb3aa60cacf91c5400044b",
1126
1184
  "config": {
1127
1185
  "owners": [
1128
1186
  {
@@ -2544,11 +2602,11 @@ describe('admin keys (TIP-1049)', () => {
2544
2602
  expect((authTuple as unknown as unknown[]).length).toBe(3)
2545
2603
  })
2546
2604
 
2547
- test('fromTuple: drops orphan isAdmin without account', () => {
2605
+ test('fromTuple: preserves isAdmin without account', () => {
2548
2606
  const restored = KeyAuthorization.fromTuple([
2549
2607
  ['0x01', '0x', address, '0x', [], [], '0x', '0x01'],
2550
2608
  ])
2551
- expect(restored.isAdmin).toBeUndefined()
2609
+ expect(restored.isAdmin).toBe(true)
2552
2610
  expect(restored.account).toBeUndefined()
2553
2611
  })
2554
2612
 
@@ -2556,7 +2614,7 @@ describe('admin keys (TIP-1049)', () => {
2556
2614
  const restored = KeyAuthorization.fromTuple([
2557
2615
  ['0x01', '0x', address, '0x', [], [], '0x', '0x', account],
2558
2616
  ])
2559
- expect(restored.isAdmin).toBe(false)
2617
+ expect(restored.isAdmin).toBeUndefined()
2560
2618
  expect(restored.account).toBe(account)
2561
2619
  })
2562
2620
 
@@ -2602,7 +2660,7 @@ describe('admin keys (TIP-1049)', () => {
2602
2660
  })
2603
2661
  const serialized = KeyAuthorization.serialize(authorization)
2604
2662
  const restored = KeyAuthorization.deserialize(serialized)
2605
- expect(restored.isAdmin).toBe(false)
2663
+ expect(restored.isAdmin).toBeUndefined()
2606
2664
  expect(restored.account).toBe(account)
2607
2665
  })
2608
2666
 
@@ -2625,14 +2683,14 @@ describe('admin keys (TIP-1049)', () => {
2625
2683
  expect(restored.account).toBe(account)
2626
2684
  })
2627
2685
 
2628
- test('fromRpc: drops orphan isAdmin without account', () => {
2686
+ test('fromRpc: preserves isAdmin without account', () => {
2629
2687
  const authorization = KeyAuthorization.from(
2630
2688
  { address, chainId: 1n, type: 'secp256k1' },
2631
2689
  { signature: SignatureEnvelope.from(signature_secp256k1) },
2632
2690
  )
2633
2691
  const rpc = KeyAuthorization.toRpc(authorization)
2634
2692
  const restored = KeyAuthorization.fromRpc({ ...rpc, isAdmin: true })
2635
- expect(restored.isAdmin).toBeUndefined()
2693
+ expect(restored.isAdmin).toBe(true)
2636
2694
  expect(restored.account).toBeUndefined()
2637
2695
  })
2638
2696
 
@@ -2643,7 +2701,7 @@ describe('admin keys (TIP-1049)', () => {
2643
2701
  )
2644
2702
  const rpc = KeyAuthorization.toRpc(authorization)
2645
2703
  const restored = KeyAuthorization.fromRpc({ ...rpc, account })
2646
- expect(restored.isAdmin).toBe(false)
2704
+ expect(restored.isAdmin).toBeUndefined()
2647
2705
  expect(restored.account).toBe(account)
2648
2706
  })
2649
2707