@quantovainc/qcore 0.5.4 → 0.5.6
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/README.md +7 -0
- package/index.d.ts +1 -0
- package/package.json +1 -1
- package/pkg/README.md +7 -0
- package/pkg/package.json +1 -1
- package/pkg/qcore_js_bg.js +4 -1
- package/pkg/qcore_js_bg.wasm +0 -0
- package/pkg/qcore_js_bg.wasm.d.ts +1 -1
- package/pkg-node/README.md +7 -0
- package/pkg-node/package.json +1 -1
- package/pkg-node/qcore_js.js +4 -1
- package/pkg-node/qcore_js_bg.wasm +0 -0
- package/shared.js +26 -9
- package/shared.mjs +26 -9
package/README.md
CHANGED
|
@@ -134,6 +134,13 @@ Pass `addressBook`, a list of Q1 addresses you trust, in the Client options, and
|
|
|
134
134
|
a target that shares two or more leading and trailing characters with a known address, eight in all, but is a
|
|
135
135
|
different address. The sending accounts and every target signed for in the session are known as well.
|
|
136
136
|
|
|
137
|
+
Pass `fetch`, a function with the fetch signature, in the Client options to route every gateway request
|
|
138
|
+
through your own transport, for example one that enforces an address allow list. Without it the Client
|
|
139
|
+
uses the platform fetch, which on Node follows HTTPS_PROXY only when NODE_USE_ENV_PROXY is set. The
|
|
140
|
+
Client refuses to start when NODE_TLS_REJECT_UNAUTHORIZED is 0. Signing calls for one account run one at a
|
|
141
|
+
time across every Client in the process, and each Client keeps its own record of signed nonces, so keep
|
|
142
|
+
one Client per account to have every nonce tracked in one place.
|
|
143
|
+
|
|
137
144
|
The last argument to a Client signing call, transfer, register, call, or callSignedOrder, is a fee
|
|
138
145
|
ceiling, the most you are ever willing to pay in fees for one transaction. You choose it yourself, as a
|
|
139
146
|
fixed number your app decides on its own, before you sign. The Client reads the gateway's reported fee,
|
package/index.d.ts
CHANGED
|
@@ -237,6 +237,7 @@ export interface ClientOptions {
|
|
|
237
237
|
network?: Network;
|
|
238
238
|
expectedChainId?: string;
|
|
239
239
|
addressBook?: ReadonlyArray<string>;
|
|
240
|
+
fetch?: (url: string, init: { method: string; headers: Record<string, string>; body: string; signal: AbortSignal; redirect: 'error' }) => Promise<Response>;
|
|
240
241
|
}
|
|
241
242
|
|
|
242
243
|
export class Client {
|
package/package.json
CHANGED
package/pkg/README.md
CHANGED
|
@@ -134,6 +134,13 @@ Pass `addressBook`, a list of Q1 addresses you trust, in the Client options, and
|
|
|
134
134
|
a target that shares two or more leading and trailing characters with a known address, eight in all, but is a
|
|
135
135
|
different address. The sending accounts and every target signed for in the session are known as well.
|
|
136
136
|
|
|
137
|
+
Pass `fetch`, a function with the fetch signature, in the Client options to route every gateway request
|
|
138
|
+
through your own transport, for example one that enforces an address allow list. Without it the Client
|
|
139
|
+
uses the platform fetch, which on Node follows HTTPS_PROXY only when NODE_USE_ENV_PROXY is set. The
|
|
140
|
+
Client refuses to start when NODE_TLS_REJECT_UNAUTHORIZED is 0. Signing calls for one account run one at a
|
|
141
|
+
time across every Client in the process, and each Client keeps its own record of signed nonces, so keep
|
|
142
|
+
one Client per account to have every nonce tracked in one place.
|
|
143
|
+
|
|
137
144
|
The last argument to a Client signing call, transfer, register, call, or callSignedOrder, is a fee
|
|
138
145
|
ceiling, the most you are ever willing to pay in fees for one transaction. You choose it yourself, as a
|
|
139
146
|
fixed number your app decides on its own, before you sign. The Client reads the gateway's reported fee,
|
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.
|
|
5
|
+
"version": "0.5.6",
|
|
6
6
|
"license": "Apache-2.0 OR MIT",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
package/pkg/qcore_js_bg.js
CHANGED
|
@@ -323,7 +323,10 @@ export function chainIdFromName(name) {
|
|
|
323
323
|
const ptr0 = passStringToWasm0(name, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
324
324
|
const len0 = WASM_VECTOR_LEN;
|
|
325
325
|
const ret = wasm.chainIdFromName(ptr0, len0);
|
|
326
|
-
|
|
326
|
+
if (ret[2]) {
|
|
327
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
328
|
+
}
|
|
329
|
+
return BigInt.asUintN(64, ret[0]);
|
|
327
330
|
}
|
|
328
331
|
|
|
329
332
|
/**
|
package/pkg/qcore_js_bg.wasm
CHANGED
|
Binary file
|
|
@@ -10,7 +10,7 @@ export const block_by_height_body: (a: bigint) => [number, number];
|
|
|
10
10
|
export const boundedValidUntil: (a: number, b: number, c: bigint, d: bigint, e: number, f: bigint, g: bigint) => [bigint, number, number];
|
|
11
11
|
export const buildSignedOrderCall: (a: bigint, b: number, c: number, d: number, e: number, f: number, g: number, h: bigint, i: bigint, j: bigint, k: number, l: number, m: number, n: number, o: bigint, p: number, q: number, r: bigint, s: bigint, t: bigint) => [number, number, number, number];
|
|
12
12
|
export const buildTypedOrderCall: (a: bigint, b: number, c: number, d: number, e: number, f: number, g: number, h: bigint, i: bigint, j: bigint, k: bigint, l: number, m: number, n: number, o: number, p: bigint, q: bigint, r: bigint) => [number, number, number, number];
|
|
13
|
-
export const chainIdFromName: (a: number, b: number) => bigint;
|
|
13
|
+
export const chainIdFromName: (a: number, b: number) => [bigint, number, number];
|
|
14
14
|
export const checkGatewayJson: (a: number, b: number) => [number, number];
|
|
15
15
|
export const checkOrderExpiry: (a: bigint, b: bigint) => [number, number];
|
|
16
16
|
export const checkValidUntil: (a: bigint, b: bigint) => [number, number];
|
package/pkg-node/README.md
CHANGED
|
@@ -134,6 +134,13 @@ Pass `addressBook`, a list of Q1 addresses you trust, in the Client options, and
|
|
|
134
134
|
a target that shares two or more leading and trailing characters with a known address, eight in all, but is a
|
|
135
135
|
different address. The sending accounts and every target signed for in the session are known as well.
|
|
136
136
|
|
|
137
|
+
Pass `fetch`, a function with the fetch signature, in the Client options to route every gateway request
|
|
138
|
+
through your own transport, for example one that enforces an address allow list. Without it the Client
|
|
139
|
+
uses the platform fetch, which on Node follows HTTPS_PROXY only when NODE_USE_ENV_PROXY is set. The
|
|
140
|
+
Client refuses to start when NODE_TLS_REJECT_UNAUTHORIZED is 0. Signing calls for one account run one at a
|
|
141
|
+
time across every Client in the process, and each Client keeps its own record of signed nonces, so keep
|
|
142
|
+
one Client per account to have every nonce tracked in one place.
|
|
143
|
+
|
|
137
144
|
The last argument to a Client signing call, transfer, register, call, or callSignedOrder, is a fee
|
|
138
145
|
ceiling, the most you are ever willing to pay in fees for one transaction. You choose it yourself, as a
|
|
139
146
|
fixed number your app decides on its own, before you sign. The Client reads the gateway's reported fee,
|
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.5.
|
|
4
|
+
"version": "0.5.6",
|
|
5
5
|
"license": "Apache-2.0 OR MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
package/pkg-node/qcore_js.js
CHANGED
|
@@ -334,7 +334,10 @@ function chainIdFromName(name) {
|
|
|
334
334
|
const ptr0 = passStringToWasm0(name, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
335
335
|
const len0 = WASM_VECTOR_LEN;
|
|
336
336
|
const ret = wasm.chainIdFromName(ptr0, len0);
|
|
337
|
-
|
|
337
|
+
if (ret[2]) {
|
|
338
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
339
|
+
}
|
|
340
|
+
return BigInt.asUintN(64, ret[0]);
|
|
338
341
|
}
|
|
339
342
|
exports.chainIdFromName = chainIdFromName;
|
|
340
343
|
|
|
Binary file
|
package/shared.js
CHANGED
|
@@ -59,6 +59,20 @@ function wholeNumber(value, label, max) {
|
|
|
59
59
|
return n;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
const ACCOUNT_LOCKS = new Map();
|
|
63
|
+
|
|
64
|
+
function requireVerifiedTls() {
|
|
65
|
+
const env = typeof process !== 'undefined' && process && process.env ? process.env : null;
|
|
66
|
+
if (env && env.NODE_TLS_REJECT_UNAUTHORIZED === '0') {
|
|
67
|
+
throw new Error('this process has TLS certificate checks turned off with NODE_TLS_REJECT_UNAUTHORIZED=0, refusing to talk to a gateway');
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function shown(value) {
|
|
72
|
+
const text = String(value).replace(/[\u0000-\u001f\u007f-\u009f\u200b-\u200f\u2028-\u202e\u2066-\u2069\ufeff]/g, '');
|
|
73
|
+
return text.length > 96 ? text.slice(0, 96) + '...' : text;
|
|
74
|
+
}
|
|
75
|
+
|
|
62
76
|
function coreArg(kind, label, value) {
|
|
63
77
|
if (kind === 'text') {
|
|
64
78
|
if (typeof value !== 'string') throw new Error(`the ${label} must be a string`);
|
|
@@ -343,7 +357,10 @@ function makeClient(core) {
|
|
|
343
357
|
this._session = new core.SigningSession(book);
|
|
344
358
|
this._pinnedChainName = null;
|
|
345
359
|
this._headFloor = null;
|
|
346
|
-
|
|
360
|
+
if (opts.fetch != null && typeof opts.fetch !== 'function') throw new Error('the fetch option must be a function with the fetch signature');
|
|
361
|
+
this._fetch = opts.fetch || ((url, init) => fetch(url, init));
|
|
362
|
+
requireVerifiedTls();
|
|
363
|
+
this._locks = ACCOUNT_LOCKS;
|
|
347
364
|
for (const name of ['transfer', 'register', 'call', 'assetCall', 'payableCall']) {
|
|
348
365
|
const inner = this[name].bind(this);
|
|
349
366
|
this[name] = (seed, index, ...rest) => {
|
|
@@ -392,18 +409,18 @@ function makeClient(core) {
|
|
|
392
409
|
const mainnet = isMainnetChain(name);
|
|
393
410
|
if (configured) {
|
|
394
411
|
if (name !== configured) {
|
|
395
|
-
throw new Error(`the gateway reports chain ${name} but this client is configured for ${configured}; refusing to sign a transaction that would be valid on a network you did not choose`);
|
|
412
|
+
throw new Error(`the gateway reports chain ${shown(name)} but this client is configured for ${configured}; refusing to sign a transaction that would be valid on a network you did not choose`);
|
|
396
413
|
}
|
|
397
414
|
} else if (isPublicChain(name) && !(mainnet && this.acknowledgeMainnet)) {
|
|
398
|
-
throw new Error(`the gateway reports the public chain ${name} but this client was opened for an unnamed network; configure the testnet or mainnet network before signing for it`);
|
|
415
|
+
throw new Error(`the gateway reports the public chain ${shown(name)} but this client was opened for an unnamed network; configure the testnet or mainnet network before signing for it`);
|
|
399
416
|
}
|
|
400
417
|
if (mainnet && !this.acknowledgeMainnet) {
|
|
401
|
-
throw new Error(`the gateway reports the mainnet chain ${name}; refusing to sign a mainnet transaction without acknowledgeMainnet`);
|
|
418
|
+
throw new Error(`the gateway reports the mainnet chain ${shown(name)}; refusing to sign a mainnet transaction without acknowledgeMainnet`);
|
|
402
419
|
}
|
|
403
420
|
if (this._pinnedChainName === null) {
|
|
404
421
|
this._pinnedChainName = name;
|
|
405
422
|
} else if (this._pinnedChainName !== name) {
|
|
406
|
-
throw new Error(`the gateway reported chain ${this._pinnedChainName} earlier and now reports ${name}; refusing to sign, the endpoint is not naming one network`);
|
|
423
|
+
throw new Error(`the gateway reported chain ${shown(this._pinnedChainName)} earlier and now reports ${shown(name)}; refusing to sign, the endpoint is not naming one network`);
|
|
407
424
|
}
|
|
408
425
|
return BigInt(core.chainIdFromName(name));
|
|
409
426
|
}
|
|
@@ -412,7 +429,7 @@ function makeClient(core) {
|
|
|
412
429
|
const controller = new AbortController();
|
|
413
430
|
const timer = setTimeout(() => controller.abort(), TIMEOUT_MS);
|
|
414
431
|
try {
|
|
415
|
-
const res = await
|
|
432
|
+
const res = await this._fetch(this.base + '/v1/' + method, {
|
|
416
433
|
method: 'POST',
|
|
417
434
|
headers: { 'Content-Type': 'application/json' },
|
|
418
435
|
body: body || '{}',
|
|
@@ -425,7 +442,7 @@ function makeClient(core) {
|
|
|
425
442
|
try { data = JSON.parse(text); } catch { throw new Error('the node returned a non JSON response'); }
|
|
426
443
|
if (res.status !== 200) {
|
|
427
444
|
const detail = data && typeof data === 'object' ? (data.message || data.error) : null;
|
|
428
|
-
throw new Error(detail
|
|
445
|
+
throw new Error(detail ? shown(detail) : ('status ' + res.status));
|
|
429
446
|
}
|
|
430
447
|
return data;
|
|
431
448
|
} finally {
|
|
@@ -441,7 +458,7 @@ function makeClient(core) {
|
|
|
441
458
|
throw new Error(`the gateway answered about ${address} without naming the account, refusing to trust it`);
|
|
442
459
|
}
|
|
443
460
|
if (acct.address !== address) {
|
|
444
|
-
throw new Error(`the gateway answered for ${acct.address} when asked about ${address}, refusing to trust it`);
|
|
461
|
+
throw new Error(`the gateway answered for ${shown(acct.address)} when asked about ${address}, refusing to trust it`);
|
|
445
462
|
}
|
|
446
463
|
return acct;
|
|
447
464
|
}
|
|
@@ -469,7 +486,7 @@ function makeClient(core) {
|
|
|
469
486
|
for (const [key, slot] of slots) this._session.signed(key, slot);
|
|
470
487
|
const outcome = await this.submit(txHex);
|
|
471
488
|
const verdict = outcome && outcome.verdict;
|
|
472
|
-
if (verdict !== 'accepted' && verdict !== 'rejected') throw new Error(`unknown verdict ${verdict}`);
|
|
489
|
+
if (verdict !== 'accepted' && verdict !== 'rejected') throw new Error(`unknown verdict ${shown(verdict)}`);
|
|
473
490
|
for (const [key, slot] of slots) this._session.outcome(key, slot, verdict === 'accepted');
|
|
474
491
|
return outcome;
|
|
475
492
|
}
|
package/shared.mjs
CHANGED
|
@@ -59,6 +59,20 @@ function wholeNumber(value, label, max) {
|
|
|
59
59
|
return n;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
const ACCOUNT_LOCKS = new Map();
|
|
63
|
+
|
|
64
|
+
function requireVerifiedTls() {
|
|
65
|
+
const env = typeof process !== 'undefined' && process && process.env ? process.env : null;
|
|
66
|
+
if (env && env.NODE_TLS_REJECT_UNAUTHORIZED === '0') {
|
|
67
|
+
throw new Error('this process has TLS certificate checks turned off with NODE_TLS_REJECT_UNAUTHORIZED=0, refusing to talk to a gateway');
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function shown(value) {
|
|
72
|
+
const text = String(value).replace(/[\u0000-\u001f\u007f-\u009f\u200b-\u200f\u2028-\u202e\u2066-\u2069\ufeff]/g, '');
|
|
73
|
+
return text.length > 96 ? text.slice(0, 96) + '...' : text;
|
|
74
|
+
}
|
|
75
|
+
|
|
62
76
|
function coreArg(kind, label, value) {
|
|
63
77
|
if (kind === 'text') {
|
|
64
78
|
if (typeof value !== 'string') throw new Error(`the ${label} must be a string`);
|
|
@@ -343,7 +357,10 @@ function makeClient(core) {
|
|
|
343
357
|
this._session = new core.SigningSession(book);
|
|
344
358
|
this._pinnedChainName = null;
|
|
345
359
|
this._headFloor = null;
|
|
346
|
-
|
|
360
|
+
if (opts.fetch != null && typeof opts.fetch !== 'function') throw new Error('the fetch option must be a function with the fetch signature');
|
|
361
|
+
this._fetch = opts.fetch || ((url, init) => fetch(url, init));
|
|
362
|
+
requireVerifiedTls();
|
|
363
|
+
this._locks = ACCOUNT_LOCKS;
|
|
347
364
|
for (const name of ['transfer', 'register', 'call', 'assetCall', 'payableCall']) {
|
|
348
365
|
const inner = this[name].bind(this);
|
|
349
366
|
this[name] = (seed, index, ...rest) => {
|
|
@@ -392,18 +409,18 @@ function makeClient(core) {
|
|
|
392
409
|
const mainnet = isMainnetChain(name);
|
|
393
410
|
if (configured) {
|
|
394
411
|
if (name !== configured) {
|
|
395
|
-
throw new Error(`the gateway reports chain ${name} but this client is configured for ${configured}; refusing to sign a transaction that would be valid on a network you did not choose`);
|
|
412
|
+
throw new Error(`the gateway reports chain ${shown(name)} but this client is configured for ${configured}; refusing to sign a transaction that would be valid on a network you did not choose`);
|
|
396
413
|
}
|
|
397
414
|
} else if (isPublicChain(name) && !(mainnet && this.acknowledgeMainnet)) {
|
|
398
|
-
throw new Error(`the gateway reports the public chain ${name} but this client was opened for an unnamed network; configure the testnet or mainnet network before signing for it`);
|
|
415
|
+
throw new Error(`the gateway reports the public chain ${shown(name)} but this client was opened for an unnamed network; configure the testnet or mainnet network before signing for it`);
|
|
399
416
|
}
|
|
400
417
|
if (mainnet && !this.acknowledgeMainnet) {
|
|
401
|
-
throw new Error(`the gateway reports the mainnet chain ${name}; refusing to sign a mainnet transaction without acknowledgeMainnet`);
|
|
418
|
+
throw new Error(`the gateway reports the mainnet chain ${shown(name)}; refusing to sign a mainnet transaction without acknowledgeMainnet`);
|
|
402
419
|
}
|
|
403
420
|
if (this._pinnedChainName === null) {
|
|
404
421
|
this._pinnedChainName = name;
|
|
405
422
|
} else if (this._pinnedChainName !== name) {
|
|
406
|
-
throw new Error(`the gateway reported chain ${this._pinnedChainName} earlier and now reports ${name}; refusing to sign, the endpoint is not naming one network`);
|
|
423
|
+
throw new Error(`the gateway reported chain ${shown(this._pinnedChainName)} earlier and now reports ${shown(name)}; refusing to sign, the endpoint is not naming one network`);
|
|
407
424
|
}
|
|
408
425
|
return BigInt(core.chainIdFromName(name));
|
|
409
426
|
}
|
|
@@ -412,7 +429,7 @@ function makeClient(core) {
|
|
|
412
429
|
const controller = new AbortController();
|
|
413
430
|
const timer = setTimeout(() => controller.abort(), TIMEOUT_MS);
|
|
414
431
|
try {
|
|
415
|
-
const res = await
|
|
432
|
+
const res = await this._fetch(this.base + '/v1/' + method, {
|
|
416
433
|
method: 'POST',
|
|
417
434
|
headers: { 'Content-Type': 'application/json' },
|
|
418
435
|
body: body || '{}',
|
|
@@ -425,7 +442,7 @@ function makeClient(core) {
|
|
|
425
442
|
try { data = JSON.parse(text); } catch { throw new Error('the node returned a non JSON response'); }
|
|
426
443
|
if (res.status !== 200) {
|
|
427
444
|
const detail = data && typeof data === 'object' ? (data.message || data.error) : null;
|
|
428
|
-
throw new Error(detail
|
|
445
|
+
throw new Error(detail ? shown(detail) : ('status ' + res.status));
|
|
429
446
|
}
|
|
430
447
|
return data;
|
|
431
448
|
} finally {
|
|
@@ -441,7 +458,7 @@ function makeClient(core) {
|
|
|
441
458
|
throw new Error(`the gateway answered about ${address} without naming the account, refusing to trust it`);
|
|
442
459
|
}
|
|
443
460
|
if (acct.address !== address) {
|
|
444
|
-
throw new Error(`the gateway answered for ${acct.address} when asked about ${address}, refusing to trust it`);
|
|
461
|
+
throw new Error(`the gateway answered for ${shown(acct.address)} when asked about ${address}, refusing to trust it`);
|
|
445
462
|
}
|
|
446
463
|
return acct;
|
|
447
464
|
}
|
|
@@ -469,7 +486,7 @@ function makeClient(core) {
|
|
|
469
486
|
for (const [key, slot] of slots) this._session.signed(key, slot);
|
|
470
487
|
const outcome = await this.submit(txHex);
|
|
471
488
|
const verdict = outcome && outcome.verdict;
|
|
472
|
-
if (verdict !== 'accepted' && verdict !== 'rejected') throw new Error(`unknown verdict ${verdict}`);
|
|
489
|
+
if (verdict !== 'accepted' && verdict !== 'rejected') throw new Error(`unknown verdict ${shown(verdict)}`);
|
|
473
490
|
for (const [key, slot] of slots) this._session.outcome(key, slot, verdict === 'accepted');
|
|
474
491
|
return outcome;
|
|
475
492
|
}
|