quantum-coin-js-sdk 1.0.39 → 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 (226) hide show
  1. package/.gitignore +2 -1
  2. package/README.md +109 -768
  3. package/index.d.ts +76 -545
  4. package/index.js +319 -1194
  5. package/package.json +20 -5
  6. package/wasmBase64.js +7 -16
  7. package/wasm_exec.js +575 -587
  8. package/.idea/.name +0 -1
  9. package/.idea/modules.xml +0 -8
  10. package/.idea/quantum-coin-js-sdk.iml +0 -12
  11. package/.idea/vcs.xml +0 -6
  12. package/.vs/ProjectSettings.json +0 -3
  13. package/.vs/VSWorkspaceState.json +0 -8
  14. package/.vs/quantum-coin-js-sdk/FileContentIndex/a9d6de82-cfc3-4c22-ac38-06d706ff3673.vsidx +0 -0
  15. package/.vs/quantum-coin-js-sdk/FileContentIndex/fdc816df-1898-4153-99f2-c69ef4c2283b.vsidx +0 -0
  16. package/.vs/quantum-coin-js-sdk/config/applicationhost.config +0 -1011
  17. package/.vs/quantum-coin-js-sdk/v17/.wsuo +0 -0
  18. package/.vs/quantum-coin-js-sdk/v17/DocumentLayout.backup.json +0 -39
  19. package/.vs/quantum-coin-js-sdk/v17/DocumentLayout.json +0 -57
  20. package/.vs/slnx.sqlite +0 -0
  21. package/example/README.md +0 -14
  22. package/example/conversion-example.js +0 -19
  23. package/example/example-create-contract.js +0 -396
  24. package/example/example-encode-decode-rlp.js +0 -225
  25. package/example/example-event-pack-unpack.js +0 -391
  26. package/example/example-misc.js +0 -100
  27. package/example/example-rpc-send-signRawTransaction.js +0 -318
  28. package/example/example-rpc-send.js +0 -115
  29. package/example/example-send.js +0 -69
  30. package/example/example-token-pack-unpack.js +0 -960
  31. package/example/example-wallet-version4.js +0 -34
  32. package/example/example-wallet.js +0 -43
  33. package/example/example.js +0 -405
  34. package/example/node_modules/.bin/sdkgen +0 -16
  35. package/example/node_modules/.bin/sdkgen.cmd +0 -17
  36. package/example/node_modules/.bin/sdkgen.ps1 +0 -28
  37. package/example/node_modules/.package-lock.json +0 -47
  38. package/example/node_modules/quantumcoin/.github/workflows/publish-npmjs.yaml +0 -22
  39. package/example/node_modules/quantumcoin/LICENSE +0 -21
  40. package/example/node_modules/quantumcoin/README-SDK.md +0 -828
  41. package/example/node_modules/quantumcoin/README.md +0 -197
  42. package/example/node_modules/quantumcoin/config.d.ts +0 -50
  43. package/example/node_modules/quantumcoin/config.js +0 -123
  44. package/example/node_modules/quantumcoin/examples/AllSolidityTypes.sol +0 -184
  45. package/example/node_modules/quantumcoin/examples/SimpleIERC20.sol +0 -74
  46. package/example/node_modules/quantumcoin/examples/events.js +0 -41
  47. package/example/node_modules/quantumcoin/examples/events.ts +0 -35
  48. package/example/node_modules/quantumcoin/examples/example-generator-sdk-js.js +0 -100
  49. package/example/node_modules/quantumcoin/examples/example-generator-sdk-js.ts +0 -77
  50. package/example/node_modules/quantumcoin/examples/example-generator-sdk-ts.js +0 -100
  51. package/example/node_modules/quantumcoin/examples/example-generator-sdk-ts.ts +0 -77
  52. package/example/node_modules/quantumcoin/examples/example.js +0 -67
  53. package/example/node_modules/quantumcoin/examples/example.ts +0 -56
  54. package/example/node_modules/quantumcoin/examples/offline-signing.js +0 -77
  55. package/example/node_modules/quantumcoin/examples/offline-signing.ts +0 -65
  56. package/example/node_modules/quantumcoin/examples/package-lock.json +0 -596
  57. package/example/node_modules/quantumcoin/examples/package.json +0 -32
  58. package/example/node_modules/quantumcoin/examples/read-operations.js +0 -32
  59. package/example/node_modules/quantumcoin/examples/read-operations.ts +0 -31
  60. package/example/node_modules/quantumcoin/examples/sdk-generator-erc20.inline.json +0 -251
  61. package/example/node_modules/quantumcoin/examples/solidity-types.ts +0 -43
  62. package/example/node_modules/quantumcoin/examples/wallet-offline.js +0 -36
  63. package/example/node_modules/quantumcoin/examples/wallet-offline.ts +0 -26
  64. package/example/node_modules/quantumcoin/generate-sdk.js +0 -1846
  65. package/example/node_modules/quantumcoin/index.js +0 -12
  66. package/example/node_modules/quantumcoin/package.json +0 -95
  67. package/example/node_modules/quantumcoin/scripts/copy-declarations.js +0 -31
  68. package/example/node_modules/quantumcoin/scripts/run-all-one-by-one.js +0 -151
  69. package/example/node_modules/quantumcoin/src/abi/fragments.d.ts +0 -42
  70. package/example/node_modules/quantumcoin/src/abi/fragments.js +0 -63
  71. package/example/node_modules/quantumcoin/src/abi/index.d.ts +0 -13
  72. package/example/node_modules/quantumcoin/src/abi/index.js +0 -9
  73. package/example/node_modules/quantumcoin/src/abi/interface.d.ts +0 -128
  74. package/example/node_modules/quantumcoin/src/abi/interface.js +0 -605
  75. package/example/node_modules/quantumcoin/src/abi/js-abi-coder.d.ts +0 -8
  76. package/example/node_modules/quantumcoin/src/abi/js-abi-coder.js +0 -538
  77. package/example/node_modules/quantumcoin/src/constants.d.ts +0 -61
  78. package/example/node_modules/quantumcoin/src/constants.js +0 -94
  79. package/example/node_modules/quantumcoin/src/contract/contract-factory.d.ts +0 -28
  80. package/example/node_modules/quantumcoin/src/contract/contract-factory.js +0 -111
  81. package/example/node_modules/quantumcoin/src/contract/contract.d.ts +0 -113
  82. package/example/node_modules/quantumcoin/src/contract/contract.js +0 -408
  83. package/example/node_modules/quantumcoin/src/contract/index.d.ts +0 -9
  84. package/example/node_modules/quantumcoin/src/contract/index.js +0 -9
  85. package/example/node_modules/quantumcoin/src/errors/index.d.ts +0 -92
  86. package/example/node_modules/quantumcoin/src/errors/index.js +0 -200
  87. package/example/node_modules/quantumcoin/src/generator/index.d.ts +0 -81
  88. package/example/node_modules/quantumcoin/src/generator/index.js +0 -1571
  89. package/example/node_modules/quantumcoin/src/index.d.ts +0 -122
  90. package/example/node_modules/quantumcoin/src/index.js +0 -41
  91. package/example/node_modules/quantumcoin/src/internal/hex.d.ts +0 -68
  92. package/example/node_modules/quantumcoin/src/internal/hex.js +0 -180
  93. package/example/node_modules/quantumcoin/src/providers/extra-providers.d.ts +0 -139
  94. package/example/node_modules/quantumcoin/src/providers/extra-providers.js +0 -614
  95. package/example/node_modules/quantumcoin/src/providers/index.d.ts +0 -17
  96. package/example/node_modules/quantumcoin/src/providers/index.js +0 -10
  97. package/example/node_modules/quantumcoin/src/providers/json-rpc-provider.d.ts +0 -12
  98. package/example/node_modules/quantumcoin/src/providers/json-rpc-provider.js +0 -89
  99. package/example/node_modules/quantumcoin/src/providers/provider.d.ts +0 -206
  100. package/example/node_modules/quantumcoin/src/providers/provider.js +0 -524
  101. package/example/node_modules/quantumcoin/src/types/index.d.ts +0 -214
  102. package/example/node_modules/quantumcoin/src/types/index.js +0 -9
  103. package/example/node_modules/quantumcoin/src/utils/address.d.ts +0 -58
  104. package/example/node_modules/quantumcoin/src/utils/address.js +0 -144
  105. package/example/node_modules/quantumcoin/src/utils/encoding.d.ts +0 -120
  106. package/example/node_modules/quantumcoin/src/utils/encoding.js +0 -306
  107. package/example/node_modules/quantumcoin/src/utils/fixednumber.d.ts +0 -57
  108. package/example/node_modules/quantumcoin/src/utils/fixednumber.js +0 -366
  109. package/example/node_modules/quantumcoin/src/utils/hashing.d.ts +0 -76
  110. package/example/node_modules/quantumcoin/src/utils/hashing.js +0 -298
  111. package/example/node_modules/quantumcoin/src/utils/index.d.ts +0 -63
  112. package/example/node_modules/quantumcoin/src/utils/index.js +0 -14
  113. package/example/node_modules/quantumcoin/src/utils/result.d.ts +0 -57
  114. package/example/node_modules/quantumcoin/src/utils/result.js +0 -128
  115. package/example/node_modules/quantumcoin/src/utils/rlp.d.ts +0 -12
  116. package/example/node_modules/quantumcoin/src/utils/rlp.js +0 -215
  117. package/example/node_modules/quantumcoin/src/utils/units.d.ts +0 -29
  118. package/example/node_modules/quantumcoin/src/utils/units.js +0 -107
  119. package/example/node_modules/quantumcoin/src/wallet/index.d.ts +0 -10
  120. package/example/node_modules/quantumcoin/src/wallet/index.js +0 -8
  121. package/example/node_modules/quantumcoin/src/wallet/wallet.d.ts +0 -192
  122. package/example/node_modules/quantumcoin/src/wallet/wallet.js +0 -713
  123. package/example/node_modules/quantumcoin/test/e2e/all-solidity-types.dynamic.test.js +0 -207
  124. package/example/node_modules/quantumcoin/test/e2e/all-solidity-types.dynamic.test.ts +0 -191
  125. package/example/node_modules/quantumcoin/test/e2e/all-solidity-types.fixtures.js +0 -231
  126. package/example/node_modules/quantumcoin/test/e2e/all-solidity-types.generated-sdks.e2e.test.js +0 -387
  127. package/example/node_modules/quantumcoin/test/e2e/all-solidity-types.generated-sdks.e2e.test.ts +0 -350
  128. package/example/node_modules/quantumcoin/test/e2e/generator-interface.e2e.test.js +0 -165
  129. package/example/node_modules/quantumcoin/test/e2e/generator-interface.e2e.test.ts +0 -160
  130. package/example/node_modules/quantumcoin/test/e2e/helpers.js +0 -59
  131. package/example/node_modules/quantumcoin/test/e2e/signing-context-and-fee.e2e.test.js +0 -141
  132. package/example/node_modules/quantumcoin/test/e2e/signing-context-and-fee.e2e.test.ts +0 -128
  133. package/example/node_modules/quantumcoin/test/e2e/simple-erc20.generated-sdks.e2e.test.js +0 -168
  134. package/example/node_modules/quantumcoin/test/e2e/simple-erc20.generated-sdks.e2e.test.ts +0 -141
  135. package/example/node_modules/quantumcoin/test/e2e/transactional.test.js +0 -245
  136. package/example/node_modules/quantumcoin/test/e2e/transactional.test.ts +0 -208
  137. package/example/node_modules/quantumcoin/test/e2e/typed-generator.e2e.test.js +0 -407
  138. package/example/node_modules/quantumcoin/test/e2e/typed-generator.e2e.test.ts +0 -337
  139. package/example/node_modules/quantumcoin/test/fixtures/ConstructorParam.sol +0 -23
  140. package/example/node_modules/quantumcoin/test/fixtures/MultiContracts.sol +0 -37
  141. package/example/node_modules/quantumcoin/test/fixtures/SimpleStorage.sol +0 -18
  142. package/example/node_modules/quantumcoin/test/fixtures/StakingContract.abi.json +0 -1
  143. package/example/node_modules/quantumcoin/test/integration/ipc-provider.test.js +0 -49
  144. package/example/node_modules/quantumcoin/test/integration/ipc-provider.test.ts +0 -44
  145. package/example/node_modules/quantumcoin/test/integration/provider.test.js +0 -88
  146. package/example/node_modules/quantumcoin/test/integration/provider.test.ts +0 -85
  147. package/example/node_modules/quantumcoin/test/integration/ws-provider.test.js +0 -41
  148. package/example/node_modules/quantumcoin/test/integration/ws-provider.test.ts +0 -38
  149. package/example/node_modules/quantumcoin/test/security/abi-decoder-bounds.test.js +0 -122
  150. package/example/node_modules/quantumcoin/test/security/contract-overrides.test.js +0 -112
  151. package/example/node_modules/quantumcoin/test/security/generator-injection.test.js +0 -195
  152. package/example/node_modules/quantumcoin/test/security/malformed-input.test.js +0 -330
  153. package/example/node_modules/quantumcoin/test/security/malformed-input.test.ts +0 -35
  154. package/example/node_modules/quantumcoin/test/security/rpc-numeric-bounds.test.js +0 -81
  155. package/example/node_modules/quantumcoin/test/security/rpc-trust.test.js +0 -202
  156. package/example/node_modules/quantumcoin/test/unit/_encrypted-output.txt +0 -6
  157. package/example/node_modules/quantumcoin/test/unit/_log-encrypted-jsons.js +0 -45
  158. package/example/node_modules/quantumcoin/test/unit/_write-keystore-fixture.js +0 -16
  159. package/example/node_modules/quantumcoin/test/unit/abi-interface.test.js +0 -110
  160. package/example/node_modules/quantumcoin/test/unit/abi-interface.test.ts +0 -109
  161. package/example/node_modules/quantumcoin/test/unit/address-wallet.test.js +0 -923
  162. package/example/node_modules/quantumcoin/test/unit/address-wallet.test.ts +0 -877
  163. package/example/node_modules/quantumcoin/test/unit/browser-provider.test.js +0 -85
  164. package/example/node_modules/quantumcoin/test/unit/browser-provider.test.ts +0 -79
  165. package/example/node_modules/quantumcoin/test/unit/contract.test.js +0 -85
  166. package/example/node_modules/quantumcoin/test/unit/contract.test.ts +0 -83
  167. package/example/node_modules/quantumcoin/test/unit/encoding-units-rlp.test.js +0 -127
  168. package/example/node_modules/quantumcoin/test/unit/encoding-units-rlp.test.ts +0 -91
  169. package/example/node_modules/quantumcoin/test/unit/errors.test.js +0 -77
  170. package/example/node_modules/quantumcoin/test/unit/errors.test.ts +0 -76
  171. package/example/node_modules/quantumcoin/test/unit/filter-by-blockhash.test.js +0 -55
  172. package/example/node_modules/quantumcoin/test/unit/filter-by-blockhash.test.ts +0 -54
  173. package/example/node_modules/quantumcoin/test/unit/fixednumber.test.js +0 -656
  174. package/example/node_modules/quantumcoin/test/unit/fixednumber.test.ts +0 -660
  175. package/example/node_modules/quantumcoin/test/unit/fixtures/encrypted-keystores-48-32-36.js +0 -9
  176. package/example/node_modules/quantumcoin/test/unit/generate-contract-cli.test.js +0 -42
  177. package/example/node_modules/quantumcoin/test/unit/generate-contract-cli.test.ts +0 -41
  178. package/example/node_modules/quantumcoin/test/unit/generate-sdk-artifacts-json.test.js +0 -113
  179. package/example/node_modules/quantumcoin/test/unit/generate-sdk-artifacts-json.test.ts +0 -110
  180. package/example/node_modules/quantumcoin/test/unit/generator.test.js +0 -149
  181. package/example/node_modules/quantumcoin/test/unit/generator.test.ts +0 -148
  182. package/example/node_modules/quantumcoin/test/unit/hashing.test.js +0 -64
  183. package/example/node_modules/quantumcoin/test/unit/hashing.test.ts +0 -63
  184. package/example/node_modules/quantumcoin/test/unit/init.test.js +0 -39
  185. package/example/node_modules/quantumcoin/test/unit/init.test.ts +0 -38
  186. package/example/node_modules/quantumcoin/test/unit/interface.test.js +0 -56
  187. package/example/node_modules/quantumcoin/test/unit/interface.test.ts +0 -54
  188. package/example/node_modules/quantumcoin/test/unit/internal-hex.test.js +0 -81
  189. package/example/node_modules/quantumcoin/test/unit/internal-hex.test.ts +0 -80
  190. package/example/node_modules/quantumcoin/test/unit/populate-transaction.test.js +0 -98
  191. package/example/node_modules/quantumcoin/test/unit/populate-transaction.test.ts +0 -64
  192. package/example/node_modules/quantumcoin/test/unit/providers.test.js +0 -252
  193. package/example/node_modules/quantumcoin/test/unit/providers.test.ts +0 -251
  194. package/example/node_modules/quantumcoin/test/unit/result.test.js +0 -80
  195. package/example/node_modules/quantumcoin/test/unit/result.test.ts +0 -79
  196. package/example/node_modules/quantumcoin/test/unit/solidity-types.test.js +0 -49
  197. package/example/node_modules/quantumcoin/test/unit/solidity-types.test.ts +0 -39
  198. package/example/node_modules/quantumcoin/test/unit/utils.test.js +0 -57
  199. package/example/node_modules/quantumcoin/test/unit/utils.test.ts +0 -56
  200. package/example/node_modules/quantumcoin/test/verbose-logger.js +0 -74
  201. package/example/node_modules/quantumcoin/tsconfig.build.json +0 -14
  202. package/example/node_modules/seed-words/.github/workflows/publish-npmjs.yaml +0 -22
  203. package/example/node_modules/seed-words/BUILD.md +0 -7
  204. package/example/node_modules/seed-words/LICENSE +0 -121
  205. package/example/node_modules/seed-words/README.md +0 -67
  206. package/example/node_modules/seed-words/dist/seedwords.d.ts +0 -39
  207. package/example/node_modules/seed-words/package.json +0 -27
  208. package/example/node_modules/seed-words/seedwords.js +0 -315
  209. package/example/node_modules/seed-words/seedwords.txt +0 -65536
  210. package/example/node_modules/seed-words/tsconfig.json +0 -21
  211. package/example/package-lock.json +0 -56
  212. package/example/package.json +0 -15
  213. package/tests/encrypted-32.json +0 -1
  214. package/tests/encrypted-36.json +0 -1
  215. package/tests/encrypted-48.json +0 -1
  216. package/tests/generate-verify-vectors.js +0 -91
  217. package/tests/get-gas-price.test.js +0 -59
  218. package/tests/non-transactional.preinit.test.js +0 -41
  219. package/tests/non-transactional.test.js +0 -1389
  220. package/tests/scrypt.test.js +0 -128
  221. package/tests/sign-raw-keytype5-context-null.test.js +0 -107
  222. package/tests/sign-raw-transaction.test.js +0 -196
  223. package/tests/sign-verify.test.js +0 -311
  224. package/tests/transactional.relay.test.js +0 -131
  225. package/tests/transactional.rpc.test.js +0 -103
  226. package/tests/verify-vectors.json +0 -95035
@@ -1,311 +0,0 @@
1
- /**
2
- * Tests for sign(privateKey, message) and verify(publicKey, signature, message).
3
- * Covers all 3 key types: default (null → type 3), 3, and 5.
4
- */
5
- const { describe, test, before } = require('node:test');
6
- const assert = require('node:assert/strict');
7
-
8
- const qcsdk = require('..');
9
-
10
- const MAINNET_CHAIN_ID = 123123;
11
- const READ_RELAY_URL = 'https://sdk.readrelay.quantumcoinapi.com';
12
- const WRITE_RELAY_URL = 'https://sdk.writerelay.quantumcoinapi.com';
13
-
14
- // 32-byte message (CIRCL expects fixed length where applicable)
15
- const MESSAGE_32 = new Uint8Array(32);
16
- for (let i = 0; i < 32; i++) MESSAGE_32[i] = (i + 1) & 0xff;
17
-
18
- function isCirclAvailable() {
19
- const w = qcsdk.newWallet();
20
- return (
21
- typeof w === 'object' &&
22
- w != null &&
23
- w.privateKey != null &&
24
- w.address != null &&
25
- qcsdk.verifyWallet(w) === true
26
- );
27
- }
28
-
29
- function toByteArray(buf) {
30
- return buf instanceof Uint8Array ? Array.from(buf) : buf;
31
- }
32
-
33
- describe('sign and verify', () => {
34
- before(async () => {
35
- const cfg = new qcsdk.Config(READ_RELAY_URL, WRITE_RELAY_URL, MAINNET_CHAIN_ID, '', '');
36
- const initResult = await qcsdk.initialize(cfg);
37
- assert.equal(initResult, true, 'SDK initialize should succeed');
38
- });
39
-
40
- test('CIRCL is available', () => {
41
- assert.ok(isCirclAvailable(), 'CIRCL must be loaded and verifyWallet(newWallet()) must pass');
42
- });
43
-
44
- test('keyType default (null): sign then verify with wallet bytes', () => {
45
- assert.ok(isCirclAvailable());
46
- const wallet = qcsdk.newWallet(null);
47
- assert.ok(wallet && typeof wallet === 'object');
48
- const privateKey = wallet.privateKey;
49
- const publicKey = wallet.publicKey;
50
- const message = toByteArray(MESSAGE_32);
51
-
52
- const signResult = qcsdk.sign(privateKey, message);
53
- assert.equal(signResult.resultCode, 0, `sign failed: resultCode ${signResult.resultCode}`);
54
- assert.ok(signResult.signature != null && signResult.signature.length > 0);
55
-
56
- const verifyResult = qcsdk.verify(publicKey, signResult.signature, message);
57
- assert.equal(verifyResult.resultCode, 0, `verify failed: resultCode ${verifyResult.resultCode}`);
58
- assert.equal(verifyResult.valid, true);
59
- });
60
-
61
- test('keyType 3: sign then verify with wallet bytes', () => {
62
- assert.ok(isCirclAvailable());
63
- const wallet = qcsdk.newWallet(3);
64
- assert.ok(wallet && typeof wallet === 'object');
65
- const privateKey = wallet.privateKey;
66
- const publicKey = wallet.publicKey;
67
- const message = toByteArray(MESSAGE_32);
68
-
69
- const signResult = qcsdk.sign(privateKey, message);
70
- assert.equal(signResult.resultCode, 0, `sign failed: resultCode ${signResult.resultCode}`);
71
- assert.ok(signResult.signature != null && signResult.signature.length > 0);
72
-
73
- const verifyResult = qcsdk.verify(publicKey, signResult.signature, message);
74
- assert.equal(verifyResult.resultCode, 0, `verify failed: resultCode ${verifyResult.resultCode}`);
75
- assert.equal(verifyResult.valid, true);
76
- });
77
-
78
- test('keyType 5: sign then verify with wallet bytes', () => {
79
- assert.ok(isCirclAvailable());
80
- const wallet = qcsdk.newWallet(5);
81
- assert.ok(wallet && typeof wallet === 'object');
82
- const privateKey = wallet.privateKey;
83
- const publicKey = wallet.publicKey;
84
- const message = toByteArray(MESSAGE_32);
85
-
86
- const signResult = qcsdk.sign(privateKey, message);
87
- assert.equal(signResult.resultCode, 0, `sign failed: resultCode ${signResult.resultCode}`);
88
- assert.ok(signResult.signature != null && signResult.signature.length > 0);
89
-
90
- const verifyResult = qcsdk.verify(publicKey, signResult.signature, message);
91
- assert.equal(verifyResult.resultCode, 0, `verify failed: resultCode ${verifyResult.resultCode}`);
92
- assert.equal(verifyResult.valid, true);
93
- });
94
-
95
- test('verify with wrong message returns valid: false', () => {
96
- assert.ok(isCirclAvailable());
97
- const wallet = qcsdk.newWallet(null);
98
- const message = toByteArray(MESSAGE_32);
99
- const signResult = qcsdk.sign(wallet.privateKey, message);
100
- assert.equal(signResult.resultCode, 0);
101
-
102
- const wrongMessage = new Uint8Array(32);
103
- wrongMessage[0] = 0xff;
104
- const verifyResult = qcsdk.verify(wallet.publicKey, signResult.signature, wrongMessage);
105
- assert.equal(verifyResult.valid, false, 'valid must be false for wrong message');
106
- // resultCode may be -717 (CIRCL error) or -719 (signature invalid)
107
- assert.ok(verifyResult.resultCode === -717 || verifyResult.resultCode === -719);
108
- });
109
-
110
- test('sign with invalid privateKey returns error code', () => {
111
- const result = qcsdk.sign(null, MESSAGE_32);
112
- assert.notEqual(result.resultCode, 0);
113
- assert.equal(result.signature, null);
114
- });
115
-
116
- test('verify with invalid publicKey returns error code', () => {
117
- assert.ok(isCirclAvailable());
118
- const wallet = qcsdk.newWallet(null);
119
- const signResult = qcsdk.sign(wallet.privateKey, toByteArray(MESSAGE_32));
120
- assert.equal(signResult.resultCode, 0);
121
-
122
- const result = qcsdk.verify(null, signResult.signature, toByteArray(MESSAGE_32));
123
- assert.notEqual(result.resultCode, 0);
124
- assert.equal(result.valid, false);
125
- });
126
-
127
- test('sign with explicit signingContext 0 (keyType 3 wallet) then verify', () => {
128
- assert.ok(isCirclAvailable());
129
- const wallet = qcsdk.newWallet(3);
130
- const message = toByteArray(MESSAGE_32);
131
- const signResult = qcsdk.sign(wallet.privateKey, message, 0);
132
- assert.equal(signResult.resultCode, 0, `sign failed: ${signResult.resultCode}`);
133
- const verifyResult = qcsdk.verify(wallet.publicKey, signResult.signature, message);
134
- assert.equal(verifyResult.resultCode, 0);
135
- assert.equal(verifyResult.valid, true);
136
- });
137
-
138
- test('sign with explicit signingContext 1 (keyType 5 wallet) then verify', () => {
139
- assert.ok(isCirclAvailable());
140
- const wallet = qcsdk.newWallet(5);
141
- const message = toByteArray(MESSAGE_32);
142
- const signResult = qcsdk.sign(wallet.privateKey, message, 1);
143
- assert.equal(signResult.resultCode, 0, `sign failed: ${signResult.resultCode}`);
144
- const verifyResult = qcsdk.verify(wallet.publicKey, signResult.signature, message);
145
- assert.equal(verifyResult.resultCode, 0);
146
- assert.equal(verifyResult.valid, true);
147
- });
148
-
149
- test('sign with explicit signingContext 2 (keyType 3 wallet) then verify', () => {
150
- assert.ok(isCirclAvailable());
151
- const wallet = qcsdk.newWallet(3);
152
- const message = toByteArray(MESSAGE_32);
153
- const signResult = qcsdk.sign(wallet.privateKey, message, 2);
154
- assert.equal(signResult.resultCode, 0, `sign failed: ${signResult.resultCode}`);
155
- const verifyResult = qcsdk.verify(wallet.publicKey, signResult.signature, message);
156
- assert.equal(verifyResult.resultCode, 0);
157
- assert.equal(verifyResult.valid, true);
158
- });
159
-
160
- test('sign with invalid signingContext returns error code', () => {
161
- assert.ok(isCirclAvailable());
162
- const wallet = qcsdk.newWallet(3);
163
- const result = qcsdk.sign(wallet.privateKey, toByteArray(MESSAGE_32), 99);
164
- assert.notEqual(result.resultCode, 0);
165
- assert.equal(result.signature, null);
166
- });
167
- });
168
-
169
- describe('verify by signature first byte (types 3, 4, 5)', () => {
170
- test('verify type 3 (signCompact): sign(..., 0) then verify', () => {
171
- const wallet = qcsdk.newWallet(3);
172
- const message = toByteArray(MESSAGE_32);
173
- const signResult = qcsdk.sign(wallet.privateKey, message, 0);
174
- assert.equal(signResult.resultCode, 0);
175
- const verifyResult = qcsdk.verify(wallet.publicKey, signResult.signature, message);
176
- assert.equal(verifyResult.resultCode, 0);
177
- assert.equal(verifyResult.valid, true);
178
- });
179
-
180
- test('verify type 4 (hybrid full): sign(..., 2) then verify', () => {
181
- const wallet = qcsdk.newWallet(3);
182
- const message = toByteArray(MESSAGE_32);
183
- const signResult = qcsdk.sign(wallet.privateKey, message, 2);
184
- assert.equal(signResult.resultCode, 0);
185
- const verifyResult = qcsdk.verify(wallet.publicKey, signResult.signature, message);
186
- assert.equal(verifyResult.resultCode, 0);
187
- assert.equal(verifyResult.valid, true);
188
- });
189
-
190
- test('verify type 5 (hybrid5): sign(..., 1) then verify', () => {
191
- const wallet = qcsdk.newWallet(5);
192
- const message = toByteArray(MESSAGE_32);
193
- const signResult = qcsdk.sign(wallet.privateKey, message, 1);
194
- assert.equal(signResult.resultCode, 0);
195
- const verifyResult = qcsdk.verify(wallet.publicKey, signResult.signature, message);
196
- assert.equal(verifyResult.resultCode, 0);
197
- assert.equal(verifyResult.valid, true);
198
- });
199
-
200
- test('verify with invalid signature first byte returns -718', () => {
201
- const wallet = qcsdk.newWallet(3);
202
- const signResult = qcsdk.sign(wallet.privateKey, toByteArray(MESSAGE_32), 0);
203
- assert.equal(signResult.resultCode, 0);
204
- const sig = signResult.signature;
205
- const badSig = Array.isArray(sig) ? sig.slice() : Array.from(sig);
206
- badSig[0] = 0;
207
- const result = qcsdk.verify(wallet.publicKey, badSig, toByteArray(MESSAGE_32));
208
- assert.equal(result.resultCode, -718, 'first byte 0 is unknown type');
209
- assert.equal(result.valid, false);
210
- });
211
-
212
- test('verify type 1 (hybrideds verifyCompact): dispatch runs, wrong sig fails with -717 or -719', () => {
213
- const wallet = qcsdk.newWallet(3);
214
- const signResult = qcsdk.sign(wallet.privateKey, toByteArray(MESSAGE_32), 0);
215
- assert.equal(signResult.resultCode, 0);
216
- const sig = signResult.signature;
217
- const sigWithType1 = Array.isArray(sig) ? sig.slice() : Array.from(sig);
218
- sigWithType1[0] = 1;
219
- const result = qcsdk.verify(wallet.publicKey, sigWithType1, toByteArray(MESSAGE_32));
220
- assert.equal(result.valid, false);
221
- assert.ok(result.resultCode === -717 || result.resultCode === -719, 'type 1 dispatch should run and fail verify');
222
- });
223
-
224
- test('verify type 2 (hybrideds verify): dispatch runs, wrong sig fails with -717 or -719', () => {
225
- const wallet = qcsdk.newWallet(3);
226
- const signResult = qcsdk.sign(wallet.privateKey, toByteArray(MESSAGE_32), 0);
227
- assert.equal(signResult.resultCode, 0);
228
- const sig = signResult.signature;
229
- const sigWithType2 = Array.isArray(sig) ? sig.slice() : Array.from(sig);
230
- sigWithType2[0] = 2;
231
- const result = qcsdk.verify(wallet.publicKey, sigWithType2, toByteArray(MESSAGE_32));
232
- assert.equal(result.valid, false);
233
- assert.ok(result.resultCode === -717 || result.resultCode === -719, 'type 2 dispatch should run and fail verify');
234
- });
235
- });
236
-
237
- describe('verify hardcoded deterministic', () => {
238
- const vectors = require('./verify-vectors.json');
239
-
240
- describe('keyType 3 verifyCompact (32-word seed, sign context 0)', () => {
241
- const { publicKey: PUBLIC_KEY, signature: SIGNATURE, message: MESSAGE } = vectors.type3Compact;
242
-
243
- test('accepts hardcoded publicKey + signature + message', () => {
244
- const result = qcsdk.verify(PUBLIC_KEY, SIGNATURE, MESSAGE);
245
- assert.equal(result.resultCode, 0, `expected resultCode 0, got ${result.resultCode}`);
246
- assert.equal(result.valid, true, 'valid must be true for correct vector');
247
- });
248
-
249
- test('rejects hardcoded vector with wrong signature', () => {
250
- const wrongSignature = SIGNATURE.slice();
251
- wrongSignature[0] = (wrongSignature[0] + 1) % 256;
252
- const result = qcsdk.verify(PUBLIC_KEY, wrongSignature, MESSAGE);
253
- assert.equal(result.valid, false, 'valid must be false for wrong signature');
254
- });
255
-
256
- test('rejects hardcoded vector with wrong message', () => {
257
- const wrongMessage = MESSAGE.slice();
258
- wrongMessage[0] = (wrongMessage[0] + 1) % 256;
259
- const result = qcsdk.verify(PUBLIC_KEY, SIGNATURE, wrongMessage);
260
- assert.equal(result.valid, false, 'valid must be false for wrong message');
261
- });
262
- });
263
-
264
- describe('keyType 3 verify full (32-word seed, sign context 2)', () => {
265
- const { publicKey: PUBLIC_KEY, signature: SIGNATURE, message: MESSAGE } = vectors.type3Full;
266
-
267
- test('accepts hardcoded publicKey + signature + message', () => {
268
- const result = qcsdk.verify(PUBLIC_KEY, SIGNATURE, MESSAGE);
269
- assert.equal(result.resultCode, 0, `expected resultCode 0, got ${result.resultCode}`);
270
- assert.equal(result.valid, true, 'valid must be true for correct vector');
271
- });
272
-
273
- test('rejects hardcoded vector with wrong signature', () => {
274
- const wrongSignature = SIGNATURE.slice();
275
- wrongSignature[0] = (wrongSignature[0] + 1) % 256;
276
- const result = qcsdk.verify(PUBLIC_KEY, wrongSignature, MESSAGE);
277
- assert.equal(result.valid, false, 'valid must be false for wrong signature');
278
- });
279
-
280
- test('rejects hardcoded vector with wrong message', () => {
281
- const wrongMessage = MESSAGE.slice();
282
- wrongMessage[0] = (wrongMessage[0] + 1) % 256;
283
- const result = qcsdk.verify(PUBLIC_KEY, SIGNATURE, wrongMessage);
284
- assert.equal(result.valid, false, 'valid must be false for wrong message');
285
- });
286
- });
287
-
288
- describe('keyType 5 (36-word seed, sign context 1)', () => {
289
- const { publicKey: PUBLIC_KEY, signature: SIGNATURE, message: MESSAGE } = vectors.type5;
290
-
291
- test('accepts hardcoded publicKey + signature + message', () => {
292
- const result = qcsdk.verify(PUBLIC_KEY, SIGNATURE, MESSAGE);
293
- assert.equal(result.resultCode, 0, `expected resultCode 0, got ${result.resultCode}`);
294
- assert.equal(result.valid, true, 'valid must be true for correct vector');
295
- });
296
-
297
- test('rejects hardcoded vector with wrong signature', () => {
298
- const wrongSignature = SIGNATURE.slice();
299
- wrongSignature[0] = (wrongSignature[0] + 1) % 256;
300
- const result = qcsdk.verify(PUBLIC_KEY, wrongSignature, MESSAGE);
301
- assert.equal(result.valid, false, 'valid must be false for wrong signature');
302
- });
303
-
304
- test('rejects hardcoded vector with wrong message', () => {
305
- const wrongMessage = MESSAGE.slice();
306
- wrongMessage[0] = (wrongMessage[0] + 1) % 256;
307
- const result = qcsdk.verify(PUBLIC_KEY, SIGNATURE, wrongMessage);
308
- assert.equal(result.valid, false, 'valid must be false for wrong message');
309
- });
310
- });
311
- });
@@ -1,131 +0,0 @@
1
- const { describe, test } = require('node:test');
2
- const assert = require('node:assert/strict');
3
-
4
- // These are the "transactional" tests using relay endpoints from examples.
5
- // Per requirements:
6
- // - Relay transactional tests must use the relay endpoints shown in examples
7
- // - The transaction must either succeed OR fail only due to no coins for gas.
8
-
9
- const qcsdk = require('..');
10
-
11
- const MAINNET_CHAIN_ID = 123123;
12
- const READ_RELAY_URL = 'https://sdk.readrelay.quantumcoinapi.com';
13
- const WRITE_RELAY_URL = 'https://sdk.writerelay.quantumcoinapi.com';
14
-
15
- const TO_ADDRESS_EXAMPLE =
16
- '0x8293cd9b6ac502d2fe077b0c157dad39f36a5e546525b053151dced633634612';
17
-
18
- function isCirclAvailable() {
19
- const w = qcsdk.newWallet();
20
- return (
21
- typeof w === 'object' &&
22
- w != null &&
23
- w.privateKey != null &&
24
- w.address != null &&
25
- qcsdk.verifyWallet(w) === true
26
- );
27
- }
28
-
29
- const EXAMPLE_WALLET_ENCRYPTED_JSON =
30
- '{"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}';
31
- const EXAMPLE_WALLET_PASSPHRASE = 'QuantumCoinExample123!';
32
-
33
- function isInsufficientGasErrorText(text) {
34
- if (!text || typeof text !== 'string') return false;
35
- const t = text.toLowerCase();
36
- return t.includes('insufficient') && t.includes('fund') && t.includes('gas');
37
- }
38
-
39
- async function readResponseTextSafe(response) {
40
- try {
41
- if (!response) return '';
42
- return await response.text();
43
- } catch {
44
- return '';
45
- }
46
- }
47
-
48
- describe('transactional', { concurrency: 1 }, () => {
49
- test(
50
- 'relay submit sendCoins: must succeed or fail only for insufficient gas',
51
- { timeout: 120_000 },
52
- async () => {
53
- const initOk = await qcsdk.initialize(
54
- new qcsdk.Config(READ_RELAY_URL, WRITE_RELAY_URL, MAINNET_CHAIN_ID, '', ''),
55
- );
56
- assert.equal(initOk, true);
57
-
58
- assert.ok(isCirclAvailable(), 'CIRCL WASM must be loaded and verifyWallet(newWallet()) must pass');
59
- const wallet = qcsdk.newWallet();
60
- assert.ok(wallet);
61
-
62
- const acct = await qcsdk.getAccountDetails(wallet.address);
63
- assert.ok(acct);
64
- assert.equal(acct.resultCode, 0, 'relay getAccountDetails must succeed to proceed');
65
- const nonce = acct.accountDetails.nonce;
66
- assert.ok(Number.isInteger(nonce) && nonce >= 0);
67
-
68
- // Send 0 coins so the only acceptable failure is "no gas".
69
- const send = await qcsdk.sendCoins(wallet, TO_ADDRESS_EXAMPLE, '0', nonce);
70
- assert.ok(send);
71
-
72
- if (send.resultCode === 0) {
73
- // Accepted by relay
74
- return;
75
- }
76
-
77
- // Only acceptable failure is insufficient gas.
78
- const statusText = send.response?.statusText ?? '';
79
- const bodyText = await readResponseTextSafe(send.response);
80
- const combined = `${statusText}\n${bodyText}`.trim();
81
-
82
- assert.ok(
83
- isInsufficientGasErrorText(combined),
84
- `Transactional relay test failed with unexpected error. resultCode=${send.resultCode}\n${combined || '(no response body)'}`,
85
- );
86
- },
87
- );
88
-
89
- test(
90
- 'relay signSendCoinTransaction + postTransaction: must succeed or fail only for insufficient gas',
91
- { timeout: 120_000 },
92
- async () => {
93
- await qcsdk.initialize(
94
- new qcsdk.Config(READ_RELAY_URL, WRITE_RELAY_URL, MAINNET_CHAIN_ID, '', ''),
95
- );
96
- // initialize() returns false if already initialized (e.g. by previous test); either way SDK is ready
97
-
98
- assert.ok(isCirclAvailable(), 'CIRCL WASM must be loaded and verifyWallet(newWallet()) must pass');
99
- const wallet = qcsdk.newWallet();
100
- assert.ok(wallet);
101
-
102
- const acct = await qcsdk.getAccountDetails(wallet.address);
103
- assert.ok(acct);
104
- assert.equal(acct.resultCode, 0, 'relay getAccountDetails must succeed to proceed');
105
- const nonce = acct.accountDetails.nonce;
106
- assert.ok(Number.isInteger(nonce) && nonce >= 0);
107
-
108
- const signResult = await qcsdk.signSendCoinTransaction(wallet, TO_ADDRESS_EXAMPLE, '0', nonce);
109
- assert.ok(signResult);
110
- assert.equal(signResult.resultCode, 0, 'signSendCoinTransaction must succeed');
111
- assert.ok(signResult.txnData && typeof signResult.txnData === 'string');
112
-
113
- const post = await qcsdk.postTransaction(signResult.txnData);
114
- assert.ok(post && typeof post.resultCode === 'number');
115
-
116
- if (post.resultCode === 0) {
117
- return;
118
- }
119
-
120
- const statusText = post.response?.statusText ?? '';
121
- const bodyText = await readResponseTextSafe(post.response);
122
- const combined = `${statusText}\n${bodyText}`.trim();
123
-
124
- assert.ok(
125
- isInsufficientGasErrorText(combined),
126
- `Transactional relay test (signSendCoinTransaction + postTransaction) failed with unexpected error. resultCode=${post.resultCode}\n${combined || '(no response body)'}`,
127
- );
128
- },
129
- );
130
- });
131
-
@@ -1,103 +0,0 @@
1
- const { describe, test } = require('node:test');
2
- const assert = require('node:assert/strict');
3
-
4
- // These are the "transactional" tests: they attempt to submit a transaction.
5
- // Per requirements:
6
- // - RPC-based transactional tests must use `https://public.rpc.quantumcoinapi.com`
7
- // - The transaction must either succeed OR fail only due to no coins for gas.
8
-
9
- const qcsdk = require('..');
10
-
11
- const MAINNET_CHAIN_ID = 123123;
12
- const PUBLIC_RPC_URL = 'https://public.rpc.quantumcoinapi.com';
13
-
14
- const TO_ADDRESS_EXAMPLE =
15
- '0x8293cd9b6ac502d2fe077b0c157dad39f36a5e546525b053151dced633634612';
16
-
17
- function isCirclAvailable() {
18
- const w = qcsdk.newWallet();
19
- return (
20
- typeof w === 'object' &&
21
- w != null &&
22
- w.privateKey != null &&
23
- w.address != null &&
24
- qcsdk.verifyWallet(w) === true
25
- );
26
- }
27
-
28
- const EXAMPLE_WALLET_ENCRYPTED_JSON =
29
- '{"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}';
30
- const EXAMPLE_WALLET_PASSPHRASE = 'QuantumCoinExample123!';
31
-
32
- async function rpc(method, params) {
33
- const response = await fetch(PUBLIC_RPC_URL, {
34
- method: 'POST',
35
- headers: { 'Content-Type': 'application/json' },
36
- body: JSON.stringify({ jsonrpc: '2.0', id: 1, method, params }),
37
- });
38
- assert.ok(response.ok, `RPC HTTP ${response.status}`);
39
- return response.json();
40
- }
41
-
42
- function isInsufficientGasErrorMessage(message) {
43
- if (!message || typeof message !== 'string') return false;
44
- const m = message.toLowerCase();
45
- return (
46
- (m.includes('insufficient') && m.includes('fund')) &&
47
- m.includes('gas')
48
- );
49
- }
50
-
51
- describe('transactional', { concurrency: 1 }, () => {
52
- test(
53
- 'RPC submit signed raw tx: must succeed or fail only for insufficient gas',
54
- { timeout: 120_000 },
55
- async () => {
56
- // For RPC-only flows, read/write URLs can be empty strings (see examples)
57
- const initOk = await qcsdk.initialize(new qcsdk.Config('', '', MAINNET_CHAIN_ID, '', ''));
58
- assert.equal(initOk, true);
59
-
60
- assert.ok(isCirclAvailable(), 'CIRCL WASM must be loaded and verifyWallet(newWallet()) must pass');
61
- const wallet = qcsdk.newWallet();
62
- assert.ok(wallet);
63
-
64
- const txnCount = await rpc('eth_getTransactionCount', [wallet.address, 'latest']);
65
- assert.ok(txnCount && (txnCount.result || txnCount.error));
66
- assert.ok(txnCount.result, `RPC error: ${txnCount.error?.message ?? 'unknown'}`);
67
- const nonce = parseInt(txnCount.result, 16);
68
- assert.ok(Number.isInteger(nonce) && nonce >= 0);
69
-
70
- // Build and sign a minimal transfer with value 0 to keep "value" out of the equation.
71
- const txReq = new qcsdk.TransactionSigningRequest(
72
- wallet,
73
- TO_ADDRESS_EXAMPLE,
74
- '0x0',
75
- nonce,
76
- null,
77
- 21000,
78
- null,
79
- MAINNET_CHAIN_ID,
80
- );
81
- const sign = qcsdk.signRawTransaction(txReq);
82
- assert.equal(sign.resultCode, 0);
83
- assert.ok(typeof sign.txnData === 'string' && sign.txnData.startsWith('0x'));
84
-
85
- const send = await rpc('eth_sendRawTransaction', [sign.txnData]);
86
-
87
- if (send && send.result && typeof send.result === 'string') {
88
- assert.ok(send.result.startsWith('0x'));
89
- return;
90
- }
91
-
92
- console.log(sign.txnData);
93
-
94
- // If it failed, ONLY accept "insufficient funds for gas" style errors.
95
- const msg = send?.error?.message ?? '';
96
- assert.ok(
97
- isInsufficientGasErrorMessage(msg),
98
- `Transactional RPC test failed with unexpected error: ${msg || JSON.stringify(send)}`,
99
- );
100
- },
101
- );
102
- });
103
-