@quantovainc/qcore 0.1.23 → 0.1.25

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quantovainc/qcore",
3
- "version": "0.1.23",
3
+ "version": "0.1.25",
4
4
  "description": "Quantova's post quantum client core for JavaScript. Signs with ML-DSA-65 and builds Q1 addresses.",
5
5
  "scripts": {
6
6
  "build": "bash scripts/build.sh",
Binary file
Binary file
package/shared.js CHANGED
@@ -35,6 +35,25 @@ function accountIndex(index) {
35
35
  return i;
36
36
  }
37
37
 
38
+ // The nonce is the one signing input that comes from the gateway. A number above 2^53 has already
39
+ // lost precision when read, and a negative or oversized value would wrap into a different unsigned
40
+ // 64 bit nonce at the signer, so each is refused before it is bound into a signature.
41
+ function accountNonce(nonce) {
42
+ if (typeof nonce === 'number' && !Number.isSafeInteger(nonce)) {
43
+ throw new Error('the gateway reported a nonce outside the safe integer range, a number that large silently rounds and would sign a different nonce');
44
+ }
45
+ let n;
46
+ try {
47
+ n = BigInt(nonce);
48
+ } catch {
49
+ throw new Error('the gateway reported a nonce that is not a whole number');
50
+ }
51
+ if (n < 0n || n > 0xffffffffffffffffn) {
52
+ throw new Error('the gateway reported a nonce outside the unsigned 64 bit range');
53
+ }
54
+ return n;
55
+ }
56
+
38
57
  async function readBounded(res) {
39
58
  if (!res.body || typeof res.body.getReader !== 'function') {
40
59
  const header = res.headers.get('content-length');
@@ -188,6 +207,7 @@ function makeClient(core) {
188
207
  _signingChainId(info) {
189
208
  const name = info && info.chain_id;
190
209
  if (!name) throw new Error('the gateway did not report a chain id to bind the signature to');
210
+ if (typeof name !== 'string') throw new Error('the gateway reported a chain id that is not a string, refusing to bind a signature to it');
191
211
  const id = BigInt(core.chainIdFromName(name));
192
212
  const configured = this.network && this.network.chainId;
193
213
  if (configured && name !== configured) {
@@ -259,7 +279,7 @@ function makeClient(core) {
259
279
  const acct = await this.account(from);
260
280
  if (!acct || acct.nonce == null) throw new Error('the gateway did not report a nonce');
261
281
  const signed = JSON.parse(
262
- core.sign_transfer(seedHex, accountIndex(index), to, String(amount), BigInt(acct.nonce), String(fee), chainId)
282
+ core.sign_transfer(seedHex, accountIndex(index), to, String(amount), accountNonce(acct.nonce), String(fee), chainId)
263
283
  );
264
284
  const outcome = await this.submit(signed.tx_hex);
265
285
  return { signed, outcome };
@@ -278,7 +298,7 @@ function makeClient(core) {
278
298
  const from = core.address(seedHex, accountIndex(index));
279
299
  const acct = await this.account(from);
280
300
  if (!acct || acct.nonce == null) throw new Error('the gateway did not report a nonce');
281
- const signed = JSON.parse(core.signRegister(seedHex, accountIndex(index), BigInt(acct.nonce), String(fee), chainId));
301
+ const signed = JSON.parse(core.signRegister(seedHex, accountIndex(index), accountNonce(acct.nonce), String(fee), chainId));
282
302
  const outcome = await this.submit(signed.tx_hex);
283
303
  return { signed, outcome };
284
304
  }
@@ -298,7 +318,7 @@ function makeClient(core) {
298
318
  const acct = await this.account(from);
299
319
  if (!acct || acct.nonce == null) throw new Error('the gateway did not report a nonce');
300
320
  const signed = JSON.parse(
301
- core.sign_call(seedHex, accountIndex(index), target, argsHex, BigInt(acct.nonce), BigInt(meterLimit), String(fee), chainId)
321
+ core.sign_call(seedHex, accountIndex(index), target, argsHex, accountNonce(acct.nonce), BigInt(meterLimit), String(fee), chainId)
302
322
  );
303
323
  const outcome = await this.submit(signed.tx_hex);
304
324
  return { signed, outcome };
@@ -343,7 +363,7 @@ function makeClient(core) {
343
363
  const acct = await this.account(from);
344
364
  if (!acct || acct.nonce == null) throw new Error('the gateway did not report a nonce');
345
365
  const signed = JSON.parse(
346
- core.sign_call(callerSeedHex, accountIndex(callerIndex), contract, order.call_args, BigInt(acct.nonce), BigInt(meterLimit), String(fee), chainId)
366
+ core.sign_call(callerSeedHex, accountIndex(callerIndex), contract, order.call_args, accountNonce(acct.nonce), BigInt(meterLimit), String(fee), chainId)
347
367
  );
348
368
  const outcome = await this.submit(signed.tx_hex);
349
369
  return { order, signed, outcome };