ox 1.0.0-beta.9 → 1.0.0

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.
Files changed (244) hide show
  1. package/CHANGELOG.md +1143 -0
  2. package/dist/core/AbiParameters.d.ts.map +1 -1
  3. package/dist/core/AbiParameters.js +4 -1
  4. package/dist/core/AbiParameters.js.map +1 -1
  5. package/dist/core/Rlp.d.ts +27 -5
  6. package/dist/core/Rlp.d.ts.map +1 -1
  7. package/dist/core/Rlp.js +40 -4
  8. package/dist/core/Rlp.js.map +1 -1
  9. package/dist/core/RpcSchema.d.ts +1 -1
  10. package/dist/core/internal/abiParameters.d.ts.map +1 -1
  11. package/dist/core/internal/abiParameters.js +21 -3
  12. package/dist/core/internal/abiParameters.js.map +1 -1
  13. package/dist/core/internal/rpcSchemas/eth.d.ts +36 -0
  14. package/dist/core/internal/rpcSchemas/eth.d.ts.map +1 -1
  15. package/dist/erc4337/EntryPoint.d.ts +1072 -1
  16. package/dist/erc4337/EntryPoint.d.ts.map +1 -1
  17. package/dist/erc4337/EntryPoint.js +872 -0
  18. package/dist/erc4337/EntryPoint.js.map +1 -1
  19. package/dist/erc4337/RpcSchema.d.ts +2 -2
  20. package/dist/erc4337/RpcSchema.d.ts.map +1 -1
  21. package/dist/erc4337/UserOperation.d.ts +39 -10
  22. package/dist/erc4337/UserOperation.d.ts.map +1 -1
  23. package/dist/erc4337/UserOperation.js +62 -48
  24. package/dist/erc4337/UserOperation.js.map +1 -1
  25. package/dist/erc4337/UserOperationGas.d.ts +9 -5
  26. package/dist/erc4337/UserOperationGas.d.ts.map +1 -1
  27. package/dist/erc4337/UserOperationGas.js +17 -15
  28. package/dist/erc4337/UserOperationGas.js.map +1 -1
  29. package/dist/erc4337/UserOperationReceipt.d.ts +4 -4
  30. package/dist/erc4337/UserOperationReceipt.d.ts.map +1 -1
  31. package/dist/erc4337/UserOperationReceipt.js.map +1 -1
  32. package/dist/tempo/Channel.d.ts +8 -14
  33. package/dist/tempo/Channel.d.ts.map +1 -1
  34. package/dist/tempo/Channel.js +4 -8
  35. package/dist/tempo/Channel.js.map +1 -1
  36. package/dist/tempo/KeyAuthorization.d.ts +5 -5
  37. package/dist/tempo/KeyAuthorization.d.ts.map +1 -1
  38. package/dist/tempo/KeyAuthorization.js +4 -4
  39. package/dist/tempo/KeyAuthorization.js.map +1 -1
  40. package/dist/tempo/MultisigConfig.d.ts +37 -85
  41. package/dist/tempo/MultisigConfig.d.ts.map +1 -1
  42. package/dist/tempo/MultisigConfig.js +39 -83
  43. package/dist/tempo/MultisigConfig.js.map +1 -1
  44. package/dist/tempo/PoolId.d.ts +8 -7
  45. package/dist/tempo/PoolId.d.ts.map +1 -1
  46. package/dist/tempo/PoolId.js +10 -6
  47. package/dist/tempo/PoolId.js.map +1 -1
  48. package/dist/tempo/SignatureEnvelope.d.ts +32 -30
  49. package/dist/tempo/SignatureEnvelope.d.ts.map +1 -1
  50. package/dist/tempo/SignatureEnvelope.js +56 -51
  51. package/dist/tempo/SignatureEnvelope.js.map +1 -1
  52. package/dist/tempo/Transaction.d.ts +16 -5
  53. package/dist/tempo/Transaction.d.ts.map +1 -1
  54. package/dist/tempo/Transaction.js +34 -7
  55. package/dist/tempo/Transaction.js.map +1 -1
  56. package/dist/tempo/TransactionReceipt.d.ts +3 -3
  57. package/dist/tempo/TransactionReceipt.d.ts.map +1 -1
  58. package/dist/tempo/TransactionReceipt.js +8 -1
  59. package/dist/tempo/TransactionReceipt.js.map +1 -1
  60. package/dist/tempo/TransactionRequest.d.ts +15 -2
  61. package/dist/tempo/TransactionRequest.d.ts.map +1 -1
  62. package/dist/tempo/TransactionRequest.js +65 -29
  63. package/dist/tempo/TransactionRequest.js.map +1 -1
  64. package/dist/tempo/TxEnvelopeTempo.d.ts +2 -3
  65. package/dist/tempo/TxEnvelopeTempo.d.ts.map +1 -1
  66. package/dist/tempo/TxEnvelopeTempo.js +5 -6
  67. package/dist/tempo/TxEnvelopeTempo.js.map +1 -1
  68. package/dist/tempo/index.d.ts +6 -26
  69. package/dist/tempo/index.d.ts.map +1 -1
  70. package/dist/tempo/index.js +6 -26
  71. package/dist/tempo/index.js.map +1 -1
  72. package/dist/zod/Abi.d.ts +214 -0
  73. package/dist/zod/Abi.d.ts.map +1 -0
  74. package/dist/zod/Abi.js +5 -0
  75. package/dist/zod/Abi.js.map +1 -0
  76. package/dist/zod/AbiConstructor.d.ts +58 -0
  77. package/dist/zod/AbiConstructor.d.ts.map +1 -0
  78. package/dist/zod/AbiConstructor.js +18 -0
  79. package/dist/zod/AbiConstructor.js.map +1 -0
  80. package/dist/zod/AbiError.d.ts +20 -0
  81. package/dist/zod/AbiError.d.ts.map +1 -0
  82. package/dist/zod/AbiError.js +9 -0
  83. package/dist/zod/AbiError.js.map +1 -0
  84. package/dist/zod/AbiEvent.d.ts +23 -0
  85. package/dist/zod/AbiEvent.d.ts.map +1 -0
  86. package/dist/zod/AbiEvent.js +11 -0
  87. package/dist/zod/AbiEvent.js.map +1 -0
  88. package/dist/zod/AbiFallback.d.ts +16 -0
  89. package/dist/zod/AbiFallback.d.ts.map +1 -0
  90. package/dist/zod/AbiFallback.js +16 -0
  91. package/dist/zod/AbiFallback.js.map +1 -0
  92. package/dist/zod/AbiFunction.d.ts +109 -0
  93. package/dist/zod/AbiFunction.d.ts.map +1 -0
  94. package/dist/zod/AbiFunction.js +26 -0
  95. package/dist/zod/AbiFunction.js.map +1 -0
  96. package/dist/zod/AbiItem.d.ts +216 -0
  97. package/dist/zod/AbiItem.d.ts.map +1 -0
  98. package/dist/zod/AbiItem.js +26 -0
  99. package/dist/zod/AbiItem.js.map +1 -0
  100. package/dist/zod/AbiParameter.d.ts +32 -0
  101. package/dist/zod/AbiParameter.d.ts.map +1 -0
  102. package/dist/zod/AbiParameter.js +28 -0
  103. package/dist/zod/AbiParameter.js.map +1 -0
  104. package/dist/zod/AbiParameters.d.ts +30 -0
  105. package/dist/zod/AbiParameters.d.ts.map +1 -0
  106. package/dist/zod/AbiParameters.js +6 -0
  107. package/dist/zod/AbiParameters.js.map +1 -0
  108. package/dist/zod/AbiReceive.d.ts +6 -0
  109. package/dist/zod/AbiReceive.d.ts.map +1 -0
  110. package/dist/zod/AbiReceive.js +7 -0
  111. package/dist/zod/AbiReceive.js.map +1 -0
  112. package/dist/zod/RpcSchema.d.ts +1 -0
  113. package/dist/zod/RpcSchema.d.ts.map +1 -1
  114. package/dist/zod/Solidity.d.ts +15 -0
  115. package/dist/zod/Solidity.d.ts.map +1 -0
  116. package/dist/zod/Solidity.js +41 -0
  117. package/dist/zod/Solidity.js.map +1 -0
  118. package/dist/zod/TypedData.d.ts +226 -0
  119. package/dist/zod/TypedData.d.ts.map +1 -0
  120. package/dist/zod/TypedData.js +84 -0
  121. package/dist/zod/TypedData.js.map +1 -0
  122. package/dist/zod/internal/rpcSchemas/Eth.d.ts +1 -0
  123. package/dist/zod/internal/rpcSchemas/Eth.d.ts.map +1 -1
  124. package/dist/zod/internal/rpcSchemas/Eth.js +5 -0
  125. package/dist/zod/internal/rpcSchemas/Eth.js.map +1 -1
  126. package/dist/zod/tempo/AuthorizationTempo.d.ts +0 -20
  127. package/dist/zod/tempo/AuthorizationTempo.d.ts.map +1 -1
  128. package/dist/zod/tempo/KeyAuthorization.d.ts +503 -67
  129. package/dist/zod/tempo/KeyAuthorization.d.ts.map +1 -1
  130. package/dist/zod/tempo/KeyAuthorization.js +32 -15
  131. package/dist/zod/tempo/KeyAuthorization.js.map +1 -1
  132. package/dist/zod/tempo/RpcSchemaTempo.d.ts +216 -34
  133. package/dist/zod/tempo/RpcSchemaTempo.d.ts.map +1 -1
  134. package/dist/zod/tempo/SignatureEnvelope.d.ts +0 -6
  135. package/dist/zod/tempo/SignatureEnvelope.d.ts.map +1 -1
  136. package/dist/zod/tempo/SignatureEnvelope.js +0 -2
  137. package/dist/zod/tempo/SignatureEnvelope.js.map +1 -1
  138. package/dist/zod/tempo/Transaction.d.ts +1479 -333
  139. package/dist/zod/tempo/Transaction.d.ts.map +1 -1
  140. package/dist/zod/tempo/Transaction.js +65 -16
  141. package/dist/zod/tempo/Transaction.js.map +1 -1
  142. package/dist/zod/tempo/TransactionRequest.d.ts +410 -57
  143. package/dist/zod/tempo/TransactionRequest.d.ts.map +1 -1
  144. package/dist/zod/tempo/TransactionRequest.js +81 -18
  145. package/dist/zod/tempo/TransactionRequest.js.map +1 -1
  146. package/dist/zod/tempo/TxEnvelopeTempo.d.ts +225 -18
  147. package/dist/zod/tempo/TxEnvelopeTempo.d.ts.map +1 -1
  148. package/dist/zod/tempo/TxEnvelopeTempo.js +1 -1
  149. package/dist/zod/tempo/TxEnvelopeTempo.js.map +1 -1
  150. package/dist/zod/tempo/ZoneRpcAuthentication.d.ts +0 -3
  151. package/dist/zod/tempo/ZoneRpcAuthentication.d.ts.map +1 -1
  152. package/dist/zod/tempo/z.d.ts +0 -1
  153. package/dist/zod/tempo/z.d.ts.map +1 -1
  154. package/dist/zod/tempo/z.js +0 -1
  155. package/dist/zod/tempo/z.js.map +1 -1
  156. package/dist/zod/z.d.ts +12 -0
  157. package/dist/zod/z.d.ts.map +1 -1
  158. package/dist/zod/z.js +12 -0
  159. package/dist/zod/z.js.map +1 -1
  160. package/package.json +62 -11
  161. package/src/core/AbiParameters.ts +3 -1
  162. package/src/core/Rlp.ts +66 -3
  163. package/src/core/RpcSchema.ts +1 -1
  164. package/src/core/_test/AbiParameters.decode.test.ts +88 -12
  165. package/src/core/_test/AbiParameters.encode.test.ts +68 -0
  166. package/src/core/_test/Rlp.test.ts +101 -0
  167. package/src/core/internal/abiParameters.ts +21 -3
  168. package/src/core/internal/rpcSchemas/eth.ts +36 -0
  169. package/src/erc4337/EntryPoint.ts +875 -1
  170. package/src/erc4337/RpcSchema.ts +4 -2
  171. package/src/erc4337/UserOperation.ts +130 -60
  172. package/src/erc4337/UserOperationGas.ts +36 -28
  173. package/src/erc4337/UserOperationReceipt.ts +15 -7
  174. package/src/erc4337/_test/EntryPoint.test.ts +48 -0
  175. package/src/erc4337/_test/RpcSchema.test-d.ts +56 -0
  176. package/src/erc4337/_test/UserOperation.snap-d.ts +31 -0
  177. package/src/erc4337/_test/UserOperation.test.ts +221 -5
  178. package/src/erc4337/_test/UserOperationGas.test.ts +30 -1
  179. package/src/tempo/Channel.test.ts +2 -23
  180. package/src/tempo/Channel.ts +10 -22
  181. package/src/tempo/KeyAuthorization.test.ts +22 -0
  182. package/src/tempo/KeyAuthorization.ts +9 -9
  183. package/src/tempo/MultisigConfig.test.ts +54 -37
  184. package/src/tempo/MultisigConfig.ts +59 -134
  185. package/src/tempo/PoolId.test.ts +7 -41
  186. package/src/tempo/PoolId.ts +15 -10
  187. package/src/tempo/SignatureEnvelope.test.ts +118 -17
  188. package/src/tempo/SignatureEnvelope.ts +77 -72
  189. package/src/tempo/Transaction.test.ts +0 -15
  190. package/src/tempo/Transaction.ts +63 -12
  191. package/src/tempo/TransactionReceipt.test.ts +76 -0
  192. package/src/tempo/TransactionReceipt.ts +11 -5
  193. package/src/tempo/TransactionRequest.test.ts +174 -1
  194. package/src/tempo/TransactionRequest.ts +84 -32
  195. package/src/tempo/TxEnvelopeTempo.test.ts +2 -2
  196. package/src/tempo/TxEnvelopeTempo.ts +7 -7
  197. package/src/tempo/e2e.test.ts +228 -50
  198. package/src/tempo/index.ts +6 -26
  199. package/src/version.ts +1 -1
  200. package/src/zod/Abi.ts +5 -0
  201. package/src/zod/AbiConstructor.ts +24 -0
  202. package/src/zod/AbiError.ts +9 -0
  203. package/src/zod/AbiEvent.ts +11 -0
  204. package/src/zod/AbiFallback.ts +22 -0
  205. package/src/zod/AbiFunction.ts +32 -0
  206. package/src/zod/AbiItem.ts +28 -0
  207. package/src/zod/AbiParameter.ts +36 -0
  208. package/src/zod/AbiParameters.ts +7 -0
  209. package/src/zod/AbiReceive.ts +7 -0
  210. package/src/zod/Solidity.ts +83 -0
  211. package/src/zod/TypedData.ts +111 -0
  212. package/src/zod/_test/Abi.test-d.ts +46 -0
  213. package/src/zod/_test/Abi.test.ts +163 -0
  214. package/src/zod/_test/TypedData.test-d.ts +20 -0
  215. package/src/zod/_test/TypedData.test.ts +87 -0
  216. package/src/zod/_test/z.test-d.ts +6 -0
  217. package/src/zod/_test/z.test.ts +17 -0
  218. package/src/zod/internal/rpcSchemas/Eth.ts +6 -0
  219. package/src/zod/tempo/KeyAuthorization.ts +34 -15
  220. package/src/zod/tempo/SignatureEnvelope.ts +0 -2
  221. package/src/zod/tempo/Transaction.ts +84 -22
  222. package/src/zod/tempo/TransactionRequest.ts +86 -20
  223. package/src/zod/tempo/TxEnvelopeTempo.ts +1 -1
  224. package/src/zod/tempo/_test/KeyAuthorization.test.ts +53 -0
  225. package/src/zod/tempo/_test/SignatureEnvelope.test.ts +0 -2
  226. package/src/zod/tempo/_test/Transaction.test.ts +155 -0
  227. package/src/zod/tempo/_test/TransactionRequest.test.ts +44 -0
  228. package/src/zod/tempo/z.ts +0 -1
  229. package/src/zod/z.ts +12 -0
  230. package/dist/tempo/TokenId.d.ts +0 -87
  231. package/dist/tempo/TokenId.d.ts.map +0 -1
  232. package/dist/tempo/TokenId.js +0 -123
  233. package/dist/tempo/TokenId.js.map +0 -1
  234. package/dist/zod/tempo/TokenId.d.ts +0 -6
  235. package/dist/zod/tempo/TokenId.d.ts.map +0 -1
  236. package/dist/zod/tempo/TokenId.js +0 -14
  237. package/dist/zod/tempo/TokenId.js.map +0 -1
  238. package/src/CHANGELOG.md +0 -820
  239. package/src/tempo/TokenId.bench.ts +0 -36
  240. package/src/tempo/TokenId.test.ts +0 -79
  241. package/src/tempo/TokenId.ts +0 -141
  242. package/src/zod/tempo/TokenId.ts +0 -15
  243. package/src/zod/tempo/_test/TokenId.test-d.ts +0 -17
  244. 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.0-beta.9",
5
+ "version": "1.0.0",
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
- cursor.setPosition(consumed)
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(cursor, length, to) as {} as decodeRlpCursor.ReturnType<to>
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 = Errors.GlobalErrorType
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
+ }
@@ -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> =
@@ -1601,22 +1601,12 @@ test('zst', () => {
1601
1601
  expect(() =>
1602
1602
  AbiParameters.decode([{ type: 'uint256[0][4294967295]' }], payload),
1603
1603
  ).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
- `,
1604
+ '[Cursor.RecursiveReadLimitExceededError: Recursive read limit of `8192` exceeded (recursive read count: `8193`).]',
1610
1605
  )
1611
1606
  expect(() =>
1612
1607
  AbiParameters.decode([{ type: 'uint32[0][4294967295]' }], payload),
1613
1608
  ).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
- `,
1609
+ '[Cursor.RecursiveReadLimitExceededError: Recursive read limit of `8192` exceeded (recursive read count: `8193`).]',
1620
1610
  )
1621
1611
  expect(() =>
1622
1612
  AbiParameters.decode(
@@ -1798,3 +1788,89 @@ test('recursive 2', () => {
1798
1788
  '[Cursor.RecursiveReadLimitExceededError: Recursive read limit of `8192` exceeded (recursive read count: `8193`).]',
1799
1789
  )
1800
1790
  })
1791
+
1792
+ describe('zero-width types', () => {
1793
+ test('zero-length fixed array', () => {
1794
+ expect(
1795
+ AbiParameters.decode(
1796
+ [{ type: 'uint256[0]' }, { type: 'uint256' }],
1797
+ '0x0000000000000000000000000000000000000000000000000000000000000003',
1798
+ ),
1799
+ ).toEqual([[], 3n])
1800
+ })
1801
+
1802
+ test('trailing empty tuple', () => {
1803
+ expect(
1804
+ AbiParameters.decode(
1805
+ [{ type: 'uint256' }, { type: 'tuple', components: [] }],
1806
+ '0x0000000000000000000000000000000000000000000000000000000000000005',
1807
+ ),
1808
+ ).toEqual([5n, []])
1809
+ })
1810
+
1811
+ test('zero-length fixed array of dynamic type', () => {
1812
+ expect(
1813
+ AbiParameters.decode(
1814
+ [{ type: 'string[0]' }, { type: 'uint256' }],
1815
+ '0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000003',
1816
+ ),
1817
+ ).toEqual([[], 3n])
1818
+ })
1819
+
1820
+ test('standalone zero-length fixed array of dynamic type', () => {
1821
+ // The head is a single offset word pointing at an empty tail.
1822
+ expect(
1823
+ AbiParameters.decode(
1824
+ [{ type: 'string[0]' }],
1825
+ '0x0000000000000000000000000000000000000000000000000000000000000020',
1826
+ ),
1827
+ ).toEqual([[]])
1828
+ expect(
1829
+ AbiParameters.decode(
1830
+ [{ type: 'bytes[0]' }],
1831
+ '0x0000000000000000000000000000000000000000000000000000000000000020',
1832
+ ),
1833
+ ).toEqual([[]])
1834
+ })
1835
+
1836
+ test('round-trip', () => {
1837
+ const cases = [
1838
+ {
1839
+ parameters: [{ type: 'uint256[0]' }, { type: 'uint256' }],
1840
+ values: [[], 3n],
1841
+ },
1842
+ {
1843
+ parameters: [{ type: 'uint256' }, { type: 'tuple', components: [] }],
1844
+ values: [5n, []],
1845
+ },
1846
+ {
1847
+ parameters: [{ type: 'string[0]' }, { type: 'uint256' }],
1848
+ values: [[], 3n],
1849
+ },
1850
+ {
1851
+ parameters: [{ type: 'uint256[0]' }, { type: 'string' }],
1852
+ values: [[], 'hello'],
1853
+ },
1854
+ {
1855
+ parameters: [{ type: 'uint256[0][2]' }, { type: 'uint256' }],
1856
+ values: [[[], []], 9n],
1857
+ },
1858
+ {
1859
+ parameters: [{ type: 'string[0]' }],
1860
+ values: [[]],
1861
+ },
1862
+ {
1863
+ parameters: [{ type: 'tuple', components: [{ type: 'string[0]' }] }],
1864
+ values: [[[]]],
1865
+ },
1866
+ ] as const
1867
+ for (const { parameters, values } of cases) {
1868
+ expect(
1869
+ AbiParameters.decode(
1870
+ parameters,
1871
+ AbiParameters.encode(parameters, values as never),
1872
+ ),
1873
+ ).toEqual(values)
1874
+ }
1875
+ })
1876
+ })
@@ -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
+ })
@@ -150,7 +150,8 @@ export function decodeArray(
150
150
 
151
151
  // If the length of the array is not known in advance (dynamic array),
152
152
  // this means we will need to wonder off to the pointer and decode.
153
- if (!length) {
153
+ // Note: zero-length fixed arrays (`T[0]`) are not dynamic.
154
+ if (length === null) {
154
155
  // Dealing with a dynamic type, so get the offset of the array data.
155
156
  const offset = Bytes.toNumber(cursor.readBytes(sizeOfOffset))
156
157
 
@@ -177,6 +178,12 @@ export function decodeArray(
177
178
  })
178
179
  consumed += consumed_
179
180
  value.push(data)
181
+ // Charge zero-width elements against the read limit to bound work
182
+ // on huge lengths of zero-width types (e.g. `uint256[0][]`).
183
+ if (consumed_ === 0) {
184
+ cursor.assertReadLimit()
185
+ cursor._touch()
186
+ }
180
187
  }
181
188
 
182
189
  // As we have gone wondering, restore to the original position + next slot.
@@ -206,7 +213,10 @@ export function decodeArray(
206
213
  }
207
214
 
208
215
  // As we have gone wondering, restore to the original position + next slot.
209
- cursor.setPosition(staticPosition + 32)
216
+ // Zero-length arrays of dynamic types (e.g. `string[0]`) have no tail, so
217
+ // the next slot may sit past the end of the data.
218
+ if (staticPosition + 32 < cursor.bytes.length)
219
+ cursor.setPosition(staticPosition + 32)
210
220
  return [value, 32]
211
221
  }
212
222
 
@@ -221,6 +231,12 @@ export function decodeArray(
221
231
  })
222
232
  consumed += consumed_
223
233
  value.push(data)
234
+ // Charge zero-width elements against the read limit to bound work
235
+ // on huge lengths of zero-width types (e.g. `uint256[0][4294967295]`).
236
+ if (consumed_ === 0) {
237
+ cursor.assertReadLimit()
238
+ cursor._touch()
239
+ }
224
240
  }
225
241
  return [value, consumed]
226
242
  }
@@ -593,7 +609,9 @@ export function encodeArray<const parameter extends AbiParameters.Parameter>(
593
609
  type: `${parameter.type}[${length}]`,
594
610
  })
595
611
 
596
- let dynamicChild = false
612
+ // Zero-length fixed arrays of dynamic types (e.g. `string[0]`) are dynamic
613
+ // per the ABI spec, even though they have no elements to inspect.
614
+ let dynamicChild = value.length === 0 && hasDynamicChild(parameter)
597
615
  const preparedParameters: PreparedParameter[] = []
598
616
  for (let i = 0; i < value.length; i++) {
599
617
  const preparedParam = prepareParameter({
@@ -218,6 +218,26 @@ export type Eth = RpcSchema.From<
218
218
  }
219
219
  ReturnType: Fee.FeeHistoryRpc
220
220
  }
221
+ /**
222
+ * Fills the defaults (nonce, gas, gasPrice, or 1559 fields) on a given unsigned transaction, and returns the unsigned transaction along with its raw form
223
+ *
224
+ * @example
225
+ * ```
226
+ * request({ method: 'eth_fillTransaction', params: [{ from: '0x...', to: '0x...', value: '0x...' }] })
227
+ * // { raw: '0x...', tx: { ... } }
228
+ * ```
229
+ */
230
+ | {
231
+ Request: {
232
+ method: 'eth_fillTransaction'
233
+ params: [transaction: TransactionRequest.Rpc]
234
+ }
235
+ ReturnType: {
236
+ capabilities?: Record<string, unknown> | undefined
237
+ raw: Hex.Hex
238
+ tx: Transaction.Rpc
239
+ }
240
+ }
221
241
  /**
222
242
  * Returns the current price of gas expressed in wei
223
243
  *
@@ -425,6 +445,22 @@ export type Eth = RpcSchema.From<
425
445
  }
426
446
  ReturnType: AccountProof.Rpc
427
447
  }
448
+ /**
449
+ * Returns the raw, serialized transaction specified by hash
450
+ *
451
+ * @example
452
+ * ```
453
+ * request({ method: 'eth_getRawTransactionByHash', params: ['0x...'] })
454
+ * // '0x...'
455
+ * ```
456
+ */
457
+ | {
458
+ Request: {
459
+ method: 'eth_getRawTransactionByHash'
460
+ params: [hash: Hex.Hex]
461
+ }
462
+ ReturnType: Hex.Hex | null
463
+ }
428
464
  /**
429
465
  * Returns the value from a storage position at an address
430
466
  *