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
@@ -23,6 +23,7 @@ const KeyType = z.union([
23
23
  z.literal('secp256k1'),
24
24
  z.literal('p256'),
25
25
  z.literal('webAuthn'),
26
+ z.literal('multisig'),
26
27
  ])
27
28
 
28
29
  const SignatureRpc = z.object({
@@ -83,6 +84,7 @@ export const Rpc = z.object({
83
84
  maxFeePerBlobGas: z.optional(z_Hex.Hex),
84
85
  maxFeePerGas: z.optional(z_Hex.Hex),
85
86
  maxPriorityFeePerGas: z.optional(z_Hex.Hex),
87
+ keyAuthorizationSimulation: z.optional(z_MultisigSimulation.Rpc),
86
88
  multisigSimulation: z.optional(z_MultisigSimulation.Rpc),
87
89
  nonce: z.optional(z_Hex.Hex),
88
90
  nonceKey: z.optional(z_Hex.Hex),
@@ -136,6 +138,7 @@ export const Domain = z.object({
136
138
  maxFeePerBlobGas: z.optional(z.bigint()),
137
139
  maxFeePerGas: z.optional(z.bigint()),
138
140
  maxPriorityFeePerGas: z.optional(z.bigint()),
141
+ keyAuthorizationSimulation: z.optional(z_MultisigSimulation.Domain),
139
142
  multisigSimulation: z.optional(z_MultisigSimulation.Domain),
140
143
  nonce: z.optional(z.bigint()),
141
144
  nonceKey: z.optional(z.union([z.bigint(), z.literal('random')])),
@@ -175,6 +178,7 @@ export const DomainToRpc = z.object({
175
178
  maxFeePerBlobGas: z.optional(uintBigintNumberish()),
176
179
  maxFeePerGas: z.optional(uintBigintNumberish()),
177
180
  maxPriorityFeePerGas: z.optional(uintBigintNumberish()),
181
+ keyAuthorizationSimulation: z.optional(z_MultisigSimulation.Domain),
178
182
  multisigSimulation: z.optional(z_MultisigSimulation.Domain),
179
183
  nonce: z.optional(uintBigintNumberish()),
180
184
  nonceKey: z.optional(z.union([uintBigintNumberish(), z.literal('random')])),
@@ -250,6 +254,11 @@ function fromRpc(
250
254
  if (typeof request.keyData !== 'undefined') request_.keyData = request.keyData
251
255
  if (typeof request.keyId !== 'undefined') request_.keyId = request.keyId
252
256
  if (typeof request.keyType !== 'undefined') request_.keyType = request.keyType
257
+ if (typeof request.keyAuthorizationSimulation !== 'undefined')
258
+ request_.keyAuthorizationSimulation = z.decode(
259
+ z_MultisigSimulation.MultisigSimulation,
260
+ request.keyAuthorizationSimulation,
261
+ )
253
262
  if (typeof request.multisigSimulation !== 'undefined')
254
263
  request_.multisigSimulation = z.decode(
255
264
  z_MultisigSimulation.MultisigSimulation,
@@ -338,6 +347,11 @@ function toRpc(
338
347
  if (typeof request.keyId !== 'undefined') request_rpc.keyId = request.keyId
339
348
  if (typeof request.keyType !== 'undefined')
340
349
  request_rpc.keyType = request.keyType
350
+ if (typeof request.keyAuthorizationSimulation !== 'undefined')
351
+ request_rpc.keyAuthorizationSimulation = z.encode(
352
+ z_MultisigSimulation.MultisigSimulation,
353
+ request.keyAuthorizationSimulation,
354
+ )
341
355
  if (typeof request.multisigSimulation !== 'undefined')
342
356
  request_rpc.multisigSimulation = z.encode(
343
357
  z_MultisigSimulation.MultisigSimulation,
@@ -1,4 +1,5 @@
1
1
  import { describe, expect, test } from 'vp/test'
2
+ import * as core_SignatureEnvelope from '../../../tempo/SignatureEnvelope.js'
2
3
  import * as core_KeyAuthorization from '../../../tempo/KeyAuthorization.js'
3
4
  import * as z_KeyAuthorization from '../KeyAuthorization.js'
4
5
  import * as z from 'zod/mini'
@@ -20,6 +21,35 @@ const rpc = {
20
21
  } as const
21
22
 
22
23
  describe('KeyAuthorization', () => {
24
+ test('rejects unbound multisig grants through every schema', () => {
25
+ const domain = {
26
+ ...z.decode(z_KeyAuthorization.KeyAuthorization, rpc),
27
+ type: 'multisig',
28
+ } as const
29
+ for (const account of [undefined, null])
30
+ expect(
31
+ z.safeDecode(z_KeyAuthorization.KeyAuthorization, {
32
+ ...rpc,
33
+ keyType: 'multisig',
34
+ account,
35
+ }).success,
36
+ ).toMatchInlineSnapshot(`false`)
37
+ for (const schema of [
38
+ z_KeyAuthorization.Domain,
39
+ z_KeyAuthorization.DomainToRpc,
40
+ ]) {
41
+ expect(z.safeParse(schema, domain).success).toMatchInlineSnapshot(`false`)
42
+ expect(
43
+ z.safeParse(schema, { ...domain, account: rpc.keyId }).success,
44
+ ).toMatchInlineSnapshot(`true`)
45
+ }
46
+ for (const codec of [
47
+ z_KeyAuthorization.KeyAuthorization,
48
+ z_KeyAuthorization.KeyAuthorizationToRpc,
49
+ ])
50
+ expect(z.safeEncode(codec, domain).success).toMatchInlineSnapshot(`false`)
51
+ })
52
+
23
53
  test('decodes an RPC key authorization', () => {
24
54
  expect(z.decode(z_KeyAuthorization.KeyAuthorization, rpc)).toEqual(
25
55
  core_KeyAuthorization.fromRpc(rpc),
@@ -141,27 +171,15 @@ describe('KeyAuthorization', () => {
141
171
  ).toBe(false)
142
172
  })
143
173
 
144
- test('round-trips multisig signatures', () => {
145
- const multisigRpc =
146
- '0xf89794be95c3f554e9fc85ec51be69a3d807a0d55bcf2cf83ba000000000000000000000000000000000000000000000000000000000000000000101d7d694f39fd6e51aad88f6f4ce6ab8827279cfffb9226601f843b841fa78c5905fb0b9d6066ef531f962a62bc6ef0d5eb59ecb134056d206f75aaed7780926ff2601a935c2c79707d9e1799948c9f19dcdde1e090e903b19a07923d01c' as const
147
- const withMultisig = { ...rpc, signature: multisigRpc }
148
- const decoded = z.decode(z_KeyAuthorization.KeyAuthorization, withMultisig)
149
- expect(decoded).toEqual(core_KeyAuthorization.fromRpc(withMultisig))
150
- expect(z.encode(z_KeyAuthorization.KeyAuthorization, decoded)).toEqual(
151
- core_KeyAuthorization.toRpc(decoded),
152
- )
153
- })
154
-
155
- test('rejects keychain signatures', () => {
156
- const keychainRpc = {
157
- signature: rpc.signature,
158
- type: 'keychain',
159
- userAddress: '0x1111111111111111111111111111111111111111',
174
+ test('rejects legacy multisig signatures', () => {
175
+ const multisigRpc = {
176
+ account: '0x1111111111111111111111111111111111111111',
177
+ signatures: [rpc.signature],
160
178
  } as const
161
179
  expect(
162
180
  z.safeDecode(z_KeyAuthorization.KeyAuthorization, {
163
181
  ...rpc,
164
- signature: keychainRpc,
182
+ signature: multisigRpc,
165
183
  } as never).success,
166
184
  ).toBe(false)
167
185
 
@@ -170,11 +188,42 @@ describe('KeyAuthorization', () => {
170
188
  z.safeEncode(z_KeyAuthorization.KeyAuthorization, {
171
189
  ...authorization,
172
190
  signature: {
173
- inner: authorization.signature,
174
- type: 'keychain',
175
- userAddress: keychainRpc.userAddress,
191
+ account: multisigRpc.account,
192
+ signatures: [authorization.signature],
193
+ type: 'multisig',
176
194
  },
177
195
  } as never).success,
178
196
  ).toBe(false)
179
197
  })
198
+ test('round-trips account-bound multisig grants', () => {
199
+ const signature = core_SignatureEnvelope.from({
200
+ account: '0x2222222222222222222222222222222222222222',
201
+ config: {
202
+ threshold: 1,
203
+ owners: [
204
+ { owner: '0x1111111111111111111111111111111111111111', weight: 1 },
205
+ ],
206
+ },
207
+ signatures: [
208
+ core_SignatureEnvelope.fromRpc(
209
+ rpc.signature,
210
+ ) as core_SignatureEnvelope.Primitive,
211
+ ],
212
+ })
213
+ const signed = core_KeyAuthorization.from(
214
+ {
215
+ account: signature.account,
216
+ address: '0x3333333333333333333333333333333333333333',
217
+ chainId: 1n,
218
+ type: 'multisig',
219
+ },
220
+ { signature },
221
+ )
222
+ const encoded = z.encode(z_KeyAuthorization.KeyAuthorization, signed)
223
+ const decoded = z.decode(z_KeyAuthorization.KeyAuthorization, encoded)
224
+ expect(decoded).toEqual(
225
+ core_KeyAuthorization.fromRpc(core_KeyAuthorization.toRpc(signed)),
226
+ )
227
+ expect(decoded.account).toBe(signature.account)
228
+ })
180
229
  })
@@ -4,24 +4,11 @@ import * as z_MultisigSimulation from '../MultisigSimulation.js'
4
4
  import * as z from 'zod/mini'
5
5
 
6
6
  const rpc = {
7
- account: '0xcccccccccccccccccccccccccccccccccccccccc',
8
7
  approvals: [
9
8
  {
10
- owner: '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
11
- type: 'primitive',
12
- },
13
- {
14
- spec: {
15
- account: '0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
16
- approvals: [
17
- {
18
- owner: '0xdddddddddddddddddddddddddddddddddddddddd',
19
- },
20
- ],
21
- config:
22
- '0xf83ba022222222222222222222222222222222222222222222222222222222222222220201d7d694dddddddddddddddddddddddddddddddddddddddd01',
23
- },
24
- type: 'multisig',
9
+ keyType: 'webAuthn',
10
+ keyData: '0x0005',
11
+ owner: '0x1111111111111111111111111111111111111111',
25
12
  },
26
13
  ],
27
14
  config:
@@ -46,24 +33,12 @@ describe('MultisigSimulation', () => {
46
33
  }).success,
47
34
  ).toMatchInlineSnapshot(`false`)
48
35
  })
49
-
50
- test('error: rejects more than eight nested approvals', () => {
36
+ test('error: rejects nested approvals', () => {
51
37
  expect(
52
38
  z.safeDecode(z_MultisigSimulation.Rpc, {
53
39
  ...rpc,
54
- approvals: [
55
- {
56
- ...rpc.approvals[1],
57
- spec: {
58
- ...rpc.approvals[1].spec,
59
- approvals: Array.from(
60
- { length: 9 },
61
- () => rpc.approvals[1].spec.approvals[0],
62
- ),
63
- },
64
- },
65
- ],
66
- }).success,
40
+ approvals: [{ type: 'multisig', spec: rpc }],
41
+ } as never).success,
67
42
  ).toMatchInlineSnapshot(`false`)
68
43
  })
69
44
 
@@ -19,25 +19,37 @@ const p256 = {
19
19
  type: 'p256',
20
20
  } as const
21
21
 
22
- const multisig =
23
- '0xf897949dba7f426b711d4893c11611eacf7cc334e7146bf83ba000000000000000000000000000000000000000000000000000000000000000008001d7d6947e5f4552091a69125d5dfcb7b8c2659029395bdf01f843b841869437e01f64bebeb78a8a6b30bfd3a993819c8cad82c807515d9b9e9b36f98535dfaa5eebc597715d05f6ce4927747f14fa4cd2acc717fdcd3877146437f8f41b' as const
24
- const nestedMultisig =
25
- '0xf8f0949969e2243075b27a8eab61009c59b77ab13b83f6f83ba033333333333333333333333333333333333333333333333333333333333333338001d7d6944f9f5b162a7464bcc260ce44d7ae0d935f9c583701f89cb89a05f897944f9f5b162a7464bcc260ce44d7ae0d935f9c5837f83ba022222222222222222222222222222222222222222222222222222222222222228001d7d6946813eb9362372eef6200f3b1dbc3f819671cba6901f843b841032aa6f3ea7b0b7069720d0f3891983c493d149326c5c957d864ed7371b8475e3e95325079b24491f4b6d68920e4b3bacd7c6094df6ed88b8674864ab559c8fb1b' as const
22
+ const envelope = core_SignatureEnvelope.from({
23
+ account: '0x2222222222222222222222222222222222222222',
24
+ config: {
25
+ version: 2n,
26
+ threshold: 1,
27
+ owners: [
28
+ { owner: '0x1111111111111111111111111111111111111111', weight: 1 },
29
+ ],
30
+ },
31
+ signatures: [
32
+ core_SignatureEnvelope.fromRpc(
33
+ secp256k1,
34
+ ) as core_SignatureEnvelope.Primitive,
35
+ ],
36
+ })
37
+ const multisig = core_SignatureEnvelope.toRpc(envelope)
26
38
 
27
39
  describe('SignatureEnvelope', () => {
28
- test('behavior: decodes a secp256k1 envelope', () => {
40
+ test('decodes a secp256k1 envelope', () => {
29
41
  expect(z.decode(z_SignatureEnvelope.SignatureEnvelope, secp256k1)).toEqual(
30
42
  core_SignatureEnvelope.fromRpc(secp256k1),
31
43
  )
32
44
  })
33
45
 
34
- test('behavior: decodes a p256 envelope', () => {
46
+ test('decodes a p256 envelope', () => {
35
47
  expect(z.decode(z_SignatureEnvelope.SignatureEnvelope, p256)).toEqual(
36
48
  core_SignatureEnvelope.fromRpc(p256),
37
49
  )
38
50
  })
39
51
 
40
- test('behavior: decodes a recursive keychain envelope', () => {
52
+ test('decodes a recursive keychain envelope', () => {
41
53
  const keychain = {
42
54
  signature: secp256k1,
43
55
  type: 'keychain',
@@ -48,107 +60,128 @@ describe('SignatureEnvelope', () => {
48
60
  )
49
61
  })
50
62
 
51
- test('behavior: decodes a multisig envelope', () => {
52
- expect(z.decode(z_SignatureEnvelope.SignatureEnvelope, multisig)).toEqual(
53
- core_SignatureEnvelope.fromRpc(multisig),
63
+ test('round-trips versioned multisig RPC bytes', () => {
64
+ const decoded = z.decode(z_SignatureEnvelope.SignatureEnvelope, multisig)
65
+ expect(decoded).toEqual(envelope)
66
+ expect(z.encode(z_SignatureEnvelope.SignatureEnvelope, decoded)).toEqual(
67
+ multisig,
54
68
  )
55
69
  })
56
70
 
57
- test('behavior: decodes recursive multisig approvals', () => {
71
+ test('round-trips a multisig delegate in a keychain', () => {
72
+ const rpc = {
73
+ type: 'keychain',
74
+ version: 'v2',
75
+ userAddress: '0x3333333333333333333333333333333333333333',
76
+ signature: multisig,
77
+ } as const
58
78
  expect(
59
- z.decode(z_SignatureEnvelope.SignatureEnvelope, nestedMultisig),
60
- ).toEqual(core_SignatureEnvelope.fromRpc(nestedMultisig))
79
+ z.encode(
80
+ z_SignatureEnvelope.SignatureEnvelope,
81
+ z.decode(z_SignatureEnvelope.SignatureEnvelope, rpc),
82
+ ),
83
+ ).toEqual(rpc)
61
84
  })
62
85
 
63
- test('behavior: round-trips secp256k1 via encode', () => {
64
- const decoded = z.decode(z_SignatureEnvelope.SignatureEnvelope, secp256k1)
65
- expect(z.encode(z_SignatureEnvelope.SignatureEnvelope, decoded)).toEqual(
66
- core_SignatureEnvelope.toRpc(decoded),
67
- )
86
+ test('rejects legacy RPC shapes and malformed bytes', () => {
87
+ for (const rpc of [
88
+ { account: envelope.account, signatures: [secp256k1] },
89
+ '0xc0',
90
+ '0x',
91
+ ])
92
+ expect(
93
+ z.safeDecode(z_SignatureEnvelope.SignatureEnvelope, rpc as never)
94
+ .success,
95
+ ).toMatchInlineSnapshot('false')
68
96
  })
69
97
 
70
- test('behavior: round-trips multisig via encode', () => {
71
- const decoded = z.decode(z_SignatureEnvelope.SignatureEnvelope, multisig)
72
- expect(z.encode(z_SignatureEnvelope.SignatureEnvelope, decoded)).toEqual(
73
- multisig,
74
- )
98
+ test('rejects recursive and empty owner approvals', () => {
99
+ for (const signatures of [
100
+ [],
101
+ [envelope],
102
+ [{ type: 'keychain', userAddress: envelope.account, inner: envelope }],
103
+ ])
104
+ expect(
105
+ z.safeEncode(z_SignatureEnvelope.SignatureEnvelope, {
106
+ ...envelope,
107
+ signatures,
108
+ } as never).success,
109
+ ).toMatchInlineSnapshot('false')
75
110
  })
76
-
77
- test('error: rejects invalid recursive multisig domains before encode', () => {
78
- const decoded = core_SignatureEnvelope.fromRpc(multisig)
79
- if (decoded.type !== 'multisig') throw new Error('unreachable')
111
+ test('rejects keychain V1 multisig delegates', () => {
112
+ const rpc = {
113
+ type: 'keychain',
114
+ version: 'v1',
115
+ userAddress: envelope.account,
116
+ signature: multisig,
117
+ } as const
118
+ expect(
119
+ z.safeDecode(z_SignatureEnvelope.SignatureEnvelope, rpc).success,
120
+ ).toMatchInlineSnapshot('false')
80
121
  expect(
81
122
  z.safeEncode(z_SignatureEnvelope.SignatureEnvelope, {
82
- ...decoded,
83
- signatures: [
84
- {
85
- inner: core_SignatureEnvelope.fromRpc(secp256k1),
86
- type: 'keychain',
87
- userAddress: decoded.account,
88
- },
89
- ],
90
- } as never).success,
91
- ).toMatchInlineSnapshot(`false`)
123
+ type: 'keychain',
124
+ version: 'v1',
125
+ userAddress: envelope.account,
126
+ inner: envelope,
127
+ }).success,
128
+ ).toMatchInlineSnapshot('false')
92
129
  })
93
130
 
94
- test('error: rejects multisig approval counts outside protocol limits', () => {
95
- const decoded = core_SignatureEnvelope.fromRpc(multisig)
96
- if (decoded.type !== 'multisig') throw new Error('unreachable')
131
+ test('round-trips primitive RPC envelopes', () => {
132
+ for (const rpc of [secp256k1, p256])
133
+ expect(
134
+ z.encode(
135
+ z_SignatureEnvelope.SignatureEnvelope,
136
+ z.decode(z_SignatureEnvelope.SignatureEnvelope, rpc),
137
+ ),
138
+ ).toEqual(rpc)
139
+ })
140
+ })
141
+
142
+ describe('Keychain', () => {
143
+ test('rejects V1 wrappers with nested multisig delegates', () => {
144
+ const inner = {
145
+ inner: envelope,
146
+ type: 'keychain',
147
+ userAddress: envelope.account,
148
+ version: 'v2',
149
+ } as const
150
+ const value = {
151
+ inner,
152
+ type: 'keychain',
153
+ userAddress: envelope.account,
154
+ version: 'v1',
155
+ } as const
156
+ const rpc = {
157
+ signature: core_SignatureEnvelope.toRpc(inner),
158
+ type: 'keychain',
159
+ userAddress: envelope.account,
160
+ version: 'v1',
161
+ } as const
97
162
  expect(
98
- z.safeEncode(z_SignatureEnvelope.SignatureEnvelope, {
99
- ...decoded,
100
- signatures: [],
101
- } as never).success,
163
+ z.safeParse(z_SignatureEnvelope.Keychain, value).success,
102
164
  ).toMatchInlineSnapshot(`false`)
103
165
  expect(
104
- z.safeEncode(z_SignatureEnvelope.SignatureEnvelope, {
105
- ...decoded,
106
- signatures: Array.from({ length: 9 }, () => decoded.signatures[0]),
107
- } as never).success,
166
+ z.safeParse(z_SignatureEnvelope.KeychainRpc, rpc).success,
108
167
  ).toMatchInlineSnapshot(`false`)
109
- })
110
-
111
- test('error: rejects excess multisig nesting', () => {
112
- const nested = core_SignatureEnvelope.fromRpc(nestedMultisig)
113
- if (nested.type !== 'multisig') throw new Error('unreachable')
114
168
  expect(
115
- z.safeEncode(z_SignatureEnvelope.SignatureEnvelope, {
116
- account: '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
117
- config: {
118
- ...nested.config,
119
- owners: [{ owner: nested.account, weight: 1 }],
120
- version: 1n,
121
- },
122
- signatures: [nested],
123
- type: 'multisig',
124
- } as never).success,
169
+ z.safeEncode(z_SignatureEnvelope.SignatureEnvelope, value).success,
125
170
  ).toMatchInlineSnapshot(`false`)
126
- })
127
-
128
- test('error: rejects structured multisig RPC envelopes', () => {
129
171
  expect(
130
- z.safeDecode(z_SignatureEnvelope.SignatureEnvelope, {
131
- account: '0x9dba7f426b711d4893c11611eacf7cc334e7146b',
132
- config: {},
133
- signatures: [],
134
- } as never).success,
172
+ z.safeDecode(z_SignatureEnvelope.SignatureEnvelope, rpc).success,
135
173
  ).toMatchInlineSnapshot(`false`)
136
- })
137
-
138
- test('error: rejects tagged multisig RPC envelopes', () => {
139
174
  expect(
140
- z.safeDecode(
141
- z_SignatureEnvelope.SignatureEnvelope,
142
- `0x05${multisig.slice(2)}`,
143
- ).success,
144
- ).toMatchInlineSnapshot(`false`)
145
- })
146
-
147
- test('error: rejects an invalid envelope', () => {
175
+ z.safeEncode(z_SignatureEnvelope.SignatureEnvelope, {
176
+ ...value,
177
+ version: 'v2',
178
+ }).success,
179
+ ).toMatchInlineSnapshot(`true`)
148
180
  expect(
149
181
  z.safeDecode(z_SignatureEnvelope.SignatureEnvelope, {
150
- type: 'secp256k1',
151
- } as never).success,
152
- ).toBe(false)
182
+ ...rpc,
183
+ version: 'v2',
184
+ }).success,
185
+ ).toMatchInlineSnapshot(`true`)
153
186
  })
154
187
  })
@@ -65,27 +65,11 @@ describe('TransactionRequest', () => {
65
65
 
66
66
  test('multisig simulation round-trips', () => {
67
67
  const multisigSimulation = {
68
- account: '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
69
68
  approvals: [
70
69
  {
71
- keyType: 'secp256k1',
70
+ keyType: 'webAuthn',
71
+ keyData: '0x0005',
72
72
  owner: '0x1111111111111111111111111111111111111111',
73
- type: 'primitive',
74
- },
75
- {
76
- spec: {
77
- account: '0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
78
- approvals: [
79
- {
80
- keyData: '0x0578',
81
- keyType: 'webAuthn',
82
- owner: '0x2222222222222222222222222222222222222222',
83
- },
84
- ],
85
- config:
86
- '0xf83ba022222222222222222222222222222222222222222222222222222222222222220101d7d694222222222222222222222222222222222222222201',
87
- },
88
- type: 'multisig',
89
73
  },
90
74
  ],
91
75
  config:
@@ -94,13 +78,19 @@ describe('TransactionRequest', () => {
94
78
 
95
79
  const decoded = z.decode(z_TransactionRequest.TransactionRequest, {
96
80
  ...rpc,
81
+ keyAuthorizationSimulation: multisigSimulation,
97
82
  multisigSimulation,
98
83
  })
99
84
  expect(decoded).toEqual(
100
- core_TransactionRequest.fromRpc({ ...rpc, multisigSimulation }),
85
+ core_TransactionRequest.fromRpc({
86
+ ...rpc,
87
+ keyAuthorizationSimulation: multisigSimulation,
88
+ multisigSimulation,
89
+ }),
101
90
  )
102
91
 
103
92
  const encoded = z.encode(z_TransactionRequest.TransactionRequest, decoded)
93
+ expect(encoded.keyAuthorizationSimulation).toStrictEqual(multisigSimulation)
104
94
  expect(encoded.multisigSimulation).toStrictEqual(multisigSimulation)
105
95
  expect(encoded).toEqual(core_TransactionRequest.toRpc(decoded))
106
96
  })
package/src/zod/z.ts CHANGED
@@ -20,6 +20,9 @@ export * as Bytes from './Bytes.js'
20
20
  export * as Fee from './Fee.js'
21
21
  export * as Filter from './Filter.js'
22
22
  export * as Hash from './Hash.js'
23
+ export * as Frame from './Frame.js'
24
+ export * as FrameReceipt from './FrameReceipt.js'
25
+ export * as FrameSignature from './FrameSignature.js'
23
26
  export * as Hex from './Hex.js'
24
27
  export * as Log from './Log.js'
25
28
  export * as RpcResponse from './RpcResponse.js'
@@ -36,6 +39,7 @@ export * as TxEnvelopeEip1559 from './TxEnvelopeEip1559.js'
36
39
  export * as TxEnvelopeEip2930 from './TxEnvelopeEip2930.js'
37
40
  export * as TxEnvelopeEip4844 from './TxEnvelopeEip4844.js'
38
41
  export * as TxEnvelopeEip7702 from './TxEnvelopeEip7702.js'
42
+ export * as TxEnvelopeEip8141 from './TxEnvelopeEip8141.js'
39
43
  export * as TxEnvelopeLegacy from './TxEnvelopeLegacy.js'
40
44
  export * as Withdrawal from './Withdrawal.js'
41
45
  export * as tempo from './tempo/z.js'