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.
Files changed (273) hide show
  1. package/dist/electrum/index.js +105 -42
  2. package/dist/electrum/index.js.map +1 -1
  3. package/dist/types/electrum/index.d.ts +11 -4
  4. package/dist/types/electrum.js +8 -1
  5. package/dist/types/electrum.js.map +1 -1
  6. package/dist/types/types/electrum.d.ts +6 -0
  7. package/dist/types/types/transaction.d.ts +4 -0
  8. package/dist/types/types/wallet.d.ts +7 -1
  9. package/dist/types/utils/helpers.d.ts +2 -0
  10. package/dist/types/utils/wallet.d.ts +19 -1
  11. package/dist/types/wallet/constants.d.ts +0 -5
  12. package/dist/types/wallet/index.d.ts +14 -3
  13. package/dist/types/wallet.js.map +1 -1
  14. package/dist/utils/helpers.js +11 -1
  15. package/dist/utils/helpers.js.map +1 -1
  16. package/dist/utils/wallet.js +48 -1
  17. package/dist/utils/wallet.js.map +1 -1
  18. package/dist/wallet/constants.js +1 -7
  19. package/dist/wallet/constants.js.map +1 -1
  20. package/dist/wallet/index.js +181 -86
  21. package/dist/wallet/index.js.map +1 -1
  22. package/docs/html/assets/search.js +1 -1
  23. package/docs/html/classes/Electrum.html +79 -70
  24. package/docs/html/classes/Transaction.html +59 -28
  25. package/docs/html/classes/Wallet.html +224 -174
  26. package/docs/html/enums/EAddressType.html +22 -7
  27. package/docs/html/enums/EAvailableNetworks.html +19 -11
  28. package/docs/html/enums/EBoostType.html +14 -6
  29. package/docs/html/enums/EElectrumNetworks.html +15 -7
  30. package/docs/html/enums/EFeeId.html +17 -9
  31. package/docs/html/enums/EPaymentType.html +14 -6
  32. package/docs/html/enums/EProtocol.html +14 -6
  33. package/docs/html/enums/EUnit.html +15 -7
  34. package/docs/html/functions/availableNetworks.html +12 -4
  35. package/docs/html/functions/constructByteCountParam.html +12 -4
  36. package/docs/html/functions/decodeOpReturnMessage.html +12 -4
  37. package/docs/html/functions/decodeRawTransaction.html +12 -4
  38. package/docs/html/functions/err.html +12 -4
  39. package/docs/html/functions/formatKeyDerivationPath.html +12 -4
  40. package/docs/html/functions/formatPeerData.html +12 -4
  41. package/docs/html/functions/generateMnemonic.html +12 -4
  42. package/docs/html/functions/generateWalletId.html +12 -4
  43. package/docs/html/functions/getAddressFromKeyPair.html +222 -0
  44. package/docs/html/functions/getAddressFromScriptPubKey.html +12 -4
  45. package/docs/html/functions/getAddressTypeFromPath.html +12 -4
  46. package/docs/html/functions/getAddressesFromPrivateKey.html +222 -0
  47. package/docs/html/functions/getByteCount.html +12 -4
  48. package/docs/html/functions/getDataFallback.html +12 -4
  49. package/docs/html/functions/getDefaultPort.html +12 -4
  50. package/docs/html/functions/getDefaultWalletData.html +12 -4
  51. package/docs/html/functions/getDefaultWalletDataKeys.html +12 -4
  52. package/docs/html/functions/getElectrumNetwork.html +216 -0
  53. package/docs/html/functions/getHighestUsedIndexFromTxHashes.html +12 -4
  54. package/docs/html/functions/getKeyDerivationPath.html +12 -4
  55. package/docs/html/functions/getKeyDerivationPathObject.html +12 -4
  56. package/docs/html/functions/getKeyDerivationPathString.html +12 -4
  57. package/docs/html/functions/getKeyValue.html +12 -4
  58. package/docs/html/functions/getPeers.html +12 -4
  59. package/docs/html/functions/getProtocolForPort.html +12 -4
  60. package/docs/html/functions/getScriptHash.html +12 -4
  61. package/docs/html/functions/getSeed.html +12 -4
  62. package/docs/html/functions/getSeedHash.html +12 -4
  63. package/docs/html/functions/getSha256.html +12 -4
  64. package/docs/html/functions/getStorageKeyValues.html +12 -4
  65. package/docs/html/{variables/mostUsedExchangeTickers.html → functions/getTapRootAddressFromPublicKey.html} +74 -97
  66. package/docs/html/functions/getTxFee.html +12 -4
  67. package/docs/html/functions/getWalletDataStorageKey.html +12 -4
  68. package/docs/html/functions/isP2trPrefix.html +217 -0
  69. package/docs/html/functions/isValidBech32mEncodedString.html +12 -4
  70. package/docs/html/functions/objectKeys-1.html +12 -4
  71. package/docs/html/functions/objectsMatch.html +12 -4
  72. package/docs/html/functions/ok.html +12 -4
  73. package/docs/html/functions/parseOnChainPaymentRequest.html +12 -4
  74. package/docs/html/functions/reduceValue.html +12 -4
  75. package/docs/html/functions/removeDustOutputs.html +12 -4
  76. package/docs/html/functions/setReplaceByFee.html +12 -4
  77. package/docs/html/functions/shuffleArray.html +12 -4
  78. package/docs/html/functions/{getExchangeRates.html → sleep.html} +22 -12
  79. package/docs/html/functions/validateAddress.html +12 -4
  80. package/docs/html/functions/validateMnemonic.html +12 -4
  81. package/docs/html/functions/validateTransaction.html +12 -4
  82. package/docs/html/index.html +22 -6
  83. package/docs/html/interfaces/IAddInput.html +16 -8
  84. package/docs/html/interfaces/IAddress.html +17 -9
  85. package/docs/html/interfaces/IAddressData.html +15 -7
  86. package/docs/html/interfaces/IAddressType.html +12 -4
  87. package/docs/html/interfaces/IAddressTypeData.html +18 -10
  88. package/docs/html/interfaces/IAddresses.html +12 -4
  89. package/docs/html/interfaces/IBoostedTransaction.html +16 -8
  90. package/docs/html/interfaces/IBoostedTransactions.html +12 -4
  91. package/docs/html/interfaces/ICreateTransaction.html +14 -6
  92. package/docs/html/interfaces/ICustomGetAddress.html +15 -7
  93. package/docs/html/interfaces/ICustomGetScriptHash.html +14 -6
  94. package/docs/html/interfaces/IElectrumGetAddressBalanceRes.html +15 -7
  95. package/docs/html/interfaces/IFormattedPeerData.html +17 -9
  96. package/docs/html/interfaces/IFormattedTransaction.html +31 -23
  97. package/docs/html/interfaces/IFormattedTransactions.html +12 -4
  98. package/docs/html/interfaces/IGenerateAddresses.html +19 -11
  99. package/docs/html/interfaces/IGenerateAddressesResponse.html +14 -6
  100. package/docs/html/interfaces/IGetAddress.html +15 -7
  101. package/docs/html/interfaces/IGetAddressBalanceRes.html +14 -6
  102. package/docs/html/interfaces/IGetAddressByPath.html +14 -6
  103. package/docs/html/interfaces/IGetAddressHistoryResponse.html +19 -11
  104. package/docs/html/interfaces/IGetAddressResponse.html +15 -7
  105. package/docs/html/interfaces/IGetAddressScriptHashBalances.html +17 -9
  106. package/docs/html/interfaces/IGetAddressScriptHashesHistoryResponse.html +17 -9
  107. package/docs/html/interfaces/{IExchangeRates.html → IGetAddressesFromKeyPair.html} +45 -23
  108. package/docs/html/interfaces/IGetAddressesFromPrivateKey.html +234 -0
  109. package/docs/html/interfaces/IGetDerivationPath.html +18 -10
  110. package/docs/html/interfaces/IGetFeeEstimatesResponse.html +16 -8
  111. package/docs/html/interfaces/IGetHeaderResponse.html +17 -9
  112. package/docs/html/interfaces/IGetNextAvailableAddressResponse.html +16 -8
  113. package/docs/html/interfaces/IGetTransactions.html +17 -9
  114. package/docs/html/interfaces/IGetTransactionsFromInputs.html +17 -9
  115. package/docs/html/interfaces/IGetUtxosResponse.html +14 -6
  116. package/docs/html/interfaces/IHeader.html +15 -7
  117. package/docs/html/interfaces/IIndexes.html +16 -8
  118. package/docs/html/interfaces/IKeyDerivationPath.html +17 -9
  119. package/docs/html/interfaces/IKeyDerivationPathData.html +14 -6
  120. package/docs/html/interfaces/INewBlock.html +14 -6
  121. package/docs/html/interfaces/IOnchainFees.html +17 -9
  122. package/docs/html/interfaces/IOutput.html +15 -7
  123. package/docs/html/interfaces/IPeerData.html +15 -7
  124. package/docs/html/interfaces/IPrivateKeyInfo.html +248 -0
  125. package/docs/html/interfaces/IRbfData.html +18 -10
  126. package/docs/html/interfaces/ISend.html +14 -6
  127. package/docs/html/interfaces/ISendTransaction.html +28 -20
  128. package/docs/html/interfaces/ISendTx.html +15 -7
  129. package/docs/html/interfaces/ISetupTransaction.html +17 -9
  130. package/docs/html/interfaces/ISubscribeToAddress.html +16 -8
  131. package/docs/html/interfaces/ISubscribeToHeader.html +16 -8
  132. package/docs/html/interfaces/ISweepPrivateKey.html +255 -0
  133. package/docs/html/interfaces/ISweepPrivateKeyRes.html +241 -0
  134. package/docs/html/interfaces/ITargets.html +16 -8
  135. package/docs/html/interfaces/ITransaction.html +17 -9
  136. package/docs/html/interfaces/ITxHash.html +13 -5
  137. package/docs/html/interfaces/ITxHashes.html +15 -7
  138. package/docs/html/interfaces/IUtxo.html +27 -21
  139. package/docs/html/interfaces/IVin.html +17 -9
  140. package/docs/html/interfaces/IVout.html +15 -7
  141. package/docs/html/interfaces/IWallet.html +53 -20
  142. package/docs/html/interfaces/IWalletData.html +30 -29
  143. package/docs/html/types/ElectrumConnectionPubSub.html +12 -4
  144. package/docs/html/types/ElectrumConnectionSubscription.html +13 -5
  145. package/docs/html/types/InputData.html +12 -4
  146. package/docs/html/types/ObjectKeys.html +12 -4
  147. package/docs/html/types/Result.html +12 -4
  148. package/docs/html/types/TAddressIndexInfo.html +12 -4
  149. package/docs/html/types/TAddressLabel.html +12 -4
  150. package/docs/html/types/TAddressType.html +12 -4
  151. package/docs/html/types/TAddressTypeContent.html +12 -4
  152. package/docs/html/types/TAddressTypes.html +12 -4
  153. package/docs/html/types/TAvailableNetworks.html +12 -4
  154. package/docs/html/types/TConnectToElectrumRes.html +12 -4
  155. package/docs/html/types/TDecodeRawTx.html +12 -4
  156. package/docs/html/types/TElectrumNetworks.html +12 -4
  157. package/docs/html/types/TGetAddressHistory.html +12 -4
  158. package/docs/html/types/TGetByteCountInput.html +12 -4
  159. package/docs/html/types/TGetByteCountInputs.html +12 -4
  160. package/docs/html/types/TGetByteCountOutput.html +12 -4
  161. package/docs/html/types/TGetByteCountOutputs.html +12 -4
  162. package/docs/html/types/TGetData.html +12 -4
  163. package/docs/html/types/TGetTotalFeeObj.html +12 -4
  164. package/docs/html/types/TKeyDerivationAccount.html +12 -4
  165. package/docs/html/types/TKeyDerivationChange.html +12 -4
  166. package/docs/html/types/TKeyDerivationCoinType.html +12 -4
  167. package/docs/html/types/TKeyDerivationIndex.html +12 -4
  168. package/docs/html/types/TKeyDerivationPurpose.html +12 -4
  169. package/docs/html/types/TMessageDataMap.html +12 -4
  170. package/docs/html/types/TMessageKeys.html +12 -4
  171. package/docs/html/types/TOnMessage.html +12 -4
  172. package/docs/html/types/TProcessUnconfirmedTransactions.html +12 -4
  173. package/docs/html/types/TProtocol.html +12 -4
  174. package/docs/html/types/TServer.html +12 -4
  175. package/docs/html/types/TSetData.html +12 -4
  176. package/docs/html/types/TSetupTransactionResponse.html +12 -4
  177. package/docs/html/types/TStorage.html +12 -4
  178. package/docs/html/types/TSubscribedReceive.html +12 -4
  179. package/docs/html/types/TTransactionMessage.html +12 -4
  180. package/docs/html/types/TTxResponse.html +12 -4
  181. package/docs/html/types/TTxResult.html +12 -4
  182. package/docs/html/types/TUnspentAddressScriptHashData.html +12 -4
  183. package/docs/html/types/TWalletDataKeys.html +12 -4
  184. package/docs/html/variables/defaultElectrumPorts.html +12 -4
  185. package/docs/html/variables/electrumConnection.html +12 -4
  186. package/docs/markdown/README.md +224 -128
  187. package/docs/markdown/classes/Electrum.md +74 -72
  188. package/docs/markdown/classes/Transaction.md +48 -23
  189. package/docs/markdown/classes/Wallet.md +240 -181
  190. package/docs/markdown/enums/EAddressType.md +14 -3
  191. package/docs/markdown/enums/EAvailableNetworks.md +7 -7
  192. package/docs/markdown/enums/EBoostType.md +2 -2
  193. package/docs/markdown/enums/EElectrumNetworks.md +3 -3
  194. package/docs/markdown/enums/EFeeId.md +5 -5
  195. package/docs/markdown/enums/EPaymentType.md +2 -2
  196. package/docs/markdown/enums/EProtocol.md +2 -2
  197. package/docs/markdown/enums/EUnit.md +3 -3
  198. package/docs/markdown/interfaces/IAddInput.md +4 -4
  199. package/docs/markdown/interfaces/IAddress.md +5 -5
  200. package/docs/markdown/interfaces/IAddressData.md +3 -3
  201. package/docs/markdown/interfaces/IAddressTypeData.md +6 -6
  202. package/docs/markdown/interfaces/IBoostedTransaction.md +4 -4
  203. package/docs/markdown/interfaces/ICreateTransaction.md +2 -2
  204. package/docs/markdown/interfaces/ICustomGetAddress.md +3 -3
  205. package/docs/markdown/interfaces/ICustomGetScriptHash.md +2 -2
  206. package/docs/markdown/interfaces/IElectrumGetAddressBalanceRes.md +3 -3
  207. package/docs/markdown/interfaces/IFormattedPeerData.md +5 -5
  208. package/docs/markdown/interfaces/IFormattedTransaction.md +19 -19
  209. package/docs/markdown/interfaces/IGenerateAddresses.md +7 -7
  210. package/docs/markdown/interfaces/IGenerateAddressesResponse.md +2 -2
  211. package/docs/markdown/interfaces/IGetAddress.md +3 -3
  212. package/docs/markdown/interfaces/IGetAddressBalanceRes.md +2 -2
  213. package/docs/markdown/interfaces/IGetAddressByPath.md +2 -2
  214. package/docs/markdown/interfaces/IGetAddressHistoryResponse.md +7 -7
  215. package/docs/markdown/interfaces/IGetAddressResponse.md +3 -3
  216. package/docs/markdown/interfaces/IGetAddressScriptHashBalances.md +5 -5
  217. package/docs/markdown/interfaces/IGetAddressScriptHashesHistoryResponse.md +5 -5
  218. package/docs/markdown/interfaces/IGetAddressesFromKeyPair.md +30 -0
  219. package/docs/markdown/interfaces/IGetAddressesFromPrivateKey.md +30 -0
  220. package/docs/markdown/interfaces/IGetDerivationPath.md +6 -6
  221. package/docs/markdown/interfaces/IGetFeeEstimatesResponse.md +4 -4
  222. package/docs/markdown/interfaces/IGetHeaderResponse.md +5 -5
  223. package/docs/markdown/interfaces/IGetNextAvailableAddressResponse.md +4 -4
  224. package/docs/markdown/interfaces/IGetTransactions.md +5 -5
  225. package/docs/markdown/interfaces/IGetTransactionsFromInputs.md +5 -5
  226. package/docs/markdown/interfaces/IGetUtxosResponse.md +2 -2
  227. package/docs/markdown/interfaces/IHeader.md +3 -3
  228. package/docs/markdown/interfaces/IIndexes.md +4 -4
  229. package/docs/markdown/interfaces/IKeyDerivationPath.md +5 -5
  230. package/docs/markdown/interfaces/IKeyDerivationPathData.md +2 -2
  231. package/docs/markdown/interfaces/INewBlock.md +2 -2
  232. package/docs/markdown/interfaces/IOnchainFees.md +5 -5
  233. package/docs/markdown/interfaces/IOutput.md +3 -3
  234. package/docs/markdown/interfaces/IPeerData.md +3 -3
  235. package/docs/markdown/interfaces/IPrivateKeyInfo.md +52 -0
  236. package/docs/markdown/interfaces/IRbfData.md +6 -6
  237. package/docs/markdown/interfaces/ISend.md +2 -2
  238. package/docs/markdown/interfaces/ISendTransaction.md +16 -16
  239. package/docs/markdown/interfaces/ISendTx.md +3 -3
  240. package/docs/markdown/interfaces/ISetupTransaction.md +5 -5
  241. package/docs/markdown/interfaces/ISubscribeToAddress.md +4 -4
  242. package/docs/markdown/interfaces/ISubscribeToHeader.md +4 -4
  243. package/docs/markdown/interfaces/ISweepPrivateKey.md +63 -0
  244. package/docs/markdown/interfaces/ISweepPrivateKeyRes.md +41 -0
  245. package/docs/markdown/interfaces/ITargets.md +4 -4
  246. package/docs/markdown/interfaces/ITransaction.md +5 -5
  247. package/docs/markdown/interfaces/ITxHash.md +1 -1
  248. package/docs/markdown/interfaces/ITxHashes.md +3 -3
  249. package/docs/markdown/interfaces/IUtxo.md +18 -23
  250. package/docs/markdown/interfaces/IVin.md +5 -5
  251. package/docs/markdown/interfaces/IVout.md +3 -3
  252. package/docs/markdown/interfaces/IWallet.md +50 -15
  253. package/docs/markdown/interfaces/IWalletData.md +18 -29
  254. package/package.json +3 -3
  255. package/src/electrum/index.ts +147 -60
  256. package/src/types/electrum.ts +7 -0
  257. package/src/types/transaction.ts +5 -0
  258. package/src/types/wallet.ts +7 -1
  259. package/src/utils/helpers.ts +14 -0
  260. package/src/utils/wallet.ts +73 -0
  261. package/src/wallet/constants.ts +0 -8
  262. package/src/wallet/index.ts +262 -118
  263. package/tests/wallet.test.ts +71 -1
  264. package/dist/mempool/index.js +0 -28
  265. package/dist/mempool/index.js.map +0 -1
  266. package/dist/types/mempool/index.d.ts +0 -15
  267. package/dist/types/mempool.js +0 -3
  268. package/dist/types/mempool.js.map +0 -1
  269. package/dist/types/types/mempool.d.ts +0 -16
  270. package/dist/types/utils/exchange-rate.d.ts +0 -30
  271. package/dist/utils/exchange-rate.js +0 -49
  272. package/dist/utils/exchange-rate.js.map +0 -1
  273. package/docs/markdown/interfaces/IExchangeRates.md +0 -7
@@ -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
- generateWalletId,
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
- servers: electrumOptions?.servers,
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({ scanAllAddresses });
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
- if (addressIndex?.index < 0 || !addressIndex?.address) {
891
- const generatedAddresses = await this.generateAddresses({
892
- addressAmount: GENERATE_ADDRESS_AMOUNT,
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
- const addresses = generatedAddresses.value.addresses;
902
- const sorted = Object.values(addresses).sort(
903
- (a, b) => a.index - b.index
904
- );
905
- addressIndex = sorted[0];
906
- }
907
-
908
- if (changeAddressIndex?.index < 0 || !changeAddressIndex?.address) {
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
- let addresses: IAddresses = currentWallet.addresses[addressType];
927
- let changeAddresses: IAddresses =
928
- currentWallet.changeAddresses[addressType];
929
-
930
- //How many addresses/changeAddresses are currently stored
931
- const addressCount = Object.values(addresses).length;
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
- addressCount < GENERATE_ADDRESS_AMOUNT ||
940
- addressIndex.index === addressCount
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 (newAddresses.isOk()) {
952
- addresses = newAddresses.value.addresses;
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
- * Create more change addresses if none exist or the highest change address index matches the current
958
- * change address count
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 (highestUsedAddressIndex.index < highestStoredAddressIndex.index) {
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
- highestUsedChangeAddressIndex.index <
1069
- highestStoredChangeAddressIndex.index
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: GENERATE_ADDRESS_AMOUNT,
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: GENERATE_ADDRESS_AMOUNT,
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 > GAP_LIMIT) {
1393
- const excessAmount = currentGap - GAP_LIMIT;
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 > GAP_LIMIT) {
1415
- const excessAmount = currentGap - GAP_LIMIT;
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 >= GAP_LIMIT) {
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 {boolean} scanAllAddresses
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
- scanAllAddresses = false
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
- scanAllAddresses
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
- receivedTxs.forEach((tx) => {
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
- confirmedTxs.forEach((tx) => {
1815
- this.sendMessage('transactionConfirmed', tx);
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].height
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 chunkLimit = CHUNK_LIMIT[this.network];
2369
- for (let i = 0; i < inputs.length; i += chunkLimit) {
2370
- const chunk = inputs.slice(i, i + chunkLimit);
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' ? GENERATE_ADDRESS_AMOUNT : 0,
2890
+ indexToUpdate === 'addressIndex' ? this.gapLimitOptions.lookAhead : 0,
2790
2891
  addressIndex: index,
2791
2892
  changeAddressAmount:
2792
- indexToUpdate === 'changeAddressIndex' ? GENERATE_ADDRESS_AMOUNT : 0,
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
  }