ox 1.7.1 → 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 +42 -0
- package/dist/core/Hash.js +1 -1
- package/dist/core/Hash.js.map +1 -1
- package/dist/tempo/KeyAuthorization.d.ts +2 -2
- package/dist/tempo/KeyAuthorization.d.ts.map +1 -1
- package/dist/tempo/MultisigConfig.d.ts +151 -83
- package/dist/tempo/MultisigConfig.d.ts.map +1 -1
- package/dist/tempo/MultisigConfig.js +164 -86
- package/dist/tempo/MultisigConfig.js.map +1 -1
- package/dist/tempo/MultisigOperation.d.ts +340 -0
- package/dist/tempo/MultisigOperation.d.ts.map +1 -0
- package/dist/tempo/MultisigOperation.js +839 -0
- package/dist/tempo/MultisigOperation.js.map +1 -0
- 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 +45 -0
- package/dist/tempo/RpcSchemaTempo.d.ts.map +1 -1
- package/dist/tempo/SignatureEnvelope.d.ts +55 -86
- package/dist/tempo/SignatureEnvelope.d.ts.map +1 -1
- package/dist/tempo/SignatureEnvelope.js +93 -158
- package/dist/tempo/SignatureEnvelope.js.map +1 -1
- package/dist/tempo/TransactionRequest.d.ts +9 -17
- 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/TxEnvelopeTempo.d.ts +3 -2
- package/dist/tempo/TxEnvelopeTempo.d.ts.map +1 -1
- package/dist/tempo/TxEnvelopeTempo.js +3 -2
- package/dist/tempo/TxEnvelopeTempo.js.map +1 -1
- package/dist/tempo/index.d.ts +22 -2
- package/dist/tempo/index.d.ts.map +1 -1
- package/dist/tempo/index.js +22 -2
- package/dist/tempo/index.js.map +1 -1
- package/dist/zod/tempo/AuthorizationTempo.d.ts +60 -180
- package/dist/zod/tempo/AuthorizationTempo.d.ts.map +1 -1
- package/dist/zod/tempo/KeyAuthorization.d.ts +65 -118
- package/dist/zod/tempo/KeyAuthorization.d.ts.map +1 -1
- package/dist/zod/tempo/MultisigConfig.d.ts +31 -2
- package/dist/zod/tempo/MultisigConfig.d.ts.map +1 -1
- package/dist/zod/tempo/MultisigConfig.js +26 -3
- package/dist/zod/tempo/MultisigConfig.js.map +1 -1
- package/dist/zod/tempo/MultisigOperation.d.ts +158 -0
- package/dist/zod/tempo/MultisigOperation.d.ts.map +1 -0
- package/dist/zod/tempo/MultisigOperation.js +62 -0
- package/dist/zod/tempo/MultisigOperation.js.map +1 -0
- package/dist/zod/tempo/MultisigSimulation.d.ts +120 -0
- package/dist/zod/tempo/MultisigSimulation.d.ts.map +1 -0
- package/dist/zod/tempo/MultisigSimulation.js +78 -0
- package/dist/zod/tempo/MultisigSimulation.js.map +1 -0
- package/dist/zod/tempo/RpcSchemaTempo.d.ts +528 -144
- package/dist/zod/tempo/RpcSchemaTempo.d.ts.map +1 -1
- package/dist/zod/tempo/RpcSchemaTempo.js +47 -0
- package/dist/zod/tempo/RpcSchemaTempo.js.map +1 -1
- package/dist/zod/tempo/SignatureEnvelope.d.ts +18 -54
- package/dist/zod/tempo/SignatureEnvelope.d.ts.map +1 -1
- package/dist/zod/tempo/SignatureEnvelope.js +5 -22
- package/dist/zod/tempo/SignatureEnvelope.js.map +1 -1
- package/dist/zod/tempo/Transaction.d.ts +138 -348
- package/dist/zod/tempo/Transaction.d.ts.map +1 -1
- package/dist/zod/tempo/TransactionRequest.d.ts +286 -239
- package/dist/zod/tempo/TransactionRequest.d.ts.map +1 -1
- package/dist/zod/tempo/TransactionRequest.js +11 -22
- package/dist/zod/tempo/TransactionRequest.js.map +1 -1
- package/dist/zod/tempo/TxEnvelopeTempo.d.ts +60 -48
- package/dist/zod/tempo/TxEnvelopeTempo.d.ts.map +1 -1
- package/dist/zod/tempo/ZoneRpcAuthentication.d.ts +15 -12
- package/dist/zod/tempo/ZoneRpcAuthentication.d.ts.map +1 -1
- package/dist/zod/tempo/z.d.ts +2 -0
- package/dist/zod/tempo/z.d.ts.map +1 -1
- package/dist/zod/tempo/z.js +2 -0
- package/dist/zod/tempo/z.js.map +1 -1
- package/package.json +21 -1
- package/src/core/Hash.ts +1 -1
- package/src/core/_test/Hash.test.ts +15 -0
- package/src/tempo/AuthorizationTempo.test.ts +4 -0
- package/src/tempo/KeyAuthorization.test-d.ts +13 -12
- package/src/tempo/KeyAuthorization.test.ts +109 -3
- package/src/tempo/KeyAuthorization.ts +4 -4
- package/src/tempo/MultisigConfig.test-d.ts +52 -0
- package/src/tempo/MultisigConfig.test.ts +288 -227
- package/src/tempo/MultisigConfig.ts +275 -104
- package/src/tempo/MultisigOperation.test-d.ts +79 -0
- package/src/tempo/MultisigOperation.test.ts +1950 -0
- package/src/tempo/MultisigOperation.ts +1293 -0
- 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 +91 -0
- package/src/tempo/RpcSchemaTempo.ts +46 -0
- package/src/tempo/SignatureEnvelope.test-d.ts +33 -72
- package/src/tempo/SignatureEnvelope.test.ts +533 -500
- package/src/tempo/SignatureEnvelope.ts +171 -258
- package/src/tempo/Transaction.test.ts +61 -0
- package/src/tempo/TransactionRequest.test-d.ts +11 -0
- package/src/tempo/TransactionRequest.test.ts +214 -41
- package/src/tempo/TransactionRequest.ts +19 -20
- package/src/tempo/TxEnvelopeTempo.test-d.ts +7 -0
- package/src/tempo/TxEnvelopeTempo.test.ts +25 -0
- package/src/tempo/TxEnvelopeTempo.ts +5 -3
- package/src/tempo/index.ts +22 -2
- package/src/tempo/multisig.e2e.test.ts +164 -87
- package/src/version.ts +1 -1
- package/src/zod/tempo/MultisigConfig.ts +29 -3
- package/src/zod/tempo/MultisigOperation.ts +66 -0
- package/src/zod/tempo/MultisigSimulation.ts +98 -0
- package/src/zod/tempo/RpcSchemaTempo.ts +53 -0
- package/src/zod/tempo/SignatureEnvelope.ts +12 -54
- package/src/zod/tempo/TransactionRequest.ts +17 -26
- package/src/zod/tempo/_test/KeyAuthorization.test.ts +2 -4
- package/src/zod/tempo/_test/MultisigConfig.test-d.ts +13 -0
- package/src/zod/tempo/_test/MultisigConfig.test.ts +13 -2
- package/src/zod/tempo/_test/MultisigOperation.test-d.ts +27 -0
- package/src/zod/tempo/_test/MultisigOperation.test.ts +66 -0
- 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 +48 -0
- package/src/zod/tempo/_test/RpcSchemaTempo.test.ts +83 -0
- package/src/zod/tempo/_test/SignatureEnvelope.test-d.ts +1 -1
- package/src/zod/tempo/_test/SignatureEnvelope.test.ts +57 -120
- package/src/zod/tempo/_test/TransactionRequest.test.ts +43 -16
- package/src/zod/tempo/z.ts +2 -0
|
@@ -2,14 +2,19 @@ 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'
|
|
9
14
|
|
|
10
15
|
const chainId = chain.id
|
|
11
16
|
const updateConfig = AbiFunction.from(
|
|
12
|
-
'function updateConfig(uint8 threshold, (address owner, uint8 weight)[] owners)',
|
|
17
|
+
'function updateConfig((bytes32 salt, uint64 version, uint8 threshold, (address owner, uint8 weight)[] owners) current, uint8 threshold, (address owner, uint8 weight)[] owners)',
|
|
13
18
|
)
|
|
14
19
|
|
|
15
20
|
describe('behavior: multisig (TIP-1061)', () => {
|
|
@@ -49,16 +54,21 @@ describe('behavior: multisig (TIP-1061)', () => {
|
|
|
49
54
|
}
|
|
50
55
|
|
|
51
56
|
function approve(parameters: {
|
|
52
|
-
|
|
57
|
+
address?: Address.Address | undefined
|
|
58
|
+
config: MultisigConfig.Config
|
|
53
59
|
payload: Hex.Hex
|
|
54
60
|
signers: readonly { privateKey: Hex.Hex }[]
|
|
55
|
-
version?: bigint | undefined
|
|
56
61
|
}) {
|
|
57
|
-
const {
|
|
62
|
+
const {
|
|
63
|
+
address = MultisigConfig.getAddress(parameters.config),
|
|
64
|
+
config,
|
|
65
|
+
payload,
|
|
66
|
+
signers,
|
|
67
|
+
} = parameters
|
|
58
68
|
const digest = MultisigConfig.getSignPayload({
|
|
69
|
+
account: address,
|
|
70
|
+
config,
|
|
59
71
|
payload,
|
|
60
|
-
initialConfig,
|
|
61
|
-
version,
|
|
62
72
|
})
|
|
63
73
|
const signatures = signers.map((signer) =>
|
|
64
74
|
SignatureEnvelope.from(
|
|
@@ -67,25 +77,10 @@ describe('behavior: multisig (TIP-1061)', () => {
|
|
|
67
77
|
)
|
|
68
78
|
// The node requires approvals ordered by recovered owner address.
|
|
69
79
|
return SignatureEnvelope.sortMultisigApprovals({
|
|
70
|
-
|
|
80
|
+
account: address,
|
|
81
|
+
config,
|
|
71
82
|
payload,
|
|
72
83
|
signatures,
|
|
73
|
-
version,
|
|
74
|
-
})
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function multisigSignature(parameters: {
|
|
78
|
-
initialConfig: MultisigConfig.Config
|
|
79
|
-
payload: Hex.Hex
|
|
80
|
-
signers: readonly { privateKey: Hex.Hex }[]
|
|
81
|
-
init?: boolean | undefined
|
|
82
|
-
version?: bigint | undefined
|
|
83
|
-
}) {
|
|
84
|
-
const { init = false, ...approval } = parameters
|
|
85
|
-
return SignatureEnvelope.from({
|
|
86
|
-
initialConfig: parameters.initialConfig,
|
|
87
|
-
...(init ? { init: true } : {}),
|
|
88
|
-
signatures: approve(approval),
|
|
89
84
|
})
|
|
90
85
|
}
|
|
91
86
|
|
|
@@ -111,11 +106,14 @@ describe('behavior: multisig (TIP-1061)', () => {
|
|
|
111
106
|
})
|
|
112
107
|
const receipt = await send(
|
|
113
108
|
TxEnvelopeTempo.serialize(transaction, {
|
|
114
|
-
signature:
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
109
|
+
signature: SignatureEnvelope.from({
|
|
110
|
+
account: multisig.account,
|
|
111
|
+
config: multisig.initialConfig,
|
|
112
|
+
signatures: approve({
|
|
113
|
+
config: multisig.initialConfig,
|
|
114
|
+
payload: TxEnvelopeTempo.getSignPayload(transaction),
|
|
115
|
+
signers: multisig.ownerKeys,
|
|
116
|
+
}),
|
|
119
117
|
}),
|
|
120
118
|
}),
|
|
121
119
|
)
|
|
@@ -142,6 +140,51 @@ describe('behavior: multisig (TIP-1061)', () => {
|
|
|
142
140
|
})
|
|
143
141
|
}
|
|
144
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
|
+
|
|
145
188
|
test('examples: bootstrap, initialized, and configuration rotation', async () => {
|
|
146
189
|
const { account, initialConfig, ownerKeys } = setup({
|
|
147
190
|
count: 3,
|
|
@@ -149,9 +192,10 @@ describe('behavior: multisig (TIP-1061)', () => {
|
|
|
149
192
|
})
|
|
150
193
|
const replacement = createKey()
|
|
151
194
|
const rotatedConfig = MultisigConfig.from({
|
|
195
|
+
owners: [{ owner: replacement.address, weight: 1 }],
|
|
152
196
|
salt: initialConfig.salt,
|
|
153
197
|
threshold: 1,
|
|
154
|
-
|
|
198
|
+
version: 1,
|
|
155
199
|
})
|
|
156
200
|
|
|
157
201
|
await fundAddress(client, { address: account })
|
|
@@ -168,10 +212,10 @@ describe('behavior: multisig (TIP-1061)', () => {
|
|
|
168
212
|
|
|
169
213
|
const bootstrap_signed = TxEnvelopeTempo.serialize(bootstrap, {
|
|
170
214
|
signature: SignatureEnvelope.from({
|
|
171
|
-
|
|
172
|
-
|
|
215
|
+
account,
|
|
216
|
+
config: initialConfig,
|
|
173
217
|
signatures: approve({
|
|
174
|
-
initialConfig,
|
|
218
|
+
config: initialConfig,
|
|
175
219
|
payload: TxEnvelopeTempo.getSignPayload(bootstrap),
|
|
176
220
|
signers: [ownerKeys[0]!, ownerKeys[1]!],
|
|
177
221
|
}),
|
|
@@ -199,7 +243,7 @@ describe('behavior: multisig (TIP-1061)', () => {
|
|
|
199
243
|
expect(response.from).toBe(account)
|
|
200
244
|
expect(response.signature?.type).toBe('multisig')
|
|
201
245
|
expect(
|
|
202
|
-
(response.signature as SignatureEnvelope.Multisig | undefined)?.
|
|
246
|
+
(response.signature as SignatureEnvelope.Multisig | undefined)?.config,
|
|
203
247
|
).toEqual(initialConfig)
|
|
204
248
|
}
|
|
205
249
|
|
|
@@ -212,6 +256,7 @@ describe('behavior: multisig (TIP-1061)', () => {
|
|
|
212
256
|
{
|
|
213
257
|
to: '0xaacc000000000000000000000000000000000000',
|
|
214
258
|
data: AbiFunction.encodeData(updateConfig, [
|
|
259
|
+
initialConfig,
|
|
215
260
|
rotatedConfig.threshold,
|
|
216
261
|
rotatedConfig.owners,
|
|
217
262
|
]),
|
|
@@ -226,9 +271,10 @@ describe('behavior: multisig (TIP-1061)', () => {
|
|
|
226
271
|
})
|
|
227
272
|
const updateSigned = TxEnvelopeTempo.serialize(update, {
|
|
228
273
|
signature: SignatureEnvelope.from({
|
|
229
|
-
|
|
274
|
+
account,
|
|
275
|
+
config: initialConfig,
|
|
230
276
|
signatures: approve({
|
|
231
|
-
initialConfig,
|
|
277
|
+
config: initialConfig,
|
|
232
278
|
payload: TxEnvelopeTempo.getSignPayload(update),
|
|
233
279
|
signers: [ownerKeys[0]!, ownerKeys[1]!],
|
|
234
280
|
}),
|
|
@@ -259,12 +305,13 @@ describe('behavior: multisig (TIP-1061)', () => {
|
|
|
259
305
|
|
|
260
306
|
const spend_signed = TxEnvelopeTempo.serialize(spend, {
|
|
261
307
|
signature: SignatureEnvelope.from({
|
|
262
|
-
|
|
308
|
+
account,
|
|
309
|
+
config: rotatedConfig,
|
|
263
310
|
signatures: approve({
|
|
264
|
-
|
|
311
|
+
address: account,
|
|
312
|
+
config: rotatedConfig,
|
|
265
313
|
payload: TxEnvelopeTempo.getSignPayload(spend),
|
|
266
314
|
signers: [replacement],
|
|
267
|
-
version: 1n,
|
|
268
315
|
}),
|
|
269
316
|
}),
|
|
270
317
|
})
|
|
@@ -295,10 +342,10 @@ describe('behavior: multisig (TIP-1061)', () => {
|
|
|
295
342
|
})
|
|
296
343
|
const childBootstrapSigned = TxEnvelopeTempo.serialize(childBootstrap, {
|
|
297
344
|
signature: SignatureEnvelope.from({
|
|
298
|
-
|
|
299
|
-
|
|
345
|
+
account: child.account,
|
|
346
|
+
config: child.initialConfig,
|
|
300
347
|
signatures: approve({
|
|
301
|
-
|
|
348
|
+
config: child.initialConfig,
|
|
302
349
|
payload: TxEnvelopeTempo.getSignPayload(childBootstrap),
|
|
303
350
|
signers: child.ownerKeys,
|
|
304
351
|
}),
|
|
@@ -330,21 +377,23 @@ describe('behavior: multisig (TIP-1061)', () => {
|
|
|
330
377
|
maxPriorityFeePerGas: Value.fromGwei('10'),
|
|
331
378
|
})
|
|
332
379
|
const digest = MultisigConfig.getSignPayload({
|
|
333
|
-
|
|
380
|
+
account,
|
|
381
|
+
config: initialConfig,
|
|
334
382
|
payload: TxEnvelopeTempo.getSignPayload(bootstrap),
|
|
335
383
|
})
|
|
336
384
|
const nested = SignatureEnvelope.from({
|
|
337
|
-
|
|
385
|
+
account: child.account,
|
|
386
|
+
config: child.initialConfig,
|
|
338
387
|
signatures: approve({
|
|
339
|
-
|
|
388
|
+
config: child.initialConfig,
|
|
340
389
|
payload: digest,
|
|
341
390
|
signers: child.ownerKeys,
|
|
342
391
|
}),
|
|
343
392
|
})
|
|
344
393
|
const bootstrapSigned = TxEnvelopeTempo.serialize(bootstrap, {
|
|
345
394
|
signature: SignatureEnvelope.from({
|
|
346
|
-
|
|
347
|
-
|
|
395
|
+
account,
|
|
396
|
+
config: initialConfig,
|
|
348
397
|
signatures: [nested],
|
|
349
398
|
}),
|
|
350
399
|
})
|
|
@@ -368,17 +417,23 @@ describe('behavior: multisig (TIP-1061)', () => {
|
|
|
368
417
|
maxPriorityFeePerGas: Value.fromGwei('10'),
|
|
369
418
|
})
|
|
370
419
|
const parentDigest = MultisigConfig.getSignPayload({
|
|
371
|
-
|
|
420
|
+
account,
|
|
421
|
+
config: initialConfig,
|
|
372
422
|
payload: TxEnvelopeTempo.getSignPayload(transaction),
|
|
373
423
|
})
|
|
374
|
-
const childSignature =
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
424
|
+
const childSignature = SignatureEnvelope.from({
|
|
425
|
+
account: child.account,
|
|
426
|
+
config: child.initialConfig,
|
|
427
|
+
signatures: approve({
|
|
428
|
+
config: child.initialConfig,
|
|
429
|
+
payload: parentDigest,
|
|
430
|
+
signers: child.ownerKeys,
|
|
431
|
+
}),
|
|
378
432
|
})
|
|
379
433
|
const serialized = TxEnvelopeTempo.serialize(transaction, {
|
|
380
434
|
signature: SignatureEnvelope.from({
|
|
381
|
-
|
|
435
|
+
account,
|
|
436
|
+
config: initialConfig,
|
|
382
437
|
signatures: [childSignature],
|
|
383
438
|
}),
|
|
384
439
|
})
|
|
@@ -410,10 +465,14 @@ describe('behavior: multisig (TIP-1061)', () => {
|
|
|
410
465
|
maxPriorityFeePerGas: Value.fromGwei('10'),
|
|
411
466
|
})
|
|
412
467
|
const signedByOwners = TxEnvelopeTempo.from(transaction, {
|
|
413
|
-
signature:
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
468
|
+
signature: SignatureEnvelope.from({
|
|
469
|
+
account: multisig.account,
|
|
470
|
+
config: multisig.initialConfig,
|
|
471
|
+
signatures: approve({
|
|
472
|
+
config: multisig.initialConfig,
|
|
473
|
+
payload: TxEnvelopeTempo.getSignPayload(transaction),
|
|
474
|
+
signers: multisig.ownerKeys,
|
|
475
|
+
}),
|
|
417
476
|
}),
|
|
418
477
|
})
|
|
419
478
|
const sponsored = TxEnvelopeTempo.from({
|
|
@@ -461,10 +520,14 @@ describe('behavior: multisig (TIP-1061)', () => {
|
|
|
461
520
|
const sponsored = TxEnvelopeTempo.from(transaction, { feePayerSignature })
|
|
462
521
|
const receipt = await send(
|
|
463
522
|
TxEnvelopeTempo.serialize(sponsored, {
|
|
464
|
-
signature:
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
523
|
+
signature: SignatureEnvelope.from({
|
|
524
|
+
account: multisig.account,
|
|
525
|
+
config: multisig.initialConfig,
|
|
526
|
+
signatures: approve({
|
|
527
|
+
config: multisig.initialConfig,
|
|
528
|
+
payload: TxEnvelopeTempo.getSignPayload(sponsored),
|
|
529
|
+
signers: multisig.ownerKeys,
|
|
530
|
+
}),
|
|
468
531
|
}),
|
|
469
532
|
}),
|
|
470
533
|
)
|
|
@@ -495,14 +558,16 @@ describe('behavior: multisig (TIP-1061)', () => {
|
|
|
495
558
|
const serialize = (
|
|
496
559
|
value: ReturnType<typeof transaction>,
|
|
497
560
|
signers: readonly { privateKey: Hex.Hex }[],
|
|
498
|
-
init = false,
|
|
499
561
|
) =>
|
|
500
562
|
TxEnvelopeTempo.serialize(value, {
|
|
501
|
-
signature:
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
563
|
+
signature: SignatureEnvelope.from({
|
|
564
|
+
account,
|
|
565
|
+
config: initialConfig,
|
|
566
|
+
signatures: approve({
|
|
567
|
+
config: initialConfig,
|
|
568
|
+
payload: TxEnvelopeTempo.getSignPayload(value),
|
|
569
|
+
signers,
|
|
570
|
+
}),
|
|
506
571
|
}),
|
|
507
572
|
})
|
|
508
573
|
|
|
@@ -510,7 +575,7 @@ describe('behavior: multisig (TIP-1061)', () => {
|
|
|
510
575
|
const bootstrapReceipt = (await client
|
|
511
576
|
.request({
|
|
512
577
|
method: 'eth_sendRawTransactionSync',
|
|
513
|
-
params: [serialize(bootstrap, [ownerKeys[0]!, ownerKeys[1]!]
|
|
578
|
+
params: [serialize(bootstrap, [ownerKeys[0]!, ownerKeys[1]!])],
|
|
514
579
|
})
|
|
515
580
|
.then((tx) => TransactionReceipt.fromRpc(tx as any)))!
|
|
516
581
|
expect(bootstrapReceipt.status).toBe('success')
|
|
@@ -568,10 +633,10 @@ describe('behavior: multisig (TIP-1061)', () => {
|
|
|
568
633
|
|
|
569
634
|
const bootstrap_signed = TxEnvelopeTempo.serialize(bootstrap, {
|
|
570
635
|
signature: SignatureEnvelope.from({
|
|
571
|
-
|
|
572
|
-
|
|
636
|
+
account,
|
|
637
|
+
config: initialConfig,
|
|
573
638
|
signatures: approve({
|
|
574
|
-
initialConfig,
|
|
639
|
+
config: initialConfig,
|
|
575
640
|
payload: TxEnvelopeTempo.getSignPayload(bootstrap),
|
|
576
641
|
signers: ownerKeys,
|
|
577
642
|
}),
|
|
@@ -618,9 +683,10 @@ describe('behavior: multisig (TIP-1061)', () => {
|
|
|
618
683
|
|
|
619
684
|
const authorize_signed = TxEnvelopeTempo.serialize(authorize, {
|
|
620
685
|
signature: SignatureEnvelope.from({
|
|
621
|
-
|
|
686
|
+
account,
|
|
687
|
+
config: initialConfig,
|
|
622
688
|
signatures: approve({
|
|
623
|
-
initialConfig,
|
|
689
|
+
config: initialConfig,
|
|
624
690
|
payload: TxEnvelopeTempo.getSignPayload(authorize),
|
|
625
691
|
signers: ownerKeys,
|
|
626
692
|
}),
|
|
@@ -698,6 +764,7 @@ describe('behavior: multisig (TIP-1061)', () => {
|
|
|
698
764
|
{
|
|
699
765
|
to: '0xaacc000000000000000000000000000000000000',
|
|
700
766
|
data: AbiFunction.encodeData(updateConfig, [
|
|
767
|
+
initialConfig,
|
|
701
768
|
initialConfig.threshold,
|
|
702
769
|
initialConfig.owners,
|
|
703
770
|
]),
|
|
@@ -744,11 +811,14 @@ describe('behavior: multisig (TIP-1061)', () => {
|
|
|
744
811
|
type: 'secp256k1',
|
|
745
812
|
})
|
|
746
813
|
const keyAuthorizationSigned = KeyAuthorization.from(keyAuthorization, {
|
|
747
|
-
signature:
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
814
|
+
signature: SignatureEnvelope.from({
|
|
815
|
+
account: multisig.account,
|
|
816
|
+
config: multisig.initialConfig,
|
|
817
|
+
signatures: approve({
|
|
818
|
+
config: multisig.initialConfig,
|
|
819
|
+
payload: KeyAuthorization.getSignPayload(keyAuthorization),
|
|
820
|
+
signers: multisig.ownerKeys,
|
|
821
|
+
}),
|
|
752
822
|
}),
|
|
753
823
|
})
|
|
754
824
|
const transaction = TxEnvelopeTempo.from({
|
|
@@ -787,10 +857,14 @@ describe('behavior: multisig (TIP-1061)', () => {
|
|
|
787
857
|
type: 'secp256k1',
|
|
788
858
|
})
|
|
789
859
|
const keyAuthorizationSigned = KeyAuthorization.from(keyAuthorization, {
|
|
790
|
-
signature:
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
860
|
+
signature: SignatureEnvelope.from({
|
|
861
|
+
account: multisig.account,
|
|
862
|
+
config: multisig.initialConfig,
|
|
863
|
+
signatures: approve({
|
|
864
|
+
config: multisig.initialConfig,
|
|
865
|
+
payload: KeyAuthorization.getSignPayload(keyAuthorization),
|
|
866
|
+
signers: multisig.ownerKeys,
|
|
867
|
+
}),
|
|
794
868
|
}),
|
|
795
869
|
})
|
|
796
870
|
const bootstrapTransaction = TxEnvelopeTempo.from({
|
|
@@ -805,11 +879,14 @@ describe('behavior: multisig (TIP-1061)', () => {
|
|
|
805
879
|
})
|
|
806
880
|
const bootstrapReceipt = await send(
|
|
807
881
|
TxEnvelopeTempo.serialize(bootstrapTransaction, {
|
|
808
|
-
signature:
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
882
|
+
signature: SignatureEnvelope.from({
|
|
883
|
+
account: multisig.account,
|
|
884
|
+
config: multisig.initialConfig,
|
|
885
|
+
signatures: approve({
|
|
886
|
+
config: multisig.initialConfig,
|
|
887
|
+
payload: TxEnvelopeTempo.getSignPayload(bootstrapTransaction),
|
|
888
|
+
signers: multisig.ownerKeys,
|
|
889
|
+
}),
|
|
813
890
|
}),
|
|
814
891
|
}),
|
|
815
892
|
)
|
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'
|
|
@@ -10,12 +10,13 @@ export const Owner = z.object({
|
|
|
10
10
|
weight: z.number(),
|
|
11
11
|
})
|
|
12
12
|
|
|
13
|
-
/** Native multisig configuration schema. */
|
|
13
|
+
/** Native multisig configuration domain schema. */
|
|
14
14
|
export const Config = z
|
|
15
15
|
.object({
|
|
16
|
-
salt: z.optional(z_Hex.Hex),
|
|
17
|
-
threshold: z.number(),
|
|
18
16
|
owners: z.readonly(z.array(Owner)),
|
|
17
|
+
salt: z_Hex.Hex,
|
|
18
|
+
threshold: z.number(),
|
|
19
|
+
version: z.bigint(),
|
|
19
20
|
})
|
|
20
21
|
.check(
|
|
21
22
|
z.refine(
|
|
@@ -23,3 +24,28 @@ export const Config = z
|
|
|
23
24
|
'expected valid native multisig configuration',
|
|
24
25
|
),
|
|
25
26
|
)
|
|
27
|
+
|
|
28
|
+
/** Native multisig configuration RPC schema. */
|
|
29
|
+
export const Rpc = z
|
|
30
|
+
.object({
|
|
31
|
+
owners: z.readonly(z.array(Owner)),
|
|
32
|
+
salt: z_Hex.Hex,
|
|
33
|
+
threshold: z.number(),
|
|
34
|
+
version: z_Hex.Hex,
|
|
35
|
+
})
|
|
36
|
+
.check(
|
|
37
|
+
z.refine((value) => {
|
|
38
|
+
try {
|
|
39
|
+
core_MultisigConfig.fromRpc(value)
|
|
40
|
+
return true
|
|
41
|
+
} catch {
|
|
42
|
+
return false
|
|
43
|
+
}
|
|
44
|
+
}, 'expected valid native multisig configuration'),
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
/** Codec decoding an RPC multisig configuration into a domain configuration. */
|
|
48
|
+
export const MultisigConfig = z.codec(Rpc, Config, {
|
|
49
|
+
decode: (value) => core_MultisigConfig.fromRpc(value),
|
|
50
|
+
encode: (value) => core_MultisigConfig.toRpc(value),
|
|
51
|
+
})
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/* eslint-disable jsdoc-js/require-jsdoc, jsdoc-js/require-description, jsdoc-js/require-example */
|
|
2
|
+
import * as core_MultisigOperation from '../../tempo/MultisigOperation.js'
|
|
3
|
+
import * as z_Address from '../Address.js'
|
|
4
|
+
import * as z_Hash from '../Hash.js'
|
|
5
|
+
import * as z_Hex from '../Hex.js'
|
|
6
|
+
import * as z from 'zod/mini'
|
|
7
|
+
import * as z_MultisigConfig from './MultisigConfig.js'
|
|
8
|
+
|
|
9
|
+
function baseFields() {
|
|
10
|
+
return {
|
|
11
|
+
account: z_Address.Address,
|
|
12
|
+
approvals: z.readonly(z.array(z_Hex.Hex)),
|
|
13
|
+
config: z_MultisigConfig.MultisigConfig,
|
|
14
|
+
createdAt: z.number(),
|
|
15
|
+
hash: z_Hash.Hash,
|
|
16
|
+
signatureCount: z.number(),
|
|
17
|
+
threshold: z.number(),
|
|
18
|
+
updatedAt: z.number(),
|
|
19
|
+
weight: z.number(),
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const valid = z.refine((value) => {
|
|
24
|
+
try {
|
|
25
|
+
core_MultisigOperation.from(value as never)
|
|
26
|
+
return true
|
|
27
|
+
} catch {
|
|
28
|
+
return false
|
|
29
|
+
}
|
|
30
|
+
}, 'expected valid multisig operation')
|
|
31
|
+
|
|
32
|
+
/** Fields shared by every multisig operation schema. */
|
|
33
|
+
export const Base = z.object(baseFields())
|
|
34
|
+
|
|
35
|
+
/** Multisig transaction approval operation schema. */
|
|
36
|
+
export const TransactionOperation = z
|
|
37
|
+
.object({
|
|
38
|
+
...baseFields(),
|
|
39
|
+
expiresAt: z.optional(z.number()),
|
|
40
|
+
status: z.union([
|
|
41
|
+
z.literal('pending'),
|
|
42
|
+
z.literal('submitting'),
|
|
43
|
+
z.literal('success'),
|
|
44
|
+
]),
|
|
45
|
+
submissionId: z.optional(z_Hash.Hash),
|
|
46
|
+
transaction: z_Hex.Hex,
|
|
47
|
+
transactionHash: z.optional(z_Hash.Hash),
|
|
48
|
+
type: z.literal('transaction'),
|
|
49
|
+
})
|
|
50
|
+
.check(valid)
|
|
51
|
+
|
|
52
|
+
/** Multisig key authorization approval operation schema. */
|
|
53
|
+
export const KeyAuthorizationOperation = z
|
|
54
|
+
.object({
|
|
55
|
+
...baseFields(),
|
|
56
|
+
keyAuthorization: z_Hex.Hex,
|
|
57
|
+
status: z.union([z.literal('pending'), z.literal('success')]),
|
|
58
|
+
type: z.literal('keyAuthorization'),
|
|
59
|
+
})
|
|
60
|
+
.check(valid)
|
|
61
|
+
|
|
62
|
+
/** Transaction or key authorization multisig operation schema. */
|
|
63
|
+
export const Operation = z.union([
|
|
64
|
+
TransactionOperation,
|
|
65
|
+
KeyAuthorizationOperation,
|
|
66
|
+
])
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/* eslint-disable jsdoc-js/require-jsdoc, jsdoc-js/require-description, jsdoc-js/require-example */
|
|
2
|
+
import * as core_MultisigConfig from '../../tempo/MultisigConfig.js'
|
|
3
|
+
import * as core_MultisigSimulation from '../../tempo/MultisigSimulation.js'
|
|
4
|
+
import * as z_Address from '../Address.js'
|
|
5
|
+
import * as z_Hex from '../Hex.js'
|
|
6
|
+
import * as z from 'zod/mini'
|
|
7
|
+
import * as z_MultisigConfig from './MultisigConfig.js'
|
|
8
|
+
import * as z_SignatureEnvelope from './SignatureEnvelope.js'
|
|
9
|
+
|
|
10
|
+
const NestedPrimitiveApproval = z.object({
|
|
11
|
+
keyData: z.optional(z_Hex.Hex),
|
|
12
|
+
keyType: z.optional(z_SignatureEnvelope.Type),
|
|
13
|
+
owner: z_Address.Address,
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
const PrimitiveApproval = z.object({
|
|
17
|
+
keyData: z.optional(z_Hex.Hex),
|
|
18
|
+
keyType: z.optional(z_SignatureEnvelope.Type),
|
|
19
|
+
owner: z_Address.Address,
|
|
20
|
+
type: z.literal('primitive'),
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
const NestedSpec = z.object({
|
|
24
|
+
account: z_Address.Address,
|
|
25
|
+
approvals: z.readonly(
|
|
26
|
+
z
|
|
27
|
+
.array(NestedPrimitiveApproval)
|
|
28
|
+
.check(z.maxLength(core_MultisigConfig.maxSignatures)),
|
|
29
|
+
),
|
|
30
|
+
config: z_MultisigConfig.Config,
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
const NestedSpecRpc = z.object({
|
|
34
|
+
account: z_Address.Address,
|
|
35
|
+
approvals: z.readonly(
|
|
36
|
+
z
|
|
37
|
+
.array(NestedPrimitiveApproval)
|
|
38
|
+
.check(z.maxLength(core_MultisigConfig.maxSignatures)),
|
|
39
|
+
),
|
|
40
|
+
config: z_Hex.Hex,
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
/** Native multisig simulation spec schema. */
|
|
44
|
+
export const Domain = z.object({
|
|
45
|
+
account: z_Address.Address,
|
|
46
|
+
approvals: z.readonly(
|
|
47
|
+
z
|
|
48
|
+
.array(
|
|
49
|
+
z.union([
|
|
50
|
+
PrimitiveApproval,
|
|
51
|
+
z.object({
|
|
52
|
+
spec: NestedSpec,
|
|
53
|
+
type: z.literal('multisig'),
|
|
54
|
+
}),
|
|
55
|
+
]),
|
|
56
|
+
)
|
|
57
|
+
.check(z.maxLength(core_MultisigConfig.maxSignatures)),
|
|
58
|
+
),
|
|
59
|
+
config: z_MultisigConfig.Config,
|
|
60
|
+
})
|
|
61
|
+
|
|
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
|
+
)
|
|
90
|
+
|
|
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),
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
/** RPC native multisig simulation spec schema. */
|
|
98
|
+
export const Rpc = Rpc_
|