ox 1.0.0-beta.0 → 1.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/Provider.d.ts +7 -7
- package/dist/core/Provider.d.ts.map +1 -1
- package/dist/core/RpcSchema.d.ts +50 -0
- package/dist/core/RpcSchema.d.ts.map +1 -1
- package/dist/core/RpcSchema.js.map +1 -1
- package/dist/core/RpcTransport.d.ts +2 -2
- package/dist/core/RpcTransport.d.ts.map +1 -1
- package/dist/core/RpcTransport.js.map +1 -1
- package/dist/core/internal/rpcTransport.d.ts +1 -1
- package/dist/core/internal/rpcTransport.d.ts.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/tempo/MultisigConfig.d.ts +79 -16
- package/dist/tempo/MultisigConfig.d.ts.map +1 -1
- package/dist/tempo/MultisigConfig.js +69 -11
- package/dist/tempo/MultisigConfig.js.map +1 -1
- package/dist/tempo/SignatureEnvelope.d.ts +83 -19
- package/dist/tempo/SignatureEnvelope.d.ts.map +1 -1
- package/dist/tempo/SignatureEnvelope.js +99 -30
- package/dist/tempo/SignatureEnvelope.js.map +1 -1
- package/dist/tempo/index.d.ts +2 -2
- package/dist/tempo/index.js +2 -2
- package/dist/zod/RpcSchema.d.ts +144 -25
- package/dist/zod/RpcSchema.d.ts.map +1 -1
- package/dist/zod/RpcSchema.js +85 -13
- package/dist/zod/RpcSchema.js.map +1 -1
- package/dist/zod/internal/rpcSchemas/Eth.d.ts +12 -12
- package/dist/zod/internal/rpcSchemas/Eth.d.ts.map +1 -1
- package/dist/zod/internal/rpcSchemas/Eth.js +14 -12
- package/dist/zod/internal/rpcSchemas/Eth.js.map +1 -1
- package/dist/zod/tempo/AuthorizationTempo.d.ts +6 -6
- package/dist/zod/tempo/KeyAuthorization.d.ts +3 -3
- package/dist/zod/tempo/RpcSchemaTempo.d.ts +6 -6
- package/dist/zod/tempo/SignatureEnvelope.d.ts +3 -3
- package/dist/zod/tempo/SignatureEnvelope.js +1 -1
- package/dist/zod/tempo/SignatureEnvelope.js.map +1 -1
- package/dist/zod/tempo/Transaction.d.ts +6 -6
- package/dist/zod/tempo/TransactionRequest.d.ts +6 -6
- package/dist/zod/tempo/TxEnvelopeTempo.d.ts +9 -9
- package/dist/zod/tempo/ZoneRpcAuthentication.d.ts +3 -3
- package/package.json +1 -1
- package/src/CHANGELOG.md +6 -0
- package/src/core/Provider.ts +7 -7
- package/src/core/RpcSchema.ts +60 -0
- package/src/core/RpcTransport.ts +7 -4
- package/src/core/_test/Provider.test-d.ts +21 -0
- package/src/core/_test/RpcSchema.test-d.ts +87 -1
- package/src/core/_test/RpcTransport.test-d.ts +43 -0
- package/src/core/internal/rpcTransport.ts +1 -1
- package/src/index.ts +2 -0
- package/src/tempo/MultisigConfig.test.ts +21 -12
- package/src/tempo/MultisigConfig.ts +103 -18
- package/src/tempo/SignatureEnvelope.test.ts +124 -26
- package/src/tempo/SignatureEnvelope.ts +150 -48
- package/src/tempo/e2e.test.ts +42 -47
- package/src/tempo/index.ts +2 -2
- package/src/version.ts +1 -1
- package/src/zod/RpcSchema.ts +190 -13
- package/src/zod/_test/RpcSchema.test-d.ts +53 -6
- package/src/zod/_test/RpcSchema.test.ts +138 -18
- package/src/zod/internal/rpcSchemas/Eth.ts +14 -12
- package/src/zod/tempo/SignatureEnvelope.ts +1 -1
- package/src/zod/tempo/_test/RpcSchemaTempo.test.ts +1 -1
- package/src/zod/tempo/_test/SignatureEnvelope.test.ts +23 -0
package/src/tempo/e2e.test.ts
CHANGED
|
@@ -87,6 +87,7 @@ test('behavior: default (secp256k1)', async () => {
|
|
|
87
87
|
from,
|
|
88
88
|
keyAuthorization: __,
|
|
89
89
|
nonce,
|
|
90
|
+
gasPrice,
|
|
90
91
|
maxFeePerGas,
|
|
91
92
|
maxPriorityFeePerGas,
|
|
92
93
|
signature,
|
|
@@ -100,6 +101,7 @@ test('behavior: default (secp256k1)', async () => {
|
|
|
100
101
|
expect(chainId).toBe(chainId)
|
|
101
102
|
expect(hash).toBe(receipt.transactionHash)
|
|
102
103
|
expect(from).toBe(address)
|
|
104
|
+
expect(gasPrice).toBeDefined()
|
|
103
105
|
expect(maxFeePerGas).toBeDefined()
|
|
104
106
|
expect(maxPriorityFeePerGas).toBeDefined()
|
|
105
107
|
expect(nonce).toBeDefined()
|
|
@@ -119,7 +121,6 @@ test('behavior: default (secp256k1)', async () => {
|
|
|
119
121
|
"data": undefined,
|
|
120
122
|
"feePayerSignature": null,
|
|
121
123
|
"gas": 500000n,
|
|
122
|
-
"gasPrice": 20000000000n,
|
|
123
124
|
"nonceKey": 0n,
|
|
124
125
|
"type": "tempo",
|
|
125
126
|
"validAfter": null,
|
|
@@ -133,6 +134,7 @@ test('behavior: default (secp256k1)', async () => {
|
|
|
133
134
|
blockNumber,
|
|
134
135
|
blockHash,
|
|
135
136
|
cumulativeGasUsed,
|
|
137
|
+
effectiveGasPrice,
|
|
136
138
|
feePayer,
|
|
137
139
|
feeToken: _,
|
|
138
140
|
from,
|
|
@@ -147,6 +149,7 @@ test('behavior: default (secp256k1)', async () => {
|
|
|
147
149
|
expect(blockNumber).toBeDefined()
|
|
148
150
|
expect(blockHash).toBeDefined()
|
|
149
151
|
expect(cumulativeGasUsed).toBeDefined()
|
|
152
|
+
expect(effectiveGasPrice).toBeDefined()
|
|
150
153
|
expect(feePayer).toBeDefined()
|
|
151
154
|
expect(from).toBe(address)
|
|
152
155
|
expect(gasUsed).toBeDefined()
|
|
@@ -159,7 +162,6 @@ test('behavior: default (secp256k1)', async () => {
|
|
|
159
162
|
"blobGasPrice": undefined,
|
|
160
163
|
"blobGasUsed": undefined,
|
|
161
164
|
"contractAddress": null,
|
|
162
|
-
"effectiveGasPrice": 20000000000n,
|
|
163
165
|
"status": "success",
|
|
164
166
|
"to": "0x0000000000000000000000000000000000000000",
|
|
165
167
|
"type": "0x76",
|
|
@@ -298,6 +300,7 @@ test('behavior: default (p256)', async () => {
|
|
|
298
300
|
keyAuthorization: __,
|
|
299
301
|
hash,
|
|
300
302
|
nonce,
|
|
303
|
+
gasPrice,
|
|
301
304
|
maxFeePerGas,
|
|
302
305
|
maxPriorityFeePerGas,
|
|
303
306
|
signature,
|
|
@@ -312,6 +315,7 @@ test('behavior: default (p256)', async () => {
|
|
|
312
315
|
expect(from).toBe(address)
|
|
313
316
|
expect(hash).toBe(receipt.transactionHash)
|
|
314
317
|
expect(nonce).toBeDefined()
|
|
318
|
+
expect(gasPrice).toBeDefined()
|
|
315
319
|
expect(maxFeePerGas).toBeDefined()
|
|
316
320
|
expect(maxPriorityFeePerGas).toBeDefined()
|
|
317
321
|
expect(signature).toBeDefined()
|
|
@@ -330,7 +334,6 @@ test('behavior: default (p256)', async () => {
|
|
|
330
334
|
"data": undefined,
|
|
331
335
|
"feePayerSignature": null,
|
|
332
336
|
"gas": 500000n,
|
|
333
|
-
"gasPrice": 20000000000n,
|
|
334
337
|
"nonceKey": 0n,
|
|
335
338
|
"type": "tempo",
|
|
336
339
|
"validAfter": null,
|
|
@@ -344,6 +347,7 @@ test('behavior: default (p256)', async () => {
|
|
|
344
347
|
blockNumber,
|
|
345
348
|
blockHash,
|
|
346
349
|
cumulativeGasUsed,
|
|
350
|
+
effectiveGasPrice,
|
|
347
351
|
feePayer,
|
|
348
352
|
feeToken: _,
|
|
349
353
|
from,
|
|
@@ -358,6 +362,7 @@ test('behavior: default (p256)', async () => {
|
|
|
358
362
|
expect(blockNumber).toBeDefined()
|
|
359
363
|
expect(blockHash).toBeDefined()
|
|
360
364
|
expect(cumulativeGasUsed).toBeDefined()
|
|
365
|
+
expect(effectiveGasPrice).toBeDefined()
|
|
361
366
|
expect(feePayer).toBeDefined()
|
|
362
367
|
expect(from).toBe(address)
|
|
363
368
|
expect(gasUsed).toBeDefined()
|
|
@@ -370,7 +375,6 @@ test('behavior: default (p256)', async () => {
|
|
|
370
375
|
"blobGasPrice": undefined,
|
|
371
376
|
"blobGasUsed": undefined,
|
|
372
377
|
"contractAddress": null,
|
|
373
|
-
"effectiveGasPrice": 20000000000n,
|
|
374
378
|
"status": "success",
|
|
375
379
|
"to": "0x0000000000000000000000000000000000000000",
|
|
376
380
|
"type": "0x76",
|
|
@@ -441,6 +445,7 @@ test('behavior: default (p256 - webcrypto)', async () => {
|
|
|
441
445
|
keyAuthorization: __,
|
|
442
446
|
hash,
|
|
443
447
|
nonce,
|
|
448
|
+
gasPrice,
|
|
444
449
|
maxFeePerGas,
|
|
445
450
|
maxPriorityFeePerGas,
|
|
446
451
|
signature,
|
|
@@ -455,6 +460,7 @@ test('behavior: default (p256 - webcrypto)', async () => {
|
|
|
455
460
|
expect(from).toBeDefined()
|
|
456
461
|
expect(hash).toBe(receipt.transactionHash)
|
|
457
462
|
expect(nonce).toBeDefined()
|
|
463
|
+
expect(gasPrice).toBeDefined()
|
|
458
464
|
expect(maxFeePerGas).toBeDefined()
|
|
459
465
|
expect(maxPriorityFeePerGas).toBeDefined()
|
|
460
466
|
expect(signature).toBeDefined()
|
|
@@ -473,7 +479,6 @@ test('behavior: default (p256 - webcrypto)', async () => {
|
|
|
473
479
|
"data": undefined,
|
|
474
480
|
"feePayerSignature": null,
|
|
475
481
|
"gas": 500000n,
|
|
476
|
-
"gasPrice": 20000000000n,
|
|
477
482
|
"nonceKey": 0n,
|
|
478
483
|
"type": "tempo",
|
|
479
484
|
"validAfter": null,
|
|
@@ -487,6 +492,7 @@ test('behavior: default (p256 - webcrypto)', async () => {
|
|
|
487
492
|
blockNumber,
|
|
488
493
|
blockHash,
|
|
489
494
|
cumulativeGasUsed,
|
|
495
|
+
effectiveGasPrice,
|
|
490
496
|
feePayer,
|
|
491
497
|
feeToken: _,
|
|
492
498
|
from,
|
|
@@ -501,6 +507,7 @@ test('behavior: default (p256 - webcrypto)', async () => {
|
|
|
501
507
|
expect(blockNumber).toBeDefined()
|
|
502
508
|
expect(blockHash).toBeDefined()
|
|
503
509
|
expect(cumulativeGasUsed).toBeDefined()
|
|
510
|
+
expect(effectiveGasPrice).toBeDefined()
|
|
504
511
|
expect(feePayer).toBeDefined()
|
|
505
512
|
expect(from).toBeDefined()
|
|
506
513
|
expect(gasUsed).toBeDefined()
|
|
@@ -513,7 +520,6 @@ test('behavior: default (p256 - webcrypto)', async () => {
|
|
|
513
520
|
"blobGasPrice": undefined,
|
|
514
521
|
"blobGasUsed": undefined,
|
|
515
522
|
"contractAddress": null,
|
|
516
|
-
"effectiveGasPrice": 20000000000n,
|
|
517
523
|
"status": "success",
|
|
518
524
|
"to": "0x0000000000000000000000000000000000000000",
|
|
519
525
|
"type": "0x76",
|
|
@@ -591,6 +597,7 @@ test('behavior: default (webauthn)', async () => {
|
|
|
591
597
|
keyAuthorization: __,
|
|
592
598
|
hash,
|
|
593
599
|
nonce,
|
|
600
|
+
gasPrice,
|
|
594
601
|
maxFeePerGas,
|
|
595
602
|
maxPriorityFeePerGas,
|
|
596
603
|
transactionIndex,
|
|
@@ -605,6 +612,7 @@ test('behavior: default (webauthn)', async () => {
|
|
|
605
612
|
expect(from).toBeDefined()
|
|
606
613
|
expect(hash).toBe(receipt.transactionHash)
|
|
607
614
|
expect(nonce).toBeDefined()
|
|
615
|
+
expect(gasPrice).toBeDefined()
|
|
608
616
|
expect(maxFeePerGas).toBeDefined()
|
|
609
617
|
expect(maxPriorityFeePerGas).toBeDefined()
|
|
610
618
|
expect(signature).toBeDefined()
|
|
@@ -623,7 +631,6 @@ test('behavior: default (webauthn)', async () => {
|
|
|
623
631
|
"data": undefined,
|
|
624
632
|
"feePayerSignature": null,
|
|
625
633
|
"gas": 500000n,
|
|
626
|
-
"gasPrice": 20000000000n,
|
|
627
634
|
"nonceKey": 0n,
|
|
628
635
|
"type": "tempo",
|
|
629
636
|
"validAfter": null,
|
|
@@ -637,6 +644,7 @@ test('behavior: default (webauthn)', async () => {
|
|
|
637
644
|
blockNumber,
|
|
638
645
|
blockHash,
|
|
639
646
|
cumulativeGasUsed,
|
|
647
|
+
effectiveGasPrice,
|
|
640
648
|
feePayer,
|
|
641
649
|
feeToken: _,
|
|
642
650
|
from,
|
|
@@ -651,6 +659,7 @@ test('behavior: default (webauthn)', async () => {
|
|
|
651
659
|
expect(blockNumber).toBeDefined()
|
|
652
660
|
expect(blockHash).toBeDefined()
|
|
653
661
|
expect(cumulativeGasUsed).toBeDefined()
|
|
662
|
+
expect(effectiveGasPrice).toBeDefined()
|
|
654
663
|
expect(feePayer).toBeDefined()
|
|
655
664
|
expect(from).toBe(address)
|
|
656
665
|
expect(gasUsed).toBeDefined()
|
|
@@ -663,7 +672,6 @@ test('behavior: default (webauthn)', async () => {
|
|
|
663
672
|
"blobGasPrice": undefined,
|
|
664
673
|
"blobGasUsed": undefined,
|
|
665
674
|
"contractAddress": null,
|
|
666
|
-
"effectiveGasPrice": 20000000000n,
|
|
667
675
|
"status": "success",
|
|
668
676
|
"to": "0x0000000000000000000000000000000000000000",
|
|
669
677
|
"type": "0x76",
|
|
@@ -745,6 +753,7 @@ test('behavior: feePayerSignature (user → feePayer)', async () => {
|
|
|
745
753
|
blockNumber,
|
|
746
754
|
blockHash,
|
|
747
755
|
cumulativeGasUsed,
|
|
756
|
+
effectiveGasPrice,
|
|
748
757
|
feePayer,
|
|
749
758
|
feeToken: _,
|
|
750
759
|
from,
|
|
@@ -759,6 +768,7 @@ test('behavior: feePayerSignature (user → feePayer)', async () => {
|
|
|
759
768
|
expect(blockNumber).toBeDefined()
|
|
760
769
|
expect(blockHash).toBeDefined()
|
|
761
770
|
expect(cumulativeGasUsed).toBeDefined()
|
|
771
|
+
expect(effectiveGasPrice).toBeDefined()
|
|
762
772
|
expect(feePayer).toBe(feePayerAddress)
|
|
763
773
|
expect(from).toBe(senderAddress)
|
|
764
774
|
expect(gasUsed).toBeDefined()
|
|
@@ -771,7 +781,6 @@ test('behavior: feePayerSignature (user → feePayer)', async () => {
|
|
|
771
781
|
"blobGasPrice": undefined,
|
|
772
782
|
"blobGasUsed": undefined,
|
|
773
783
|
"contractAddress": null,
|
|
774
|
-
"effectiveGasPrice": 20000000000n,
|
|
775
784
|
"status": "success",
|
|
776
785
|
"to": "0x0000000000000000000000000000000000000000",
|
|
777
786
|
"type": "0x76",
|
|
@@ -1019,6 +1028,7 @@ describe('behavior: keyAuthorization', () => {
|
|
|
1019
1028
|
blockNumber,
|
|
1020
1029
|
blockHash,
|
|
1021
1030
|
cumulativeGasUsed,
|
|
1031
|
+
effectiveGasPrice,
|
|
1022
1032
|
feePayer,
|
|
1023
1033
|
feeToken,
|
|
1024
1034
|
from,
|
|
@@ -1033,6 +1043,7 @@ describe('behavior: keyAuthorization', () => {
|
|
|
1033
1043
|
expect(blockNumber).toBeDefined()
|
|
1034
1044
|
expect(blockHash).toBeDefined()
|
|
1035
1045
|
expect(cumulativeGasUsed).toBeDefined()
|
|
1046
|
+
expect(effectiveGasPrice).toBeDefined()
|
|
1036
1047
|
expect(feeToken).toBeDefined()
|
|
1037
1048
|
expect(feePayer).toBeDefined()
|
|
1038
1049
|
expect(gasUsed).toBeDefined()
|
|
@@ -1046,7 +1057,6 @@ describe('behavior: keyAuthorization', () => {
|
|
|
1046
1057
|
"blobGasPrice": undefined,
|
|
1047
1058
|
"blobGasUsed": undefined,
|
|
1048
1059
|
"contractAddress": null,
|
|
1049
|
-
"effectiveGasPrice": 20000000000n,
|
|
1050
1060
|
"status": "success",
|
|
1051
1061
|
"to": "0x0000000000000000000000000000000000000000",
|
|
1052
1062
|
"type": "0x76",
|
|
@@ -1238,6 +1248,7 @@ describe('behavior: keyAuthorization', () => {
|
|
|
1238
1248
|
blockNumber,
|
|
1239
1249
|
blockHash,
|
|
1240
1250
|
cumulativeGasUsed,
|
|
1251
|
+
effectiveGasPrice,
|
|
1241
1252
|
feePayer,
|
|
1242
1253
|
feeToken,
|
|
1243
1254
|
from,
|
|
@@ -1252,6 +1263,7 @@ describe('behavior: keyAuthorization', () => {
|
|
|
1252
1263
|
expect(blockNumber).toBeDefined()
|
|
1253
1264
|
expect(blockHash).toBeDefined()
|
|
1254
1265
|
expect(cumulativeGasUsed).toBeDefined()
|
|
1266
|
+
expect(effectiveGasPrice).toBeDefined()
|
|
1255
1267
|
expect(feePayer).toBeDefined()
|
|
1256
1268
|
expect(feeToken).toBeDefined()
|
|
1257
1269
|
expect(from).toBeDefined()
|
|
@@ -1265,7 +1277,6 @@ describe('behavior: keyAuthorization', () => {
|
|
|
1265
1277
|
"blobGasPrice": undefined,
|
|
1266
1278
|
"blobGasUsed": undefined,
|
|
1267
1279
|
"contractAddress": null,
|
|
1268
|
-
"effectiveGasPrice": 20000000000n,
|
|
1269
1280
|
"status": "success",
|
|
1270
1281
|
"to": "0x0000000000000000000000000000000000000000",
|
|
1271
1282
|
"type": "0x76",
|
|
@@ -3015,7 +3026,7 @@ describe.skip('behavior: multisig (TIP-1061)', () => {
|
|
|
3015
3026
|
return { address, privateKey } as const
|
|
3016
3027
|
})
|
|
3017
3028
|
|
|
3018
|
-
const
|
|
3029
|
+
const genesisConfig = MultisigConfig.from({
|
|
3019
3030
|
// A fresh random salt yields a distinct account each run, exercising the
|
|
3020
3031
|
// salt-inclusive config-ID derivation against the node.
|
|
3021
3032
|
salt: Hex.random(32),
|
|
@@ -3025,10 +3036,9 @@ describe.skip('behavior: multisig (TIP-1061)', () => {
|
|
|
3025
3036
|
weight: 1,
|
|
3026
3037
|
})),
|
|
3027
3038
|
})
|
|
3028
|
-
const
|
|
3029
|
-
const account = MultisigConfig.getAddress({ configId })
|
|
3039
|
+
const account = MultisigConfig.getAddress(genesisConfig)
|
|
3030
3040
|
|
|
3031
|
-
return { account,
|
|
3041
|
+
return { account, genesisConfig, ownerKeys } as const
|
|
3032
3042
|
}
|
|
3033
3043
|
|
|
3034
3044
|
// Signs the multisig owner digest with the provided owner keys, returning
|
|
@@ -3036,32 +3046,26 @@ describe.skip('behavior: multisig (TIP-1061)', () => {
|
|
|
3036
3046
|
// address (required by the node: "recovered owners must be strictly
|
|
3037
3047
|
// ascending").
|
|
3038
3048
|
function approve(parameters: {
|
|
3039
|
-
|
|
3040
|
-
configId: Hex.Hex
|
|
3049
|
+
genesisConfig: MultisigConfig.Config
|
|
3041
3050
|
payload: Hex.Hex
|
|
3042
3051
|
signers: readonly { privateKey: Hex.Hex }[]
|
|
3043
3052
|
}) {
|
|
3044
|
-
const {
|
|
3045
|
-
const digest = MultisigConfig.getSignPayload({
|
|
3046
|
-
account,
|
|
3047
|
-
configId,
|
|
3048
|
-
payload,
|
|
3049
|
-
})
|
|
3053
|
+
const { genesisConfig, payload, signers } = parameters
|
|
3054
|
+
const digest = MultisigConfig.getSignPayload({ payload, genesisConfig })
|
|
3050
3055
|
const signatures = signers.map((signer) =>
|
|
3051
3056
|
SignatureEnvelope.from(
|
|
3052
3057
|
Secp256k1.sign({ payload: digest, privateKey: signer.privateKey }),
|
|
3053
3058
|
),
|
|
3054
3059
|
)
|
|
3055
3060
|
return SignatureEnvelope.sortMultisigApprovals({
|
|
3056
|
-
|
|
3057
|
-
configId,
|
|
3061
|
+
genesisConfig,
|
|
3058
3062
|
payload,
|
|
3059
3063
|
signatures,
|
|
3060
3064
|
})
|
|
3061
3065
|
}
|
|
3062
3066
|
|
|
3063
3067
|
test('behavior: bootstrap + spend (2-of-3 secp256k1)', async () => {
|
|
3064
|
-
const { account,
|
|
3068
|
+
const { account, genesisConfig, ownerKeys } = setup({
|
|
3065
3069
|
count: 3,
|
|
3066
3070
|
threshold: 2,
|
|
3067
3071
|
})
|
|
@@ -3083,15 +3087,12 @@ describe.skip('behavior: multisig (TIP-1061)', () => {
|
|
|
3083
3087
|
|
|
3084
3088
|
const bootstrap_signed = TxEnvelopeTempo.serialize(bootstrap, {
|
|
3085
3089
|
signature: SignatureEnvelope.from({
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
// The bootstrap config is carried by the signature `init`.
|
|
3090
|
-
init: config,
|
|
3090
|
+
genesisConfig,
|
|
3091
|
+
// Initialize multisig.
|
|
3092
|
+
init: true,
|
|
3091
3093
|
// Approve with 2 of the 3 owners to satisfy the threshold.
|
|
3092
3094
|
signatures: approve({
|
|
3093
|
-
|
|
3094
|
-
configId,
|
|
3095
|
+
genesisConfig,
|
|
3095
3096
|
payload: TxEnvelopeTempo.getSignPayload(bootstrap),
|
|
3096
3097
|
signers: [ownerKeys[0]!, ownerKeys[1]!],
|
|
3097
3098
|
}),
|
|
@@ -3121,7 +3122,7 @@ describe.skip('behavior: multisig (TIP-1061)', () => {
|
|
|
3121
3122
|
// The bootstrap config is carried by the multisig signature `init`.
|
|
3122
3123
|
expect(
|
|
3123
3124
|
(response.signature as SignatureEnvelope.Multisig | undefined)?.init,
|
|
3124
|
-
).toEqual(
|
|
3125
|
+
).toEqual(genesisConfig)
|
|
3125
3126
|
}
|
|
3126
3127
|
|
|
3127
3128
|
// Spend (subsequent transaction): no signature `init`, nonce 1, uses the
|
|
@@ -3143,13 +3144,10 @@ describe.skip('behavior: multisig (TIP-1061)', () => {
|
|
|
3143
3144
|
|
|
3144
3145
|
const spend_signed = TxEnvelopeTempo.serialize(spend, {
|
|
3145
3146
|
signature: SignatureEnvelope.from({
|
|
3146
|
-
|
|
3147
|
-
account,
|
|
3148
|
-
configId,
|
|
3147
|
+
genesisConfig,
|
|
3149
3148
|
// A different 2-of-3 subset still authorizes the transaction.
|
|
3150
3149
|
signatures: approve({
|
|
3151
|
-
|
|
3152
|
-
configId,
|
|
3150
|
+
genesisConfig,
|
|
3153
3151
|
payload: TxEnvelopeTempo.getSignPayload(spend),
|
|
3154
3152
|
signers: [ownerKeys[1]!, ownerKeys[2]!],
|
|
3155
3153
|
}),
|
|
@@ -3168,7 +3166,7 @@ describe.skip('behavior: multisig (TIP-1061)', () => {
|
|
|
3168
3166
|
})
|
|
3169
3167
|
|
|
3170
3168
|
test('behavior: rejects below-threshold approvals', async () => {
|
|
3171
|
-
const { account,
|
|
3169
|
+
const { account, genesisConfig, ownerKeys } = setup({
|
|
3172
3170
|
count: 3,
|
|
3173
3171
|
threshold: 2,
|
|
3174
3172
|
})
|
|
@@ -3187,15 +3185,12 @@ describe.skip('behavior: multisig (TIP-1061)', () => {
|
|
|
3187
3185
|
|
|
3188
3186
|
const serialized_signed = TxEnvelopeTempo.serialize(bootstrap, {
|
|
3189
3187
|
signature: SignatureEnvelope.from({
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
// The bootstrap config is carried by the signature `init`.
|
|
3194
|
-
init: config,
|
|
3188
|
+
genesisConfig,
|
|
3189
|
+
// Opt into bootstrap: writes `genesisConfig` into the signature `init`.
|
|
3190
|
+
init: true,
|
|
3195
3191
|
// Only one approval — below the threshold of 2.
|
|
3196
3192
|
signatures: approve({
|
|
3197
|
-
|
|
3198
|
-
configId,
|
|
3193
|
+
genesisConfig,
|
|
3199
3194
|
payload: TxEnvelopeTempo.getSignPayload(bootstrap),
|
|
3200
3195
|
signers: [ownerKeys[0]!],
|
|
3201
3196
|
}),
|
package/src/tempo/index.ts
CHANGED
|
@@ -131,7 +131,7 @@ export * as KeyAuthorization from './KeyAuthorization.js'
|
|
|
131
131
|
* ```ts twoslash
|
|
132
132
|
* import { MultisigConfig } from 'ox/tempo'
|
|
133
133
|
*
|
|
134
|
-
* const
|
|
134
|
+
* const genesisConfig = MultisigConfig.from({
|
|
135
135
|
* threshold: 2,
|
|
136
136
|
* owners: [
|
|
137
137
|
* {
|
|
@@ -145,7 +145,7 @@ export * as KeyAuthorization from './KeyAuthorization.js'
|
|
|
145
145
|
* ]
|
|
146
146
|
* })
|
|
147
147
|
*
|
|
148
|
-
* const account = MultisigConfig.getAddress(
|
|
148
|
+
* const account = MultisigConfig.getAddress(genesisConfig)
|
|
149
149
|
* ```
|
|
150
150
|
*
|
|
151
151
|
* @category Reference
|
package/src/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** @internal */
|
|
2
|
-
export const version = '1.0.0-beta.
|
|
2
|
+
export const version = '1.0.0-beta.2'
|
package/src/zod/RpcSchema.ts
CHANGED
|
@@ -1,12 +1,103 @@
|
|
|
1
1
|
import * as Errors from '../core/Errors.js'
|
|
2
2
|
import * as eth from './internal/rpcSchemas/Eth.js'
|
|
3
|
+
import { from as fromItem } from './internal/rpcSchemas/from.js'
|
|
3
4
|
import type { Item } from './internal/rpcSchemas/from.js'
|
|
4
5
|
import * as wallet from './internal/rpcSchemas/Wallet.js'
|
|
5
6
|
import * as z from 'zod/mini'
|
|
6
7
|
|
|
7
|
-
export { from } from './internal/rpcSchemas/from.js'
|
|
8
8
|
export type { Item } from './internal/rpcSchemas/from.js'
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Instantiates JSON-RPC method schema(s) from Zod `params`/`returns` schemas.
|
|
12
|
+
*
|
|
13
|
+
* Two forms are supported:
|
|
14
|
+
*
|
|
15
|
+
* - A single method `{ method, params, returns }`, returning a `RpcSchema.Item`.
|
|
16
|
+
* - A record of `{ params, returns }` keyed by method name, returning a
|
|
17
|
+
* normalized `RpcSchema.Namespace` (each method's name is taken from its key
|
|
18
|
+
* and its `request` schema is derived). The result is usable with the
|
|
19
|
+
* `RpcSchema.decode*`/`RpcSchema.encode*` methods and as a schema for
|
|
20
|
+
* `Provider`/`RpcTransport`.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ### Single Method
|
|
24
|
+
*
|
|
25
|
+
* ```ts twoslash
|
|
26
|
+
* import { z } from 'ox/zod'
|
|
27
|
+
*
|
|
28
|
+
* const eth_blockNumber = z.RpcSchema.from({
|
|
29
|
+
* method: 'eth_blockNumber',
|
|
30
|
+
* params: z.optional(z.tuple([])),
|
|
31
|
+
* returns: z.Hex.Hex
|
|
32
|
+
* })
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ### Namespace
|
|
37
|
+
*
|
|
38
|
+
* ```ts twoslash
|
|
39
|
+
* import { z } from 'ox/zod'
|
|
40
|
+
*
|
|
41
|
+
* const schema = z.RpcSchema.from({
|
|
42
|
+
* ...z.RpcSchema.Eth,
|
|
43
|
+
* abe_foo: {
|
|
44
|
+
* params: z.tuple([z.number()]),
|
|
45
|
+
* returns: z.string()
|
|
46
|
+
* }
|
|
47
|
+
* })
|
|
48
|
+
*
|
|
49
|
+
* const params = z.RpcSchema.decodeParams(
|
|
50
|
+
* schema,
|
|
51
|
+
* 'abe_foo',
|
|
52
|
+
* [123]
|
|
53
|
+
* )
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
export function from<
|
|
57
|
+
const method extends string,
|
|
58
|
+
params extends z.ZodMiniType,
|
|
59
|
+
returns extends z.ZodMiniType,
|
|
60
|
+
>(parameters: {
|
|
61
|
+
method: method
|
|
62
|
+
params: params
|
|
63
|
+
returns: returns
|
|
64
|
+
}): Item<method, params, returns>
|
|
65
|
+
export function from<const namespace extends from.Namespace>(
|
|
66
|
+
namespace: namespace,
|
|
67
|
+
): from.ReturnType<namespace>
|
|
68
|
+
// eslint-disable-next-line jsdoc-js/require-jsdoc
|
|
69
|
+
export function from(
|
|
70
|
+
input:
|
|
71
|
+
| { method?: string; params?: z.ZodMiniType; returns?: z.ZodMiniType }
|
|
72
|
+
| from.Namespace,
|
|
73
|
+
): unknown {
|
|
74
|
+
if (typeof input.method === 'string')
|
|
75
|
+
return fromItem(input as Parameters<typeof fromItem>[0])
|
|
76
|
+
return Object.fromEntries(
|
|
77
|
+
Object.entries(input as from.Namespace).map(([method, item]) => [
|
|
78
|
+
method,
|
|
79
|
+
fromItem({ method, params: item.params, returns: item.returns }),
|
|
80
|
+
]),
|
|
81
|
+
)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export declare namespace from {
|
|
85
|
+
/** A record of `{ params, returns }` Zod schemas keyed by method name. */
|
|
86
|
+
type Namespace = Record<
|
|
87
|
+
string,
|
|
88
|
+
{ params: z.ZodMiniType; returns: z.ZodMiniType }
|
|
89
|
+
>
|
|
90
|
+
|
|
91
|
+
/** The normalized `RpcSchema.Namespace` derived from a {@link from.Namespace}. */
|
|
92
|
+
type ReturnType<namespace extends Namespace> = {
|
|
93
|
+
[method in keyof namespace & string]: Item<
|
|
94
|
+
method,
|
|
95
|
+
namespace[method]['params'],
|
|
96
|
+
namespace[method]['returns']
|
|
97
|
+
>
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
10
101
|
/** A namespace of JSON-RPC method schemas, keyed by method name. */
|
|
11
102
|
export type Namespace = Record<string, Item>
|
|
12
103
|
|
|
@@ -61,13 +152,15 @@ export function parseItem<
|
|
|
61
152
|
}
|
|
62
153
|
|
|
63
154
|
/**
|
|
64
|
-
*
|
|
155
|
+
* Decodes (wire → native) the `params` for a method on a namespace. Use on the
|
|
156
|
+
* receiving side (e.g. a server) to coerce incoming wire params into their
|
|
157
|
+
* native representation.
|
|
65
158
|
*
|
|
66
159
|
* @example
|
|
67
160
|
* ```ts twoslash
|
|
68
161
|
* import { z } from 'ox/zod'
|
|
69
162
|
*
|
|
70
|
-
* const params = z.RpcSchema.
|
|
163
|
+
* const params = z.RpcSchema.decodeParams(
|
|
71
164
|
* z.RpcSchema.Eth,
|
|
72
165
|
* 'eth_getBlockByNumber',
|
|
73
166
|
* ['0x1', true]
|
|
@@ -76,7 +169,7 @@ export function parseItem<
|
|
|
76
169
|
*
|
|
77
170
|
* @throws `RpcSchema.MethodNotFoundError` if the method does not exist.
|
|
78
171
|
*/
|
|
79
|
-
export function
|
|
172
|
+
export function decodeParams<
|
|
80
173
|
const namespace extends Namespace,
|
|
81
174
|
method extends MethodName<namespace>,
|
|
82
175
|
>(
|
|
@@ -88,13 +181,44 @@ export function parseParams<
|
|
|
88
181
|
}
|
|
89
182
|
|
|
90
183
|
/**
|
|
91
|
-
*
|
|
184
|
+
* Encodes (native → wire) the `params` for a method on a namespace. Use on the
|
|
185
|
+
* sending side (e.g. a client) to serialize native params into the wire shape
|
|
186
|
+
* a JSON-RPC endpoint expects.
|
|
187
|
+
*
|
|
188
|
+
* @example
|
|
189
|
+
* ```ts twoslash
|
|
190
|
+
* import { z } from 'ox/zod'
|
|
191
|
+
*
|
|
192
|
+
* const params = z.RpcSchema.encodeParams(
|
|
193
|
+
* z.RpcSchema.Eth,
|
|
194
|
+
* 'eth_getBlockByNumber',
|
|
195
|
+
* [1n, true]
|
|
196
|
+
* )
|
|
197
|
+
* ```
|
|
198
|
+
*
|
|
199
|
+
* @throws `RpcSchema.MethodNotFoundError` if the method does not exist.
|
|
200
|
+
*/
|
|
201
|
+
export function encodeParams<
|
|
202
|
+
const namespace extends Namespace,
|
|
203
|
+
method extends MethodName<namespace>,
|
|
204
|
+
>(
|
|
205
|
+
namespace: namespace,
|
|
206
|
+
method: method,
|
|
207
|
+
params: z.output<namespace[method]['params']>,
|
|
208
|
+
): z.input<namespace[method]['params']> {
|
|
209
|
+
return z.encode(parseItem(namespace, method).params, params as never) as never
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Decodes (wire → native) the `returns` value for a method on a namespace. Use
|
|
214
|
+
* on the receiving side (e.g. a client) to coerce a wire result into its native
|
|
215
|
+
* representation.
|
|
92
216
|
*
|
|
93
217
|
* @example
|
|
94
218
|
* ```ts twoslash
|
|
95
219
|
* import { z } from 'ox/zod'
|
|
96
220
|
*
|
|
97
|
-
* const result = z.RpcSchema.
|
|
221
|
+
* const result = z.RpcSchema.decodeReturns(
|
|
98
222
|
* z.RpcSchema.Eth,
|
|
99
223
|
* 'eth_blockNumber',
|
|
100
224
|
* '0x1b4'
|
|
@@ -103,7 +227,7 @@ export function parseParams<
|
|
|
103
227
|
*
|
|
104
228
|
* @throws `RpcSchema.MethodNotFoundError` if the method does not exist.
|
|
105
229
|
*/
|
|
106
|
-
export function
|
|
230
|
+
export function decodeReturns<
|
|
107
231
|
const namespace extends Namespace,
|
|
108
232
|
method extends MethodName<namespace>,
|
|
109
233
|
>(
|
|
@@ -118,20 +242,52 @@ export function parseReturns<
|
|
|
118
242
|
}
|
|
119
243
|
|
|
120
244
|
/**
|
|
121
|
-
*
|
|
122
|
-
* a
|
|
245
|
+
* Encodes (native → wire) the `returns` value for a method on a namespace. Use
|
|
246
|
+
* on the sending side (e.g. a server) to serialize a native result into the
|
|
247
|
+
* wire shape.
|
|
123
248
|
*
|
|
124
249
|
* @example
|
|
125
250
|
* ```ts twoslash
|
|
126
251
|
* import { z } from 'ox/zod'
|
|
127
252
|
*
|
|
128
|
-
* const
|
|
253
|
+
* const result = z.RpcSchema.encodeReturns(
|
|
254
|
+
* z.RpcSchema.Eth,
|
|
255
|
+
* 'eth_blockNumber',
|
|
256
|
+
* 436n
|
|
257
|
+
* )
|
|
258
|
+
* ```
|
|
259
|
+
*
|
|
260
|
+
* @throws `RpcSchema.MethodNotFoundError` if the method does not exist.
|
|
261
|
+
*/
|
|
262
|
+
export function encodeReturns<
|
|
263
|
+
const namespace extends Namespace,
|
|
264
|
+
method extends MethodName<namespace>,
|
|
265
|
+
>(
|
|
266
|
+
namespace: namespace,
|
|
267
|
+
method: method,
|
|
268
|
+
returns: z.output<namespace[method]['returns']>,
|
|
269
|
+
): z.input<namespace[method]['returns']> {
|
|
270
|
+
return z.encode(
|
|
271
|
+
parseItem(namespace, method).returns,
|
|
272
|
+
returns as never,
|
|
273
|
+
) as never
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Decodes (wire → native) a full JSON-RPC request (`{ method, params }`)
|
|
278
|
+
* against a namespace, dispatching on `method`.
|
|
279
|
+
*
|
|
280
|
+
* @example
|
|
281
|
+
* ```ts twoslash
|
|
282
|
+
* import { z } from 'ox/zod'
|
|
283
|
+
*
|
|
284
|
+
* const request = z.RpcSchema.decodeRequest(z.RpcSchema.Eth, {
|
|
129
285
|
* method: 'eth_getBlockByNumber',
|
|
130
286
|
* params: ['0x1', true]
|
|
131
287
|
* })
|
|
132
288
|
* ```
|
|
133
289
|
*/
|
|
134
|
-
export function
|
|
290
|
+
export function decodeRequest<const namespace extends Namespace>(
|
|
135
291
|
namespace: namespace,
|
|
136
292
|
request: RequestInput<namespace>,
|
|
137
293
|
): RequestOutput<namespace> {
|
|
@@ -139,7 +295,28 @@ export function parseRequest<const namespace extends Namespace>(
|
|
|
139
295
|
}
|
|
140
296
|
|
|
141
297
|
/**
|
|
142
|
-
*
|
|
298
|
+
* Encodes (native → wire) a full JSON-RPC request (`{ method, params }`)
|
|
299
|
+
* against a namespace, dispatching on `method`.
|
|
300
|
+
*
|
|
301
|
+
* @example
|
|
302
|
+
* ```ts twoslash
|
|
303
|
+
* import { z } from 'ox/zod'
|
|
304
|
+
*
|
|
305
|
+
* const request = z.RpcSchema.encodeRequest(z.RpcSchema.Eth, {
|
|
306
|
+
* method: 'eth_getBlockByNumber',
|
|
307
|
+
* params: [1n, true]
|
|
308
|
+
* })
|
|
309
|
+
* ```
|
|
310
|
+
*/
|
|
311
|
+
export function encodeRequest<const namespace extends Namespace>(
|
|
312
|
+
namespace: namespace,
|
|
313
|
+
request: RequestOutput<namespace>,
|
|
314
|
+
): RequestInput<namespace> {
|
|
315
|
+
return z.encode(requestSchema(namespace), request as never) as never
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Alias for `RpcSchema.decodeRequest`.
|
|
143
320
|
*
|
|
144
321
|
* @example
|
|
145
322
|
* ```ts twoslash
|
|
@@ -154,7 +331,7 @@ export function parseRequest<const namespace extends Namespace>(
|
|
|
154
331
|
* })
|
|
155
332
|
* ```
|
|
156
333
|
*/
|
|
157
|
-
export const parse =
|
|
334
|
+
export const parse = decodeRequest
|
|
158
335
|
|
|
159
336
|
/** Wire (input) request envelope for a namespace. */
|
|
160
337
|
export type RequestInput<namespace extends Namespace> = {
|