ox 1.7.1 → 1.7.2

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 (121) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/core/Hash.js +1 -1
  3. package/dist/core/Hash.js.map +1 -1
  4. package/dist/tempo/KeyAuthorization.d.ts +1 -1
  5. package/dist/tempo/KeyAuthorization.d.ts.map +1 -1
  6. package/dist/tempo/MultisigConfig.d.ts +151 -83
  7. package/dist/tempo/MultisigConfig.d.ts.map +1 -1
  8. package/dist/tempo/MultisigConfig.js +164 -86
  9. package/dist/tempo/MultisigConfig.js.map +1 -1
  10. package/dist/tempo/MultisigOperation.d.ts +324 -0
  11. package/dist/tempo/MultisigOperation.d.ts.map +1 -0
  12. package/dist/tempo/MultisigOperation.js +809 -0
  13. package/dist/tempo/MultisigOperation.js.map +1 -0
  14. package/dist/tempo/MultisigWitness.d.ts +106 -0
  15. package/dist/tempo/MultisigWitness.d.ts.map +1 -0
  16. package/dist/tempo/MultisigWitness.js +118 -0
  17. package/dist/tempo/MultisigWitness.js.map +1 -0
  18. package/dist/tempo/RpcSchemaTempo.d.ts +35 -0
  19. package/dist/tempo/RpcSchemaTempo.d.ts.map +1 -1
  20. package/dist/tempo/SignatureEnvelope.d.ts +60 -80
  21. package/dist/tempo/SignatureEnvelope.d.ts.map +1 -1
  22. package/dist/tempo/SignatureEnvelope.js +87 -146
  23. package/dist/tempo/SignatureEnvelope.js.map +1 -1
  24. package/dist/tempo/TransactionRequest.d.ts +9 -17
  25. package/dist/tempo/TransactionRequest.d.ts.map +1 -1
  26. package/dist/tempo/TransactionRequest.js +7 -7
  27. package/dist/tempo/TransactionRequest.js.map +1 -1
  28. package/dist/tempo/TxEnvelopeTempo.d.ts +3 -2
  29. package/dist/tempo/TxEnvelopeTempo.d.ts.map +1 -1
  30. package/dist/tempo/TxEnvelopeTempo.js +3 -2
  31. package/dist/tempo/TxEnvelopeTempo.js.map +1 -1
  32. package/dist/tempo/index.d.ts +22 -2
  33. package/dist/tempo/index.d.ts.map +1 -1
  34. package/dist/tempo/index.js +22 -2
  35. package/dist/tempo/index.js.map +1 -1
  36. package/dist/zod/tempo/AuthorizationTempo.d.ts +110 -110
  37. package/dist/zod/tempo/AuthorizationTempo.d.ts.map +1 -1
  38. package/dist/zod/tempo/KeyAuthorization.d.ts +90 -83
  39. package/dist/zod/tempo/KeyAuthorization.d.ts.map +1 -1
  40. package/dist/zod/tempo/MultisigConfig.d.ts +31 -2
  41. package/dist/zod/tempo/MultisigConfig.d.ts.map +1 -1
  42. package/dist/zod/tempo/MultisigConfig.js +26 -3
  43. package/dist/zod/tempo/MultisigConfig.js.map +1 -1
  44. package/dist/zod/tempo/MultisigOperation.d.ts +168 -0
  45. package/dist/zod/tempo/MultisigOperation.d.ts.map +1 -0
  46. package/dist/zod/tempo/MultisigOperation.js +65 -0
  47. package/dist/zod/tempo/MultisigOperation.js.map +1 -0
  48. package/dist/zod/tempo/MultisigWitness.d.ts +152 -0
  49. package/dist/zod/tempo/MultisigWitness.d.ts.map +1 -0
  50. package/dist/zod/tempo/MultisigWitness.js +76 -0
  51. package/dist/zod/tempo/MultisigWitness.js.map +1 -0
  52. package/dist/zod/tempo/RpcSchemaTempo.d.ts +607 -102
  53. package/dist/zod/tempo/RpcSchemaTempo.d.ts.map +1 -1
  54. package/dist/zod/tempo/RpcSchemaTempo.js +38 -0
  55. package/dist/zod/tempo/RpcSchemaTempo.js.map +1 -1
  56. package/dist/zod/tempo/SignatureEnvelope.d.ts +33 -33
  57. package/dist/zod/tempo/SignatureEnvelope.d.ts.map +1 -1
  58. package/dist/zod/tempo/SignatureEnvelope.js +9 -16
  59. package/dist/zod/tempo/SignatureEnvelope.js.map +1 -1
  60. package/dist/zod/tempo/Transaction.d.ts +228 -222
  61. package/dist/zod/tempo/Transaction.d.ts.map +1 -1
  62. package/dist/zod/tempo/TransactionRequest.d.ts +379 -176
  63. package/dist/zod/tempo/TransactionRequest.d.ts.map +1 -1
  64. package/dist/zod/tempo/TransactionRequest.js +11 -22
  65. package/dist/zod/tempo/TransactionRequest.js.map +1 -1
  66. package/dist/zod/tempo/TxEnvelopeTempo.d.ts +60 -48
  67. package/dist/zod/tempo/TxEnvelopeTempo.d.ts.map +1 -1
  68. package/dist/zod/tempo/ZoneRpcAuthentication.d.ts +15 -12
  69. package/dist/zod/tempo/ZoneRpcAuthentication.d.ts.map +1 -1
  70. package/dist/zod/tempo/z.d.ts +2 -0
  71. package/dist/zod/tempo/z.d.ts.map +1 -1
  72. package/dist/zod/tempo/z.js +2 -0
  73. package/dist/zod/tempo/z.js.map +1 -1
  74. package/package.json +21 -1
  75. package/src/core/Hash.ts +1 -1
  76. package/src/core/_test/Hash.test.ts +15 -0
  77. package/src/tempo/KeyAuthorization.test-d.ts +13 -1
  78. package/src/tempo/KeyAuthorization.test.ts +65 -0
  79. package/src/tempo/KeyAuthorization.ts +1 -1
  80. package/src/tempo/MultisigConfig.test-d.ts +52 -0
  81. package/src/tempo/MultisigConfig.test.ts +288 -227
  82. package/src/tempo/MultisigConfig.ts +275 -104
  83. package/src/tempo/MultisigOperation.test-d.ts +77 -0
  84. package/src/tempo/MultisigOperation.test.ts +1883 -0
  85. package/src/tempo/MultisigOperation.ts +1254 -0
  86. package/src/tempo/MultisigWitness.test-d.ts +42 -0
  87. package/src/tempo/MultisigWitness.test.ts +288 -0
  88. package/src/tempo/MultisigWitness.ts +210 -0
  89. package/src/tempo/RpcSchemaTempo.test-d.ts +56 -0
  90. package/src/tempo/RpcSchemaTempo.ts +37 -0
  91. package/src/tempo/SignatureEnvelope.test-d.ts +63 -46
  92. package/src/tempo/SignatureEnvelope.test.ts +523 -500
  93. package/src/tempo/SignatureEnvelope.ts +172 -242
  94. package/src/tempo/TransactionRequest.test-d.ts +11 -0
  95. package/src/tempo/TransactionRequest.test.ts +285 -33
  96. package/src/tempo/TransactionRequest.ts +15 -20
  97. package/src/tempo/TxEnvelopeTempo.test-d.ts +7 -0
  98. package/src/tempo/TxEnvelopeTempo.test.ts +25 -0
  99. package/src/tempo/TxEnvelopeTempo.ts +5 -3
  100. package/src/tempo/index.ts +22 -2
  101. package/src/tempo/multisig.e2e.test.ts +113 -86
  102. package/src/version.ts +1 -1
  103. package/src/zod/tempo/MultisigConfig.ts +29 -3
  104. package/src/zod/tempo/MultisigOperation.ts +69 -0
  105. package/src/zod/tempo/MultisigWitness.ts +101 -0
  106. package/src/zod/tempo/RpcSchemaTempo.ts +43 -0
  107. package/src/zod/tempo/SignatureEnvelope.ts +20 -38
  108. package/src/zod/tempo/TransactionRequest.ts +17 -26
  109. package/src/zod/tempo/_test/KeyAuthorization.test.ts +11 -0
  110. package/src/zod/tempo/_test/MultisigConfig.test-d.ts +13 -0
  111. package/src/zod/tempo/_test/MultisigConfig.test.ts +13 -2
  112. package/src/zod/tempo/_test/MultisigOperation.test-d.ts +27 -0
  113. package/src/zod/tempo/_test/MultisigOperation.test.ts +68 -0
  114. package/src/zod/tempo/_test/MultisigWitness.test-d.ts +13 -0
  115. package/src/zod/tempo/_test/MultisigWitness.test.ts +149 -0
  116. package/src/zod/tempo/_test/RpcSchemaTempo.test-d.ts +31 -0
  117. package/src/zod/tempo/_test/RpcSchemaTempo.test.ts +41 -0
  118. package/src/zod/tempo/_test/SignatureEnvelope.test-d.ts +1 -1
  119. package/src/zod/tempo/_test/SignatureEnvelope.test.ts +25 -34
  120. package/src/zod/tempo/_test/TransactionRequest.test.ts +176 -8
  121. package/src/zod/tempo/z.ts +2 -0
@@ -86,42 +86,24 @@ export const KeychainRpc = z.object({
86
86
 
87
87
  /** RPC native multisig signature envelope schema. */
88
88
  export const MultisigRpc = z
89
- .union([
90
- z.strictObject({
91
- account: z_Address.Address,
92
- signatures: z.lazy(
93
- (): z.ZodMiniType<
94
- readonly core_SignatureEnvelope.SignatureEnvelopeRpc[],
95
- readonly core_SignatureEnvelope.SignatureEnvelopeRpc[]
96
- > =>
97
- z.readonly(
98
- z
99
- .array(Rpc)
100
- .check(
101
- z.minLength(1),
102
- z.maxLength(core_MultisigConfig.maxSignatures),
103
- ),
104
- ) as never,
105
- ),
106
- }),
107
- z.strictObject({
108
- init: z_MultisigConfig.Config,
109
- signatures: z.lazy(
110
- (): z.ZodMiniType<
111
- readonly core_SignatureEnvelope.SignatureEnvelopeRpc[],
112
- readonly core_SignatureEnvelope.SignatureEnvelopeRpc[]
113
- > =>
114
- z.readonly(
115
- z
116
- .array(Rpc)
117
- .check(
118
- z.minLength(1),
119
- z.maxLength(core_MultisigConfig.maxSignatures),
120
- ),
121
- ) as never,
122
- ),
123
- }),
124
- ])
89
+ .strictObject({
90
+ account: z_Address.Address,
91
+ config: z_MultisigConfig.Rpc,
92
+ signatures: z.lazy(
93
+ (): z.ZodMiniType<
94
+ readonly core_SignatureEnvelope.SignatureEnvelopeRpc[],
95
+ readonly core_SignatureEnvelope.SignatureEnvelopeRpc[]
96
+ > =>
97
+ z.readonly(
98
+ z
99
+ .array(Rpc)
100
+ .check(
101
+ z.minLength(1),
102
+ z.maxLength(core_MultisigConfig.maxSignatures),
103
+ ),
104
+ ) as never,
105
+ ),
106
+ })
125
107
  // Keep invalid recursive approvals inside Zod's issue path.
126
108
  .check(
127
109
  z.refine((value) => {
@@ -188,7 +170,7 @@ export const Keychain = z.object({
188
170
  export const Multisig = z
189
171
  .object({
190
172
  account: z_Address.Address,
191
- init: z.optional(z_MultisigConfig.Config),
173
+ config: z_MultisigConfig.Config,
192
174
  // `signatures` is recursive; type the getter concretely to break the cycle.
193
175
  signatures: z.lazy(
194
176
  (): z.ZodMiniType<readonly core_SignatureEnvelope.SignatureEnvelope[]> =>
@@ -273,7 +255,7 @@ function fromRpc(
273
255
  }
274
256
  }
275
257
 
276
- if ('signatures' in value && ('account' in value || 'init' in value))
258
+ if ('config' in value && 'signatures' in value)
277
259
  return core_SignatureEnvelope.fromRpc(
278
260
  value as core_SignatureEnvelope.MultisigRpc,
279
261
  )
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable jsdoc-js/require-jsdoc, jsdoc-js/require-description, jsdoc-js/require-example */
2
- import type * as core_TransactionRequest from '../../tempo/TransactionRequest.js'
3
2
  import * as core_Hex from '../../core/Hex.js'
3
+ import type * as core_TransactionRequest from '../../tempo/TransactionRequest.js'
4
4
  import * as z_AccessList from '../AccessList.js'
5
5
  import * as z_Address from '../Address.js'
6
6
  import * as z_Hex from '../Hex.js'
@@ -13,6 +13,7 @@ import {
13
13
  import * as z from 'zod/mini'
14
14
  import * as z_AuthorizationTempo from './AuthorizationTempo.js'
15
15
  import * as z_KeyAuthorization from './KeyAuthorization.js'
16
+ import * as z_MultisigWitness from './MultisigWitness.js'
16
17
  import * as z_SignatureEnvelope from './SignatureEnvelope.js'
17
18
 
18
19
  const fromRpcType = { '0x76': 'tempo' } as const
@@ -58,14 +59,6 @@ const CallToRpc = z.object({
58
59
 
59
60
  const Capabilities = z.record(z.string(), z.unknown())
60
61
 
61
- const MultisigInit = z.object({
62
- salt: z_Hex.Hex,
63
- threshold: z.number(),
64
- owners: z.readonly(
65
- z.array(z.object({ owner: z_Address.Address, weight: z.number() })),
66
- ),
67
- })
68
-
69
62
  /** RPC tempo transaction request schema. */
70
63
  export const Rpc = z.object({
71
64
  accessList: z.optional(z_AccessList.AccessList),
@@ -90,8 +83,7 @@ export const Rpc = z.object({
90
83
  maxFeePerBlobGas: z.optional(z_Hex.Hex),
91
84
  maxFeePerGas: z.optional(z_Hex.Hex),
92
85
  maxPriorityFeePerGas: z.optional(z_Hex.Hex),
93
- multisigInit: z.optional(MultisigInit),
94
- multisigSignatureCount: z.optional(z.number()),
86
+ multisigWitness: z.optional(z_MultisigWitness.Rpc),
95
87
  nonce: z.optional(z_Hex.Hex),
96
88
  nonceKey: z.optional(z_Hex.Hex),
97
89
  r: z.optional(z_Hex.Hex),
@@ -144,8 +136,7 @@ export const Domain = z.object({
144
136
  maxFeePerBlobGas: z.optional(z.bigint()),
145
137
  maxFeePerGas: z.optional(z.bigint()),
146
138
  maxPriorityFeePerGas: z.optional(z.bigint()),
147
- multisigInit: z.optional(MultisigInit),
148
- multisigSignatureCount: z.optional(z.number()),
139
+ multisigWitness: z.optional(z_MultisigWitness.Domain),
149
140
  nonce: z.optional(z.bigint()),
150
141
  nonceKey: z.optional(z.union([z.bigint(), z.literal('random')])),
151
142
  r: z.optional(z_Hex.Hex),
@@ -184,8 +175,7 @@ export const DomainToRpc = z.object({
184
175
  maxFeePerBlobGas: z.optional(uintBigintNumberish()),
185
176
  maxFeePerGas: z.optional(uintBigintNumberish()),
186
177
  maxPriorityFeePerGas: z.optional(uintBigintNumberish()),
187
- multisigInit: z.optional(MultisigInit),
188
- multisigSignatureCount: z.optional(z.number()),
178
+ multisigWitness: z.optional(z_MultisigWitness.Domain),
189
179
  nonce: z.optional(uintBigintNumberish()),
190
180
  nonceKey: z.optional(z.union([uintBigintNumberish(), z.literal('random')])),
191
181
  r: z.optional(z_Hex.Hex),
@@ -216,7 +206,7 @@ export const TransactionRequestToRpc = z.codec(Rpc, DomainToRpc, {
216
206
  function fromRpc(
217
207
  request: core_TransactionRequest.Rpc,
218
208
  ): core_TransactionRequest.TransactionRequest {
219
- const { authorizationList: _, ...rest } = request
209
+ const { authorizationList: _, multisigWitness: __, ...rest } = request
220
210
  const request_ = z.decode(
221
211
  z_TransactionRequest.TransactionRequest,
222
212
  rest as never,
@@ -260,10 +250,11 @@ function fromRpc(
260
250
  if (typeof request.keyData !== 'undefined') request_.keyData = request.keyData
261
251
  if (typeof request.keyId !== 'undefined') request_.keyId = request.keyId
262
252
  if (typeof request.keyType !== 'undefined') request_.keyType = request.keyType
263
- if (typeof request.multisigInit !== 'undefined')
264
- request_.multisigInit = request.multisigInit
265
- if (typeof request.multisigSignatureCount !== 'undefined')
266
- request_.multisigSignatureCount = request.multisigSignatureCount
253
+ if (typeof request.multisigWitness !== 'undefined')
254
+ request_.multisigWitness = z.decode(
255
+ z_MultisigWitness.MultisigWitness,
256
+ request.multisigWitness,
257
+ )
267
258
  if (typeof request.validBefore !== 'undefined')
268
259
  request_.validBefore = core_Hex.toNumber(request.validBefore)
269
260
  if (typeof request.validAfter !== 'undefined')
@@ -292,8 +283,7 @@ function toRpc(
292
283
  typeof request.keyData !== 'undefined' ||
293
284
  typeof request.keyId !== 'undefined' ||
294
285
  typeof request.keyType !== 'undefined' ||
295
- typeof request.multisigInit !== 'undefined' ||
296
- typeof request.multisigSignatureCount !== 'undefined' ||
286
+ typeof request.multisigWitness !== 'undefined' ||
297
287
  typeof request.nonceKey !== 'undefined' ||
298
288
  typeof request.validBefore !== 'undefined' ||
299
289
  typeof request.validAfter !== 'undefined' ||
@@ -348,10 +338,11 @@ function toRpc(
348
338
  if (typeof request.keyId !== 'undefined') request_rpc.keyId = request.keyId
349
339
  if (typeof request.keyType !== 'undefined')
350
340
  request_rpc.keyType = request.keyType
351
- if (typeof request.multisigInit !== 'undefined')
352
- request_rpc.multisigInit = request.multisigInit
353
- if (typeof request.multisigSignatureCount !== 'undefined')
354
- request_rpc.multisigSignatureCount = request.multisigSignatureCount
341
+ if (typeof request.multisigWitness !== 'undefined')
342
+ request_rpc.multisigWitness = z.encode(
343
+ z_MultisigWitness.MultisigWitness,
344
+ request.multisigWitness,
345
+ )
355
346
  if (typeof request.validBefore !== 'undefined')
356
347
  request_rpc.validBefore = encodeNumberish(request.validBefore)
357
348
  if (typeof request.validAfter !== 'undefined')
@@ -144,6 +144,17 @@ describe('KeyAuthorization', () => {
144
144
  test('round-trips multisig signatures', () => {
145
145
  const multisigRpc = {
146
146
  account: '0x1111111111111111111111111111111111111111',
147
+ config: {
148
+ owners: [
149
+ {
150
+ owner: '0x2222222222222222222222222222222222222222',
151
+ weight: 1,
152
+ },
153
+ ],
154
+ salt: '0x0000000000000000000000000000000000000000000000000000000000000000',
155
+ threshold: 1,
156
+ version: '0x1',
157
+ },
147
158
  signatures: [rpc.signature],
148
159
  } as const
149
160
  const withMultisig = { ...rpc, signature: multisigRpc }
@@ -0,0 +1,13 @@
1
+ import type * as core_MultisigConfig from '../../../tempo/MultisigConfig.js'
2
+ import type * as z from 'zod/mini'
3
+ import { expectTypeOf, test } from 'vp/test'
4
+ import * as z_MultisigConfig from '../MultisigConfig.js'
5
+
6
+ test('MultisigConfig decodes RPC configurations', () => {
7
+ expectTypeOf<core_MultisigConfig.Rpc>().toMatchTypeOf<
8
+ z.input<typeof z_MultisigConfig.MultisigConfig>
9
+ >()
10
+ expectTypeOf<
11
+ z.output<typeof z_MultisigConfig.MultisigConfig>
12
+ >().toMatchTypeOf<core_MultisigConfig.Config>()
13
+ })
@@ -9,20 +9,31 @@ const config = {
9
9
  weight: 1,
10
10
  },
11
11
  ],
12
+ salt: '0x0000000000000000000000000000000000000000000000000000000000000000',
12
13
  threshold: 1,
14
+ version: 0n,
13
15
  } as const
14
16
 
17
+ const rpc = { ...config, version: '0x0' } as const
18
+
15
19
  describe('Config', () => {
16
20
  test('accepts valid native multisig configurations', () => {
17
21
  expect(z.safeDecode(z_MultisigConfig.Config, config).success).toBe(true)
18
22
  })
19
23
 
24
+ test('round-trips RPC configurations', () => {
25
+ const decoded = z.decode(z_MultisigConfig.MultisigConfig, rpc)
26
+
27
+ expect(decoded).toEqual(config)
28
+ expect(z.encode(z_MultisigConfig.MultisigConfig, decoded)).toEqual(rpc)
29
+ })
30
+
20
31
  test('rejects configurations outside protocol limits', () => {
21
32
  expect(
22
33
  z.safeDecode(z_MultisigConfig.Config, {
23
34
  ...config,
24
- owners: [{ ...config.owners[0], weight: 9 }],
25
- threshold: 9,
35
+ owners: [{ ...config.owners[0], weight: 255 }],
36
+ threshold: 256,
26
37
  }).success,
27
38
  ).toMatchInlineSnapshot(`false`)
28
39
  })
@@ -0,0 +1,27 @@
1
+ import type * as core_MultisigOperation from '../../../tempo/MultisigOperation.js'
2
+ import type * as z from 'zod/mini'
3
+ import { expectTypeOf, test } from 'vp/test'
4
+ import * as z_MultisigOperation from '../MultisigOperation.js'
5
+
6
+ test('operation schemas decode RPC operations', () => {
7
+ expectTypeOf<core_MultisigOperation.TransactionRpc>().toMatchTypeOf<
8
+ z.input<typeof z_MultisigOperation.TransactionOperation>
9
+ >()
10
+ expectTypeOf<
11
+ z.output<typeof z_MultisigOperation.TransactionOperation>
12
+ >().toMatchTypeOf<core_MultisigOperation.TransactionOperation>()
13
+
14
+ expectTypeOf<core_MultisigOperation.KeyAuthorizationRpc>().toMatchTypeOf<
15
+ z.input<typeof z_MultisigOperation.KeyAuthorizationOperation>
16
+ >()
17
+ expectTypeOf<
18
+ z.output<typeof z_MultisigOperation.KeyAuthorizationOperation>
19
+ >().toMatchTypeOf<core_MultisigOperation.KeyAuthorizationOperation>()
20
+
21
+ expectTypeOf<core_MultisigOperation.Rpc>().toMatchTypeOf<
22
+ z.input<typeof z_MultisigOperation.Operation>
23
+ >()
24
+ expectTypeOf<
25
+ z.output<typeof z_MultisigOperation.Operation>
26
+ >().toMatchTypeOf<core_MultisigOperation.Operation>()
27
+ })
@@ -0,0 +1,68 @@
1
+ import { describe, expect, test } from 'vp/test'
2
+ import * as core_MultisigOperation from '../../../tempo/MultisigOperation.js'
3
+ import * as z_MultisigOperation from '../MultisigOperation.js'
4
+ import * as z from 'zod/mini'
5
+
6
+ const rpc = {
7
+ account: '0xf81b7763d3a6876195d780865bd783dbd97dd36e',
8
+ approvals: [
9
+ '0x01000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000065ecbe4d1a6330a44c8f7ef951d4bf165e6c6b721efada985fb41661bc6e7fd6c8734640c4998ff7e374b06ce1a64a2ecd82ab036384fb83d9a79b127a27d503200',
10
+ ],
11
+ config: {
12
+ owners: [
13
+ {
14
+ owner: '0x07e1ed8ea0e9601e5546b0a03aed683df3601407',
15
+ weight: 1,
16
+ },
17
+ {
18
+ owner: '0x288f0cd85005f34168f731a468aef268c2f9456f',
19
+ weight: 1,
20
+ },
21
+ ],
22
+ salt: '0x0000000000000000000000000000000000000000000000000000000000000000',
23
+ threshold: 2,
24
+ version: '0x1',
25
+ },
26
+ configVersion: '0x1',
27
+ createdAt: 1,
28
+ hash: '0xcdbc24a8fb192f799c5d166b13a99fb29cbb15e71a5e730988d6f8b3c5959d02',
29
+ init: false,
30
+ signatureCount: 1,
31
+ status: 'pending',
32
+ threshold: 2,
33
+ transaction:
34
+ '0x76e9821079808080dad99407e1ed8ea0e9601e5546b0a03aed683df360140780821234c0808080808080c0',
35
+ type: 'transaction',
36
+ updatedAt: 2,
37
+ weight: 1,
38
+ } as const
39
+
40
+ describe('TransactionOperation', () => {
41
+ test('decodes an RPC operation', () => {
42
+ expect(z.decode(z_MultisigOperation.TransactionOperation, rpc)).toEqual(
43
+ core_MultisigOperation.fromRpc(rpc),
44
+ )
45
+ })
46
+
47
+ test('round-trips via encode', () => {
48
+ const operation = z.decode(z_MultisigOperation.TransactionOperation, rpc)
49
+ expect(
50
+ z.encode(z_MultisigOperation.TransactionOperation, operation),
51
+ ).toEqual(core_MultisigOperation.toRpc(operation))
52
+ })
53
+
54
+ test('rejects internally inconsistent operations', () => {
55
+ expect(
56
+ z.safeDecode(z_MultisigOperation.TransactionOperation, {
57
+ ...rpc,
58
+ weight: 2,
59
+ }).success,
60
+ ).toBe(false)
61
+ })
62
+ })
63
+
64
+ describe('Operation', () => {
65
+ test('accepts transaction operations', () => {
66
+ expect(z.safeDecode(z_MultisigOperation.Operation, rpc).success).toBe(true)
67
+ })
68
+ })
@@ -0,0 +1,13 @@
1
+ import type * as core_MultisigWitness from '../../../tempo/MultisigWitness.js'
2
+ import type * as z from 'zod/mini'
3
+ import { expectTypeOf, test } from 'vp/test'
4
+ import * as z_MultisigWitness from '../MultisigWitness.js'
5
+
6
+ test('MultisigWitness decodes RPC witnesses', () => {
7
+ expectTypeOf<core_MultisigWitness.Rpc>().toMatchTypeOf<
8
+ z.input<typeof z_MultisigWitness.MultisigWitness>
9
+ >()
10
+ expectTypeOf<
11
+ z.output<typeof z_MultisigWitness.MultisigWitness>
12
+ >().toMatchTypeOf<core_MultisigWitness.MultisigWitness>()
13
+ })
@@ -0,0 +1,149 @@
1
+ import { describe, expect, test } from 'vp/test'
2
+ import * as z from 'zod/mini'
3
+ import * as z_MultisigWitness from '../MultisigWitness.js'
4
+
5
+ const rpc = {
6
+ account: '0xcccccccccccccccccccccccccccccccccccccccc',
7
+ approvals: [
8
+ {
9
+ owner: '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
10
+ type: 'primitive',
11
+ },
12
+ {
13
+ type: 'multisig',
14
+ witness: {
15
+ account: '0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
16
+ approvals: [
17
+ {
18
+ owner: '0xdddddddddddddddddddddddddddddddddddddddd',
19
+ },
20
+ ],
21
+ config: {
22
+ owners: [
23
+ {
24
+ owner: '0xdddddddddddddddddddddddddddddddddddddddd',
25
+ weight: 1,
26
+ },
27
+ ],
28
+ salt: '0x2222222222222222222222222222222222222222222222222222222222222222',
29
+ threshold: 1,
30
+ version: 2,
31
+ },
32
+ },
33
+ },
34
+ ],
35
+ config: {
36
+ owners: [
37
+ {
38
+ owner: '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
39
+ weight: 1,
40
+ },
41
+ {
42
+ owner: '0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
43
+ weight: 1,
44
+ },
45
+ ],
46
+ salt: '0x1111111111111111111111111111111111111111111111111111111111111111',
47
+ threshold: 2,
48
+ version: 1,
49
+ },
50
+ } as const
51
+
52
+ describe('MultisigWitness', () => {
53
+ test('behavior: converts between RPC and domain witnesses', () => {
54
+ const witness = z.decode(z_MultisigWitness.MultisigWitness, rpc)
55
+
56
+ expect(witness).toMatchInlineSnapshot(`
57
+ {
58
+ "account": "0xcccccccccccccccccccccccccccccccccccccccc",
59
+ "approvals": [
60
+ {
61
+ "owner": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
62
+ "type": "primitive",
63
+ },
64
+ {
65
+ "type": "multisig",
66
+ "witness": {
67
+ "account": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
68
+ "approvals": [
69
+ {
70
+ "owner": "0xdddddddddddddddddddddddddddddddddddddddd",
71
+ },
72
+ ],
73
+ "config": {
74
+ "owners": [
75
+ {
76
+ "owner": "0xdddddddddddddddddddddddddddddddddddddddd",
77
+ "weight": 1,
78
+ },
79
+ ],
80
+ "salt": "0x2222222222222222222222222222222222222222222222222222222222222222",
81
+ "threshold": 1,
82
+ "version": 2n,
83
+ },
84
+ },
85
+ },
86
+ ],
87
+ "config": {
88
+ "owners": [
89
+ {
90
+ "owner": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
91
+ "weight": 1,
92
+ },
93
+ {
94
+ "owner": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
95
+ "weight": 1,
96
+ },
97
+ ],
98
+ "salt": "0x1111111111111111111111111111111111111111111111111111111111111111",
99
+ "threshold": 2,
100
+ "version": 1n,
101
+ },
102
+ }
103
+ `)
104
+ expect(z.encode(z_MultisigWitness.MultisigWitness, witness)).toStrictEqual(
105
+ rpc,
106
+ )
107
+ })
108
+
109
+ test('error: rejects more than eight root approvals', () => {
110
+ expect(
111
+ z.safeDecode(z_MultisigWitness.Rpc, {
112
+ ...rpc,
113
+ approvals: Array.from({ length: 9 }, () => rpc.approvals[0]),
114
+ }).success,
115
+ ).toMatchInlineSnapshot(`false`)
116
+ })
117
+
118
+ test('error: rejects more than eight nested approvals', () => {
119
+ expect(
120
+ z.safeDecode(z_MultisigWitness.Rpc, {
121
+ ...rpc,
122
+ approvals: [
123
+ {
124
+ ...rpc.approvals[1],
125
+ witness: {
126
+ ...rpc.approvals[1].witness,
127
+ approvals: Array.from(
128
+ { length: 9 },
129
+ () => rpc.approvals[1].witness.approvals[0],
130
+ ),
131
+ },
132
+ },
133
+ ],
134
+ }).success,
135
+ ).toMatchInlineSnapshot(`false`)
136
+ })
137
+
138
+ test('error: rejects unsafe numeric configuration versions', () => {
139
+ expect(
140
+ z.safeDecode(z_MultisigWitness.Rpc, {
141
+ ...rpc,
142
+ config: {
143
+ ...rpc.config,
144
+ version: Number.MAX_SAFE_INTEGER + 1,
145
+ },
146
+ }).success,
147
+ ).toMatchInlineSnapshot(`false`)
148
+ })
149
+ })
@@ -1,3 +1,4 @@
1
+ import type * as core_MultisigOperation from '../../../tempo/MultisigOperation.js'
1
2
  import type * as z from 'zod/mini'
2
3
  import { expectTypeOf, test } from 'vp/test'
3
4
  import * as z_RpcSchemaTempo from '../RpcSchemaTempo.js'
@@ -20,3 +21,33 @@ test('Tempo namespace exposes tempo_simulateV1', () => {
20
21
  typeof z_RpcSchemaTempo.tempo_simulateV1
21
22
  >()
22
23
  })
24
+
25
+ test('multisig methods have the expected method names', () => {
26
+ expectTypeOf<
27
+ typeof z_RpcSchemaTempo.multisig_approveRawTransaction.method
28
+ >().toEqualTypeOf<'multisig_approveRawTransaction'>()
29
+ expectTypeOf<
30
+ typeof z_RpcSchemaTempo.multisig_approveRawTransactionSync.method
31
+ >().toEqualTypeOf<'multisig_approveRawTransactionSync'>()
32
+ expectTypeOf<
33
+ typeof z_RpcSchemaTempo.multisig_approveKeyAuthorization.method
34
+ >().toEqualTypeOf<'multisig_approveKeyAuthorization'>()
35
+ expectTypeOf<
36
+ typeof z_RpcSchemaTempo.multisig_getOperation.method
37
+ >().toEqualTypeOf<'multisig_getOperation'>()
38
+ })
39
+
40
+ test('multisig return schemas decode RPC operations', () => {
41
+ expectTypeOf<
42
+ z.output<typeof z_RpcSchemaTempo.multisig_approveRawTransactionSync.returns>
43
+ >().toMatchTypeOf<core_MultisigOperation.TransactionOperation>()
44
+ expectTypeOf<
45
+ z.output<typeof z_RpcSchemaTempo.multisig_getOperation.returns>
46
+ >().toMatchTypeOf<core_MultisigOperation.Operation | null>()
47
+ })
48
+
49
+ test('Multisig namespace exposes multisig methods', () => {
50
+ expectTypeOf<
51
+ typeof z_RpcSchemaTempo.Multisig.multisig_getOperation
52
+ >().toEqualTypeOf<typeof z_RpcSchemaTempo.multisig_getOperation>()
53
+ })
@@ -54,3 +54,44 @@ describe('tempo_simulateV1', () => {
54
54
  ).toBe(true)
55
55
  })
56
56
  })
57
+
58
+ describe('multisig methods', () => {
59
+ test('decodes raw transaction params', () => {
60
+ expect(
61
+ z_RpcSchema.decodeParams(
62
+ z_RpcSchemaTempo.Multisig,
63
+ 'multisig_approveRawTransactionSync',
64
+ ['0x76', 30_000],
65
+ ),
66
+ ).toEqual(['0x76', 30_000])
67
+ })
68
+
69
+ test('decodes key authorization approval params', () => {
70
+ expect(
71
+ z_RpcSchema.decodeParams(
72
+ z_RpcSchemaTempo.Multisig,
73
+ 'multisig_approveKeyAuthorization',
74
+ [{ hash: '0x01', signature: '0x02' }],
75
+ ),
76
+ ).toEqual([{ hash: '0x01', signature: '0x02' }])
77
+ })
78
+
79
+ test('accepts a missing operation result', () => {
80
+ expect(
81
+ z_RpcSchema.decodeReturns(
82
+ z_RpcSchemaTempo.Multisig,
83
+ 'multisig_getOperation',
84
+ null,
85
+ ),
86
+ ).toBeNull()
87
+ })
88
+
89
+ test('exposes method and request schemas', () => {
90
+ expect(
91
+ z.safeDecode(z_RpcSchemaTempo.multisig_getOperation.request, {
92
+ method: 'multisig_getOperation',
93
+ params: ['0x01'],
94
+ }).success,
95
+ ).toBe(true)
96
+ })
97
+ })
@@ -12,7 +12,7 @@ test('SignatureEnvelope decodes RPC into a signature envelope', () => {
12
12
  >()
13
13
  })
14
14
 
15
- test('MultisigRpc preserves the native multisig RPC union', () => {
15
+ test('MultisigRpc preserves the complete witness shape', () => {
16
16
  expectTypeOf<core_SignatureEnvelope.MultisigRpc>().toExtend<
17
17
  z.input<typeof z_SignatureEnvelope.MultisigRpc>
18
18
  >()