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.
- package/CHANGELOG.md +27 -0
- package/dist/tempo/KeyAuthorization.d.ts +1 -1
- package/dist/tempo/KeyAuthorization.d.ts.map +1 -1
- package/dist/tempo/MultisigOperation.d.ts +42 -26
- package/dist/tempo/MultisigOperation.d.ts.map +1 -1
- package/dist/tempo/MultisigOperation.js +78 -48
- package/dist/tempo/MultisigOperation.js.map +1 -1
- package/dist/tempo/MultisigSimulation.d.ts +132 -0
- package/dist/tempo/MultisigSimulation.d.ts.map +1 -0
- package/dist/tempo/MultisigSimulation.js +140 -0
- package/dist/tempo/MultisigSimulation.js.map +1 -0
- package/dist/tempo/RpcSchemaTempo.d.ts +20 -10
- package/dist/tempo/RpcSchemaTempo.d.ts.map +1 -1
- package/dist/tempo/SignatureEnvelope.d.ts +9 -20
- package/dist/tempo/SignatureEnvelope.d.ts.map +1 -1
- package/dist/tempo/SignatureEnvelope.js +12 -18
- package/dist/tempo/SignatureEnvelope.js.map +1 -1
- package/dist/tempo/TransactionRequest.d.ts +6 -6
- package/dist/tempo/TransactionRequest.d.ts.map +1 -1
- package/dist/tempo/TransactionRequest.js +7 -7
- package/dist/tempo/TransactionRequest.js.map +1 -1
- package/dist/tempo/index.d.ts +4 -4
- package/dist/tempo/index.d.ts.map +1 -1
- package/dist/tempo/index.js +4 -4
- package/dist/tempo/index.js.map +1 -1
- package/dist/zod/tempo/AuthorizationTempo.d.ts +10 -130
- package/dist/zod/tempo/AuthorizationTempo.d.ts.map +1 -1
- package/dist/zod/tempo/KeyAuthorization.d.ts +5 -65
- package/dist/zod/tempo/KeyAuthorization.d.ts.map +1 -1
- package/dist/zod/tempo/MultisigOperation.d.ts +0 -10
- package/dist/zod/tempo/MultisigOperation.d.ts.map +1 -1
- package/dist/zod/tempo/MultisigOperation.js +0 -3
- package/dist/zod/tempo/MultisigOperation.js.map +1 -1
- package/dist/zod/tempo/{MultisigWitness.d.ts → MultisigSimulation.d.ts} +17 -49
- package/dist/zod/tempo/MultisigSimulation.d.ts.map +1 -0
- package/dist/zod/tempo/{MultisigWitness.js → MultisigSimulation.js} +26 -24
- package/dist/zod/tempo/MultisigSimulation.js.map +1 -0
- package/dist/zod/tempo/RpcSchemaTempo.d.ts +83 -204
- package/dist/zod/tempo/RpcSchemaTempo.d.ts.map +1 -1
- package/dist/zod/tempo/RpcSchemaTempo.js +19 -10
- package/dist/zod/tempo/RpcSchemaTempo.js.map +1 -1
- package/dist/zod/tempo/SignatureEnvelope.d.ts +3 -39
- package/dist/zod/tempo/SignatureEnvelope.d.ts.map +1 -1
- package/dist/zod/tempo/SignatureEnvelope.js +4 -14
- package/dist/zod/tempo/SignatureEnvelope.js.map +1 -1
- package/dist/zod/tempo/Transaction.d.ts +18 -234
- package/dist/zod/tempo/Transaction.d.ts.map +1 -1
- package/dist/zod/tempo/TransactionRequest.d.ts +36 -192
- package/dist/zod/tempo/TransactionRequest.d.ts.map +1 -1
- package/dist/zod/tempo/TransactionRequest.js +10 -10
- package/dist/zod/tempo/TransactionRequest.js.map +1 -1
- package/dist/zod/tempo/z.d.ts +1 -1
- package/dist/zod/tempo/z.d.ts.map +1 -1
- package/dist/zod/tempo/z.js +1 -1
- package/dist/zod/tempo/z.js.map +1 -1
- package/package.json +9 -9
- package/src/tempo/AuthorizationTempo.test.ts +4 -0
- package/src/tempo/KeyAuthorization.test-d.ts +1 -12
- package/src/tempo/KeyAuthorization.test.ts +44 -3
- package/src/tempo/KeyAuthorization.ts +3 -3
- package/src/tempo/MultisigOperation.test-d.ts +8 -6
- package/src/tempo/MultisigOperation.test.ts +236 -169
- package/src/tempo/MultisigOperation.ts +122 -83
- package/src/tempo/MultisigSimulation.test-d.ts +33 -0
- package/src/tempo/MultisigSimulation.test.ts +283 -0
- package/src/tempo/MultisigSimulation.ts +266 -0
- package/src/tempo/RpcSchemaTempo.test-d.ts +45 -10
- package/src/tempo/RpcSchemaTempo.ts +15 -6
- package/src/tempo/SignatureEnvelope.test-d.ts +3 -59
- package/src/tempo/SignatureEnvelope.test.ts +61 -51
- package/src/tempo/SignatureEnvelope.ts +27 -44
- package/src/tempo/Transaction.test.ts +61 -0
- package/src/tempo/TransactionRequest.test-d.ts +7 -7
- package/src/tempo/TransactionRequest.test.ts +129 -208
- package/src/tempo/TransactionRequest.ts +16 -12
- package/src/tempo/index.ts +4 -4
- package/src/tempo/multisig.e2e.test.ts +51 -1
- package/src/version.ts +1 -1
- package/src/zod/tempo/MultisigOperation.ts +0 -3
- package/src/zod/tempo/{MultisigWitness.ts → MultisigSimulation.ts} +39 -42
- package/src/zod/tempo/RpcSchemaTempo.ts +20 -10
- package/src/zod/tempo/SignatureEnvelope.ts +11 -35
- package/src/zod/tempo/TransactionRequest.ts +14 -14
- package/src/zod/tempo/_test/KeyAuthorization.test.ts +2 -15
- package/src/zod/tempo/_test/MultisigOperation.test.ts +0 -2
- package/src/zod/tempo/_test/MultisigSimulation.test-d.ts +13 -0
- package/src/zod/tempo/_test/MultisigSimulation.test.ts +78 -0
- package/src/zod/tempo/_test/RpcSchemaTempo.test-d.ts +19 -2
- package/src/zod/tempo/_test/RpcSchemaTempo.test.ts +46 -4
- package/src/zod/tempo/_test/SignatureEnvelope.test.ts +58 -112
- package/src/zod/tempo/_test/TransactionRequest.test.ts +19 -160
- package/src/zod/tempo/z.ts +1 -1
- package/dist/tempo/MultisigWitness.d.ts +0 -106
- package/dist/tempo/MultisigWitness.d.ts.map +0 -1
- package/dist/tempo/MultisigWitness.js +0 -118
- package/dist/tempo/MultisigWitness.js.map +0 -1
- package/dist/zod/tempo/MultisigWitness.d.ts.map +0 -1
- package/dist/zod/tempo/MultisigWitness.js.map +0 -1
- package/src/tempo/MultisigWitness.test-d.ts +0 -42
- package/src/tempo/MultisigWitness.test.ts +0 -288
- package/src/tempo/MultisigWitness.ts +0 -210
- package/src/zod/tempo/_test/MultisigWitness.test-d.ts +0 -13
- 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
|
|
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
|
-
|
|
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
|
-
| '
|
|
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
|
-
|
|
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: _,
|
|
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.
|
|
133
|
-
request_.
|
|
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
|
-
|
|
|
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.
|
|
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.
|
|
274
|
-
request_rpc.
|
|
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
|
-
|
|
|
313
|
+
| MultisigSimulation.toRpc.ErrorType
|
|
310
314
|
| Errors.GlobalErrorType
|
|
311
315
|
}
|
|
312
316
|
|
package/src/tempo/index.ts
CHANGED
|
@@ -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
|
|
186
|
+
* Native multisig RPC simulation utilities.
|
|
187
187
|
*
|
|
188
|
-
* Converts complete root and nested owner
|
|
189
|
-
*
|
|
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
|
|
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 {
|
|
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
|
+
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
|
|
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
|
|
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
|
|
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:
|
|
40
|
+
config: z_Hex.Hex,
|
|
55
41
|
})
|
|
56
42
|
|
|
57
|
-
/** Native multisig simulation
|
|
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
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
z
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
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
|
|
95
|
-
export const
|
|
96
|
-
decode: (value) =>
|
|
97
|
-
encode: (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
|
|
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 `
|
|
106
|
-
export const
|
|
107
|
-
method: '
|
|
108
|
-
params: z.tuple([
|
|
109
|
-
|
|
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 =
|
|
89
|
-
.
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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: _,
|
|
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.
|
|
254
|
-
request_.
|
|
255
|
-
|
|
256
|
-
request.
|
|
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.
|
|
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.
|
|
342
|
-
request_rpc.
|
|
343
|
-
|
|
344
|
-
request.
|
|
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
|
-
|
|
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
|
+
})
|