quantumcoin 7.0.12 → 7.0.14

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 (214) hide show
  1. package/README-SDK.md +828 -823
  2. package/README.md +4 -0
  3. package/config.d.ts +50 -50
  4. package/examples/example-generated-sdk-js/README.md +65 -0
  5. package/examples/example-generated-sdk-js/examples/_test-wallet.js +17 -0
  6. package/examples/example-generated-sdk-js/examples/deploy.js +41 -0
  7. package/examples/example-generated-sdk-js/examples/events.js +36 -0
  8. package/examples/example-generated-sdk-js/examples/read-operations.js +46 -0
  9. package/examples/example-generated-sdk-js/examples/write-operations.js +44 -0
  10. package/examples/example-generated-sdk-js/index.d.ts +1 -0
  11. package/examples/example-generated-sdk-js/index.js +15 -0
  12. package/examples/example-generated-sdk-js/package-lock.json +59 -0
  13. package/examples/example-generated-sdk-js/package.json +22 -0
  14. package/examples/example-generated-sdk-js/src/SimpleERC20.d.ts +19 -0
  15. package/examples/example-generated-sdk-js/src/SimpleERC20.js +353 -0
  16. package/examples/example-generated-sdk-js/src/SimpleERC20__factory.d.ts +10 -0
  17. package/examples/example-generated-sdk-js/src/SimpleERC20__factory.js +29 -0
  18. package/examples/example-generated-sdk-js/src/index.d.ts +4 -0
  19. package/examples/example-generated-sdk-js/src/index.js +5 -0
  20. package/examples/example-generated-sdk-js/src/quantumcoin-shims.d.ts +23 -0
  21. package/examples/example-generated-sdk-js/src/types.d.ts +3 -0
  22. package/examples/example-generated-sdk-js/src/types.js +3 -0
  23. package/examples/example-generated-sdk-js/test/e2e/SimpleERC20.e2e.test.js +78 -0
  24. package/examples/example-generated-sdk-ts/README.md +65 -0
  25. package/examples/example-generated-sdk-ts/examples/_test-wallet.js +17 -0
  26. package/examples/example-generated-sdk-ts/examples/deploy.js +41 -0
  27. package/examples/example-generated-sdk-ts/examples/events.js +36 -0
  28. package/examples/example-generated-sdk-ts/examples/read-operations.js +46 -0
  29. package/examples/example-generated-sdk-ts/examples/write-operations.js +44 -0
  30. package/examples/example-generated-sdk-ts/index.d.ts +1 -0
  31. package/examples/example-generated-sdk-ts/index.js +15 -0
  32. package/examples/example-generated-sdk-ts/package-lock.json +59 -0
  33. package/examples/example-generated-sdk-ts/package.json +23 -0
  34. package/examples/example-generated-sdk-ts/src/SimpleERC20.ts +334 -0
  35. package/examples/example-generated-sdk-ts/src/SimpleERC20__factory.ts +28 -0
  36. package/examples/example-generated-sdk-ts/src/index.ts +4 -0
  37. package/examples/example-generated-sdk-ts/src/quantumcoin-shims.d.ts +23 -0
  38. package/examples/example-generated-sdk-ts/src/types.ts +4 -0
  39. package/examples/example-generated-sdk-ts/test/e2e/SimpleERC20.e2e.test.js +78 -0
  40. package/examples/example-generated-sdk-ts/tsconfig.json +14 -0
  41. package/examples/node_modules/.package-lock.json +5 -5
  42. package/examples/node_modules/quantum-coin-js-sdk/README.md +5 -5
  43. package/examples/node_modules/quantum-coin-js-sdk/example/package-lock.json +1 -1
  44. package/examples/node_modules/quantum-coin-js-sdk/index.d.ts +1031 -1031
  45. package/examples/node_modules/quantum-coin-js-sdk/index.js +15 -15
  46. package/examples/node_modules/quantum-coin-js-sdk/package.json +1 -1
  47. package/examples/node_modules/quantum-coin-js-sdk/wasmBase64.js +2 -2
  48. package/examples/package-lock.json +6 -6
  49. package/examples/package.json +1 -1
  50. package/examples/sdk-generator-erc20.inline.json +251 -251
  51. package/generate-sdk.js +1845 -1822
  52. package/package.json +2 -2
  53. package/src/abi/fragments.d.ts +42 -42
  54. package/src/abi/index.d.ts +13 -13
  55. package/src/abi/interface.js +11 -2
  56. package/src/abi/js-abi-coder.js +61 -2
  57. package/src/contract/contract.js +53 -5
  58. package/src/contract/index.d.ts +9 -9
  59. package/src/errors/index.d.ts +92 -92
  60. package/src/generator/index.d.ts +11 -4
  61. package/src/generator/index.js +185 -18
  62. package/src/internal/hex.d.ts +68 -61
  63. package/src/internal/hex.js +36 -0
  64. package/src/providers/json-rpc-provider.d.ts +12 -12
  65. package/src/providers/provider.js +141 -8
  66. package/src/utils/address.d.ts +58 -58
  67. package/src/utils/encoding.d.ts +120 -120
  68. package/src/utils/hashing.js +298 -298
  69. package/src/utils/index.d.ts +63 -63
  70. package/src/utils/index.js +14 -14
  71. package/src/utils/result.d.ts +57 -57
  72. package/src/utils/rlp.d.ts +12 -12
  73. package/src/utils/rlp.js +13 -1
  74. package/src/utils/units.d.ts +29 -29
  75. package/src/wallet/index.d.ts +10 -10
  76. package/src/wallet/wallet.d.ts +192 -192
  77. package/src/wallet/wallet.js +713 -630
  78. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/README.md +83 -0
  79. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/artifacts/AllSolidityTypes.abi.json +12544 -0
  80. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/artifacts/AllSolidityTypes.bin +1 -0
  81. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/examples/_test-wallet.js +17 -0
  82. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/examples/_test-wallet.ts +10 -0
  83. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/examples/deploy.js +41 -0
  84. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/examples/deploy.ts +41 -0
  85. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/examples/events.js +36 -0
  86. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/examples/events.ts +36 -0
  87. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/examples/offline-signing.js +82 -0
  88. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/examples/offline-signing.ts +80 -0
  89. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/examples/read-operations.js +46 -0
  90. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/examples/read-operations.ts +44 -0
  91. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/examples/write-operations.js +44 -0
  92. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/examples/write-operations.ts +44 -0
  93. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/index.d.ts +1 -0
  94. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/index.js +21 -0
  95. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/package-lock.json +597 -0
  96. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/package.json +25 -0
  97. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/src/AllSolidityTypes.d.ts +1280 -0
  98. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/src/AllSolidityTypes.js +14021 -0
  99. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/src/AllSolidityTypes__factory.d.ts +11 -0
  100. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/src/AllSolidityTypes__factory.js +31 -0
  101. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/src/index.d.ts +4 -0
  102. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/src/index.js +5 -0
  103. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/src/quantumcoin-shims.d.ts +25 -0
  104. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/src/types.d.ts +3 -0
  105. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/src/types.js +3 -0
  106. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/test/e2e/AllSolidityTypes.e2e.test.js +77 -0
  107. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/test/e2e/AllSolidityTypes.extra.test.js +195 -0
  108. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/README.md +83 -0
  109. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/artifacts/AllSolidityTypes.abi.json +12544 -0
  110. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/artifacts/AllSolidityTypes.bin +1 -0
  111. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/examples/_test-wallet.js +17 -0
  112. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/examples/_test-wallet.ts +10 -0
  113. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/examples/deploy.js +41 -0
  114. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/examples/deploy.ts +41 -0
  115. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/examples/events.js +36 -0
  116. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/examples/events.ts +36 -0
  117. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/examples/offline-signing.js +82 -0
  118. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/examples/offline-signing.ts +80 -0
  119. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/examples/read-operations.js +46 -0
  120. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/examples/read-operations.ts +44 -0
  121. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/examples/write-operations.js +44 -0
  122. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/examples/write-operations.ts +44 -0
  123. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/index.d.ts +1 -0
  124. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/index.js +21 -0
  125. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/package-lock.json +597 -0
  126. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/package.json +26 -0
  127. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/src/AllSolidityTypes.ts +13940 -0
  128. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/src/AllSolidityTypes__factory.ts +31 -0
  129. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/src/index.ts +4 -0
  130. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/src/quantumcoin-shims.d.ts +25 -0
  131. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/src/types.ts +4 -0
  132. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/test/e2e/AllSolidityTypes.e2e.test.js +77 -0
  133. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/test/e2e/AllSolidityTypes.extra.test.js +195 -0
  134. package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/tsconfig.json +18 -0
  135. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/README.md +74 -0
  136. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/artifacts/SimpleERC20.abi.json +245 -0
  137. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/artifacts/SimpleERC20.bin +1 -0
  138. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/examples/_test-wallet.js +17 -0
  139. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/examples/_test-wallet.ts +10 -0
  140. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/examples/deploy.js +41 -0
  141. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/examples/deploy.ts +41 -0
  142. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/examples/events.js +36 -0
  143. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/examples/events.ts +36 -0
  144. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/examples/offline-signing.js +82 -0
  145. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/examples/offline-signing.ts +80 -0
  146. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/examples/read-operations.js +46 -0
  147. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/examples/read-operations.ts +44 -0
  148. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/examples/write-operations.js +44 -0
  149. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/examples/write-operations.ts +44 -0
  150. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/index.d.ts +1 -0
  151. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/index.js +16 -0
  152. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/package-lock.json +597 -0
  153. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/package.json +25 -0
  154. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/src/SimpleERC20.d.ts +24 -0
  155. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/src/SimpleERC20.js +378 -0
  156. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/src/SimpleERC20__factory.d.ts +10 -0
  157. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/src/SimpleERC20__factory.js +31 -0
  158. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/src/index.d.ts +4 -0
  159. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/src/index.js +5 -0
  160. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/src/quantumcoin-shims.d.ts +25 -0
  161. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/src/types.d.ts +3 -0
  162. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/src/types.js +3 -0
  163. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/test/e2e/SimpleERC20.e2e.test.js +90 -0
  164. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/README.md +74 -0
  165. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/artifacts/SimpleERC20.abi.json +245 -0
  166. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/artifacts/SimpleERC20.bin +1 -0
  167. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/examples/_test-wallet.js +17 -0
  168. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/examples/_test-wallet.ts +10 -0
  169. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/examples/deploy.js +41 -0
  170. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/examples/deploy.ts +41 -0
  171. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/examples/events.js +36 -0
  172. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/examples/events.ts +36 -0
  173. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/examples/offline-signing.js +82 -0
  174. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/examples/offline-signing.ts +80 -0
  175. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/examples/read-operations.js +46 -0
  176. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/examples/read-operations.ts +44 -0
  177. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/examples/write-operations.js +44 -0
  178. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/examples/write-operations.ts +44 -0
  179. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/index.d.ts +1 -0
  180. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/index.js +16 -0
  181. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/package-lock.json +597 -0
  182. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/package.json +26 -0
  183. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/src/SimpleERC20.ts +361 -0
  184. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/src/SimpleERC20__factory.ts +30 -0
  185. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/src/index.ts +4 -0
  186. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/src/quantumcoin-shims.d.ts +25 -0
  187. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/src/types.ts +4 -0
  188. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/test/e2e/SimpleERC20.e2e.test.js +90 -0
  189. package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/tsconfig.json +18 -0
  190. package/test/e2e/generator-interface.e2e.test.js +165 -0
  191. package/test/e2e/generator-interface.e2e.test.ts +160 -0
  192. package/test/e2e/signing-context-and-fee.e2e.test.js +141 -141
  193. package/test/e2e/signing-context-and-fee.e2e.test.ts +128 -128
  194. package/test/integration/provider.test.js +88 -88
  195. package/test/security/abi-decoder-bounds.test.js +122 -0
  196. package/test/security/contract-overrides.test.js +112 -0
  197. package/test/security/generator-injection.test.js +195 -0
  198. package/test/security/malformed-input.test.js +26 -27
  199. package/test/security/rpc-numeric-bounds.test.js +81 -0
  200. package/test/security/rpc-trust.test.js +202 -0
  201. package/test/unit/abi-interface.test.js +12 -5
  202. package/test/unit/abi-interface.test.ts +8 -1
  203. package/test/unit/address-wallet.test.js +923 -892
  204. package/test/unit/address-wallet.test.ts +877 -877
  205. package/test/unit/encoding-units-rlp.test.js +35 -0
  206. package/test/unit/generator.test.js +48 -1
  207. package/test/unit/generator.test.ts +48 -1
  208. package/test/unit/hashing.test.js +64 -64
  209. package/test/unit/hashing.test.ts +63 -63
  210. package/test/unit/internal-hex.test.js +32 -1
  211. package/test/unit/internal-hex.test.ts +32 -1
  212. package/test/unit/populate-transaction.test.js +33 -0
  213. package/test/unit/providers.test.js +51 -1
  214. package/test/unit/providers.test.ts +53 -0
@@ -7,7 +7,7 @@
7
7
 
8
8
  const { EventEmitter } = require("events");
9
9
  const { makeError, assertArgument } = require("../errors");
10
- const { normalizeHex, isHexString } = require("../internal/hex");
10
+ const { normalizeHex, toQuantityHex, isHexString } = require("../internal/hex");
11
11
 
12
12
  /**
13
13
  * @typedef {import("../utils/encoding").BytesLike} BytesLike
@@ -44,7 +44,17 @@ function _hexToBigInt(hex) {
44
44
  }
45
45
 
46
46
  function _hexToNumber(hex) {
47
- return Number(_hexToBigInt(hex));
47
+ // RPC quantities are untrusted. Previously `Number(bigint)` silently
48
+ // truncated values above 2^53, corrupting blockNumber/nonce/status/indices used
49
+ // in confirmation math. We keep returning a `number` (no signature/type change),
50
+ // but fail loudly for out-of-range values instead of returning a corrupted one.
51
+ // Real chain values are far below MAX_SAFE_INTEGER, so honest flows are
52
+ // unaffected. (Returning bigint would break field types and wait() arithmetic.)
53
+ const bi = _hexToBigInt(hex);
54
+ if (bi > BigInt(Number.MAX_SAFE_INTEGER) || bi < BigInt(Number.MIN_SAFE_INTEGER)) {
55
+ throw makeError("RPC quantity exceeds safe integer range", "NUMERIC_FAULT", { value: bi.toString() });
56
+ }
57
+ return Number(bi);
48
58
  }
49
59
 
50
60
  /**
@@ -52,13 +62,54 @@ function _hexToNumber(hex) {
52
62
  * @param {number|string|undefined} blockTag
53
63
  * @returns {string|undefined}
54
64
  */
65
+ /**
66
+ * Build a lowercase Set of allowed log addresses from a filter's `address` field
67
+ * (string or string[]). Returns null when no address constraint is present.
68
+ * @param {string|string[]|undefined|null} address
69
+ * @returns {Set<string>|null}
70
+ */
71
+ function _normalizeAddressFilter(address) {
72
+ if (address == null) return null;
73
+ const list = Array.isArray(address) ? address : [address];
74
+ const set = new Set();
75
+ for (const a of list) {
76
+ if (typeof a === "string" && a.length > 0) set.add(a.toLowerCase());
77
+ }
78
+ return set.size ? set : null;
79
+ }
80
+
81
+ /**
82
+ * Check a log's topics against a requested topics filter (eth_getLogs
83
+ * semantics). Each filter position may be null (wildcard), a string (exact
84
+ * match), or an array of strings (any match). Used to drop logs a malicious node
85
+ * returns that do not actually match the requested event topic(s).
86
+ * @param {any[]} logTopics
87
+ * @param {(string|string[]|null)[]} filterTopics
88
+ * @returns {boolean}
89
+ */
90
+ function _topicsMatch(logTopics, filterTopics) {
91
+ if (!Array.isArray(filterTopics)) return true;
92
+ const topics = Array.isArray(logTopics) ? logTopics : [];
93
+ for (let i = 0; i < filterTopics.length; i++) {
94
+ const want = filterTopics[i];
95
+ if (want == null) continue; // wildcard position
96
+ const have = typeof topics[i] === "string" ? topics[i].toLowerCase() : null;
97
+ if (have == null) return false;
98
+ const allowed = (Array.isArray(want) ? want : [want])
99
+ .filter((t) => typeof t === "string")
100
+ .map((t) => t.toLowerCase());
101
+ if (allowed.length && !allowed.includes(have)) return false;
102
+ }
103
+ return true;
104
+ }
105
+
55
106
  function _blockTagToHex(blockTag) {
56
107
  if (blockTag === undefined || blockTag === null) return undefined;
57
108
  const s = String(blockTag).toLowerCase();
58
109
  if (s === "latest" || s === "pending" || s === "earliest") return s;
59
110
  const n = typeof blockTag === "number" ? blockTag : Number(blockTag);
60
111
  if (!Number.isInteger(n) || n < 0) return undefined;
61
- return normalizeHex("0x" + n.toString(16));
112
+ return toQuantityHex(n);
62
113
  }
63
114
 
64
115
  /**
@@ -251,7 +302,7 @@ class AbstractProvider extends Provider {
251
302
  * @returns {Promise<Block>}
252
303
  */
253
304
  async getBlock(blockNumber) {
254
- const tag = blockNumber === "latest" ? "latest" : normalizeHex("0x" + Number(blockNumber).toString(16));
305
+ const tag = blockNumber === "latest" ? "latest" : toQuantityHex(blockNumber);
255
306
  const block = await this._perform("eth_getBlockByNumber", [tag, false]);
256
307
  return new Block(block, this);
257
308
  }
@@ -263,7 +314,23 @@ class AbstractProvider extends Provider {
263
314
  async getTransaction(txHash) {
264
315
  const tx = await this._perform("eth_getTransactionByHash", [txHash]);
265
316
  if (!tx) return null;
266
- return new TransactionResponse(tx, this);
317
+ const result = new TransactionResponse(tx, this);
318
+ // Do not trust the node to return the transaction we actually asked for.
319
+ // When the response carries a hash, it must match the requested hash;
320
+ // otherwise a malicious node could substitute a different transaction.
321
+ if (
322
+ typeof txHash === "string" &&
323
+ typeof result.hash === "string" &&
324
+ result.hash.length > 0 &&
325
+ result.hash.toLowerCase() !== txHash.toLowerCase()
326
+ ) {
327
+ throw makeError("RPC node returned a transaction whose hash does not match the requested hash", "UNKNOWN_ERROR", {
328
+ operation: "getTransaction",
329
+ expected: txHash,
330
+ got: result.hash,
331
+ });
332
+ }
333
+ return result;
267
334
  }
268
335
 
269
336
  /**
@@ -273,7 +340,23 @@ class AbstractProvider extends Provider {
273
340
  async getTransactionReceipt(txHash) {
274
341
  const receipt = await this._perform("eth_getTransactionReceipt", [txHash]);
275
342
  if (!receipt) return null;
276
- return new TransactionReceipt(receipt, this);
343
+ const result = new TransactionReceipt(receipt, this);
344
+ // The receipt must belong to the transaction we asked about. A node must
345
+ // not be able to confirm an unrelated/fabricated transaction (which would let
346
+ // wait() report success for the wrong tx).
347
+ if (
348
+ typeof txHash === "string" &&
349
+ typeof result.transactionHash === "string" &&
350
+ result.transactionHash.length > 0 &&
351
+ result.transactionHash.toLowerCase() !== txHash.toLowerCase()
352
+ ) {
353
+ throw makeError("RPC node returned a receipt whose hash does not match the requested hash", "UNKNOWN_ERROR", {
354
+ operation: "getTransactionReceipt",
355
+ expected: txHash,
356
+ got: result.transactionHash,
357
+ });
358
+ }
359
+ return result;
277
360
  }
278
361
 
279
362
  /**
@@ -299,15 +382,47 @@ class AbstractProvider extends Provider {
299
382
  /**
300
383
  * Broadcasts a signed transaction.
301
384
  * @param {TransactionRequest|string} tx
385
+ * @param {{ expectedHash?: string }=} opts Optional. When `expectedHash` is set,
386
+ * the hash returned by the node (and the fetched-back transaction's hash) must
387
+ * match it, otherwise an error is thrown (do not trust the RPC node to
388
+ * broadcast the exact transaction that was signed).
302
389
  * @returns {Promise<TransactionResponse>}
303
390
  */
304
- async sendTransaction(tx) {
391
+ async sendTransaction(tx, opts) {
305
392
  // For QuantumCoin.js, tx is expected to be a signed raw transaction hex string.
306
393
  const raw = typeof tx === "string" ? tx : tx?.raw;
307
394
  if (typeof raw !== "string") throw makeError("sendTransaction requires a signed raw transaction string", "INVALID_ARGUMENT", { tx });
395
+ const expectedHash =
396
+ opts && typeof opts.expectedHash === "string" && opts.expectedHash.length > 0 ? opts.expectedHash.toLowerCase() : null;
397
+
308
398
  const hash = await this._perform("eth_sendRawTransaction", [raw]);
399
+
400
+ // The node returns the hash it claims to have accepted. If we know the
401
+ // hash of the transaction we signed, reject any mismatch — a malicious or
402
+ // buggy node must not be able to silently substitute a different transaction.
403
+ if (expectedHash != null && typeof hash === "string" && hash.length > 0) {
404
+ if (hash.toLowerCase() !== expectedHash) {
405
+ throw makeError("RPC node returned a transaction hash that does not match the signed transaction", "UNKNOWN_ERROR", {
406
+ operation: "sendTransaction",
407
+ expected: expectedHash,
408
+ got: hash,
409
+ });
410
+ }
411
+ }
412
+
309
413
  // Fetch back transaction (best-effort)
310
414
  const result = await this.getTransaction(hash);
415
+
416
+ // Verify the fetched-back transaction's hash too, so a node cannot return
417
+ // a fabricated transaction object under the correct hash lookup.
418
+ if (result && expectedHash != null && typeof result.hash === "string" && result.hash.toLowerCase() !== expectedHash) {
419
+ throw makeError("RPC node returned a transaction whose hash does not match the signed transaction", "UNKNOWN_ERROR", {
420
+ operation: "sendTransaction",
421
+ expected: expectedHash,
422
+ got: result.hash,
423
+ });
424
+ }
425
+
311
426
  return result || new TransactionResponse({ hash }, this);
312
427
  }
313
428
 
@@ -376,7 +491,25 @@ class AbstractProvider extends Provider {
376
491
  if (fromBlock !== undefined) normalized.fromBlock = fromBlock;
377
492
  if (toBlock !== undefined) normalized.toBlock = toBlock;
378
493
  const logs = await this._perform("eth_getLogs", [normalized]);
379
- return (logs || []).map((l) => new Log(l, this));
494
+ const mapped = (logs || []).map((l) => new Log(l, this));
495
+
496
+ // A malicious node could return logs emitted by contracts other than the
497
+ // one(s) requested. When the filter constrains the address, drop any log whose
498
+ // address is not in that set so foreign-contract events cannot be injected.
499
+ const allowed = _normalizeAddressFilter(filter.address);
500
+ // A malicious node could return logs for a different event (different
501
+ // topic0) or from foreign contracts. Drop anything that does not match the
502
+ // requested address and topic constraints.
503
+ const hasTopicFilter = Array.isArray(filter.topics) && filter.topics.some((t) => t != null);
504
+ if (allowed || hasTopicFilter) {
505
+ return mapped.filter((l) => {
506
+ if (!l) return false;
507
+ if (allowed && !(typeof l.address === "string" && allowed.has(l.address.toLowerCase()))) return false;
508
+ if (hasTopicFilter && !_topicsMatch(l.topics, filter.topics)) return false;
509
+ return true;
510
+ });
511
+ }
512
+ return mapped;
380
513
  }
381
514
  }
382
515
 
@@ -1,58 +1,58 @@
1
- /**
2
- * Checks if string is a valid address (32 bytes, 66 hex characters).
3
- * @param {string} address
4
- * @returns {boolean}
5
- */
6
- export function isAddress(address: string): boolean;
7
- /**
8
- * Returns normalized address.
9
- * Note: QuantumCoin checksumming uses QuantumCoin conventions; currently this normalizes to lowercase.
10
- * @param {string} address
11
- * @returns {string}
12
- */
13
- export function getAddress(address: string): string;
14
- /**
15
- * Returns true if value is an object implementing Addressable (has getAddress()).
16
- * @param {any} value
17
- * @returns {boolean}
18
- */
19
- export function isAddressable(value: any): boolean;
20
- /**
21
- * Resolve an AddressLike into a string address.
22
- * For QuantumCoin, ENS is not supported.
23
- * @param {any} target
24
- * @returns {string|Promise<string>}
25
- */
26
- export function resolveAddress(target: any): string | Promise<string>;
27
- /**
28
- * Calculates contract address from deployer and nonce.
29
- * @param {{ from: string, nonce: number }} tx
30
- * @returns {string}
31
- */
32
- export function getContractAddress(tx: {
33
- from: string;
34
- nonce: number;
35
- }): string;
36
- /**
37
- * Alias for getContractAddress.
38
- * @param {{ from: string, nonce: number }} tx
39
- * @returns {string}
40
- */
41
- export function getCreateAddress(tx: {
42
- from: string;
43
- nonce: number;
44
- }): string;
45
- /**
46
- * Calculates CREATE2 contract address.
47
- * @param {string} from
48
- * @param {string} salt
49
- * @param {string} initCodeHash
50
- * @returns {string}
51
- */
52
- export function getCreate2Address(from: string, salt: string, initCodeHash: string): string;
53
- /**
54
- * Computes address from a public key.
55
- * @param {string|Uint8Array} key
56
- * @returns {string}
57
- */
58
- export function computeAddress(key: string | Uint8Array): string;
1
+ /**
2
+ * Checks if string is a valid address (32 bytes, 66 hex characters).
3
+ * @param {string} address
4
+ * @returns {boolean}
5
+ */
6
+ export function isAddress(address: string): boolean;
7
+ /**
8
+ * Returns normalized address.
9
+ * Note: QuantumCoin checksumming uses QuantumCoin conventions; currently this normalizes to lowercase.
10
+ * @param {string} address
11
+ * @returns {string}
12
+ */
13
+ export function getAddress(address: string): string;
14
+ /**
15
+ * Returns true if value is an object implementing Addressable (has getAddress()).
16
+ * @param {any} value
17
+ * @returns {boolean}
18
+ */
19
+ export function isAddressable(value: any): boolean;
20
+ /**
21
+ * Resolve an AddressLike into a string address.
22
+ * For QuantumCoin, ENS is not supported.
23
+ * @param {any} target
24
+ * @returns {string|Promise<string>}
25
+ */
26
+ export function resolveAddress(target: any): string | Promise<string>;
27
+ /**
28
+ * Calculates contract address from deployer and nonce.
29
+ * @param {{ from: string, nonce: number }} tx
30
+ * @returns {string}
31
+ */
32
+ export function getContractAddress(tx: {
33
+ from: string;
34
+ nonce: number;
35
+ }): string;
36
+ /**
37
+ * Alias for getContractAddress.
38
+ * @param {{ from: string, nonce: number }} tx
39
+ * @returns {string}
40
+ */
41
+ export function getCreateAddress(tx: {
42
+ from: string;
43
+ nonce: number;
44
+ }): string;
45
+ /**
46
+ * Calculates CREATE2 contract address.
47
+ * @param {string} from
48
+ * @param {string} salt
49
+ * @param {string} initCodeHash
50
+ * @returns {string}
51
+ */
52
+ export function getCreate2Address(from: string, salt: string, initCodeHash: string): string;
53
+ /**
54
+ * Computes address from a public key.
55
+ * @param {string|Uint8Array} key
56
+ * @returns {string}
57
+ */
58
+ export function computeAddress(key: string | Uint8Array): string;
@@ -1,120 +1,120 @@
1
- export type BytesLike = string | Uint8Array;
2
- /**
3
- * @typedef {string | Uint8Array} BytesLike
4
- */
5
- /**
6
- * Converts bytes to UTF-8 string.
7
- * @param {BytesLike} data
8
- * @returns {string}
9
- */
10
- export function toUtf8String(data: BytesLike): string;
11
- /**
12
- * Converts string to UTF-8 bytes.
13
- * @param {string} str
14
- * @returns {Uint8Array}
15
- */
16
- export function toUtf8Bytes(str: string): Uint8Array;
17
- /**
18
- * Converts data to hex string.
19
- * @param {BytesLike} data
20
- * @returns {string}
21
- */
22
- export function toHex(data: BytesLike): string;
23
- /**
24
- * Alias for toHex.
25
- * @param {BytesLike} data
26
- * @returns {string}
27
- */
28
- export function hexlify(data: BytesLike): string;
29
- /**
30
- * Converts data to byte array.
31
- * @param {BytesLike} data
32
- * @returns {Uint8Array}
33
- */
34
- export function arrayify(data: BytesLike): Uint8Array;
35
- /**
36
- * Concatenates byte arrays and returns a hex string.
37
- * @param {BytesLike[]} items
38
- * @returns {string}
39
- */
40
- export function concat(items: BytesLike[]): string;
41
- /**
42
- * Strips leading zeros from a hex string.
43
- * @param {BytesLike} data
44
- * @returns {string}
45
- */
46
- export function stripZerosLeft(data: BytesLike): string;
47
- /**
48
- * Encodes a short UTF-8 string into a bytes32 hex string.
49
- * @param {string} text
50
- * @returns {string}
51
- */
52
- export function encodeBytes32String(text: string): string;
53
- /**
54
- * Decodes a bytes32 hex string into a UTF-8 string (trailing zeros stripped).
55
- * @param {BytesLike} bytes
56
- * @returns {string}
57
- */
58
- export function decodeBytes32String(bytes: BytesLike): string;
59
- /**
60
- * Decode Base58 string to bytes.
61
- * @param {string} data
62
- * @returns {Uint8Array}
63
- */
64
- export function decodeBase58(data: string): Uint8Array;
65
- /**
66
- * Base64 decode to bytes.
67
- * @param {string} data
68
- * @returns {Uint8Array}
69
- */
70
- export function decodeBase64(data: string): Uint8Array;
71
- /**
72
- * Encode BytesLike as Base58.
73
- * @param {BytesLike} data
74
- * @returns {string}
75
- */
76
- export function encodeBase58(data: BytesLike): string;
77
- /**
78
- * Base64 encode BytesLike.
79
- * @param {BytesLike} data
80
- * @returns {string}
81
- */
82
- export function encodeBase64(data: BytesLike): string;
83
- /**
84
- * Returns UTF-8 code points for a string.
85
- * @param {string} str
86
- * @returns {number[]}
87
- */
88
- export function toUtf8CodePoints(str: string): number[];
89
- import { isHexString } from "../internal/hex";
90
- /**
91
- * Returns true if value is BytesLike.
92
- * @param {any} value
93
- * @returns {boolean}
94
- */
95
- export function isBytesLike(value: any): boolean;
96
- /**
97
- * Pads a BytesLike value to the left with zeros (byte length).
98
- * @param {BytesLike} value
99
- * @param {number} length
100
- * @returns {string}
101
- */
102
- export function zeroPad(value: BytesLike, length: number): string;
103
- /**
104
- * Pads a hex value (interpreted as bytes) to the left with zeros (byte length).
105
- * @param {BytesLike} value
106
- * @param {number} length
107
- * @returns {string}
108
- */
109
- export function zeroPadValue(value: BytesLike, length: number): string;
110
- /**
111
- * Solidity packed encoding.
112
- * This is a complex helper in ethers.js; in QuantumCoin.js it is currently not implemented.
113
- * @throws
114
- */
115
- export function solidityPacked(): void;
116
- export function solidityPackedKeccak256(): void;
117
- export function solidityPackedSha256(): void;
118
- import { bytesToHex } from "../internal/hex";
119
- import { hexToBytes } from "../internal/hex";
120
- export { isHexString, bytesToHex, hexToBytes };
1
+ export type BytesLike = string | Uint8Array;
2
+ /**
3
+ * @typedef {string | Uint8Array} BytesLike
4
+ */
5
+ /**
6
+ * Converts bytes to UTF-8 string.
7
+ * @param {BytesLike} data
8
+ * @returns {string}
9
+ */
10
+ export function toUtf8String(data: BytesLike): string;
11
+ /**
12
+ * Converts string to UTF-8 bytes.
13
+ * @param {string} str
14
+ * @returns {Uint8Array}
15
+ */
16
+ export function toUtf8Bytes(str: string): Uint8Array;
17
+ /**
18
+ * Converts data to hex string.
19
+ * @param {BytesLike} data
20
+ * @returns {string}
21
+ */
22
+ export function toHex(data: BytesLike): string;
23
+ /**
24
+ * Alias for toHex.
25
+ * @param {BytesLike} data
26
+ * @returns {string}
27
+ */
28
+ export function hexlify(data: BytesLike): string;
29
+ /**
30
+ * Converts data to byte array.
31
+ * @param {BytesLike} data
32
+ * @returns {Uint8Array}
33
+ */
34
+ export function arrayify(data: BytesLike): Uint8Array;
35
+ /**
36
+ * Concatenates byte arrays and returns a hex string.
37
+ * @param {BytesLike[]} items
38
+ * @returns {string}
39
+ */
40
+ export function concat(items: BytesLike[]): string;
41
+ /**
42
+ * Strips leading zeros from a hex string.
43
+ * @param {BytesLike} data
44
+ * @returns {string}
45
+ */
46
+ export function stripZerosLeft(data: BytesLike): string;
47
+ /**
48
+ * Encodes a short UTF-8 string into a bytes32 hex string.
49
+ * @param {string} text
50
+ * @returns {string}
51
+ */
52
+ export function encodeBytes32String(text: string): string;
53
+ /**
54
+ * Decodes a bytes32 hex string into a UTF-8 string (trailing zeros stripped).
55
+ * @param {BytesLike} bytes
56
+ * @returns {string}
57
+ */
58
+ export function decodeBytes32String(bytes: BytesLike): string;
59
+ /**
60
+ * Decode Base58 string to bytes.
61
+ * @param {string} data
62
+ * @returns {Uint8Array}
63
+ */
64
+ export function decodeBase58(data: string): Uint8Array;
65
+ /**
66
+ * Base64 decode to bytes.
67
+ * @param {string} data
68
+ * @returns {Uint8Array}
69
+ */
70
+ export function decodeBase64(data: string): Uint8Array;
71
+ /**
72
+ * Encode BytesLike as Base58.
73
+ * @param {BytesLike} data
74
+ * @returns {string}
75
+ */
76
+ export function encodeBase58(data: BytesLike): string;
77
+ /**
78
+ * Base64 encode BytesLike.
79
+ * @param {BytesLike} data
80
+ * @returns {string}
81
+ */
82
+ export function encodeBase64(data: BytesLike): string;
83
+ /**
84
+ * Returns UTF-8 code points for a string.
85
+ * @param {string} str
86
+ * @returns {number[]}
87
+ */
88
+ export function toUtf8CodePoints(str: string): number[];
89
+ import { isHexString } from "../internal/hex";
90
+ /**
91
+ * Returns true if value is BytesLike.
92
+ * @param {any} value
93
+ * @returns {boolean}
94
+ */
95
+ export function isBytesLike(value: any): boolean;
96
+ /**
97
+ * Pads a BytesLike value to the left with zeros (byte length).
98
+ * @param {BytesLike} value
99
+ * @param {number} length
100
+ * @returns {string}
101
+ */
102
+ export function zeroPad(value: BytesLike, length: number): string;
103
+ /**
104
+ * Pads a hex value (interpreted as bytes) to the left with zeros (byte length).
105
+ * @param {BytesLike} value
106
+ * @param {number} length
107
+ * @returns {string}
108
+ */
109
+ export function zeroPadValue(value: BytesLike, length: number): string;
110
+ /**
111
+ * Solidity packed encoding.
112
+ * This is a complex helper in ethers.js; in QuantumCoin.js it is currently not implemented.
113
+ * @throws
114
+ */
115
+ export function solidityPacked(): void;
116
+ export function solidityPackedKeccak256(): void;
117
+ export function solidityPackedSha256(): void;
118
+ import { bytesToHex } from "../internal/hex";
119
+ import { hexToBytes } from "../internal/hex";
120
+ export { isHexString, bytesToHex, hexToBytes };