mainnet-js 3.0.0-next.0 → 3.0.0-next.2
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/dist/index.html +1 -1
- package/dist/{mainnet-3.0.0-next.0.js → mainnet-3.0.0-next.2.js} +21 -41
- package/dist/module/cache/walletCache.d.ts +10 -4
- package/dist/module/cache/walletCache.d.ts.map +1 -1
- package/dist/module/cache/walletCache.js +12 -13
- package/dist/module/cache/walletCache.js.map +1 -1
- package/dist/module/chain.d.ts +1 -1
- package/dist/module/chain.js +1 -1
- package/dist/module/chain.js.map +1 -1
- package/dist/module/constant.d.ts +1 -1
- package/dist/module/constant.d.ts.map +1 -1
- package/dist/module/constant.js +1 -1
- package/dist/module/constant.js.map +1 -1
- package/dist/module/enum.d.ts +1 -7
- package/dist/module/enum.d.ts.map +1 -1
- package/dist/module/enum.js +0 -6
- package/dist/module/enum.js.map +1 -1
- package/dist/module/history/getHistory.d.ts.map +1 -1
- package/dist/module/history/getHistory.js +17 -47
- package/dist/module/history/getHistory.js.map +1 -1
- package/dist/module/history/interface.d.ts +1 -1
- package/dist/module/history/interface.d.ts.map +1 -1
- package/dist/module/interface.d.ts +6 -5
- package/dist/module/interface.d.ts.map +1 -1
- package/dist/module/interface.js.map +1 -1
- package/dist/module/network/ElectrumNetworkProvider.d.ts.map +1 -1
- package/dist/module/network/ElectrumNetworkProvider.js +2 -4
- package/dist/module/network/ElectrumNetworkProvider.js.map +1 -1
- package/dist/module/network/getRelayFeeCache.js +2 -2
- package/dist/module/network/getRelayFeeCache.js.map +1 -1
- package/dist/module/network/interface.d.ts +2 -2
- package/dist/module/network/interface.d.ts.map +1 -1
- package/dist/module/rate/ExchangeRate.d.ts +2 -1
- package/dist/module/rate/ExchangeRate.d.ts.map +1 -1
- package/dist/module/rate/ExchangeRate.js +4 -1
- package/dist/module/rate/ExchangeRate.js.map +1 -1
- package/dist/module/transaction/Wif.d.ts +9 -9
- package/dist/module/transaction/Wif.d.ts.map +1 -1
- package/dist/module/transaction/Wif.js +35 -35
- package/dist/module/transaction/Wif.js.map +1 -1
- package/dist/module/transaction/allocateFee.d.ts +3 -3
- package/dist/module/transaction/allocateFee.d.ts.map +1 -1
- package/dist/module/transaction/allocateFee.js +5 -6
- package/dist/module/transaction/allocateFee.js.map +1 -1
- package/dist/module/util/amountInSatoshi.d.ts +1 -1
- package/dist/module/util/amountInSatoshi.d.ts.map +1 -1
- package/dist/module/util/amountInSatoshi.js +3 -9
- package/dist/module/util/amountInSatoshi.js.map +1 -1
- package/dist/module/util/asSendRequestObject.d.ts.map +1 -1
- package/dist/module/util/asSendRequestObject.js +10 -7
- package/dist/module/util/asSendRequestObject.js.map +1 -1
- package/dist/module/util/convert.d.ts +3 -0
- package/dist/module/util/convert.d.ts.map +1 -1
- package/dist/module/util/convert.js +12 -0
- package/dist/module/util/convert.js.map +1 -1
- package/dist/module/util/index.d.ts +2 -3
- package/dist/module/util/index.d.ts.map +1 -1
- package/dist/module/util/index.js +2 -3
- package/dist/module/util/index.js.map +1 -1
- package/dist/module/util/satoshiToAmount.d.ts +1 -1
- package/dist/module/util/satoshiToAmount.d.ts.map +1 -1
- package/dist/module/util/satoshiToAmount.js +3 -9
- package/dist/module/util/satoshiToAmount.js.map +1 -1
- package/dist/module/util/sumSendRequestAmounts.d.ts.map +1 -1
- package/dist/module/util/sumSendRequestAmounts.js +3 -4
- package/dist/module/util/sumSendRequestAmounts.js.map +1 -1
- package/dist/module/util/sumUtxoValue.d.ts +1 -1
- package/dist/module/util/sumUtxoValue.js +3 -3
- package/dist/module/util/sumUtxoValue.js.map +1 -1
- package/dist/module/wallet/Base.d.ts +28 -30
- package/dist/module/wallet/Base.d.ts.map +1 -1
- package/dist/module/wallet/Base.js +82 -119
- package/dist/module/wallet/Base.js.map +1 -1
- package/dist/module/wallet/HDWallet.d.ts +1 -1
- package/dist/module/wallet/Util.js +1 -1
- package/dist/module/wallet/Util.js.map +1 -1
- package/dist/module/wallet/Wif.d.ts +1 -1
- package/dist/module/wallet/interface.d.ts +2 -3
- package/dist/module/wallet/interface.d.ts.map +1 -1
- package/dist/module/wallet/model.d.ts +53 -41
- package/dist/module/wallet/model.d.ts.map +1 -1
- package/dist/module/wallet/model.js +14 -22
- package/dist/module/wallet/model.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/cache/walletCache.ts +23 -36
- package/src/chain.ts +1 -1
- package/src/constant.ts +1 -1
- package/src/enum.ts +0 -6
- package/src/history/getHistory.test.ts +20 -34
- package/src/history/getHistory.ts +17 -49
- package/src/history/interface.ts +1 -1
- package/src/interface.ts +6 -5
- package/src/network/Connection.test.ts +3 -3
- package/src/network/ElectrumNetworkProvider.ts +2 -4
- package/src/network/Rpc.test.ts +2 -3
- package/src/network/getRelayFeeCache.ts +2 -2
- package/src/network/interface.ts +2 -2
- package/src/rate/ExchangeRate.test.ts +2 -44
- package/src/rate/ExchangeRate.ts +5 -2
- package/src/transaction/Wif.ts +50 -45
- package/src/transaction/allocateFee.test.ts +110 -131
- package/src/transaction/allocateFee.ts +14 -15
- package/src/util/amountInSatoshi.test.ts +1 -9
- package/src/util/amountInSatoshi.ts +6 -10
- package/src/util/asSendRequestObject.ts +12 -7
- package/src/util/convert.ts +18 -0
- package/src/util/index.ts +2 -7
- package/src/util/satoshiToAmount.test.ts +1 -1
- package/src/util/satoshiToAmount.ts +4 -10
- package/src/util/sumSendRequestAmounts.ts +3 -4
- package/src/util/sumUtxoValue.ts +4 -4
- package/src/wallet/Base.ts +95 -164
- package/src/wallet/Cashtokens.test.headless.js +228 -173
- package/src/wallet/Cashtokens.test.ts +506 -406
- package/src/wallet/HDWallet.test.ts +223 -68
- package/src/wallet/Util.ts +1 -1
- package/src/wallet/Wif.test.ts +108 -133
- package/src/wallet/interface.ts +2 -3
- package/src/wallet/model.test.ts +2 -5
- package/src/wallet/model.ts +64 -71
- package/dist/module/util/balanceObjectFromSatoshi.d.ts +0 -8
- package/dist/module/util/balanceObjectFromSatoshi.d.ts.map +0 -1
- package/dist/module/util/balanceObjectFromSatoshi.js +0 -35
- package/dist/module/util/balanceObjectFromSatoshi.js.map +0 -1
- package/src/util/balanceObjectFromSatoshi.test.ts +0 -58
- package/src/util/balanceObjectFromSatoshi.ts +0 -52
package/src/wallet/Base.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { binToHex, CashAddressNetworkPrefix } from "@bitauth/libauth";
|
|
2
|
-
import {
|
|
2
|
+
import { WalletCache } from "../cache/walletCache.js";
|
|
3
3
|
import StorageProvider from "../db/StorageProvider.js";
|
|
4
|
-
import { NetworkType, prefixFromNetworkMap
|
|
4
|
+
import { NetworkType, prefixFromNetworkMap } from "../enum.js";
|
|
5
5
|
import { HexHeaderI, NFTCapability, TxI, Utxo, UtxoId } from "../interface.js";
|
|
6
6
|
import {
|
|
7
7
|
SignedMessageResponseI,
|
|
@@ -18,21 +18,14 @@ import {
|
|
|
18
18
|
getSuitableUtxos,
|
|
19
19
|
placeholderPrivateKeyBin,
|
|
20
20
|
} from "../transaction/Wif.js";
|
|
21
|
-
import {
|
|
22
|
-
balanceFromSatoshi,
|
|
23
|
-
BalanceResponse,
|
|
24
|
-
balanceResponseFromSatoshi,
|
|
25
|
-
} from "../util/balanceObjectFromSatoshi.js";
|
|
26
21
|
import { checkUtxos } from "../util/checkUtxos.js";
|
|
27
22
|
import {
|
|
28
|
-
amountInSatoshi,
|
|
29
23
|
asSendRequestObject,
|
|
30
24
|
getRuntimePlatform,
|
|
31
25
|
sumTokenAmounts,
|
|
32
26
|
sumUtxoValue,
|
|
33
27
|
toTokenaddr,
|
|
34
28
|
} from "../util/index.js";
|
|
35
|
-
import { sanitizeUnit } from "../util/sanitizeUnit.js";
|
|
36
29
|
import { sumSendRequestAmounts } from "../util/sumSendRequestAmounts.js";
|
|
37
30
|
import { FeePaidByEnum, WalletTypeEnum } from "./enum.js";
|
|
38
31
|
import {
|
|
@@ -70,7 +63,7 @@ export const placeholderTokenAddr =
|
|
|
70
63
|
export class BaseWallet implements WalletI {
|
|
71
64
|
public static StorageProvider?: typeof StorageProvider;
|
|
72
65
|
|
|
73
|
-
readonly walletCache?:
|
|
66
|
+
readonly walletCache?: WalletCache;
|
|
74
67
|
readonly provider: ElectrumNetworkProvider;
|
|
75
68
|
readonly network: NetworkType;
|
|
76
69
|
readonly walletType: WalletTypeEnum;
|
|
@@ -412,28 +405,13 @@ export class BaseWallet implements WalletI {
|
|
|
412
405
|
throw Error("getUtxos not implemented in BaseWallet");
|
|
413
406
|
}
|
|
414
407
|
|
|
415
|
-
// gets wallet balance in sats
|
|
416
|
-
public async getBalance(
|
|
417
|
-
|
|
418
|
-
priceCache = true
|
|
419
|
-
): Promise<BalanceResponse | number> {
|
|
420
|
-
if (rawUnit) {
|
|
421
|
-
const unit = sanitizeUnit(rawUnit);
|
|
422
|
-
return await balanceFromSatoshi(
|
|
423
|
-
await this.getBalanceFromProvider(),
|
|
424
|
-
unit,
|
|
425
|
-
priceCache
|
|
426
|
-
);
|
|
427
|
-
} else {
|
|
428
|
-
return await balanceResponseFromSatoshi(
|
|
429
|
-
await this.getBalanceFromProvider(),
|
|
430
|
-
priceCache
|
|
431
|
-
);
|
|
432
|
-
}
|
|
408
|
+
// gets wallet balance in sats
|
|
409
|
+
public async getBalance(): Promise<bigint> {
|
|
410
|
+
return this.getBalanceFromProvider();
|
|
433
411
|
}
|
|
434
412
|
|
|
435
413
|
// Gets balance by summing value in all utxos in stats
|
|
436
|
-
public async getBalanceFromUtxos(): Promise<
|
|
414
|
+
public async getBalanceFromUtxos(): Promise<bigint> {
|
|
437
415
|
const utxos = (await this.getUtxos()).filter(
|
|
438
416
|
(val) => val.token === undefined
|
|
439
417
|
);
|
|
@@ -441,7 +419,7 @@ export class BaseWallet implements WalletI {
|
|
|
441
419
|
}
|
|
442
420
|
|
|
443
421
|
// Gets balance from fulcrum
|
|
444
|
-
public async getBalanceFromProvider(): Promise<
|
|
422
|
+
public async getBalanceFromProvider(): Promise<bigint> {
|
|
445
423
|
// Fulcrum reports balance of all utxos, including tokens, which is undesirable
|
|
446
424
|
// // TODO not sure why getting the balance from a provider doesn't work
|
|
447
425
|
// if (this._slpAware || this._slpSemiAware) {
|
|
@@ -488,82 +466,42 @@ export class BaseWallet implements WalletI {
|
|
|
488
466
|
// sets up a callback to be called upon wallet's balance change
|
|
489
467
|
// can be cancelled by calling the function returned from this one
|
|
490
468
|
public async watchBalance(
|
|
491
|
-
callback: (balance:
|
|
469
|
+
callback: (balance: bigint) => void
|
|
492
470
|
): Promise<CancelFn> {
|
|
493
471
|
return this.provider.watchAddressStatus(
|
|
494
472
|
this.getDepositAddress(),
|
|
495
473
|
async (_status: string) => {
|
|
496
|
-
const balance =
|
|
497
|
-
callback(balance);
|
|
498
|
-
}
|
|
499
|
-
);
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
// sets up a callback to be called upon wallet's BCH or USD balance change
|
|
503
|
-
// if BCH balance does not change, the callback will be triggered every
|
|
504
|
-
// @param `usdPriceRefreshInterval` milliseconds by polling for new BCH USD price
|
|
505
|
-
// Since we want to be most sensitive to usd value change, we do not use the cached exchange rates
|
|
506
|
-
// can be cancelled by calling the function returned from this one
|
|
507
|
-
public async watchBalanceUsd(
|
|
508
|
-
callback: (balance: BalanceResponse) => void,
|
|
509
|
-
usdPriceRefreshInterval = 30000
|
|
510
|
-
): Promise<CancelFn> {
|
|
511
|
-
let usdPrice = -1;
|
|
512
|
-
|
|
513
|
-
const _callback = async () => {
|
|
514
|
-
const balance = (await this.getBalance(
|
|
515
|
-
undefined,
|
|
516
|
-
false
|
|
517
|
-
)) as BalanceResponse;
|
|
518
|
-
if (usdPrice !== balance.usd!) {
|
|
519
|
-
usdPrice = balance.usd;
|
|
474
|
+
const balance = await this.getBalanceFromProvider();
|
|
520
475
|
callback(balance);
|
|
521
476
|
}
|
|
522
|
-
};
|
|
523
|
-
|
|
524
|
-
const watchCancel = await this.provider.watchAddressStatus(
|
|
525
|
-
this.getDepositAddress(),
|
|
526
|
-
_callback
|
|
527
477
|
);
|
|
528
|
-
const interval = setInterval(_callback, usdPriceRefreshInterval);
|
|
529
|
-
|
|
530
|
-
return async () => {
|
|
531
|
-
await watchCancel?.();
|
|
532
|
-
clearInterval(interval);
|
|
533
|
-
};
|
|
534
478
|
}
|
|
535
479
|
|
|
536
480
|
// waits for address balance to be greater than or equal to the target value
|
|
537
481
|
// this call halts the execution
|
|
538
|
-
public async waitForBalance(
|
|
539
|
-
value: number,
|
|
540
|
-
rawUnit: UnitEnum = UnitEnum.BCH
|
|
541
|
-
): Promise<BalanceResponse> {
|
|
482
|
+
public async waitForBalance(value: bigint): Promise<bigint> {
|
|
542
483
|
return new Promise(async (resolve) => {
|
|
543
484
|
let watchCancel: CancelFn;
|
|
544
|
-
watchCancel = await this.watchBalance(
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
await watchCancel?.();
|
|
549
|
-
resolve(balance);
|
|
550
|
-
}
|
|
485
|
+
watchCancel = await this.watchBalance(async (balance: bigint) => {
|
|
486
|
+
if (balance >= value) {
|
|
487
|
+
await watchCancel?.();
|
|
488
|
+
resolve(balance);
|
|
551
489
|
}
|
|
552
|
-
);
|
|
490
|
+
});
|
|
553
491
|
});
|
|
554
492
|
}
|
|
555
493
|
|
|
556
494
|
// sets up a callback to be called upon wallet's token balance change
|
|
557
495
|
// can be cancelled by calling the function returned from this one
|
|
558
496
|
public async watchTokenBalance(
|
|
559
|
-
|
|
497
|
+
category: string,
|
|
560
498
|
callback: (balance: bigint) => void
|
|
561
499
|
): Promise<CancelFn> {
|
|
562
500
|
let previous: bigint | undefined = undefined;
|
|
563
501
|
return await this.provider.watchAddressStatus(
|
|
564
502
|
this.getDepositAddress(),
|
|
565
503
|
async (_status: string) => {
|
|
566
|
-
const balance = await this.getTokenBalance(
|
|
504
|
+
const balance = await this.getTokenBalance(category);
|
|
567
505
|
if (previous != balance) {
|
|
568
506
|
callback(balance);
|
|
569
507
|
}
|
|
@@ -575,13 +513,13 @@ export class BaseWallet implements WalletI {
|
|
|
575
513
|
// waits for address token balance to be greater than or equal to the target amount
|
|
576
514
|
// this call halts the execution
|
|
577
515
|
public async waitForTokenBalance(
|
|
578
|
-
|
|
516
|
+
category: string,
|
|
579
517
|
amount: bigint
|
|
580
518
|
): Promise<bigint> {
|
|
581
519
|
return new Promise(async (resolve) => {
|
|
582
520
|
let watchCancel: CancelFn;
|
|
583
521
|
watchCancel = await this.watchTokenBalance(
|
|
584
|
-
|
|
522
|
+
category,
|
|
585
523
|
async (balance: bigint) => {
|
|
586
524
|
if (balance >= amount) {
|
|
587
525
|
await watchCancel?.();
|
|
@@ -601,7 +539,7 @@ export class BaseWallet implements WalletI {
|
|
|
601
539
|
outputCount: 1,
|
|
602
540
|
options: {},
|
|
603
541
|
}
|
|
604
|
-
): Promise<{ value:
|
|
542
|
+
): Promise<{ value: bigint; utxos: Utxo[] }> {
|
|
605
543
|
if (params.options && params.options.slpSemiAware) {
|
|
606
544
|
this._slpSemiAware = true;
|
|
607
545
|
}
|
|
@@ -632,8 +570,7 @@ export class BaseWallet implements WalletI {
|
|
|
632
570
|
// simulate outputs using the sender's address
|
|
633
571
|
const sendRequest = new SendRequest({
|
|
634
572
|
cashaddr: placeholderCashAddr,
|
|
635
|
-
value:
|
|
636
|
-
unit: "sat",
|
|
573
|
+
value: 100n,
|
|
637
574
|
});
|
|
638
575
|
const sendRequests = Array(params.outputCount)
|
|
639
576
|
.fill(0)
|
|
@@ -657,8 +594,8 @@ export class BaseWallet implements WalletI {
|
|
|
657
594
|
const spendableAmount = sumUtxoValue(fundingUtxos);
|
|
658
595
|
|
|
659
596
|
let result = spendableAmount - fee;
|
|
660
|
-
if (result <
|
|
661
|
-
result =
|
|
597
|
+
if (result < 0n) {
|
|
598
|
+
result = 0n;
|
|
662
599
|
}
|
|
663
600
|
|
|
664
601
|
return { value: result, utxos: fundingUtxos };
|
|
@@ -672,10 +609,10 @@ export class BaseWallet implements WalletI {
|
|
|
672
609
|
outputCount: 1,
|
|
673
610
|
options: {},
|
|
674
611
|
}
|
|
675
|
-
): Promise<
|
|
612
|
+
): Promise<bigint> {
|
|
676
613
|
const { value: result } = await this._getMaxAmountToSend(params);
|
|
677
614
|
|
|
678
|
-
return
|
|
615
|
+
return result;
|
|
679
616
|
}
|
|
680
617
|
|
|
681
618
|
/**
|
|
@@ -695,11 +632,11 @@ export class BaseWallet implements WalletI {
|
|
|
695
632
|
| SendRequestArray[],
|
|
696
633
|
options?: SendRequestOptionsI
|
|
697
634
|
): Promise<SendResponse> {
|
|
698
|
-
const { encodedTransaction,
|
|
635
|
+
const { encodedTransaction, categories, sourceOutputs } =
|
|
699
636
|
await this.encodeTransaction(requests, undefined, options);
|
|
700
637
|
|
|
701
638
|
const resp = new SendResponse({});
|
|
702
|
-
resp.
|
|
639
|
+
resp.categories = categories;
|
|
703
640
|
|
|
704
641
|
if (options?.buildUnsigned !== true) {
|
|
705
642
|
const txId = await this.submitTransaction(
|
|
@@ -715,7 +652,7 @@ export class BaseWallet implements WalletI {
|
|
|
715
652
|
options?.queryBalance === undefined ||
|
|
716
653
|
options?.queryBalance === true
|
|
717
654
|
) {
|
|
718
|
-
resp.balance =
|
|
655
|
+
resp.balance = await this.getBalance();
|
|
719
656
|
}
|
|
720
657
|
} else {
|
|
721
658
|
resp.unsignedTransaction = binToHex(encodedTransaction);
|
|
@@ -770,14 +707,13 @@ export class BaseWallet implements WalletI {
|
|
|
770
707
|
const sendRequest = new SendRequest({
|
|
771
708
|
cashaddr: cashaddr,
|
|
772
709
|
value: maxSpendableAmount,
|
|
773
|
-
unit: "sat",
|
|
774
710
|
});
|
|
775
711
|
|
|
776
|
-
const { encodedTransaction,
|
|
712
|
+
const { encodedTransaction, categories, sourceOutputs } =
|
|
777
713
|
await this.encodeTransaction([sendRequest], true, options, privateKey);
|
|
778
714
|
|
|
779
715
|
const resp = new SendResponse({});
|
|
780
|
-
resp.
|
|
716
|
+
resp.categories = categories;
|
|
781
717
|
|
|
782
718
|
if (options?.buildUnsigned !== true) {
|
|
783
719
|
const txId = await this.submitTransaction(
|
|
@@ -793,7 +729,7 @@ export class BaseWallet implements WalletI {
|
|
|
793
729
|
options?.queryBalance === undefined ||
|
|
794
730
|
options?.queryBalance === true
|
|
795
731
|
) {
|
|
796
|
-
resp.balance =
|
|
732
|
+
resp.balance = await this.getBalance();
|
|
797
733
|
}
|
|
798
734
|
} else {
|
|
799
735
|
resp.unsignedTransaction = binToHex(encodedTransaction);
|
|
@@ -877,19 +813,19 @@ export class BaseWallet implements WalletI {
|
|
|
877
813
|
const allTokenOutputs = outputs.filter(
|
|
878
814
|
(val) => val instanceof TokenSendRequest
|
|
879
815
|
) as TokenSendRequest[];
|
|
880
|
-
const
|
|
881
|
-
.map((val) => val.
|
|
816
|
+
const categories = allTokenOutputs
|
|
817
|
+
.map((val) => val.category)
|
|
882
818
|
.filter((val, idx, arr) => arr.indexOf(val) === idx);
|
|
883
|
-
for (let
|
|
819
|
+
for (let category of categories) {
|
|
884
820
|
const tokenInputs = allTokenInputs.filter(
|
|
885
|
-
(val) => val.token?.
|
|
821
|
+
(val) => val.token?.category === category
|
|
886
822
|
);
|
|
887
823
|
const inputAmountSum = tokenInputs.reduce(
|
|
888
824
|
(prev, cur) => prev + cur.token!.amount,
|
|
889
825
|
0n
|
|
890
826
|
);
|
|
891
827
|
const tokenOutputs = allTokenOutputs.filter(
|
|
892
|
-
(val) => val.
|
|
828
|
+
(val) => val.category === category
|
|
893
829
|
);
|
|
894
830
|
const outputAmountSum = tokenOutputs.reduce(
|
|
895
831
|
(prev, cur) => prev + cur.amount,
|
|
@@ -931,9 +867,8 @@ export class BaseWallet implements WalletI {
|
|
|
931
867
|
new TokenSendRequest({
|
|
932
868
|
cashaddr: toTokenaddr(this.getChangeAddress()),
|
|
933
869
|
amount: change,
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
capability: tokenOutputs[0].capability,
|
|
870
|
+
category: category,
|
|
871
|
+
nft: tokenOutputs[0].nft,
|
|
937
872
|
value: tokenOutputs[0].value,
|
|
938
873
|
})
|
|
939
874
|
);
|
|
@@ -964,7 +899,7 @@ export class BaseWallet implements WalletI {
|
|
|
964
899
|
|
|
965
900
|
const fundingUtxos = await getSuitableUtxos(
|
|
966
901
|
utxos,
|
|
967
|
-
|
|
902
|
+
spendAmount + feeEstimate,
|
|
968
903
|
bestHeight,
|
|
969
904
|
feePaidBy,
|
|
970
905
|
sendRequests,
|
|
@@ -998,16 +933,16 @@ export class BaseWallet implements WalletI {
|
|
|
998
933
|
}
|
|
999
934
|
);
|
|
1000
935
|
|
|
1001
|
-
const
|
|
936
|
+
const categories = [
|
|
1002
937
|
...fundingUtxos
|
|
1003
|
-
.filter((val) => val.token?.
|
|
1004
|
-
.map((val) => val.token!.
|
|
938
|
+
.filter((val) => val.token?.category)
|
|
939
|
+
.map((val) => val.token!.category),
|
|
1005
940
|
...sendRequests
|
|
1006
941
|
.filter((val) => val instanceof TokenSendRequest)
|
|
1007
|
-
.map((val) => (val as TokenSendRequest).
|
|
942
|
+
.map((val) => (val as TokenSendRequest).category),
|
|
1008
943
|
].filter((value, index, array) => array.indexOf(value) === index);
|
|
1009
944
|
|
|
1010
|
-
return { encodedTransaction,
|
|
945
|
+
return { encodedTransaction, categories, sourceOutputs };
|
|
1011
946
|
}
|
|
1012
947
|
|
|
1013
948
|
// Submit a raw transaction
|
|
@@ -1194,10 +1129,9 @@ export class BaseWallet implements WalletI {
|
|
|
1194
1129
|
const genesisSendRequest = new TokenSendRequest({
|
|
1195
1130
|
cashaddr: genesisRequest.cashaddr || this.getTokenDepositAddress(),
|
|
1196
1131
|
amount: genesisRequest.amount,
|
|
1197
|
-
value: genesisRequest.value ||
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
tokenId: genesisInputs[0].txid,
|
|
1132
|
+
value: genesisRequest.value || 1000n,
|
|
1133
|
+
nft: genesisRequest.nft,
|
|
1134
|
+
category: genesisInputs[0].txid,
|
|
1201
1135
|
});
|
|
1202
1136
|
|
|
1203
1137
|
return this.send([genesisSendRequest, ...(sendRequests as any)], {
|
|
@@ -1213,7 +1147,7 @@ export class BaseWallet implements WalletI {
|
|
|
1213
1147
|
/**
|
|
1214
1148
|
* Mint new NFT cashtokens using an existing minting token
|
|
1215
1149
|
* Refer to spec https://github.com/bitjson/cashtokens
|
|
1216
|
-
* @param {string}
|
|
1150
|
+
* @param {string} category category of an NFT to mint
|
|
1217
1151
|
* @param {TokenMintRequest | TokenMintRequest[]} mintRequests mint requests with new token properties and recipients
|
|
1218
1152
|
* @param {NFTCapability?} mintRequest.capability capability of new NFT
|
|
1219
1153
|
* @param {string?} mintRequest.commitment NFT commitment message
|
|
@@ -1223,13 +1157,13 @@ export class BaseWallet implements WalletI {
|
|
|
1223
1157
|
* @param {SendRequestOptionsI} options Options of the send requests
|
|
1224
1158
|
*/
|
|
1225
1159
|
public async tokenMint(
|
|
1226
|
-
|
|
1160
|
+
category: string,
|
|
1227
1161
|
mintRequests: TokenMintRequest | Array<TokenMintRequest>,
|
|
1228
1162
|
deductTokenAmount: boolean = false,
|
|
1229
1163
|
options?: SendRequestOptionsI
|
|
1230
1164
|
): Promise<SendResponse> {
|
|
1231
|
-
if (
|
|
1232
|
-
throw Error(`Invalid
|
|
1165
|
+
if (category?.length !== 64) {
|
|
1166
|
+
throw Error(`Invalid category supplied: ${category}`);
|
|
1233
1167
|
}
|
|
1234
1168
|
|
|
1235
1169
|
if (!Array.isArray(mintRequests)) {
|
|
@@ -1239,12 +1173,12 @@ export class BaseWallet implements WalletI {
|
|
|
1239
1173
|
const utxos = await this.getUtxos();
|
|
1240
1174
|
const nftUtxos = utxos.filter(
|
|
1241
1175
|
(val) =>
|
|
1242
|
-
val.token?.
|
|
1243
|
-
val.token?.capability === NFTCapability.minting
|
|
1176
|
+
val.token?.category === category &&
|
|
1177
|
+
val.token?.nft?.capability === NFTCapability.minting
|
|
1244
1178
|
);
|
|
1245
1179
|
if (!nftUtxos.length) {
|
|
1246
1180
|
throw new Error(
|
|
1247
|
-
"You do not have any token UTXOs with minting capability for specified
|
|
1181
|
+
"You do not have any token UTXOs with minting capability for specified category"
|
|
1248
1182
|
);
|
|
1249
1183
|
}
|
|
1250
1184
|
const newAmount =
|
|
@@ -1254,9 +1188,8 @@ export class BaseWallet implements WalletI {
|
|
|
1254
1188
|
const safeNewAmount = newAmount < 0n ? 0n : newAmount;
|
|
1255
1189
|
const mintingInput = new TokenSendRequest({
|
|
1256
1190
|
cashaddr: toTokenaddr(nftUtxos[0].address),
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
commitment: nftUtxos[0].token!.commitment,
|
|
1191
|
+
category: category,
|
|
1192
|
+
nft: nftUtxos[0].token?.nft,
|
|
1260
1193
|
amount: safeNewAmount,
|
|
1261
1194
|
value: nftUtxos[0].satoshis,
|
|
1262
1195
|
});
|
|
@@ -1267,11 +1200,10 @@ export class BaseWallet implements WalletI {
|
|
|
1267
1200
|
(val) =>
|
|
1268
1201
|
new TokenSendRequest({
|
|
1269
1202
|
cashaddr: val.cashaddr || this.getTokenDepositAddress(),
|
|
1270
|
-
amount:
|
|
1271
|
-
|
|
1203
|
+
amount: 0n,
|
|
1204
|
+
category: category,
|
|
1272
1205
|
value: val.value,
|
|
1273
|
-
|
|
1274
|
-
commitment: val.commitment,
|
|
1206
|
+
nft: val.nft,
|
|
1275
1207
|
})
|
|
1276
1208
|
),
|
|
1277
1209
|
],
|
|
@@ -1293,7 +1225,7 @@ export class BaseWallet implements WalletI {
|
|
|
1293
1225
|
* * FTs' amount is reduced by the amount specified, if 0 FT amount is left and no NFT present, the token is "destroyed"
|
|
1294
1226
|
*
|
|
1295
1227
|
* Refer to spec https://github.com/bitjson/cashtokens
|
|
1296
|
-
* @param {string} burnRequest.
|
|
1228
|
+
* @param {string} burnRequest.category category of a token to burn
|
|
1297
1229
|
* @param {NFTCapability} burnRequest.capability capability of the NFT token to select, optional
|
|
1298
1230
|
* @param {string?} burnRequest.commitment commitment of the NFT token to select, optional
|
|
1299
1231
|
* @param {number?} burnRequest.amount amount of fungible tokens to burn, optional
|
|
@@ -1306,16 +1238,16 @@ export class BaseWallet implements WalletI {
|
|
|
1306
1238
|
message?: string,
|
|
1307
1239
|
options?: SendRequestOptionsI
|
|
1308
1240
|
): Promise<SendResponse> {
|
|
1309
|
-
if (burnRequest.
|
|
1310
|
-
throw Error(`Invalid
|
|
1241
|
+
if (burnRequest.category?.length !== 64) {
|
|
1242
|
+
throw Error(`Invalid category supplied: ${burnRequest.category}`);
|
|
1311
1243
|
}
|
|
1312
1244
|
|
|
1313
1245
|
const utxos = await this.getUtxos();
|
|
1314
1246
|
const tokenUtxos = utxos.filter(
|
|
1315
1247
|
(val) =>
|
|
1316
|
-
val.token?.
|
|
1317
|
-
val.token?.capability === burnRequest.capability &&
|
|
1318
|
-
val.token?.commitment === burnRequest.commitment
|
|
1248
|
+
val.token?.category === burnRequest.category &&
|
|
1249
|
+
val.token?.nft?.capability === burnRequest.nft?.capability &&
|
|
1250
|
+
val.token?.nft?.commitment === burnRequest.nft?.commitment
|
|
1319
1251
|
);
|
|
1320
1252
|
|
|
1321
1253
|
if (!tokenUtxos.length) {
|
|
@@ -1329,7 +1261,7 @@ export class BaseWallet implements WalletI {
|
|
|
1329
1261
|
let fungibleBurnAmount =
|
|
1330
1262
|
burnRequest.amount && burnRequest.amount > 0 ? burnRequest.amount! : 0n;
|
|
1331
1263
|
fungibleBurnAmount = BigInt(fungibleBurnAmount);
|
|
1332
|
-
const hasNFT = burnRequest.
|
|
1264
|
+
const hasNFT = burnRequest.nft !== undefined;
|
|
1333
1265
|
|
|
1334
1266
|
let utxoIds: Utxo[] = [];
|
|
1335
1267
|
let changeSendRequests: TokenSendRequest[];
|
|
@@ -1356,9 +1288,8 @@ export class BaseWallet implements WalletI {
|
|
|
1356
1288
|
new TokenSendRequest({
|
|
1357
1289
|
cashaddr:
|
|
1358
1290
|
burnRequest.cashaddr || toTokenaddr(this.getChangeAddress()),
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
commitment: burnRequest.commitment,
|
|
1291
|
+
category: burnRequest.category,
|
|
1292
|
+
nft: burnRequest.nft,
|
|
1362
1293
|
amount: safeNewAmount,
|
|
1363
1294
|
value: tokenUtxos[0].satoshis,
|
|
1364
1295
|
}),
|
|
@@ -1387,9 +1318,9 @@ export class BaseWallet implements WalletI {
|
|
|
1387
1318
|
new TokenSendRequest({
|
|
1388
1319
|
cashaddr:
|
|
1389
1320
|
burnRequest.cashaddr || toTokenaddr(this.getChangeAddress()),
|
|
1390
|
-
|
|
1321
|
+
category: burnRequest.category,
|
|
1391
1322
|
amount: safeNewAmount,
|
|
1392
|
-
value: tokenUtxos.reduce((a, c) => a + c.satoshis,
|
|
1323
|
+
value: tokenUtxos.reduce((a, c) => a + c.satoshis, 0n),
|
|
1393
1324
|
}),
|
|
1394
1325
|
];
|
|
1395
1326
|
}
|
|
@@ -1407,78 +1338,78 @@ export class BaseWallet implements WalletI {
|
|
|
1407
1338
|
|
|
1408
1339
|
/**
|
|
1409
1340
|
* getTokenUtxos Get unspent token outputs for the wallet
|
|
1410
|
-
* will return utxos only for the specified token if `
|
|
1411
|
-
* @param {string?}
|
|
1341
|
+
* will return utxos only for the specified token if `category` provided
|
|
1342
|
+
* @param {string?} category category to filter utxos by, if not set will return utxos from all tokens
|
|
1412
1343
|
* @returns {Utxo[]} token utxos
|
|
1413
1344
|
*/
|
|
1414
|
-
public async getTokenUtxos(
|
|
1345
|
+
public async getTokenUtxos(category?: string): Promise<Utxo[]> {
|
|
1415
1346
|
const utxos = await this.getUtxos();
|
|
1416
1347
|
return utxos.filter((val) =>
|
|
1417
|
-
|
|
1348
|
+
category ? val.token?.category === category : val.token
|
|
1418
1349
|
);
|
|
1419
1350
|
}
|
|
1420
1351
|
|
|
1421
1352
|
/**
|
|
1422
1353
|
* getTokenBalance Gets fungible token balance
|
|
1423
1354
|
* for NFT token balance see @ref getNftTokenBalance
|
|
1424
|
-
* @param {string}
|
|
1355
|
+
* @param {string} category category to get balance for
|
|
1425
1356
|
* @returns {bigint} fungible token balance
|
|
1426
1357
|
*/
|
|
1427
|
-
public async getTokenBalance(
|
|
1428
|
-
const utxos = (await this.getTokenUtxos(
|
|
1358
|
+
public async getTokenBalance(category: string): Promise<bigint> {
|
|
1359
|
+
const utxos = (await this.getTokenUtxos(category)).filter(
|
|
1429
1360
|
(val) => val.token?.amount
|
|
1430
1361
|
);
|
|
1431
|
-
return sumTokenAmounts(utxos,
|
|
1362
|
+
return sumTokenAmounts(utxos, category);
|
|
1432
1363
|
}
|
|
1433
1364
|
|
|
1434
1365
|
/**
|
|
1435
|
-
* getNftTokenBalance Gets non-fungible token (NFT) balance for a particular
|
|
1366
|
+
* getNftTokenBalance Gets non-fungible token (NFT) balance for a particular category
|
|
1436
1367
|
* disregards fungible token balances
|
|
1437
1368
|
* for fungible token balance see @ref getTokenBalance
|
|
1438
|
-
* @param {string}
|
|
1369
|
+
* @param {string} category category to get balance for
|
|
1439
1370
|
* @returns {number} non-fungible token balance
|
|
1440
1371
|
*/
|
|
1441
|
-
public async getNftTokenBalance(
|
|
1442
|
-
const utxos = (await this.getTokenUtxos(
|
|
1443
|
-
(val) => val.token?.commitment !== undefined
|
|
1372
|
+
public async getNftTokenBalance(category: string): Promise<number> {
|
|
1373
|
+
const utxos = (await this.getTokenUtxos(category)).filter(
|
|
1374
|
+
(val) => val.token?.nft?.commitment !== undefined
|
|
1444
1375
|
);
|
|
1445
1376
|
return utxos.length;
|
|
1446
1377
|
}
|
|
1447
1378
|
|
|
1448
1379
|
/**
|
|
1449
1380
|
* getAllTokenBalances Gets all fungible token balances in this wallet
|
|
1450
|
-
* @returns {Object} a map [
|
|
1381
|
+
* @returns {Object} a map [category => balance] for all tokens in this wallet
|
|
1451
1382
|
*/
|
|
1452
|
-
public async getAllTokenBalances(): Promise<{ [
|
|
1383
|
+
public async getAllTokenBalances(): Promise<{ [category: string]: bigint }> {
|
|
1453
1384
|
const result = {};
|
|
1454
1385
|
const utxos = (await this.getTokenUtxos()).filter(
|
|
1455
1386
|
(val) => val.token?.amount
|
|
1456
1387
|
);
|
|
1457
1388
|
for (const utxo of utxos) {
|
|
1458
|
-
if (!result[utxo.token!.
|
|
1459
|
-
result[utxo.token!.
|
|
1389
|
+
if (!result[utxo.token!.category]) {
|
|
1390
|
+
result[utxo.token!.category] = 0n;
|
|
1460
1391
|
}
|
|
1461
|
-
result[utxo.token!.
|
|
1392
|
+
result[utxo.token!.category] += utxo.token!.amount;
|
|
1462
1393
|
}
|
|
1463
1394
|
return result;
|
|
1464
1395
|
}
|
|
1465
1396
|
|
|
1466
1397
|
/**
|
|
1467
1398
|
* getAllNftTokenBalances Gets all non-fungible token (NFT) balances in this wallet
|
|
1468
|
-
* @returns {Object} a map [
|
|
1399
|
+
* @returns {Object} a map [category => balance] for all NFTs in this wallet
|
|
1469
1400
|
*/
|
|
1470
1401
|
public async getAllNftTokenBalances(): Promise<{
|
|
1471
|
-
[
|
|
1402
|
+
[category: string]: number;
|
|
1472
1403
|
}> {
|
|
1473
1404
|
const result = {};
|
|
1474
1405
|
const utxos = (await this.getTokenUtxos()).filter(
|
|
1475
|
-
(val) => val.token?.commitment !== undefined
|
|
1406
|
+
(val) => val.token?.nft?.commitment !== undefined
|
|
1476
1407
|
);
|
|
1477
1408
|
for (const utxo of utxos) {
|
|
1478
|
-
if (!result[utxo.token!.
|
|
1479
|
-
result[utxo.token!.
|
|
1409
|
+
if (!result[utxo.token!.category]) {
|
|
1410
|
+
result[utxo.token!.category] = 0;
|
|
1480
1411
|
}
|
|
1481
|
-
result[utxo.token!.
|
|
1412
|
+
result[utxo.token!.category] += 1;
|
|
1482
1413
|
}
|
|
1483
1414
|
return result;
|
|
1484
1415
|
}
|