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
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { Transaction } from 'ox/tempo'
|
|
2
2
|
import { describe, expect, test } from 'vp/test'
|
|
3
3
|
|
|
4
|
+
const multisigRpcSignature =
|
|
5
|
+
'0xf897949dba7f426b711d4893c11611eacf7cc334e7146bf83ba000000000000000000000000000000000000000000000000000000000000000008001d7d6947e5f4552091a69125d5dfcb7b8c2659029395bdf01f843b841869437e01f64bebeb78a8a6b30bfd3a993819c8cad82c807515d9b9e9b36f98535dfaa5eebc597715d05f6ce4927747f14fa4cd2acc717fdcd3877146437f8f41b' as const
|
|
6
|
+
|
|
4
7
|
describe('fromRpc', () => {
|
|
5
8
|
test('default', () => {
|
|
6
9
|
const transaction = Transaction.fromRpc({
|
|
@@ -512,3 +515,61 @@ describe('toRpc', () => {
|
|
|
512
515
|
`)
|
|
513
516
|
})
|
|
514
517
|
})
|
|
518
|
+
|
|
519
|
+
describe('roundtrip', () => {
|
|
520
|
+
test('behavior: multisig RPC signature', () => {
|
|
521
|
+
const rpc = {
|
|
522
|
+
accessList: [],
|
|
523
|
+
blockHash:
|
|
524
|
+
'0xc350d807505fb835650f0013632c5515592987ba169bbc6626d9fc54d91f0f0b',
|
|
525
|
+
blockNumber: '0x12f296f',
|
|
526
|
+
calls: [],
|
|
527
|
+
chainId: '0x1',
|
|
528
|
+
feeToken: '0x20c0000000000000000000000000000000000000',
|
|
529
|
+
from: '0x9dba7f426b711d4893c11611eacf7cc334e7146b',
|
|
530
|
+
gas: '0x43f5d',
|
|
531
|
+
hash: '0x353fdfc38a2f26115daadee9f5b8392ce62b84f410957967e2ed56b35338cdd0',
|
|
532
|
+
maxFeePerGas: '0x2',
|
|
533
|
+
maxPriorityFeePerGas: '0x1',
|
|
534
|
+
nonce: '0x357',
|
|
535
|
+
signature: multisigRpcSignature,
|
|
536
|
+
transactionIndex: '0x2',
|
|
537
|
+
type: '0x76',
|
|
538
|
+
} as const satisfies Transaction.TempoRpc
|
|
539
|
+
const transaction = Transaction.fromRpc(rpc)
|
|
540
|
+
|
|
541
|
+
expect({
|
|
542
|
+
rpc: Transaction.toRpc(transaction).signature,
|
|
543
|
+
signature: transaction.signature,
|
|
544
|
+
}).toMatchInlineSnapshot(`
|
|
545
|
+
{
|
|
546
|
+
"rpc": "0xf897949dba7f426b711d4893c11611eacf7cc334e7146bf83ba000000000000000000000000000000000000000000000000000000000000000008001d7d6947e5f4552091a69125d5dfcb7b8c2659029395bdf01f843b841869437e01f64bebeb78a8a6b30bfd3a993819c8cad82c807515d9b9e9b36f98535dfaa5eebc597715d05f6ce4927747f14fa4cd2acc717fdcd3877146437f8f41b",
|
|
547
|
+
"signature": {
|
|
548
|
+
"account": "0x9dba7f426b711d4893c11611eacf7cc334e7146b",
|
|
549
|
+
"config": {
|
|
550
|
+
"owners": [
|
|
551
|
+
{
|
|
552
|
+
"owner": "0x7e5f4552091a69125d5dfcb7b8c2659029395bdf",
|
|
553
|
+
"weight": 1,
|
|
554
|
+
},
|
|
555
|
+
],
|
|
556
|
+
"salt": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
557
|
+
"threshold": 1,
|
|
558
|
+
"version": 0n,
|
|
559
|
+
},
|
|
560
|
+
"signatures": [
|
|
561
|
+
{
|
|
562
|
+
"signature": {
|
|
563
|
+
"r": "0x869437e01f64bebeb78a8a6b30bfd3a993819c8cad82c807515d9b9e9b36f985",
|
|
564
|
+
"s": "0x35dfaa5eebc597715d05f6ce4927747f14fa4cd2acc717fdcd3877146437f8f4",
|
|
565
|
+
"yParity": 0,
|
|
566
|
+
},
|
|
567
|
+
"type": "secp256k1",
|
|
568
|
+
},
|
|
569
|
+
],
|
|
570
|
+
"type": "multisig",
|
|
571
|
+
},
|
|
572
|
+
}
|
|
573
|
+
`)
|
|
574
|
+
})
|
|
575
|
+
})
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type * as ox_TransactionRequest from '../core/TransactionRequest.js'
|
|
2
2
|
import * as Signature from '../core/Signature.js'
|
|
3
3
|
import { describe, expectTypeOf, test } from 'vp/test'
|
|
4
|
+
import * as MultisigSimulation from './MultisigSimulation.js'
|
|
4
5
|
import * as SignatureEnvelope from './SignatureEnvelope.js'
|
|
5
6
|
import * as TransactionRequest from './TransactionRequest.js'
|
|
6
7
|
import * as TxEnvelopeTempo from './TxEnvelopeTempo.js'
|
|
@@ -47,6 +48,15 @@ describe('TransactionRequest type', () => {
|
|
|
47
48
|
Signature.Rpc | null | undefined
|
|
48
49
|
>()
|
|
49
50
|
})
|
|
51
|
+
|
|
52
|
+
test('carries domain and RPC multisig simulations', () => {
|
|
53
|
+
expectTypeOf<
|
|
54
|
+
TransactionRequest.TransactionRequest['multisigSimulation']
|
|
55
|
+
>().toEqualTypeOf<MultisigSimulation.Spec | undefined>()
|
|
56
|
+
expectTypeOf<TransactionRequest.Rpc['multisigSimulation']>().toEqualTypeOf<
|
|
57
|
+
MultisigSimulation.Rpc | undefined
|
|
58
|
+
>()
|
|
59
|
+
})
|
|
50
60
|
})
|
|
51
61
|
|
|
52
62
|
describe('toEnvelope', () => {
|
|
@@ -77,6 +87,7 @@ describe('toEnvelope', () => {
|
|
|
77
87
|
keyType: 'secp256k1',
|
|
78
88
|
maxFeePerGas: 1n,
|
|
79
89
|
maxPriorityFeePerGas: 1n,
|
|
90
|
+
multisigSimulation: undefined,
|
|
80
91
|
nonce: 0n,
|
|
81
92
|
nonceKey: 'random',
|
|
82
93
|
signature: undefined,
|
|
@@ -1,6 +1,77 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
MultisigConfig,
|
|
3
|
+
type MultisigSimulation,
|
|
4
|
+
TransactionRequest,
|
|
5
|
+
} from 'ox/tempo'
|
|
2
6
|
import { describe, expect, test } from 'vp/test'
|
|
3
7
|
|
|
8
|
+
const multisigSimulationRpc = {
|
|
9
|
+
account: '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
|
|
10
|
+
approvals: [
|
|
11
|
+
{
|
|
12
|
+
keyType: 'secp256k1',
|
|
13
|
+
owner: '0x1111111111111111111111111111111111111111',
|
|
14
|
+
type: 'primitive',
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
spec: {
|
|
18
|
+
account: '0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
|
|
19
|
+
approvals: [
|
|
20
|
+
{
|
|
21
|
+
keyData: '0x0578',
|
|
22
|
+
keyType: 'webAuthn',
|
|
23
|
+
owner: '0x2222222222222222222222222222222222222222',
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
config:
|
|
27
|
+
'0xf83ba022222222222222222222222222222222222222222222222222222222222222220101d7d694222222222222222222222222222222222222222201',
|
|
28
|
+
},
|
|
29
|
+
type: 'multisig',
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
config:
|
|
33
|
+
'0xf852a011111111111111111111111111111111111111111111111111111111111111118002eed694111111111111111111111111111111111111111101d694bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb01',
|
|
34
|
+
} as const satisfies MultisigSimulation.Rpc
|
|
35
|
+
|
|
36
|
+
const multisigSimulation = {
|
|
37
|
+
account: multisigSimulationRpc.account,
|
|
38
|
+
approvals: [
|
|
39
|
+
multisigSimulationRpc.approvals[0],
|
|
40
|
+
{
|
|
41
|
+
spec: {
|
|
42
|
+
account: multisigSimulationRpc.approvals[1].spec.account,
|
|
43
|
+
approvals: multisigSimulationRpc.approvals[1].spec.approvals,
|
|
44
|
+
config: MultisigConfig.from({
|
|
45
|
+
owners: [
|
|
46
|
+
{
|
|
47
|
+
owner: '0x2222222222222222222222222222222222222222',
|
|
48
|
+
weight: 1,
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
salt: `0x${'22'.repeat(32)}`,
|
|
52
|
+
threshold: 1,
|
|
53
|
+
version: 1n,
|
|
54
|
+
}),
|
|
55
|
+
},
|
|
56
|
+
type: 'multisig',
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
config: MultisigConfig.from({
|
|
60
|
+
owners: [
|
|
61
|
+
{
|
|
62
|
+
owner: '0x1111111111111111111111111111111111111111',
|
|
63
|
+
weight: 1,
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
owner: '0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
|
|
67
|
+
weight: 1,
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
salt: `0x${'11'.repeat(32)}`,
|
|
71
|
+
threshold: 2,
|
|
72
|
+
}),
|
|
73
|
+
} as const satisfies MultisigSimulation.Spec
|
|
74
|
+
|
|
4
75
|
describe('fromRpc', () => {
|
|
5
76
|
test('default', () => {
|
|
6
77
|
const request = TransactionRequest.fromRpc({
|
|
@@ -69,7 +140,7 @@ describe('fromRpc', () => {
|
|
|
69
140
|
expect(request.nonceKey).toBe(255n)
|
|
70
141
|
})
|
|
71
142
|
|
|
72
|
-
test('behavior:
|
|
143
|
+
test('behavior: capabilities and key hints pass through', () => {
|
|
73
144
|
const request = TransactionRequest.fromRpc({
|
|
74
145
|
calls: [{ to: '0xcafebabecafebabecafebabecafebabecafebabe' }],
|
|
75
146
|
capabilities: { balanceDiffs: true },
|
|
@@ -77,30 +148,86 @@ describe('fromRpc', () => {
|
|
|
77
148
|
keyData: '0x0578',
|
|
78
149
|
keyId: '0xcccccccccccccccccccccccccccccccccccccccc',
|
|
79
150
|
keyType: 'webAuthn',
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
owner: '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
|
|
86
|
-
weight: 1,
|
|
87
|
-
},
|
|
151
|
+
type: '0x76',
|
|
152
|
+
})
|
|
153
|
+
expect(request).toMatchInlineSnapshot(`
|
|
154
|
+
{
|
|
155
|
+
"calls": [
|
|
88
156
|
{
|
|
89
|
-
|
|
90
|
-
|
|
157
|
+
"data": undefined,
|
|
158
|
+
"to": "0xcafebabecafebabecafebabecafebabecafebabe",
|
|
91
159
|
},
|
|
92
160
|
],
|
|
93
|
-
|
|
94
|
-
|
|
161
|
+
"capabilities": {
|
|
162
|
+
"balanceDiffs": true,
|
|
163
|
+
},
|
|
164
|
+
"feePayer": true,
|
|
165
|
+
"keyData": "0x0578",
|
|
166
|
+
"keyId": "0xcccccccccccccccccccccccccccccccccccccccc",
|
|
167
|
+
"keyType": "webAuthn",
|
|
168
|
+
"type": "tempo",
|
|
169
|
+
}
|
|
170
|
+
`)
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
test('behavior: multisig simulation', () => {
|
|
174
|
+
const request = TransactionRequest.fromRpc({
|
|
175
|
+
from: '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
|
|
176
|
+
multisigSimulation: multisigSimulationRpc,
|
|
95
177
|
type: '0x76',
|
|
96
178
|
})
|
|
97
|
-
|
|
98
|
-
expect(request.
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
179
|
+
|
|
180
|
+
expect(request.multisigSimulation).toMatchInlineSnapshot(`
|
|
181
|
+
{
|
|
182
|
+
"account": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
|
183
|
+
"approvals": [
|
|
184
|
+
{
|
|
185
|
+
"keyType": "secp256k1",
|
|
186
|
+
"owner": "0x1111111111111111111111111111111111111111",
|
|
187
|
+
"type": "primitive",
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
"spec": {
|
|
191
|
+
"account": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
|
|
192
|
+
"approvals": [
|
|
193
|
+
{
|
|
194
|
+
"keyData": "0x0578",
|
|
195
|
+
"keyType": "webAuthn",
|
|
196
|
+
"owner": "0x2222222222222222222222222222222222222222",
|
|
197
|
+
},
|
|
198
|
+
],
|
|
199
|
+
"config": {
|
|
200
|
+
"owners": [
|
|
201
|
+
{
|
|
202
|
+
"owner": "0x2222222222222222222222222222222222222222",
|
|
203
|
+
"weight": 1,
|
|
204
|
+
},
|
|
205
|
+
],
|
|
206
|
+
"salt": "0x2222222222222222222222222222222222222222222222222222222222222222",
|
|
207
|
+
"threshold": 1,
|
|
208
|
+
"version": 1n,
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
"type": "multisig",
|
|
212
|
+
},
|
|
213
|
+
],
|
|
214
|
+
"config": {
|
|
215
|
+
"owners": [
|
|
216
|
+
{
|
|
217
|
+
"owner": "0x1111111111111111111111111111111111111111",
|
|
218
|
+
"weight": 1,
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
"owner": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
|
|
222
|
+
"weight": 1,
|
|
223
|
+
},
|
|
224
|
+
],
|
|
225
|
+
"salt": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
226
|
+
"threshold": 2,
|
|
227
|
+
"version": 0n,
|
|
228
|
+
},
|
|
229
|
+
}
|
|
230
|
+
`)
|
|
104
231
|
})
|
|
105
232
|
|
|
106
233
|
test('behavior: empty', () => {
|
|
@@ -157,7 +284,7 @@ describe('toRpc', () => {
|
|
|
157
284
|
`)
|
|
158
285
|
})
|
|
159
286
|
|
|
160
|
-
test('behavior:
|
|
287
|
+
test('behavior: capabilities and key hints are carried', () => {
|
|
161
288
|
const request = TransactionRequest.toRpc({
|
|
162
289
|
calls: [{ to: '0xcafebabecafebabecafebabecafebabecafebabe' }],
|
|
163
290
|
capabilities: { balanceDiffs: true },
|
|
@@ -165,30 +292,72 @@ describe('toRpc', () => {
|
|
|
165
292
|
keyData: '0x0578',
|
|
166
293
|
keyId: '0xcccccccccccccccccccccccccccccccccccccccc',
|
|
167
294
|
keyType: 'webAuthn',
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
295
|
+
})
|
|
296
|
+
expect(request).toMatchInlineSnapshot(`
|
|
297
|
+
{
|
|
298
|
+
"calls": [
|
|
172
299
|
{
|
|
173
|
-
|
|
174
|
-
|
|
300
|
+
"data": "0x",
|
|
301
|
+
"to": "0xcafebabecafebabecafebabecafebabecafebabe",
|
|
302
|
+
"value": "0x",
|
|
175
303
|
},
|
|
304
|
+
],
|
|
305
|
+
"capabilities": {
|
|
306
|
+
"balanceDiffs": true,
|
|
307
|
+
},
|
|
308
|
+
"feePayer": false,
|
|
309
|
+
"keyData": "0x0578",
|
|
310
|
+
"keyId": "0xcccccccccccccccccccccccccccccccccccccccc",
|
|
311
|
+
"keyType": "webAuthn",
|
|
312
|
+
"type": "0x76",
|
|
313
|
+
}
|
|
314
|
+
`)
|
|
315
|
+
})
|
|
316
|
+
|
|
317
|
+
test('behavior: multisig simulation', () => {
|
|
318
|
+
const request = TransactionRequest.toRpc({
|
|
319
|
+
from: '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
|
|
320
|
+
multisigSimulation,
|
|
321
|
+
})
|
|
322
|
+
|
|
323
|
+
expect(request).toMatchInlineSnapshot(`
|
|
324
|
+
{
|
|
325
|
+
"calls": [
|
|
176
326
|
{
|
|
177
|
-
|
|
178
|
-
|
|
327
|
+
"data": "0x",
|
|
328
|
+
"to": "0x0000000000000000000000000000000000000000",
|
|
329
|
+
"value": "0x",
|
|
179
330
|
},
|
|
180
331
|
],
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
332
|
+
"from": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
|
333
|
+
"multisigSimulation": {
|
|
334
|
+
"account": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
|
335
|
+
"approvals": [
|
|
336
|
+
{
|
|
337
|
+
"keyType": "secp256k1",
|
|
338
|
+
"owner": "0x1111111111111111111111111111111111111111",
|
|
339
|
+
"type": "primitive",
|
|
340
|
+
},
|
|
341
|
+
{
|
|
342
|
+
"spec": {
|
|
343
|
+
"account": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
|
|
344
|
+
"approvals": [
|
|
345
|
+
{
|
|
346
|
+
"keyData": "0x0578",
|
|
347
|
+
"keyType": "webAuthn",
|
|
348
|
+
"owner": "0x2222222222222222222222222222222222222222",
|
|
349
|
+
},
|
|
350
|
+
],
|
|
351
|
+
"config": "0xf83ba022222222222222222222222222222222222222222222222222222222222222220101d7d694222222222222222222222222222222222222222201",
|
|
352
|
+
},
|
|
353
|
+
"type": "multisig",
|
|
354
|
+
},
|
|
355
|
+
],
|
|
356
|
+
"config": "0xf852a011111111111111111111111111111111111111111111111111111111111111118002eed694111111111111111111111111111111111111111101d694bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb01",
|
|
357
|
+
},
|
|
358
|
+
"type": "0x76",
|
|
359
|
+
}
|
|
360
|
+
`)
|
|
192
361
|
})
|
|
193
362
|
|
|
194
363
|
test('behavior: key data longer than 4 bytes shims into a length hint', () => {
|
|
@@ -288,6 +457,7 @@ describe('roundtrip', () => {
|
|
|
288
457
|
nonceKey: 255n,
|
|
289
458
|
gas: 100000n,
|
|
290
459
|
maxFeePerGas: 1000000000n,
|
|
460
|
+
multisigSimulation,
|
|
291
461
|
}
|
|
292
462
|
|
|
293
463
|
const rpc = TransactionRequest.toRpc(original)
|
|
@@ -308,6 +478,7 @@ describe('roundtrip', () => {
|
|
|
308
478
|
expect(converted.nonceKey).toBe(original.nonceKey)
|
|
309
479
|
expect(converted.gas).toBe(original.gas)
|
|
310
480
|
expect(converted.maxFeePerGas).toBe(original.maxFeePerGas)
|
|
481
|
+
expect(converted.multisigSimulation).toEqual(original.multisigSimulation)
|
|
311
482
|
expect(converted.type).toBe('tempo')
|
|
312
483
|
})
|
|
313
484
|
|
|
@@ -325,6 +496,7 @@ describe('roundtrip', () => {
|
|
|
325
496
|
validAfter: '0x32',
|
|
326
497
|
nonceKey: '0xff',
|
|
327
498
|
gas: '0x186a0',
|
|
499
|
+
multisigSimulation: multisigSimulationRpc,
|
|
328
500
|
type: '0x76',
|
|
329
501
|
}
|
|
330
502
|
|
|
@@ -337,6 +509,7 @@ describe('roundtrip', () => {
|
|
|
337
509
|
expect(rpc.validAfter).toBe(original.validAfter)
|
|
338
510
|
expect(rpc.nonceKey).toBe(original.nonceKey)
|
|
339
511
|
expect(rpc.gas).toBe(original.gas)
|
|
512
|
+
expect(rpc.multisigSimulation).toEqual(original.multisigSimulation)
|
|
340
513
|
expect(rpc.type).toBe('0x76')
|
|
341
514
|
})
|
|
342
515
|
})
|
|
@@ -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
|
|
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'
|
|
@@ -15,13 +15,6 @@ import type { Call } from './TxEnvelopeTempo.js'
|
|
|
15
15
|
|
|
16
16
|
type KeyType = 'secp256k1' | 'p256' | 'webAuthn'
|
|
17
17
|
|
|
18
|
-
/**
|
|
19
|
-
* Bootstrap multisig config hint for node-side gas modeling (TIP-1061).
|
|
20
|
-
* The node prices multisig gas from it during simulation, and ignores it
|
|
21
|
-
* for registered senders.
|
|
22
|
-
*/
|
|
23
|
-
export type MultisigInit = Compute<MultisigConfig.Config & { salt: Hex.Hex }>
|
|
24
|
-
|
|
25
18
|
/**
|
|
26
19
|
* A Transaction Request that is generic to all transaction types.
|
|
27
20
|
*
|
|
@@ -44,19 +37,18 @@ export type TransactionRequest<
|
|
|
44
37
|
| undefined
|
|
45
38
|
calls?: readonly Call<bigintType>[] | undefined
|
|
46
39
|
capabilities?: Record<string, unknown> | undefined
|
|
40
|
+
feePayer?: boolean | undefined
|
|
47
41
|
feePayerSignature?: Signature.Signature<true, numberType> | null | undefined
|
|
42
|
+
feeToken?: Address.Address | undefined
|
|
48
43
|
keyAuthorization?: KeyAuthorization.KeyAuthorization<true> | undefined
|
|
49
44
|
keyData?: Hex.Hex | undefined
|
|
50
45
|
keyId?: Address.Address | undefined
|
|
51
46
|
keyType?: KeyType | undefined
|
|
52
|
-
|
|
53
|
-
feeToken?: Address.Address | undefined
|
|
54
|
-
multisigInit?: MultisigInit | undefined
|
|
55
|
-
multisigSignatureCount?: number | undefined
|
|
47
|
+
multisigSimulation?: MultisigSimulation.Spec | undefined
|
|
56
48
|
nonceKey?: 'random' | bigintType | undefined
|
|
57
49
|
signature?: SignatureEnvelope.SignatureEnvelope<numberType> | undefined
|
|
58
|
-
validBefore?: numberType | undefined
|
|
59
50
|
validAfter?: numberType | undefined
|
|
51
|
+
validBefore?: numberType | undefined
|
|
60
52
|
}
|
|
61
53
|
>
|
|
62
54
|
|
|
@@ -67,12 +59,14 @@ export type Rpc = Omit<
|
|
|
67
59
|
| 'feePayerSignature'
|
|
68
60
|
| 'feeToken'
|
|
69
61
|
| 'keyAuthorization'
|
|
62
|
+
| 'multisigSimulation'
|
|
70
63
|
| 'signature'
|
|
71
64
|
> & {
|
|
72
65
|
authorizationList?: AuthorizationTempo.ListRpc | undefined
|
|
73
66
|
feePayerSignature?: Signature.Rpc | null | undefined
|
|
74
67
|
feeToken?: Hex.Hex | undefined
|
|
75
68
|
keyAuthorization?: KeyAuthorization.Rpc | undefined
|
|
69
|
+
multisigSimulation?: MultisigSimulation.Rpc | undefined
|
|
76
70
|
nonceKey?: Hex.Hex | undefined
|
|
77
71
|
signature?: SignatureEnvelope.SignatureEnvelopeRpc | undefined
|
|
78
72
|
}
|
|
@@ -100,7 +94,7 @@ export type Rpc = Omit<
|
|
|
100
94
|
* @returns A transaction request.
|
|
101
95
|
*/
|
|
102
96
|
export function fromRpc(request: Rpc): TransactionRequest {
|
|
103
|
-
const { authorizationList: _, ...rest } = request
|
|
97
|
+
const { authorizationList: _, multisigSimulation: __, ...rest } = request
|
|
104
98
|
const request_ = ox_TransactionRequest.fromRpc(
|
|
105
99
|
rest as any,
|
|
106
100
|
) as TransactionRequest
|
|
@@ -135,6 +129,10 @@ export function fromRpc(request: Rpc): TransactionRequest {
|
|
|
135
129
|
request_.keyAuthorization = KeyAuthorization.fromRpc(
|
|
136
130
|
request.keyAuthorization,
|
|
137
131
|
)
|
|
132
|
+
if (request.multisigSimulation)
|
|
133
|
+
request_.multisigSimulation = MultisigSimulation.fromRpc(
|
|
134
|
+
request.multisigSimulation,
|
|
135
|
+
)
|
|
138
136
|
if (typeof request.validBefore !== 'undefined')
|
|
139
137
|
request_.validBefore = Hex.toNumber(request.validBefore as Hex.Hex)
|
|
140
138
|
if (typeof request.validAfter !== 'undefined')
|
|
@@ -150,6 +148,7 @@ export declare namespace fromRpc {
|
|
|
150
148
|
| AuthorizationTempo.fromRpcList.ErrorType
|
|
151
149
|
| Hex.toNumber.ErrorType
|
|
152
150
|
| Hex.toBigInt.ErrorType
|
|
151
|
+
| MultisigSimulation.fromRpc.ErrorType
|
|
153
152
|
| Errors.GlobalErrorType
|
|
154
153
|
}
|
|
155
154
|
|
|
@@ -223,8 +222,7 @@ export function toRpc(request: toRpc.Input): Rpc {
|
|
|
223
222
|
typeof request.keyData !== 'undefined' ||
|
|
224
223
|
typeof request.keyId !== 'undefined' ||
|
|
225
224
|
typeof request.keyType !== 'undefined' ||
|
|
226
|
-
typeof request.
|
|
227
|
-
typeof request.multisigSignatureCount !== 'undefined' ||
|
|
225
|
+
typeof request.multisigSimulation !== 'undefined' ||
|
|
228
226
|
typeof request.nonceKey !== 'undefined' ||
|
|
229
227
|
typeof request.validBefore !== 'undefined' ||
|
|
230
228
|
typeof request.validAfter !== 'undefined' ||
|
|
@@ -274,10 +272,10 @@ export function toRpc(request: toRpc.Input): Rpc {
|
|
|
274
272
|
if (typeof request.keyId !== 'undefined') request_rpc.keyId = request.keyId
|
|
275
273
|
if (typeof request.keyType !== 'undefined')
|
|
276
274
|
request_rpc.keyType = request.keyType
|
|
277
|
-
if (typeof request.
|
|
278
|
-
request_rpc.
|
|
279
|
-
|
|
280
|
-
|
|
275
|
+
if (typeof request.multisigSimulation !== 'undefined')
|
|
276
|
+
request_rpc.multisigSimulation = MultisigSimulation.toRpc(
|
|
277
|
+
request.multisigSimulation,
|
|
278
|
+
)
|
|
281
279
|
if (typeof request.validBefore !== 'undefined')
|
|
282
280
|
request_rpc.validBefore = Quantity.fromNumberish(request.validBefore)
|
|
283
281
|
if (typeof request.validAfter !== 'undefined')
|
|
@@ -312,6 +310,7 @@ export declare namespace toRpc {
|
|
|
312
310
|
export type ErrorType =
|
|
313
311
|
| AuthorizationTempo.toRpcList.ErrorType
|
|
314
312
|
| Hex.fromNumber.ErrorType
|
|
313
|
+
| MultisigSimulation.toRpc.ErrorType
|
|
315
314
|
| Errors.GlobalErrorType
|
|
316
315
|
}
|
|
317
316
|
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { expectTypeOf, test } from 'vp/test'
|
|
2
|
+
import type * as TxEnvelopeTempo from './TxEnvelopeTempo.js'
|
|
3
|
+
|
|
4
|
+
test('Serialized', () => {
|
|
5
|
+
expectTypeOf<'0x76'>().toExtend<TxEnvelopeTempo.Serialized>()
|
|
6
|
+
expectTypeOf<'0x78'>().toExtend<TxEnvelopeTempo.Serialized>()
|
|
7
|
+
})
|
|
@@ -138,6 +138,31 @@ describe('deserialize', () => {
|
|
|
138
138
|
expect(deserialized).toEqual(transaction)
|
|
139
139
|
})
|
|
140
140
|
|
|
141
|
+
test('fee payer', () => {
|
|
142
|
+
const serialized = TxEnvelopeTempo.serialize(transaction, {
|
|
143
|
+
format: 'feePayer',
|
|
144
|
+
sender: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
expect(TxEnvelopeTempo.deserialize(serialized)).toMatchInlineSnapshot(`
|
|
148
|
+
{
|
|
149
|
+
"calls": [
|
|
150
|
+
{
|
|
151
|
+
"to": "0x70997970c51812dc3a010c7d01b50e0d17dc79c8",
|
|
152
|
+
},
|
|
153
|
+
],
|
|
154
|
+
"chainId": 1,
|
|
155
|
+
"feePayerSignature": null,
|
|
156
|
+
"from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266",
|
|
157
|
+
"maxFeePerGas": 2000000000n,
|
|
158
|
+
"maxPriorityFeePerGas": 2000000000n,
|
|
159
|
+
"nonce": 785n,
|
|
160
|
+
"nonceKey": 0n,
|
|
161
|
+
"type": "tempo",
|
|
162
|
+
}
|
|
163
|
+
`)
|
|
164
|
+
})
|
|
165
|
+
|
|
141
166
|
test('minimal', () => {
|
|
142
167
|
const transaction = TxEnvelopeTempo.from({
|
|
143
168
|
chainId: 1,
|
|
@@ -134,7 +134,8 @@ export type Rpc<signed extends boolean = boolean> = TxEnvelopeTempo<
|
|
|
134
134
|
export const feePayerMagic = '0x78' as const
|
|
135
135
|
export type FeePayerMagic = typeof feePayerMagic
|
|
136
136
|
|
|
137
|
-
|
|
137
|
+
/** Serialized standard or fee-payer Tempo transaction. */
|
|
138
|
+
export type Serialized = `${SerializedType | FeePayerMagic}${string}`
|
|
138
139
|
|
|
139
140
|
export type Signed = TxEnvelopeTempo<true>
|
|
140
141
|
|
|
@@ -232,7 +233,7 @@ export declare namespace assert {
|
|
|
232
233
|
}
|
|
233
234
|
|
|
234
235
|
/**
|
|
235
|
-
* Deserializes a {@link ox#TxEnvelopeTempo.TxEnvelopeTempo}
|
|
236
|
+
* Deserializes a standard or fee-payer {@link ox#TxEnvelopeTempo.TxEnvelopeTempo}.
|
|
236
237
|
*
|
|
237
238
|
* @example
|
|
238
239
|
* ```ts twoslash
|
|
@@ -254,7 +255,8 @@ export declare namespace assert {
|
|
|
254
255
|
* @returns Deserialized Transaction Envelope.
|
|
255
256
|
*/
|
|
256
257
|
export function deserialize(serialized: Serialized): Compute<TxEnvelopeTempo> {
|
|
257
|
-
|
|
258
|
+
const prefix = Hex.slice(serialized, 0, 1)
|
|
259
|
+
if (prefix !== serializedType && prefix !== feePayerMagic)
|
|
258
260
|
throw new TransactionEnvelope.InvalidSerializedError({
|
|
259
261
|
attributes: {},
|
|
260
262
|
serialized,
|
package/src/tempo/index.ts
CHANGED
|
@@ -173,6 +173,24 @@ export * as KeyAuthorization from './KeyAuthorization.js'
|
|
|
173
173
|
* @category Reference
|
|
174
174
|
*/
|
|
175
175
|
export * as MultisigConfig from './MultisigConfig.js'
|
|
176
|
+
/**
|
|
177
|
+
* Offchain multisig transaction and key authorization operation utilities.
|
|
178
|
+
*
|
|
179
|
+
* Derives operation hashes, selects owner approvals, serializes transactions,
|
|
180
|
+
* validates operation state, and converts JSON-RPC representations.
|
|
181
|
+
*
|
|
182
|
+
* @category Reference
|
|
183
|
+
*/
|
|
184
|
+
export * as MultisigOperation from './MultisigOperation.js'
|
|
185
|
+
/**
|
|
186
|
+
* Native multisig RPC simulation utilities.
|
|
187
|
+
*
|
|
188
|
+
* Converts complete root and nested owner specs between their domain and Tempo
|
|
189
|
+
* JSON-RPC representations.
|
|
190
|
+
*
|
|
191
|
+
* @category Reference
|
|
192
|
+
*/
|
|
193
|
+
export * as MultisigSimulation from './MultisigSimulation.js'
|
|
176
194
|
/**
|
|
177
195
|
* Utilities for constructing period durations (in seconds) for recurring spending limits.
|
|
178
196
|
*
|
|
@@ -251,7 +269,7 @@ export * as PoolId from './PoolId.js'
|
|
|
251
269
|
*/
|
|
252
270
|
export * as ReceivePolicyReceipt from './ReceivePolicyReceipt.js'
|
|
253
271
|
/**
|
|
254
|
-
*
|
|
272
|
+
* JSON-RPC schemas for the `tempo_` and `multisig_` namespaces.
|
|
255
273
|
*
|
|
256
274
|
* @example
|
|
257
275
|
* ```ts twoslash
|
|
@@ -260,7 +278,9 @@ export * as ReceivePolicyReceipt from './ReceivePolicyReceipt.js'
|
|
|
260
278
|
* import { RpcSchemaTempo } from 'ox/tempo'
|
|
261
279
|
*
|
|
262
280
|
* const schema = RpcSchema.from<
|
|
263
|
-
* RpcSchema.Default
|
|
281
|
+
* | RpcSchema.Default
|
|
282
|
+
* | RpcSchemaTempo.Multisig
|
|
283
|
+
* | RpcSchemaTempo.Tempo
|
|
264
284
|
* >()
|
|
265
285
|
*
|
|
266
286
|
* const provider = Provider.from(window.ethereum!, { schema })
|