quantumcoin 7.0.10 → 7.0.11

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 (172) hide show
  1. package/README-SDK.md +0 -5
  2. package/README.md +1 -3
  3. package/SPEC.md +2 -63
  4. package/config.js +10 -2
  5. package/examples/example.js +0 -5
  6. package/examples/example.ts +0 -5
  7. package/examples/node_modules/.bin/esbuild +16 -0
  8. package/examples/node_modules/.bin/esbuild.cmd +17 -0
  9. package/examples/node_modules/.bin/esbuild.ps1 +28 -0
  10. package/examples/node_modules/.bin/sdkgen +16 -0
  11. package/examples/node_modules/.bin/sdkgen.cmd +17 -0
  12. package/examples/node_modules/.bin/sdkgen.ps1 +28 -0
  13. package/examples/node_modules/.bin/tsx +16 -0
  14. package/examples/node_modules/.bin/tsx.cmd +17 -0
  15. package/examples/node_modules/.bin/tsx.ps1 +28 -0
  16. package/examples/node_modules/.package-lock.json +235 -0
  17. package/examples/node_modules/@esbuild/win32-x64/README.md +3 -0
  18. package/examples/node_modules/@esbuild/win32-x64/esbuild.exe +0 -0
  19. package/examples/node_modules/@esbuild/win32-x64/package.json +20 -0
  20. package/examples/node_modules/esbuild/LICENSE.md +21 -0
  21. package/examples/node_modules/esbuild/README.md +3 -0
  22. package/examples/node_modules/esbuild/bin/esbuild +223 -0
  23. package/examples/node_modules/esbuild/install.js +289 -0
  24. package/examples/node_modules/esbuild/lib/main.d.ts +716 -0
  25. package/examples/node_modules/esbuild/lib/main.js +2532 -0
  26. package/examples/node_modules/esbuild/package.json +49 -0
  27. package/examples/node_modules/get-tsconfig/LICENSE +21 -0
  28. package/examples/node_modules/get-tsconfig/README.md +235 -0
  29. package/examples/node_modules/get-tsconfig/dist/index.cjs +7 -0
  30. package/examples/node_modules/get-tsconfig/dist/index.d.cts +2088 -0
  31. package/examples/node_modules/get-tsconfig/dist/index.d.mts +2088 -0
  32. package/examples/node_modules/get-tsconfig/dist/index.mjs +7 -0
  33. package/examples/node_modules/get-tsconfig/package.json +46 -0
  34. package/examples/node_modules/quantum-coin-js-sdk/.github/workflows/publish-npmjs.yaml +22 -0
  35. package/examples/node_modules/quantum-coin-js-sdk/LICENSE +21 -0
  36. package/examples/node_modules/quantum-coin-js-sdk/LICENSE-wasm_exec.js.txt +30 -0
  37. package/examples/node_modules/quantum-coin-js-sdk/README.md +1665 -0
  38. package/examples/node_modules/quantum-coin-js-sdk/example/README.md +14 -0
  39. package/examples/node_modules/quantum-coin-js-sdk/example/conversion-example.js +19 -0
  40. package/examples/node_modules/quantum-coin-js-sdk/example/example-create-contract.js +396 -0
  41. package/examples/node_modules/quantum-coin-js-sdk/example/example-encode-decode-rlp.js +225 -0
  42. package/examples/node_modules/quantum-coin-js-sdk/example/example-event-pack-unpack.js +391 -0
  43. package/examples/node_modules/quantum-coin-js-sdk/example/example-misc.js +101 -0
  44. package/examples/node_modules/quantum-coin-js-sdk/example/example-rpc-send-signRawTransaction.js +318 -0
  45. package/examples/node_modules/quantum-coin-js-sdk/example/example-rpc-send.js +116 -0
  46. package/examples/node_modules/quantum-coin-js-sdk/example/example-send.js +70 -0
  47. package/examples/node_modules/quantum-coin-js-sdk/example/example-token-pack-unpack.js +961 -0
  48. package/examples/node_modules/quantum-coin-js-sdk/example/example-wallet-version4.js +35 -0
  49. package/examples/node_modules/quantum-coin-js-sdk/example/example-wallet.js +43 -0
  50. package/examples/node_modules/quantum-coin-js-sdk/example/example.js +405 -0
  51. package/examples/node_modules/quantum-coin-js-sdk/example/package-lock.json +134 -0
  52. package/examples/node_modules/quantum-coin-js-sdk/example/package.json +15 -0
  53. package/examples/node_modules/quantum-coin-js-sdk/index.d.ts +1024 -0
  54. package/examples/node_modules/quantum-coin-js-sdk/index.js +3062 -0
  55. package/examples/node_modules/quantum-coin-js-sdk/package.json +34 -0
  56. package/examples/node_modules/quantum-coin-js-sdk/tests/encrypted-32.json +1 -0
  57. package/examples/node_modules/quantum-coin-js-sdk/tests/encrypted-36.json +1 -0
  58. package/examples/node_modules/quantum-coin-js-sdk/tests/encrypted-48.json +1 -0
  59. package/examples/node_modules/quantum-coin-js-sdk/tests/generate-verify-vectors.js +91 -0
  60. package/examples/node_modules/quantum-coin-js-sdk/tests/non-transactional.preinit.test.js +41 -0
  61. package/examples/node_modules/quantum-coin-js-sdk/tests/non-transactional.test.js +686 -0
  62. package/examples/node_modules/quantum-coin-js-sdk/tests/sign-raw-keytype5-context-null.test.js +107 -0
  63. package/examples/node_modules/quantum-coin-js-sdk/tests/sign-raw-transaction.test.js +196 -0
  64. package/examples/node_modules/quantum-coin-js-sdk/tests/sign-verify.test.js +311 -0
  65. package/examples/node_modules/quantum-coin-js-sdk/tests/transactional.relay.test.js +131 -0
  66. package/examples/node_modules/quantum-coin-js-sdk/tests/transactional.rpc.test.js +103 -0
  67. package/examples/node_modules/quantum-coin-js-sdk/tests/verify-vectors.json +95035 -0
  68. package/examples/node_modules/quantum-coin-js-sdk/wasmBase64.d.ts +9 -0
  69. package/examples/node_modules/quantum-coin-js-sdk/wasmBase64.js +16 -0
  70. package/examples/node_modules/quantum-coin-js-sdk/wasm_exec.d.ts +0 -0
  71. package/examples/node_modules/quantum-coin-js-sdk/wasm_exec.js +587 -0
  72. package/examples/node_modules/resolve-pkg-maps/LICENSE +21 -0
  73. package/examples/node_modules/resolve-pkg-maps/README.md +216 -0
  74. package/examples/node_modules/resolve-pkg-maps/dist/index.cjs +1 -0
  75. package/examples/node_modules/resolve-pkg-maps/dist/index.d.cts +11 -0
  76. package/examples/node_modules/resolve-pkg-maps/dist/index.d.mts +11 -0
  77. package/examples/node_modules/resolve-pkg-maps/dist/index.mjs +1 -0
  78. package/examples/node_modules/resolve-pkg-maps/package.json +42 -0
  79. package/examples/node_modules/seed-words/.github/workflows/publish-npmjs.yaml +22 -0
  80. package/examples/node_modules/seed-words/BUILD.md +7 -0
  81. package/examples/node_modules/seed-words/LICENSE +121 -0
  82. package/examples/node_modules/seed-words/README.md +67 -0
  83. package/examples/node_modules/seed-words/dist/seedwords.d.ts +39 -0
  84. package/examples/node_modules/seed-words/package.json +27 -0
  85. package/examples/node_modules/seed-words/seedwords.js +315 -0
  86. package/examples/node_modules/seed-words/seedwords.txt +65536 -0
  87. package/examples/node_modules/seed-words/tsconfig.json +21 -0
  88. package/examples/node_modules/tsx/LICENSE +21 -0
  89. package/examples/node_modules/tsx/README.md +32 -0
  90. package/examples/node_modules/tsx/dist/cjs/api/index.cjs +1 -0
  91. package/examples/node_modules/tsx/dist/cjs/api/index.d.cts +35 -0
  92. package/examples/node_modules/tsx/dist/cjs/api/index.d.mts +35 -0
  93. package/examples/node_modules/tsx/dist/cjs/api/index.mjs +1 -0
  94. package/examples/node_modules/tsx/dist/cjs/index.cjs +1 -0
  95. package/examples/node_modules/tsx/dist/cjs/index.mjs +1 -0
  96. package/examples/node_modules/tsx/dist/cli.cjs +54 -0
  97. package/examples/node_modules/tsx/dist/cli.mjs +55 -0
  98. package/examples/node_modules/tsx/dist/client-BQVF1NaW.mjs +1 -0
  99. package/examples/node_modules/tsx/dist/client-D6NvIMSC.cjs +1 -0
  100. package/examples/node_modules/tsx/dist/esm/api/index.cjs +1 -0
  101. package/examples/node_modules/tsx/dist/esm/api/index.d.cts +35 -0
  102. package/examples/node_modules/tsx/dist/esm/api/index.d.mts +35 -0
  103. package/examples/node_modules/tsx/dist/esm/api/index.mjs +1 -0
  104. package/examples/node_modules/tsx/dist/esm/index.cjs +2 -0
  105. package/examples/node_modules/tsx/dist/esm/index.mjs +2 -0
  106. package/examples/node_modules/tsx/dist/get-pipe-path-BHW2eJdv.mjs +1 -0
  107. package/examples/node_modules/tsx/dist/get-pipe-path-BoR10qr8.cjs +1 -0
  108. package/examples/node_modules/tsx/dist/index-7AaEi15b.mjs +14 -0
  109. package/examples/node_modules/tsx/dist/index-BWFBUo6r.cjs +1 -0
  110. package/examples/node_modules/tsx/dist/index-gbaejti9.mjs +1 -0
  111. package/examples/node_modules/tsx/dist/index-gckBtVBf.cjs +14 -0
  112. package/examples/node_modules/tsx/dist/lexer-DQCqS3nf.mjs +3 -0
  113. package/examples/node_modules/tsx/dist/lexer-DgIbo0BU.cjs +3 -0
  114. package/examples/node_modules/tsx/dist/loader.cjs +1 -0
  115. package/examples/node_modules/tsx/dist/loader.mjs +1 -0
  116. package/examples/node_modules/tsx/dist/node-features-_8ZFwP_x.mjs +1 -0
  117. package/examples/node_modules/tsx/dist/node-features-roYmp9jK.cjs +1 -0
  118. package/examples/node_modules/tsx/dist/package-CeBgXWuR.mjs +1 -0
  119. package/examples/node_modules/tsx/dist/package-Dxt5kIHw.cjs +1 -0
  120. package/examples/node_modules/tsx/dist/patch-repl.cjs +1 -0
  121. package/examples/node_modules/tsx/dist/patch-repl.mjs +1 -0
  122. package/examples/node_modules/tsx/dist/preflight.cjs +1 -0
  123. package/examples/node_modules/tsx/dist/preflight.mjs +1 -0
  124. package/examples/node_modules/tsx/dist/register-2sWVXuRQ.cjs +1 -0
  125. package/examples/node_modules/tsx/dist/register-B7jrtLTO.mjs +1 -0
  126. package/examples/node_modules/tsx/dist/register-CFH5oNdT.mjs +4 -0
  127. package/examples/node_modules/tsx/dist/register-D46fvsV_.cjs +4 -0
  128. package/examples/node_modules/tsx/dist/repl.cjs +3 -0
  129. package/examples/node_modules/tsx/dist/repl.mjs +3 -0
  130. package/examples/node_modules/tsx/dist/require-D4F1Lv60.cjs +1 -0
  131. package/examples/node_modules/tsx/dist/require-DQxpCAr4.mjs +1 -0
  132. package/examples/node_modules/tsx/dist/suppress-warnings.cjs +1 -0
  133. package/examples/node_modules/tsx/dist/suppress-warnings.mjs +1 -0
  134. package/examples/node_modules/tsx/dist/temporary-directory-B83uKxJF.cjs +1 -0
  135. package/examples/node_modules/tsx/dist/temporary-directory-CwHp0_NW.mjs +1 -0
  136. package/examples/node_modules/tsx/dist/types-Cxp8y2TL.d.ts +5 -0
  137. package/examples/node_modules/tsx/package.json +68 -0
  138. package/examples/offline-signing.js +0 -2
  139. package/examples/offline-signing.ts +0 -1
  140. package/examples/package-lock.json +422 -73
  141. package/examples/package.json +1 -1
  142. package/examples/wallet-offline.js +1 -9
  143. package/examples/wallet-offline.ts +1 -9
  144. package/generate-sdk.js +4 -6
  145. package/package.json +2 -2
  146. package/src/abi/interface.js +13 -7
  147. package/src/abi/js-abi-coder.js +23 -18
  148. package/src/constants.d.ts +0 -5
  149. package/src/constants.js +0 -7
  150. package/src/contract/contract-factory.js +9 -3
  151. package/src/contract/contract.js +9 -3
  152. package/src/errors/index.js +12 -0
  153. package/src/index.d.ts +0 -3
  154. package/src/providers/extra-providers.js +20 -6
  155. package/src/providers/json-rpc-provider.js +15 -5
  156. package/src/providers/provider.d.ts +0 -2
  157. package/src/providers/provider.js +1 -3
  158. package/src/utils/address.d.ts +0 -14
  159. package/src/utils/address.js +12 -49
  160. package/src/utils/hashing.d.ts +0 -6
  161. package/src/utils/hashing.js +8 -23
  162. package/src/utils/index.d.ts +0 -3
  163. package/src/utils/rlp.js +7 -4
  164. package/src/wallet/wallet.d.ts +2 -13
  165. package/src/wallet/wallet.js +116 -97
  166. package/test/security/malformed-input.test.js +295 -1
  167. package/test/unit/address-wallet.test.js +188 -129
  168. package/test/unit/address-wallet.test.ts +187 -128
  169. package/test/unit/hashing.test.js +0 -11
  170. package/test/unit/hashing.test.ts +0 -11
  171. package/test/unit/providers.test.js +3 -1
  172. package/test/unit/providers.test.ts +3 -1
@@ -8,18 +8,22 @@
8
8
  const qcsdk = require("quantum-coin-js-sdk");
9
9
  const { assertArgument, makeError } = require("../errors");
10
10
  const { arrayify, bytesToHex, hexToBytes, isHexString, normalizeHex } = require("../internal/hex");
11
- const { hashMessage } = require("./hashing");
11
+
12
12
 
13
13
  function _requireInitialized() {
14
- // The spec requires Initialize() to be called before using the SDK.
15
- // config.js tracks initialization state for this package.
16
14
  // eslint-disable-next-line global-require
17
- const { isInitialized } = require("../../config");
18
- if (!isInitialized()) {
19
- throw makeError("QuantumCoin SDK not initialized. Call Initialize() first.", "UNKNOWN_ERROR", {
20
- operation: "address-utils",
21
- });
15
+ const { isInitialized, getInitializationPromise } = require("../../config");
16
+ if (isInitialized()) return;
17
+ if (getInitializationPromise() != null) {
18
+ throw makeError(
19
+ "QuantumCoin SDK is still initializing. Await the Initialize() promise before using SDK methods.",
20
+ "UNKNOWN_ERROR",
21
+ { operation: "requireInitialized" },
22
+ );
22
23
  }
24
+ throw makeError("QuantumCoin SDK not initialized. Call Initialize() first.", "UNKNOWN_ERROR", {
25
+ operation: "address-utils",
26
+ });
23
27
  }
24
28
 
25
29
  /**
@@ -127,45 +131,6 @@ function computeAddress(key) {
127
131
  return normalizeHex(out);
128
132
  }
129
133
 
130
- function _digestMessage(message) {
131
- const digestHex = hashMessage(message);
132
- const digest = Array.from(hexToBytes(digestHex));
133
- assertArgument(digest.length === 32, "invalid digest length", "digest", digest.length);
134
- return digest;
135
- }
136
-
137
- function _signatureToBytes(signature) {
138
- assertArgument(typeof signature === "string", "signature must be a hex string", "signature", signature);
139
- assertArgument(isHexString(signature), "invalid signature hex", "signature", signature);
140
- return Array.from(hexToBytes(signature));
141
- }
142
-
143
- /**
144
- * Verifies a message signature and recovers the address.
145
- * @param {string|Uint8Array} message
146
- * @param {string} signature Hex string signature
147
- * @returns {string}
148
- */
149
- function verifyMessage(message, signature) {
150
- return recoverAddress(message, signature);
151
- }
152
-
153
- /**
154
- * Recovers the address from a message signature.
155
- * @param {string|Uint8Array} message
156
- * @param {string} signature Hex string signature
157
- * @returns {string}
158
- */
159
- function recoverAddress(message, signature) {
160
- _requireInitialized();
161
- const digest = _digestMessage(message);
162
- const sigBytes = _signatureToBytes(signature);
163
- const pubHex = qcsdk.publicKeyFromSignature(digest, sigBytes);
164
- if (typeof pubHex !== "string") throw makeError("publicKeyFromSignature failed", "UNKNOWN_ERROR", {});
165
- const addr = computeAddress(pubHex);
166
- return addr;
167
- }
168
-
169
134
  module.exports = {
170
135
  isAddress,
171
136
  getAddress,
@@ -175,7 +140,5 @@ module.exports = {
175
140
  getCreateAddress,
176
141
  getCreate2Address,
177
142
  computeAddress,
178
- verifyMessage,
179
- recoverAddress,
180
143
  };
181
144
 
@@ -4,12 +4,6 @@
4
4
  * @returns {string}
5
5
  */
6
6
  export function keccak256(data: string | Uint8Array): string;
7
- /**
8
- * EIP-191 personal-sign message digest (ethers.js hashMessage pattern).
9
- * @param {string|Uint8Array} message
10
- * @returns {string}
11
- */
12
- export function hashMessage(message: string | Uint8Array): string;
13
7
  /**
14
8
  * sha256 hash of BytesLike.
15
9
  * @param {string|Uint8Array} data
@@ -7,9 +7,7 @@
7
7
  */
8
8
 
9
9
  const crypto = require("crypto");
10
- const { MessagePrefix } = require("../constants");
11
10
  const { arrayify, bytesToHex, utf8ToBytes } = require("../internal/hex");
12
- const { concat } = require("./encoding");
13
11
 
14
12
  const _MASK64 = (1n << 64n) - 1n;
15
13
 
@@ -192,18 +190,6 @@ function ripemd160(data) {
192
190
  return _hash("ripemd160", data);
193
191
  }
194
192
 
195
- /**
196
- * EIP-191 personal-sign message digest (ethers.js hashMessage pattern).
197
- * Prefixes message with MessagePrefix and decimal length, then keccak256.
198
- * If message is a string, it is converted to UTF-8 bytes first.
199
- * @param {string|Uint8Array} message
200
- * @returns {string} Hex digest
201
- */
202
- function hashMessage(message) {
203
- const msgBytes = typeof message === "string" ? utf8ToBytes(message) : arrayify(message);
204
- return keccak256(concat([utf8ToBytes(MessagePrefix), utf8ToBytes(String(msgBytes.length)), msgBytes]));
205
- }
206
-
207
193
  /**
208
194
  * ethers-style id(text) => keccak256(utf8Bytes(text))
209
195
  * @param {string} text
@@ -230,8 +216,8 @@ function randomBytes(length) {
230
216
  * @returns {string}
231
217
  */
232
218
  function computeHmac(algorithm, key, data) {
233
- const k = arrayify(key);
234
- const d = arrayify(data);
219
+ const k = typeof key === "string" ? utf8ToBytes(key) : arrayify(key);
220
+ const d = typeof data === "string" ? utf8ToBytes(data) : arrayify(data);
235
221
  const h = crypto.createHmac(algorithm, Buffer.from(k)).update(Buffer.from(d)).digest();
236
222
  return bytesToHex(new Uint8Array(h));
237
223
  }
@@ -246,8 +232,8 @@ function computeHmac(algorithm, key, data) {
246
232
  * @returns {string}
247
233
  */
248
234
  function pbkdf2(password, salt, iterations, keylen, algorithm) {
249
- const p = arrayify(password);
250
- const s = arrayify(salt);
235
+ const p = typeof password === "string" ? utf8ToBytes(password) : arrayify(password);
236
+ const s = typeof salt === "string" ? utf8ToBytes(salt) : arrayify(salt);
251
237
  const a = algorithm || "sha256";
252
238
  const out = crypto.pbkdf2Sync(Buffer.from(p), Buffer.from(s), iterations, keylen, a);
253
239
  return bytesToHex(new Uint8Array(out));
@@ -264,8 +250,8 @@ function pbkdf2(password, salt, iterations, keylen, algorithm) {
264
250
  * @returns {Promise<string>}
265
251
  */
266
252
  function scrypt(password, salt, N, r, p, dkLen) {
267
- const pw = arrayify(password);
268
- const sa = arrayify(salt);
253
+ const pw = typeof password === "string" ? utf8ToBytes(password) : arrayify(password);
254
+ const sa = typeof salt === "string" ? utf8ToBytes(salt) : arrayify(salt);
269
255
  return new Promise((resolve, reject) => {
270
256
  crypto.scrypt(
271
257
  Buffer.from(pw),
@@ -291,15 +277,14 @@ function scrypt(password, salt, N, r, p, dkLen) {
291
277
  * @returns {string}
292
278
  */
293
279
  function scryptSync(password, salt, N, r, p, dkLen) {
294
- const pw = arrayify(password);
295
- const sa = arrayify(salt);
280
+ const pw = typeof password === "string" ? utf8ToBytes(password) : arrayify(password);
281
+ const sa = typeof salt === "string" ? utf8ToBytes(salt) : arrayify(salt);
296
282
  const out = crypto.scryptSync(Buffer.from(pw), Buffer.from(sa), dkLen, { N, r, p, maxmem: 257 * 1024 * 1024 }); //257 instead of 256 for buffer for compat for N=262144, r=8, p=1
297
283
  return bytesToHex(new Uint8Array(out));
298
284
  }
299
285
 
300
286
  module.exports = {
301
287
  keccak256,
302
- hashMessage,
303
288
  sha256,
304
289
  sha512,
305
290
  ripemd160,
@@ -12,7 +12,6 @@ declare const _exports: {
12
12
  encodeRlp(value: any): string;
13
13
  decodeRlp(data: string): any;
14
14
  keccak256(data: string | Uint8Array): string;
15
- hashMessage(message: string | Uint8Array): string;
16
15
  sha256(data: string | Uint8Array): string;
17
16
  sha512(data: string | Uint8Array): string;
18
17
  ripemd160(data: string | Uint8Array): string;
@@ -59,8 +58,6 @@ declare const _exports: {
59
58
  }): string;
60
59
  getCreate2Address(from: string, salt: string, initCodeHash: string): string;
61
60
  computeAddress(key: string | Uint8Array): string;
62
- verifyMessage(message: string | Uint8Array, signature: string): string;
63
- recoverAddress(message: string | Uint8Array, signature: string): string;
64
61
  FixedNumber: typeof import("./fixednumber").FixedNumber;
65
62
  };
66
63
  export = _exports;
package/src/utils/rlp.js CHANGED
@@ -110,7 +110,10 @@ function _readLen(bytes, offset, lenOfLen) {
110
110
  return len;
111
111
  }
112
112
 
113
- function _decode(bytes, start, end) {
113
+ const MAX_RLP_DEPTH = 64;
114
+
115
+ function _decode(bytes, start, end, depth) {
116
+ if (depth > MAX_RLP_DEPTH) throw new Error("RLP: maximum nesting depth exceeded");
114
117
  if (start >= end) throw new Error("RLP: empty input");
115
118
  const prefix = bytes[start];
116
119
 
@@ -149,7 +152,7 @@ function _decode(bytes, start, end) {
149
152
  const out = [];
150
153
  let pos = dataStart;
151
154
  while (pos < dataEnd) {
152
- const decoded = _decode(bytes, pos, dataEnd);
155
+ const decoded = _decode(bytes, pos, dataEnd, depth + 1);
153
156
  out.push(decoded.value);
154
157
  pos = decoded.next;
155
158
  }
@@ -166,7 +169,7 @@ function _decode(bytes, start, end) {
166
169
  const out = [];
167
170
  let pos = dataStart;
168
171
  while (pos < dataEnd) {
169
- const decoded = _decode(bytes, pos, dataEnd);
172
+ const decoded = _decode(bytes, pos, dataEnd, depth + 1);
170
173
  out.push(decoded.value);
171
174
  pos = decoded.next;
172
175
  }
@@ -191,7 +194,7 @@ function encodeRlp(value) {
191
194
  function decodeRlp(data) {
192
195
  if (typeof data !== "string") throw new TypeError("RLP data must be a hex string");
193
196
  const bytes = arrayify(data);
194
- const decoded = _decode(bytes, 0, bytes.length);
197
+ const decoded = _decode(bytes, 0, bytes.length, 0);
195
198
  if (decoded.next !== bytes.length) throw new Error("RLP: trailing data");
196
199
  return decoded.value;
197
200
  }
@@ -38,14 +38,9 @@ export class BaseWallet extends AbstractSigner {
38
38
  _qcWallet: any;
39
39
  /** @type {string} */
40
40
  address: string;
41
+ readonly publicKey: string;
42
+ readonly seed: string | null;
41
43
  getAddress(): Promise<string>;
42
- /**
43
- * Sign a message synchronously.
44
- * Signature format: combined publicKey+signature as a hex string.
45
- * @param {string|Uint8Array} message
46
- * @returns {string}
47
- */
48
- signMessageSync(message: string | Uint8Array): string;
49
44
  /**
50
45
  * Sign a transaction using quantum-coin-js-sdk signRawTransaction().
51
46
  * @param {import("../providers/provider").TransactionRequest} tx
@@ -77,12 +72,6 @@ export class Wallet extends BaseWallet {
77
72
  * @returns {Wallet}
78
73
  */
79
74
  static createRandom(provider?: import("../providers/provider").AbstractProvider | undefined, keyType?: number | null): Wallet;
80
- /**
81
- * Creates a new random seed word list (32 words for keyType 3, 36 for keyType 5).
82
- * @param {number|null=} keyType Optional key type: null (default=3), 3, or 5
83
- * @returns {string[]}
84
- */
85
- static createRandomSeed(keyType?: number | null): string[];
86
75
  /**
87
76
  * Creates a wallet from raw seed bytes.
88
77
  * @param {number[]} seed Raw seed bytes: 64 (keyType 3), 72 (keyType 5), or 96 (legacy)
@@ -10,24 +10,52 @@
10
10
 
11
11
  const qcsdk = require("quantum-coin-js-sdk");
12
12
  const { JsonRpcProvider } = require("../providers/json-rpc-provider");
13
- const { assertArgument, makeError } = require("../errors");
13
+ const { assertArgument, assertSecretArgument, makeError } = require("../errors");
14
14
  const { arrayify, bytesToHex, hexToBytes, isHexString, normalizeHex } = require("../internal/hex");
15
- const { hashMessage } = require("../utils/hashing");
16
15
  const { getAddress } = require("../utils/address");
17
16
  const { WeiPerEther } = require("../constants");
18
17
 
19
18
  function _requireInitialized() {
20
19
  // eslint-disable-next-line global-require
21
- const { isInitialized } = require("../../config");
22
- if (!isInitialized()) {
23
- throw makeError("QuantumCoin SDK not initialized. Call Initialize() first.", "UNKNOWN_ERROR", { operation: "wallet" });
20
+ const { isInitialized, getInitializationPromise } = require("../../config");
21
+ if (isInitialized()) return;
22
+ if (getInitializationPromise() != null) {
23
+ throw makeError(
24
+ "QuantumCoin SDK is still initializing. Await the Initialize() promise before using SDK methods.",
25
+ "UNKNOWN_ERROR",
26
+ { operation: "requireInitialized" },
27
+ );
24
28
  }
29
+ throw makeError("QuantumCoin SDK not initialized. Call Initialize() first.", "UNKNOWN_ERROR", { operation: "wallet" });
25
30
  }
26
31
 
27
32
  function _bytesToNumberArray(bytes) {
28
33
  return Array.from(bytes);
29
34
  }
30
35
 
36
+ const _maxSafeInt = 0x1fffffffffffffn; // 2^53 - 1
37
+
38
+ function _getBigInt(value, name) {
39
+ if (typeof value === "bigint") return value;
40
+ if (typeof value === "number") {
41
+ assertArgument(Number.isInteger(value), "underflow", name, value);
42
+ assertArgument(value >= -Number(_maxSafeInt) && value <= Number(_maxSafeInt), "overflow", name, value);
43
+ return BigInt(value);
44
+ }
45
+ if (typeof value === "string") {
46
+ if (value === "0x" || value === "0X") return 0n;
47
+ try { return BigInt(value); }
48
+ catch { assertArgument(false, "invalid BigNumberish string", name, value); }
49
+ }
50
+ assertArgument(false, "invalid BigNumberish", name, value);
51
+ }
52
+
53
+ function _getNumber(value, name) {
54
+ const bi = _getBigInt(value, name);
55
+ assertArgument(bi >= -_maxSafeInt && bi <= _maxSafeInt, "overflow", name, value);
56
+ return Number(bi);
57
+ }
58
+
31
59
  /**
32
60
  * SigningKey wrapper (PQC private/public key bytes).
33
61
  */
@@ -37,9 +65,18 @@ class SigningKey {
37
65
  * @param {Uint8Array} publicKeyBytes
38
66
  */
39
67
  constructor(privateKeyBytes, publicKeyBytes) {
40
- this.privateKeyBytes = new Uint8Array(privateKeyBytes);
68
+ Object.defineProperty(this, "privateKeyBytes", {
69
+ enumerable: false,
70
+ configurable: false,
71
+ writable: false,
72
+ value: new Uint8Array(privateKeyBytes),
73
+ });
41
74
  this.publicKeyBytes = new Uint8Array(publicKeyBytes);
42
75
  }
76
+
77
+ toJSON() {
78
+ return {};
79
+ }
43
80
  }
44
81
 
45
82
  /**
@@ -71,56 +108,52 @@ class BaseWallet extends AbstractSigner {
71
108
  constructor(signingKey, provider, precomputed, qcWallet) {
72
109
  super(provider || null);
73
110
  _requireInitialized();
74
- this.signingKey = signingKey;
75
- this._qcWallet = qcWallet || null;
111
+
112
+ Object.defineProperty(this, "signingKey", {
113
+ enumerable: false,
114
+ configurable: false,
115
+ writable: false,
116
+ value: signingKey,
117
+ });
118
+ Object.defineProperty(this, "_qcWallet", {
119
+ enumerable: false,
120
+ configurable: true,
121
+ writable: true,
122
+ value: qcWallet || null,
123
+ });
76
124
 
77
125
  /** @type {string} */
78
126
  this.address = precomputed?.address || "";
79
127
 
80
128
  Object.defineProperty(this, "privateKey", {
81
- enumerable: true,
129
+ enumerable: false,
82
130
  get: () => bytesToHex(this.signingKey.privateKeyBytes),
83
131
  });
132
+
133
+ Object.defineProperty(this, "publicKey", {
134
+ enumerable: true,
135
+ get: () => bytesToHex(this.signingKey.publicKeyBytes),
136
+ });
137
+
138
+ Object.defineProperty(this, "_seed", {
139
+ enumerable: false,
140
+ configurable: true,
141
+ writable: true,
142
+ value: null,
143
+ });
144
+
145
+ Object.defineProperty(this, "seed", {
146
+ enumerable: false,
147
+ get: () => this._seed,
148
+ });
84
149
  }
85
150
 
86
- async getAddress() {
87
- return this.address;
151
+ toJSON() {
152
+ return { address: this.address };
88
153
  }
89
154
 
90
- /**
91
- * Sign a message synchronously.
92
- * Signature format: combined publicKey+signature as a hex string.
93
- * @param {string|Uint8Array} message
94
- * @returns {string}
95
- */
96
- signMessageSync(message) {
97
- _requireInitialized();
98
- const digestHex = hashMessage(message);
99
- const digest = hexToBytes(digestHex);
100
- const signResult = qcsdk.sign(this.signingKey.privateKeyBytes, digest, null);
101
- if (signResult.resultCode !== 0) {
102
- throw makeError("sign failed", "UNKNOWN_ERROR", { resultCode: signResult.resultCode });
103
- }
104
- const sigBytes = signResult.signature;
105
- if (!sigBytes) throw makeError("sign returned no signature", "UNKNOWN_ERROR", {});
106
- const sigArr = Array.from(sigBytes instanceof Uint8Array ? sigBytes : sigBytes);
107
- let combined = qcsdk.combinePublicKeySignature(
108
- _bytesToNumberArray(this.signingKey.publicKeyBytes),
109
- sigArr,
110
- );
111
- if (combined != null && typeof combined === "object") {
112
- if (typeof combined.String === "function") combined = combined.String();
113
- else if (combined instanceof Uint8Array) combined = bytesToHex(combined);
114
- else if (Array.isArray(combined)) combined = bytesToHex(new Uint8Array(combined));
115
- else if (typeof combined.length === "number" && combined.length >= 0) combined = bytesToHex(new Uint8Array(Array.from(combined)));
116
- }
117
- if (combined == null || typeof combined !== "string") {
118
- throw makeError("combinePublicKeySignature failed (SDK may not support this key type for message signing)", "UNKNOWN_ERROR", {
119
- combinedType: typeof combined,
120
- sigLength: sigArr.length,
121
- });
122
- }
123
- return normalizeHex(combined);
155
+ async getAddress() {
156
+ return this.address;
124
157
  }
125
158
 
126
159
  /**
@@ -133,27 +166,8 @@ class BaseWallet extends AbstractSigner {
133
166
  assertArgument(tx && typeof tx === "object", "invalid tx", "tx", tx);
134
167
 
135
168
  const toAddress = tx.to == null ? null : getAddress(tx.to);
136
- const valueInWei =
137
- tx.value == null
138
- ? 0n
139
- : typeof tx.value === "bigint"
140
- ? tx.value
141
- : typeof tx.value === "number"
142
- ? BigInt(tx.value)
143
- : typeof tx.value === "string"
144
- ? BigInt(tx.value.startsWith("0x") ? tx.value : tx.value)
145
- : 0n;
146
-
147
- const gasLimit =
148
- tx.gasLimit == null
149
- ? 21000
150
- : typeof tx.gasLimit === "bigint"
151
- ? Number(tx.gasLimit)
152
- : typeof tx.gasLimit === "number"
153
- ? tx.gasLimit
154
- : typeof tx.gasLimit === "string"
155
- ? Number(BigInt(tx.gasLimit))
156
- : 21000;
169
+ const valueInWei = tx.value == null ? 0n : _getBigInt(tx.value, "tx.value");
170
+ const gasLimit = tx.gasLimit == null ? 21000 : _getNumber(tx.gasLimit, "tx.gasLimit");
157
171
 
158
172
  const data = tx.data == null ? null : normalizeHex(tx.data);
159
173
  const remarks = tx.remarks == null ? null : normalizeHex(tx.remarks);
@@ -299,13 +313,19 @@ class Wallet extends BaseWallet {
299
313
  }
300
314
 
301
315
  /**
302
- * Encrypts and serializes this wallet to JSON.
316
+ * Encrypts and serializes this wallet to JSON.
303
317
  * @param {string|Uint8Array} password
304
318
  * @returns {string}
305
319
  */
306
320
  encryptSync(password) {
307
321
  _requireInitialized();
308
- const pw = typeof password === "string" ? password : Buffer.from(arrayify(password)).toString("utf8");
322
+ if (this._seed != null) {
323
+ return Wallet.encryptSeedSync(hexToBytes(this._seed), password);
324
+ }
325
+ const pw = typeof password === "string"
326
+ ? password.normalize("NFC")
327
+ : Buffer.from(arrayify(password)).toString("utf8").normalize("NFC");
328
+ assertSecretArgument(pw.length >= 12, "password must be at least 12 characters", "password");
309
329
  const json = qcsdk.serializeEncryptedWallet(this._qcWallet, pw);
310
330
  if (typeof json !== "string") throw makeError("serializeEncryptedWallet failed", "UNKNOWN_ERROR", {});
311
331
  return json;
@@ -325,7 +345,10 @@ class Wallet extends BaseWallet {
325
345
  assertArgument(Array.isArray(seedArr), "seed must be an array of numbers or Uint8Array", "seed", seed);
326
346
  const allowedLengths = [64, 72, 96];
327
347
  assertArgument(allowedLengths.includes(seedArr.length), "seed must be 64, 72, or 96 bytes", "seed", seedArr.length);
328
- const pw = typeof password === "string" ? password : Buffer.from(arrayify(password)).toString("utf8");
348
+ const pw = typeof password === "string"
349
+ ? password.normalize("NFC")
350
+ : Buffer.from(arrayify(password)).toString("utf8").normalize("NFC");
351
+ assertSecretArgument(pw.length >= 12, "password must be at least 12 characters", "password");
329
352
  const json = qcsdk.serializeSeedAsEncryptedWallet(seedArr, pw);
330
353
  if (typeof json !== "string") throw makeError("serializeSeedAsEncryptedWallet failed", "UNKNOWN_ERROR", {});
331
354
  return json;
@@ -355,7 +378,10 @@ class Wallet extends BaseWallet {
355
378
  * @returns {Wallet}
356
379
  */
357
380
  connect(provider) {
358
- return new Wallet(this.signingKey, provider);
381
+ const w = new Wallet(this.signingKey, provider);
382
+ w._qcWallet = this._qcWallet;
383
+ w._seed = this._seed;
384
+ return w;
359
385
  }
360
386
 
361
387
  /**
@@ -369,29 +395,11 @@ class Wallet extends BaseWallet {
369
395
  if (keyType != null) {
370
396
  assertArgument(keyType === 3 || keyType === 5, "keyType must be null, 3, or 5", "keyType", keyType);
371
397
  }
372
- const qcWallet = qcsdk.newWallet(keyType ?? null);
373
- if (!qcWallet || typeof qcWallet === "number") {
374
- throw makeError("newWallet failed", "UNKNOWN_ERROR", { result: qcWallet });
375
- }
376
- return Wallet._fromQcWallet(qcWallet, provider || null);
377
- }
378
-
379
- /**
380
- * Creates a new random seed word list (32 words for keyType 3, 36 for keyType 5).
381
- * Use the returned words with `Wallet.fromPhrase()` to create a wallet.
382
- * @param {number|null=} keyType Optional key type: null (default=3), 3, or 5
383
- * @returns {string[]}
384
- */
385
- static createRandomSeed(keyType) {
386
- _requireInitialized();
387
- if (keyType != null) {
388
- assertArgument(keyType === 3 || keyType === 5, "keyType must be null, 3, or 5", "keyType", keyType);
389
- }
390
- const words = qcsdk.newWalletSeed(keyType ?? null);
398
+ const words = qcsdk.newWalletSeedWords(keyType ?? null);
391
399
  if (!words || !Array.isArray(words)) {
392
- throw makeError("newWalletSeed failed", "UNKNOWN_ERROR", { result: words });
400
+ throw makeError("newWalletSeedWords failed", "UNKNOWN_ERROR", { result: words });
393
401
  }
394
- return words;
402
+ return Wallet.fromPhrase(words, provider);
395
403
  }
396
404
 
397
405
  /**
@@ -465,8 +473,8 @@ class Wallet extends BaseWallet {
465
473
  _requireInitialized();
466
474
  const privBytes = typeof privateKey === "string" ? hexToBytes(privateKey) : arrayify(privateKey);
467
475
  const pubBytes = typeof publicKey === "string" ? hexToBytes(publicKey) : arrayify(publicKey);
468
- assertArgument(privBytes.length > 0, "privateKey must not be empty", "privateKey", privateKey);
469
- assertArgument(pubBytes.length > 0, "publicKey must not be empty", "publicKey", publicKey);
476
+ assertSecretArgument(privBytes.length > 0, "privateKey must not be empty", "privateKey");
477
+ assertSecretArgument(pubBytes.length > 0, "publicKey must not be empty", "publicKey");
470
478
 
471
479
  const privArr = _bytesToNumberArray(privBytes);
472
480
  const pubArr = _bytesToNumberArray(pubBytes);
@@ -489,15 +497,20 @@ class Wallet extends BaseWallet {
489
497
  * @returns {Wallet}
490
498
  */
491
499
  static _fromQcWallet(qcWallet, provider) {
492
- // Preserve key material from quantum-coin-js-sdk Wallet.
493
- // newWallet() returns Uint8Array keys; other constructors may return number[].
494
500
  const privSrc = qcWallet.privateKey;
495
501
  const pubSrc = qcWallet.publicKey;
496
502
 
503
+ if (!privSrc || (privSrc instanceof Uint8Array && privSrc.length === 0) || (Array.isArray(privSrc) && privSrc.length === 0)) {
504
+ throw makeError("qcWallet.privateKey is empty or missing", "UNKNOWN_ERROR", {});
505
+ }
506
+ if (!pubSrc || (pubSrc instanceof Uint8Array && pubSrc.length === 0) || (Array.isArray(pubSrc) && pubSrc.length === 0)) {
507
+ throw makeError("qcWallet.publicKey is empty or missing", "UNKNOWN_ERROR", {});
508
+ }
509
+
497
510
  const privBytes =
498
- privSrc instanceof Uint8Array ? new Uint8Array(privSrc) : Uint8Array.from(Array.from(privSrc || []).map((n) => (Number(n) & 0xff)));
511
+ privSrc instanceof Uint8Array ? new Uint8Array(privSrc) : Uint8Array.from(Array.from(privSrc).map((n) => (Number(n) & 0xff)));
499
512
  const pubBytes =
500
- pubSrc instanceof Uint8Array ? new Uint8Array(pubSrc) : Uint8Array.from(Array.from(pubSrc || []).map((n) => (Number(n) & 0xff)));
513
+ pubSrc instanceof Uint8Array ? new Uint8Array(pubSrc) : Uint8Array.from(Array.from(pubSrc).map((n) => (Number(n) & 0xff)));
501
514
  const key = new SigningKey(privBytes, pubBytes);
502
515
 
503
516
  const w = new Wallet(key, provider || null);
@@ -506,6 +519,12 @@ class Wallet extends BaseWallet {
506
519
  if (typeof qcWallet.address === "string") {
507
520
  w.address = normalizeHex(qcWallet.address);
508
521
  }
522
+ if (qcWallet.preExpansionSeed != null) {
523
+ const seedSrc = qcWallet.preExpansionSeed;
524
+ const seedBytes =
525
+ seedSrc instanceof Uint8Array ? seedSrc : Uint8Array.from(Array.from(seedSrc).map((n) => (Number(n) & 0xff)));
526
+ w._seed = bytesToHex(seedBytes);
527
+ }
509
528
  return w;
510
529
  }
511
530
  }