@quantovainc/qcore 0.1.33 → 0.2.1
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 +33 -9
- package/browser.mjs +5 -3
- package/index.d.ts +63 -51
- package/index.js +5 -3
- package/package.json +2 -2
- package/pkg/package.json +1 -1
- package/pkg/qcore_js.d.ts +11 -3
- package/pkg/qcore_js.js +1 -1
- package/pkg/qcore_js_bg.js +151 -33
- package/pkg/qcore_js_bg.wasm +0 -0
- package/pkg/qcore_js_bg.wasm.d.ts +9 -4
- package/pkg-node/package.json +1 -1
- package/pkg-node/qcore_js.d.ts +11 -3
- package/pkg-node/qcore_js.js +155 -33
- package/pkg-node/qcore_js_bg.wasm +0 -0
- package/shared.js +151 -37
- package/shared.mjs +151 -37
package/shared.mjs
CHANGED
|
@@ -63,7 +63,82 @@ const VALIDITY_BLOCKS = 300n;
|
|
|
63
63
|
const MAX_PLAUSIBLE_HEAD = 1n << 40n;
|
|
64
64
|
const HEAD_BLOCKS_PER_SEC = 4n;
|
|
65
65
|
const HEAD_SLACK_SECS = 60n;
|
|
66
|
-
const
|
|
66
|
+
const U64_MAX = 0xffffffffffffffffn;
|
|
67
|
+
const U128_MAX = (1n << 128n) - 1n;
|
|
68
|
+
|
|
69
|
+
function wholeNumber(value, label, max) {
|
|
70
|
+
let n;
|
|
71
|
+
if (typeof value === 'bigint') {
|
|
72
|
+
n = value;
|
|
73
|
+
} else if (typeof value === 'number') {
|
|
74
|
+
if (!Number.isSafeInteger(value)) {
|
|
75
|
+
throw new Error(`the ${label} must be a whole number in the safe integer range, a number outside it silently rounds, pass a decimal string or a BigInt`);
|
|
76
|
+
}
|
|
77
|
+
n = BigInt(value);
|
|
78
|
+
} else if (typeof value === 'string' && /^[0-9]+$/.test(value)) {
|
|
79
|
+
n = BigInt(value);
|
|
80
|
+
} else {
|
|
81
|
+
throw new Error(`the ${label} must be a string of decimal digits, a BigInt, or a safe integer number`);
|
|
82
|
+
}
|
|
83
|
+
if (n < 0n || n > max) {
|
|
84
|
+
throw new Error(`the ${label} must be a whole number from 0 to ${max}`);
|
|
85
|
+
}
|
|
86
|
+
return n;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function coreArg(kind, label, value) {
|
|
90
|
+
if (kind === 'text') {
|
|
91
|
+
if (typeof value !== 'string') throw new Error(`the ${label} must be a string`);
|
|
92
|
+
return value;
|
|
93
|
+
}
|
|
94
|
+
if (kind === 'u64') return wholeNumber(value, label, U64_MAX);
|
|
95
|
+
if (kind === 'u64s') return wholeNumber(value, label, U64_MAX).toString();
|
|
96
|
+
if (kind === 'u128s') return wholeNumber(value, label, U128_MAX).toString();
|
|
97
|
+
throw new Error(`unknown argument kind ${kind}`);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const CORE_ARGS = {
|
|
101
|
+
address: [['text', 'seed'], ['u64', 'account index']],
|
|
102
|
+
mnemonicFromSeed: [['text', 'seed']],
|
|
103
|
+
seedFromMnemonic: [['text', 'recovery phrase']],
|
|
104
|
+
orderSigner: [['text', 'seed'], ['u64', 'account index']],
|
|
105
|
+
sign_transfer: [['text', 'seed'], ['u64', 'account index'], ['text', 'recipient'], ['u64s', 'amount'], ['u64', 'nonce'], ['u128s', 'fee'], ['u64', 'chain id'], ['u64', 'validity deadline']],
|
|
106
|
+
signRegister: [['text', 'seed'], ['u64', 'account index'], ['u64', 'nonce'], ['u128s', 'fee'], ['u64', 'chain id'], ['u64', 'validity deadline']],
|
|
107
|
+
sign_call: [['text', 'seed'], ['u64', 'account index'], ['text', 'target'], ['text', 'call arguments'], ['u64', 'nonce'], ['u64', 'meter limit'], ['u128s', 'fee'], ['u64', 'chain id'], ['u64', 'validity deadline'], ['u128s', 'transfer fee']],
|
|
108
|
+
signPayableCall: [['text', 'seed'], ['u64', 'account index'], ['text', 'target'], ['text', 'call arguments'], ['u64', 'nonce'], ['u64', 'meter limit'], ['u128s', 'fee'], ['u64s', 'value'], ['u64', 'chain id'], ['u64', 'validity deadline'], ['u128s', 'transfer fee']],
|
|
109
|
+
signAssetCall: [['text', 'seed'], ['u64', 'account index'], ['text', 'target'], ['text', 'call arguments'], ['text', 'asset issuer'], ['u64s', 'amount'], ['u64', 'nonce'], ['u64', 'meter limit'], ['u128s', 'fee'], ['u64', 'chain id'], ['u64', 'validity deadline'], ['u128s', 'transfer fee']],
|
|
110
|
+
buildSignedOrderCall: [['u64', 'chain id'], ['text', 'contract'], ['text', 'selector'], ['u64', 'scheme offset'], ['u64', 'pointer offset'], ['text', 'field offsets'], ['text', 'fields'], ['u64', 'region offset'], ['text', 'owner seed'], ['u64', 'owner index'], ['u64', 'order nonce']],
|
|
111
|
+
buildTypedOrderCall: [['u64', 'chain id'], ['text', 'contract'], ['text', 'selector'], ['u64', 'scheme offset'], ['u64', 'pointer offset'], ['u64', 'region offset'], ['text', 'fields'], ['text', 'owner seed'], ['u64', 'owner index'], ['u64', 'order nonce']],
|
|
112
|
+
contractAddress: [['text', 'deployer'], ['u64', 'nonce']],
|
|
113
|
+
scalarSlotKey: [['u64', 'slot']],
|
|
114
|
+
mapSlotKey: [['u64', 'map domain tag'], ['text', 'key address']],
|
|
115
|
+
mapAddrWordKey: [['u64', 'map domain tag'], ['text', 'key'], ['u64', 'word']],
|
|
116
|
+
unpackSymbol: [['u64', 'symbol word']],
|
|
117
|
+
eventsBody: [['u64', 'height']],
|
|
118
|
+
block_by_height_body: [['u64', 'height']],
|
|
119
|
+
vmCallFee: [['u128s', 'transfer fee'], ['u64', 'meter limit']],
|
|
120
|
+
checkValidUntil: [['u64', 'validity deadline'], ['u64', 'head height']],
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
function wrapCore(raw) {
|
|
124
|
+
const core = Object.assign({}, raw);
|
|
125
|
+
for (const [name, kinds] of Object.entries(CORE_ARGS)) {
|
|
126
|
+
const fn = raw[name];
|
|
127
|
+
if (typeof fn !== 'function') continue;
|
|
128
|
+
core[name] = (...args) => fn(...kinds.map(([kind, label], i) => coreArg(kind, label, args[i])));
|
|
129
|
+
}
|
|
130
|
+
const fee = core.vmCallFee;
|
|
131
|
+
if (typeof fee === 'function') core.vmCallFee = (transferFee, meterLimit) => BigInt(fee(transferFee, meterLimit));
|
|
132
|
+
return Object.freeze(core);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function isMainnetChain(name) {
|
|
136
|
+
return name.startsWith('Q-main-net-');
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function isPublicChain(name) {
|
|
140
|
+
return name.startsWith('Q-test-net-') || isMainnetChain(name);
|
|
141
|
+
}
|
|
67
142
|
|
|
68
143
|
function meterLimitOf(meterLimit) {
|
|
69
144
|
if (typeof meterLimit === 'number' && !Number.isSafeInteger(meterLimit)) {
|
|
@@ -81,13 +156,6 @@ function meterLimitOf(meterLimit) {
|
|
|
81
156
|
return meter;
|
|
82
157
|
}
|
|
83
158
|
|
|
84
|
-
function vmCallFee(transferFee, meterLimit) {
|
|
85
|
-
const meter = meterLimitOf(meterLimit);
|
|
86
|
-
let units = (meter + TRANSFER_METER - 1n) / TRANSFER_METER;
|
|
87
|
-
if (units < 1n) units = 1n;
|
|
88
|
-
return BigInt(transferFee) * units;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
159
|
function validUntil(info) {
|
|
92
160
|
const head = info && info.head_height;
|
|
93
161
|
if (head == null) throw new Error('the gateway did not report a head height to bound the transaction to');
|
|
@@ -201,7 +269,7 @@ class Network {
|
|
|
201
269
|
static testnet() {
|
|
202
270
|
return new Network({
|
|
203
271
|
name: 'testnet',
|
|
204
|
-
chainId: 'Q-test-net-
|
|
272
|
+
chainId: 'Q-test-net-1',
|
|
205
273
|
rpcUrl: 'https://rpc-testnet.quantova.org',
|
|
206
274
|
explorerUrl: 'https://qvmscan.io',
|
|
207
275
|
isMainnet: false,
|
|
@@ -271,13 +339,17 @@ function makeClient(core) {
|
|
|
271
339
|
const name = info && info.chain_id;
|
|
272
340
|
if (!name) throw new Error('the gateway did not report a chain id to bind the signature to');
|
|
273
341
|
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');
|
|
274
|
-
const id = BigInt(core.chainIdFromName(name));
|
|
275
342
|
const configured =
|
|
276
343
|
this.expectedChainId || (this.network && this.network.chainId) || null;
|
|
277
|
-
|
|
278
|
-
|
|
344
|
+
const mainnet = isMainnetChain(name);
|
|
345
|
+
if (configured) {
|
|
346
|
+
if (name !== configured) {
|
|
347
|
+
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`);
|
|
348
|
+
}
|
|
349
|
+
} else if (isPublicChain(name) && !(mainnet && this.acknowledgeMainnet)) {
|
|
350
|
+
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`);
|
|
279
351
|
}
|
|
280
|
-
if (
|
|
352
|
+
if (mainnet && !this.acknowledgeMainnet) {
|
|
281
353
|
throw new Error(`the gateway reports the mainnet chain ${name}; refusing to sign a mainnet transaction without acknowledgeMainnet`);
|
|
282
354
|
}
|
|
283
355
|
if (this._pinnedChainName === null) {
|
|
@@ -285,11 +357,7 @@ function makeClient(core) {
|
|
|
285
357
|
} else if (this._pinnedChainName !== name) {
|
|
286
358
|
throw new Error(`the gateway reported chain ${this._pinnedChainName} earlier and now reports ${name}; refusing to sign, the endpoint is not naming one network`);
|
|
287
359
|
}
|
|
288
|
-
return
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
_isMainnetId(id) {
|
|
292
|
-
return id === BigInt(core.mainnetChainId());
|
|
360
|
+
return BigInt(core.chainIdFromName(name));
|
|
293
361
|
}
|
|
294
362
|
|
|
295
363
|
async _call(method, body) {
|
|
@@ -330,17 +398,47 @@ function makeClient(core) {
|
|
|
330
398
|
}
|
|
331
399
|
_checkedNonce(reported, expected, key) {
|
|
332
400
|
const n = accountNonce(reported);
|
|
401
|
+
if (expected != null) {
|
|
402
|
+
const e = wholeNumber(expected, 'expected nonce', U64_MAX);
|
|
403
|
+
if (e !== n) {
|
|
404
|
+
throw new Error(`the gateway reported nonce ${n} but you expected ${e}; the chain admits only the nonce the account has reached, refusing to sign`);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
333
407
|
if (!this._nextNonces) this._nextNonces = new Map();
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
return
|
|
408
|
+
if (key != null) {
|
|
409
|
+
const local = this._nextNonces.get(key);
|
|
410
|
+
if (local == null || local < n) this._nextNonces.set(key, n);
|
|
411
|
+
}
|
|
412
|
+
return n;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
_guardSigned(key, slot, txHex, until, explicit) {
|
|
416
|
+
if (key == null) return;
|
|
417
|
+
if (!this._signedNonces) this._signedNonces = new Map();
|
|
418
|
+
let held = this._signedNonces.get(key);
|
|
419
|
+
if (!held) { held = new Map(); this._signedNonces.set(key, held); }
|
|
420
|
+
const head = until - VALIDITY_BLOCKS;
|
|
421
|
+
for (const [slotKey, entry] of held) {
|
|
422
|
+
if (head > entry.until) held.delete(slotKey);
|
|
423
|
+
}
|
|
424
|
+
const seen = held.get(String(slot));
|
|
425
|
+
if (!explicit && seen != null && seen.txHex !== txHex) {
|
|
426
|
+
throw new Error(`a different transaction was already signed for nonce ${slot} in this session and was neither rejected nor expired; one nonce carries one signature, pass the nonce explicitly to replace one that never landed`);
|
|
427
|
+
}
|
|
428
|
+
held.set(String(slot), { txHex, until });
|
|
339
429
|
}
|
|
340
430
|
|
|
341
431
|
_remember(key, used, outcome) {
|
|
342
432
|
if (!this._nextNonces) this._nextNonces = new Map();
|
|
343
|
-
|
|
433
|
+
const verdict = outcome && outcome.verdict;
|
|
434
|
+
if (verdict === 'accepted') {
|
|
435
|
+
const next = BigInt(used) + 1n;
|
|
436
|
+
const local = this._nextNonces.get(key);
|
|
437
|
+
if (local == null || local < next) this._nextNonces.set(key, next);
|
|
438
|
+
} else if (verdict === 'rejected') {
|
|
439
|
+
const held = this._signedNonces && this._signedNonces.get(key);
|
|
440
|
+
if (held) held.delete(String(used));
|
|
441
|
+
}
|
|
344
442
|
}
|
|
345
443
|
|
|
346
444
|
_validity(info) {
|
|
@@ -353,9 +451,9 @@ function makeClient(core) {
|
|
|
353
451
|
const elapsed = now > at ? now - at : 0n;
|
|
354
452
|
const allowed = (elapsed + HEAD_SLACK_SECS) * HEAD_BLOCKS_PER_SEC;
|
|
355
453
|
if (head > height + allowed) throw new Error(`the gateway head leapt from ${height} to ${head} faster than blocks are made, refusing to sign`);
|
|
356
|
-
} else {
|
|
357
|
-
this._headFloor = { height: head, at: now };
|
|
358
454
|
}
|
|
455
|
+
core.checkValidUntil(until, head);
|
|
456
|
+
if (!this._headFloor || head > this._headFloor.height) this._headFloor = { height: head, at: now };
|
|
359
457
|
return until;
|
|
360
458
|
}
|
|
361
459
|
transaction(txId) { return this._call('get_transaction', core.transaction_body(txId)); }
|
|
@@ -380,13 +478,15 @@ function makeClient(core) {
|
|
|
380
478
|
if (fee > ceiling) {
|
|
381
479
|
throw new Error(`the gateway fee ${fee} is above the maximum you allowed ${maxFeeQuon}, refusing to sign`);
|
|
382
480
|
}
|
|
481
|
+
const until = this._validity(info);
|
|
383
482
|
const from = core.address(seedHex, accountIndex(index));
|
|
384
483
|
const acct = await this.account(from);
|
|
385
484
|
if (!acct || acct.nonce == null) throw new Error('the gateway did not report a nonce');
|
|
386
485
|
const nonce = this._checkedNonce(acct.nonce, expectedNonce, from);
|
|
387
486
|
const signed = JSON.parse(
|
|
388
|
-
core.sign_transfer(seedHex, accountIndex(index), to, String(amount), nonce, String(fee), chainId,
|
|
487
|
+
core.sign_transfer(seedHex, accountIndex(index), to, String(amount), nonce, String(fee), chainId, until)
|
|
389
488
|
);
|
|
489
|
+
this._guardSigned(from, nonce, signed.tx_hex, until, expectedNonce != null);
|
|
390
490
|
const outcome = await this.submit(signed.tx_hex);
|
|
391
491
|
this._remember(from, nonce, outcome);
|
|
392
492
|
return { signed, outcome };
|
|
@@ -403,11 +503,13 @@ function makeClient(core) {
|
|
|
403
503
|
if (fee > ceiling) {
|
|
404
504
|
throw new Error(`the gateway fee ${fee} is above the maximum you allowed ${maxFeeQuon}, refusing to sign`);
|
|
405
505
|
}
|
|
506
|
+
const until = this._validity(info);
|
|
406
507
|
const from = core.address(seedHex, accountIndex(index));
|
|
407
508
|
const acct = await this.account(from);
|
|
408
509
|
if (!acct || acct.nonce == null) throw new Error('the gateway did not report a nonce');
|
|
409
510
|
const nonce = this._checkedNonce(acct.nonce, expectedNonce, from);
|
|
410
|
-
const signed = JSON.parse(core.signRegister(seedHex, accountIndex(index), nonce, String(fee), chainId,
|
|
511
|
+
const signed = JSON.parse(core.signRegister(seedHex, accountIndex(index), nonce, String(fee), chainId, until));
|
|
512
|
+
this._guardSigned(from, nonce, signed.tx_hex, until, expectedNonce != null);
|
|
411
513
|
const outcome = await this.submit(signed.tx_hex);
|
|
412
514
|
this._remember(from, nonce, outcome);
|
|
413
515
|
return { signed, outcome };
|
|
@@ -421,17 +523,20 @@ function makeClient(core) {
|
|
|
421
523
|
const chainId = this._signingChainId(info);
|
|
422
524
|
const reported = info && info.fee && info.fee.transfer_quon;
|
|
423
525
|
if (reported == null) throw new Error('the gateway did not report a transfer fee');
|
|
424
|
-
const
|
|
526
|
+
const transferFee = gatewayFee(reported);
|
|
527
|
+
const fee = BigInt(core.vmCallFee(String(transferFee), meterLimitOf(meterLimit)));
|
|
425
528
|
if (fee > ceiling) {
|
|
426
529
|
throw new Error(`the fee ${fee} is above the maximum you allowed ${maxFeeQuon}, refusing to sign`);
|
|
427
530
|
}
|
|
531
|
+
const until = this._validity(info);
|
|
428
532
|
const from = core.address(seedHex, accountIndex(index));
|
|
429
533
|
const acct = await this.account(from);
|
|
430
534
|
if (!acct || acct.nonce == null) throw new Error('the gateway did not report a nonce');
|
|
431
535
|
const nonce = this._checkedNonce(acct.nonce, expectedNonce, from);
|
|
432
536
|
const signed = JSON.parse(
|
|
433
|
-
core.sign_call(seedHex, accountIndex(index), target, argsHex, nonce, meterLimitOf(meterLimit), String(fee), chainId,
|
|
537
|
+
core.sign_call(seedHex, accountIndex(index), target, argsHex, nonce, meterLimitOf(meterLimit), String(fee), chainId, until, String(transferFee))
|
|
434
538
|
);
|
|
539
|
+
this._guardSigned(from, nonce, signed.tx_hex, until, expectedNonce != null);
|
|
435
540
|
const outcome = await this.submit(signed.tx_hex);
|
|
436
541
|
this._remember(from, nonce, outcome);
|
|
437
542
|
return { signed, outcome };
|
|
@@ -447,17 +552,20 @@ function makeClient(core) {
|
|
|
447
552
|
const chainId = this._signingChainId(info);
|
|
448
553
|
const reported = info && info.fee && info.fee.transfer_quon;
|
|
449
554
|
if (reported == null) throw new Error('the gateway did not report a transfer fee');
|
|
450
|
-
const
|
|
555
|
+
const transferFee = gatewayFee(reported);
|
|
556
|
+
const fee = BigInt(core.vmCallFee(String(transferFee), meterLimitOf(meterLimit)));
|
|
451
557
|
if (fee > ceiling) {
|
|
452
558
|
throw new Error(`the fee ${fee} is above the maximum you allowed ${maxFeeQuon}, refusing to sign`);
|
|
453
559
|
}
|
|
560
|
+
const until = this._validity(info);
|
|
454
561
|
const from = core.address(seedHex, accountIndex(index));
|
|
455
562
|
const acct = await this.account(from);
|
|
456
563
|
if (!acct || acct.nonce == null) throw new Error('the gateway did not report a nonce');
|
|
457
564
|
const nonce = this._checkedNonce(acct.nonce, expectedNonce, from);
|
|
458
565
|
const signed = JSON.parse(
|
|
459
|
-
core.signAssetCall(seedHex, accountIndex(index), target, argsHex, assetIssuer, String(amount), nonce, meterLimitOf(meterLimit), String(fee), chainId,
|
|
566
|
+
core.signAssetCall(seedHex, accountIndex(index), target, argsHex, assetIssuer, String(amount), nonce, meterLimitOf(meterLimit), String(fee), chainId, until, String(transferFee))
|
|
460
567
|
);
|
|
568
|
+
this._guardSigned(from, nonce, signed.tx_hex, until, expectedNonce != null);
|
|
461
569
|
const outcome = await this.submit(signed.tx_hex);
|
|
462
570
|
this._remember(from, nonce, outcome);
|
|
463
571
|
return { signed, outcome };
|
|
@@ -472,17 +580,20 @@ function makeClient(core) {
|
|
|
472
580
|
const chainId = this._signingChainId(info);
|
|
473
581
|
const reported = info && info.fee && info.fee.transfer_quon;
|
|
474
582
|
if (reported == null) throw new Error('the gateway did not report a transfer fee');
|
|
475
|
-
const
|
|
583
|
+
const transferFee = gatewayFee(reported);
|
|
584
|
+
const fee = BigInt(core.vmCallFee(String(transferFee), meterLimitOf(meterLimit)));
|
|
476
585
|
if (fee > ceiling) {
|
|
477
586
|
throw new Error(`the fee ${fee} is above the maximum you allowed ${maxFeeQuon}, refusing to sign`);
|
|
478
587
|
}
|
|
588
|
+
const until = this._validity(info);
|
|
479
589
|
const from = core.address(seedHex, accountIndex(index));
|
|
480
590
|
const acct = await this.account(from);
|
|
481
591
|
if (!acct || acct.nonce == null) throw new Error('the gateway did not report a nonce');
|
|
482
592
|
const nonce = this._checkedNonce(acct.nonce, expectedNonce, from);
|
|
483
593
|
const signed = JSON.parse(
|
|
484
|
-
core.signPayableCall(seedHex, accountIndex(index), target, argsHex, nonce, meterLimitOf(meterLimit), String(fee), String(value), chainId,
|
|
594
|
+
core.signPayableCall(seedHex, accountIndex(index), target, argsHex, nonce, meterLimitOf(meterLimit), String(fee), String(value), chainId, until, String(transferFee))
|
|
485
595
|
);
|
|
596
|
+
this._guardSigned(from, nonce, signed.tx_hex, until, expectedNonce != null);
|
|
486
597
|
const outcome = await this.submit(signed.tx_hex);
|
|
487
598
|
this._remember(from, nonce, outcome);
|
|
488
599
|
return { signed, outcome };
|
|
@@ -509,10 +620,12 @@ function makeClient(core) {
|
|
|
509
620
|
const chainId = this._signingChainId(info);
|
|
510
621
|
const reported = info && info.fee && info.fee.transfer_quon;
|
|
511
622
|
if (reported == null) throw new Error('the gateway did not report a transfer fee');
|
|
512
|
-
const
|
|
623
|
+
const transferFee = gatewayFee(reported);
|
|
624
|
+
const fee = BigInt(core.vmCallFee(String(transferFee), meterLimitOf(meterLimit)));
|
|
513
625
|
if (fee > ceiling) {
|
|
514
626
|
throw new Error(`the fee ${fee} is above the maximum you allowed ${maxFeeQuon}, refusing to sign`);
|
|
515
627
|
}
|
|
628
|
+
const until = this._validity(info);
|
|
516
629
|
const signer = core.orderSigner(ownerSeedHex, accountIndex(ownerIndex));
|
|
517
630
|
const orderKey = contract + '/' + signer;
|
|
518
631
|
const reportedOrder = await this.contractNonce(contract, signer);
|
|
@@ -544,8 +657,9 @@ function makeClient(core) {
|
|
|
544
657
|
if (!acct || acct.nonce == null) throw new Error('the gateway did not report a nonce');
|
|
545
658
|
const accountNonceUsed = this._checkedNonce(acct.nonce, expectedNonce, from);
|
|
546
659
|
const signed = JSON.parse(
|
|
547
|
-
core.sign_call(callerSeedHex, accountIndex(callerIndex), contract, order.call_args, accountNonceUsed, meterLimitOf(meterLimit), String(fee), chainId,
|
|
660
|
+
core.sign_call(callerSeedHex, accountIndex(callerIndex), contract, order.call_args, accountNonceUsed, meterLimitOf(meterLimit), String(fee), chainId, until, String(transferFee))
|
|
548
661
|
);
|
|
662
|
+
this._guardSigned(from, accountNonceUsed, signed.tx_hex, until, expectedNonce != null);
|
|
549
663
|
const outcome = await this.submit(signed.tx_hex);
|
|
550
664
|
this._remember(from, accountNonceUsed, outcome);
|
|
551
665
|
this._remember(orderKey, nonce, outcome);
|
|
@@ -554,4 +668,4 @@ function makeClient(core) {
|
|
|
554
668
|
};
|
|
555
669
|
}
|
|
556
670
|
|
|
557
|
-
export { makeClient, feeCeiling, checkAmount, generateSeed, readBounded, requireSafeTransport, validUntil,
|
|
671
|
+
export { makeClient, wrapCore, feeCeiling, checkAmount, generateSeed, readBounded, requireSafeTransport, validUntil, VALIDITY_BLOCKS, Network };
|