quantum-coin-js-sdk 2.0.1 → 2.1.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 (232) hide show
  1. package/README.md +13 -0
  2. package/index.d.ts +9 -0
  3. package/index.js +37 -4
  4. package/package.json +12 -4
  5. package/wasmBase64.js +3 -2
  6. package/.idea/.name +0 -1
  7. package/.idea/modules.xml +0 -8
  8. package/.idea/quantum-coin-js-sdk.iml +0 -12
  9. package/.idea/vcs.xml +0 -6
  10. package/.vs/ProjectSettings.json +0 -3
  11. package/.vs/VSWorkspaceState.json +0 -8
  12. package/.vs/quantum-coin-js-sdk/FileContentIndex/a9d6de82-cfc3-4c22-ac38-06d706ff3673.vsidx +0 -0
  13. package/.vs/quantum-coin-js-sdk/FileContentIndex/fdc816df-1898-4153-99f2-c69ef4c2283b.vsidx +0 -0
  14. package/.vs/quantum-coin-js-sdk/config/applicationhost.config +0 -1011
  15. package/.vs/quantum-coin-js-sdk/v17/.wsuo +0 -0
  16. package/.vs/quantum-coin-js-sdk/v17/DocumentLayout.backup.json +0 -39
  17. package/.vs/quantum-coin-js-sdk/v17/DocumentLayout.json +0 -57
  18. package/.vs/slnx.sqlite +0 -0
  19. package/example/README.md +0 -14
  20. package/example/conversion-example.js +0 -19
  21. package/example/example-create-contract.js +0 -396
  22. package/example/example-encode-decode-rlp.js +0 -225
  23. package/example/example-event-pack-unpack.js +0 -391
  24. package/example/example-misc.js +0 -96
  25. package/example/example-token-pack-unpack.js +0 -960
  26. package/example/example-wallet-version4.js +0 -34
  27. package/example/example-wallet.js +0 -39
  28. package/example/example.js +0 -115
  29. package/example/node_modules/.bin/sdkgen +0 -16
  30. package/example/node_modules/.bin/sdkgen.cmd +0 -17
  31. package/example/node_modules/.bin/sdkgen.ps1 +0 -28
  32. package/example/node_modules/.package-lock.json +0 -51
  33. package/example/node_modules/quantumcoin/.github/workflows/publish-npmjs.yaml +0 -22
  34. package/example/node_modules/quantumcoin/LICENSE +0 -21
  35. package/example/node_modules/quantumcoin/README-SDK.md +0 -828
  36. package/example/node_modules/quantumcoin/README.md +0 -197
  37. package/example/node_modules/quantumcoin/config.d.ts +0 -50
  38. package/example/node_modules/quantumcoin/config.js +0 -123
  39. package/example/node_modules/quantumcoin/examples/AllSolidityTypes.sol +0 -184
  40. package/example/node_modules/quantumcoin/examples/SimpleIERC20.sol +0 -74
  41. package/example/node_modules/quantumcoin/examples/events.js +0 -41
  42. package/example/node_modules/quantumcoin/examples/events.ts +0 -35
  43. package/example/node_modules/quantumcoin/examples/example-generator-sdk-js.js +0 -100
  44. package/example/node_modules/quantumcoin/examples/example-generator-sdk-js.ts +0 -77
  45. package/example/node_modules/quantumcoin/examples/example-generator-sdk-ts.js +0 -100
  46. package/example/node_modules/quantumcoin/examples/example-generator-sdk-ts.ts +0 -77
  47. package/example/node_modules/quantumcoin/examples/example.js +0 -67
  48. package/example/node_modules/quantumcoin/examples/example.ts +0 -56
  49. package/example/node_modules/quantumcoin/examples/offline-signing.js +0 -77
  50. package/example/node_modules/quantumcoin/examples/offline-signing.ts +0 -65
  51. package/example/node_modules/quantumcoin/examples/package-lock.json +0 -596
  52. package/example/node_modules/quantumcoin/examples/package.json +0 -32
  53. package/example/node_modules/quantumcoin/examples/read-operations.js +0 -32
  54. package/example/node_modules/quantumcoin/examples/read-operations.ts +0 -31
  55. package/example/node_modules/quantumcoin/examples/sdk-generator-erc20.inline.json +0 -251
  56. package/example/node_modules/quantumcoin/examples/solidity-types.ts +0 -43
  57. package/example/node_modules/quantumcoin/examples/wallet-offline.js +0 -36
  58. package/example/node_modules/quantumcoin/examples/wallet-offline.ts +0 -26
  59. package/example/node_modules/quantumcoin/generate-sdk.js +0 -1846
  60. package/example/node_modules/quantumcoin/index.js +0 -12
  61. package/example/node_modules/quantumcoin/package.json +0 -95
  62. package/example/node_modules/quantumcoin/scripts/copy-declarations.js +0 -31
  63. package/example/node_modules/quantumcoin/scripts/run-all-one-by-one.js +0 -151
  64. package/example/node_modules/quantumcoin/src/abi/fragments.d.ts +0 -42
  65. package/example/node_modules/quantumcoin/src/abi/fragments.js +0 -63
  66. package/example/node_modules/quantumcoin/src/abi/index.d.ts +0 -13
  67. package/example/node_modules/quantumcoin/src/abi/index.js +0 -9
  68. package/example/node_modules/quantumcoin/src/abi/interface.d.ts +0 -128
  69. package/example/node_modules/quantumcoin/src/abi/interface.js +0 -605
  70. package/example/node_modules/quantumcoin/src/abi/js-abi-coder.d.ts +0 -8
  71. package/example/node_modules/quantumcoin/src/abi/js-abi-coder.js +0 -538
  72. package/example/node_modules/quantumcoin/src/constants.d.ts +0 -61
  73. package/example/node_modules/quantumcoin/src/constants.js +0 -94
  74. package/example/node_modules/quantumcoin/src/contract/contract-factory.d.ts +0 -28
  75. package/example/node_modules/quantumcoin/src/contract/contract-factory.js +0 -111
  76. package/example/node_modules/quantumcoin/src/contract/contract.d.ts +0 -113
  77. package/example/node_modules/quantumcoin/src/contract/contract.js +0 -408
  78. package/example/node_modules/quantumcoin/src/contract/index.d.ts +0 -9
  79. package/example/node_modules/quantumcoin/src/contract/index.js +0 -9
  80. package/example/node_modules/quantumcoin/src/errors/index.d.ts +0 -92
  81. package/example/node_modules/quantumcoin/src/errors/index.js +0 -200
  82. package/example/node_modules/quantumcoin/src/generator/index.d.ts +0 -81
  83. package/example/node_modules/quantumcoin/src/generator/index.js +0 -1571
  84. package/example/node_modules/quantumcoin/src/index.d.ts +0 -122
  85. package/example/node_modules/quantumcoin/src/index.js +0 -41
  86. package/example/node_modules/quantumcoin/src/internal/hex.d.ts +0 -68
  87. package/example/node_modules/quantumcoin/src/internal/hex.js +0 -180
  88. package/example/node_modules/quantumcoin/src/providers/extra-providers.d.ts +0 -139
  89. package/example/node_modules/quantumcoin/src/providers/extra-providers.js +0 -614
  90. package/example/node_modules/quantumcoin/src/providers/index.d.ts +0 -17
  91. package/example/node_modules/quantumcoin/src/providers/index.js +0 -10
  92. package/example/node_modules/quantumcoin/src/providers/json-rpc-provider.d.ts +0 -12
  93. package/example/node_modules/quantumcoin/src/providers/json-rpc-provider.js +0 -89
  94. package/example/node_modules/quantumcoin/src/providers/provider.d.ts +0 -206
  95. package/example/node_modules/quantumcoin/src/providers/provider.js +0 -524
  96. package/example/node_modules/quantumcoin/src/types/index.d.ts +0 -214
  97. package/example/node_modules/quantumcoin/src/types/index.js +0 -9
  98. package/example/node_modules/quantumcoin/src/utils/address.d.ts +0 -58
  99. package/example/node_modules/quantumcoin/src/utils/address.js +0 -144
  100. package/example/node_modules/quantumcoin/src/utils/encoding.d.ts +0 -120
  101. package/example/node_modules/quantumcoin/src/utils/encoding.js +0 -306
  102. package/example/node_modules/quantumcoin/src/utils/fixednumber.d.ts +0 -57
  103. package/example/node_modules/quantumcoin/src/utils/fixednumber.js +0 -366
  104. package/example/node_modules/quantumcoin/src/utils/hashing.d.ts +0 -76
  105. package/example/node_modules/quantumcoin/src/utils/hashing.js +0 -298
  106. package/example/node_modules/quantumcoin/src/utils/index.d.ts +0 -63
  107. package/example/node_modules/quantumcoin/src/utils/index.js +0 -14
  108. package/example/node_modules/quantumcoin/src/utils/result.d.ts +0 -57
  109. package/example/node_modules/quantumcoin/src/utils/result.js +0 -128
  110. package/example/node_modules/quantumcoin/src/utils/rlp.d.ts +0 -12
  111. package/example/node_modules/quantumcoin/src/utils/rlp.js +0 -215
  112. package/example/node_modules/quantumcoin/src/utils/units.d.ts +0 -29
  113. package/example/node_modules/quantumcoin/src/utils/units.js +0 -107
  114. package/example/node_modules/quantumcoin/src/wallet/index.d.ts +0 -10
  115. package/example/node_modules/quantumcoin/src/wallet/index.js +0 -8
  116. package/example/node_modules/quantumcoin/src/wallet/wallet.d.ts +0 -192
  117. package/example/node_modules/quantumcoin/src/wallet/wallet.js +0 -713
  118. package/example/node_modules/quantumcoin/test/e2e/all-solidity-types.dynamic.test.js +0 -207
  119. package/example/node_modules/quantumcoin/test/e2e/all-solidity-types.dynamic.test.ts +0 -191
  120. package/example/node_modules/quantumcoin/test/e2e/all-solidity-types.fixtures.js +0 -231
  121. package/example/node_modules/quantumcoin/test/e2e/all-solidity-types.generated-sdks.e2e.test.js +0 -387
  122. package/example/node_modules/quantumcoin/test/e2e/all-solidity-types.generated-sdks.e2e.test.ts +0 -350
  123. package/example/node_modules/quantumcoin/test/e2e/generator-interface.e2e.test.js +0 -165
  124. package/example/node_modules/quantumcoin/test/e2e/generator-interface.e2e.test.ts +0 -160
  125. package/example/node_modules/quantumcoin/test/e2e/helpers.js +0 -59
  126. package/example/node_modules/quantumcoin/test/e2e/signing-context-and-fee.e2e.test.js +0 -141
  127. package/example/node_modules/quantumcoin/test/e2e/signing-context-and-fee.e2e.test.ts +0 -128
  128. package/example/node_modules/quantumcoin/test/e2e/simple-erc20.generated-sdks.e2e.test.js +0 -168
  129. package/example/node_modules/quantumcoin/test/e2e/simple-erc20.generated-sdks.e2e.test.ts +0 -141
  130. package/example/node_modules/quantumcoin/test/e2e/transactional.test.js +0 -245
  131. package/example/node_modules/quantumcoin/test/e2e/transactional.test.ts +0 -208
  132. package/example/node_modules/quantumcoin/test/e2e/typed-generator.e2e.test.js +0 -407
  133. package/example/node_modules/quantumcoin/test/e2e/typed-generator.e2e.test.ts +0 -337
  134. package/example/node_modules/quantumcoin/test/fixtures/ConstructorParam.sol +0 -23
  135. package/example/node_modules/quantumcoin/test/fixtures/MultiContracts.sol +0 -37
  136. package/example/node_modules/quantumcoin/test/fixtures/SimpleStorage.sol +0 -18
  137. package/example/node_modules/quantumcoin/test/fixtures/StakingContract.abi.json +0 -1
  138. package/example/node_modules/quantumcoin/test/integration/ipc-provider.test.js +0 -49
  139. package/example/node_modules/quantumcoin/test/integration/ipc-provider.test.ts +0 -44
  140. package/example/node_modules/quantumcoin/test/integration/provider.test.js +0 -88
  141. package/example/node_modules/quantumcoin/test/integration/provider.test.ts +0 -85
  142. package/example/node_modules/quantumcoin/test/integration/ws-provider.test.js +0 -41
  143. package/example/node_modules/quantumcoin/test/integration/ws-provider.test.ts +0 -38
  144. package/example/node_modules/quantumcoin/test/security/abi-decoder-bounds.test.js +0 -122
  145. package/example/node_modules/quantumcoin/test/security/contract-overrides.test.js +0 -112
  146. package/example/node_modules/quantumcoin/test/security/generator-injection.test.js +0 -195
  147. package/example/node_modules/quantumcoin/test/security/malformed-input.test.js +0 -330
  148. package/example/node_modules/quantumcoin/test/security/malformed-input.test.ts +0 -35
  149. package/example/node_modules/quantumcoin/test/security/rpc-numeric-bounds.test.js +0 -81
  150. package/example/node_modules/quantumcoin/test/security/rpc-trust.test.js +0 -202
  151. package/example/node_modules/quantumcoin/test/unit/_encrypted-output.txt +0 -6
  152. package/example/node_modules/quantumcoin/test/unit/_log-encrypted-jsons.js +0 -45
  153. package/example/node_modules/quantumcoin/test/unit/_write-keystore-fixture.js +0 -16
  154. package/example/node_modules/quantumcoin/test/unit/abi-interface.test.js +0 -110
  155. package/example/node_modules/quantumcoin/test/unit/abi-interface.test.ts +0 -109
  156. package/example/node_modules/quantumcoin/test/unit/address-wallet.test.js +0 -923
  157. package/example/node_modules/quantumcoin/test/unit/address-wallet.test.ts +0 -877
  158. package/example/node_modules/quantumcoin/test/unit/browser-provider.test.js +0 -85
  159. package/example/node_modules/quantumcoin/test/unit/browser-provider.test.ts +0 -79
  160. package/example/node_modules/quantumcoin/test/unit/contract.test.js +0 -85
  161. package/example/node_modules/quantumcoin/test/unit/contract.test.ts +0 -83
  162. package/example/node_modules/quantumcoin/test/unit/encoding-units-rlp.test.js +0 -127
  163. package/example/node_modules/quantumcoin/test/unit/encoding-units-rlp.test.ts +0 -91
  164. package/example/node_modules/quantumcoin/test/unit/errors.test.js +0 -77
  165. package/example/node_modules/quantumcoin/test/unit/errors.test.ts +0 -76
  166. package/example/node_modules/quantumcoin/test/unit/filter-by-blockhash.test.js +0 -55
  167. package/example/node_modules/quantumcoin/test/unit/filter-by-blockhash.test.ts +0 -54
  168. package/example/node_modules/quantumcoin/test/unit/fixednumber.test.js +0 -656
  169. package/example/node_modules/quantumcoin/test/unit/fixednumber.test.ts +0 -660
  170. package/example/node_modules/quantumcoin/test/unit/fixtures/encrypted-keystores-48-32-36.js +0 -9
  171. package/example/node_modules/quantumcoin/test/unit/generate-contract-cli.test.js +0 -42
  172. package/example/node_modules/quantumcoin/test/unit/generate-contract-cli.test.ts +0 -41
  173. package/example/node_modules/quantumcoin/test/unit/generate-sdk-artifacts-json.test.js +0 -113
  174. package/example/node_modules/quantumcoin/test/unit/generate-sdk-artifacts-json.test.ts +0 -110
  175. package/example/node_modules/quantumcoin/test/unit/generator.test.js +0 -149
  176. package/example/node_modules/quantumcoin/test/unit/generator.test.ts +0 -148
  177. package/example/node_modules/quantumcoin/test/unit/hashing.test.js +0 -64
  178. package/example/node_modules/quantumcoin/test/unit/hashing.test.ts +0 -63
  179. package/example/node_modules/quantumcoin/test/unit/init.test.js +0 -39
  180. package/example/node_modules/quantumcoin/test/unit/init.test.ts +0 -38
  181. package/example/node_modules/quantumcoin/test/unit/interface.test.js +0 -56
  182. package/example/node_modules/quantumcoin/test/unit/interface.test.ts +0 -54
  183. package/example/node_modules/quantumcoin/test/unit/internal-hex.test.js +0 -81
  184. package/example/node_modules/quantumcoin/test/unit/internal-hex.test.ts +0 -80
  185. package/example/node_modules/quantumcoin/test/unit/populate-transaction.test.js +0 -98
  186. package/example/node_modules/quantumcoin/test/unit/populate-transaction.test.ts +0 -64
  187. package/example/node_modules/quantumcoin/test/unit/providers.test.js +0 -252
  188. package/example/node_modules/quantumcoin/test/unit/providers.test.ts +0 -251
  189. package/example/node_modules/quantumcoin/test/unit/result.test.js +0 -80
  190. package/example/node_modules/quantumcoin/test/unit/result.test.ts +0 -79
  191. package/example/node_modules/quantumcoin/test/unit/solidity-types.test.js +0 -49
  192. package/example/node_modules/quantumcoin/test/unit/solidity-types.test.ts +0 -39
  193. package/example/node_modules/quantumcoin/test/unit/utils.test.js +0 -57
  194. package/example/node_modules/quantumcoin/test/unit/utils.test.ts +0 -56
  195. package/example/node_modules/quantumcoin/test/verbose-logger.js +0 -74
  196. package/example/node_modules/quantumcoin/tsconfig.build.json +0 -14
  197. package/example/node_modules/seed-words/.github/workflows/publish-npmjs.yaml +0 -22
  198. package/example/node_modules/seed-words/BUILD.md +0 -7
  199. package/example/node_modules/seed-words/LICENSE +0 -121
  200. package/example/node_modules/seed-words/README.md +0 -67
  201. package/example/node_modules/seed-words/dist/seedwords.d.ts +0 -39
  202. package/example/node_modules/seed-words/package.json +0 -27
  203. package/example/node_modules/seed-words/seedwords.js +0 -315
  204. package/example/node_modules/seed-words/seedwords.txt +0 -65536
  205. package/example/node_modules/seed-words/tsconfig.json +0 -21
  206. package/example/package-lock.json +0 -60
  207. package/example/package.json +0 -15
  208. package/scripts/build-browser-tests.js +0 -29
  209. package/scripts/build-wasm.js +0 -85
  210. package/tests/browser/bundle.js +0 -97643
  211. package/tests/browser/entry.js +0 -57
  212. package/tests/browser/harness.html +0 -20
  213. package/tests/browser/run-browser.js +0 -50
  214. package/tests/encrypted-32.json +0 -1
  215. package/tests/encrypted-36.json +0 -1
  216. package/tests/encrypted-48.json +0 -1
  217. package/tests/generate-verify-vectors.js +0 -88
  218. package/tests/get-gas-price.test.js +0 -59
  219. package/tests/hashing.test.js +0 -34
  220. package/tests/non-transactional.preinit.test.js +0 -33
  221. package/tests/non-transactional.test.js +0 -1318
  222. package/tests/sign-raw-keytype5-context-null.test.js +0 -105
  223. package/tests/sign-raw-transaction.test.js +0 -194
  224. package/tests/sign-verify.test.js +0 -308
  225. package/tests/specs/assert.js +0 -74
  226. package/tests/specs/crypto.spec.js +0 -104
  227. package/tests/specs/hex.js +0 -31
  228. package/tests/specs/preinit.spec.js +0 -19
  229. package/tests/specs/sign.spec.js +0 -90
  230. package/tests/specs/wallet.spec.js +0 -98
  231. package/tests/transactional.rpc.test.js +0 -102
  232. package/tests/verify-vectors.json +0 -95035
@@ -1,245 +0,0 @@
1
- /**
2
- * @testCategory e2e
3
- * @blockchainRequired write
4
- * @transactional true
5
- * @description Transactional tests (send coins, deploy contract, invoke contract) against a JSON-RPC endpoint.
6
- *
7
- * IMPORTANT / WARNING:
8
- * - This file contains a HARDCODED TEST WALLET (encrypted JSON + passphrase).
9
- * - It is assumed to have funds on the target network for testing.
10
- * - NEVER reuse this wallet for real funds or production usage.
11
- * - Running these tests will broadcast REAL transactions and WILL change chain state.
12
- *
13
- * RPC endpoint parameterization:
14
- * - Provide the JSON-RPC URL via `QC_RPC_URL` env var OR `--rpc=<url>` argument.
15
- * - Example (PowerShell):
16
- * `$env:QC_RPC_URL = "https://public.rpc.quantumcoinapi.com"; npm run test:e2e`
17
- */
18
-
19
- const { describe, it } = require("node:test");
20
- const assert = require("node:assert/strict");
21
- const path = require("node:path");
22
- const os = require("node:os");
23
- const fs = require("node:fs");
24
- const { execFileSync } = require("node:child_process");
25
-
26
- const qc = require("../../index");
27
- const { Initialize } = require("../../config");
28
- const { getRpcUrl, getChainId, getSolcPath, assertSolcExists, logE2eConfig } = require("./helpers");
29
- const { logSuite, logTest, logTxn, logAddress } = require("../verbose-logger");
30
-
31
- // ---------------------------------------------------------------------------
32
- // Hardcoded funded test wallet (from upstream SDK examples)
33
- // ---------------------------------------------------------------------------
34
- // NOTE: This wallet is used in quantum-coin-js-sdk examples and is intended ONLY for testing.
35
- const TEST_WALLET_ENCRYPTED_JSON =
36
- "{\"address\":\"1a846abe71c8b989e8337c55d608be81c28ab3b2e40c83eaa2a68d516049aec6\",\"crypto\":{\"cipher\":\"aes-256-ctr\",\"ciphertext\":\"ab7e620dd66cb55ac201b9c6796de92bbb06f3681b5932eabe099871f1f7d79acabe30921a39ad13bfe74f42c515734882b6723760142aa3e26e011df514a534ae47bd15d86badd9c6f17c48d4c892711d54d441ee3a0ee0e5b060f816e79c7badd13ff4c235934b1986774223ecf6e8761388969bb239c759b54c8c70e6a2e27c93a4b70129c8159f461d271ae8f3573414c78b88e4d0abfa6365ed45456636d4ed971c7a0c6b84e6f0c2621e819268b135e2bcc169a54d1847b39e6ba2ae8ec969b69f330b7db9e785ed02204d5a1185915ae5338b0f40ef2a7f4d5aaf7563d502135e57f4eb89d5ec1efa5c77e374969d6cd85be625a2ed1225d68ecdd84067bfc69adb83ecd5c6050472eca28a5a646fcdd28077165c629975bec8a79fe1457cb53389b788b25e1f8eff8b2ca326d7dfcaba3f8839225a08057c018a458891fd2caa0d2b27632cffd80f592147ccec9a10dc8a08a48fb55047bff5cf85cda39eb089096bef63842fc3686412f298a54a9e4b0bf4ad36907ba373cbd6d32e7ac494af371da5aa9d38a3463220865114c4adc5e4ac258ba9c6af9fa2ddfd1aec2e16887e4b3977c69561df8599ac9d411c9dd2a4d57f92ea4e5c02aae3f49fb3bc83e16673e6c2dbe96bb181c8dfd0f9757ade2e4ff27215a836058c5ffeab042f6f97c7c02339f76a6284680e01b4bb733690eb3347fbfcc26614b8bf755f9dfce3fea9d4e4d15b164983201732c2e87593a86bca6da6972e128490338f76ae68135888070f4e59e90db54d23834769bdbda9769213faf5357f9167a224523975a946367b68f0cec98658575609f58bfd329e420a921c06713326e4cb20a0df1d77f37e78a320a637a96c604ca3fa89e24beb42313751b8f09b14f9c14c77e4fd13fc6382505d27c771bca0d821ec7c3765acffa99d83c50140a56b0b28101c762bd682fe55cb6f23cbeb3f421d7b36021010e45ac27160dd7ead99c864a1b550c7edb1246950fe32dcc049799f9085287f0a747a6ef7a023df46a23a22f3e833bbf8d404f84344870492658256ee1dfc40fda33bb8d48fc72d4520ba9fc820c9123104a045206809037709f2a5f6723fa77d6bac5a573823d4ec3a7f1cb786a52ee2697e622e5d75962fa554d1024a6c355e21f33a63b2b72e6c4742a8b1c373aa532b40518c38c90b5373c2eb8c9d7be2a9e16047a3ee09dc9a6849deac5183ace6cfe91a9bef2ffc0a7df6ccebfd4c858c84b0e0355650d7466971e66f1e3883013e5ad1be33199b1d110b79070ac1b745ccb14cf63a08f8cca3a21c9525e626ff5f0c34746e10750fb742ad51f11f2acae3676c2111853d7250d01b77821a6ba9e04400ba2c543ca9f2d701ae6f47bfad14ffe3039ee9e71f7b2401359ade9938750ddb9c5a8b018a7929ed8d0e717ff1861446ce17535e9b17c187711190aae3388bd9490837a636c25ed4d42d7079ad1a51e13292c683d5d012abcf46965c534b83ab53f2c1f0cf5830ef7582e06863a33c19a70511df632885d63245965047ea96b56f1af5b3b94a54999f784fb9574fdfcd7c1230e07a2aaa04acd3097b2b9f8ddba05ae9734491deb5c1a513c76ed276cb78bbf4839dae3156d76af444a5805129d5df791167a9c8576a1d7f760b2d2797c4658669608706fbd0ace1be2346f74862dfc9ef518e55632e43c043186e5d070deb34d12fb9e5aba84e5cb50213dc88efd39cc35bf42455aa82d5e3b707b3140be3b8623b34fdd81d08615c188ae8438a13881fdf6bf32f2cb9ff5fa625561040c6b71d4b8eccc90bc3b99650d28dd1ee63773e49664e3d48c484996b290943635a6f2eb1ce9796d3fa144a3f00ef82faaa32d6a413668f7b521517cb68b2b017fcf56c79326fa5e4060e643631ca3f0a0dc0ed718798b6f46b130d437c33f64039e887324b6f5e604b1669d613923794edbf04b1b3caea54793b52b44b170173a4f25c7ecef3b71e2aad76e556b1cb9f1d637ec52ececfa950dd31dbb6a60828a3ad34c1beffe09eb4785786d63bad10a0b0f66ea88c57380f38ea85f018dbd7f538cf1ee7624095b9a01ec5edd528f281168af020609e651ff316aa1320a710134ddfca600cc72174dcdb846d2aa29916488aa1b537b66da92e61af526debef4eb38c984569eaf549ff2129449269b492d030cd74d885f6f5785881cc4804b4a8a09ba4ff7aefe9074ac7d0c4f05d51fe4cc0ff7388a772092b9d02d70e5433a5cf3e02f46a6bd6b818d59a07ce3b9fbbf8b5faba74563bcc5240930c2d406c9aaee3e3ce0429bf68ac2b0a57adb09414cff50817d2a48fb9fa624ab863cb0c31a8b8dc5eaf6fa68cc1d7c6c685c5a33edd5c8933b9e8ab628ee428d0743699b2ff17f25586c7ce959280bb0b8c5342251f0a30b53dbc7bf1ee426ac9619c3560f811f2268ee37f189794e2e4b3db3a2fb2e34b649e504fb467438abfd1082619cc4a0b30d66beb831077812e418d2e2148db10cf4d4a29101ca52ec445b8d83519dd7de85a98e0beae9ee537096d3f1a55a7a80cdfa93d25f07c9f98e8af18cde19ec1f99c5dd4588b717a5039ddb7f177717caf0d0fd45420a70dbd6d3146890d9e450d5224146db4c33b779e3c3a04b976c052bad042ac57dd38be45407808c0fb0d7e2a8819e6cd53c6739e6612996ddaa6f066552590aa0343bc1e62b298ff2514a0cef8be21956c2e942816f7a3a3a0935eaf9b37251409ce444c986c3817e82835555fe18239f3ae33469d7965c2bde9991fde556bd07af01df52bbde0c35bb4ef48e3b5d0db53f8ca4ed35b83f760f0a1bc4ed9f86e85d6039a17df373c85402ef956f01db00eb39c4b74bd0660d29ee746714d9780d738e05c6cca414ce3d7b40dda8036a9eea9ab1388805f913eb19bdd3f09d9e161eaa50231bd9caba61971f194332dd28c696a60458c1c6c2cc5da8b1192611c7c553e9e12fe48ce46bbb891be8bb118721c86222e671ddd1da8f0ccb2b68e02f2014b4925e904e88369aaf7466bd7033a60c265d45955944916ecbdb84bf1b522b01b0149c632e04c568a7eb627c5bb90ece052ebcf79166c28b30d23fe52da0a5ab5dea83ca479a3e3b7a9cfbbfea04dbe6137c19d067317c2ec427a8c75a6b06bec6dcd5d5c0edc9aa80b9003b8e17c088b2f3db327d3e42630d82d20120240c3ba56232280787da4aabbf5bc95a864029f00710e195f2a76460a0317d10b552fe1bea097e41d49756c680a41d6ac186e62169b6b6cd7776ea84618b5b752328a5bacaa10aa122ff9b2698b43efe73d852a899db644863c8c9bc8068ea86ea843fd6fe36272b91cdc5d5317083ef3fd1e5462a0b0d0604dc57b3bbfceb0fca4cd349625dd7b25166af30efe5ee6a0af953a74d65f4736c59918ee55a3b0d9d9d42e04c7f8a77e479109f740e20c464d5d7e3d16805f47b61f403ff7f408c9e850d9baacd8067e544536a4953480b0f9ee9cd45f41ebd67b51f78788a6470cb1e5ca72ca346ce8a50d0ca0c921d5576a4455a1afb6d0bc688004712ee122cacdb29c51e84893324c27fa4a3f1917edf5352272b4c97579a6152e4b77663d0ab532915f2eeb6a862de8b696452321b660c3f2449673d086e95a7af28845a5259b763e0fcd09f72acf7b6c811066263060e5aa5b24658e880a01fd56bda4dad5ab604e129290f7d5489728f2a40968c6168b21cebbbcd11727cc9e9160c4e92e04387d3b0d62aab06a61f26daedd9fed11816ef2180172a47f47184ac4032b88758c98a2e0fb200f70e93ba695f5ebb7a1029610ad360d3b7fa1b4640b9dc674d3625eef786da93dff19bc7991b5d6193a3896664763fde479b5dfc04812111a80782854f2cf68ca7d82765cc9eb40fba4b44640710ed6e653abf9f07b466333f4fd22784d53cf40e17120f42caa841eaa24056b237827b0f47f7257c103c35027e9f503e5acfd023e7357b600d3084d361d5ee65ba319b45c153212a54e6fed85af7e43e0a926ebcbc2edf8de7e2ec9528f00bec262ad04d5c9dafccaea06a24748d28bf1799bae0e895543084539c50b5aaa4fb50d7431d6f0c8cee2a54aaf7ee7919b55bf40adb688632e5dbe273cea09e97b19c3d8e1f4de000deb66fa1942ad03a62d3252f51992244366c156000b49c297167a6cbdedea7ebae139d295f0ad298e0864249b905b7eb812886ec70ecdb286702274b5b8574149bf3866f9e46b997ff5ed622b169a0eb071347f18d530db1663906a28f4544ee4e004ab87b65476af30ede118052ff052b8dc986ca2c93dd5d4943266a579c7698ea014f688b3e8063a107feb162d392e2177b01bff77fb5abe5feebd0607158049a5a093325b7c9ee6b4dfa7a9f65c7c2fb628920d3603a1c2dad979eaa047cd661a268af1078c9788d720e64e4ce9d12e68de1e417ef2f293323681e1071f9220e1ee43d2e29d111b870ce3439f5100ecd4551ab65ee74aa1667e564957e9bc0ae1ea193980da2a0ec2698073388c85bec25ef447f0d5e93a5203fa44dff268e5cb799ed3b66e63d5e07b487e7534f24934c73a62a243e0151843a0fd3807711a101eaa7fc71f0ba68aebb9534d57cba41b094eebfb4c31cca8eddfa426f676aa347be8a7023a4e91ddb154b35cd4d5f7dbc2e5db491de99f33fc2cff2d57029ac950e1ccd681980af6a4e8969dfe39b3c7bfcbcf8fac92f1e6ec9fe572bfa6a7d65860eab2ed10ac01a71290b52e3148e84b7376a8605cd2bb0e8681ffc54691ce087685e33921bd44d36c78291713dce17569570f62137e6904f0d68cf53aa2ec395c389a75141f08114fb293ea63950e4ffee55ec6fc83cf44876b8e7f25cdd393ff87b9eda6eb746085b61a6900de191f0ce2cb388d61ece52e78bc47368194e8e00277e0d1631e6b9d4626ef76f8522582ccd5a40be3febc699bb510acc6271d55ff0f4cf3bb7669855a72efd9ca3e1056a2fe592a5bc877cce2b1f63b58383971da87873d2d1349cf5881242cdce4e7e2c5c514755746a0e0a7c2a6d9701cde005ae3420beb17c379a3516662253554f51f0423bb1844b0b90c54ed8177ceb0e1036a6609d836e748ca06c40ca64befadc6443ec286a0ce464678e8d11eb455f7bb305acebf6cb1f50e394a9bfeb752df1687831bac9cdd811f4f112ef6658d0f8799a866374ff96c5e2b79f30e7a74f8a2bc9ed1f88f01f30e30cb78ffb2bff10108f35e910ee3be4463e9e6f0ed910e8d598326e71dfa2277ffe5579d7fe9b6018bfe295b25219eae07b3b0270665c3fa00c3e0d180812b5cd62925585de84a7c48a9a86dba96544a251654d1966e082432dc85b6149cf21e91a46020ec32b66d28ba3b6a90c0617bc6fdd55aea819af2bcf84864ad60c28fe3c9f8339d0aee68b39d97f63b6e082835d86119cf9b9fdc8b827c847ce40aa10e1577a710132316845e825345e95bdf94d0c66ec65a6c4319fce4792313663b5f7a651a6710783e6ab71608ac6cbbf3af6911adf596ccf7c172b9bd5bceb6db379967b32b143bdd11d2ee12ddf64ecef6391e0f8570e6cddd3db95204919362b89b739fa94e7c1bfde799fd5e22aa25ca6ca42e30c08e23aae2385d99ebab441072a880dcefdab74a4c9bd39d363f6d1933d59400fca161d432aa00f23b1b1c19a154be8989699d549b66d44e39896f5523443bc6ddf4a65e91f1f3fb7b52318869a05856a4fc92f3694c81ed833c972fb918f7e5\",\"cipherparams\":{\"iv\":\"8c46d6162cd4c765759aedcbce2a5874\"},\"kdf\":\"scrypt\",\"kdfparams\":{\"dklen\":32,\"n\":262144,\"p\":1,\"r\":8,\"salt\":\"82fb6cdc6917609135277badacf15baa31899d08b71a5a0fa33167167c161537\"},\"mac\":\"9187b17f7eca48e6b8c586b0cd790dbe0feb876ac8385f93faa7d5e22a3c8fc7\"},\"id\":\"92caf6ee-2d43-48c0-859e-ffa1e0e23312\",\"version\":3}";
37
- const TEST_WALLET_PASSPHRASE = "QuantumCoinExample123!";
38
-
39
- // Gas assumption per user requirements:
40
- // "Assume 1000 coins needed for 21000 units of gas."
41
- const ONE_COIN_WEI = 1000000000000000000n;
42
- const FIXED_COINS_PER_21000_GAS = 1000n;
43
- const FIXED_GAS_UNITS = 21000n;
44
- const FIXED_GAS_PRICE_WEI = (FIXED_COINS_PER_21000_GAS * ONE_COIN_WEI) / FIXED_GAS_UNITS;
45
-
46
- function parseHexToBigInt(hex) {
47
- return BigInt(hex);
48
- }
49
-
50
- function compileSimpleStorage(solcPath) {
51
- const srcPath = path.join(__dirname, "..", "fixtures", "SimpleStorage.sol");
52
- const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "qc-solc-"));
53
- const out = execFileSync(solcPath, ["--optimize", "--combined-json", "abi,bin", srcPath], { encoding: "utf8" });
54
-
55
- const json = JSON.parse(out);
56
- const contracts = json.contracts || {};
57
- const key = Object.keys(contracts).find((k) => k.toLowerCase().includes("simplestorage"));
58
- if (!key) throw new Error("solc output missing SimpleStorage contract");
59
-
60
- const abi = JSON.parse(contracts[key].abi);
61
- const bin = contracts[key].bin;
62
- if (!bin) throw new Error("solc output missing bytecode");
63
- return { abi, bytecode: "0x" + bin };
64
- }
65
-
66
- describe("Transactional E2E (write)", () => {
67
- it("sends coins and validates balances + receipt", async (t) => {
68
- logSuite("Transactional E2E (write)");
69
- logTest("sends coins and validates balances + receipt", {});
70
- const rpcUrl = getRpcUrl();
71
- if (!rpcUrl) {
72
- t.skip("QC_RPC_URL (or --rpc) not provided");
73
- return;
74
- }
75
- logE2eConfig();
76
-
77
- const chainId = getChainId();
78
- await Initialize(null);
79
-
80
- const provider = qc.getProvider(rpcUrl, chainId);
81
- const wallet = qc.Wallet.fromEncryptedJsonSync(TEST_WALLET_ENCRYPTED_JSON, TEST_WALLET_PASSPHRASE, provider);
82
- logAddress("sender", wallet.address);
83
-
84
- // Recipient: random wallet (unfunded) so we can assert delta precisely.
85
- const recipient = qc.Wallet.createRandom();
86
- logAddress("recipient", recipient.address);
87
-
88
- const sendValue = qc.parseEther("1.0");
89
-
90
- const senderBefore = await provider.getBalance(wallet.address);
91
- const recipientBefore = await provider.getBalance(recipient.address);
92
- const nonceBefore = await provider.getTransactionCount(wallet.address, "latest");
93
-
94
- // GasLimit is the standard transfer gas.
95
- const gasLimit = 21000;
96
- const tx = await wallet.sendTransaction({
97
- to: recipient.address,
98
- value: sendValue,
99
- gasLimit,
100
- remarks: null,
101
- });
102
- logTxn(tx.hash, { from: wallet.address, to: recipient.address, value: sendValue.toString() });
103
-
104
- const receipt = await tx.wait(1, 600_000);
105
- logTxn(tx.hash, { blockNumber: receipt.blockNumber, status: receipt.status });
106
- assert.ok(receipt);
107
- assert.ok(receipt.blockNumber != null);
108
-
109
- const senderAfter = await provider.getBalance(wallet.address);
110
- const recipientAfter = await provider.getBalance(recipient.address);
111
- const nonceAfter = await provider.getTransactionCount(wallet.address, "latest");
112
-
113
- // Receiver must increase exactly by the sent value.
114
- assert.equal(recipientAfter - recipientBefore, sendValue);
115
-
116
- // Sender must decrease by at least value + fee (fee is chain-defined).
117
- const senderDelta = senderBefore - senderAfter;
118
- assert.ok(senderDelta >= sendValue);
119
-
120
- // Fee sanity check using fixed gas-price assumption.
121
- // feePaid ~= gasLimit * fixedGasPrice
122
- const expectedFee = BigInt(gasLimit) * FIXED_GAS_PRICE_WEI;
123
- const feePaid = senderDelta - sendValue;
124
- // Allow a wide tolerance (network/client gas price may differ significantly).
125
- assert.ok(feePaid > 0n);
126
- assert.ok(feePaid <= expectedFee * 20n);
127
-
128
- // Nonce should increment by at least 1.
129
- assert.ok(nonceAfter >= nonceBefore + 1);
130
- }, { timeout: 900_000 });
131
-
132
- it("sends coins with remarks and verifies remarks on read-back", async (t) => {
133
- logSuite("Transactional E2E (write)");
134
- logTest("sends coins with remarks and verifies remarks on read-back", {});
135
- const rpcUrl = getRpcUrl();
136
- if (!rpcUrl) {
137
- t.skip("QC_RPC_URL (or --rpc) not provided");
138
- return;
139
- }
140
- logE2eConfig();
141
-
142
- const chainId = getChainId();
143
- await Initialize(null);
144
-
145
- const provider = qc.getProvider(rpcUrl, chainId);
146
- const wallet = qc.Wallet.fromEncryptedJsonSync(TEST_WALLET_ENCRYPTED_JSON, TEST_WALLET_PASSPHRASE, provider);
147
- const recipient = qc.Wallet.createRandom();
148
-
149
- const remarksText = "hello world";
150
- const remarksHex = qc.hexlify(qc.toUtf8Bytes(remarksText));
151
- const sendValue = qc.parseEther("0.01");
152
- const gasLimit = 21000;
153
-
154
- const tx = await wallet.sendTransaction({
155
- to: recipient.address,
156
- value: sendValue,
157
- gasLimit,
158
- remarks: remarksHex,
159
- });
160
- logTxn(tx.hash, { from: wallet.address, to: recipient.address, remarks: remarksText });
161
-
162
- const receipt = await tx.wait(1, 600_000);
163
- assert.ok(receipt);
164
- assert.ok(receipt.blockNumber != null);
165
-
166
- const readBack = await provider.getTransaction(tx.hash);
167
- assert.ok(readBack, "getTransaction must return the transaction");
168
- assert.equal(readBack.remarks, remarksHex, "remarks on chain must match what was set");
169
- }, { timeout: 900_000 });
170
-
171
- it("deploys a contract (solc) and validates code + storage mutation", async (t) => {
172
- logTest("deploys a contract (solc) and validates code + storage mutation", {});
173
- const rpcUrl = getRpcUrl();
174
- if (!rpcUrl) {
175
- t.skip("QC_RPC_URL (or --rpc) not provided");
176
- return;
177
- }
178
- logE2eConfig();
179
-
180
- const chainId = getChainId();
181
- const solcPath = getSolcPath();
182
- assertSolcExists(solcPath);
183
-
184
- await Initialize(null);
185
- const provider = qc.getProvider(rpcUrl, chainId);
186
- const wallet = qc.Wallet.fromEncryptedJsonSync(TEST_WALLET_ENCRYPTED_JSON, TEST_WALLET_PASSPHRASE, provider);
187
- logAddress("deployer", wallet.address);
188
-
189
- const { abi, bytecode } = compileSimpleStorage(solcPath);
190
-
191
- const deployNonce = await provider.getTransactionCount(wallet.address, "latest");
192
- const expectedAddress = qc.getCreateAddress({ from: wallet.address, nonce: deployNonce });
193
- logAddress("expected_contract", expectedAddress);
194
-
195
- // Use ContractFactory's deploy tx builder (uses quantum-coin-js-sdk packCreateContractData).
196
- const factory = new qc.ContractFactory(abi, bytecode, wallet);
197
- const deployTxReq = factory.getDeployTransaction();
198
-
199
- // Estimate gas and add some buffer.
200
- let gasLimit = 500000;
201
- try {
202
- const est = await provider.estimateGas({ from: wallet.address, data: deployTxReq.data });
203
- gasLimit = Number(est + 50_000n);
204
- } catch {
205
- // keep fallback
206
- }
207
-
208
- const deployTx = await wallet.sendTransaction({
209
- ...deployTxReq,
210
- nonce: deployNonce,
211
- gasLimit,
212
- value: 0n,
213
- });
214
- logTxn(deployTx.hash, { type: "deploy", expectedAddress });
215
-
216
- const receipt = await deployTx.wait(1, 600_000);
217
- logTxn(deployTx.hash, { blockNumber: receipt.blockNumber, contractAddress: receipt.contractAddress });
218
- assert.ok(receipt);
219
- if (receipt.contractAddress) {
220
- assert.equal(receipt.contractAddress.toLowerCase(), expectedAddress.toLowerCase());
221
- }
222
-
223
- const code = await provider.getCode(expectedAddress, "latest");
224
- assert.ok(typeof code === "string");
225
- assert.ok(code.length > 2); // "0x" means no code
226
-
227
- // Interact with the deployed contract.
228
- const contract = new qc.Contract(expectedAddress, abi, wallet);
229
-
230
- const before = await contract.get();
231
- const beforeValue = Array.isArray(before) ? before[0] : before;
232
- assert.ok(beforeValue == 0 || beforeValue === "0" || beforeValue === 0n);
233
-
234
- const setTx = await contract.set(42n, { gasLimit: 200000 });
235
- logTxn(setTx.hash, { contractAddress: expectedAddress });
236
- await setTx.wait(1, 600_000);
237
-
238
- const after = await contract.get();
239
- const afterValue = Array.isArray(after) ? after[0] : after;
240
- // qcsdk decode may return string/number; normalize to BigInt for comparison
241
- const afterBI = typeof afterValue === "bigint" ? afterValue : BigInt(afterValue);
242
- assert.equal(afterBI, 42n);
243
- }, { timeout: 900_000 });
244
- });
245
-
@@ -1,208 +0,0 @@
1
- /**
2
- * @testCategory e2e
3
- * @blockchainRequired write
4
- * @transactional true
5
- * @description Transactional tests (send coins, deploy contract, invoke contract) against a JSON-RPC endpoint.
6
- */
7
-
8
- import { describe, it } from "node:test";
9
- import assert from "node:assert/strict";
10
- import path from "node:path";
11
- import os from "node:os";
12
- import fs from "node:fs";
13
- import { execFileSync } from "node:child_process";
14
-
15
- import qc from "../../index";
16
- import { Initialize } from "../../config";
17
- import { getRpcUrl, getChainId, getSolcPath, assertSolcExists, logE2eConfig } from "./helpers";
18
- import { logSuite, logTest, logTxn, logAddress } from "../verbose-logger";
19
-
20
- const TEST_WALLET_ENCRYPTED_JSON =
21
- "{\"address\":\"1a846abe71c8b989e8337c55d608be81c28ab3b2e40c83eaa2a68d516049aec6\",\"crypto\":{\"cipher\":\"aes-256-ctr\",\"ciphertext\":\"ab7e620dd66cb55ac201b9c6796de92bbb06f3681b5932eabe099871f1f7d79acabe30921a39ad13bfe74f42c515734882b6723760142aa3e26e011df514a534ae47bd15d86badd9c6f17c48d4c892711d54d441ee3a0ee0e5b060f816e79c7badd13ff4c235934b1986774223ecf6e8761388969bb239c759b54c8c70e6a2e27c93a4b70129c8159f461d271ae8f3573414c78b88e4d0abfa6365ed45456636d4ed971c7a0c6b84e6f0c2621e819268b135e2bcc169a54d1847b39e6ba2ae8ec969b69f330b7db9e785ed02204d5a1185915ae5338b0f40ef2a7f4d5aaf7563d502135e57f4eb89d5ec1efa5c77e374969d6cd85be625a2ed1225d68ecdd84067bfc69adb83ecd5c6050472eca28a5a646fcdd28077165c629975bec8a79fe1457cb53389b788b25e1f8eff8b2ca326d7dfcaba3f8839225a08057c018a458891fd2caa0d2b27632cffd80f592147ccec9a10dc8a08a48fb55047bff5cf85cda39eb089096bef63842fc3686412f298a54a9e4b0bf4ad36907ba373cbd6d32e7ac494af371da5aa9d38a3463220865114c4adc5e4ac258ba9c6af9fa2ddfd1aec2e16887e4b3977c69561df8599ac9d411c9dd2a4d57f92ea4e5c02aae3f49fb3bc83e16673e6c2dbe96bb181c8dfd0f9757ade2e4ff27215a836058c5ffeab042f6f97c7c02339f76a6284680e01b4bb733690eb3347fbfcc26614b8bf755f9dfce3fea9d4e4d15b164983201732c2e87593a86bca6da6972e128490338f76ae68135888070f4e59e90db54d23834769bdbda9769213faf5357f9167a224523975a946367b68f0cec98658575609f58bfd329e420a921c06713326e4cb20a0df1d77f37e78a320a637a96c604ca3fa89e24beb42313751b8f09b14f9c14c77e4fd13fc6382505d27c771bca0d821ec7c3765acffa99d83c50140a56b0b28101c762bd682fe55cb6f23cbeb3f421d7b36021010e45ac27160dd7ead99c864a1b550c7edb1246950fe32dcc049799f9085287f0a747a6ef7a023df46a23a22f3e833bbf8d404f84344870492658256ee1dfc40fda33bb8d48fc72d4520ba9fc820c9123104a045206809037709f2a5f6723fa77d6bac5a573823d4ec3a7f1cb786a52ee2697e622e5d75962fa554d1024a6c355e21f33a63b2b72e6c4742a8b1c373aa532b40518c38c90b5373c2eb8c9d7be2a9e16047a3ee09dc9a6849deac5183ace6cfe91a9bef2ffc0a7df6ccebfd4c858c84b0e0355650d7466971e66f1e3883013e5ad1be33199b1d110b79070ac1b745ccb14cf63a08f8cca3a21c9525e626ff5f0c34746e10750fb742ad51f11f2acae3676c2111853d7250d01b77821a6ba9e04400ba2c543ca9f2d701ae6f47bfad14ffe3039ee9e71f7b2401359ade9938750ddb9c5a8b018a7929ed8d0e717ff1861446ce17535e9b17c187711190aae3388bd9490837a636c25ed4d42d7079ad1a51e13292c683d5d012abcf46965c534b83ab53f2c1f0cf5830ef7582e06863a33c19a70511df632885d63245965047ea96b56f1af5b3b94a54999f784fb9574fdfcd7c1230e07a2aaa04acd3097b2b9f8ddba05ae9734491deb5c1a513c76ed276cb78bbf4839dae3156d76af444a5805129d5df791167a9c8576a1d7f760b2d2797c4658669608706fbd0ace1be2346f74862dfc9ef518e55632e43c043186e5d070deb34d12fb9e5aba84e5cb50213dc88efd39cc35bf42455aa82d5e3b707b3140be3b8623b34fdd81d08615c188ae8438a13881fdf6bf32f2cb9ff5fa625561040c6b71d4b8eccc90bc3b99650d28dd1ee63773e49664e3d48c484996b290943635a6f2eb1ce9796d3fa144a3f00ef82faaa32d6a413668f7b521517cb68b2b017fcf56c79326fa5e4060e643631ca3f0a0dc0ed718798b6f46b130d437c33f64039e887324b6f5e604b1669d613923794edbf04b1b3caea54793b52b44b170173a4f25c7ecef3b71e2aad76e556b1cb9f1d637ec52ececfa950dd31dbb6a60828a3ad34c1beffe09eb4785786d63bad10a0b0f66ea88c57380f38ea85f018dbd7f538cf1ee7624095b9a01ec5edd528f281168af020609e651ff316aa1320a710134ddfca600cc72174dcdb846d2aa29916488aa1b537b66da92e61af526debef4eb38c984569eaf549ff2129449269b492d030cd74d885f6f5785881cc4804b4a8a09ba4ff7aefe9074ac7d0c4f05d51fe4cc0ff7388a772092b9d02d70e5433a5cf3e02f46a6bd6b818d59a07ce3b9fbbf8b5faba74563bcc5240930c2d406c9aaee3e3ce0429bf68ac2b0a57adb09414cff50817d2a48fb9fa624ab863cb0c31a8b8dc5eaf6fa68cc1d7c6c685c5a33edd5c8933b9e8ab628ee428d0743699b2ff17f25586c7ce959280bb0b8c5342251f0a30b53dbc7bf1ee426ac9619c3560f811f2268ee37f189794e2e4b3db3a2fb2e34b649e504fb467438abfd1082619cc4a0b30d66beb831077812e418d2e2148db10cf4d4a29101ca52ec445b8d83519dd7de85a98e0beae9ee537096d3f1a55a7a80cdfa93d25f07c9f98e8af18cde19ec1f99c5dd4588b717a5039ddb7f177717caf0d0fd45420a70dbd6d3146890d9e450d5224146db4c33b779e3c3a04b976c052bad042ac57dd38be45407808c0fb0d7e2a8819e6cd53c6739e6612996ddaa6f066552590aa0343bc1e62b298ff2514a0cef8be21956c2e942816f7a3a3a0935eaf9b37251409ce444c986c3817e82835555fe18239f3ae33469d7965c2bde9991fde556bd07af01df52bbde0c35bb4ef48e3b5d0db53f8ca4ed35b83f760f0a1bc4ed9f86e85d6039a17df373c85402ef956f01db00eb39c4b74bd0660d29ee746714d9780d738e05c6cca414ce3d7b40dda8036a9eea9ab1388805f913eb19bdd3f09d9e161eaa50231bd9caba61971f194332dd28c696a60458c1c6c2cc5da8b1192611c7c553e9e12fe48ce46bbb891be8bb118721c86222e671ddd1da8f0ccb2b68e02f2014b4925e904e88369aaf7466bd7033a60c265d45955944916ecbdb84bf1b522b01b0149c632e04c568a7eb627c5bb90ece052ebcf79166c28b30d23fe52da0a5ab5dea83ca479a3e3b7a9cfbbfea04dbe6137c19d067317c2ec427a8c75a6b06bec6dcd5d5c0edc9aa80b9003b8e17c088b2f3db327d3e42630d82d20120240c3ba56232280787da4aabbf5bc95a864029f00710e195f2a76460a0317d10b552fe1bea097e41d49756c680a41d6ac186e62169b6b6cd7776ea84618b5b752328a5bacaa10aa122ff9b2698b43efe73d852a899db644863c8c9bc8068ea86ea843fd6fe36272b91cdc5d5317083ef3fd1e5462a0b0d0604dc57b3bbfceb0fca4cd349625dd7b25166af30efe5ee6a0af953a74d65f4736c59918ee55a3b0d9d9d42e04c7f8a77e479109f740e20c464d5d7e3d16805f47b61f403ff7f408c9e850d9baacd8067e544536a4953480b0f9ee9cd45f41ebd67b51f78788a6470cb1e5ca72ca346ce8a50d0ca0c921d5576a4455a1afb6d0bc688004712ee122cacdb29c51e84893324c27fa4a3f1917edf5352272b4c97579a6152e4b77663d0ab532915f2eeb6a862de8b696452321b660c3f2449673d086e95a7af28845a5259b763e0fcd09f72acf7b6c811066263060e5aa5b24658e880a01fd56bda4dad5ab604e129290f7d5489728f2a40968c6168b21cebbbcd11727cc9e9160c4e92e04387d3b0d62aab06a61f26daedd9fed11816ef2180172a47f47184ac4032b88758c98a2e0fb200f70e93ba695f5ebb7a1029610ad360d3b7fa1b4640b9dc674d3625eef786da93dff19bc7991b5d6193a3896664763fde479b5dfc04812111a80782854f2cf68ca7d82765cc9eb40fba4b44640710ed6e653abf9f07b466333f4fd22784d53cf40e17120f42caa841eaa24056b237827b0f47f7257c103c35027e9f503e5acfd023e7357b600d3084d361d5ee65ba319b45c153212a54e6fed85af7e43e0a926ebcbc2edf8de7e2ec9528f00bec262ad04d5c9dafccaea06a24748d28bf1799bae0e895543084539c50b5aaa4fb50d7431d6f0c8cee2a54aaf7ee7919b55bf40adb688632e5dbe273cea09e97b19c3d8e1f4de000deb66fa1942ad03a62d3252f51992244366c156000b49c297167a6cbdedea7ebae139d295f0ad298e0864249b905b7eb812886ec70ecdb286702274b5b8574149bf3866f9e46b997ff5ed622b169a0eb071347f18d530db1663906a28f4544ee4e004ab87b65476af30ede118052ff052b8dc986ca2c93dd5d4943266a579c7698ea014f688b3e8063a107feb162d392e2177b01bff77fb5abe5feebd0607158049a5a093325b7c9ee6b4dfa7a9f65c7c2fb628920d3603a1c2dad979eaa047cd661a268af1078c9788d720e64e4ce9d12e68de1e417ef2f293323681e1071f9220e1ee43d2e29d111b870ce3439f5100ecd4551ab65ee74aa1667e564957e9bc0ae1ea193980da2a0ec2698073388c85bec25ef447f0d5e93a5203fa44dff268e5cb799ed3b66e63d5e07b487e7534f24934c73a62a243e0151843a0fd3807711a101eaa7fc71f0ba68aebb9534d57cba41b094eebfb4c31cca8eddfa426f676aa347be8a7023a4e91ddb154b35cd4d5f7dbc2e5db491de99f33fc2cff2d57029ac950e1ccd681980af6a4e8969dfe39b3c7bfcbcf8fac92f1e6ec9fe572bfa6a7d65860eab2ed10ac01a71290b52e3148e84b7376a8605cd2bb0e8681ffc54691ce087685e33921bd44d36c78291713dce17569570f62137e6904f0d68cf53aa2ec395c389a75141f08114fb293ea63950e4ffee55ec6fc83cf44876b8e7f25cdd393ff87b9eda6eb746085b61a6900de191f0ce2cb388d61ece52e78bc47368194e8e00277e0d1631e6b9d4626ef76f8522582ccd5a40be3febc699bb510acc6271d55ff0f4cf3bb7669855a72efd9ca3e1056a2fe592a5bc877cce2b1f63b58383971da87873d2d1349cf5881242cdce4e7e2c5c514755746a0e0a7c2a6d9701cde005ae3420beb17c379a3516662253554f51f0423bb1844b0b90c54ed8177ceb0e1036a6609d836e748ca06c40ca64befadc6443ec286a0ce464678e8d11eb455f7bb305acebf6cb1f50e394a9bfeb752df1687831bac9cdd811f4f112ef6658d0f8799a866374ff96c5e2b79f30e7a74f8a2bc9ed1f88f01f30e30cb78ffb2bff10108f35e910ee3be4463e9e6f0ed910e8d598326e71dfa2277ffe5579d7fe9b6018bfe295b25219eae07b3b0270665c3fa00c3e0d180812b5cd62925585de84a7c48a9a86dba96544a251654d1966e082432dc85b6149cf21e91a46020ec32b66d28ba3b6a90c0617bc6fdd55aea819af2bcf84864ad60c28fe3c9f8339d0aee68b39d97f63b6e082835d86119cf9b9fdc8b827c847ce40aa10e1577a710132316845e825345e95bdf94d0c66ec65a6c4319fce4792313663b5f7a651a6710783e6ab71608ac6cbbf3af6911adf596ccf7c172b9bd5bceb6db379967b32b143bdd11d2ee12ddf64ecef6391e0f8570e6cddd3db95204919362b89b739fa94e7c1bfde799fd5e22aa25ca6ca42e30c08e23aae2385d99ebab441072a880dcefdab74a4c9bd39d363f6d1933d59400fca161d432aa00f23b1b1c19a154be8989699d549b66d44e39896f5523443bc6ddf4a65e91f1f3fb7b52318869a05856a4fc92f3694c81ed833c972fb918f7e5\",\"cipherparams\":{\"iv\":\"8c46d6162cd4c765759aedcbce2a5874\"},\"kdf\":\"scrypt\",\"kdfparams\":{\"dklen\":32,\"n\":262144,\"p\":1,\"r\":8,\"salt\":\"82fb6cdc6917609135277badacf15baa31899d08b71a5a0fa33167167c161537\"},\"mac\":\"9187b17f7eca48e6b8c586b0cd790dbe0feb876ac8385f93faa7d5e22a3c8fc7\"},\"id\":\"92caf6ee-2d43-48c0-859e-ffa1e0e23312\",\"version\":3}";
22
- const TEST_WALLET_PASSPHRASE = "QuantumCoinExample123!";
23
-
24
- const ONE_COIN_WEI = 1000000000000000000n;
25
- const FIXED_COINS_PER_21000_GAS = 1000n;
26
- const FIXED_GAS_UNITS = 21000n;
27
- const FIXED_GAS_PRICE_WEI = (FIXED_COINS_PER_21000_GAS * ONE_COIN_WEI) / FIXED_GAS_UNITS;
28
-
29
- function compileSimpleStorage(solcPath: string) {
30
- const srcPath = path.join(__dirname, "..", "fixtures", "SimpleStorage.sol");
31
- const out = execFileSync(solcPath, ["--optimize", "--combined-json", "abi,bin", srcPath], { encoding: "utf8" });
32
- const json = JSON.parse(out);
33
- const contracts = json.contracts || {};
34
- const key = Object.keys(contracts).find((k) => k.toLowerCase().includes("simplestorage"));
35
- if (!key) throw new Error("solc output missing SimpleStorage contract");
36
- const abi = JSON.parse(contracts[key].abi);
37
- const bin = contracts[key].bin;
38
- if (!bin) throw new Error("solc output missing bytecode");
39
- return { abi, bytecode: "0x" + bin };
40
- }
41
-
42
- describe("Transactional E2E (write)", () => {
43
- it("sends coins and validates balances + receipt", async (t: { skip: (msg: string) => void }) => {
44
- logSuite("Transactional E2E (write)");
45
- logTest("sends coins and validates balances + receipt", {});
46
- const rpcUrl = getRpcUrl();
47
- if (!rpcUrl) {
48
- t.skip("QC_RPC_URL (or --rpc) not provided");
49
- return;
50
- }
51
- logE2eConfig();
52
-
53
- const chainId = getChainId();
54
- await Initialize(null);
55
-
56
- const provider = qc.getProvider(rpcUrl, chainId);
57
- const wallet = qc.Wallet.fromEncryptedJsonSync(TEST_WALLET_ENCRYPTED_JSON, TEST_WALLET_PASSPHRASE, provider);
58
- logAddress("sender", wallet.address);
59
-
60
- const recipient = qc.Wallet.createRandom();
61
- logAddress("recipient", recipient.address);
62
-
63
- const sendValue = qc.parseEther("1.0");
64
-
65
- const senderBefore = await provider.getBalance(wallet.address);
66
- const recipientBefore = await provider.getBalance(recipient.address);
67
- const nonceBefore = await provider.getTransactionCount(wallet.address, "latest");
68
-
69
- const gasLimit = 21000;
70
- const tx = await wallet.sendTransaction({
71
- to: recipient.address,
72
- value: sendValue,
73
- gasLimit,
74
- remarks: null,
75
- });
76
- logTxn(tx.hash, { from: wallet.address, to: recipient.address, value: sendValue.toString() });
77
-
78
- const receipt = await tx.wait(1, 600_000);
79
- logTxn(tx.hash, { blockNumber: receipt.blockNumber, status: receipt.status });
80
- assert.ok(receipt);
81
- assert.ok(receipt.blockNumber != null);
82
-
83
- const senderAfter = await provider.getBalance(wallet.address);
84
- const recipientAfter = await provider.getBalance(recipient.address);
85
- const nonceAfter = await provider.getTransactionCount(wallet.address, "latest");
86
-
87
- assert.equal(recipientAfter - recipientBefore, sendValue);
88
-
89
- const senderDelta = senderBefore - senderAfter;
90
- assert.ok(senderDelta >= sendValue);
91
-
92
- const expectedFee = BigInt(gasLimit) * FIXED_GAS_PRICE_WEI;
93
- const feePaid = senderDelta - sendValue;
94
- assert.ok(feePaid > 0n);
95
- assert.ok(feePaid <= expectedFee * 20n);
96
-
97
- assert.ok(nonceAfter >= nonceBefore + 1);
98
- }, { timeout: 900_000 });
99
-
100
- it("sends coins with remarks and verifies remarks on read-back", async (t: { skip: (msg: string) => void }) => {
101
- logSuite("Transactional E2E (write)");
102
- logTest("sends coins with remarks and verifies remarks on read-back", {});
103
- const rpcUrl = getRpcUrl();
104
- if (!rpcUrl) {
105
- t.skip("QC_RPC_URL (or --rpc) not provided");
106
- return;
107
- }
108
- logE2eConfig();
109
-
110
- const chainId = getChainId();
111
- await Initialize(null);
112
-
113
- const provider = qc.getProvider(rpcUrl, chainId);
114
- const wallet = qc.Wallet.fromEncryptedJsonSync(TEST_WALLET_ENCRYPTED_JSON, TEST_WALLET_PASSPHRASE, provider);
115
- const recipient = qc.Wallet.createRandom();
116
-
117
- const remarksText = "hello world";
118
- const remarksHex = qc.hexlify(qc.toUtf8Bytes(remarksText));
119
- const sendValue = qc.parseEther("0.01");
120
- const gasLimit = 21000;
121
-
122
- const tx = await wallet.sendTransaction({
123
- to: recipient.address,
124
- value: sendValue,
125
- gasLimit,
126
- remarks: remarksHex,
127
- });
128
- logTxn(tx.hash, { from: wallet.address, to: recipient.address, remarks: remarksText });
129
-
130
- const receipt = await tx.wait(1, 600_000);
131
- assert.ok(receipt);
132
- assert.ok(receipt.blockNumber != null);
133
-
134
- const readBack = await provider.getTransaction(tx.hash);
135
- assert.ok(readBack, "getTransaction must return the transaction");
136
- assert.equal(readBack.remarks, remarksHex, "remarks on chain must match what was set");
137
- }, { timeout: 900_000 });
138
-
139
- it("deploys a contract (solc) and validates code + storage mutation", async (t: { skip: (msg: string) => void }) => {
140
- logTest("deploys a contract (solc) and validates code + storage mutation", {});
141
- const rpcUrl = getRpcUrl();
142
- if (!rpcUrl) {
143
- t.skip("QC_RPC_URL (or --rpc) not provided");
144
- return;
145
- }
146
- logE2eConfig();
147
-
148
- const chainId = getChainId();
149
- const solcPath = getSolcPath();
150
- assertSolcExists(solcPath);
151
-
152
- await Initialize(null);
153
- const provider = qc.getProvider(rpcUrl, chainId);
154
- const wallet = qc.Wallet.fromEncryptedJsonSync(TEST_WALLET_ENCRYPTED_JSON, TEST_WALLET_PASSPHRASE, provider);
155
- logAddress("deployer", wallet.address);
156
-
157
- const { abi, bytecode } = compileSimpleStorage(solcPath);
158
-
159
- const deployNonce = await provider.getTransactionCount(wallet.address, "latest");
160
- const expectedAddress = qc.getCreateAddress({ from: wallet.address, nonce: deployNonce });
161
- logAddress("expected_contract", expectedAddress);
162
-
163
- const factory = new qc.ContractFactory(abi, bytecode, wallet);
164
- const deployTxReq = factory.getDeployTransaction();
165
-
166
- let gasLimit = 500000;
167
- try {
168
- const est = await provider.estimateGas({ from: wallet.address, data: deployTxReq.data });
169
- gasLimit = Number(est + 50_000n);
170
- } catch {
171
- // keep fallback
172
- }
173
-
174
- const deployTx = await wallet.sendTransaction({
175
- ...deployTxReq,
176
- nonce: deployNonce,
177
- gasLimit,
178
- value: 0n,
179
- });
180
- logTxn(deployTx.hash, { type: "deploy", expectedAddress });
181
-
182
- const receipt = await deployTx.wait(1, 600_000);
183
- logTxn(deployTx.hash, { blockNumber: receipt.blockNumber, contractAddress: receipt.contractAddress });
184
- assert.ok(receipt);
185
- if (receipt.contractAddress) {
186
- assert.equal(receipt.contractAddress.toLowerCase(), expectedAddress.toLowerCase());
187
- }
188
-
189
- const code = await provider.getCode(expectedAddress, "latest");
190
- assert.ok(typeof code === "string");
191
- assert.ok(code.length > 2);
192
-
193
- const contract = new qc.Contract(expectedAddress, abi, wallet);
194
-
195
- const before = await contract.get();
196
- const beforeValue = Array.isArray(before) ? before[0] : before;
197
- assert.ok(beforeValue == 0 || beforeValue === "0" || beforeValue === 0n);
198
-
199
- const setTx = await contract.set(42n, { gasLimit: 200000 });
200
- logTxn(setTx.hash, { contractAddress: expectedAddress });
201
- await setTx.wait(1, 600_000);
202
-
203
- const after = await contract.get();
204
- const afterValue = Array.isArray(after) ? after[0] : after;
205
- const afterBI = typeof afterValue === "bigint" ? afterValue : BigInt(afterValue);
206
- assert.equal(afterBI, 42n);
207
- }, { timeout: 900_000 });
208
- });