ox 1.0.0-beta.9 → 1.0.1
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 +1151 -0
- package/dist/core/AbiParameters.d.ts.map +1 -1
- package/dist/core/AbiParameters.js +4 -1
- package/dist/core/AbiParameters.js.map +1 -1
- package/dist/core/Rlp.d.ts +27 -5
- package/dist/core/Rlp.d.ts.map +1 -1
- package/dist/core/Rlp.js +40 -4
- package/dist/core/Rlp.js.map +1 -1
- package/dist/core/RpcSchema.d.ts +1 -1
- package/dist/core/Siwe.d.ts +4 -4
- package/dist/core/Siwe.js +5 -5
- package/dist/core/Siwe.js.map +1 -1
- package/dist/core/internal/abiParameters.d.ts +1 -1
- package/dist/core/internal/abiParameters.d.ts.map +1 -1
- package/dist/core/internal/abiParameters.js +22 -4
- package/dist/core/internal/abiParameters.js.map +1 -1
- package/dist/core/internal/rpcSchemas/eth.d.ts +36 -0
- package/dist/core/internal/rpcSchemas/eth.d.ts.map +1 -1
- package/dist/erc4337/EntryPoint.d.ts +1072 -1
- package/dist/erc4337/EntryPoint.d.ts.map +1 -1
- package/dist/erc4337/EntryPoint.js +872 -0
- package/dist/erc4337/EntryPoint.js.map +1 -1
- package/dist/erc4337/RpcSchema.d.ts +2 -2
- package/dist/erc4337/RpcSchema.d.ts.map +1 -1
- package/dist/erc4337/UserOperation.d.ts +39 -10
- package/dist/erc4337/UserOperation.d.ts.map +1 -1
- package/dist/erc4337/UserOperation.js +62 -48
- package/dist/erc4337/UserOperation.js.map +1 -1
- package/dist/erc4337/UserOperationGas.d.ts +9 -5
- package/dist/erc4337/UserOperationGas.d.ts.map +1 -1
- package/dist/erc4337/UserOperationGas.js +17 -15
- package/dist/erc4337/UserOperationGas.js.map +1 -1
- package/dist/erc4337/UserOperationReceipt.d.ts +4 -4
- package/dist/erc4337/UserOperationReceipt.d.ts.map +1 -1
- package/dist/erc4337/UserOperationReceipt.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/tempo/Channel.d.ts +8 -14
- package/dist/tempo/Channel.d.ts.map +1 -1
- package/dist/tempo/Channel.js +4 -8
- package/dist/tempo/Channel.js.map +1 -1
- package/dist/tempo/KeyAuthorization.d.ts +5 -5
- package/dist/tempo/KeyAuthorization.d.ts.map +1 -1
- package/dist/tempo/KeyAuthorization.js +4 -4
- package/dist/tempo/KeyAuthorization.js.map +1 -1
- package/dist/tempo/MultisigConfig.d.ts +37 -85
- package/dist/tempo/MultisigConfig.d.ts.map +1 -1
- package/dist/tempo/MultisigConfig.js +39 -83
- package/dist/tempo/MultisigConfig.js.map +1 -1
- package/dist/tempo/PoolId.d.ts +8 -7
- package/dist/tempo/PoolId.d.ts.map +1 -1
- package/dist/tempo/PoolId.js +10 -6
- package/dist/tempo/PoolId.js.map +1 -1
- package/dist/tempo/SignatureEnvelope.d.ts +32 -30
- package/dist/tempo/SignatureEnvelope.d.ts.map +1 -1
- package/dist/tempo/SignatureEnvelope.js +56 -51
- package/dist/tempo/SignatureEnvelope.js.map +1 -1
- package/dist/tempo/Transaction.d.ts +16 -5
- package/dist/tempo/Transaction.d.ts.map +1 -1
- package/dist/tempo/Transaction.js +34 -7
- package/dist/tempo/Transaction.js.map +1 -1
- package/dist/tempo/TransactionReceipt.d.ts +3 -3
- package/dist/tempo/TransactionReceipt.d.ts.map +1 -1
- package/dist/tempo/TransactionReceipt.js +8 -1
- package/dist/tempo/TransactionReceipt.js.map +1 -1
- package/dist/tempo/TransactionRequest.d.ts +15 -2
- package/dist/tempo/TransactionRequest.d.ts.map +1 -1
- package/dist/tempo/TransactionRequest.js +65 -29
- package/dist/tempo/TransactionRequest.js.map +1 -1
- package/dist/tempo/TxEnvelopeTempo.d.ts +2 -3
- package/dist/tempo/TxEnvelopeTempo.d.ts.map +1 -1
- package/dist/tempo/TxEnvelopeTempo.js +5 -6
- package/dist/tempo/TxEnvelopeTempo.js.map +1 -1
- package/dist/tempo/index.d.ts +6 -26
- package/dist/tempo/index.d.ts.map +1 -1
- package/dist/tempo/index.js +6 -26
- package/dist/tempo/index.js.map +1 -1
- package/dist/zod/Abi.d.ts +214 -0
- package/dist/zod/Abi.d.ts.map +1 -0
- package/dist/zod/Abi.js +5 -0
- package/dist/zod/Abi.js.map +1 -0
- package/dist/zod/AbiConstructor.d.ts +58 -0
- package/dist/zod/AbiConstructor.d.ts.map +1 -0
- package/dist/zod/AbiConstructor.js +18 -0
- package/dist/zod/AbiConstructor.js.map +1 -0
- package/dist/zod/AbiError.d.ts +20 -0
- package/dist/zod/AbiError.d.ts.map +1 -0
- package/dist/zod/AbiError.js +9 -0
- package/dist/zod/AbiError.js.map +1 -0
- package/dist/zod/AbiEvent.d.ts +23 -0
- package/dist/zod/AbiEvent.d.ts.map +1 -0
- package/dist/zod/AbiEvent.js +11 -0
- package/dist/zod/AbiEvent.js.map +1 -0
- package/dist/zod/AbiFallback.d.ts +16 -0
- package/dist/zod/AbiFallback.d.ts.map +1 -0
- package/dist/zod/AbiFallback.js +16 -0
- package/dist/zod/AbiFallback.js.map +1 -0
- package/dist/zod/AbiFunction.d.ts +109 -0
- package/dist/zod/AbiFunction.d.ts.map +1 -0
- package/dist/zod/AbiFunction.js +26 -0
- package/dist/zod/AbiFunction.js.map +1 -0
- package/dist/zod/AbiItem.d.ts +216 -0
- package/dist/zod/AbiItem.d.ts.map +1 -0
- package/dist/zod/AbiItem.js +26 -0
- package/dist/zod/AbiItem.js.map +1 -0
- package/dist/zod/AbiParameter.d.ts +32 -0
- package/dist/zod/AbiParameter.d.ts.map +1 -0
- package/dist/zod/AbiParameter.js +28 -0
- package/dist/zod/AbiParameter.js.map +1 -0
- package/dist/zod/AbiParameters.d.ts +30 -0
- package/dist/zod/AbiParameters.d.ts.map +1 -0
- package/dist/zod/AbiParameters.js +6 -0
- package/dist/zod/AbiParameters.js.map +1 -0
- package/dist/zod/AbiReceive.d.ts +6 -0
- package/dist/zod/AbiReceive.d.ts.map +1 -0
- package/dist/zod/AbiReceive.js +7 -0
- package/dist/zod/AbiReceive.js.map +1 -0
- package/dist/zod/RpcSchema.d.ts +1 -0
- package/dist/zod/RpcSchema.d.ts.map +1 -1
- package/dist/zod/Solidity.d.ts +15 -0
- package/dist/zod/Solidity.d.ts.map +1 -0
- package/dist/zod/Solidity.js +41 -0
- package/dist/zod/Solidity.js.map +1 -0
- package/dist/zod/TypedData.d.ts +226 -0
- package/dist/zod/TypedData.d.ts.map +1 -0
- package/dist/zod/TypedData.js +84 -0
- package/dist/zod/TypedData.js.map +1 -0
- package/dist/zod/internal/rpcSchemas/Eth.d.ts +1 -0
- package/dist/zod/internal/rpcSchemas/Eth.d.ts.map +1 -1
- package/dist/zod/internal/rpcSchemas/Eth.js +5 -0
- package/dist/zod/internal/rpcSchemas/Eth.js.map +1 -1
- package/dist/zod/tempo/AuthorizationTempo.d.ts +0 -20
- package/dist/zod/tempo/AuthorizationTempo.d.ts.map +1 -1
- package/dist/zod/tempo/KeyAuthorization.d.ts +503 -67
- package/dist/zod/tempo/KeyAuthorization.d.ts.map +1 -1
- package/dist/zod/tempo/KeyAuthorization.js +32 -15
- package/dist/zod/tempo/KeyAuthorization.js.map +1 -1
- package/dist/zod/tempo/RpcSchemaTempo.d.ts +216 -34
- package/dist/zod/tempo/RpcSchemaTempo.d.ts.map +1 -1
- package/dist/zod/tempo/SignatureEnvelope.d.ts +0 -6
- package/dist/zod/tempo/SignatureEnvelope.d.ts.map +1 -1
- package/dist/zod/tempo/SignatureEnvelope.js +0 -2
- package/dist/zod/tempo/SignatureEnvelope.js.map +1 -1
- package/dist/zod/tempo/Transaction.d.ts +1479 -333
- package/dist/zod/tempo/Transaction.d.ts.map +1 -1
- package/dist/zod/tempo/Transaction.js +65 -16
- package/dist/zod/tempo/Transaction.js.map +1 -1
- package/dist/zod/tempo/TransactionRequest.d.ts +410 -57
- package/dist/zod/tempo/TransactionRequest.d.ts.map +1 -1
- package/dist/zod/tempo/TransactionRequest.js +81 -18
- package/dist/zod/tempo/TransactionRequest.js.map +1 -1
- package/dist/zod/tempo/TxEnvelopeTempo.d.ts +225 -18
- package/dist/zod/tempo/TxEnvelopeTempo.d.ts.map +1 -1
- package/dist/zod/tempo/TxEnvelopeTempo.js +1 -1
- package/dist/zod/tempo/TxEnvelopeTempo.js.map +1 -1
- package/dist/zod/tempo/ZoneRpcAuthentication.d.ts +0 -3
- package/dist/zod/tempo/ZoneRpcAuthentication.d.ts.map +1 -1
- package/dist/zod/tempo/z.d.ts +0 -1
- package/dist/zod/tempo/z.d.ts.map +1 -1
- package/dist/zod/tempo/z.js +0 -1
- package/dist/zod/tempo/z.js.map +1 -1
- package/dist/zod/z.d.ts +12 -0
- package/dist/zod/z.d.ts.map +1 -1
- package/dist/zod/z.js +12 -0
- package/dist/zod/z.js.map +1 -1
- package/package.json +62 -11
- package/src/core/AbiParameters.ts +3 -1
- package/src/core/Rlp.ts +66 -3
- package/src/core/RpcSchema.ts +1 -1
- package/src/core/Siwe.ts +6 -6
- package/src/core/_test/AbiParameters.decode.test.ts +101 -12
- package/src/core/_test/AbiParameters.encode.test.ts +68 -0
- package/src/core/_test/Rlp.test.ts +101 -0
- package/src/core/_test/Siwe.test.ts +6 -8
- package/src/core/internal/abiParameters.ts +22 -5
- package/src/core/internal/rpcSchemas/eth.ts +36 -0
- package/src/erc4337/EntryPoint.ts +875 -1
- package/src/erc4337/RpcSchema.ts +4 -2
- package/src/erc4337/UserOperation.ts +130 -60
- package/src/erc4337/UserOperationGas.ts +36 -28
- package/src/erc4337/UserOperationReceipt.ts +15 -7
- package/src/erc4337/_test/EntryPoint.test.ts +48 -0
- package/src/erc4337/_test/RpcSchema.test-d.ts +56 -0
- package/src/erc4337/_test/UserOperation.snap-d.ts +31 -0
- package/src/erc4337/_test/UserOperation.test.ts +221 -5
- package/src/erc4337/_test/UserOperationGas.test.ts +30 -1
- package/src/index.ts +2 -2
- package/src/tempo/Channel.test.ts +2 -23
- package/src/tempo/Channel.ts +10 -22
- package/src/tempo/KeyAuthorization.test.ts +22 -0
- package/src/tempo/KeyAuthorization.ts +9 -9
- package/src/tempo/MultisigConfig.test.ts +54 -37
- package/src/tempo/MultisigConfig.ts +59 -134
- package/src/tempo/PoolId.test.ts +7 -41
- package/src/tempo/PoolId.ts +15 -10
- package/src/tempo/SignatureEnvelope.test.ts +118 -17
- package/src/tempo/SignatureEnvelope.ts +77 -72
- package/src/tempo/Transaction.test.ts +0 -15
- package/src/tempo/Transaction.ts +63 -12
- package/src/tempo/TransactionReceipt.test.ts +76 -0
- package/src/tempo/TransactionReceipt.ts +11 -5
- package/src/tempo/TransactionRequest.test.ts +174 -1
- package/src/tempo/TransactionRequest.ts +84 -32
- package/src/tempo/TxEnvelopeTempo.test.ts +2 -2
- package/src/tempo/TxEnvelopeTempo.ts +7 -7
- package/src/tempo/e2e.test.ts +228 -50
- package/src/tempo/index.ts +6 -26
- package/src/version.ts +1 -1
- package/src/zod/Abi.ts +5 -0
- package/src/zod/AbiConstructor.ts +24 -0
- package/src/zod/AbiError.ts +9 -0
- package/src/zod/AbiEvent.ts +11 -0
- package/src/zod/AbiFallback.ts +22 -0
- package/src/zod/AbiFunction.ts +32 -0
- package/src/zod/AbiItem.ts +28 -0
- package/src/zod/AbiParameter.ts +36 -0
- package/src/zod/AbiParameters.ts +7 -0
- package/src/zod/AbiReceive.ts +7 -0
- package/src/zod/Solidity.ts +83 -0
- package/src/zod/TypedData.ts +111 -0
- package/src/zod/_test/Abi.test-d.ts +46 -0
- package/src/zod/_test/Abi.test.ts +163 -0
- package/src/zod/_test/TypedData.test-d.ts +20 -0
- package/src/zod/_test/TypedData.test.ts +87 -0
- package/src/zod/_test/z.test-d.ts +6 -0
- package/src/zod/_test/z.test.ts +17 -0
- package/src/zod/internal/rpcSchemas/Eth.ts +6 -0
- package/src/zod/tempo/KeyAuthorization.ts +34 -15
- package/src/zod/tempo/SignatureEnvelope.ts +0 -2
- package/src/zod/tempo/Transaction.ts +84 -22
- package/src/zod/tempo/TransactionRequest.ts +86 -20
- package/src/zod/tempo/TxEnvelopeTempo.ts +1 -1
- package/src/zod/tempo/_test/KeyAuthorization.test.ts +53 -0
- package/src/zod/tempo/_test/SignatureEnvelope.test.ts +0 -2
- package/src/zod/tempo/_test/Transaction.test.ts +155 -0
- package/src/zod/tempo/_test/TransactionRequest.test.ts +44 -0
- package/src/zod/tempo/z.ts +0 -1
- package/src/zod/z.ts +12 -0
- package/dist/tempo/TokenId.d.ts +0 -87
- package/dist/tempo/TokenId.d.ts.map +0 -1
- package/dist/tempo/TokenId.js +0 -123
- package/dist/tempo/TokenId.js.map +0 -1
- package/dist/zod/tempo/TokenId.d.ts +0 -6
- package/dist/zod/tempo/TokenId.d.ts.map +0 -1
- package/dist/zod/tempo/TokenId.js +0 -14
- package/dist/zod/tempo/TokenId.js.map +0 -1
- package/src/CHANGELOG.md +0 -820
- package/src/tempo/TokenId.bench.ts +0 -36
- package/src/tempo/TokenId.test.ts +0 -79
- package/src/tempo/TokenId.ts +0 -141
- package/src/zod/tempo/TokenId.ts +0 -15
- package/src/zod/tempo/_test/TokenId.test-d.ts +0 -17
- package/src/zod/tempo/_test/TokenId.test.ts +0 -21
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "ox",
|
|
3
3
|
"description": "Ethereum Standard Library",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "1.0.
|
|
5
|
+
"version": "1.0.1",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"sideEffects": false,
|
|
8
8
|
"license": "MIT",
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
"evm"
|
|
27
27
|
],
|
|
28
28
|
"files": [
|
|
29
|
+
"CHANGELOG.md",
|
|
29
30
|
"dist",
|
|
30
31
|
"src"
|
|
31
32
|
],
|
|
@@ -559,11 +560,6 @@
|
|
|
559
560
|
"types": "./dist/tempo/Tick.d.ts",
|
|
560
561
|
"default": "./dist/tempo/Tick.js"
|
|
561
562
|
},
|
|
562
|
-
"./tempo/TokenId": {
|
|
563
|
-
"src": "./src/tempo/TokenId.ts",
|
|
564
|
-
"types": "./dist/tempo/TokenId.d.ts",
|
|
565
|
-
"default": "./dist/tempo/TokenId.js"
|
|
566
|
-
},
|
|
567
563
|
"./tempo/TokenRole": {
|
|
568
564
|
"src": "./src/tempo/TokenRole.ts",
|
|
569
565
|
"types": "./dist/tempo/TokenRole.d.ts",
|
|
@@ -659,6 +655,56 @@
|
|
|
659
655
|
"types": "./dist/zod/index.d.ts",
|
|
660
656
|
"default": "./dist/zod/index.js"
|
|
661
657
|
},
|
|
658
|
+
"./zod/Abi": {
|
|
659
|
+
"src": "./src/zod/Abi.ts",
|
|
660
|
+
"types": "./dist/zod/Abi.d.ts",
|
|
661
|
+
"default": "./dist/zod/Abi.js"
|
|
662
|
+
},
|
|
663
|
+
"./zod/AbiConstructor": {
|
|
664
|
+
"src": "./src/zod/AbiConstructor.ts",
|
|
665
|
+
"types": "./dist/zod/AbiConstructor.d.ts",
|
|
666
|
+
"default": "./dist/zod/AbiConstructor.js"
|
|
667
|
+
},
|
|
668
|
+
"./zod/AbiError": {
|
|
669
|
+
"src": "./src/zod/AbiError.ts",
|
|
670
|
+
"types": "./dist/zod/AbiError.d.ts",
|
|
671
|
+
"default": "./dist/zod/AbiError.js"
|
|
672
|
+
},
|
|
673
|
+
"./zod/AbiEvent": {
|
|
674
|
+
"src": "./src/zod/AbiEvent.ts",
|
|
675
|
+
"types": "./dist/zod/AbiEvent.d.ts",
|
|
676
|
+
"default": "./dist/zod/AbiEvent.js"
|
|
677
|
+
},
|
|
678
|
+
"./zod/AbiFallback": {
|
|
679
|
+
"src": "./src/zod/AbiFallback.ts",
|
|
680
|
+
"types": "./dist/zod/AbiFallback.d.ts",
|
|
681
|
+
"default": "./dist/zod/AbiFallback.js"
|
|
682
|
+
},
|
|
683
|
+
"./zod/AbiFunction": {
|
|
684
|
+
"src": "./src/zod/AbiFunction.ts",
|
|
685
|
+
"types": "./dist/zod/AbiFunction.d.ts",
|
|
686
|
+
"default": "./dist/zod/AbiFunction.js"
|
|
687
|
+
},
|
|
688
|
+
"./zod/AbiItem": {
|
|
689
|
+
"src": "./src/zod/AbiItem.ts",
|
|
690
|
+
"types": "./dist/zod/AbiItem.d.ts",
|
|
691
|
+
"default": "./dist/zod/AbiItem.js"
|
|
692
|
+
},
|
|
693
|
+
"./zod/AbiParameter": {
|
|
694
|
+
"src": "./src/zod/AbiParameter.ts",
|
|
695
|
+
"types": "./dist/zod/AbiParameter.d.ts",
|
|
696
|
+
"default": "./dist/zod/AbiParameter.js"
|
|
697
|
+
},
|
|
698
|
+
"./zod/AbiParameters": {
|
|
699
|
+
"src": "./src/zod/AbiParameters.ts",
|
|
700
|
+
"types": "./dist/zod/AbiParameters.d.ts",
|
|
701
|
+
"default": "./dist/zod/AbiParameters.js"
|
|
702
|
+
},
|
|
703
|
+
"./zod/AbiReceive": {
|
|
704
|
+
"src": "./src/zod/AbiReceive.ts",
|
|
705
|
+
"types": "./dist/zod/AbiReceive.d.ts",
|
|
706
|
+
"default": "./dist/zod/AbiReceive.js"
|
|
707
|
+
},
|
|
662
708
|
"./zod/AccessList": {
|
|
663
709
|
"src": "./src/zod/AccessList.ts",
|
|
664
710
|
"types": "./dist/zod/AccessList.d.ts",
|
|
@@ -749,6 +795,11 @@
|
|
|
749
795
|
"types": "./dist/zod/Signature.d.ts",
|
|
750
796
|
"default": "./dist/zod/Signature.js"
|
|
751
797
|
},
|
|
798
|
+
"./zod/Solidity": {
|
|
799
|
+
"src": "./src/zod/Solidity.ts",
|
|
800
|
+
"types": "./dist/zod/Solidity.d.ts",
|
|
801
|
+
"default": "./dist/zod/Solidity.js"
|
|
802
|
+
},
|
|
752
803
|
"./zod/StateOverrides": {
|
|
753
804
|
"src": "./src/zod/StateOverrides.ts",
|
|
754
805
|
"types": "./dist/zod/StateOverrides.d.ts",
|
|
@@ -799,6 +850,11 @@
|
|
|
799
850
|
"types": "./dist/zod/TxEnvelopeLegacy.d.ts",
|
|
800
851
|
"default": "./dist/zod/TxEnvelopeLegacy.js"
|
|
801
852
|
},
|
|
853
|
+
"./zod/TypedData": {
|
|
854
|
+
"src": "./src/zod/TypedData.ts",
|
|
855
|
+
"types": "./dist/zod/TypedData.d.ts",
|
|
856
|
+
"default": "./dist/zod/TypedData.js"
|
|
857
|
+
},
|
|
802
858
|
"./zod/Uint": {
|
|
803
859
|
"src": "./src/zod/Uint.ts",
|
|
804
860
|
"types": "./dist/zod/Uint.d.ts",
|
|
@@ -849,11 +905,6 @@
|
|
|
849
905
|
"types": "./dist/zod/tempo/Tick.d.ts",
|
|
850
906
|
"default": "./dist/zod/tempo/Tick.js"
|
|
851
907
|
},
|
|
852
|
-
"./zod/tempo/TokenId": {
|
|
853
|
-
"src": "./src/zod/tempo/TokenId.ts",
|
|
854
|
-
"types": "./dist/zod/tempo/TokenId.d.ts",
|
|
855
|
-
"default": "./dist/zod/tempo/TokenId.js"
|
|
856
|
-
},
|
|
857
908
|
"./zod/tempo/TokenRole": {
|
|
858
909
|
"src": "./src/zod/tempo/TokenRole.ts",
|
|
859
910
|
"types": "./dist/zod/tempo/TokenRole.d.ts",
|
|
@@ -109,7 +109,9 @@ export function decode(
|
|
|
109
109
|
for (let i = 0; i < parameters.length; ++i) {
|
|
110
110
|
const param = parameters[i] as Parameter
|
|
111
111
|
try {
|
|
112
|
-
|
|
112
|
+
// Zero-width types (e.g. `uint256[0]`, empty tuples) at the end of the
|
|
113
|
+
// data consume no bytes, so the cursor may already be exhausted.
|
|
114
|
+
if (consumed < bytes.length) cursor.setPosition(consumed)
|
|
113
115
|
const [data_, consumed_] = internal.decodeParameter(cursor, param, {
|
|
114
116
|
checksumAddress,
|
|
115
117
|
staticPosition: 0,
|
package/src/core/Rlp.ts
CHANGED
|
@@ -5,6 +5,9 @@ import * as internal_bytes from './internal/bytes.js'
|
|
|
5
5
|
import * as Cursor from './internal/cursor.js'
|
|
6
6
|
import type { ExactPartial, RecursiveArray } from './internal/types.js'
|
|
7
7
|
|
|
8
|
+
/** Maximum nesting depth permitted when decoding an RLP value. */
|
|
9
|
+
const depthLimit = 1_024
|
|
10
|
+
|
|
8
11
|
/**
|
|
9
12
|
* Decodes a Recursive-Length Prefix (RLP) value into a {@link ox#Bytes.Bytes} value.
|
|
10
13
|
*
|
|
@@ -68,6 +71,12 @@ export function to<
|
|
|
68
71
|
})
|
|
69
72
|
const result = decodeRlpCursor(cursor, to_)
|
|
70
73
|
|
|
74
|
+
// RLP payloads encode exactly one item (Yellow Paper, Appendix B).
|
|
75
|
+
if (cursor.position < cursor.bytes.length)
|
|
76
|
+
throw new TrailingBytesError({
|
|
77
|
+
count: cursor.bytes.length - cursor.position,
|
|
78
|
+
})
|
|
79
|
+
|
|
71
80
|
return result as to.ReturnType<to>
|
|
72
81
|
}
|
|
73
82
|
|
|
@@ -82,6 +91,7 @@ export declare namespace to {
|
|
|
82
91
|
| decodeRlpCursor.ErrorType
|
|
83
92
|
| Cursor.create.ErrorType
|
|
84
93
|
| Hex.InvalidLengthError
|
|
94
|
+
| TrailingBytesError
|
|
85
95
|
| Errors.GlobalErrorType
|
|
86
96
|
}
|
|
87
97
|
|
|
@@ -91,7 +101,11 @@ export declare namespace to {
|
|
|
91
101
|
export function decodeRlpCursor<to extends 'Hex' | 'Bytes' = 'Hex'>(
|
|
92
102
|
cursor: Cursor.Cursor,
|
|
93
103
|
to: to | 'Hex' | 'Bytes' | undefined = 'Hex',
|
|
104
|
+
depth = 0,
|
|
94
105
|
): decodeRlpCursor.ReturnType<to> {
|
|
106
|
+
if (depth >= depthLimit)
|
|
107
|
+
throw new DepthLimitExceededError({ limit: depthLimit })
|
|
108
|
+
|
|
95
109
|
if (cursor.bytes.length === 0)
|
|
96
110
|
return (
|
|
97
111
|
to === 'Hex' ? Hex.fromBytes(cursor.bytes) : cursor.bytes
|
|
@@ -111,7 +125,12 @@ export function decodeRlpCursor<to extends 'Hex' | 'Bytes' = 'Hex'>(
|
|
|
111
125
|
|
|
112
126
|
// list
|
|
113
127
|
const length = readLength(cursor, prefix, 0xc0)
|
|
114
|
-
return readList(
|
|
128
|
+
return readList(
|
|
129
|
+
cursor,
|
|
130
|
+
length,
|
|
131
|
+
to,
|
|
132
|
+
depth + 1,
|
|
133
|
+
) as {} as decodeRlpCursor.ReturnType<to>
|
|
115
134
|
}
|
|
116
135
|
|
|
117
136
|
/** @internal */
|
|
@@ -121,6 +140,7 @@ export declare namespace decodeRlpCursor {
|
|
|
121
140
|
| Hex.fromBytes.ErrorType
|
|
122
141
|
| readLength.ErrorType
|
|
123
142
|
| readList.ErrorType
|
|
143
|
+
| DepthLimitExceededError
|
|
124
144
|
| Errors.GlobalErrorType
|
|
125
145
|
}
|
|
126
146
|
|
|
@@ -149,17 +169,27 @@ export function readList<to extends 'Hex' | 'Bytes'>(
|
|
|
149
169
|
cursor: Cursor.Cursor,
|
|
150
170
|
length: number,
|
|
151
171
|
to: to | 'Hex' | 'Bytes',
|
|
172
|
+
depth = 0,
|
|
152
173
|
) {
|
|
153
174
|
const position = cursor.position
|
|
154
175
|
const value: decodeRlpCursor.ReturnType<to>[] = []
|
|
155
176
|
while (cursor.position - position < length)
|
|
156
|
-
value.push(decodeRlpCursor(cursor, to))
|
|
177
|
+
value.push(decodeRlpCursor(cursor, to, depth))
|
|
178
|
+
// Items must consume exactly the declared list length.
|
|
179
|
+
if (cursor.position - position !== length)
|
|
180
|
+
throw new ListBoundaryExceededError({
|
|
181
|
+
consumed: cursor.position - position,
|
|
182
|
+
declared: length,
|
|
183
|
+
})
|
|
157
184
|
return value
|
|
158
185
|
}
|
|
159
186
|
|
|
160
187
|
/** @internal */
|
|
161
188
|
export declare namespace readList {
|
|
162
|
-
type ErrorType =
|
|
189
|
+
type ErrorType =
|
|
190
|
+
| DepthLimitExceededError
|
|
191
|
+
| ListBoundaryExceededError
|
|
192
|
+
| Errors.GlobalErrorType
|
|
163
193
|
}
|
|
164
194
|
|
|
165
195
|
/**
|
|
@@ -643,3 +673,36 @@ function writeBigEndian(
|
|
|
643
673
|
function invalidNibble(hex: Hex.Hex): Errors.BaseError {
|
|
644
674
|
return new Errors.BaseError(`Invalid hex string \`${hex}\`.`)
|
|
645
675
|
}
|
|
676
|
+
|
|
677
|
+
/** Thrown when an RLP value nests deeper than the decode depth limit. */
|
|
678
|
+
export class DepthLimitExceededError extends Errors.BaseError {
|
|
679
|
+
override readonly name = 'Rlp.DepthLimitExceededError'
|
|
680
|
+
|
|
681
|
+
constructor({ limit }: { limit: number }) {
|
|
682
|
+
super(`RLP depth limit of \`${limit}\` exceeded.`)
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
/** Thrown when RLP list items overrun the list's declared length. */
|
|
687
|
+
export class ListBoundaryExceededError extends Errors.BaseError {
|
|
688
|
+
override readonly name = 'Rlp.ListBoundaryExceededError'
|
|
689
|
+
|
|
690
|
+
constructor({ consumed, declared }: { consumed: number; declared: number }) {
|
|
691
|
+
super(
|
|
692
|
+
`RLP list items consumed \`${consumed}\` bytes but the list declared a length of \`${declared}\`.`,
|
|
693
|
+
)
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
/** Thrown when an RLP payload contains bytes after the decoded item. */
|
|
698
|
+
export class TrailingBytesError extends Errors.BaseError {
|
|
699
|
+
override readonly name = 'Rlp.TrailingBytesError'
|
|
700
|
+
|
|
701
|
+
constructor({ count }: { count: number }) {
|
|
702
|
+
super(
|
|
703
|
+
`RLP payload encodes a single item, but \`${count}\` trailing ${
|
|
704
|
+
count === 1 ? 'byte remains' : 'bytes remain'
|
|
705
|
+
}.`,
|
|
706
|
+
)
|
|
707
|
+
}
|
|
708
|
+
}
|
package/src/core/RpcSchema.ts
CHANGED
|
@@ -331,7 +331,7 @@ export type Schema = Generic | FromZod.Namespace
|
|
|
331
331
|
|
|
332
332
|
/**
|
|
333
333
|
* Resolves a {@link ox#RpcSchema.Schema} input to an Ox {@link ox#RpcSchema.Generic}.
|
|
334
|
-
* A Zod namespace is converted via {@link ox#RpcSchema.FromZod}; a `Generic` is
|
|
334
|
+
* A Zod namespace is converted via {@link ox#RpcSchema.(FromZod:type)}; a `Generic` is
|
|
335
335
|
* passed through; otherwise falls back to {@link ox#RpcSchema.Default}.
|
|
336
336
|
*/
|
|
337
337
|
export type ToGeneric<schema extends Schema | undefined> =
|
package/src/core/Siwe.ts
CHANGED
|
@@ -32,7 +32,7 @@ export type Message = {
|
|
|
32
32
|
/**
|
|
33
33
|
* The [EIP-155](https://eips.ethereum.org/EIPS/eip-155) Chain ID to which the session is bound,
|
|
34
34
|
*/
|
|
35
|
-
chainId:
|
|
35
|
+
chainId: number
|
|
36
36
|
/**
|
|
37
37
|
* [RFC 3986](https://www.rfc-editor.org/rfc/rfc3986) authority that is requesting the signing.
|
|
38
38
|
*/
|
|
@@ -88,7 +88,7 @@ export type Message = {
|
|
|
88
88
|
*
|
|
89
89
|
* Siwe.createMessage({
|
|
90
90
|
* address: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e',
|
|
91
|
-
* chainId:
|
|
91
|
+
* chainId: 1,
|
|
92
92
|
* domain: 'example.com',
|
|
93
93
|
* nonce: 'foobarbaz',
|
|
94
94
|
* uri: 'https://example.com/path',
|
|
@@ -126,7 +126,7 @@ export function createMessage(value: Message): string {
|
|
|
126
126
|
// Validate fields
|
|
127
127
|
{
|
|
128
128
|
// Required fields
|
|
129
|
-
if (
|
|
129
|
+
if (!Number.isInteger(chainId) || chainId < 0)
|
|
130
130
|
throw new InvalidMessageFieldError({
|
|
131
131
|
field: 'chainId',
|
|
132
132
|
metaMessages: [
|
|
@@ -351,7 +351,7 @@ function splitUri(value: string) {
|
|
|
351
351
|
* Issued At: 2023-02-01T00:00:00.000Z`)
|
|
352
352
|
* // @log: {
|
|
353
353
|
* // @log: address: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e',
|
|
354
|
-
* // @log: chainId:
|
|
354
|
+
* // @log: chainId: 1,
|
|
355
355
|
* // @log: domain: 'example.com',
|
|
356
356
|
* // @log: issuedAt: '2023-02-01T00:00:00.000Z',
|
|
357
357
|
* // @log: nonce: 'foobarbaz',
|
|
@@ -387,7 +387,7 @@ export function parseMessage(message: string): ExactPartial<Message> {
|
|
|
387
387
|
return {
|
|
388
388
|
...prefix,
|
|
389
389
|
...suffix,
|
|
390
|
-
...(chainId ? { chainId:
|
|
390
|
+
...(chainId ? { chainId: Number(chainId) } : {}),
|
|
391
391
|
...(expirationTime ? { expirationTime: new Date(expirationTime) } : {}),
|
|
392
392
|
...(issuedAt ? { issuedAt: new Date(issuedAt) } : {}),
|
|
393
393
|
...(notBefore ? { notBefore: new Date(notBefore) } : {}),
|
|
@@ -410,7 +410,7 @@ export function parseMessage(message: string): ExactPartial<Message> {
|
|
|
410
410
|
* domain: 'example.com',
|
|
411
411
|
* message: {
|
|
412
412
|
* address: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e',
|
|
413
|
-
* chainId:
|
|
413
|
+
* chainId: 1,
|
|
414
414
|
* domain: 'example.com',
|
|
415
415
|
* nonce: 'foobarbaz',
|
|
416
416
|
* uri: 'https://example.com/path',
|
|
@@ -443,6 +443,19 @@ describe('dynamic', () => {
|
|
|
443
443
|
expect(result).toEqual([''])
|
|
444
444
|
})
|
|
445
445
|
|
|
446
|
+
test('leading NUL byte', () => {
|
|
447
|
+
const result = AbiParameters.decode(
|
|
448
|
+
AbiParameters.from('string'),
|
|
449
|
+
'0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030061620000000000000000000000000000000000000000000000000000000000',
|
|
450
|
+
)
|
|
451
|
+
assertType<readonly [string]>(result)
|
|
452
|
+
expect(result).toMatchInlineSnapshot(`
|
|
453
|
+
[
|
|
454
|
+
"\u0000ab",
|
|
455
|
+
]
|
|
456
|
+
`)
|
|
457
|
+
})
|
|
458
|
+
|
|
446
459
|
test('default', () => {
|
|
447
460
|
expect(
|
|
448
461
|
AbiParameters.decode(
|
|
@@ -1601,22 +1614,12 @@ test('zst', () => {
|
|
|
1601
1614
|
expect(() =>
|
|
1602
1615
|
AbiParameters.decode([{ type: 'uint256[0][4294967295]' }], payload),
|
|
1603
1616
|
).toThrowErrorMatchingInlineSnapshot(
|
|
1604
|
-
`
|
|
1605
|
-
[AbiParameters.DataSizeTooSmallError: Data size of 64 bytes is too small for given parameters.
|
|
1606
|
-
|
|
1607
|
-
Params: (uint256[0][4294967295])
|
|
1608
|
-
Data: 0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000FFFFFFFF (64 bytes)]
|
|
1609
|
-
`,
|
|
1617
|
+
'[Cursor.RecursiveReadLimitExceededError: Recursive read limit of `8192` exceeded (recursive read count: `8193`).]',
|
|
1610
1618
|
)
|
|
1611
1619
|
expect(() =>
|
|
1612
1620
|
AbiParameters.decode([{ type: 'uint32[0][4294967295]' }], payload),
|
|
1613
1621
|
).toThrowErrorMatchingInlineSnapshot(
|
|
1614
|
-
`
|
|
1615
|
-
[AbiParameters.DataSizeTooSmallError: Data size of 64 bytes is too small for given parameters.
|
|
1616
|
-
|
|
1617
|
-
Params: (uint32[0][4294967295])
|
|
1618
|
-
Data: 0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000FFFFFFFF (64 bytes)]
|
|
1619
|
-
`,
|
|
1622
|
+
'[Cursor.RecursiveReadLimitExceededError: Recursive read limit of `8192` exceeded (recursive read count: `8193`).]',
|
|
1620
1623
|
)
|
|
1621
1624
|
expect(() =>
|
|
1622
1625
|
AbiParameters.decode(
|
|
@@ -1798,3 +1801,89 @@ test('recursive 2', () => {
|
|
|
1798
1801
|
'[Cursor.RecursiveReadLimitExceededError: Recursive read limit of `8192` exceeded (recursive read count: `8193`).]',
|
|
1799
1802
|
)
|
|
1800
1803
|
})
|
|
1804
|
+
|
|
1805
|
+
describe('zero-width types', () => {
|
|
1806
|
+
test('zero-length fixed array', () => {
|
|
1807
|
+
expect(
|
|
1808
|
+
AbiParameters.decode(
|
|
1809
|
+
[{ type: 'uint256[0]' }, { type: 'uint256' }],
|
|
1810
|
+
'0x0000000000000000000000000000000000000000000000000000000000000003',
|
|
1811
|
+
),
|
|
1812
|
+
).toEqual([[], 3n])
|
|
1813
|
+
})
|
|
1814
|
+
|
|
1815
|
+
test('trailing empty tuple', () => {
|
|
1816
|
+
expect(
|
|
1817
|
+
AbiParameters.decode(
|
|
1818
|
+
[{ type: 'uint256' }, { type: 'tuple', components: [] }],
|
|
1819
|
+
'0x0000000000000000000000000000000000000000000000000000000000000005',
|
|
1820
|
+
),
|
|
1821
|
+
).toEqual([5n, []])
|
|
1822
|
+
})
|
|
1823
|
+
|
|
1824
|
+
test('zero-length fixed array of dynamic type', () => {
|
|
1825
|
+
expect(
|
|
1826
|
+
AbiParameters.decode(
|
|
1827
|
+
[{ type: 'string[0]' }, { type: 'uint256' }],
|
|
1828
|
+
'0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000003',
|
|
1829
|
+
),
|
|
1830
|
+
).toEqual([[], 3n])
|
|
1831
|
+
})
|
|
1832
|
+
|
|
1833
|
+
test('standalone zero-length fixed array of dynamic type', () => {
|
|
1834
|
+
// The head is a single offset word pointing at an empty tail.
|
|
1835
|
+
expect(
|
|
1836
|
+
AbiParameters.decode(
|
|
1837
|
+
[{ type: 'string[0]' }],
|
|
1838
|
+
'0x0000000000000000000000000000000000000000000000000000000000000020',
|
|
1839
|
+
),
|
|
1840
|
+
).toEqual([[]])
|
|
1841
|
+
expect(
|
|
1842
|
+
AbiParameters.decode(
|
|
1843
|
+
[{ type: 'bytes[0]' }],
|
|
1844
|
+
'0x0000000000000000000000000000000000000000000000000000000000000020',
|
|
1845
|
+
),
|
|
1846
|
+
).toEqual([[]])
|
|
1847
|
+
})
|
|
1848
|
+
|
|
1849
|
+
test('round-trip', () => {
|
|
1850
|
+
const cases = [
|
|
1851
|
+
{
|
|
1852
|
+
parameters: [{ type: 'uint256[0]' }, { type: 'uint256' }],
|
|
1853
|
+
values: [[], 3n],
|
|
1854
|
+
},
|
|
1855
|
+
{
|
|
1856
|
+
parameters: [{ type: 'uint256' }, { type: 'tuple', components: [] }],
|
|
1857
|
+
values: [5n, []],
|
|
1858
|
+
},
|
|
1859
|
+
{
|
|
1860
|
+
parameters: [{ type: 'string[0]' }, { type: 'uint256' }],
|
|
1861
|
+
values: [[], 3n],
|
|
1862
|
+
},
|
|
1863
|
+
{
|
|
1864
|
+
parameters: [{ type: 'uint256[0]' }, { type: 'string' }],
|
|
1865
|
+
values: [[], 'hello'],
|
|
1866
|
+
},
|
|
1867
|
+
{
|
|
1868
|
+
parameters: [{ type: 'uint256[0][2]' }, { type: 'uint256' }],
|
|
1869
|
+
values: [[[], []], 9n],
|
|
1870
|
+
},
|
|
1871
|
+
{
|
|
1872
|
+
parameters: [{ type: 'string[0]' }],
|
|
1873
|
+
values: [[]],
|
|
1874
|
+
},
|
|
1875
|
+
{
|
|
1876
|
+
parameters: [{ type: 'tuple', components: [{ type: 'string[0]' }] }],
|
|
1877
|
+
values: [[[]]],
|
|
1878
|
+
},
|
|
1879
|
+
] as const
|
|
1880
|
+
for (const { parameters, values } of cases) {
|
|
1881
|
+
expect(
|
|
1882
|
+
AbiParameters.decode(
|
|
1883
|
+
parameters,
|
|
1884
|
+
AbiParameters.encode(parameters, values as never),
|
|
1885
|
+
),
|
|
1886
|
+
).toEqual(values)
|
|
1887
|
+
}
|
|
1888
|
+
})
|
|
1889
|
+
})
|
|
@@ -1963,3 +1963,71 @@ test('https://github.com/wevm/viem/issues/1960', () => {
|
|
|
1963
1963
|
`[BaseError: Invalid boolean value: "true" (type: string). Expected: \`true\` or \`false\`.]`,
|
|
1964
1964
|
)
|
|
1965
1965
|
})
|
|
1966
|
+
|
|
1967
|
+
describe('zero-width types', () => {
|
|
1968
|
+
// Per the ABI spec, `enc(T[0])` and `enc(())` are zero-length: a zero-length
|
|
1969
|
+
// fixed array or empty tuple contributes no bytes. Expected values verified
|
|
1970
|
+
// against ethers `AbiCoder.defaultAbiCoder()`.
|
|
1971
|
+
test('zero-length fixed array', () => {
|
|
1972
|
+
expect(
|
|
1973
|
+
AbiParameters.encode(
|
|
1974
|
+
[{ type: 'uint256[0]' }, { type: 'uint256' }],
|
|
1975
|
+
[[], 3n],
|
|
1976
|
+
),
|
|
1977
|
+
).toBe('0x0000000000000000000000000000000000000000000000000000000000000003')
|
|
1978
|
+
})
|
|
1979
|
+
|
|
1980
|
+
test('empty tuple', () => {
|
|
1981
|
+
expect(
|
|
1982
|
+
AbiParameters.encode(
|
|
1983
|
+
[{ type: 'uint256' }, { type: 'tuple', components: [] }],
|
|
1984
|
+
[5n, []],
|
|
1985
|
+
),
|
|
1986
|
+
).toBe('0x0000000000000000000000000000000000000000000000000000000000000005')
|
|
1987
|
+
})
|
|
1988
|
+
|
|
1989
|
+
test('empty tuple only', () => {
|
|
1990
|
+
expect(
|
|
1991
|
+
AbiParameters.encode([{ type: 'tuple', components: [] }], [[]]),
|
|
1992
|
+
).toBe('0x')
|
|
1993
|
+
})
|
|
1994
|
+
|
|
1995
|
+
test('nested zero-length fixed arrays', () => {
|
|
1996
|
+
expect(
|
|
1997
|
+
AbiParameters.encode(
|
|
1998
|
+
[{ type: 'uint256[0][2]' }, { type: 'uint256' }],
|
|
1999
|
+
[[[], []], 9n],
|
|
2000
|
+
),
|
|
2001
|
+
).toBe('0x0000000000000000000000000000000000000000000000000000000000000009')
|
|
2002
|
+
expect(
|
|
2003
|
+
AbiParameters.encode(
|
|
2004
|
+
[{ type: 'uint256[2][0]' }, { type: 'uint256' }],
|
|
2005
|
+
[[], 9n],
|
|
2006
|
+
),
|
|
2007
|
+
).toBe('0x0000000000000000000000000000000000000000000000000000000000000009')
|
|
2008
|
+
})
|
|
2009
|
+
|
|
2010
|
+
test('offsets skip zero-width parameters', () => {
|
|
2011
|
+
expect(
|
|
2012
|
+
AbiParameters.encode(
|
|
2013
|
+
[{ type: 'uint256[0]' }, { type: 'string' }],
|
|
2014
|
+
[[], 'hello'],
|
|
2015
|
+
),
|
|
2016
|
+
).toBe(
|
|
2017
|
+
'0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000568656c6c6f000000000000000000000000000000000000000000000000000000',
|
|
2018
|
+
)
|
|
2019
|
+
})
|
|
2020
|
+
|
|
2021
|
+
// `T[0]` of a dynamic `T` is dynamic per the ABI spec: 32-byte offset
|
|
2022
|
+
// pointing at a zero-length tail.
|
|
2023
|
+
test('zero-length fixed array of dynamic type', () => {
|
|
2024
|
+
expect(
|
|
2025
|
+
AbiParameters.encode(
|
|
2026
|
+
[{ type: 'string[0]' }, { type: 'uint256' }],
|
|
2027
|
+
[[], 3n],
|
|
2028
|
+
),
|
|
2029
|
+
).toBe(
|
|
2030
|
+
'0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000003',
|
|
2031
|
+
)
|
|
2032
|
+
})
|
|
2033
|
+
})
|
|
@@ -13,6 +13,9 @@ test('exports', () => {
|
|
|
13
13
|
"from",
|
|
14
14
|
"fromBytes",
|
|
15
15
|
"fromHex",
|
|
16
|
+
"DepthLimitExceededError",
|
|
17
|
+
"ListBoundaryExceededError",
|
|
18
|
+
"TrailingBytesError",
|
|
16
19
|
]
|
|
17
20
|
`)
|
|
18
21
|
})
|
|
@@ -337,3 +340,101 @@ describe('Rlp.to', () => {
|
|
|
337
340
|
)
|
|
338
341
|
})
|
|
339
342
|
})
|
|
343
|
+
|
|
344
|
+
describe('decode depth limit', () => {
|
|
345
|
+
// Builds an RLP-encoded value of `depth` nested empty lists without recursing
|
|
346
|
+
// (so we can exceed the decoder's depth limit without overflowing the encoder).
|
|
347
|
+
const nestedEmptyLists = (depth: number) => {
|
|
348
|
+
let bytes = Uint8Array.from([0xc0])
|
|
349
|
+
for (let i = 0; i < depth; i++) {
|
|
350
|
+
const length = bytes.length
|
|
351
|
+
const prefix =
|
|
352
|
+
length <= 55
|
|
353
|
+
? [0xc0 + length]
|
|
354
|
+
: (() => {
|
|
355
|
+
const lengthBytes: number[] = []
|
|
356
|
+
let n = length
|
|
357
|
+
while (n > 0) {
|
|
358
|
+
lengthBytes.unshift(n & 0xff)
|
|
359
|
+
n >>= 8
|
|
360
|
+
}
|
|
361
|
+
return [0xf7 + lengthBytes.length, ...lengthBytes]
|
|
362
|
+
})()
|
|
363
|
+
const next = new Uint8Array(prefix.length + bytes.length)
|
|
364
|
+
next.set(prefix, 0)
|
|
365
|
+
next.set(bytes, prefix.length)
|
|
366
|
+
bytes = next
|
|
367
|
+
}
|
|
368
|
+
return bytes
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
test('decodes up to the depth limit', () => {
|
|
372
|
+
expect(() => Rlp.toBytes(nestedEmptyLists(1_023))).not.toThrow()
|
|
373
|
+
})
|
|
374
|
+
|
|
375
|
+
test('throws when the depth limit is exceeded', () => {
|
|
376
|
+
expect(() =>
|
|
377
|
+
Rlp.toBytes(nestedEmptyLists(2_000)),
|
|
378
|
+
).toThrowErrorMatchingInlineSnapshot(
|
|
379
|
+
`[Rlp.DepthLimitExceededError: RLP depth limit of \`1024\` exceeded.]`,
|
|
380
|
+
)
|
|
381
|
+
})
|
|
382
|
+
})
|
|
383
|
+
|
|
384
|
+
describe('trailing bytes', () => {
|
|
385
|
+
// RLP payloads encode exactly one item (Yellow Paper, Appendix B).
|
|
386
|
+
test('after string item', () => {
|
|
387
|
+
expect(() => Rlp.toHex('0x80deadbeef')).toThrowErrorMatchingInlineSnapshot(
|
|
388
|
+
`[Rlp.TrailingBytesError: RLP payload encodes a single item, but \`4\` trailing bytes remain.]`,
|
|
389
|
+
)
|
|
390
|
+
})
|
|
391
|
+
|
|
392
|
+
test('after list item', () => {
|
|
393
|
+
expect(() => Rlp.toHex('0xc2010203')).toThrowErrorMatchingInlineSnapshot(
|
|
394
|
+
`[Rlp.TrailingBytesError: RLP payload encodes a single item, but \`1\` trailing byte remains.]`,
|
|
395
|
+
)
|
|
396
|
+
})
|
|
397
|
+
|
|
398
|
+
test('after empty list', () => {
|
|
399
|
+
expect(() => Rlp.toHex('0xc000')).toThrowErrorMatchingInlineSnapshot(
|
|
400
|
+
`[Rlp.TrailingBytesError: RLP payload encodes a single item, but \`1\` trailing byte remains.]`,
|
|
401
|
+
)
|
|
402
|
+
})
|
|
403
|
+
|
|
404
|
+
test('bytes input', () => {
|
|
405
|
+
expect(() =>
|
|
406
|
+
Rlp.toHex(Uint8Array.from([0x80, 0xde, 0xad])),
|
|
407
|
+
).toThrowErrorMatchingInlineSnapshot(
|
|
408
|
+
`[Rlp.TrailingBytesError: RLP payload encodes a single item, but \`2\` trailing bytes remain.]`,
|
|
409
|
+
)
|
|
410
|
+
})
|
|
411
|
+
|
|
412
|
+
test('valid single items still decode', () => {
|
|
413
|
+
expect(Rlp.toHex('0x80')).toEqual('0x')
|
|
414
|
+
expect(Rlp.toHex('0xc0')).toEqual([])
|
|
415
|
+
expect(Rlp.toHex('0xc1c0')).toEqual([[]])
|
|
416
|
+
expect(Rlp.toHex('0x83646f67')).toEqual('0x646f67')
|
|
417
|
+
})
|
|
418
|
+
})
|
|
419
|
+
|
|
420
|
+
describe('list boundary', () => {
|
|
421
|
+
// Items must consume exactly the declared list length.
|
|
422
|
+
test('item extends beyond list', () => {
|
|
423
|
+
// `0xc1` declares 1 payload byte; `0x82aabb` consumes 3.
|
|
424
|
+
expect(() => Rlp.toHex('0xc182aabb')).toThrowErrorMatchingInlineSnapshot(
|
|
425
|
+
`[Rlp.ListBoundaryExceededError: RLP list items consumed \`3\` bytes but the list declared a length of \`1\`.]`,
|
|
426
|
+
)
|
|
427
|
+
})
|
|
428
|
+
|
|
429
|
+
test('item extends beyond nested list', () => {
|
|
430
|
+
expect(() => Rlp.toHex('0xc3c182aabb')).toThrowErrorMatchingInlineSnapshot(
|
|
431
|
+
`[Rlp.ListBoundaryExceededError: RLP list items consumed \`3\` bytes but the list declared a length of \`1\`.]`,
|
|
432
|
+
)
|
|
433
|
+
})
|
|
434
|
+
|
|
435
|
+
test('item extends beyond list with trailing bytes', () => {
|
|
436
|
+
expect(() => Rlp.toHex('0xc182aabbff')).toThrowErrorMatchingInlineSnapshot(
|
|
437
|
+
`[Rlp.ListBoundaryExceededError: RLP list items consumed \`3\` bytes but the list declared a length of \`1\`.]`,
|
|
438
|
+
)
|
|
439
|
+
})
|
|
440
|
+
})
|