ox 1.7.2 → 1.7.4

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 (103) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/tempo/KeyAuthorization.d.ts +1 -1
  3. package/dist/tempo/KeyAuthorization.d.ts.map +1 -1
  4. package/dist/tempo/MultisigOperation.d.ts +42 -26
  5. package/dist/tempo/MultisigOperation.d.ts.map +1 -1
  6. package/dist/tempo/MultisigOperation.js +78 -48
  7. package/dist/tempo/MultisigOperation.js.map +1 -1
  8. package/dist/tempo/MultisigSimulation.d.ts +132 -0
  9. package/dist/tempo/MultisigSimulation.d.ts.map +1 -0
  10. package/dist/tempo/MultisigSimulation.js +140 -0
  11. package/dist/tempo/MultisigSimulation.js.map +1 -0
  12. package/dist/tempo/RpcSchemaTempo.d.ts +20 -10
  13. package/dist/tempo/RpcSchemaTempo.d.ts.map +1 -1
  14. package/dist/tempo/SignatureEnvelope.d.ts +9 -20
  15. package/dist/tempo/SignatureEnvelope.d.ts.map +1 -1
  16. package/dist/tempo/SignatureEnvelope.js +12 -18
  17. package/dist/tempo/SignatureEnvelope.js.map +1 -1
  18. package/dist/tempo/TransactionRequest.d.ts +6 -6
  19. package/dist/tempo/TransactionRequest.d.ts.map +1 -1
  20. package/dist/tempo/TransactionRequest.js +7 -7
  21. package/dist/tempo/TransactionRequest.js.map +1 -1
  22. package/dist/tempo/index.d.ts +4 -4
  23. package/dist/tempo/index.d.ts.map +1 -1
  24. package/dist/tempo/index.js +4 -4
  25. package/dist/tempo/index.js.map +1 -1
  26. package/dist/zod/tempo/AuthorizationTempo.d.ts +10 -130
  27. package/dist/zod/tempo/AuthorizationTempo.d.ts.map +1 -1
  28. package/dist/zod/tempo/KeyAuthorization.d.ts +5 -65
  29. package/dist/zod/tempo/KeyAuthorization.d.ts.map +1 -1
  30. package/dist/zod/tempo/MultisigOperation.d.ts +0 -10
  31. package/dist/zod/tempo/MultisigOperation.d.ts.map +1 -1
  32. package/dist/zod/tempo/MultisigOperation.js +0 -3
  33. package/dist/zod/tempo/MultisigOperation.js.map +1 -1
  34. package/dist/zod/tempo/{MultisigWitness.d.ts → MultisigSimulation.d.ts} +17 -49
  35. package/dist/zod/tempo/MultisigSimulation.d.ts.map +1 -0
  36. package/dist/zod/tempo/{MultisigWitness.js → MultisigSimulation.js} +26 -24
  37. package/dist/zod/tempo/MultisigSimulation.js.map +1 -0
  38. package/dist/zod/tempo/RpcSchemaTempo.d.ts +83 -204
  39. package/dist/zod/tempo/RpcSchemaTempo.d.ts.map +1 -1
  40. package/dist/zod/tempo/RpcSchemaTempo.js +19 -10
  41. package/dist/zod/tempo/RpcSchemaTempo.js.map +1 -1
  42. package/dist/zod/tempo/SignatureEnvelope.d.ts +3 -39
  43. package/dist/zod/tempo/SignatureEnvelope.d.ts.map +1 -1
  44. package/dist/zod/tempo/SignatureEnvelope.js +4 -14
  45. package/dist/zod/tempo/SignatureEnvelope.js.map +1 -1
  46. package/dist/zod/tempo/Transaction.d.ts +18 -234
  47. package/dist/zod/tempo/Transaction.d.ts.map +1 -1
  48. package/dist/zod/tempo/TransactionRequest.d.ts +36 -192
  49. package/dist/zod/tempo/TransactionRequest.d.ts.map +1 -1
  50. package/dist/zod/tempo/TransactionRequest.js +10 -10
  51. package/dist/zod/tempo/TransactionRequest.js.map +1 -1
  52. package/dist/zod/tempo/z.d.ts +1 -1
  53. package/dist/zod/tempo/z.d.ts.map +1 -1
  54. package/dist/zod/tempo/z.js +1 -1
  55. package/dist/zod/tempo/z.js.map +1 -1
  56. package/package.json +9 -9
  57. package/src/tempo/AuthorizationTempo.test.ts +4 -0
  58. package/src/tempo/KeyAuthorization.test-d.ts +1 -12
  59. package/src/tempo/KeyAuthorization.test.ts +44 -3
  60. package/src/tempo/KeyAuthorization.ts +3 -3
  61. package/src/tempo/MultisigOperation.test-d.ts +8 -6
  62. package/src/tempo/MultisigOperation.test.ts +236 -169
  63. package/src/tempo/MultisigOperation.ts +122 -83
  64. package/src/tempo/MultisigSimulation.test-d.ts +33 -0
  65. package/src/tempo/MultisigSimulation.test.ts +283 -0
  66. package/src/tempo/MultisigSimulation.ts +266 -0
  67. package/src/tempo/RpcSchemaTempo.test-d.ts +45 -10
  68. package/src/tempo/RpcSchemaTempo.ts +15 -6
  69. package/src/tempo/SignatureEnvelope.test-d.ts +3 -59
  70. package/src/tempo/SignatureEnvelope.test.ts +61 -51
  71. package/src/tempo/SignatureEnvelope.ts +27 -44
  72. package/src/tempo/Transaction.test.ts +61 -0
  73. package/src/tempo/TransactionRequest.test-d.ts +7 -7
  74. package/src/tempo/TransactionRequest.test.ts +129 -208
  75. package/src/tempo/TransactionRequest.ts +16 -12
  76. package/src/tempo/index.ts +4 -4
  77. package/src/tempo/multisig.e2e.test.ts +51 -1
  78. package/src/version.ts +1 -1
  79. package/src/zod/tempo/MultisigOperation.ts +0 -3
  80. package/src/zod/tempo/{MultisigWitness.ts → MultisigSimulation.ts} +39 -42
  81. package/src/zod/tempo/RpcSchemaTempo.ts +20 -10
  82. package/src/zod/tempo/SignatureEnvelope.ts +11 -35
  83. package/src/zod/tempo/TransactionRequest.ts +14 -14
  84. package/src/zod/tempo/_test/KeyAuthorization.test.ts +2 -15
  85. package/src/zod/tempo/_test/MultisigOperation.test.ts +0 -2
  86. package/src/zod/tempo/_test/MultisigSimulation.test-d.ts +13 -0
  87. package/src/zod/tempo/_test/MultisigSimulation.test.ts +78 -0
  88. package/src/zod/tempo/_test/RpcSchemaTempo.test-d.ts +19 -2
  89. package/src/zod/tempo/_test/RpcSchemaTempo.test.ts +46 -4
  90. package/src/zod/tempo/_test/SignatureEnvelope.test.ts +58 -112
  91. package/src/zod/tempo/_test/TransactionRequest.test.ts +19 -160
  92. package/src/zod/tempo/z.ts +1 -1
  93. package/dist/tempo/MultisigWitness.d.ts +0 -106
  94. package/dist/tempo/MultisigWitness.d.ts.map +0 -1
  95. package/dist/tempo/MultisigWitness.js +0 -118
  96. package/dist/tempo/MultisigWitness.js.map +0 -1
  97. package/dist/zod/tempo/MultisigWitness.d.ts.map +0 -1
  98. package/dist/zod/tempo/MultisigWitness.js.map +0 -1
  99. package/src/tempo/MultisigWitness.test-d.ts +0 -42
  100. package/src/tempo/MultisigWitness.test.ts +0 -288
  101. package/src/tempo/MultisigWitness.ts +0 -210
  102. package/src/zod/tempo/_test/MultisigWitness.test-d.ts +0 -13
  103. package/src/zod/tempo/_test/MultisigWitness.test.ts +0 -149
@@ -7,7 +7,7 @@ import * as Signature from '../core/Signature.js'
7
7
  import * as ox_TransactionRequest from '../core/TransactionRequest.js'
8
8
  import * as AuthorizationTempo from './AuthorizationTempo.js'
9
9
  import * as KeyAuthorization from './KeyAuthorization.js'
10
- import * as MultisigWitness from './MultisigWitness.js'
10
+ import * as MultisigSimulation from './MultisigSimulation.js'
11
11
  import * as SignatureEnvelope from './SignatureEnvelope.js'
12
12
  import * as Transaction from './Transaction.js'
13
13
  import * as TxEnvelopeTempo from './TxEnvelopeTempo.js'
@@ -44,7 +44,7 @@ export type TransactionRequest<
44
44
  keyData?: Hex.Hex | undefined
45
45
  keyId?: Address.Address | undefined
46
46
  keyType?: KeyType | undefined
47
- multisigWitness?: MultisigWitness.MultisigWitness | undefined
47
+ multisigSimulation?: MultisigSimulation.Spec | undefined
48
48
  nonceKey?: 'random' | bigintType | undefined
49
49
  signature?: SignatureEnvelope.SignatureEnvelope<numberType> | undefined
50
50
  validAfter?: numberType | undefined
@@ -59,14 +59,14 @@ export type Rpc = Omit<
59
59
  | 'feePayerSignature'
60
60
  | 'feeToken'
61
61
  | 'keyAuthorization'
62
- | 'multisigWitness'
62
+ | 'multisigSimulation'
63
63
  | 'signature'
64
64
  > & {
65
65
  authorizationList?: AuthorizationTempo.ListRpc | undefined
66
66
  feePayerSignature?: Signature.Rpc | null | undefined
67
67
  feeToken?: Hex.Hex | undefined
68
68
  keyAuthorization?: KeyAuthorization.Rpc | undefined
69
- multisigWitness?: MultisigWitness.Rpc | undefined
69
+ multisigSimulation?: MultisigSimulation.Rpc | undefined
70
70
  nonceKey?: Hex.Hex | undefined
71
71
  signature?: SignatureEnvelope.SignatureEnvelopeRpc | undefined
72
72
  }
@@ -94,7 +94,7 @@ export type Rpc = Omit<
94
94
  * @returns A transaction request.
95
95
  */
96
96
  export function fromRpc(request: Rpc): TransactionRequest {
97
- const { authorizationList: _, multisigWitness: __, ...rest } = request
97
+ const { authorizationList: _, multisigSimulation: __, ...rest } = request
98
98
  const request_ = ox_TransactionRequest.fromRpc(
99
99
  rest as any,
100
100
  ) as TransactionRequest
@@ -129,8 +129,10 @@ export function fromRpc(request: Rpc): TransactionRequest {
129
129
  request_.keyAuthorization = KeyAuthorization.fromRpc(
130
130
  request.keyAuthorization,
131
131
  )
132
- if (request.multisigWitness)
133
- request_.multisigWitness = MultisigWitness.fromRpc(request.multisigWitness)
132
+ if (request.multisigSimulation)
133
+ request_.multisigSimulation = MultisigSimulation.fromRpc(
134
+ request.multisigSimulation,
135
+ )
134
136
  if (typeof request.validBefore !== 'undefined')
135
137
  request_.validBefore = Hex.toNumber(request.validBefore as Hex.Hex)
136
138
  if (typeof request.validAfter !== 'undefined')
@@ -146,7 +148,7 @@ export declare namespace fromRpc {
146
148
  | AuthorizationTempo.fromRpcList.ErrorType
147
149
  | Hex.toNumber.ErrorType
148
150
  | Hex.toBigInt.ErrorType
149
- | MultisigWitness.fromRpc.ErrorType
151
+ | MultisigSimulation.fromRpc.ErrorType
150
152
  | Errors.GlobalErrorType
151
153
  }
152
154
 
@@ -220,7 +222,7 @@ export function toRpc(request: toRpc.Input): Rpc {
220
222
  typeof request.keyData !== 'undefined' ||
221
223
  typeof request.keyId !== 'undefined' ||
222
224
  typeof request.keyType !== 'undefined' ||
223
- typeof request.multisigWitness !== 'undefined' ||
225
+ typeof request.multisigSimulation !== 'undefined' ||
224
226
  typeof request.nonceKey !== 'undefined' ||
225
227
  typeof request.validBefore !== 'undefined' ||
226
228
  typeof request.validAfter !== 'undefined' ||
@@ -270,8 +272,10 @@ export function toRpc(request: toRpc.Input): Rpc {
270
272
  if (typeof request.keyId !== 'undefined') request_rpc.keyId = request.keyId
271
273
  if (typeof request.keyType !== 'undefined')
272
274
  request_rpc.keyType = request.keyType
273
- if (typeof request.multisigWitness !== 'undefined')
274
- request_rpc.multisigWitness = MultisigWitness.toRpc(request.multisigWitness)
275
+ if (typeof request.multisigSimulation !== 'undefined')
276
+ request_rpc.multisigSimulation = MultisigSimulation.toRpc(
277
+ request.multisigSimulation,
278
+ )
275
279
  if (typeof request.validBefore !== 'undefined')
276
280
  request_rpc.validBefore = Quantity.fromNumberish(request.validBefore)
277
281
  if (typeof request.validAfter !== 'undefined')
@@ -306,7 +310,7 @@ export declare namespace toRpc {
306
310
  export type ErrorType =
307
311
  | AuthorizationTempo.toRpcList.ErrorType
308
312
  | Hex.fromNumber.ErrorType
309
- | MultisigWitness.toRpc.ErrorType
313
+ | MultisigSimulation.toRpc.ErrorType
310
314
  | Errors.GlobalErrorType
311
315
  }
312
316
 
@@ -183,14 +183,14 @@ export * as MultisigConfig from './MultisigConfig.js'
183
183
  */
184
184
  export * as MultisigOperation from './MultisigOperation.js'
185
185
  /**
186
- * Native multisig RPC simulation witness utilities.
186
+ * Native multisig RPC simulation utilities.
187
187
  *
188
- * Converts complete root and nested owner witnesses between their domain and
189
- * Tempo JSON-RPC representations.
188
+ * Converts complete root and nested owner specs between their domain and Tempo
189
+ * JSON-RPC representations.
190
190
  *
191
191
  * @category Reference
192
192
  */
193
- export * as MultisigWitness from './MultisigWitness.js'
193
+ export * as MultisigSimulation from './MultisigSimulation.js'
194
194
  /**
195
195
  * Utilities for constructing period durations (in seconds) for recurring spending limits.
196
196
  *
@@ -2,7 +2,12 @@ import { AbiFunction, Address, Hex, Secp256k1, Value } from 'ox'
2
2
  import { getTransactionCount } from 'viem/actions'
3
3
  import { describe, expect, test } from 'vp/test'
4
4
  import { chain, client, fundAddress } from '../../test/tempo/config.js'
5
- import { KeyAuthorization, MultisigConfig, SignatureEnvelope } from './index.js'
5
+ import {
6
+ KeyAuthorization,
7
+ MultisigConfig,
8
+ SignatureEnvelope,
9
+ TransactionRequest,
10
+ } from './index.js'
6
11
  import * as Transaction from './Transaction.js'
7
12
  import * as TransactionReceipt from './TransactionReceipt.js'
8
13
  import * as TxEnvelopeTempo from './TxEnvelopeTempo.js'
@@ -135,6 +140,51 @@ describe('behavior: multisig (TIP-1061)', () => {
135
140
  })
136
141
  }
137
142
 
143
+ test('behavior: fills a multisig simulation', async () => {
144
+ const { account, initialConfig, ownerKeys } = setup({
145
+ count: 2,
146
+ threshold: 2,
147
+ })
148
+ await fundAddress(client, { address: account })
149
+
150
+ const request = TransactionRequest.toRpc({
151
+ calls: [{ to: '0x0000000000000000000000000000000000000000' }],
152
+ from: account,
153
+ multisigSimulation: {
154
+ account,
155
+ approvals: ownerKeys.map((owner) => ({
156
+ keyType: 'secp256k1',
157
+ owner: owner.address,
158
+ type: 'primitive',
159
+ })),
160
+ config: initialConfig,
161
+ },
162
+ })
163
+ expect(request.multisigSimulation?.config).toBeTypeOf('string')
164
+
165
+ const response = await client.request({
166
+ method: 'eth_fillTransaction',
167
+ params: [request as never],
168
+ })
169
+ const transaction = TransactionRequest.fromRpc(
170
+ response.tx as TransactionRequest.Rpc,
171
+ )
172
+
173
+ expect(Hex.validate(response.raw)).toBe(true)
174
+ expect(transaction.calls).toHaveLength(1)
175
+ expect(transaction.calls?.[0]?.to).toBe(
176
+ '0x0000000000000000000000000000000000000000',
177
+ )
178
+ expect(transaction.chainId).toBe(chainId)
179
+ expect(transaction.feeToken).toBeNull()
180
+ expect(transaction.gas).toBeGreaterThan(0n)
181
+ expect(transaction.maxFeePerGas).toBeTypeOf('bigint')
182
+ expect(transaction.maxPriorityFeePerGas).toBeTypeOf('bigint')
183
+ expect(transaction.nonce ?? 0n).toBe(0n)
184
+ expect(transaction.nonceKey ?? 0n).toBe(0n)
185
+ expect(transaction.type).toBe('tempo')
186
+ })
187
+
138
188
  test('examples: bootstrap, initialized, and configuration rotation', async () => {
139
189
  const { account, initialConfig, ownerKeys } = setup({
140
190
  count: 3,
package/src/version.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  /** @internal */
2
- export const version = '1.7.2'
2
+ export const version = '1.7.4'
@@ -3,7 +3,6 @@ import * as core_MultisigOperation from '../../tempo/MultisigOperation.js'
3
3
  import * as z_Address from '../Address.js'
4
4
  import * as z_Hash from '../Hash.js'
5
5
  import * as z_Hex from '../Hex.js'
6
- import * as z_Uint from '../Uint.js'
7
6
  import * as z from 'zod/mini'
8
7
  import * as z_MultisigConfig from './MultisigConfig.js'
9
8
 
@@ -12,10 +11,8 @@ function baseFields() {
12
11
  account: z_Address.Address,
13
12
  approvals: z.readonly(z.array(z_Hex.Hex)),
14
13
  config: z_MultisigConfig.MultisigConfig,
15
- configVersion: z_Uint.Uint64,
16
14
  createdAt: z.number(),
17
15
  hash: z_Hash.Hash,
18
- init: z.boolean(),
19
16
  signatureCount: z.number(),
20
17
  threshold: z.number(),
21
18
  updatedAt: z.number(),
@@ -1,26 +1,12 @@
1
1
  /* eslint-disable jsdoc-js/require-jsdoc, jsdoc-js/require-description, jsdoc-js/require-example */
2
2
  import * as core_MultisigConfig from '../../tempo/MultisigConfig.js'
3
- import * as core_MultisigWitness from '../../tempo/MultisigWitness.js'
3
+ import * as core_MultisigSimulation from '../../tempo/MultisigSimulation.js'
4
4
  import * as z_Address from '../Address.js'
5
5
  import * as z_Hex from '../Hex.js'
6
6
  import * as z from 'zod/mini'
7
7
  import * as z_MultisigConfig from './MultisigConfig.js'
8
8
  import * as z_SignatureEnvelope from './SignatureEnvelope.js'
9
9
 
10
- const ConfigRpc = z
11
- .object({
12
- owners: z.readonly(z.array(z_MultisigConfig.Owner)),
13
- salt: z_Hex.Hex,
14
- threshold: z.number(),
15
- version: z.number(),
16
- })
17
- .check(
18
- z.refine(
19
- (value) => core_MultisigConfig.validate(value),
20
- 'expected valid native multisig configuration',
21
- ),
22
- )
23
-
24
10
  const NestedPrimitiveApproval = z.object({
25
11
  keyData: z.optional(z_Hex.Hex),
26
12
  keyType: z.optional(z_SignatureEnvelope.Type),
@@ -34,7 +20,7 @@ const PrimitiveApproval = z.object({
34
20
  type: z.literal('primitive'),
35
21
  })
36
22
 
37
- const NestedWitness = z.object({
23
+ const NestedSpec = z.object({
38
24
  account: z_Address.Address,
39
25
  approvals: z.readonly(
40
26
  z
@@ -44,17 +30,17 @@ const NestedWitness = z.object({
44
30
  config: z_MultisigConfig.Config,
45
31
  })
46
32
 
47
- const NestedWitnessRpc = z.object({
33
+ const NestedSpecRpc = z.object({
48
34
  account: z_Address.Address,
49
35
  approvals: z.readonly(
50
36
  z
51
37
  .array(NestedPrimitiveApproval)
52
38
  .check(z.maxLength(core_MultisigConfig.maxSignatures)),
53
39
  ),
54
- config: ConfigRpc,
40
+ config: z_Hex.Hex,
55
41
  })
56
42
 
57
- /** Native multisig simulation witness schema. */
43
+ /** Native multisig simulation spec schema. */
58
44
  export const Domain = z.object({
59
45
  account: z_Address.Address,
60
46
  approvals: z.readonly(
@@ -63,8 +49,8 @@ export const Domain = z.object({
63
49
  z.union([
64
50
  PrimitiveApproval,
65
51
  z.object({
52
+ spec: NestedSpec,
66
53
  type: z.literal('multisig'),
67
- witness: NestedWitness,
68
54
  }),
69
55
  ]),
70
56
  )
@@ -73,29 +59,40 @@ export const Domain = z.object({
73
59
  config: z_MultisigConfig.Config,
74
60
  })
75
61
 
76
- const Rpc_ = z.object({
77
- account: z_Address.Address,
78
- approvals: z.readonly(
79
- z
80
- .array(
81
- z.union([
82
- PrimitiveApproval,
83
- z.object({
84
- type: z.literal('multisig'),
85
- witness: NestedWitnessRpc,
86
- }),
87
- ]),
88
- )
89
- .check(z.maxLength(core_MultisigConfig.maxSignatures)),
90
- ),
91
- config: ConfigRpc,
92
- })
62
+ const Rpc_ = z
63
+ .object({
64
+ account: z_Address.Address,
65
+ approvals: z.readonly(
66
+ z
67
+ .array(
68
+ z.union([
69
+ PrimitiveApproval,
70
+ z.object({
71
+ spec: NestedSpecRpc,
72
+ type: z.literal('multisig'),
73
+ }),
74
+ ]),
75
+ )
76
+ .check(z.maxLength(core_MultisigConfig.maxSignatures)),
77
+ ),
78
+ config: z_Hex.Hex,
79
+ })
80
+ .check(
81
+ z.refine((value) => {
82
+ try {
83
+ core_MultisigSimulation.fromRpc(value)
84
+ return true
85
+ } catch {
86
+ return false
87
+ }
88
+ }, 'expected valid native multisig simulation spec'),
89
+ )
93
90
 
94
- /** Codec decoding an RPC multisig witness into its domain representation. */
95
- export const MultisigWitness = z.codec(Rpc_, Domain, {
96
- decode: (value) => core_MultisigWitness.fromRpc(value),
97
- encode: (value) => core_MultisigWitness.toRpc(value),
91
+ /** Codec decoding an RPC multisig simulation spec into its domain representation. */
92
+ export const MultisigSimulation = z.codec(Rpc_, Domain, {
93
+ decode: (value) => core_MultisigSimulation.fromRpc(value),
94
+ encode: (value) => core_MultisigSimulation.toRpc(value),
98
95
  })
99
96
 
100
- /** RPC native multisig simulation witness schema. */
97
+ /** RPC native multisig simulation spec schema. */
101
98
  export const Rpc = Rpc_
@@ -1,4 +1,5 @@
1
1
  /* eslint-disable jsdoc-js/require-jsdoc, jsdoc-js/require-description, jsdoc-js/require-example */
2
+ import * as z_Address from '../Address.js'
2
3
  import * as z_Block from '../Block.js'
3
4
  import * as z_BlockOverrides from '../BlockOverrides.js'
4
5
  import * as z_Hex from '../Hex.js'
@@ -7,6 +8,7 @@ import * as z_StateOverrides from '../StateOverrides.js'
7
8
  import { from } from '../internal/rpcSchemas/from.js'
8
9
  import * as z from 'zod/mini'
9
10
  import * as z_KeyAuthorization from './KeyAuthorization.js'
11
+ import * as z_MultisigConfig from './MultisigConfig.js'
10
12
  import * as z_MultisigOperation from './MultisigOperation.js'
11
13
  import * as z_TransactionRequest from './TransactionRequest.js'
12
14
 
@@ -88,6 +90,18 @@ export const tempo_simulateV1 = from({
88
90
  /** JSON-RPC method schemas for the `tempo_` namespace. */
89
91
  export const Tempo = { tempo_simulateV1 }
90
92
 
93
+ /** Schema for the `multisig_approveKeyAuthorization` JSON-RPC method. */
94
+ export const multisig_approveKeyAuthorization = from({
95
+ method: 'multisig_approveKeyAuthorization',
96
+ params: z.tuple([
97
+ z.union([
98
+ z.object({ keyAuthorization: z_KeyAuthorization.Rpc }),
99
+ z.object({ hash: z_Hex.Hex, signature: z_Hex.Hex }),
100
+ ]),
101
+ ]),
102
+ returns: z_MultisigOperation.KeyAuthorizationOperation,
103
+ })
104
+
91
105
  /** Schema for the `multisig_approveRawTransaction` JSON-RPC method. */
92
106
  export const multisig_approveRawTransaction = from({
93
107
  method: 'multisig_approveRawTransaction',
@@ -102,16 +116,11 @@ export const multisig_approveRawTransactionSync = from({
102
116
  returns: z_MultisigOperation.TransactionOperation,
103
117
  })
104
118
 
105
- /** Schema for the `multisig_approveKeyAuthorization` JSON-RPC method. */
106
- export const multisig_approveKeyAuthorization = from({
107
- method: 'multisig_approveKeyAuthorization',
108
- params: z.tuple([
109
- z.union([
110
- z.object({ keyAuthorization: z_KeyAuthorization.Rpc }),
111
- z.object({ hash: z_Hex.Hex, signature: z_Hex.Hex }),
112
- ]),
113
- ]),
114
- returns: z_MultisigOperation.KeyAuthorizationOperation,
119
+ /** Schema for the `multisig_getConfig` JSON-RPC method. */
120
+ export const multisig_getConfig = from({
121
+ method: 'multisig_getConfig',
122
+ params: z.tuple([z.object({ address: z_Address.Address })]),
123
+ returns: z.nullable(z_MultisigConfig.Rpc),
115
124
  })
116
125
 
117
126
  /** Schema for the `multisig_getOperation` JSON-RPC method. */
@@ -126,5 +135,6 @@ export const Multisig = {
126
135
  multisig_approveKeyAuthorization,
127
136
  multisig_approveRawTransaction,
128
137
  multisig_approveRawTransactionSync,
138
+ multisig_getConfig,
129
139
  multisig_getOperation,
130
140
  }
@@ -85,36 +85,15 @@ export const KeychainRpc = z.object({
85
85
  })
86
86
 
87
87
  /** RPC native multisig signature envelope schema. */
88
- export const MultisigRpc = z
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
- })
107
- // Keep invalid recursive approvals inside Zod's issue path.
108
- .check(
109
- z.refine((value) => {
110
- try {
111
- core_SignatureEnvelope.fromRpc(value)
112
- return true
113
- } catch {
114
- return false
115
- }
116
- }, 'expected valid native multisig signature'),
117
- )
88
+ export const MultisigRpc = z_Hex.Hex.check(
89
+ z.refine((value) => {
90
+ try {
91
+ return core_SignatureEnvelope.fromRpc(value).type === 'multisig'
92
+ } catch {
93
+ return false
94
+ }
95
+ }, 'expected valid native multisig signature'),
96
+ )
118
97
 
119
98
  /** RPC signature envelope schema. */
120
99
  export const Rpc = z.union([
@@ -209,6 +188,8 @@ export const Serialized = z_Hex.Hex
209
188
  function fromRpc(
210
189
  value: core_SignatureEnvelope.SignatureEnvelopeRpc,
211
190
  ): core_SignatureEnvelope.SignatureEnvelope {
191
+ if (typeof value === 'string') return core_SignatureEnvelope.fromRpc(value)
192
+
212
193
  if (value.type === 'secp256k1') {
213
194
  const secp256k1 = value as core_SignatureEnvelope.Secp256k1Rpc
214
195
  return {
@@ -255,11 +236,6 @@ function fromRpc(
255
236
  }
256
237
  }
257
238
 
258
- if ('config' in value && 'signatures' in value)
259
- return core_SignatureEnvelope.fromRpc(
260
- value as core_SignatureEnvelope.MultisigRpc,
261
- )
262
-
263
239
  const keychain = value as core_SignatureEnvelope.KeychainRpc
264
240
  return {
265
241
  inner: fromRpc(keychain.signature),
@@ -13,7 +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
+ import * as z_MultisigSimulation from './MultisigSimulation.js'
17
17
  import * as z_SignatureEnvelope from './SignatureEnvelope.js'
18
18
 
19
19
  const fromRpcType = { '0x76': 'tempo' } as const
@@ -83,7 +83,7 @@ export const Rpc = z.object({
83
83
  maxFeePerBlobGas: z.optional(z_Hex.Hex),
84
84
  maxFeePerGas: z.optional(z_Hex.Hex),
85
85
  maxPriorityFeePerGas: z.optional(z_Hex.Hex),
86
- multisigWitness: z.optional(z_MultisigWitness.Rpc),
86
+ multisigSimulation: z.optional(z_MultisigSimulation.Rpc),
87
87
  nonce: z.optional(z_Hex.Hex),
88
88
  nonceKey: z.optional(z_Hex.Hex),
89
89
  r: z.optional(z_Hex.Hex),
@@ -136,7 +136,7 @@ export const Domain = z.object({
136
136
  maxFeePerBlobGas: z.optional(z.bigint()),
137
137
  maxFeePerGas: z.optional(z.bigint()),
138
138
  maxPriorityFeePerGas: z.optional(z.bigint()),
139
- multisigWitness: z.optional(z_MultisigWitness.Domain),
139
+ multisigSimulation: z.optional(z_MultisigSimulation.Domain),
140
140
  nonce: z.optional(z.bigint()),
141
141
  nonceKey: z.optional(z.union([z.bigint(), z.literal('random')])),
142
142
  r: z.optional(z_Hex.Hex),
@@ -175,7 +175,7 @@ export const DomainToRpc = z.object({
175
175
  maxFeePerBlobGas: z.optional(uintBigintNumberish()),
176
176
  maxFeePerGas: z.optional(uintBigintNumberish()),
177
177
  maxPriorityFeePerGas: z.optional(uintBigintNumberish()),
178
- multisigWitness: z.optional(z_MultisigWitness.Domain),
178
+ multisigSimulation: z.optional(z_MultisigSimulation.Domain),
179
179
  nonce: z.optional(uintBigintNumberish()),
180
180
  nonceKey: z.optional(z.union([uintBigintNumberish(), z.literal('random')])),
181
181
  r: z.optional(z_Hex.Hex),
@@ -206,7 +206,7 @@ export const TransactionRequestToRpc = z.codec(Rpc, DomainToRpc, {
206
206
  function fromRpc(
207
207
  request: core_TransactionRequest.Rpc,
208
208
  ): core_TransactionRequest.TransactionRequest {
209
- const { authorizationList: _, multisigWitness: __, ...rest } = request
209
+ const { authorizationList: _, multisigSimulation: __, ...rest } = request
210
210
  const request_ = z.decode(
211
211
  z_TransactionRequest.TransactionRequest,
212
212
  rest as never,
@@ -250,10 +250,10 @@ function fromRpc(
250
250
  if (typeof request.keyData !== 'undefined') request_.keyData = request.keyData
251
251
  if (typeof request.keyId !== 'undefined') request_.keyId = request.keyId
252
252
  if (typeof request.keyType !== 'undefined') request_.keyType = request.keyType
253
- if (typeof request.multisigWitness !== 'undefined')
254
- request_.multisigWitness = z.decode(
255
- z_MultisigWitness.MultisigWitness,
256
- request.multisigWitness,
253
+ if (typeof request.multisigSimulation !== 'undefined')
254
+ request_.multisigSimulation = z.decode(
255
+ z_MultisigSimulation.MultisigSimulation,
256
+ request.multisigSimulation,
257
257
  )
258
258
  if (typeof request.validBefore !== 'undefined')
259
259
  request_.validBefore = core_Hex.toNumber(request.validBefore)
@@ -283,7 +283,7 @@ function toRpc(
283
283
  typeof request.keyData !== 'undefined' ||
284
284
  typeof request.keyId !== 'undefined' ||
285
285
  typeof request.keyType !== 'undefined' ||
286
- typeof request.multisigWitness !== 'undefined' ||
286
+ typeof request.multisigSimulation !== 'undefined' ||
287
287
  typeof request.nonceKey !== 'undefined' ||
288
288
  typeof request.validBefore !== 'undefined' ||
289
289
  typeof request.validAfter !== 'undefined' ||
@@ -338,10 +338,10 @@ function toRpc(
338
338
  if (typeof request.keyId !== 'undefined') request_rpc.keyId = request.keyId
339
339
  if (typeof request.keyType !== 'undefined')
340
340
  request_rpc.keyType = request.keyType
341
- if (typeof request.multisigWitness !== 'undefined')
342
- request_rpc.multisigWitness = z.encode(
343
- z_MultisigWitness.MultisigWitness,
344
- request.multisigWitness,
341
+ if (typeof request.multisigSimulation !== 'undefined')
342
+ request_rpc.multisigSimulation = z.encode(
343
+ z_MultisigSimulation.MultisigSimulation,
344
+ request.multisigSimulation,
345
345
  )
346
346
  if (typeof request.validBefore !== 'undefined')
347
347
  request_rpc.validBefore = encodeNumberish(request.validBefore)
@@ -142,21 +142,8 @@ describe('KeyAuthorization', () => {
142
142
  })
143
143
 
144
144
  test('round-trips multisig signatures', () => {
145
- const multisigRpc = {
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
- },
158
- signatures: [rpc.signature],
159
- } as const
145
+ const multisigRpc =
146
+ '0xf89794be95c3f554e9fc85ec51be69a3d807a0d55bcf2cf83ba000000000000000000000000000000000000000000000000000000000000000000101d7d694f39fd6e51aad88f6f4ce6ab8827279cfffb9226601f843b841fa78c5905fb0b9d6066ef531f962a62bc6ef0d5eb59ecb134056d206f75aaed7780926ff2601a935c2c79707d9e1799948c9f19dcdde1e090e903b19a07923d01c' as const
160
147
  const withMultisig = { ...rpc, signature: multisigRpc }
161
148
  const decoded = z.decode(z_KeyAuthorization.KeyAuthorization, withMultisig)
162
149
  expect(decoded).toEqual(core_KeyAuthorization.fromRpc(withMultisig))
@@ -23,10 +23,8 @@ const rpc = {
23
23
  threshold: 2,
24
24
  version: '0x1',
25
25
  },
26
- configVersion: '0x1',
27
26
  createdAt: 1,
28
27
  hash: '0xcdbc24a8fb192f799c5d166b13a99fb29cbb15e71a5e730988d6f8b3c5959d02',
29
- init: false,
30
28
  signatureCount: 1,
31
29
  status: 'pending',
32
30
  threshold: 2,
@@ -0,0 +1,13 @@
1
+ import type * as core_MultisigSimulation from '../../../tempo/MultisigSimulation.js'
2
+ import type * as z from 'zod/mini'
3
+ import { expectTypeOf, test } from 'vp/test'
4
+ import * as z_MultisigSimulation from '../MultisigSimulation.js'
5
+
6
+ test('MultisigSimulation decodes RPC specs', () => {
7
+ expectTypeOf<core_MultisigSimulation.Rpc>().toMatchTypeOf<
8
+ z.input<typeof z_MultisigSimulation.MultisigSimulation>
9
+ >()
10
+ expectTypeOf<
11
+ z.output<typeof z_MultisigSimulation.MultisigSimulation>
12
+ >().toMatchTypeOf<core_MultisigSimulation.Spec>()
13
+ })
@@ -0,0 +1,78 @@
1
+ import { describe, expect, test } from 'vp/test'
2
+ import * as core_MultisigSimulation from '../../../tempo/MultisigSimulation.js'
3
+ import * as z_MultisigSimulation from '../MultisigSimulation.js'
4
+ import * as z from 'zod/mini'
5
+
6
+ const rpc = {
7
+ account: '0xcccccccccccccccccccccccccccccccccccccccc',
8
+ approvals: [
9
+ {
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',
25
+ },
26
+ ],
27
+ config:
28
+ '0xf852a011111111111111111111111111111111111111111111111111111111111111110102eed694aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa01d694bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb01',
29
+ } as const satisfies core_MultisigSimulation.Rpc
30
+
31
+ describe('MultisigSimulation', () => {
32
+ test('behavior: converts between RPC and domain specs', () => {
33
+ const spec = z.decode(z_MultisigSimulation.MultisigSimulation, rpc)
34
+
35
+ expect(spec).toEqual(core_MultisigSimulation.fromRpc(rpc))
36
+ expect(
37
+ z.encode(z_MultisigSimulation.MultisigSimulation, spec),
38
+ ).toStrictEqual(rpc)
39
+ })
40
+
41
+ test('error: rejects more than eight root approvals', () => {
42
+ expect(
43
+ z.safeDecode(z_MultisigSimulation.Rpc, {
44
+ ...rpc,
45
+ approvals: Array.from({ length: 9 }, () => rpc.approvals[0]),
46
+ }).success,
47
+ ).toMatchInlineSnapshot(`false`)
48
+ })
49
+
50
+ test('error: rejects more than eight nested approvals', () => {
51
+ expect(
52
+ z.safeDecode(z_MultisigSimulation.Rpc, {
53
+ ...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,
67
+ ).toMatchInlineSnapshot(`false`)
68
+ })
69
+
70
+ test('error: rejects malformed encoded configurations', () => {
71
+ expect(
72
+ z.safeDecode(z_MultisigSimulation.Rpc, {
73
+ ...rpc,
74
+ config: '0x01',
75
+ }).success,
76
+ ).toMatchInlineSnapshot(`false`)
77
+ })
78
+ })