beignet 0.0.21 → 0.0.23
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/electrum/index.js +105 -42
- package/dist/electrum/index.js.map +1 -1
- package/dist/types/electrum/index.d.ts +11 -4
- package/dist/types/electrum.js +8 -1
- package/dist/types/electrum.js.map +1 -1
- package/dist/types/types/electrum.d.ts +6 -0
- package/dist/types/types/transaction.d.ts +4 -0
- package/dist/types/types/wallet.d.ts +7 -1
- package/dist/types/utils/helpers.d.ts +2 -0
- package/dist/types/utils/wallet.d.ts +19 -1
- package/dist/types/wallet/constants.d.ts +0 -5
- package/dist/types/wallet/index.d.ts +14 -3
- package/dist/types/wallet.js.map +1 -1
- package/dist/utils/helpers.js +11 -1
- package/dist/utils/helpers.js.map +1 -1
- package/dist/utils/wallet.js +48 -1
- package/dist/utils/wallet.js.map +1 -1
- package/dist/wallet/constants.js +1 -7
- package/dist/wallet/constants.js.map +1 -1
- package/dist/wallet/index.js +181 -86
- package/dist/wallet/index.js.map +1 -1
- package/docs/html/assets/search.js +1 -1
- package/docs/html/classes/Electrum.html +79 -70
- package/docs/html/classes/Transaction.html +59 -28
- package/docs/html/classes/Wallet.html +224 -174
- package/docs/html/enums/EAddressType.html +22 -7
- package/docs/html/enums/EAvailableNetworks.html +19 -11
- package/docs/html/enums/EBoostType.html +14 -6
- package/docs/html/enums/EElectrumNetworks.html +15 -7
- package/docs/html/enums/EFeeId.html +17 -9
- package/docs/html/enums/EPaymentType.html +14 -6
- package/docs/html/enums/EProtocol.html +14 -6
- package/docs/html/enums/EUnit.html +15 -7
- package/docs/html/functions/availableNetworks.html +12 -4
- package/docs/html/functions/constructByteCountParam.html +12 -4
- package/docs/html/functions/decodeOpReturnMessage.html +12 -4
- package/docs/html/functions/decodeRawTransaction.html +12 -4
- package/docs/html/functions/err.html +12 -4
- package/docs/html/functions/formatKeyDerivationPath.html +12 -4
- package/docs/html/functions/formatPeerData.html +12 -4
- package/docs/html/functions/generateMnemonic.html +12 -4
- package/docs/html/functions/generateWalletId.html +12 -4
- package/docs/html/functions/getAddressFromKeyPair.html +222 -0
- package/docs/html/functions/getAddressFromScriptPubKey.html +12 -4
- package/docs/html/functions/getAddressTypeFromPath.html +12 -4
- package/docs/html/functions/getAddressesFromPrivateKey.html +222 -0
- package/docs/html/functions/getByteCount.html +12 -4
- package/docs/html/functions/getDataFallback.html +12 -4
- package/docs/html/functions/getDefaultPort.html +12 -4
- package/docs/html/functions/getDefaultWalletData.html +12 -4
- package/docs/html/functions/getDefaultWalletDataKeys.html +12 -4
- package/docs/html/functions/getElectrumNetwork.html +216 -0
- package/docs/html/functions/getHighestUsedIndexFromTxHashes.html +12 -4
- package/docs/html/functions/getKeyDerivationPath.html +12 -4
- package/docs/html/functions/getKeyDerivationPathObject.html +12 -4
- package/docs/html/functions/getKeyDerivationPathString.html +12 -4
- package/docs/html/functions/getKeyValue.html +12 -4
- package/docs/html/functions/getPeers.html +12 -4
- package/docs/html/functions/getProtocolForPort.html +12 -4
- package/docs/html/functions/getScriptHash.html +12 -4
- package/docs/html/functions/getSeed.html +12 -4
- package/docs/html/functions/getSeedHash.html +12 -4
- package/docs/html/functions/getSha256.html +12 -4
- package/docs/html/functions/getStorageKeyValues.html +12 -4
- package/docs/html/{variables/mostUsedExchangeTickers.html → functions/getTapRootAddressFromPublicKey.html} +74 -97
- package/docs/html/functions/getTxFee.html +12 -4
- package/docs/html/functions/getWalletDataStorageKey.html +12 -4
- package/docs/html/functions/isP2trPrefix.html +217 -0
- package/docs/html/functions/isValidBech32mEncodedString.html +12 -4
- package/docs/html/functions/objectKeys-1.html +12 -4
- package/docs/html/functions/objectsMatch.html +12 -4
- package/docs/html/functions/ok.html +12 -4
- package/docs/html/functions/parseOnChainPaymentRequest.html +12 -4
- package/docs/html/functions/reduceValue.html +12 -4
- package/docs/html/functions/removeDustOutputs.html +12 -4
- package/docs/html/functions/setReplaceByFee.html +12 -4
- package/docs/html/functions/shuffleArray.html +12 -4
- package/docs/html/functions/{getExchangeRates.html → sleep.html} +22 -12
- package/docs/html/functions/validateAddress.html +12 -4
- package/docs/html/functions/validateMnemonic.html +12 -4
- package/docs/html/functions/validateTransaction.html +12 -4
- package/docs/html/index.html +22 -6
- package/docs/html/interfaces/IAddInput.html +16 -8
- package/docs/html/interfaces/IAddress.html +17 -9
- package/docs/html/interfaces/IAddressData.html +15 -7
- package/docs/html/interfaces/IAddressType.html +12 -4
- package/docs/html/interfaces/IAddressTypeData.html +18 -10
- package/docs/html/interfaces/IAddresses.html +12 -4
- package/docs/html/interfaces/IBoostedTransaction.html +16 -8
- package/docs/html/interfaces/IBoostedTransactions.html +12 -4
- package/docs/html/interfaces/ICreateTransaction.html +14 -6
- package/docs/html/interfaces/ICustomGetAddress.html +15 -7
- package/docs/html/interfaces/ICustomGetScriptHash.html +14 -6
- package/docs/html/interfaces/IElectrumGetAddressBalanceRes.html +15 -7
- package/docs/html/interfaces/IFormattedPeerData.html +17 -9
- package/docs/html/interfaces/IFormattedTransaction.html +31 -23
- package/docs/html/interfaces/IFormattedTransactions.html +12 -4
- package/docs/html/interfaces/IGenerateAddresses.html +19 -11
- package/docs/html/interfaces/IGenerateAddressesResponse.html +14 -6
- package/docs/html/interfaces/IGetAddress.html +15 -7
- package/docs/html/interfaces/IGetAddressBalanceRes.html +14 -6
- package/docs/html/interfaces/IGetAddressByPath.html +14 -6
- package/docs/html/interfaces/IGetAddressHistoryResponse.html +19 -11
- package/docs/html/interfaces/IGetAddressResponse.html +15 -7
- package/docs/html/interfaces/IGetAddressScriptHashBalances.html +17 -9
- package/docs/html/interfaces/IGetAddressScriptHashesHistoryResponse.html +17 -9
- package/docs/html/interfaces/{IExchangeRates.html → IGetAddressesFromKeyPair.html} +45 -23
- package/docs/html/interfaces/IGetAddressesFromPrivateKey.html +234 -0
- package/docs/html/interfaces/IGetDerivationPath.html +18 -10
- package/docs/html/interfaces/IGetFeeEstimatesResponse.html +16 -8
- package/docs/html/interfaces/IGetHeaderResponse.html +17 -9
- package/docs/html/interfaces/IGetNextAvailableAddressResponse.html +16 -8
- package/docs/html/interfaces/IGetTransactions.html +17 -9
- package/docs/html/interfaces/IGetTransactionsFromInputs.html +17 -9
- package/docs/html/interfaces/IGetUtxosResponse.html +14 -6
- package/docs/html/interfaces/IHeader.html +15 -7
- package/docs/html/interfaces/IIndexes.html +16 -8
- package/docs/html/interfaces/IKeyDerivationPath.html +17 -9
- package/docs/html/interfaces/IKeyDerivationPathData.html +14 -6
- package/docs/html/interfaces/INewBlock.html +14 -6
- package/docs/html/interfaces/IOnchainFees.html +17 -9
- package/docs/html/interfaces/IOutput.html +15 -7
- package/docs/html/interfaces/IPeerData.html +15 -7
- package/docs/html/interfaces/IPrivateKeyInfo.html +248 -0
- package/docs/html/interfaces/IRbfData.html +18 -10
- package/docs/html/interfaces/ISend.html +14 -6
- package/docs/html/interfaces/ISendTransaction.html +28 -20
- package/docs/html/interfaces/ISendTx.html +15 -7
- package/docs/html/interfaces/ISetupTransaction.html +17 -9
- package/docs/html/interfaces/ISubscribeToAddress.html +16 -8
- package/docs/html/interfaces/ISubscribeToHeader.html +16 -8
- package/docs/html/interfaces/ISweepPrivateKey.html +255 -0
- package/docs/html/interfaces/ISweepPrivateKeyRes.html +241 -0
- package/docs/html/interfaces/ITargets.html +16 -8
- package/docs/html/interfaces/ITransaction.html +17 -9
- package/docs/html/interfaces/ITxHash.html +13 -5
- package/docs/html/interfaces/ITxHashes.html +15 -7
- package/docs/html/interfaces/IUtxo.html +27 -21
- package/docs/html/interfaces/IVin.html +17 -9
- package/docs/html/interfaces/IVout.html +15 -7
- package/docs/html/interfaces/IWallet.html +53 -20
- package/docs/html/interfaces/IWalletData.html +30 -29
- package/docs/html/types/ElectrumConnectionPubSub.html +12 -4
- package/docs/html/types/ElectrumConnectionSubscription.html +13 -5
- package/docs/html/types/InputData.html +12 -4
- package/docs/html/types/ObjectKeys.html +12 -4
- package/docs/html/types/Result.html +12 -4
- package/docs/html/types/TAddressIndexInfo.html +12 -4
- package/docs/html/types/TAddressLabel.html +12 -4
- package/docs/html/types/TAddressType.html +12 -4
- package/docs/html/types/TAddressTypeContent.html +12 -4
- package/docs/html/types/TAddressTypes.html +12 -4
- package/docs/html/types/TAvailableNetworks.html +12 -4
- package/docs/html/types/TConnectToElectrumRes.html +12 -4
- package/docs/html/types/TDecodeRawTx.html +12 -4
- package/docs/html/types/TElectrumNetworks.html +12 -4
- package/docs/html/types/TGetAddressHistory.html +12 -4
- package/docs/html/types/TGetByteCountInput.html +12 -4
- package/docs/html/types/TGetByteCountInputs.html +12 -4
- package/docs/html/types/TGetByteCountOutput.html +12 -4
- package/docs/html/types/TGetByteCountOutputs.html +12 -4
- package/docs/html/types/TGetData.html +12 -4
- package/docs/html/types/TGetTotalFeeObj.html +12 -4
- package/docs/html/types/TKeyDerivationAccount.html +12 -4
- package/docs/html/types/TKeyDerivationChange.html +12 -4
- package/docs/html/types/TKeyDerivationCoinType.html +12 -4
- package/docs/html/types/TKeyDerivationIndex.html +12 -4
- package/docs/html/types/TKeyDerivationPurpose.html +12 -4
- package/docs/html/types/TMessageDataMap.html +12 -4
- package/docs/html/types/TMessageKeys.html +12 -4
- package/docs/html/types/TOnMessage.html +12 -4
- package/docs/html/types/TProcessUnconfirmedTransactions.html +12 -4
- package/docs/html/types/TProtocol.html +12 -4
- package/docs/html/types/TServer.html +12 -4
- package/docs/html/types/TSetData.html +12 -4
- package/docs/html/types/TSetupTransactionResponse.html +12 -4
- package/docs/html/types/TStorage.html +12 -4
- package/docs/html/types/TSubscribedReceive.html +12 -4
- package/docs/html/types/TTransactionMessage.html +12 -4
- package/docs/html/types/TTxResponse.html +12 -4
- package/docs/html/types/TTxResult.html +12 -4
- package/docs/html/types/TUnspentAddressScriptHashData.html +12 -4
- package/docs/html/types/TWalletDataKeys.html +12 -4
- package/docs/html/variables/defaultElectrumPorts.html +12 -4
- package/docs/html/variables/electrumConnection.html +12 -4
- package/docs/markdown/README.md +224 -128
- package/docs/markdown/classes/Electrum.md +74 -72
- package/docs/markdown/classes/Transaction.md +48 -23
- package/docs/markdown/classes/Wallet.md +240 -181
- package/docs/markdown/enums/EAddressType.md +14 -3
- package/docs/markdown/enums/EAvailableNetworks.md +7 -7
- package/docs/markdown/enums/EBoostType.md +2 -2
- package/docs/markdown/enums/EElectrumNetworks.md +3 -3
- package/docs/markdown/enums/EFeeId.md +5 -5
- package/docs/markdown/enums/EPaymentType.md +2 -2
- package/docs/markdown/enums/EProtocol.md +2 -2
- package/docs/markdown/enums/EUnit.md +3 -3
- package/docs/markdown/interfaces/IAddInput.md +4 -4
- package/docs/markdown/interfaces/IAddress.md +5 -5
- package/docs/markdown/interfaces/IAddressData.md +3 -3
- package/docs/markdown/interfaces/IAddressTypeData.md +6 -6
- package/docs/markdown/interfaces/IBoostedTransaction.md +4 -4
- package/docs/markdown/interfaces/ICreateTransaction.md +2 -2
- package/docs/markdown/interfaces/ICustomGetAddress.md +3 -3
- package/docs/markdown/interfaces/ICustomGetScriptHash.md +2 -2
- package/docs/markdown/interfaces/IElectrumGetAddressBalanceRes.md +3 -3
- package/docs/markdown/interfaces/IFormattedPeerData.md +5 -5
- package/docs/markdown/interfaces/IFormattedTransaction.md +19 -19
- package/docs/markdown/interfaces/IGenerateAddresses.md +7 -7
- package/docs/markdown/interfaces/IGenerateAddressesResponse.md +2 -2
- package/docs/markdown/interfaces/IGetAddress.md +3 -3
- package/docs/markdown/interfaces/IGetAddressBalanceRes.md +2 -2
- package/docs/markdown/interfaces/IGetAddressByPath.md +2 -2
- package/docs/markdown/interfaces/IGetAddressHistoryResponse.md +7 -7
- package/docs/markdown/interfaces/IGetAddressResponse.md +3 -3
- package/docs/markdown/interfaces/IGetAddressScriptHashBalances.md +5 -5
- package/docs/markdown/interfaces/IGetAddressScriptHashesHistoryResponse.md +5 -5
- package/docs/markdown/interfaces/IGetAddressesFromKeyPair.md +30 -0
- package/docs/markdown/interfaces/IGetAddressesFromPrivateKey.md +30 -0
- package/docs/markdown/interfaces/IGetDerivationPath.md +6 -6
- package/docs/markdown/interfaces/IGetFeeEstimatesResponse.md +4 -4
- package/docs/markdown/interfaces/IGetHeaderResponse.md +5 -5
- package/docs/markdown/interfaces/IGetNextAvailableAddressResponse.md +4 -4
- package/docs/markdown/interfaces/IGetTransactions.md +5 -5
- package/docs/markdown/interfaces/IGetTransactionsFromInputs.md +5 -5
- package/docs/markdown/interfaces/IGetUtxosResponse.md +2 -2
- package/docs/markdown/interfaces/IHeader.md +3 -3
- package/docs/markdown/interfaces/IIndexes.md +4 -4
- package/docs/markdown/interfaces/IKeyDerivationPath.md +5 -5
- package/docs/markdown/interfaces/IKeyDerivationPathData.md +2 -2
- package/docs/markdown/interfaces/INewBlock.md +2 -2
- package/docs/markdown/interfaces/IOnchainFees.md +5 -5
- package/docs/markdown/interfaces/IOutput.md +3 -3
- package/docs/markdown/interfaces/IPeerData.md +3 -3
- package/docs/markdown/interfaces/IPrivateKeyInfo.md +52 -0
- package/docs/markdown/interfaces/IRbfData.md +6 -6
- package/docs/markdown/interfaces/ISend.md +2 -2
- package/docs/markdown/interfaces/ISendTransaction.md +16 -16
- package/docs/markdown/interfaces/ISendTx.md +3 -3
- package/docs/markdown/interfaces/ISetupTransaction.md +5 -5
- package/docs/markdown/interfaces/ISubscribeToAddress.md +4 -4
- package/docs/markdown/interfaces/ISubscribeToHeader.md +4 -4
- package/docs/markdown/interfaces/ISweepPrivateKey.md +63 -0
- package/docs/markdown/interfaces/ISweepPrivateKeyRes.md +41 -0
- package/docs/markdown/interfaces/ITargets.md +4 -4
- package/docs/markdown/interfaces/ITransaction.md +5 -5
- package/docs/markdown/interfaces/ITxHash.md +1 -1
- package/docs/markdown/interfaces/ITxHashes.md +3 -3
- package/docs/markdown/interfaces/IUtxo.md +18 -23
- package/docs/markdown/interfaces/IVin.md +5 -5
- package/docs/markdown/interfaces/IVout.md +3 -3
- package/docs/markdown/interfaces/IWallet.md +50 -15
- package/docs/markdown/interfaces/IWalletData.md +18 -29
- package/package.json +3 -3
- package/src/electrum/index.ts +147 -60
- package/src/types/electrum.ts +7 -0
- package/src/types/transaction.ts +5 -0
- package/src/types/wallet.ts +7 -1
- package/src/utils/helpers.ts +14 -0
- package/src/utils/wallet.ts +73 -0
- package/src/wallet/constants.ts +0 -8
- package/src/wallet/index.ts +262 -118
- package/tests/wallet.test.ts +71 -1
- package/dist/mempool/index.js +0 -28
- package/dist/mempool/index.js.map +0 -1
- package/dist/types/mempool/index.d.ts +0 -15
- package/dist/types/mempool.js +0 -3
- package/dist/types/mempool.js.map +0 -1
- package/dist/types/types/mempool.d.ts +0 -16
- package/dist/types/utils/exchange-rate.d.ts +0 -30
- package/dist/utils/exchange-rate.js +0 -49
- package/dist/utils/exchange-rate.js.map +0 -1
- package/docs/markdown/interfaces/IExchangeRates.md +0 -7
package/src/wallet/index.ts
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
EBoostType,
|
|
9
9
|
EFeeId,
|
|
10
10
|
EPaymentType,
|
|
11
|
+
EScanningStrategy,
|
|
11
12
|
IAddress,
|
|
12
13
|
IAddresses,
|
|
13
14
|
IBoostedTransaction,
|
|
@@ -46,6 +47,7 @@ import {
|
|
|
46
47
|
TAddressIndexInfo,
|
|
47
48
|
TAddressTypeContent,
|
|
48
49
|
TAvailableNetworks,
|
|
50
|
+
TGapLimitOptions,
|
|
49
51
|
TGetData,
|
|
50
52
|
TGetTotalFeeObj,
|
|
51
53
|
TMessageDataMap,
|
|
@@ -61,11 +63,17 @@ import {
|
|
|
61
63
|
import {
|
|
62
64
|
decodeOpReturnMessage,
|
|
63
65
|
err,
|
|
66
|
+
filterAddressesObjForGapLimit,
|
|
64
67
|
formatKeyDerivationPath,
|
|
68
|
+
generateWalletId,
|
|
69
|
+
getAddressesFromPrivateKey,
|
|
70
|
+
getAddressFromKeyPair,
|
|
71
|
+
getAddressIndexDiff,
|
|
65
72
|
getAddressTypeFromPath,
|
|
66
73
|
getDataFallback,
|
|
67
74
|
getDefaultWalletData,
|
|
68
75
|
getDefaultWalletDataKeys,
|
|
76
|
+
getElectrumNetwork,
|
|
69
77
|
getHighestUsedIndexFromTxHashes,
|
|
70
78
|
getKeyDerivationPath,
|
|
71
79
|
getKeyDerivationPathObject,
|
|
@@ -73,17 +81,14 @@ import {
|
|
|
73
81
|
getScriptHash,
|
|
74
82
|
getSeed,
|
|
75
83
|
getWalletDataStorageKey,
|
|
76
|
-
|
|
84
|
+
isPositive,
|
|
77
85
|
objectKeys,
|
|
78
86
|
objectsMatch,
|
|
79
87
|
ok,
|
|
80
88
|
Result,
|
|
81
89
|
shuffleArray,
|
|
82
90
|
validateAddress,
|
|
83
|
-
validateMnemonic
|
|
84
|
-
getAddressesFromPrivateKey,
|
|
85
|
-
getAddressFromKeyPair,
|
|
86
|
-
getElectrumNetwork
|
|
91
|
+
validateMnemonic
|
|
87
92
|
} from '../utils';
|
|
88
93
|
import {
|
|
89
94
|
addressTypes,
|
|
@@ -93,12 +98,7 @@ import {
|
|
|
93
98
|
} from '../shapes';
|
|
94
99
|
import { Electrum } from '../electrum';
|
|
95
100
|
import { Transaction } from '../transaction';
|
|
96
|
-
import {
|
|
97
|
-
CHUNK_LIMIT,
|
|
98
|
-
GAP_LIMIT,
|
|
99
|
-
GENERATE_ADDRESS_AMOUNT,
|
|
100
|
-
TRANSACTION_DEFAULTS
|
|
101
|
-
} from './constants';
|
|
101
|
+
import { GAP_LIMIT, TRANSACTION_DEFAULTS } from './constants';
|
|
102
102
|
import cloneDeep from 'lodash.clonedeep';
|
|
103
103
|
import { btcToSats } from '../utils/conversion';
|
|
104
104
|
import * as bip39 from 'bip39';
|
|
@@ -136,6 +136,8 @@ export class Wallet {
|
|
|
136
136
|
servers?: TServer | TServer[];
|
|
137
137
|
tls?: TLSSocket;
|
|
138
138
|
net?: Server;
|
|
139
|
+
batchLimit?: number; // Maximum number of requests to be sent in a single batch
|
|
140
|
+
batchDelay?: number; // Delay (in milliseconds) between each batch of requests
|
|
139
141
|
};
|
|
140
142
|
public electrum: Electrum;
|
|
141
143
|
public addressType: EAddressType;
|
|
@@ -145,6 +147,7 @@ export class Wallet {
|
|
|
145
147
|
public rbf: boolean;
|
|
146
148
|
public selectedFeeId: EFeeId;
|
|
147
149
|
public disableMessages: boolean;
|
|
150
|
+
public gapLimitOptions: TGapLimitOptions;
|
|
148
151
|
private constructor({
|
|
149
152
|
mnemonic,
|
|
150
153
|
passphrase,
|
|
@@ -152,7 +155,7 @@ export class Wallet {
|
|
|
152
155
|
network = EAvailableNetworks.mainnet,
|
|
153
156
|
addressType = EAddressType.p2wpkh,
|
|
154
157
|
storage,
|
|
155
|
-
electrumOptions,
|
|
158
|
+
electrumOptions = {},
|
|
156
159
|
onMessage = (): null => null,
|
|
157
160
|
customGetAddress,
|
|
158
161
|
customGetScriptHash,
|
|
@@ -160,7 +163,11 @@ export class Wallet {
|
|
|
160
163
|
selectedFeeId = EFeeId.normal,
|
|
161
164
|
disableMessages = false,
|
|
162
165
|
disableMessagesOnCreate = false,
|
|
163
|
-
addressTypesToMonitor = Object.values(EAddressType)
|
|
166
|
+
addressTypesToMonitor = Object.values(EAddressType),
|
|
167
|
+
gapLimitOptions = {
|
|
168
|
+
lookBehind: GAP_LIMIT,
|
|
169
|
+
lookAhead: GAP_LIMIT
|
|
170
|
+
}
|
|
164
171
|
}: IWallet) {
|
|
165
172
|
if (!mnemonic) throw new Error('No mnemonic specified.');
|
|
166
173
|
if (!validateMnemonic(mnemonic)) throw new Error('Invalid mnemonic.');
|
|
@@ -199,9 +206,7 @@ export class Wallet {
|
|
|
199
206
|
this.electrum = new Electrum({
|
|
200
207
|
wallet: this,
|
|
201
208
|
network: this.network,
|
|
202
|
-
|
|
203
|
-
tls: electrumOptions?.tls,
|
|
204
|
-
net: electrumOptions?.net
|
|
209
|
+
...electrumOptions
|
|
205
210
|
});
|
|
206
211
|
this.rbf = rbf;
|
|
207
212
|
this.selectedFeeId = selectedFeeId;
|
|
@@ -213,6 +218,14 @@ export class Wallet {
|
|
|
213
218
|
}
|
|
214
219
|
// Remove duplicates
|
|
215
220
|
this.addressTypesToMonitor = [...new Set(this.addressTypesToMonitor)];
|
|
221
|
+
this.gapLimitOptions = {
|
|
222
|
+
lookBehind: isPositive(gapLimitOptions.lookBehind)
|
|
223
|
+
? gapLimitOptions.lookBehind
|
|
224
|
+
: 1,
|
|
225
|
+
lookAhead: isPositive(gapLimitOptions.lookAhead)
|
|
226
|
+
? gapLimitOptions.lookAhead
|
|
227
|
+
: 1
|
|
228
|
+
};
|
|
216
229
|
}
|
|
217
230
|
|
|
218
231
|
public get data(): IWalletData {
|
|
@@ -289,8 +302,7 @@ export class Wallet {
|
|
|
289
302
|
|
|
290
303
|
/**
|
|
291
304
|
* Refreshes/Syncs the wallet data.
|
|
292
|
-
* @param {boolean} scanAllAddresses
|
|
293
|
-
* @param {boolean} updateAllAddressTypes
|
|
305
|
+
* @param {boolean} [scanAllAddresses]
|
|
294
306
|
* @returns {Promise<Result<IWalletData>>}
|
|
295
307
|
*/
|
|
296
308
|
public async refreshWallet({ scanAllAddresses = false } = {}): Promise<
|
|
@@ -308,7 +320,9 @@ export class Wallet {
|
|
|
308
320
|
if (r1.isErr()) {
|
|
309
321
|
return this._handleRefreshError(r1.error.message);
|
|
310
322
|
}
|
|
311
|
-
const r2 = await this.getUtxos({
|
|
323
|
+
const r2 = await this.getUtxos({
|
|
324
|
+
scanningStrategy: scanAllAddresses ? EScanningStrategy.all : undefined
|
|
325
|
+
});
|
|
312
326
|
if (r2.isErr()) {
|
|
313
327
|
return this._handleRefreshError(r2.error.message);
|
|
314
328
|
}
|
|
@@ -887,93 +901,92 @@ export class Wallet {
|
|
|
887
901
|
let lastUsedChangeAddressIndex =
|
|
888
902
|
currentWallet.lastUsedChangeAddressIndex[addressType];
|
|
889
903
|
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
904
|
+
const startingAddressIndex = addressIndex?.index ?? 0;
|
|
905
|
+
const startingChangeAddressIndex = changeAddressIndex?.index ?? 0;
|
|
906
|
+
|
|
907
|
+
const addressIndexDiff = getAddressIndexDiff(
|
|
908
|
+
startingAddressIndex,
|
|
909
|
+
lastUsedAddressIndex.index
|
|
910
|
+
);
|
|
911
|
+
const addressesToGenerate =
|
|
912
|
+
this.gapLimitOptions.lookAhead - addressIndexDiff;
|
|
913
|
+
let shouldSaveAddresses = false;
|
|
914
|
+
let shouldSaveChangeAddresses = false;
|
|
915
|
+
if (addressesToGenerate > 0) {
|
|
916
|
+
const generatedAddresses = await this.addAddresses({
|
|
917
|
+
addressAmount: addressesToGenerate,
|
|
893
918
|
addressIndex: 0,
|
|
894
919
|
changeAddressAmount: 0,
|
|
895
920
|
keyDerivationPath,
|
|
896
|
-
addressType
|
|
921
|
+
addressType,
|
|
922
|
+
saveAddresses: false
|
|
897
923
|
});
|
|
898
924
|
if (generatedAddresses.isErr()) {
|
|
899
925
|
return err(generatedAddresses.error);
|
|
900
926
|
}
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
const generatedAddresses = await this.generateAddresses({
|
|
910
|
-
addressAmount: 0,
|
|
911
|
-
changeAddressAmount: GENERATE_ADDRESS_AMOUNT,
|
|
912
|
-
changeAddressIndex: 0,
|
|
913
|
-
keyDerivationPath,
|
|
914
|
-
addressType
|
|
915
|
-
});
|
|
916
|
-
if (generatedAddresses.isErr()) {
|
|
917
|
-
return err(generatedAddresses.error);
|
|
927
|
+
shouldSaveAddresses = true;
|
|
928
|
+
if (addressIndex.index < 0) {
|
|
929
|
+
const addresses = generatedAddresses.value.addresses;
|
|
930
|
+
const sorted = Object.values(addresses).sort(
|
|
931
|
+
(a, b) => a.index - b.index
|
|
932
|
+
);
|
|
933
|
+
if (sorted.length >= 1 && sorted[0].index >= 0)
|
|
934
|
+
addressIndex = sorted[0];
|
|
918
935
|
}
|
|
919
|
-
const addresses = generatedAddresses.value.changeAddresses;
|
|
920
|
-
const sorted = Object.values(addresses).sort(
|
|
921
|
-
(a, b) => a.index - b.index
|
|
922
|
-
);
|
|
923
|
-
changeAddressIndex = sorted[0];
|
|
924
936
|
}
|
|
925
937
|
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
const changeAddressCount = Object.values(changeAddresses).length;
|
|
933
|
-
|
|
934
|
-
/*
|
|
935
|
-
* Create more addresses if less than the default GENERATE_ADDRESS_AMOUNT or the highest address index matches the current address count
|
|
936
|
-
*/
|
|
938
|
+
const changeAddressIndexDiff = getAddressIndexDiff(
|
|
939
|
+
startingChangeAddressIndex,
|
|
940
|
+
lastUsedChangeAddressIndex.index
|
|
941
|
+
);
|
|
942
|
+
const changeAddressesToGenerate =
|
|
943
|
+
this.gapLimitOptions.lookAhead - changeAddressIndexDiff;
|
|
937
944
|
|
|
938
|
-
if (
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
const newAddresses = await this.addAddresses({
|
|
943
|
-
addressAmount: GENERATE_ADDRESS_AMOUNT,
|
|
944
|
-
changeAddressAmount: 0,
|
|
945
|
-
addressIndex: addressIndex.index,
|
|
945
|
+
if (changeAddressesToGenerate > 0) {
|
|
946
|
+
const generatedAddresses = await this.addAddresses({
|
|
947
|
+
addressAmount: 0,
|
|
948
|
+
changeAddressAmount: changeAddressesToGenerate,
|
|
946
949
|
changeAddressIndex: 0,
|
|
947
950
|
keyDerivationPath,
|
|
948
951
|
addressType,
|
|
949
952
|
saveAddresses: false
|
|
950
953
|
});
|
|
951
|
-
if (
|
|
952
|
-
|
|
954
|
+
if (generatedAddresses.isErr()) {
|
|
955
|
+
return err(generatedAddresses.error);
|
|
956
|
+
}
|
|
957
|
+
shouldSaveChangeAddresses = true;
|
|
958
|
+
if (changeAddressIndex.index < 0) {
|
|
959
|
+
const changeAddresses = generatedAddresses.value.changeAddresses;
|
|
960
|
+
const sorted = Object.values(changeAddresses).sort(
|
|
961
|
+
(a, b) => a.index - b.index
|
|
962
|
+
);
|
|
963
|
+
if (sorted.length >= 1 && sorted[0].index >= 0)
|
|
964
|
+
changeAddressIndex = sorted[0];
|
|
953
965
|
}
|
|
954
966
|
}
|
|
955
967
|
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
if (
|
|
961
|
-
changeAddressCount < GENERATE_ADDRESS_AMOUNT ||
|
|
962
|
-
changeAddressIndex.index === changeAddressCount
|
|
963
|
-
) {
|
|
964
|
-
const newChangeAddresses = await this.addAddresses({
|
|
965
|
-
addressAmount: 0,
|
|
966
|
-
changeAddressAmount: GENERATE_ADDRESS_AMOUNT,
|
|
967
|
-
addressIndex: 0,
|
|
968
|
-
changeAddressIndex: changeAddressIndex.index,
|
|
969
|
-
keyDerivationPath,
|
|
970
|
-
addressType,
|
|
971
|
-
saveAddresses: false
|
|
972
|
-
});
|
|
973
|
-
if (newChangeAddresses.isOk()) {
|
|
974
|
-
changeAddresses = newChangeAddresses.value.changeAddresses;
|
|
975
|
-
}
|
|
968
|
+
// Save any addresses that have been created thus far if necessary.
|
|
969
|
+
const promises: Promise<string>[] = [];
|
|
970
|
+
if (shouldSaveAddresses) {
|
|
971
|
+
promises.push(this.saveWalletData('addresses', this._data.addresses));
|
|
976
972
|
}
|
|
973
|
+
if (shouldSaveChangeAddresses) {
|
|
974
|
+
promises.push(
|
|
975
|
+
this.saveWalletData('changeAddresses', this._data.changeAddresses)
|
|
976
|
+
);
|
|
977
|
+
}
|
|
978
|
+
await Promise.all(promises);
|
|
979
|
+
|
|
980
|
+
let addresses = filterAddressesObjForGapLimit({
|
|
981
|
+
addresses: this._data.addresses[addressType],
|
|
982
|
+
index: addressIndex.index,
|
|
983
|
+
gapLimitOptions: this.gapLimitOptions
|
|
984
|
+
});
|
|
985
|
+
let changeAddresses = filterAddressesObjForGapLimit({
|
|
986
|
+
addresses: this._data.changeAddresses[addressType],
|
|
987
|
+
index: changeAddressIndex.index,
|
|
988
|
+
gapLimitOptions: this.gapLimitOptions
|
|
989
|
+
});
|
|
977
990
|
|
|
978
991
|
//Store all addresses that are to be searched and used in this method.
|
|
979
992
|
let allAddresses = Object.values(addresses).filter(
|
|
@@ -1024,8 +1037,8 @@ export class Wallet {
|
|
|
1024
1037
|
txHashes,
|
|
1025
1038
|
addresses,
|
|
1026
1039
|
changeAddresses,
|
|
1027
|
-
addressIndex,
|
|
1028
|
-
changeAddressIndex
|
|
1040
|
+
addressIndex: lastUsedAddressIndex,
|
|
1041
|
+
changeAddressIndex: lastUsedChangeAddressIndex
|
|
1029
1042
|
});
|
|
1030
1043
|
|
|
1031
1044
|
if (highestUsedIndex.isErr()) {
|
|
@@ -1033,12 +1046,15 @@ export class Wallet {
|
|
|
1033
1046
|
return lastKnownIndexes;
|
|
1034
1047
|
}
|
|
1035
1048
|
|
|
1036
|
-
addressIndex = highestUsedIndex.value.addressIndex;
|
|
1037
|
-
changeAddressIndex = highestUsedIndex.value.changeAddressIndex;
|
|
1038
1049
|
if (highestUsedIndex.value.foundAddressIndex) {
|
|
1050
|
+
lastUsedAddressIndex = highestUsedIndex.value.addressIndex;
|
|
1051
|
+
addressIndex = highestUsedIndex.value.addressIndex;
|
|
1039
1052
|
addressHasBeenUsed = true;
|
|
1040
1053
|
}
|
|
1041
1054
|
if (highestUsedIndex.value.foundChangeAddressIndex) {
|
|
1055
|
+
lastUsedChangeAddressIndex =
|
|
1056
|
+
highestUsedIndex.value.changeAddressIndex;
|
|
1057
|
+
changeAddressIndex = highestUsedIndex.value.changeAddressIndex;
|
|
1042
1058
|
changeAddressHasBeenUsed = true;
|
|
1043
1059
|
}
|
|
1044
1060
|
|
|
@@ -1060,13 +1076,20 @@ export class Wallet {
|
|
|
1060
1076
|
changeAddressIndex: highestStoredChangeAddressIndex
|
|
1061
1077
|
} = highestStoredIndex.value;
|
|
1062
1078
|
|
|
1063
|
-
if (
|
|
1079
|
+
if (
|
|
1080
|
+
getAddressIndexDiff(
|
|
1081
|
+
highestUsedAddressIndex.index,
|
|
1082
|
+
highestStoredAddressIndex.index
|
|
1083
|
+
) >= this.gapLimitOptions.lookAhead
|
|
1084
|
+
) {
|
|
1064
1085
|
foundLastUsedAddress = true;
|
|
1065
1086
|
}
|
|
1066
1087
|
|
|
1067
1088
|
if (
|
|
1068
|
-
|
|
1069
|
-
|
|
1089
|
+
getAddressIndexDiff(
|
|
1090
|
+
highestUsedChangeAddressIndex.index,
|
|
1091
|
+
highestStoredChangeAddressIndex.index
|
|
1092
|
+
) >= this.gapLimitOptions.lookAhead
|
|
1070
1093
|
) {
|
|
1071
1094
|
foundLastUsedChangeAddress = true;
|
|
1072
1095
|
}
|
|
@@ -1108,6 +1131,10 @@ export class Wallet {
|
|
|
1108
1131
|
if (!nextAvailableAddress || !nextAvailableChangeAddress) {
|
|
1109
1132
|
return lastKnownIndexes;
|
|
1110
1133
|
}
|
|
1134
|
+
await Promise.all([
|
|
1135
|
+
this.saveWalletData('addresses', this._data.addresses),
|
|
1136
|
+
this.saveWalletData('changeAddresses', this._data.changeAddresses)
|
|
1137
|
+
]);
|
|
1111
1138
|
return ok({
|
|
1112
1139
|
addressIndex: nextAvailableAddress,
|
|
1113
1140
|
lastUsedAddressIndex,
|
|
@@ -1118,10 +1145,16 @@ export class Wallet {
|
|
|
1118
1145
|
|
|
1119
1146
|
//Create receiving addresses for the next round
|
|
1120
1147
|
if (!foundLastUsedAddress) {
|
|
1148
|
+
const addressAmount =
|
|
1149
|
+
this.gapLimitOptions.lookAhead -
|
|
1150
|
+
getAddressIndexDiff(
|
|
1151
|
+
highestUsedAddressIndex.index,
|
|
1152
|
+
highestStoredAddressIndex.index
|
|
1153
|
+
);
|
|
1121
1154
|
const newAddresses = await this.addAddresses({
|
|
1122
|
-
addressAmount
|
|
1155
|
+
addressAmount,
|
|
1123
1156
|
changeAddressAmount: 0,
|
|
1124
|
-
addressIndex: highestStoredIndex.value.addressIndex.index,
|
|
1157
|
+
addressIndex: highestStoredIndex.value.addressIndex.index + 1,
|
|
1125
1158
|
changeAddressIndex: 0,
|
|
1126
1159
|
keyDerivationPath,
|
|
1127
1160
|
addressType,
|
|
@@ -1133,12 +1166,18 @@ export class Wallet {
|
|
|
1133
1166
|
}
|
|
1134
1167
|
//Create change addresses for the next round
|
|
1135
1168
|
if (!foundLastUsedChangeAddress) {
|
|
1169
|
+
const changeAddressAmount =
|
|
1170
|
+
this.gapLimitOptions.lookAhead -
|
|
1171
|
+
getAddressIndexDiff(
|
|
1172
|
+
highestUsedChangeAddressIndex.index,
|
|
1173
|
+
highestStoredChangeAddressIndex.index
|
|
1174
|
+
);
|
|
1136
1175
|
const newChangeAddresses = await this.addAddresses({
|
|
1137
1176
|
addressAmount: 0,
|
|
1138
|
-
changeAddressAmount
|
|
1177
|
+
changeAddressAmount,
|
|
1139
1178
|
addressIndex: 0,
|
|
1140
1179
|
changeAddressIndex:
|
|
1141
|
-
highestStoredIndex.value.changeAddressIndex.index,
|
|
1180
|
+
highestStoredIndex.value.changeAddressIndex.index + 1,
|
|
1142
1181
|
keyDerivationPath,
|
|
1143
1182
|
addressType,
|
|
1144
1183
|
saveAddresses: false
|
|
@@ -1158,6 +1197,12 @@ export class Wallet {
|
|
|
1158
1197
|
// Store the newly created addresses used for this method.
|
|
1159
1198
|
allAddresses = [...allAddresses, ...addressesToScan];
|
|
1160
1199
|
allChangeAddresses = [...allChangeAddresses, ...changeAddressesToScan];
|
|
1200
|
+
// Check UTXO's as we generate addresses.
|
|
1201
|
+
await this.getUtxos({
|
|
1202
|
+
addressIndex: addressIndex.index,
|
|
1203
|
+
changeAddressIndex: changeAddressIndex.index,
|
|
1204
|
+
addressTypesToCheck: [addressType]
|
|
1205
|
+
});
|
|
1161
1206
|
}
|
|
1162
1207
|
|
|
1163
1208
|
await Promise.all([
|
|
@@ -1389,8 +1434,8 @@ export class Wallet {
|
|
|
1389
1434
|
const lastUsedIndex =
|
|
1390
1435
|
lastUsedAddressIndex.index > 0 ? lastUsedAddressIndex.index : 0;
|
|
1391
1436
|
const currentGap = Math.abs(addressIndex.index - lastUsedIndex);
|
|
1392
|
-
if (currentGap >
|
|
1393
|
-
const excessAmount = currentGap -
|
|
1437
|
+
if (currentGap > this.gapLimitOptions.lookBehind) {
|
|
1438
|
+
const excessAmount = currentGap - this.gapLimitOptions.lookBehind;
|
|
1394
1439
|
const newIndex = addressIndex.index - excessAmount;
|
|
1395
1440
|
const _addressIndex = await this.generateAddresses({
|
|
1396
1441
|
addressType: addressTypeKey,
|
|
@@ -1411,8 +1456,8 @@ export class Wallet {
|
|
|
1411
1456
|
const currentChangeAddressGap = Math.abs(
|
|
1412
1457
|
changeAddressIndex.index - lastUsedChangeIndex
|
|
1413
1458
|
);
|
|
1414
|
-
if (currentChangeAddressGap >
|
|
1415
|
-
const excessAmount = currentGap -
|
|
1459
|
+
if (currentChangeAddressGap > this.gapLimitOptions.lookBehind) {
|
|
1460
|
+
const excessAmount = currentGap - this.gapLimitOptions.lookBehind;
|
|
1416
1461
|
const newIndex = addressIndex.index - excessAmount;
|
|
1417
1462
|
const _changeAddressIndex = await this.generateAddresses({
|
|
1418
1463
|
addressType: addressTypeKey,
|
|
@@ -1516,7 +1561,7 @@ export class Wallet {
|
|
|
1516
1561
|
const { addressDelta } = getGapLimitResponse.value;
|
|
1517
1562
|
|
|
1518
1563
|
// If the address delta exceeds the default gap limit, only return the current address index.
|
|
1519
|
-
if (addressDelta >=
|
|
1564
|
+
if (addressDelta >= this.gapLimitOptions.lookBehind) {
|
|
1520
1565
|
const addressIndex = currentWallet.addressIndex;
|
|
1521
1566
|
const receiveAddress = addressIndex[addressType];
|
|
1522
1567
|
return ok(receiveAddress);
|
|
@@ -1612,16 +1657,30 @@ export class Wallet {
|
|
|
1612
1657
|
|
|
1613
1658
|
/**
|
|
1614
1659
|
* Retrieves and sets UTXO's for the current wallet from Electrum.
|
|
1615
|
-
* @param {
|
|
1660
|
+
* @param {EScanningStrategy} [scanningStrategy]
|
|
1661
|
+
* @param {number} addressIndex
|
|
1662
|
+
* @param {number} changeAddressIndex
|
|
1663
|
+
* @param {EAddressType[]} [addressTypesToCheck]
|
|
1616
1664
|
* @returns {Promise<Result<IGetUtxosResponse>>}
|
|
1617
1665
|
*/
|
|
1618
1666
|
public async getUtxos({
|
|
1619
|
-
|
|
1667
|
+
scanningStrategy = EScanningStrategy.gapLimit,
|
|
1668
|
+
addressIndex,
|
|
1669
|
+
changeAddressIndex,
|
|
1670
|
+
addressTypesToCheck
|
|
1671
|
+
}: {
|
|
1672
|
+
scanningStrategy?: EScanningStrategy;
|
|
1673
|
+
addressIndex?: number;
|
|
1674
|
+
changeAddressIndex?: number;
|
|
1675
|
+
addressTypesToCheck?: EAddressType[];
|
|
1620
1676
|
}): Promise<Result<IGetUtxosResponse>> {
|
|
1621
1677
|
const checkRes = await this.checkElectrumConnection();
|
|
1622
1678
|
if (checkRes.isErr()) return err(checkRes.error.message);
|
|
1623
1679
|
const getUtxosRes = await this.electrum.getUtxos({
|
|
1624
|
-
|
|
1680
|
+
scanningStrategy,
|
|
1681
|
+
addressIndex,
|
|
1682
|
+
changeAddressIndex,
|
|
1683
|
+
addressTypesToCheck
|
|
1625
1684
|
});
|
|
1626
1685
|
if (getUtxosRes.isErr()) {
|
|
1627
1686
|
return err(getUtxosRes.error.message);
|
|
@@ -1805,15 +1864,57 @@ export class Wallet {
|
|
|
1805
1864
|
};
|
|
1806
1865
|
await this.saveWalletData('transactions', this._data.transactions);
|
|
1807
1866
|
|
|
1867
|
+
confirmedTxs.forEach((tx) => {
|
|
1868
|
+
this.sendMessage('transactionConfirmed', tx);
|
|
1869
|
+
});
|
|
1870
|
+
|
|
1808
1871
|
sentTxs.forEach((tx) => {
|
|
1809
1872
|
this.sendMessage('transactionSent', tx);
|
|
1810
1873
|
});
|
|
1811
|
-
|
|
1874
|
+
|
|
1875
|
+
const addresses = this.data.addresses;
|
|
1876
|
+
const utxoScriptHashes = new Set(
|
|
1877
|
+
this.data.utxos.map((utxo) => utxo.scriptHash)
|
|
1878
|
+
);
|
|
1879
|
+
const outsideGapLimitAddresses: {
|
|
1880
|
+
[key: string]: number[];
|
|
1881
|
+
} = {};
|
|
1882
|
+
for (const tx of receivedTxs) {
|
|
1812
1883
|
this.sendMessage('transactionReceived', tx);
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1884
|
+
// No need to scan an address with a saved UTXO.
|
|
1885
|
+
if (utxoScriptHashes.has(tx.transaction.scriptHash)) continue;
|
|
1886
|
+
for (const addressType in addresses) {
|
|
1887
|
+
const addressData: IAddresses = addresses[addressType];
|
|
1888
|
+
if (tx.transaction.scriptHash in addressData) {
|
|
1889
|
+
const address = addressData[tx.transaction.scriptHash];
|
|
1890
|
+
const index = address.index;
|
|
1891
|
+
const currentIndex = this.data.addressIndex[addressType].index;
|
|
1892
|
+
const diff = getAddressIndexDiff(index, currentIndex);
|
|
1893
|
+
if (diff > this.gapLimitOptions.lookBehind) {
|
|
1894
|
+
outsideGapLimitAddresses[addressType] = [
|
|
1895
|
+
...(outsideGapLimitAddresses[addressType] ?? []),
|
|
1896
|
+
index
|
|
1897
|
+
];
|
|
1898
|
+
}
|
|
1899
|
+
break;
|
|
1900
|
+
}
|
|
1901
|
+
}
|
|
1902
|
+
}
|
|
1903
|
+
if (receivedTxs.length > 0) {
|
|
1904
|
+
// Scan for received transactions to addresses out of the specified gap limit that we may still be subscribed to from the current session.
|
|
1905
|
+
for (const type of Object.keys(outsideGapLimitAddresses)) {
|
|
1906
|
+
const indexes = outsideGapLimitAddresses[type];
|
|
1907
|
+
if (indexes.length <= 0) continue;
|
|
1908
|
+
const lowestIndex = Math.min(...indexes);
|
|
1909
|
+
const addressType = type as EAddressType;
|
|
1910
|
+
await this.getUtxos({
|
|
1911
|
+
scanningStrategy: EScanningStrategy.startingIndex,
|
|
1912
|
+
addressIndex: lowestIndex - this.gapLimitOptions.lookBehind,
|
|
1913
|
+
changeAddressIndex: lowestIndex - this.gapLimitOptions.lookBehind,
|
|
1914
|
+
addressTypesToCheck: [addressType]
|
|
1915
|
+
});
|
|
1916
|
+
}
|
|
1917
|
+
}
|
|
1817
1918
|
|
|
1818
1919
|
return ok(notificationTxid);
|
|
1819
1920
|
}
|
|
@@ -2130,7 +2231,7 @@ export class Wallet {
|
|
|
2130
2231
|
const unconfirmedTransactions: IFormattedTransactions = {};
|
|
2131
2232
|
Object.keys(transactions).forEach((key) => {
|
|
2132
2233
|
const confirmations = this.blockHeightToConfirmations({
|
|
2133
|
-
blockHeight: transactions[key]
|
|
2234
|
+
blockHeight: transactions[key]?.height ?? 0
|
|
2134
2235
|
});
|
|
2135
2236
|
if (confirmations < 6) {
|
|
2136
2237
|
unconfirmedTransactions[key] = transactions[key];
|
|
@@ -2170,7 +2271,7 @@ export class Wallet {
|
|
|
2170
2271
|
blockHeight?: number;
|
|
2171
2272
|
currentHeight?: number;
|
|
2172
2273
|
}): number {
|
|
2173
|
-
if (!blockHeight) {
|
|
2274
|
+
if (!blockHeight || blockHeight <= 0) {
|
|
2174
2275
|
return 0;
|
|
2175
2276
|
}
|
|
2176
2277
|
if (!currentHeight) {
|
|
@@ -2365,9 +2466,9 @@ export class Wallet {
|
|
|
2365
2466
|
try {
|
|
2366
2467
|
const inputData: InputData = {};
|
|
2367
2468
|
|
|
2368
|
-
const
|
|
2369
|
-
for (let i = 0; i < inputs.length; i +=
|
|
2370
|
-
const chunk = inputs.slice(i, i +
|
|
2469
|
+
const batchLimit = this.electrum.batchLimit;
|
|
2470
|
+
for (let i = 0; i < inputs.length; i += batchLimit) {
|
|
2471
|
+
const chunk = inputs.slice(i, i + batchLimit);
|
|
2371
2472
|
|
|
2372
2473
|
const getTransactionsResponse =
|
|
2373
2474
|
await this.electrum.getTransactionsFromInputs({
|
|
@@ -2786,10 +2887,12 @@ export class Wallet {
|
|
|
2786
2887
|
if (!Object.keys(addresses).length) {
|
|
2787
2888
|
await this.addAddresses({
|
|
2788
2889
|
addressAmount:
|
|
2789
|
-
indexToUpdate === 'addressIndex' ?
|
|
2890
|
+
indexToUpdate === 'addressIndex' ? this.gapLimitOptions.lookAhead : 0,
|
|
2790
2891
|
addressIndex: index,
|
|
2791
2892
|
changeAddressAmount:
|
|
2792
|
-
indexToUpdate === 'changeAddressIndex'
|
|
2893
|
+
indexToUpdate === 'changeAddressIndex'
|
|
2894
|
+
? this.gapLimitOptions.lookAhead
|
|
2895
|
+
: 0,
|
|
2793
2896
|
changeAddressIndex: index,
|
|
2794
2897
|
addressType,
|
|
2795
2898
|
saveAddresses: false
|
|
@@ -2964,6 +3067,7 @@ export class Wallet {
|
|
|
2964
3067
|
}
|
|
2965
3068
|
path = allAddresses[scriptHash].path;
|
|
2966
3069
|
value = btcToSats(txVout.value);
|
|
3070
|
+
const publicKey = allAddresses[scriptHash].publicKey;
|
|
2967
3071
|
inputs.push({
|
|
2968
3072
|
tx_hash: input.txid,
|
|
2969
3073
|
index: input.vout,
|
|
@@ -2972,7 +3076,8 @@ export class Wallet {
|
|
|
2972
3076
|
address,
|
|
2973
3077
|
scriptHash,
|
|
2974
3078
|
path,
|
|
2975
|
-
value
|
|
3079
|
+
value,
|
|
3080
|
+
publicKey
|
|
2976
3081
|
});
|
|
2977
3082
|
if (value) {
|
|
2978
3083
|
inputTotal = inputTotal + value;
|
|
@@ -3502,4 +3607,43 @@ export class Wallet {
|
|
|
3502
3607
|
response.id = broadcastResponse.value;
|
|
3503
3608
|
return ok(response);
|
|
3504
3609
|
}
|
|
3610
|
+
|
|
3611
|
+
public getAddressInfoFromScriptHash(scriptHash: string): Result<{
|
|
3612
|
+
address: IAddress;
|
|
3613
|
+
addressType: EAddressType;
|
|
3614
|
+
}> {
|
|
3615
|
+
const addresses = this.data.addresses;
|
|
3616
|
+
let address: { address: IAddress; addressType: EAddressType } | undefined;
|
|
3617
|
+
for (const addressType in addresses) {
|
|
3618
|
+
if (scriptHash in addresses[addressType]) {
|
|
3619
|
+
address = {
|
|
3620
|
+
address: addresses[addressType][scriptHash],
|
|
3621
|
+
addressType: addressType as EAddressType
|
|
3622
|
+
};
|
|
3623
|
+
break; // Exit the loop once the address is found
|
|
3624
|
+
}
|
|
3625
|
+
}
|
|
3626
|
+
return address ? ok(address) : err('Address not found');
|
|
3627
|
+
}
|
|
3628
|
+
|
|
3629
|
+
/**
|
|
3630
|
+
* Allows the user to update the gap limit options.
|
|
3631
|
+
* @param gapLimitOptions
|
|
3632
|
+
* @returns {Promise<Result<TGapLimitOptions>>}
|
|
3633
|
+
*/
|
|
3634
|
+
public updateGapLimit(
|
|
3635
|
+
gapLimitOptions: TGapLimitOptions
|
|
3636
|
+
): Result<TGapLimitOptions> {
|
|
3637
|
+
if (!gapLimitOptions) {
|
|
3638
|
+
return err('No gap limit options provided.');
|
|
3639
|
+
}
|
|
3640
|
+
if (
|
|
3641
|
+
!isPositive(gapLimitOptions.lookAhead) ||
|
|
3642
|
+
!isPositive(gapLimitOptions.lookBehind)
|
|
3643
|
+
) {
|
|
3644
|
+
return err('Both gap limit options must be positive.');
|
|
3645
|
+
}
|
|
3646
|
+
this.gapLimitOptions = gapLimitOptions;
|
|
3647
|
+
return ok(this.gapLimitOptions);
|
|
3648
|
+
}
|
|
3505
3649
|
}
|