@quantovainc/qcore 0.1.25 → 0.1.26

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.
Files changed (3) hide show
  1. package/index.d.ts +19 -0
  2. package/package.json +1 -1
  3. package/shared.js +63 -4
package/index.d.ts CHANGED
@@ -197,6 +197,25 @@ export class Client {
197
197
  meterLimit: number | bigint,
198
198
  maxFeeQuon: string | bigint,
199
199
  ): Promise<TransferResult>;
200
+ assetCall(
201
+ seedHex: string,
202
+ index: number,
203
+ target: string,
204
+ argsHex: string,
205
+ assetIssuer: string,
206
+ amount: string | bigint,
207
+ meterLimit: number | bigint,
208
+ maxFeeQuon: string | bigint,
209
+ ): Promise<TransferResult>;
210
+ payableCall(
211
+ seedHex: string,
212
+ index: number,
213
+ target: string,
214
+ argsHex: string,
215
+ value: string | bigint,
216
+ meterLimit: number | bigint,
217
+ maxFeeQuon: string | bigint,
218
+ ): Promise<TransferResult>;
200
219
  contractNonce(contract: string, signerHex: string): Promise<bigint>;
201
220
  contractScalar(contract: string, slot: number | bigint): Promise<bigint>;
202
221
  callSignedOrder(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quantovainc/qcore",
3
- "version": "0.1.25",
3
+ "version": "0.1.26",
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",
package/shared.js CHANGED
@@ -54,6 +54,20 @@ function accountNonce(nonce) {
54
54
  return n;
55
55
  }
56
56
 
57
+ function gatewayFee(fee) {
58
+ if (typeof fee === 'number' && !Number.isSafeInteger(fee)) {
59
+ throw new Error('the gateway reported a fee outside the safe integer range, a number that large silently rounds and would sign a different fee');
60
+ }
61
+ let f;
62
+ try {
63
+ f = BigInt(fee);
64
+ } catch {
65
+ throw new Error('the gateway reported a fee that is not a whole number');
66
+ }
67
+ if (f < 0n) throw new Error('the gateway reported a negative fee');
68
+ return f;
69
+ }
70
+
57
71
  async function readBounded(res) {
58
72
  if (!res.body || typeof res.body.getReader !== 'function') {
59
73
  const header = res.headers.get('content-length');
@@ -272,7 +286,7 @@ function makeClient(core) {
272
286
  const chainId = this._signingChainId(info);
273
287
  const fee = info && info.fee && info.fee.transfer_quon;
274
288
  if (fee == null) throw new Error('the gateway did not report a transfer fee');
275
- if (BigInt(fee) > ceiling) {
289
+ if (gatewayFee(fee) > ceiling) {
276
290
  throw new Error(`the gateway fee ${fee} is above the maximum you allowed ${maxFeeQuon}, refusing to sign`);
277
291
  }
278
292
  const from = core.address(seedHex, accountIndex(index));
@@ -292,7 +306,7 @@ function makeClient(core) {
292
306
  const chainId = this._signingChainId(info);
293
307
  const fee = info && info.fee && info.fee.transfer_quon;
294
308
  if (fee == null) throw new Error('the gateway did not report a transfer fee');
295
- if (BigInt(fee) > ceiling) {
309
+ if (gatewayFee(fee) > ceiling) {
296
310
  throw new Error(`the gateway fee ${fee} is above the maximum you allowed ${maxFeeQuon}, refusing to sign`);
297
311
  }
298
312
  const from = core.address(seedHex, accountIndex(index));
@@ -311,7 +325,7 @@ function makeClient(core) {
311
325
  const chainId = this._signingChainId(info);
312
326
  const fee = info && info.fee && info.fee.transfer_quon;
313
327
  if (fee == null) throw new Error('the gateway did not report a transfer fee');
314
- if (BigInt(fee) > ceiling) {
328
+ if (gatewayFee(fee) > ceiling) {
315
329
  throw new Error(`the gateway fee ${fee} is above the maximum you allowed ${maxFeeQuon}, refusing to sign`);
316
330
  }
317
331
  const from = core.address(seedHex, accountIndex(index));
@@ -324,6 +338,51 @@ function makeClient(core) {
324
338
  return { signed, outcome };
325
339
  }
326
340
 
341
+ async assetCall(seedHex, index, target, argsHex, assetIssuer, amount, meterLimit, maxFeeQuon) {
342
+ if (!core.valid_address(target)) throw new Error('the target is not a q1 address');
343
+ if (!core.valid_address(assetIssuer)) throw new Error('the asset issuer is not a q1 address');
344
+ checkAmount(amount);
345
+ const ceiling = feeCeiling(maxFeeQuon);
346
+ const info = await this.nodeInfo();
347
+ this._guardMainnet();
348
+ const chainId = this._signingChainId(info);
349
+ const fee = info && info.fee && info.fee.transfer_quon;
350
+ if (fee == null) throw new Error('the gateway did not report a transfer fee');
351
+ if (gatewayFee(fee) > ceiling) {
352
+ throw new Error(`the gateway fee ${fee} is above the maximum you allowed ${maxFeeQuon}, refusing to sign`);
353
+ }
354
+ const from = core.address(seedHex, accountIndex(index));
355
+ const acct = await this.account(from);
356
+ if (!acct || acct.nonce == null) throw new Error('the gateway did not report a nonce');
357
+ const signed = JSON.parse(
358
+ core.signAssetCall(seedHex, accountIndex(index), target, argsHex, assetIssuer, String(amount), accountNonce(acct.nonce), BigInt(meterLimit), String(fee), chainId)
359
+ );
360
+ const outcome = await this.submit(signed.tx_hex);
361
+ return { signed, outcome };
362
+ }
363
+
364
+ async payableCall(seedHex, index, target, argsHex, value, meterLimit, maxFeeQuon) {
365
+ if (!core.valid_address(target)) throw new Error('the target is not a q1 address');
366
+ checkAmount(value);
367
+ const ceiling = feeCeiling(maxFeeQuon);
368
+ const info = await this.nodeInfo();
369
+ this._guardMainnet();
370
+ const chainId = this._signingChainId(info);
371
+ const fee = info && info.fee && info.fee.transfer_quon;
372
+ if (fee == null) throw new Error('the gateway did not report a transfer fee');
373
+ if (gatewayFee(fee) > ceiling) {
374
+ throw new Error(`the gateway fee ${fee} is above the maximum you allowed ${maxFeeQuon}, refusing to sign`);
375
+ }
376
+ const from = core.address(seedHex, accountIndex(index));
377
+ const acct = await this.account(from);
378
+ if (!acct || acct.nonce == null) throw new Error('the gateway did not report a nonce');
379
+ const signed = JSON.parse(
380
+ core.signPayableCall(seedHex, accountIndex(index), target, argsHex, accountNonce(acct.nonce), BigInt(meterLimit), String(fee), String(value), chainId)
381
+ );
382
+ const outcome = await this.submit(signed.tx_hex);
383
+ return { signed, outcome };
384
+ }
385
+
327
386
  async contractNonce(contract, signerHex) {
328
387
  const resp = await this._call('get_storage', core.storageBody(contract));
329
388
  return BigInt(core.storageValue(JSON.stringify(resp), core.nonceSlotKey(signerHex)));
@@ -342,7 +401,7 @@ function makeClient(core) {
342
401
  const chainId = this._signingChainId(info);
343
402
  const fee = info && info.fee && info.fee.transfer_quon;
344
403
  if (fee == null) throw new Error('the gateway did not report a transfer fee');
345
- if (BigInt(fee) > ceiling) {
404
+ if (gatewayFee(fee) > ceiling) {
346
405
  throw new Error(`the gateway fee ${fee} is above the maximum you allowed ${maxFeeQuon}, refusing to sign`);
347
406
  }
348
407
  const signer = core.orderSigner(ownerSeedHex, accountIndex(ownerIndex));