@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.
@@ -205,6 +205,18 @@ function chainIdFromName(name) {
205
205
  }
206
206
  exports.chainIdFromName = chainIdFromName;
207
207
 
208
+ /**
209
+ * @param {bigint} valid_until
210
+ * @param {bigint} head
211
+ */
212
+ function checkValidUntil(valid_until, head) {
213
+ const ret = wasm.checkValidUntil(valid_until, head);
214
+ if (ret[1]) {
215
+ throw takeFromExternrefTable0(ret[0]);
216
+ }
217
+ }
218
+ exports.checkValidUntil = checkValidUntil;
219
+
208
220
  /**
209
221
  * @param {string} deployer
210
222
  * @param {bigint} nonce
@@ -250,6 +262,26 @@ function localChainId() {
250
262
  }
251
263
  exports.localChainId = localChainId;
252
264
 
265
+ /**
266
+ * @param {string} candidate
267
+ * @param {string[]} known
268
+ * @returns {string | undefined}
269
+ */
270
+ function lookalikeOf(candidate, known) {
271
+ const ptr0 = passStringToWasm0(candidate, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
272
+ const len0 = WASM_VECTOR_LEN;
273
+ const ptr1 = passArrayJsValueToWasm0(known, wasm.__wbindgen_malloc);
274
+ const len1 = WASM_VECTOR_LEN;
275
+ const ret = wasm.lookalikeOf(ptr0, len0, ptr1, len1);
276
+ let v3;
277
+ if (ret[0] !== 0) {
278
+ v3 = getStringFromWasm0(ret[0], ret[1]).slice();
279
+ wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
280
+ }
281
+ return v3;
282
+ }
283
+ exports.lookalikeOf = lookalikeOf;
284
+
253
285
  /**
254
286
  * @returns {bigint}
255
287
  */
@@ -440,6 +472,21 @@ function parseEvents(response) {
440
472
  }
441
473
  exports.parseEvents = parseEvents;
442
474
 
475
+ /**
476
+ * @param {string} a
477
+ * @param {string} b
478
+ * @returns {boolean}
479
+ */
480
+ function sameAddress(a, b) {
481
+ const ptr0 = passStringToWasm0(a, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
482
+ const len0 = WASM_VECTOR_LEN;
483
+ const ptr1 = passStringToWasm0(b, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
484
+ const len1 = WASM_VECTOR_LEN;
485
+ const ret = wasm.sameAddress(ptr0, len0, ptr1, len1);
486
+ return ret !== 0;
487
+ }
488
+ exports.sameAddress = sameAddress;
489
+
443
490
  /**
444
491
  * @param {bigint} slot
445
492
  * @returns {string}
@@ -485,11 +532,12 @@ exports.seedFromMnemonic = seedFromMnemonic;
485
532
  * @param {string} fee
486
533
  * @param {bigint} chain_id
487
534
  * @param {bigint} valid_until
535
+ * @param {string | null} [transfer_fee]
488
536
  * @returns {string}
489
537
  */
490
- function signAssetCall(seed_hex, index, target, args_hex, asset_issuer, amount, nonce, meter_limit, fee, chain_id, valid_until) {
491
- let deferred8_0;
492
- let deferred8_1;
538
+ function signAssetCall(seed_hex, index, target, args_hex, asset_issuer, amount, nonce, meter_limit, fee, chain_id, valid_until, transfer_fee) {
539
+ let deferred9_0;
540
+ let deferred9_1;
493
541
  try {
494
542
  const ptr0 = passStringToWasm0(seed_hex, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
495
543
  const len0 = WASM_VECTOR_LEN;
@@ -503,18 +551,20 @@ function signAssetCall(seed_hex, index, target, args_hex, asset_issuer, amount,
503
551
  const len4 = WASM_VECTOR_LEN;
504
552
  const ptr5 = passStringToWasm0(fee, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
505
553
  const len5 = WASM_VECTOR_LEN;
506
- const ret = wasm.signAssetCall(ptr0, len0, index, ptr1, len1, ptr2, len2, ptr3, len3, ptr4, len4, nonce, meter_limit, ptr5, len5, chain_id, valid_until);
507
- var ptr7 = ret[0];
508
- var len7 = ret[1];
554
+ var ptr6 = isLikeNone(transfer_fee) ? 0 : passStringToWasm0(transfer_fee, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
555
+ var len6 = WASM_VECTOR_LEN;
556
+ const ret = wasm.signAssetCall(ptr0, len0, index, ptr1, len1, ptr2, len2, ptr3, len3, ptr4, len4, nonce, meter_limit, ptr5, len5, chain_id, valid_until, ptr6, len6);
557
+ var ptr8 = ret[0];
558
+ var len8 = ret[1];
509
559
  if (ret[3]) {
510
- ptr7 = 0; len7 = 0;
560
+ ptr8 = 0; len8 = 0;
511
561
  throw takeFromExternrefTable0(ret[2]);
512
562
  }
513
- deferred8_0 = ptr7;
514
- deferred8_1 = len7;
515
- return getStringFromWasm0(ptr7, len7);
563
+ deferred9_0 = ptr8;
564
+ deferred9_1 = len8;
565
+ return getStringFromWasm0(ptr8, len8);
516
566
  } finally {
517
- wasm.__wbindgen_free(deferred8_0, deferred8_1, 1);
567
+ wasm.__wbindgen_free(deferred9_0, deferred9_1, 1);
518
568
  }
519
569
  }
520
570
  exports.signAssetCall = signAssetCall;
@@ -530,11 +580,12 @@ exports.signAssetCall = signAssetCall;
530
580
  * @param {string} value
531
581
  * @param {bigint} chain_id
532
582
  * @param {bigint} valid_until
583
+ * @param {string | null} [transfer_fee]
533
584
  * @returns {string}
534
585
  */
535
- function signPayableCall(seed_hex, index, target, args_hex, nonce, meter_limit, fee, value, chain_id, valid_until) {
536
- let deferred7_0;
537
- let deferred7_1;
586
+ function signPayableCall(seed_hex, index, target, args_hex, nonce, meter_limit, fee, value, chain_id, valid_until, transfer_fee) {
587
+ let deferred8_0;
588
+ let deferred8_1;
538
589
  try {
539
590
  const ptr0 = passStringToWasm0(seed_hex, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
540
591
  const len0 = WASM_VECTOR_LEN;
@@ -546,18 +597,20 @@ function signPayableCall(seed_hex, index, target, args_hex, nonce, meter_limit,
546
597
  const len3 = WASM_VECTOR_LEN;
547
598
  const ptr4 = passStringToWasm0(value, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
548
599
  const len4 = WASM_VECTOR_LEN;
549
- const ret = wasm.signPayableCall(ptr0, len0, index, ptr1, len1, ptr2, len2, nonce, meter_limit, ptr3, len3, ptr4, len4, chain_id, valid_until);
550
- var ptr6 = ret[0];
551
- var len6 = ret[1];
600
+ var ptr5 = isLikeNone(transfer_fee) ? 0 : passStringToWasm0(transfer_fee, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
601
+ var len5 = WASM_VECTOR_LEN;
602
+ const ret = wasm.signPayableCall(ptr0, len0, index, ptr1, len1, ptr2, len2, nonce, meter_limit, ptr3, len3, ptr4, len4, chain_id, valid_until, ptr5, len5);
603
+ var ptr7 = ret[0];
604
+ var len7 = ret[1];
552
605
  if (ret[3]) {
553
- ptr6 = 0; len6 = 0;
606
+ ptr7 = 0; len7 = 0;
554
607
  throw takeFromExternrefTable0(ret[2]);
555
608
  }
556
- deferred7_0 = ptr6;
557
- deferred7_1 = len6;
558
- return getStringFromWasm0(ptr6, len6);
609
+ deferred8_0 = ptr7;
610
+ deferred8_1 = len7;
611
+ return getStringFromWasm0(ptr7, len7);
559
612
  } finally {
560
- wasm.__wbindgen_free(deferred7_0, deferred7_1, 1);
613
+ wasm.__wbindgen_free(deferred8_0, deferred8_1, 1);
561
614
  }
562
615
  }
563
616
  exports.signPayableCall = signPayableCall;
@@ -605,11 +658,12 @@ exports.signRegister = signRegister;
605
658
  * @param {string} fee
606
659
  * @param {bigint} chain_id
607
660
  * @param {bigint} valid_until
661
+ * @param {string | null} [transfer_fee]
608
662
  * @returns {string}
609
663
  */
610
- function sign_call(seed_hex, index, target, args_hex, nonce, meter_limit, fee, chain_id, valid_until) {
611
- let deferred6_0;
612
- let deferred6_1;
664
+ function sign_call(seed_hex, index, target, args_hex, nonce, meter_limit, fee, chain_id, valid_until, transfer_fee) {
665
+ let deferred7_0;
666
+ let deferred7_1;
613
667
  try {
614
668
  const ptr0 = passStringToWasm0(seed_hex, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
615
669
  const len0 = WASM_VECTOR_LEN;
@@ -619,18 +673,20 @@ function sign_call(seed_hex, index, target, args_hex, nonce, meter_limit, fee, c
619
673
  const len2 = WASM_VECTOR_LEN;
620
674
  const ptr3 = passStringToWasm0(fee, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
621
675
  const len3 = WASM_VECTOR_LEN;
622
- const ret = wasm.sign_call(ptr0, len0, index, ptr1, len1, ptr2, len2, nonce, meter_limit, ptr3, len3, chain_id, valid_until);
623
- var ptr5 = ret[0];
624
- var len5 = ret[1];
676
+ var ptr4 = isLikeNone(transfer_fee) ? 0 : passStringToWasm0(transfer_fee, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
677
+ var len4 = WASM_VECTOR_LEN;
678
+ const ret = wasm.sign_call(ptr0, len0, index, ptr1, len1, ptr2, len2, nonce, meter_limit, ptr3, len3, chain_id, valid_until, ptr4, len4);
679
+ var ptr6 = ret[0];
680
+ var len6 = ret[1];
625
681
  if (ret[3]) {
626
- ptr5 = 0; len5 = 0;
682
+ ptr6 = 0; len6 = 0;
627
683
  throw takeFromExternrefTable0(ret[2]);
628
684
  }
629
- deferred6_0 = ptr5;
630
- deferred6_1 = len5;
631
- return getStringFromWasm0(ptr5, len5);
685
+ deferred7_0 = ptr6;
686
+ deferred7_1 = len6;
687
+ return getStringFromWasm0(ptr6, len6);
632
688
  } finally {
633
- wasm.__wbindgen_free(deferred6_0, deferred6_1, 1);
689
+ wasm.__wbindgen_free(deferred7_0, deferred7_1, 1);
634
690
  }
635
691
  }
636
692
  exports.sign_call = sign_call;
@@ -826,6 +882,33 @@ function valid_address(address) {
826
882
  }
827
883
  exports.valid_address = valid_address;
828
884
 
885
+ /**
886
+ * @param {string} transfer_fee
887
+ * @param {bigint} meter_limit
888
+ * @returns {string}
889
+ */
890
+ function vmCallFee(transfer_fee, meter_limit) {
891
+ let deferred3_0;
892
+ let deferred3_1;
893
+ try {
894
+ const ptr0 = passStringToWasm0(transfer_fee, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
895
+ const len0 = WASM_VECTOR_LEN;
896
+ const ret = wasm.vmCallFee(ptr0, len0, meter_limit);
897
+ var ptr2 = ret[0];
898
+ var len2 = ret[1];
899
+ if (ret[3]) {
900
+ ptr2 = 0; len2 = 0;
901
+ throw takeFromExternrefTable0(ret[2]);
902
+ }
903
+ deferred3_0 = ptr2;
904
+ deferred3_1 = len2;
905
+ return getStringFromWasm0(ptr2, len2);
906
+ } finally {
907
+ wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
908
+ }
909
+ }
910
+ exports.vmCallFee = vmCallFee;
911
+
829
912
  /**
830
913
  * @returns {string}
831
914
  */
@@ -849,6 +932,17 @@ function __wbg_get_imports() {
849
932
  const ret = Error(getStringFromWasm0(arg0, arg1));
850
933
  return ret;
851
934
  },
935
+ __wbg___wbindgen_string_get_b0ca35b86a603356: function(arg0, arg1) {
936
+ const obj = arg1;
937
+ const ret = typeof(obj) === 'string' ? obj : undefined;
938
+ var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
939
+ var len1 = WASM_VECTOR_LEN;
940
+ getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
941
+ getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
942
+ },
943
+ __wbg___wbindgen_throw_344f42d3211c4765: function(arg0, arg1) {
944
+ throw new Error(getStringFromWasm0(arg0, arg1));
945
+ },
852
946
  __wbindgen_cast_0000000000000001: function(arg0, arg1) {
853
947
  // Cast intrinsic for `Ref(String) -> Externref`.
854
948
  const ret = getStringFromWasm0(arg0, arg1);
@@ -870,6 +964,20 @@ function __wbg_get_imports() {
870
964
  };
871
965
  }
872
966
 
967
+ function addToExternrefTable0(obj) {
968
+ const idx = wasm.__externref_table_alloc();
969
+ wasm.__wbindgen_externrefs.set(idx, obj);
970
+ return idx;
971
+ }
972
+
973
+ let cachedDataViewMemory0 = null;
974
+ function getDataViewMemory0() {
975
+ if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) {
976
+ cachedDataViewMemory0 = new DataView(wasm.memory.buffer);
977
+ }
978
+ return cachedDataViewMemory0;
979
+ }
980
+
873
981
  function getStringFromWasm0(ptr, len) {
874
982
  return decodeText(ptr >>> 0, len);
875
983
  }
@@ -882,6 +990,20 @@ function getUint8ArrayMemory0() {
882
990
  return cachedUint8ArrayMemory0;
883
991
  }
884
992
 
993
+ function isLikeNone(x) {
994
+ return x === undefined || x === null;
995
+ }
996
+
997
+ function passArrayJsValueToWasm0(array, malloc) {
998
+ const ptr = malloc(array.length * 4, 4) >>> 0;
999
+ for (let i = 0; i < array.length; i++) {
1000
+ const add = addToExternrefTable0(array[i]);
1001
+ getDataViewMemory0().setUint32(ptr + 4 * i, add, true);
1002
+ }
1003
+ WASM_VECTOR_LEN = array.length;
1004
+ return ptr;
1005
+ }
1006
+
885
1007
  function passStringToWasm0(arg, malloc, realloc) {
886
1008
  if (realloc === undefined) {
887
1009
  const buf = cachedTextEncoder.encode(arg);
Binary file
package/shared.js 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 TRANSFER_METER = 1210n;
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-3',
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
- if (configured && name !== configured) {
278
- 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`);
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 (!this.acknowledgeMainnet && this._isMainnetId(id)) {
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 id;
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
- const local = key != null ? this._nextNonces.get(key) : undefined;
335
- const e = expected != null ? BigInt(expected) : local;
336
- if (e == null) return n;
337
- 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`);
338
- return expected != null ? e : n;
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
- if (outcome && outcome.verdict === 'accepted') this._nextNonces.set(key, BigInt(used) + 1n);
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, this._validity(info))
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, this._validity(info)));
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 fee = vmCallFee(gatewayFee(reported), meterLimit);
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, this._validity(info))
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 fee = vmCallFee(gatewayFee(reported), meterLimit);
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, this._validity(info))
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 fee = vmCallFee(gatewayFee(reported), meterLimit);
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, this._validity(info))
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 fee = vmCallFee(gatewayFee(reported), meterLimit);
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, this._validity(info))
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
- module.exports = { makeClient, feeCeiling, checkAmount, generateSeed, readBounded, requireSafeTransport, validUntil, vmCallFee, VALIDITY_BLOCKS, Network };
671
+ module.exports = { makeClient, wrapCore, feeCeiling, checkAmount, generateSeed, readBounded, requireSafeTransport, validUntil, VALIDITY_BLOCKS, Network };