@quantovainc/qcore 0.1.33 → 0.2.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.
- package/package.json +2 -2
- package/pkg/package.json +1 -1
- package/pkg/qcore_js_bg.wasm +0 -0
- package/pkg-node/package.json +1 -1
- package/pkg-node/qcore_js_bg.wasm +0 -0
- package/shared.js +32 -3
- package/shared.mjs +32 -3
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quantovainc/qcore",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
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",
|
|
7
|
-
"test": "node test-types.js && node test-conformance.js && node test-order-nonce.js && node test-chain-binding.js && node test-sign-validate.js && node test-transport.js && node test-fee-cap.js && node test-network.js && node test-typed-order.js && node test-asset-guards.js && node test-account-index.js"
|
|
7
|
+
"test": "node test-entry-parity.mjs && node test-browser.mjs && node test-types.js && node test-conformance.js && node test-order-nonce.js && node test-chain-binding.js && node test-sign-validate.js && node test-transport.js && node test-fee-cap.js && node test-network.js && node test-typed-order.js && node test-asset-guards.js && node test-account-index.js"
|
|
8
8
|
},
|
|
9
9
|
"keywords": [
|
|
10
10
|
"post-quantum",
|
package/pkg/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "qcore-js",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"description": "The JavaScript binding for the Quantova client core, generated over QCore with wasm-bindgen. The core does the key derivation, the post quantum signing, and the wire, the page does the fetch.",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.2.0",
|
|
6
6
|
"license": "Apache-2.0 OR MIT",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
package/pkg/qcore_js_bg.wasm
CHANGED
|
Binary file
|
package/pkg-node/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "qcore-js",
|
|
3
3
|
"description": "The JavaScript binding for the Quantova client core, generated over QCore with wasm-bindgen. The core does the key derivation, the post quantum signing, and the wire, the page does the fetch.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.2.0",
|
|
5
5
|
"license": "Apache-2.0 OR MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
Binary file
|
package/shared.js
CHANGED
|
@@ -331,11 +331,34 @@ function makeClient(core) {
|
|
|
331
331
|
_checkedNonce(reported, expected, key) {
|
|
332
332
|
const n = accountNonce(reported);
|
|
333
333
|
if (!this._nextNonces) this._nextNonces = new Map();
|
|
334
|
+
if (!this._signedNonces) this._signedNonces = new Map();
|
|
334
335
|
const local = key != null ? this._nextNonces.get(key) : undefined;
|
|
335
336
|
const e = expected != null ? BigInt(expected) : local;
|
|
336
|
-
|
|
337
|
-
if (
|
|
338
|
-
|
|
337
|
+
let slot;
|
|
338
|
+
if (e == null) {
|
|
339
|
+
slot = n;
|
|
340
|
+
} else {
|
|
341
|
+
if (n > e) throw new Error(`the gateway reported nonce ${n} above the expected ${e}; refusing so a signature cannot be banked for a nonce the account has not reached`);
|
|
342
|
+
slot = expected != null ? e : n;
|
|
343
|
+
}
|
|
344
|
+
return slot;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// Refuse a second, different transaction at a nonce this session already
|
|
348
|
+
// signed at. A gateway can broadcast a transaction and still report it
|
|
349
|
+
// rejected, or walk the nonce it reports back to a slot already used.
|
|
350
|
+
// Either way two valid signatures for one slot let it choose which the
|
|
351
|
+
// chain runs. An identical retry is harmless and still allowed.
|
|
352
|
+
_guardSigned(key, slot, txHex) {
|
|
353
|
+
if (key == null) return;
|
|
354
|
+
if (!this._signedNonces) this._signedNonces = new Map();
|
|
355
|
+
let held = this._signedNonces.get(key);
|
|
356
|
+
if (!held) { held = new Map(); this._signedNonces.set(key, held); }
|
|
357
|
+
const seen = held.get(String(slot));
|
|
358
|
+
if (seen != null && seen !== txHex) {
|
|
359
|
+
throw new Error(`a different transaction was already signed for nonce ${slot} in this session; one nonce carries one signature`);
|
|
360
|
+
}
|
|
361
|
+
held.set(String(slot), txHex);
|
|
339
362
|
}
|
|
340
363
|
|
|
341
364
|
_remember(key, used, outcome) {
|
|
@@ -387,6 +410,7 @@ function makeClient(core) {
|
|
|
387
410
|
const signed = JSON.parse(
|
|
388
411
|
core.sign_transfer(seedHex, accountIndex(index), to, String(amount), nonce, String(fee), chainId, this._validity(info))
|
|
389
412
|
);
|
|
413
|
+
this._guardSigned(from, nonce, signed.tx_hex);
|
|
390
414
|
const outcome = await this.submit(signed.tx_hex);
|
|
391
415
|
this._remember(from, nonce, outcome);
|
|
392
416
|
return { signed, outcome };
|
|
@@ -408,6 +432,7 @@ function makeClient(core) {
|
|
|
408
432
|
if (!acct || acct.nonce == null) throw new Error('the gateway did not report a nonce');
|
|
409
433
|
const nonce = this._checkedNonce(acct.nonce, expectedNonce, from);
|
|
410
434
|
const signed = JSON.parse(core.signRegister(seedHex, accountIndex(index), nonce, String(fee), chainId, this._validity(info)));
|
|
435
|
+
this._guardSigned(from, nonce, signed.tx_hex);
|
|
411
436
|
const outcome = await this.submit(signed.tx_hex);
|
|
412
437
|
this._remember(from, nonce, outcome);
|
|
413
438
|
return { signed, outcome };
|
|
@@ -432,6 +457,7 @@ function makeClient(core) {
|
|
|
432
457
|
const signed = JSON.parse(
|
|
433
458
|
core.sign_call(seedHex, accountIndex(index), target, argsHex, nonce, meterLimitOf(meterLimit), String(fee), chainId, this._validity(info))
|
|
434
459
|
);
|
|
460
|
+
this._guardSigned(from, nonce, signed.tx_hex);
|
|
435
461
|
const outcome = await this.submit(signed.tx_hex);
|
|
436
462
|
this._remember(from, nonce, outcome);
|
|
437
463
|
return { signed, outcome };
|
|
@@ -458,6 +484,7 @@ function makeClient(core) {
|
|
|
458
484
|
const signed = JSON.parse(
|
|
459
485
|
core.signAssetCall(seedHex, accountIndex(index), target, argsHex, assetIssuer, String(amount), nonce, meterLimitOf(meterLimit), String(fee), chainId, this._validity(info))
|
|
460
486
|
);
|
|
487
|
+
this._guardSigned(from, nonce, signed.tx_hex);
|
|
461
488
|
const outcome = await this.submit(signed.tx_hex);
|
|
462
489
|
this._remember(from, nonce, outcome);
|
|
463
490
|
return { signed, outcome };
|
|
@@ -483,6 +510,7 @@ function makeClient(core) {
|
|
|
483
510
|
const signed = JSON.parse(
|
|
484
511
|
core.signPayableCall(seedHex, accountIndex(index), target, argsHex, nonce, meterLimitOf(meterLimit), String(fee), String(value), chainId, this._validity(info))
|
|
485
512
|
);
|
|
513
|
+
this._guardSigned(from, nonce, signed.tx_hex);
|
|
486
514
|
const outcome = await this.submit(signed.tx_hex);
|
|
487
515
|
this._remember(from, nonce, outcome);
|
|
488
516
|
return { signed, outcome };
|
|
@@ -546,6 +574,7 @@ function makeClient(core) {
|
|
|
546
574
|
const signed = JSON.parse(
|
|
547
575
|
core.sign_call(callerSeedHex, accountIndex(callerIndex), contract, order.call_args, accountNonceUsed, meterLimitOf(meterLimit), String(fee), chainId, this._validity(info))
|
|
548
576
|
);
|
|
577
|
+
this._guardSigned(from, nonce, signed.tx_hex);
|
|
549
578
|
const outcome = await this.submit(signed.tx_hex);
|
|
550
579
|
this._remember(from, accountNonceUsed, outcome);
|
|
551
580
|
this._remember(orderKey, nonce, outcome);
|
package/shared.mjs
CHANGED
|
@@ -331,11 +331,34 @@ function makeClient(core) {
|
|
|
331
331
|
_checkedNonce(reported, expected, key) {
|
|
332
332
|
const n = accountNonce(reported);
|
|
333
333
|
if (!this._nextNonces) this._nextNonces = new Map();
|
|
334
|
+
if (!this._signedNonces) this._signedNonces = new Map();
|
|
334
335
|
const local = key != null ? this._nextNonces.get(key) : undefined;
|
|
335
336
|
const e = expected != null ? BigInt(expected) : local;
|
|
336
|
-
|
|
337
|
-
if (
|
|
338
|
-
|
|
337
|
+
let slot;
|
|
338
|
+
if (e == null) {
|
|
339
|
+
slot = n;
|
|
340
|
+
} else {
|
|
341
|
+
if (n > e) throw new Error(`the gateway reported nonce ${n} above the expected ${e}; refusing so a signature cannot be banked for a nonce the account has not reached`);
|
|
342
|
+
slot = expected != null ? e : n;
|
|
343
|
+
}
|
|
344
|
+
return slot;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// Refuse a second, different transaction at a nonce this session already
|
|
348
|
+
// signed at. A gateway can broadcast a transaction and still report it
|
|
349
|
+
// rejected, or walk the nonce it reports back to a slot already used.
|
|
350
|
+
// Either way two valid signatures for one slot let it choose which the
|
|
351
|
+
// chain runs. An identical retry is harmless and still allowed.
|
|
352
|
+
_guardSigned(key, slot, txHex) {
|
|
353
|
+
if (key == null) return;
|
|
354
|
+
if (!this._signedNonces) this._signedNonces = new Map();
|
|
355
|
+
let held = this._signedNonces.get(key);
|
|
356
|
+
if (!held) { held = new Map(); this._signedNonces.set(key, held); }
|
|
357
|
+
const seen = held.get(String(slot));
|
|
358
|
+
if (seen != null && seen !== txHex) {
|
|
359
|
+
throw new Error(`a different transaction was already signed for nonce ${slot} in this session; one nonce carries one signature`);
|
|
360
|
+
}
|
|
361
|
+
held.set(String(slot), txHex);
|
|
339
362
|
}
|
|
340
363
|
|
|
341
364
|
_remember(key, used, outcome) {
|
|
@@ -387,6 +410,7 @@ function makeClient(core) {
|
|
|
387
410
|
const signed = JSON.parse(
|
|
388
411
|
core.sign_transfer(seedHex, accountIndex(index), to, String(amount), nonce, String(fee), chainId, this._validity(info))
|
|
389
412
|
);
|
|
413
|
+
this._guardSigned(from, nonce, signed.tx_hex);
|
|
390
414
|
const outcome = await this.submit(signed.tx_hex);
|
|
391
415
|
this._remember(from, nonce, outcome);
|
|
392
416
|
return { signed, outcome };
|
|
@@ -408,6 +432,7 @@ function makeClient(core) {
|
|
|
408
432
|
if (!acct || acct.nonce == null) throw new Error('the gateway did not report a nonce');
|
|
409
433
|
const nonce = this._checkedNonce(acct.nonce, expectedNonce, from);
|
|
410
434
|
const signed = JSON.parse(core.signRegister(seedHex, accountIndex(index), nonce, String(fee), chainId, this._validity(info)));
|
|
435
|
+
this._guardSigned(from, nonce, signed.tx_hex);
|
|
411
436
|
const outcome = await this.submit(signed.tx_hex);
|
|
412
437
|
this._remember(from, nonce, outcome);
|
|
413
438
|
return { signed, outcome };
|
|
@@ -432,6 +457,7 @@ function makeClient(core) {
|
|
|
432
457
|
const signed = JSON.parse(
|
|
433
458
|
core.sign_call(seedHex, accountIndex(index), target, argsHex, nonce, meterLimitOf(meterLimit), String(fee), chainId, this._validity(info))
|
|
434
459
|
);
|
|
460
|
+
this._guardSigned(from, nonce, signed.tx_hex);
|
|
435
461
|
const outcome = await this.submit(signed.tx_hex);
|
|
436
462
|
this._remember(from, nonce, outcome);
|
|
437
463
|
return { signed, outcome };
|
|
@@ -458,6 +484,7 @@ function makeClient(core) {
|
|
|
458
484
|
const signed = JSON.parse(
|
|
459
485
|
core.signAssetCall(seedHex, accountIndex(index), target, argsHex, assetIssuer, String(amount), nonce, meterLimitOf(meterLimit), String(fee), chainId, this._validity(info))
|
|
460
486
|
);
|
|
487
|
+
this._guardSigned(from, nonce, signed.tx_hex);
|
|
461
488
|
const outcome = await this.submit(signed.tx_hex);
|
|
462
489
|
this._remember(from, nonce, outcome);
|
|
463
490
|
return { signed, outcome };
|
|
@@ -483,6 +510,7 @@ function makeClient(core) {
|
|
|
483
510
|
const signed = JSON.parse(
|
|
484
511
|
core.signPayableCall(seedHex, accountIndex(index), target, argsHex, nonce, meterLimitOf(meterLimit), String(fee), String(value), chainId, this._validity(info))
|
|
485
512
|
);
|
|
513
|
+
this._guardSigned(from, nonce, signed.tx_hex);
|
|
486
514
|
const outcome = await this.submit(signed.tx_hex);
|
|
487
515
|
this._remember(from, nonce, outcome);
|
|
488
516
|
return { signed, outcome };
|
|
@@ -546,6 +574,7 @@ function makeClient(core) {
|
|
|
546
574
|
const signed = JSON.parse(
|
|
547
575
|
core.sign_call(callerSeedHex, accountIndex(callerIndex), contract, order.call_args, accountNonceUsed, meterLimitOf(meterLimit), String(fee), chainId, this._validity(info))
|
|
548
576
|
);
|
|
577
|
+
this._guardSigned(from, nonce, signed.tx_hex);
|
|
549
578
|
const outcome = await this.submit(signed.tx_hex);
|
|
550
579
|
this._remember(from, accountNonceUsed, outcome);
|
|
551
580
|
this._remember(orderKey, nonce, outcome);
|