xyqon 0.3.0 → 0.4.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.
Files changed (3) hide show
  1. package/package.json +1 -1
  2. package/src/cli.js +3 -1
  3. package/src/index.js +24 -11
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xyqon",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Friendly wallet CLI and JavaScript client for the XYQON network.",
5
5
  "keywords": [
6
6
  "xyqon",
package/src/cli.js CHANGED
@@ -42,7 +42,7 @@ ${color('bold', 'Usage')}
42
42
  xyqon wallet new --name <NAME> [--out <FILE>]
43
43
  xyqon wallet show [--wallet <FILE>] [--private]
44
44
  xyqon balance [--wallet <FILE>] [--address <PUBLIC_KEY>]
45
- xyqon send --to <PUBLIC_KEY> --amount <AMOUNT> [--wallet <FILE>]
45
+ xyqon send --to <PUBLIC_KEY> --amount <AMOUNT> [--fee <AMOUNT>] [--wallet <FILE>]
46
46
  xyqon coin create --symbol <SYMBOL> --name <NAME> --supply <AMOUNT> [--wallet <FILE>]
47
47
  xyqon coin send --symbol <SYMBOL> --to <PUBLIC_KEY> --amount <AMOUNT> [--wallet <FILE>]
48
48
  xyqon nft mint --collection <SYMBOL> --token-id <ID> --name <NAME> [--image-url <URL>] [--wallet <FILE>]
@@ -152,11 +152,13 @@ async function run() {
152
152
  wallet,
153
153
  recipient: options.to,
154
154
  amount: options.amount,
155
+ fee: options.fee,
155
156
  peers: peersFromOptions(options)
156
157
  });
157
158
 
158
159
  printHero('Transaction Sent');
159
160
  console.log(`${color('bold', 'Amount:')} ${result.transaction.amount} XYQON`);
161
+ console.log(`${color('bold', 'Fee:')} ${result.transaction.fee} XYQON`);
160
162
  console.log(`${color('bold', 'To:')} ${result.transaction.recipient}`);
161
163
  console.log(`${color('bold', 'Transaction ID:')} ${result.transactionId}`);
162
164
  console.log(`${color('dim', 'Checked balance:')} ${result.preflight.balance} XYQON at block ${result.preflight.blockHeight}`);
package/src/index.js CHANGED
@@ -9,6 +9,7 @@ export const DEFAULT_PEERS = [
9
9
  '147.182.138.183:7101'
10
10
  ];
11
11
  const XYQON_EPSILON = 0.00000001;
12
+ export const DEFAULT_XYQON_TRANSACTION_FEE = 0.001;
12
13
 
13
14
  export const DEFAULT_WALLET_PATH = 'xyqon.wallet.json';
14
15
 
@@ -103,8 +104,11 @@ function stringifyAssetOperationForSigning(assetOperation) {
103
104
  throw new Error('unknown asset operation');
104
105
  }
105
106
 
106
- export function transactionPayload(sender, recipient, amount, senderPublicKey, assetOperation = null) {
107
- const base = `${sender}|${recipient}|${Number(amount).toFixed(8)}|${senderPublicKey}`;
107
+ export function transactionPayload(sender, recipient, amount, senderPublicKey, assetOperation = null, fee = 0) {
108
+ let base = `${sender}|${recipient}|${Number(amount).toFixed(8)}|${senderPublicKey}`;
109
+ if (Math.abs(Number(fee)) > XYQON_EPSILON) {
110
+ base = `${base}|fee:${Number(fee).toFixed(8)}`;
111
+ }
108
112
  const serializedAsset = stringifyAssetOperationForSigning(assetOperation);
109
113
  return serializedAsset ? `${base}|${serializedAsset}` : base;
110
114
  }
@@ -174,22 +178,27 @@ export function normalizeTokenAmount(amount, label = 'amount') {
174
178
  return numeric;
175
179
  }
176
180
 
177
- export function createSignedTransaction(wallet, recipient, amount) {
181
+ export function createSignedTransaction(wallet, recipient, amount, fee = DEFAULT_XYQON_TRANSACTION_FEE) {
178
182
  const numericAmount = Number(amount);
179
183
  if (!Number.isFinite(numericAmount) || numericAmount <= 0) {
180
184
  throw new Error('amount must be a positive number');
181
185
  }
186
+ const numericFee = Number(fee);
187
+ if (!Number.isFinite(numericFee) || numericFee < 0) {
188
+ throw new Error('fee must be a non-negative number');
189
+ }
182
190
 
183
191
  const privateKey = hexToBytes(wallet.private_key);
184
192
  const senderPublicKey = assertWalletMatchesPrivateKey(wallet, privateKey);
185
193
 
186
- const payload = transactionPayload(wallet.name, recipient, numericAmount, senderPublicKey);
194
+ const payload = transactionPayload(wallet.name, recipient, numericAmount, senderPublicKey, null, numericFee);
187
195
  const signature = ed25519.sign(new TextEncoder().encode(payload), privateKey);
188
196
 
189
197
  return {
190
198
  sender: wallet.name,
191
199
  recipient,
192
200
  amount: numericAmount,
201
+ fee: numericFee,
193
202
  sender_public_key: senderPublicKey,
194
203
  signature: bytesToHex(signature)
195
204
  };
@@ -402,7 +411,7 @@ export function calculateBalances(chain) {
402
411
  if (transaction.asset_operation) {
403
412
  continue;
404
413
  }
405
- debit(transaction.sender_public_key, transaction.amount);
414
+ debit(transaction.sender_public_key, transaction.amount + (transaction.fee ?? 0));
406
415
  credit(transaction.recipient, transaction.amount);
407
416
  }
408
417
  }
@@ -525,20 +534,24 @@ export async function getBalance(addressOrWallet, seedPeers = DEFAULT_PEERS) {
525
534
  };
526
535
  }
527
536
 
528
- export async function assertSpendableXyqonBalance(wallet, amount, seedPeers = DEFAULT_PEERS) {
537
+ export async function assertSpendableXyqonBalance(wallet, amount, seedPeers = DEFAULT_PEERS, fee = 0) {
529
538
  const numericAmount = Number(amount);
539
+ const numericFee = Number(fee);
530
540
  const { chain, sourcePeer, peers } = await getBestChain(seedPeers);
531
541
  const balances = calculateBalances(chain);
532
542
  const balance = balances.get(wallet.public_key) ?? 0;
543
+ const totalDebit = numericAmount + numericFee;
533
544
 
534
- if (balance + XYQON_EPSILON < numericAmount) {
545
+ if (balance + XYQON_EPSILON < totalDebit) {
535
546
  throw new Error(
536
- `insufficient confirmed XYQON balance; balance is ${balance}, attempted to spend ${numericAmount}`
547
+ `insufficient confirmed XYQON balance; balance is ${balance}, attempted to spend ${numericAmount} plus fee ${numericFee}`
537
548
  );
538
549
  }
539
550
 
540
551
  return {
541
552
  balance,
553
+ fee: numericFee,
554
+ totalDebit,
542
555
  blockHeight: chain.chain.at(-1)?.index ?? 0,
543
556
  sourcePeer,
544
557
  peers
@@ -624,9 +637,9 @@ export async function broadcastTransaction(transaction, seedPeers = DEFAULT_PEER
624
637
  };
625
638
  }
626
639
 
627
- export async function sendTransaction({ wallet, recipient, amount, peers = DEFAULT_PEERS }) {
628
- const transaction = createSignedTransaction(wallet, recipient, amount);
629
- const preflight = await assertSpendableXyqonBalance(wallet, transaction.amount, peers);
640
+ export async function sendTransaction({ wallet, recipient, amount, fee = DEFAULT_XYQON_TRANSACTION_FEE, peers = DEFAULT_PEERS }) {
641
+ const transaction = createSignedTransaction(wallet, recipient, amount, fee);
642
+ const preflight = await assertSpendableXyqonBalance(wallet, transaction.amount, peers, transaction.fee);
630
643
  return {
631
644
  transaction,
632
645
  preflight,