@yaswap/bitcoin 3.3.7 → 3.4.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/CHANGELOG.md +25 -0
- package/dist/lib/index.d.ts +1 -1
- package/dist/lib/index.js +3 -1
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/types.d.ts +32 -3
- package/dist/lib/types.js.map +1 -1
- package/dist/lib/wallet/BitcoinBaseWallet.d.ts +32 -21
- package/dist/lib/wallet/BitcoinBaseWallet.js +179 -51
- package/dist/lib/wallet/BitcoinBaseWallet.js.map +1 -1
- package/dist/lib/wallet/BitcoinHDWallet.d.ts +23 -7
- package/dist/lib/wallet/BitcoinHDWallet.js +117 -20
- package/dist/lib/wallet/BitcoinHDWallet.js.map +1 -1
- package/dist/lib/wallet/BitcoinNodeWallet.d.ts +11 -7
- package/dist/lib/wallet/BitcoinNodeWallet.js +23 -3
- package/dist/lib/wallet/BitcoinNodeWallet.js.map +1 -1
- package/dist/lib/wallet/BitcoinSingleWallet.d.ts +14 -12
- package/dist/lib/wallet/BitcoinSingleWallet.js +13 -5
- package/dist/lib/wallet/BitcoinSingleWallet.js.map +1 -1
- package/dist/lib/wallet/IBitcoinWallet.d.ts +9 -3
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# @yaswap/bitcoin
|
|
2
2
|
|
|
3
|
+
## 3.4.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Support HD wallet logic
|
|
8
|
+
- Updated dependencies
|
|
9
|
+
- @yaswap/client@3.4.1
|
|
10
|
+
- @yaswap/errors@3.4.1
|
|
11
|
+
- @yaswap/types@3.4.1
|
|
12
|
+
- @yaswap/utils@3.4.1
|
|
13
|
+
|
|
14
|
+
## 3.4.0
|
|
15
|
+
|
|
16
|
+
### Minor Changes
|
|
17
|
+
|
|
18
|
+
- Support HD wallet logic
|
|
19
|
+
|
|
20
|
+
### Patch Changes
|
|
21
|
+
|
|
22
|
+
- Updated dependencies
|
|
23
|
+
- @yaswap/client@3.4.0
|
|
24
|
+
- @yaswap/errors@3.4.0
|
|
25
|
+
- @yaswap/types@3.4.0
|
|
26
|
+
- @yaswap/utils@3.4.0
|
|
27
|
+
|
|
3
28
|
## 3.3.7
|
|
4
29
|
|
|
5
30
|
### Patch Changes
|
package/dist/lib/index.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export { BitcoinSwapEsploraProvider } from './swap/BitcoinSwapEsploraProvider';
|
|
|
11
11
|
export { BitcoinSwapRpcProvider } from './swap/BitcoinSwapRpcProvider';
|
|
12
12
|
export * as BitcoinTypes from './types';
|
|
13
13
|
export * as BitcoinUtils from './utils';
|
|
14
|
-
export { BitcoinBaseWalletProvider } from './wallet/BitcoinBaseWallet';
|
|
14
|
+
export { AddressSearchType, BitcoinBaseWalletProvider, NUMBER_ADDRESS_LIMIT } from './wallet/BitcoinBaseWallet';
|
|
15
15
|
export { BitcoinHDWalletProvider } from './wallet/BitcoinHDWallet';
|
|
16
16
|
export { BitcoinNodeWalletProvider } from './wallet/BitcoinNodeWallet';
|
|
17
17
|
export { BitcoinSingleWallet } from './wallet/BitcoinSingleWallet';
|
package/dist/lib/index.js
CHANGED
|
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.BitcoinSingleWallet = exports.BitcoinNodeWalletProvider = exports.BitcoinHDWalletProvider = exports.BitcoinBaseWalletProvider = exports.BitcoinUtils = exports.BitcoinTypes = exports.BitcoinSwapRpcProvider = exports.BitcoinSwapEsploraProvider = exports.BitcoinSwapBaseProvider = exports.BitcoinNetworks = exports.BitcoinFeeApiProvider = exports.BitcoinJsonRpcProvider = exports.BitcoinJsonRpcBaseProvider = exports.BitcoinEsploraBatchBaseProvider = exports.BitcoinEsploraBaseProvider = exports.BitcoinEsploraApiProvider = exports.BitcoinBaseChainProvider = void 0;
|
|
26
|
+
exports.BitcoinSingleWallet = exports.BitcoinNodeWalletProvider = exports.BitcoinHDWalletProvider = exports.NUMBER_ADDRESS_LIMIT = exports.BitcoinBaseWalletProvider = exports.AddressSearchType = exports.BitcoinUtils = exports.BitcoinTypes = exports.BitcoinSwapRpcProvider = exports.BitcoinSwapEsploraProvider = exports.BitcoinSwapBaseProvider = exports.BitcoinNetworks = exports.BitcoinFeeApiProvider = exports.BitcoinJsonRpcProvider = exports.BitcoinJsonRpcBaseProvider = exports.BitcoinEsploraBatchBaseProvider = exports.BitcoinEsploraBaseProvider = exports.BitcoinEsploraApiProvider = exports.BitcoinBaseChainProvider = void 0;
|
|
27
27
|
var BitcoinBaseChainProvider_1 = require("./chain/BitcoinBaseChainProvider");
|
|
28
28
|
Object.defineProperty(exports, "BitcoinBaseChainProvider", { enumerable: true, get: function () { return BitcoinBaseChainProvider_1.BitcoinBaseChainProvider; } });
|
|
29
29
|
var BitcoinEsploraApiProvider_1 = require("./chain/esplora/BitcoinEsploraApiProvider");
|
|
@@ -49,7 +49,9 @@ Object.defineProperty(exports, "BitcoinSwapRpcProvider", { enumerable: true, get
|
|
|
49
49
|
exports.BitcoinTypes = __importStar(require("./types"));
|
|
50
50
|
exports.BitcoinUtils = __importStar(require("./utils"));
|
|
51
51
|
var BitcoinBaseWallet_1 = require("./wallet/BitcoinBaseWallet");
|
|
52
|
+
Object.defineProperty(exports, "AddressSearchType", { enumerable: true, get: function () { return BitcoinBaseWallet_1.AddressSearchType; } });
|
|
52
53
|
Object.defineProperty(exports, "BitcoinBaseWalletProvider", { enumerable: true, get: function () { return BitcoinBaseWallet_1.BitcoinBaseWalletProvider; } });
|
|
54
|
+
Object.defineProperty(exports, "NUMBER_ADDRESS_LIMIT", { enumerable: true, get: function () { return BitcoinBaseWallet_1.NUMBER_ADDRESS_LIMIT; } });
|
|
53
55
|
var BitcoinHDWallet_1 = require("./wallet/BitcoinHDWallet");
|
|
54
56
|
Object.defineProperty(exports, "BitcoinHDWalletProvider", { enumerable: true, get: function () { return BitcoinHDWallet_1.BitcoinHDWalletProvider; } });
|
|
55
57
|
var BitcoinNodeWallet_1 = require("./wallet/BitcoinNodeWallet");
|
package/dist/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../lib/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,6EAA4E;AAAnE,oIAAA,wBAAwB,OAAA;AACjC,uFAAsF;AAA7E,sIAAA,yBAAyB,OAAA;AAClC,yFAAwF;AAA/E,wIAAA,0BAA0B,OAAA;AACnC,mGAAkG;AAAzF,kJAAA,+BAA+B,OAAA;AACxC,yFAAwF;AAA/E,wIAAA,0BAA0B,OAAA;AACnC,iFAAgF;AAAvE,gIAAA,sBAAsB,OAAA;AAC/B,qEAAoE;AAA3D,8HAAA,qBAAqB,OAAA;AAC9B,uCAA6C;AAApC,2GAAA,eAAe,OAAA;AACxB,0EAAyE;AAAhE,kIAAA,uBAAuB,OAAA;AAChC,gFAA+E;AAAtE,wIAAA,0BAA0B,OAAA;AACnC,wEAAuE;AAA9D,gIAAA,sBAAsB,OAAA;AAC/B,wDAAwC;AACxC,wDAAwC;AACxC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../lib/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,6EAA4E;AAAnE,oIAAA,wBAAwB,OAAA;AACjC,uFAAsF;AAA7E,sIAAA,yBAAyB,OAAA;AAClC,yFAAwF;AAA/E,wIAAA,0BAA0B,OAAA;AACnC,mGAAkG;AAAzF,kJAAA,+BAA+B,OAAA;AACxC,yFAAwF;AAA/E,wIAAA,0BAA0B,OAAA;AACnC,iFAAgF;AAAvE,gIAAA,sBAAsB,OAAA;AAC/B,qEAAoE;AAA3D,8HAAA,qBAAqB,OAAA;AAC9B,uCAA6C;AAApC,2GAAA,eAAe,OAAA;AACxB,0EAAyE;AAAhE,kIAAA,uBAAuB,OAAA;AAChC,gFAA+E;AAAtE,wIAAA,0BAA0B,OAAA;AACnC,wEAAuE;AAA9D,gIAAA,sBAAsB,OAAA;AAC/B,wDAAwC;AACxC,wDAAwC;AACxC,gEAAgH;AAAvG,sHAAA,iBAAiB,OAAA;AAAE,8HAAA,yBAAyB,OAAA;AAAE,yHAAA,oBAAoB,OAAA;AAC3E,4DAAmE;AAA1D,0HAAA,uBAAuB,OAAA;AAChC,gEAAuE;AAA9D,8HAAA,yBAAyB,OAAA;AAClC,oEAAmE;AAA1D,0HAAA,mBAAmB,OAAA"}
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import { Network, TransactionRequest } from '@yaswap/types';
|
|
2
|
+
import { Address, Network, TransactionRequest } from '@yaswap/types';
|
|
3
3
|
import { ECPairInterface, Network as BitcoinJsLibNetwork } from 'bitcoinjs-lib';
|
|
4
4
|
export * as BitcoinEsploraTypes from './chain/esplora/types';
|
|
5
5
|
export * as BitcoinJsonRpcTypes from './chain/jsonRpc/types';
|
|
@@ -18,8 +18,18 @@ export interface BitcoinSingleWalletOptions extends BitcoinNodeWalletOptions {
|
|
|
18
18
|
export interface BitcoinWalletProviderOptions extends BitcoinNodeWalletOptions {
|
|
19
19
|
baseDerivationPath: string;
|
|
20
20
|
}
|
|
21
|
+
export interface RawExtendedPublicKey {
|
|
22
|
+
publicKey: Buffer;
|
|
23
|
+
chainCode: Buffer;
|
|
24
|
+
}
|
|
25
|
+
export interface RawExtendedPrivateKey {
|
|
26
|
+
privateKey: Buffer;
|
|
27
|
+
chainCode: Buffer;
|
|
28
|
+
}
|
|
21
29
|
export interface BitcoinHDWalletProviderOptions extends BitcoinWalletProviderOptions {
|
|
22
|
-
mnemonic
|
|
30
|
+
mnemonic?: string;
|
|
31
|
+
extendedPublicKey?: RawExtendedPublicKey;
|
|
32
|
+
extendedPrivateKey?: RawExtendedPrivateKey;
|
|
23
33
|
}
|
|
24
34
|
export interface OutputTarget {
|
|
25
35
|
address?: string;
|
|
@@ -86,6 +96,16 @@ export declare enum SwapMode {
|
|
|
86
96
|
export declare type AddressTxCounts = {
|
|
87
97
|
[index: string]: number;
|
|
88
98
|
};
|
|
99
|
+
export interface UsedUnusedAddressesResult {
|
|
100
|
+
usedAddresses: {
|
|
101
|
+
change: Address[];
|
|
102
|
+
external: Address[];
|
|
103
|
+
};
|
|
104
|
+
unusedAddress: {
|
|
105
|
+
change: Address | null;
|
|
106
|
+
external: Address | null;
|
|
107
|
+
};
|
|
108
|
+
}
|
|
89
109
|
export interface PsbtInputTarget {
|
|
90
110
|
index: number;
|
|
91
111
|
derivationPath: string;
|
|
@@ -96,6 +116,15 @@ export interface P2SHInput {
|
|
|
96
116
|
vout: any;
|
|
97
117
|
outputScript: Buffer;
|
|
98
118
|
}
|
|
99
|
-
|
|
119
|
+
/**
|
|
120
|
+
* Options for Bitcoin sendTransaction and sendTransactionFixedInputs.
|
|
121
|
+
* Extends TransactionRequest with Bitcoin-specific options.
|
|
122
|
+
*/
|
|
123
|
+
export interface BitcoinSendTransactionOptions extends TransactionRequest {
|
|
124
|
+
/** Pre-selected UTXOs to use as inputs. When set, only these UTXOs are used (e.g. for sendTransactionFixedInputs). */
|
|
100
125
|
inputs?: UTXO[];
|
|
126
|
+
/** When true, use a change address (internal branch) for the change output; when false, use a receiving address (external branch). Default: false. */
|
|
127
|
+
change?: boolean;
|
|
128
|
+
/** Maximum number of addresses to scan for UTXOs. Default: 40. */
|
|
129
|
+
addressLimit?: number;
|
|
101
130
|
}
|
package/dist/lib/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../lib/types.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA,6EAA6D;AAC7D,6EAA6D;AAC7D,+CAA6B;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../lib/types.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA,6EAA6D;AAC7D,6EAA6D;AAC7D,+CAA6B;AA6F7B,IAAY,WAIX;AAJD,WAAY,WAAW;IACnB,gCAAiB,CAAA;IACjB,0CAA2B,CAAA;IAC3B,gCAAiB,CAAA;AACrB,CAAC,EAJW,WAAW,GAAX,mBAAW,KAAX,mBAAW,QAItB;AAED,IAAY,QAIX;AAJD,WAAY,QAAQ;IAChB,yBAAa,CAAA;IACb,sCAA0B,CAAA;IAC1B,2BAAe,CAAA;AACnB,CAAC,EAJW,QAAQ,GAAR,gBAAQ,KAAR,gBAAQ,QAInB"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { Chain, Wallet } from '@yaswap/client';
|
|
3
|
-
import { Address, AddressType, Asset, Transaction,
|
|
3
|
+
import { Address, AddressType, Asset, Transaction, CreateTokenTransaction } from '@yaswap/types';
|
|
4
4
|
import { BIP32Interface } from 'bip32';
|
|
5
5
|
import { payments } from 'bitcoinjs-lib';
|
|
6
6
|
import { BitcoinBaseChainProvider } from '../chain/BitcoinBaseChainProvider';
|
|
7
|
-
import { AddressType as BtcAddressType, BitcoinNetwork,
|
|
7
|
+
import { AddressType as BtcAddressType, BitcoinNetwork, BitcoinSendTransactionOptions, BitcoinWalletProviderOptions, OutputTarget, P2SHInput, PsbtInputTarget, Transaction as BtcTransaction, UsedUnusedAddressesResult, UTXO } from '../types';
|
|
8
8
|
import { CoinSelectTarget } from '../utils';
|
|
9
|
+
export declare const NUMBER_ADDRESS_LIMIT = 40;
|
|
9
10
|
export declare enum AddressSearchType {
|
|
10
11
|
EXTERNAL = 0,
|
|
11
12
|
CHANGE = 1,
|
|
@@ -22,7 +23,7 @@ export declare abstract class BitcoinBaseWalletProvider<T extends BitcoinBaseCha
|
|
|
22
23
|
constructor(options: BitcoinWalletProviderOptions, chainProvider?: Chain<T>);
|
|
23
24
|
protected onChainProviderUpdate(chainProvider: Chain<T>): void;
|
|
24
25
|
protected abstract baseDerivationNode(): Promise<BIP32Interface>;
|
|
25
|
-
protected abstract buildTransaction(targets: OutputTarget[], feePerByte?: number,
|
|
26
|
+
protected abstract buildTransaction(targets: OutputTarget[], feePerByte?: number, fixedUtxos?: UTXO[], change?: boolean, addressLimit?: number): Promise<{
|
|
26
27
|
hex: string;
|
|
27
28
|
fee: number;
|
|
28
29
|
}>;
|
|
@@ -33,35 +34,45 @@ export declare abstract class BitcoinBaseWalletProvider<T extends BitcoinBaseCha
|
|
|
33
34
|
abstract signPSBT(data: string, inputs: PsbtInputTarget[]): Promise<string>;
|
|
34
35
|
abstract signBatchP2SHTransaction(inputs: P2SHInput[], addresses: string, tx: any, lockTime?: number, segwit?: boolean): Promise<Buffer[]>;
|
|
35
36
|
getDerivationCache(): DerivationCache;
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
/**
|
|
38
|
+
* Get one unused receiving or change address.
|
|
39
|
+
*
|
|
40
|
+
* @param change When true, search change addresses; otherwise external/receiving.
|
|
41
|
+
* @param addressLimit Maximum number of address indexes to scan (per branch). Defaults to NUMBER_ADDRESS_LIMIT.
|
|
42
|
+
* @returns The first unused address found or null if none within the limit.
|
|
43
|
+
*/
|
|
44
|
+
getUnusedAddress(change?: boolean, addressLimit?: number): Promise<Address>;
|
|
45
|
+
/**
|
|
46
|
+
* Get used addresses.
|
|
47
|
+
*
|
|
48
|
+
* @param addressType Which branch to scan: external, change or both. Defaults to both.
|
|
49
|
+
* @param addressLimit Maximum number of address indexes to scan (per branch). Defaults to NUMBER_ADDRESS_LIMIT.
|
|
50
|
+
* @returns List of used addresses for the requested branch(es).
|
|
51
|
+
*/
|
|
52
|
+
getUsedAddresses(addressType?: AddressSearchType, addressLimit?: number): Promise<Address[]>;
|
|
38
53
|
getAddresses(startingIndex?: number, numAddresses?: number, change?: boolean): Promise<Address[]>;
|
|
39
|
-
createToken(
|
|
40
|
-
|
|
41
|
-
|
|
54
|
+
createToken(_txRequest: CreateTokenTransaction): Promise<null>;
|
|
55
|
+
sendTransactionFixedInputs(options: BitcoinSendTransactionOptions): Promise<Transaction<BtcTransaction>>;
|
|
56
|
+
sendTransaction(options: BitcoinSendTransactionOptions): Promise<Transaction<BtcTransaction>>;
|
|
57
|
+
sendBatchTransaction(transactions: BitcoinSendTransactionOptions[]): Promise<Transaction<BtcTransaction>[]>;
|
|
42
58
|
sendSweepTransaction(externalChangeAddress: AddressType, _asset: Asset, feePerByte: number): Promise<Transaction<BtcTransaction>>;
|
|
43
59
|
updateTransactionFee(tx: Transaction<BtcTransaction> | string, newFeePerByte: number): Promise<Transaction<BtcTransaction>>;
|
|
44
|
-
getTotalFees(transactions:
|
|
45
|
-
protected _sendTransaction(transactions: OutputTarget[], feePerByte?: number): Promise<Transaction<BtcTransaction>>;
|
|
46
|
-
protected findAddress(addresses: string[], change?: boolean): Promise<Address>;
|
|
60
|
+
getTotalFees(transactions: BitcoinSendTransactionOptions[], max: boolean): Promise<any>;
|
|
61
|
+
protected _sendTransaction(transactions: OutputTarget[], feePerByte?: number, change?: boolean, addressLimit?: number): Promise<Transaction<BtcTransaction>>;
|
|
62
|
+
protected findAddress(addresses: string[], change?: boolean, addressLimit?: number): Promise<Address>;
|
|
47
63
|
getWalletAddress(address: string): Promise<Address>;
|
|
48
64
|
protected getDerivationPathAddress(path: string): Promise<Address>;
|
|
49
|
-
|
|
50
|
-
usedAddresses: Address[];
|
|
51
|
-
unusedAddress: {
|
|
52
|
-
change: Address;
|
|
53
|
-
external: Address;
|
|
54
|
-
};
|
|
55
|
-
}>;
|
|
65
|
+
getUsedUnusedAddresses(addressType: AddressSearchType, addressLimit?: number, gapLimit?: number): Promise<UsedUnusedAddressesResult>;
|
|
56
66
|
protected withCachedUtxos(func: () => any): Promise<any>;
|
|
57
|
-
|
|
58
|
-
protected
|
|
67
|
+
getTotalFeeFixedInputs(opts: BitcoinSendTransactionOptions, max: boolean): Promise<number>;
|
|
68
|
+
protected getTotalFee(opts: BitcoinSendTransactionOptions, max: boolean): Promise<number>;
|
|
69
|
+
protected getInputsForAmount(_targets: OutputTarget[], feePerByte?: number, fixedUtxos?: UTXO[], sweep?: boolean, addressLimit?: number, change?: boolean): Promise<{
|
|
59
70
|
inputs: UTXO[];
|
|
60
71
|
change: CoinSelectTarget;
|
|
61
72
|
outputs: CoinSelectTarget[];
|
|
62
73
|
fee: number;
|
|
63
74
|
}>;
|
|
64
|
-
protected sendOptionsToOutputs(transactions:
|
|
75
|
+
protected sendOptionsToOutputs(transactions: BitcoinSendTransactionOptions[]): OutputTarget[];
|
|
65
76
|
protected getAddressFromPublicKey(publicKey: Buffer): string;
|
|
66
77
|
protected getPaymentVariantFromPublicKey(publicKey: Buffer): payments.Payment;
|
|
67
78
|
}
|
|
@@ -12,7 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.BitcoinBaseWalletProvider = exports.AddressSearchType = void 0;
|
|
15
|
+
exports.BitcoinBaseWalletProvider = exports.AddressSearchType = exports.NUMBER_ADDRESS_LIMIT = void 0;
|
|
16
16
|
const client_1 = require("@yaswap/client");
|
|
17
17
|
const errors_1 = require("@yaswap/errors");
|
|
18
18
|
const types_1 = require("@yaswap/types");
|
|
@@ -22,7 +22,7 @@ const memoizee_1 = __importDefault(require("memoizee"));
|
|
|
22
22
|
const types_2 = require("../types");
|
|
23
23
|
const utils_2 = require("../utils");
|
|
24
24
|
const utils_3 = __importDefault(require("@yaswap/bitcoinselect/utils"));
|
|
25
|
-
|
|
25
|
+
exports.NUMBER_ADDRESS_LIMIT = 40;
|
|
26
26
|
var AddressSearchType;
|
|
27
27
|
(function (AddressSearchType) {
|
|
28
28
|
AddressSearchType[AddressSearchType["EXTERNAL"] = 0] = "EXTERNAL";
|
|
@@ -48,16 +48,38 @@ class BitcoinBaseWalletProvider extends client_1.Wallet {
|
|
|
48
48
|
getDerivationCache() {
|
|
49
49
|
return this._derivationCache;
|
|
50
50
|
}
|
|
51
|
-
|
|
51
|
+
/**
|
|
52
|
+
* Get one unused receiving or change address.
|
|
53
|
+
*
|
|
54
|
+
* @param change When true, search change addresses; otherwise external/receiving.
|
|
55
|
+
* @param addressLimit Maximum number of address indexes to scan (per branch). Defaults to NUMBER_ADDRESS_LIMIT.
|
|
56
|
+
* @returns The first unused address found or null if none within the limit.
|
|
57
|
+
*/
|
|
58
|
+
getUnusedAddress(change = false, addressLimit = exports.NUMBER_ADDRESS_LIMIT) {
|
|
52
59
|
return __awaiter(this, void 0, void 0, function* () {
|
|
53
60
|
const addressType = change ? AddressSearchType.CHANGE : AddressSearchType.EXTERNAL;
|
|
54
61
|
const key = change ? 'change' : 'external';
|
|
55
|
-
|
|
62
|
+
const { unusedAddress } = yield this.getUsedUnusedAddresses(addressType, addressLimit);
|
|
63
|
+
return unusedAddress[key];
|
|
56
64
|
});
|
|
57
65
|
}
|
|
58
|
-
|
|
66
|
+
/**
|
|
67
|
+
* Get used addresses.
|
|
68
|
+
*
|
|
69
|
+
* @param addressType Which branch to scan: external, change or both. Defaults to both.
|
|
70
|
+
* @param addressLimit Maximum number of address indexes to scan (per branch). Defaults to NUMBER_ADDRESS_LIMIT.
|
|
71
|
+
* @returns List of used addresses for the requested branch(es).
|
|
72
|
+
*/
|
|
73
|
+
getUsedAddresses(addressType = AddressSearchType.EXTERNAL_OR_CHANGE, addressLimit = exports.NUMBER_ADDRESS_LIMIT) {
|
|
59
74
|
return __awaiter(this, void 0, void 0, function* () {
|
|
60
|
-
|
|
75
|
+
const result = yield this.getUsedUnusedAddresses(addressType, addressLimit);
|
|
76
|
+
if (addressType === AddressSearchType.EXTERNAL) {
|
|
77
|
+
return result.usedAddresses.external;
|
|
78
|
+
}
|
|
79
|
+
if (addressType === AddressSearchType.CHANGE) {
|
|
80
|
+
return result.usedAddresses.change;
|
|
81
|
+
}
|
|
82
|
+
return [...result.usedAddresses.change, ...result.usedAddresses.external];
|
|
61
83
|
});
|
|
62
84
|
}
|
|
63
85
|
getAddresses(startingIndex = 0, numAddresses = 1, change = false) {
|
|
@@ -78,19 +100,38 @@ class BitcoinBaseWalletProvider extends client_1.Wallet {
|
|
|
78
100
|
return addresses;
|
|
79
101
|
});
|
|
80
102
|
}
|
|
81
|
-
createToken(
|
|
103
|
+
createToken(_txRequest) {
|
|
82
104
|
return __awaiter(this, void 0, void 0, function* () {
|
|
83
105
|
return null;
|
|
84
106
|
});
|
|
85
107
|
}
|
|
108
|
+
sendTransactionFixedInputs(options) {
|
|
109
|
+
var _a, _b, _c;
|
|
110
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
111
|
+
const targets = this.sendOptionsToOutputs([options]);
|
|
112
|
+
const fixedUtxos = (_a = options.inputs) !== null && _a !== void 0 ? _a : [];
|
|
113
|
+
const change = (_b = options.change) !== null && _b !== void 0 ? _b : false;
|
|
114
|
+
const addressLimit = (_c = options.addressLimit) !== null && _c !== void 0 ? _c : exports.NUMBER_ADDRESS_LIMIT;
|
|
115
|
+
const { hex, fee } = yield this.buildTransaction(targets, options.fee, fixedUtxos, change, addressLimit);
|
|
116
|
+
yield this.chainProvider.sendRawTransaction(hex);
|
|
117
|
+
return (0, utils_2.normalizeTransactionObject)((0, utils_2.decodeRawTransaction)(hex, this._network), fee);
|
|
118
|
+
});
|
|
119
|
+
}
|
|
86
120
|
sendTransaction(options) {
|
|
121
|
+
var _a, _b;
|
|
87
122
|
return __awaiter(this, void 0, void 0, function* () {
|
|
88
|
-
|
|
123
|
+
const change = (_a = options.change) !== null && _a !== void 0 ? _a : false;
|
|
124
|
+
const addressLimit = (_b = options.addressLimit) !== null && _b !== void 0 ? _b : exports.NUMBER_ADDRESS_LIMIT;
|
|
125
|
+
return this._sendTransaction(this.sendOptionsToOutputs([options]), options.fee, change, addressLimit);
|
|
89
126
|
});
|
|
90
127
|
}
|
|
91
128
|
sendBatchTransaction(transactions) {
|
|
129
|
+
var _a, _b;
|
|
92
130
|
return __awaiter(this, void 0, void 0, function* () {
|
|
93
|
-
|
|
131
|
+
const first = transactions[0];
|
|
132
|
+
const change = (_a = first === null || first === void 0 ? void 0 : first.change) !== null && _a !== void 0 ? _a : false;
|
|
133
|
+
const addressLimit = (_b = first === null || first === void 0 ? void 0 : first.addressLimit) !== null && _b !== void 0 ? _b : exports.NUMBER_ADDRESS_LIMIT;
|
|
134
|
+
return [yield this._sendTransaction(this.sendOptionsToOutputs(transactions), undefined, change, addressLimit)];
|
|
94
135
|
});
|
|
95
136
|
}
|
|
96
137
|
sendSweepTransaction(externalChangeAddress, _asset, feePerByte) {
|
|
@@ -104,7 +145,23 @@ class BitcoinBaseWalletProvider extends client_1.Wallet {
|
|
|
104
145
|
return __awaiter(this, void 0, void 0, function* () {
|
|
105
146
|
const txHash = typeof tx === 'string' ? tx : tx.hash;
|
|
106
147
|
const transaction = (yield this.chainProvider.getTransactionByHash(txHash))._raw;
|
|
107
|
-
const
|
|
148
|
+
const fixedUtxos = [];
|
|
149
|
+
const needsWitness = [types_2.AddressType.BECH32, types_2.AddressType.P2SH_SEGWIT].includes(this._addressType);
|
|
150
|
+
for (const vin of transaction.vin) {
|
|
151
|
+
const txHex = yield this.chainProvider.getProvider().getRawTransactionByHash(vin.txid);
|
|
152
|
+
const tx = (0, utils_2.decodeRawTransaction)(txHex, this._network);
|
|
153
|
+
const value = new types_1.BigNumber(tx.vout[vin.vout].value).times(1e8).toNumber();
|
|
154
|
+
const address = tx.vout[vin.vout].scriptPubKey.addresses[0];
|
|
155
|
+
const walletAddress = yield this.getWalletAddress(address);
|
|
156
|
+
fixedUtxos.push({
|
|
157
|
+
txid: vin.txid,
|
|
158
|
+
vout: vin.vout,
|
|
159
|
+
value,
|
|
160
|
+
address,
|
|
161
|
+
derivationPath: walletAddress.derivationPath,
|
|
162
|
+
witnessUtxo: needsWitness ? { script: new Uint8Array(0), value } : null,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
108
165
|
const lookupAddresses = transaction.vout.map((vout) => vout.scriptPubKey.addresses[0]);
|
|
109
166
|
const changeAddress = yield this.findAddress(lookupAddresses, true);
|
|
110
167
|
const changeOutput = transaction.vout.find((vout) => vout.scriptPubKey.addresses[0] === changeAddress.address);
|
|
@@ -117,7 +174,7 @@ class BitcoinBaseWalletProvider extends client_1.Wallet {
|
|
|
117
174
|
address: output.scriptPubKey.addresses[0],
|
|
118
175
|
value: new types_1.BigNumber(output.value).times(1e8).toNumber(),
|
|
119
176
|
}));
|
|
120
|
-
const { hex, fee } = yield this.buildTransaction(transactions, newFeePerByte,
|
|
177
|
+
const { hex, fee } = yield this.buildTransaction(transactions, newFeePerByte, fixedUtxos, true, exports.NUMBER_ADDRESS_LIMIT);
|
|
121
178
|
yield this.chainProvider.sendRawTransaction(hex);
|
|
122
179
|
return (0, utils_2.normalizeTransactionObject)((0, utils_2.decodeRawTransaction)(hex, this._network), fee);
|
|
123
180
|
});
|
|
@@ -140,18 +197,18 @@ class BitcoinBaseWalletProvider extends client_1.Wallet {
|
|
|
140
197
|
return fees;
|
|
141
198
|
});
|
|
142
199
|
}
|
|
143
|
-
_sendTransaction(transactions, feePerByte) {
|
|
200
|
+
_sendTransaction(transactions, feePerByte, change = false, addressLimit = exports.NUMBER_ADDRESS_LIMIT) {
|
|
144
201
|
return __awaiter(this, void 0, void 0, function* () {
|
|
145
|
-
const { hex, fee } = yield this.buildTransaction(transactions, feePerByte);
|
|
202
|
+
const { hex, fee } = yield this.buildTransaction(transactions, feePerByte, [], change, addressLimit);
|
|
146
203
|
yield this.chainProvider.sendRawTransaction(hex);
|
|
147
204
|
return (0, utils_2.normalizeTransactionObject)((0, utils_2.decodeRawTransaction)(hex, this._network), fee);
|
|
148
205
|
});
|
|
149
206
|
}
|
|
150
|
-
findAddress(addresses, change = false) {
|
|
207
|
+
findAddress(addresses, change = false, addressLimit = exports.NUMBER_ADDRESS_LIMIT) {
|
|
151
208
|
return __awaiter(this, void 0, void 0, function* () {
|
|
152
209
|
// A maximum number of addresses to lookup after which it is deemed that the wallet does not contain this address
|
|
153
|
-
const maxAddresses =
|
|
154
|
-
const addressesPerCall =
|
|
210
|
+
const maxAddresses = addressLimit;
|
|
211
|
+
const addressesPerCall = exports.NUMBER_ADDRESS_LIMIT;
|
|
155
212
|
let index = 0;
|
|
156
213
|
while (index < maxAddresses) {
|
|
157
214
|
const walletAddresses = yield this.getAddresses(index, addressesPerCall, change);
|
|
@@ -194,21 +251,75 @@ class BitcoinBaseWalletProvider extends client_1.Wallet {
|
|
|
194
251
|
return addressObject;
|
|
195
252
|
});
|
|
196
253
|
}
|
|
197
|
-
|
|
254
|
+
getUsedUnusedAddresses(addressType, addressLimit = exports.NUMBER_ADDRESS_LIMIT, gapLimit = 1) {
|
|
198
255
|
return __awaiter(this, void 0, void 0, function* () {
|
|
199
|
-
const usedAddresses =
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
256
|
+
const usedAddresses = {
|
|
257
|
+
change: [],
|
|
258
|
+
external: [],
|
|
259
|
+
};
|
|
260
|
+
const unusedAddressMap = {
|
|
261
|
+
change: null,
|
|
262
|
+
external: null,
|
|
263
|
+
};
|
|
264
|
+
const consecutiveUnusedCount = { change: 0, external: 0 };
|
|
265
|
+
let numAddressAlreadyGet = 0;
|
|
266
|
+
const numAddressPerCall = 100;
|
|
267
|
+
let addressIndex = 0;
|
|
268
|
+
/* eslint-disable no-unmodified-loop-condition */
|
|
269
|
+
while (((addressType === AddressSearchType.EXTERNAL_OR_CHANGE &&
|
|
270
|
+
(consecutiveUnusedCount.change < gapLimit || consecutiveUnusedCount.external < gapLimit)) ||
|
|
271
|
+
(addressType === AddressSearchType.EXTERNAL && consecutiveUnusedCount.external < gapLimit) ||
|
|
272
|
+
(addressType === AddressSearchType.CHANGE && consecutiveUnusedCount.change < gapLimit)) &&
|
|
273
|
+
numAddressAlreadyGet < addressLimit) {
|
|
274
|
+
/* eslint-enable no-unmodified-loop-condition */
|
|
275
|
+
let addrList = [];
|
|
276
|
+
let changeAddresses = [];
|
|
277
|
+
let externalAddresses = [];
|
|
278
|
+
let maxBatchSize = 0;
|
|
279
|
+
if ((addressType === AddressSearchType.EXTERNAL_OR_CHANGE || addressType === AddressSearchType.CHANGE) &&
|
|
280
|
+
consecutiveUnusedCount.change < gapLimit &&
|
|
281
|
+
numAddressAlreadyGet < addressLimit) {
|
|
282
|
+
// Scanning for change addr
|
|
283
|
+
const remainingLimit = addressLimit - numAddressAlreadyGet;
|
|
284
|
+
const batchSize = Math.min(numAddressPerCall, remainingLimit);
|
|
285
|
+
changeAddresses = yield this.getAddresses(addressIndex, batchSize, true);
|
|
286
|
+
addrList = addrList.concat(changeAddresses);
|
|
287
|
+
maxBatchSize = Math.max(maxBatchSize, batchSize);
|
|
288
|
+
}
|
|
289
|
+
if ((addressType === AddressSearchType.EXTERNAL_OR_CHANGE || addressType === AddressSearchType.EXTERNAL) &&
|
|
290
|
+
consecutiveUnusedCount.external < gapLimit &&
|
|
291
|
+
numAddressAlreadyGet < addressLimit) {
|
|
292
|
+
// Scanning for non change addr
|
|
293
|
+
const remainingLimit = addressLimit - numAddressAlreadyGet;
|
|
294
|
+
const batchSize = Math.min(numAddressPerCall, remainingLimit);
|
|
295
|
+
externalAddresses = yield this.getAddresses(addressIndex, batchSize, false);
|
|
296
|
+
addrList = addrList.concat(externalAddresses);
|
|
297
|
+
maxBatchSize = Math.max(maxBatchSize, batchSize);
|
|
298
|
+
}
|
|
299
|
+
if (addrList.length === 0) {
|
|
300
|
+
break;
|
|
301
|
+
}
|
|
302
|
+
const transactionCounts = yield this.chainProvider
|
|
303
|
+
.getProvider()
|
|
304
|
+
.getAddressTransactionCounts(addrList);
|
|
305
|
+
for (const address of addrList) {
|
|
306
|
+
const isUsed = transactionCounts[address.toString()] > 0;
|
|
307
|
+
const isChangeAddress = changeAddresses.some((a) => address.toString() === a.toString());
|
|
308
|
+
const key = isChangeAddress ? 'change' : 'external';
|
|
309
|
+
if (isUsed) {
|
|
310
|
+
usedAddresses[key].push(address);
|
|
311
|
+
consecutiveUnusedCount[key] = 0;
|
|
312
|
+
unusedAddressMap[key] = null;
|
|
313
|
+
}
|
|
314
|
+
else {
|
|
315
|
+
consecutiveUnusedCount[key]++;
|
|
316
|
+
if (!unusedAddressMap[key]) {
|
|
317
|
+
unusedAddressMap[key] = address;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
numAddressAlreadyGet += maxBatchSize;
|
|
322
|
+
addressIndex += maxBatchSize;
|
|
212
323
|
}
|
|
213
324
|
return {
|
|
214
325
|
usedAddresses,
|
|
@@ -232,47 +343,64 @@ class BitcoinBaseWalletProvider extends client_1.Wallet {
|
|
|
232
343
|
return result;
|
|
233
344
|
});
|
|
234
345
|
}
|
|
346
|
+
getTotalFeeFixedInputs(opts, max) {
|
|
347
|
+
var _a, _b, _c;
|
|
348
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
349
|
+
const targets = this.sendOptionsToOutputs([opts]);
|
|
350
|
+
const addressLimit = (_a = opts.addressLimit) !== null && _a !== void 0 ? _a : exports.NUMBER_ADDRESS_LIMIT;
|
|
351
|
+
const useChangeUtxos = (_b = opts.change) !== null && _b !== void 0 ? _b : false;
|
|
352
|
+
const { fee } = yield this.getInputsForAmount(targets.filter((t) => !t.value), opts.fee, (_c = opts.inputs) !== null && _c !== void 0 ? _c : [], max, addressLimit, useChangeUtxos);
|
|
353
|
+
return fee;
|
|
354
|
+
});
|
|
355
|
+
}
|
|
235
356
|
getTotalFee(opts, max) {
|
|
357
|
+
var _a, _b;
|
|
236
358
|
return __awaiter(this, void 0, void 0, function* () {
|
|
237
359
|
const targets = this.sendOptionsToOutputs([opts]);
|
|
360
|
+
const addressLimit = (_a = opts.addressLimit) !== null && _a !== void 0 ? _a : exports.NUMBER_ADDRESS_LIMIT;
|
|
361
|
+
const useChangeUtxos = (_b = opts.change) !== null && _b !== void 0 ? _b : false;
|
|
238
362
|
if (!max) {
|
|
239
|
-
const { fee } = yield this.getInputsForAmount(targets, opts.fee);
|
|
363
|
+
const { fee } = yield this.getInputsForAmount(targets, opts.fee, [], false, addressLimit, useChangeUtxos);
|
|
240
364
|
return fee;
|
|
241
365
|
}
|
|
242
366
|
else {
|
|
243
|
-
const { fee } = yield this.getInputsForAmount(targets.filter((t) => !t.value), opts.fee, [], true);
|
|
367
|
+
const { fee } = yield this.getInputsForAmount(targets.filter((t) => !t.value), opts.fee, [], true, addressLimit, useChangeUtxos);
|
|
244
368
|
return fee;
|
|
245
369
|
}
|
|
246
370
|
});
|
|
247
371
|
}
|
|
248
|
-
getInputsForAmount(_targets, feePerByte,
|
|
372
|
+
getInputsForAmount(_targets, feePerByte, fixedUtxos = [], sweep = false, addressLimit = exports.NUMBER_ADDRESS_LIMIT, change = false) {
|
|
249
373
|
return __awaiter(this, void 0, void 0, function* () {
|
|
250
374
|
const feePerBytePromise = this.chainProvider.getProvider().getFeePerByte();
|
|
251
375
|
const utxos = [];
|
|
252
|
-
const
|
|
253
|
-
const
|
|
376
|
+
const addressType = change ? AddressSearchType.EXTERNAL_OR_CHANGE : AddressSearchType.EXTERNAL;
|
|
377
|
+
const addresses = yield this.getUsedAddresses(addressType, addressLimit);
|
|
254
378
|
const needsWitness = [types_2.AddressType.BECH32, types_2.AddressType.P2SH_SEGWIT].includes(this._addressType);
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
const
|
|
260
|
-
|
|
261
|
-
const walletAddress = yield this.getWalletAddress(address);
|
|
262
|
-
const utxo = Object.assign(Object.assign({}, input), { value, address, derivationPath: walletAddress.derivationPath, witnessUtxo: needsWitness ? { script: new Uint8Array(0), value } : null });
|
|
263
|
-
fixedUtxos.push(utxo);
|
|
379
|
+
// Enrich fixedUtxos that are missing derivationPath or witnessUtxo
|
|
380
|
+
const enrichedFixedUtxos = yield Promise.all(fixedUtxos.map((utxo) => __awaiter(this, void 0, void 0, function* () {
|
|
381
|
+
let derivationPath = utxo.derivationPath;
|
|
382
|
+
if (derivationPath === undefined) {
|
|
383
|
+
const walletAddress = yield this.getWalletAddress(utxo.address);
|
|
384
|
+
derivationPath = walletAddress.derivationPath;
|
|
264
385
|
}
|
|
265
|
-
|
|
266
|
-
|
|
386
|
+
const witnessUtxo = utxo.witnessUtxo !== undefined
|
|
387
|
+
? utxo.witnessUtxo
|
|
388
|
+
: needsWitness
|
|
389
|
+
? { script: new Uint8Array(0), value: utxo.value }
|
|
390
|
+
: null;
|
|
391
|
+
return Object.assign(Object.assign({}, utxo), { derivationPath, witnessUtxo });
|
|
392
|
+
})));
|
|
393
|
+
if (!sweep || enrichedFixedUtxos.length === 0) {
|
|
267
394
|
const _utxos = yield this.chainProvider.getProvider().getUnspentTransactions(addresses);
|
|
268
395
|
utxos.push(..._utxos.map((utxo) => {
|
|
269
396
|
const addr = addresses.find((a) => a.address === utxo.address);
|
|
270
|
-
return Object.assign(Object.assign({}, utxo), { witnessUtxo: needsWitness ? { script: new Uint8Array(0), value: utxo.value } : null, derivationPath: addr.derivationPath });
|
|
397
|
+
return Object.assign(Object.assign({}, utxo), { witnessUtxo: needsWitness ? { script: new Uint8Array(0), value: utxo.value } : null, derivationPath: addr === null || addr === void 0 ? void 0 : addr.derivationPath });
|
|
271
398
|
}));
|
|
272
399
|
}
|
|
273
400
|
else {
|
|
274
|
-
utxos.push(...
|
|
275
|
-
|
|
401
|
+
utxos.push(...enrichedFixedUtxos.map((utxo) => {
|
|
402
|
+
var _a;
|
|
403
|
+
return (Object.assign(Object.assign({}, utxo), { witnessUtxo: (_a = utxo.witnessUtxo) !== null && _a !== void 0 ? _a : (needsWitness ? { script: new Uint8Array(0), value: utxo.value } : null) }));
|
|
276
404
|
}));
|
|
277
405
|
}
|
|
278
406
|
const utxoBalance = utxos.reduce((a, b) => a + (b.value || 0), 0);
|
|
@@ -307,11 +435,11 @@ class BitcoinBaseWalletProvider extends client_1.Wallet {
|
|
|
307
435
|
else {
|
|
308
436
|
targets = _targets.map((target) => ({ id: 'main', value: target.value, script: target.script, address: target.address }));
|
|
309
437
|
}
|
|
310
|
-
const { inputs, outputs, change, fee } = (0, utils_2.selectCoins)(utxos, targets, Math.ceil(feePerByte));
|
|
438
|
+
const { inputs, outputs, change: changeOutput, fee } = (0, utils_2.selectCoins)(utxos, targets, Math.ceil(feePerByte));
|
|
311
439
|
if (inputs && outputs) {
|
|
312
440
|
return {
|
|
313
441
|
inputs,
|
|
314
|
-
change,
|
|
442
|
+
change: changeOutput,
|
|
315
443
|
outputs,
|
|
316
444
|
fee,
|
|
317
445
|
};
|