@atomicfinance/bitcoin-wallet-provider 2.5.0 → 2.5.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.
@@ -1,45 +1,45 @@
1
- Object.defineProperty(exports, "__esModule", {
2
- value: true
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
3
13
  });
4
- exports.default = void 0;
5
- var _provider = _interopRequireDefault(require("@atomicfinance/provider"));
6
- var _types = require("@atomicfinance/types");
7
- var _bitcoinUtils = require("@liquality/bitcoin-utils");
8
- var _assert = _interopRequireDefault(require("assert"));
9
- var bitcoin = _interopRequireWildcard(require("bitcoinjs-lib"));
10
- var _secp256K1 = _interopRequireDefault(require("secp256k1"));
11
- function _interopRequireDefault(obj) {
12
- return obj && obj.__esModule ? obj : {
13
- default: obj
14
- };
15
- }
16
- function _interopRequireWildcard(obj) {
17
- if (obj && obj.__esModule) {
18
- return obj;
19
- } else {
20
- var newObj = {};
21
- if (obj != null) {
22
- for(var key in obj){
23
- if (Object.prototype.hasOwnProperty.call(obj, key)) {
24
- var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {};
25
- if (desc.get || desc.set) {
26
- Object.defineProperty(newObj, key, desc);
27
- } else {
28
- newObj[key] = obj[key];
29
- }
30
- }
31
- }
32
- }
33
- newObj.default = obj;
34
- return newObj;
35
- }
36
- }
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
21
+ var __importDefault = (this && this.__importDefault) || function (mod) {
22
+ return (mod && mod.__esModule) ? mod : { "default": mod };
23
+ };
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ const provider_1 = __importDefault(require("@atomicfinance/provider"));
26
+ const types_1 = require("@atomicfinance/types");
27
+ const bitcoin_utils_1 = require("@liquality/bitcoin-utils");
28
+ const assert_1 = __importDefault(require("assert"));
29
+ const bitcoin = __importStar(require("bitcoinjs-lib"));
30
+ const secp256k1_1 = __importDefault(require("secp256k1"));
37
31
  const FEE_PER_BYTE_FALLBACK = 5;
38
32
  const ADDRESS_GAP = 20;
39
33
  const NONCHANGE_ADDRESS = 0;
40
34
  const CHANGE_ADDRESS = 1;
41
35
  const NONCHANGE_OR_CHANGE_ADDRESS = 2;
42
- let BitcoinWalletProvider = class BitcoinWalletProvider extends _provider.default {
36
+ class BitcoinWalletProvider extends provider_1.default {
37
+ constructor(network) {
38
+ super();
39
+ this._network = network;
40
+ this._unusedAddressesBlacklist = {};
41
+ this._maxAddressesToDerive = 5000;
42
+ }
43
43
  async buildSweepTransactionWithSetOutputs(externalChangeAddress, feePerByte, _outputs, fixedInputs) {
44
44
  return this._buildSweepTransaction(externalChangeAddress, feePerByte, _outputs, fixedInputs);
45
45
  }
@@ -62,94 +62,90 @@ let BitcoinWalletProvider = class BitcoinWalletProvider extends _provider.defaul
62
62
  // Create m-of-n multisig
63
63
  const p2ms = bitcoin.payments.p2ms({
64
64
  m: m,
65
- pubkeys: pubkeys.map((key)=>Buffer.from(key, 'hex')
66
- ),
67
- network: this._network
65
+ pubkeys: pubkeys.map((key) => Buffer.from(key, 'hex')),
66
+ network: this._network,
68
67
  });
69
68
  // Create p2wsh for multisig
70
69
  const p2wsh = bitcoin.payments.p2wsh({
71
70
  redeem: p2ms,
72
- network: this._network
71
+ network: this._network,
73
72
  });
74
73
  return p2wsh;
75
74
  }
76
75
  /**
77
- * Creates a native-segwit multi-signature address (P2MS in P2WSH) with n signatures of m required keys
78
- * https://developer.bitcoin.org/reference/rpc/createmultisig.html
79
- * @param m the number of required signatures
80
- * @param pubkeys n possible pubkeys in total
81
- * @returns a json object containing the `address` and `redeemScript`
82
- */ createMultisig(m, pubkeys) {
76
+ * Creates a native-segwit multi-signature address (P2MS in P2WSH) with n signatures of m required keys
77
+ * https://developer.bitcoin.org/reference/rpc/createmultisig.html
78
+ * @param m the number of required signatures
79
+ * @param pubkeys n possible pubkeys in total
80
+ * @returns a json object containing the `address` and `redeemScript`
81
+ */
82
+ createMultisig(m, pubkeys) {
83
83
  const p2wsh = this._createMultisigPayment(m, pubkeys);
84
84
  return {
85
85
  address: p2wsh.address,
86
- redeemScript: p2wsh.redeem?.output?.toString('hex')
86
+ redeemScript: p2wsh.redeem?.output?.toString('hex'),
87
87
  };
88
88
  }
89
89
  /**
90
- * Creates a PSBT of a native-segwit multi-signature address (P2MS in P2WSH) with n signatures of m required keys
91
- * https://developer.bitcoin.org/reference/rpc/createmultisig.html
92
- * https://developer.bitcoin.org/reference/rpc/createpsbt.html
93
- * @param m the number of required signatures
94
- * @param pubkeys n possible pubkeys in total
95
- * @param inputs the Inputs to the PSBT
96
- * @param ouputs the Outputs to the PSBT
97
- * @returns a base64 encoded psbt string
98
- */ buildMultisigPSBT(m, pubkeys, inputs, outputs) {
99
- (0, _assert).default(inputs.length > 0, 'no inputs found');
100
- (0, _assert).default(outputs.length > 0, 'no outputs found');
90
+ * Creates a PSBT of a native-segwit multi-signature address (P2MS in P2WSH) with n signatures of m required keys
91
+ * https://developer.bitcoin.org/reference/rpc/createmultisig.html
92
+ * https://developer.bitcoin.org/reference/rpc/createpsbt.html
93
+ * @param m the number of required signatures
94
+ * @param pubkeys n possible pubkeys in total
95
+ * @param inputs the Inputs to the PSBT
96
+ * @param ouputs the Outputs to the PSBT
97
+ * @returns a base64 encoded psbt string
98
+ */
99
+ buildMultisigPSBT(m, pubkeys, inputs, outputs) {
100
+ assert_1.default(inputs.length > 0, 'no inputs found');
101
+ assert_1.default(outputs.length > 0, 'no outputs found');
101
102
  const p2wsh = this._createMultisigPayment(m, pubkeys);
102
103
  // Verify pubkeyhash for all inputs matches the p2wsh hash
103
- (0, _assert).default(inputs.every((input)=>p2wsh.output.toString('hex') === input.scriptPubKey
104
- ), 'address pubkeyhash does not match input scriptPubKey');
104
+ assert_1.default(inputs.every((input) => p2wsh.output.toString('hex') === input.scriptPubKey), 'address pubkeyhash does not match input scriptPubKey');
105
105
  // creator
106
- const psbt = new bitcoin.Psbt({
107
- network: this._network
108
- });
106
+ const psbt = new bitcoin.Psbt({ network: this._network });
109
107
  // updater
110
- inputs.forEach((input)=>{
108
+ inputs.forEach((input) => {
111
109
  psbt.addInput({
112
110
  hash: input.txid,
113
111
  index: input.vout,
114
- witnessUtxo: {
115
- script: p2wsh.output,
116
- value: input.value
117
- },
118
- witnessScript: p2wsh.redeem.output
112
+ witnessUtxo: { script: p2wsh.output, value: input.value },
113
+ witnessScript: p2wsh.redeem.output,
119
114
  });
120
115
  });
121
- outputs.forEach((output)=>{
116
+ outputs.forEach((output) => {
122
117
  psbt.addOutput({
123
118
  address: output.to,
124
- value: output.value
119
+ value: output.value,
125
120
  });
126
121
  });
127
122
  return psbt.toBase64();
128
123
  }
129
124
  /**
130
- * Update a PSBT with input information from our wallet and then sign inputs that we can sign for
131
- * https://developer.bitcoin.org/reference/rpc/walletprocesspsbt.html
132
- * @param psbt a base64 encoded psbt string (P2WSH only)
133
- * @returns a base64 encoded signed psbt string
134
- */ async walletProcessPSBT(psbtString) {
125
+ * Update a PSBT with input information from our wallet and then sign inputs that we can sign for
126
+ * https://developer.bitcoin.org/reference/rpc/walletprocesspsbt.html
127
+ * @param psbt a base64 encoded psbt string (P2WSH only)
128
+ * @returns a base64 encoded signed psbt string
129
+ */
130
+ async walletProcessPSBT(psbtString) {
135
131
  const psbt = bitcoin.Psbt.fromBase64(psbtString);
136
- await Promise.all(psbt.data.inputs.map(async (input, i)=>{
137
- (0, _assert).default(psbt.getInputType(i).slice(0, 5) === 'p2wsh', 'only accepts P2WSH inputs');
132
+ await Promise.all(psbt.data.inputs.map(async (input, i) => {
133
+ assert_1.default(psbt.getInputType(i).slice(0, 5) === 'p2wsh', 'only accepts P2WSH inputs');
138
134
  const scriptStack = bitcoin.script.decompile(input.witnessScript);
139
- const pubkeys = scriptStack.filter((data)=>Buffer.isBuffer(data) && _secp256K1.default.publicKeyVerify(data)
140
- );
141
- await Promise.all(pubkeys.map(async (key)=>{
135
+ const pubkeys = scriptStack.filter((data) => Buffer.isBuffer(data) && secp256k1_1.default.publicKeyVerify(data));
136
+ await Promise.all(pubkeys.map(async (key) => {
142
137
  // create address using pubkey
143
- const { address: addressString } = bitcoin.payments.p2wpkh({
138
+ const { address: addressString } = bitcoin.payments.p2wpkh({
144
139
  pubkey: key,
145
- network: this._network
140
+ network: this._network,
146
141
  });
147
142
  // Retrieve address object from wallet using address
148
143
  const address = await this.quickFindAddress([
149
- addressString,
144
+ addressString,
150
145
  ]);
151
146
  // exit if address doesn't exist in wallet
152
- if (!address) return;
147
+ if (!address)
148
+ return;
153
149
  // derive keypair
154
150
  const keyPair = await this.getMethod('keyPair')(address.derivationPath);
155
151
  // sign PSBT using keypair
@@ -160,76 +156,84 @@ let BitcoinWalletProvider = class BitcoinWalletProvider extends _provider.defaul
160
156
  return psbt.toBase64();
161
157
  }
162
158
  /**
163
- * Finalize the inputs of a PSBT. If the transaction is fully signed, it will
164
- * produce a network serialized transaction which can be broadcast with sendrawtransaction
165
- * https://developer.bitcoin.org/reference/rpc/finalizepsbt.html
166
- * @param psbt a base64 encoded psbt string
167
- * @returns a json object containing `psbt` in base64, `hex` for transaction and `complete` for if
168
- * the transaction has a complete set of signatures
169
- */ finalizePSBT(psbtString) {
159
+ * Finalize the inputs of a PSBT. If the transaction is fully signed, it will
160
+ * produce a network serialized transaction which can be broadcast with sendrawtransaction
161
+ * https://developer.bitcoin.org/reference/rpc/finalizepsbt.html
162
+ * @param psbt a base64 encoded psbt string
163
+ * @returns a json object containing `psbt` in base64, `hex` for transaction and `complete` for if
164
+ * the transaction has a complete set of signatures
165
+ */
166
+ finalizePSBT(psbtString) {
170
167
  const psbt = bitcoin.Psbt.fromBase64(psbtString);
171
168
  try {
172
169
  psbt.validateSignaturesOfAllInputs(); // ensure all signatures are valid!
173
170
  psbt.finalizeAllInputs();
174
- } catch (error) {
171
+ }
172
+ catch (error) {
175
173
  return {
176
174
  psbt: psbt.toBase64(),
177
- complete: false
175
+ complete: false,
178
176
  };
179
177
  }
180
178
  return {
181
179
  psbt: psbt.toBase64(),
182
180
  hex: psbt.extractTransaction().toHex(),
183
- complete: true
181
+ complete: true,
184
182
  };
185
183
  }
186
184
  async getUnusedAddress(change = false, numAddressPerCall = 100) {
187
185
  const addressType = change ? CHANGE_ADDRESS : NONCHANGE_ADDRESS;
188
186
  const key = change ? 'change' : 'nonChange';
189
- const address = await this._getUsedUnusedAddresses(numAddressPerCall, addressType).then(({ unusedAddress })=>unusedAddress[key]
190
- );
187
+ const address = await this._getUsedUnusedAddresses(numAddressPerCall, addressType).then(({ unusedAddress }) => unusedAddress[key]);
191
188
  this._unusedAddressesBlacklist[address.address] = true;
192
189
  return address;
193
190
  }
194
191
  async _getUsedUnusedAddresses(numAddressPerCall = 100, addressType) {
195
192
  const usedAddresses = [];
196
- const addressCountMap = {
197
- change: 0,
198
- nonChange: 0
199
- };
200
- const unusedAddressMap = {
201
- change: null,
202
- nonChange: null
203
- };
193
+ const addressCountMap = { change: 0, nonChange: 0 };
194
+ const unusedAddressMap = { change: null, nonChange: null };
204
195
  let addrList;
205
196
  let addressIndex = 0;
206
197
  let changeAddresses = [];
207
198
  let nonChangeAddresses = [];
208
- /* eslint-disable no-unmodified-loop-condition */ while(addressType === NONCHANGE_OR_CHANGE_ADDRESS && (addressCountMap.change < ADDRESS_GAP || addressCountMap.nonChange < ADDRESS_GAP) || addressType === NONCHANGE_ADDRESS && addressCountMap.nonChange < ADDRESS_GAP || addressType === CHANGE_ADDRESS && addressCountMap.change < ADDRESS_GAP){
209
- /* eslint-enable no-unmodified-loop-condition */ addrList = [];
210
- if ((addressType === NONCHANGE_OR_CHANGE_ADDRESS || addressType === CHANGE_ADDRESS) && addressCountMap.change < ADDRESS_GAP) {
199
+ /* eslint-disable no-unmodified-loop-condition */
200
+ while ((addressType === NONCHANGE_OR_CHANGE_ADDRESS &&
201
+ (addressCountMap.change < ADDRESS_GAP ||
202
+ addressCountMap.nonChange < ADDRESS_GAP)) ||
203
+ (addressType === NONCHANGE_ADDRESS &&
204
+ addressCountMap.nonChange < ADDRESS_GAP) ||
205
+ (addressType === CHANGE_ADDRESS && addressCountMap.change < ADDRESS_GAP)) {
206
+ /* eslint-enable no-unmodified-loop-condition */
207
+ addrList = [];
208
+ if ((addressType === NONCHANGE_OR_CHANGE_ADDRESS ||
209
+ addressType === CHANGE_ADDRESS) &&
210
+ addressCountMap.change < ADDRESS_GAP) {
211
211
  // Scanning for change addr
212
212
  changeAddresses = await this.client.wallet.getAddresses(addressIndex, numAddressPerCall, true);
213
213
  addrList = addrList.concat(changeAddresses);
214
- } else {
214
+ }
215
+ else {
215
216
  changeAddresses = [];
216
217
  }
217
- if ((addressType === NONCHANGE_OR_CHANGE_ADDRESS || addressType === NONCHANGE_ADDRESS) && addressCountMap.nonChange < ADDRESS_GAP) {
218
+ if ((addressType === NONCHANGE_OR_CHANGE_ADDRESS ||
219
+ addressType === NONCHANGE_ADDRESS) &&
220
+ addressCountMap.nonChange < ADDRESS_GAP) {
218
221
  // Scanning for non change addr
219
222
  nonChangeAddresses = await this.quickGetAddresses(addressIndex, numAddressPerCall, false);
220
223
  addrList = addrList.concat(nonChangeAddresses);
221
224
  }
222
225
  const transactionCounts = await this.getMethod('getAddressTransactionCounts')(addrList);
223
- for (const address of addrList){
224
- const isUsed = transactionCounts[address.address] > 0 || this._unusedAddressesBlacklist[address.address];
225
- const isChangeAddress = changeAddresses.find((a)=>address.address === a.address
226
- );
226
+ for (const address of addrList) {
227
+ const isUsed = transactionCounts[address.address] > 0 ||
228
+ this._unusedAddressesBlacklist[address.address];
229
+ const isChangeAddress = changeAddresses.find((a) => address.address === a.address);
227
230
  const key = isChangeAddress ? 'change' : 'nonChange';
228
231
  if (isUsed) {
229
232
  usedAddresses.push(address);
230
233
  addressCountMap[key] = 0;
231
234
  unusedAddressMap[key] = null;
232
- } else {
235
+ }
236
+ else {
233
237
  addressCountMap[key]++;
234
238
  if (!unusedAddressMap[key]) {
235
239
  unusedAddressMap[key] = address;
@@ -239,23 +243,31 @@ let BitcoinWalletProvider = class BitcoinWalletProvider extends _provider.defaul
239
243
  addressIndex += numAddressPerCall;
240
244
  }
241
245
  let firstUnusedAddress;
242
- const indexNonChange = unusedAddressMap.nonChange ? unusedAddressMap.nonChange.index : Infinity;
243
- const indexChange = unusedAddressMap.change ? unusedAddressMap.change.index : Infinity;
244
- if (indexNonChange <= indexChange) firstUnusedAddress = unusedAddressMap.nonChange;
245
- else firstUnusedAddress = unusedAddressMap.change;
246
+ const indexNonChange = unusedAddressMap.nonChange
247
+ ? unusedAddressMap.nonChange.index
248
+ : Infinity;
249
+ const indexChange = unusedAddressMap.change
250
+ ? unusedAddressMap.change.index
251
+ : Infinity;
252
+ if (indexNonChange <= indexChange)
253
+ firstUnusedAddress = unusedAddressMap.nonChange;
254
+ else
255
+ firstUnusedAddress = unusedAddressMap.change;
246
256
  return {
247
257
  usedAddresses,
248
258
  unusedAddress: unusedAddressMap,
249
- firstUnusedAddress
259
+ firstUnusedAddress,
250
260
  };
251
261
  }
252
262
  async sendSweepTransactionWithSetOutputs(externalChangeAddress, feePerByte, _outputs, fixedInputs) {
253
- const { hex , fee } = await this._buildSweepTransaction(externalChangeAddress, feePerByte, _outputs, fixedInputs);
263
+ const { hex, fee } = await this._buildSweepTransaction(externalChangeAddress, feePerByte, _outputs, fixedInputs);
254
264
  await this.getMethod('sendRawTransaction')(hex);
255
- return (0, _bitcoinUtils).normalizeTransactionObject((0, _bitcoinUtils).decodeRawTransaction(hex, this._network), fee);
265
+ return bitcoin_utils_1.normalizeTransactionObject(bitcoin_utils_1.decodeRawTransaction(hex, this._network), fee);
256
266
  }
257
267
  async _buildSweepTransaction(externalChangeAddress, feePerByte, _outputs = [], fixedInputs) {
258
- const _feePerByte = feePerByte || await this.getMethod('getFeePerByte')() || FEE_PER_BYTE_FALLBACK;
268
+ const _feePerByte = feePerByte ||
269
+ (await this.getMethod('getFeePerByte')()) ||
270
+ FEE_PER_BYTE_FALLBACK;
259
271
  const inputs = [];
260
272
  const outputs = [];
261
273
  try {
@@ -263,93 +275,85 @@ let BitcoinWalletProvider = class BitcoinWalletProvider extends _provider.defaul
263
275
  if (inputsForAmount.change) {
264
276
  throw Error('There should not be any change for sweeping transaction');
265
277
  }
266
- inputs.push(...inputsForAmount.inputs || []);
267
- outputs.push(...inputsForAmount.outputs || []);
268
- } catch (e) {
278
+ inputs.push(...(inputsForAmount.inputs || []));
279
+ outputs.push(...(inputsForAmount.outputs || []));
280
+ }
281
+ catch (e) {
269
282
  if (fixedInputs.length === 0) {
270
283
  throw Error(`Inputs for amount doesn't exist and no fixedInputs provided`);
271
284
  }
272
285
  const inputsForAmount = await this._getInputForAmountWithoutUtxoCheck(_outputs, _feePerByte, fixedInputs);
273
- inputs.push(...inputsForAmount.inputs.map((utxo)=>_types.Input.fromUTXO(utxo)
274
- ) || []);
275
- outputs.push(...inputsForAmount.outputs || []);
286
+ inputs.push(...(inputsForAmount.inputs.map((utxo) => types_1.Input.fromUTXO(utxo)) || []));
287
+ outputs.push(...(inputsForAmount.outputs || []));
276
288
  }
277
- _outputs.forEach((output)=>{
278
- const spliceIndex = outputs.findIndex((sweepOutput)=>output.value === sweepOutput.value
279
- );
289
+ _outputs.forEach((output) => {
290
+ const spliceIndex = outputs.findIndex((sweepOutput) => output.value === sweepOutput.value);
280
291
  outputs.splice(spliceIndex, 1);
281
292
  });
282
293
  _outputs.push({
283
294
  to: externalChangeAddress,
284
- value: outputs[0].value
295
+ value: outputs[0].value,
285
296
  });
286
297
  return this._buildTransactionWithoutUtxoCheck(_outputs, _feePerByte, inputs);
287
298
  }
288
299
  _getInputForAmountWithoutUtxoCheck(_outputs, _feePerByte, fixedInputs) {
289
- const utxoBalance = fixedInputs.reduce((a, b)=>a + (b['value'] || 0)
290
- , 0);
291
- const outputBalance = _outputs.reduce((a, b)=>a + (b['value'] || 0)
292
- , 0);
293
- const amountToSend = utxoBalance - _feePerByte * ((_outputs.length + 1) * 39 + fixedInputs.length * 153); // todo better calculation
294
- const targets = _outputs.map((target, i)=>({
295
- id: 'main',
296
- value: target.value
297
- })
298
- );
300
+ const utxoBalance = fixedInputs.reduce((a, b) => a + (b['value'] || 0), 0);
301
+ const outputBalance = _outputs.reduce((a, b) => a + (b['value'] || 0), 0);
302
+ const amountToSend = utxoBalance -
303
+ _feePerByte * ((_outputs.length + 1) * 39 + fixedInputs.length * 153); // todo better calculation
304
+ const targets = _outputs.map((target, i) => ({
305
+ id: 'main',
306
+ value: target.value,
307
+ }));
299
308
  if (amountToSend - outputBalance > 0) {
300
- targets.push({
301
- id: 'main',
302
- value: amountToSend - outputBalance
303
- });
309
+ targets.push({ id: 'main', value: amountToSend - outputBalance });
304
310
  }
305
- return (0, _bitcoinUtils).selectCoins(fixedInputs, targets, Math.ceil(_feePerByte), fixedInputs);
311
+ return bitcoin_utils_1.selectCoins(fixedInputs, targets, Math.ceil(_feePerByte), fixedInputs);
306
312
  }
307
313
  async _buildTransactionWithoutUtxoCheck(outputs, feePerByte, fixedInputs) {
308
314
  const network = this._network;
309
- const { fee } = this._getInputForAmountWithoutUtxoCheck(outputs, feePerByte, fixedInputs);
315
+ const { fee } = this._getInputForAmountWithoutUtxoCheck(outputs, feePerByte, fixedInputs);
310
316
  const inputs = fixedInputs;
311
317
  const txb = new bitcoin.TransactionBuilder(network);
312
- for (const output of outputs){
318
+ for (const output of outputs) {
313
319
  const to = output.to; // Allow for OP_RETURN
314
320
  txb.addOutput(to, output.value);
315
321
  }
316
322
  const prevOutScriptType = 'p2wpkh';
317
- for(let i = 0; i < inputs.length; i++){
323
+ for (let i = 0; i < inputs.length; i++) {
318
324
  const wallet = await this.getMethod('getWalletAddress')(inputs[i].address);
319
325
  const keyPair = await this.getMethod('keyPair')(wallet.derivationPath);
320
326
  const paymentVariant = this.getMethod('getPaymentVariantFromPublicKey')(keyPair.publicKey);
321
327
  txb.addInput(inputs[i].txid, inputs[i].vout, 0, paymentVariant.output);
322
328
  }
323
- for(let i1 = 0; i1 < inputs.length; i1++){
324
- const wallet = await this.getMethod('getWalletAddress')(inputs[i1].address);
329
+ for (let i = 0; i < inputs.length; i++) {
330
+ const wallet = await this.getMethod('getWalletAddress')(inputs[i].address);
325
331
  const keyPair = await this.getMethod('keyPair')(wallet.derivationPath);
326
332
  const paymentVariant = this.getMethod('getPaymentVariantFromPublicKey')(keyPair.publicKey);
327
333
  const needsWitness = true;
328
334
  const signParams = {
329
335
  prevOutScriptType,
330
- vin: i1,
336
+ vin: i,
331
337
  keyPair,
332
- witnessValue: 0
338
+ witnessValue: 0,
333
339
  };
334
340
  if (needsWitness) {
335
- signParams.witnessValue = inputs[i1].value;
341
+ signParams.witnessValue = inputs[i].value;
336
342
  }
337
343
  txb.sign(signParams);
338
344
  }
339
- return {
340
- hex: txb.build().toHex(),
341
- fee
342
- };
345
+ return { hex: txb.build().toHex(), fee };
343
346
  }
344
347
  /**
345
- * quickGetAddresses is an optimized version of getAddresses.
346
- * It removes the call to `asyncSetImmediate()`, speeding up the function by a factor of 6x.
347
- *
348
- * @param startingIndex
349
- * @param numAddresses
350
- * @param change
351
- * @returns {Promise<Address[]>}
352
- */ async quickGetAddresses(startingIndex = 0, numAddresses = 1, change = false) {
348
+ * quickGetAddresses is an optimized version of getAddresses.
349
+ * It removes the call to `asyncSetImmediate()`, speeding up the function by a factor of 6x.
350
+ *
351
+ * @param startingIndex
352
+ * @param numAddresses
353
+ * @param change
354
+ * @returns {Promise<Address[]>}
355
+ */
356
+ async quickGetAddresses(startingIndex = 0, numAddresses = 1, change = false) {
353
357
  if (numAddresses < 1) {
354
358
  throw new Error('You must return at least one address');
355
359
  }
@@ -359,9 +363,10 @@ let BitcoinWalletProvider = class BitcoinWalletProvider extends _provider.defaul
359
363
  // Original wallet provider is fetched to get the base derivation path
360
364
  const originalProvider = this.client.getProviderForMethod('getAddresses');
361
365
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
362
- const baseDerivationPath = originalProvider._baseDerivationPath;
366
+ const baseDerivationPath = originalProvider
367
+ ._baseDerivationPath;
363
368
  const getDerivationPathAddressFn = this.client.getMethod('getDerivationPathAddress');
364
- for(let currentIndex = startingIndex; currentIndex < lastIndex; currentIndex++){
369
+ for (let currentIndex = startingIndex; currentIndex < lastIndex; currentIndex++) {
365
370
  const subPath = changeVal + '/' + currentIndex;
366
371
  const path = baseDerivationPath + '/' + subPath;
367
372
  const addressObject = await getDerivationPathAddressFn(path);
@@ -370,28 +375,27 @@ let BitcoinWalletProvider = class BitcoinWalletProvider extends _provider.defaul
370
375
  return addresses;
371
376
  }
372
377
  /**
373
- * quickFindAddress is an optimized version of findAddress.
374
- *
375
- * It searches through both change and non-change addresses each iteration.
376
- *
377
- * This is in contrast to the original findAddress function which searches
378
- * through all non-change addresses before moving on to change addresses.
379
- *
380
- * @param addresses
381
- * @returns {Promise<Address[]>}
382
- */ async quickFindAddress(addresses) {
378
+ * quickFindAddress is an optimized version of findAddress.
379
+ *
380
+ * It searches through both change and non-change addresses each iteration.
381
+ *
382
+ * This is in contrast to the original findAddress function which searches
383
+ * through all non-change addresses before moving on to change addresses.
384
+ *
385
+ * @param addresses
386
+ * @returns {Promise<Address[]>}
387
+ */
388
+ async quickFindAddress(addresses) {
383
389
  const addressesPerCall = 20;
384
390
  let index = 0;
385
- while(index < this._maxAddressesToDerive){
391
+ while (index < this._maxAddressesToDerive) {
386
392
  const walletNonChangeAddresses = await this.quickGetAddresses(index, addressesPerCall, true);
387
393
  const walletChangeAddresses = await this.quickGetAddresses(index, addressesPerCall, false);
388
394
  const walletAddresses = [
389
395
  ...walletNonChangeAddresses,
390
- ...walletChangeAddresses,
396
+ ...walletChangeAddresses,
391
397
  ];
392
- const walletAddress = walletAddresses.find((walletAddr)=>addresses.find((addr)=>walletAddr.address === addr
393
- )
394
- );
398
+ const walletAddress = walletAddresses.find((walletAddr) => addresses.find((addr) => walletAddr.address === addr));
395
399
  if (walletAddress) {
396
400
  // Increment max addresses to derive by 100 if found within 100 addresses of maxAddressesToDerive
397
401
  this._maxAddressesToDerive = Math.max(this._maxAddressesToDerive, index + 100);
@@ -400,13 +404,6 @@ let BitcoinWalletProvider = class BitcoinWalletProvider extends _provider.defaul
400
404
  index += addressesPerCall;
401
405
  }
402
406
  }
403
- constructor(network){
404
- super();
405
- this._network = network;
406
- this._unusedAddressesBlacklist = {};
407
- this._maxAddressesToDerive = 5000;
408
- }
409
- };
407
+ }
410
408
  exports.default = BitcoinWalletProvider;
411
-
412
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL2xpYi9CaXRjb2luV2FsbGV0UHJvdmlkZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFByb3ZpZGVyIGZyb20gJ0BhdG9taWNmaW5hbmNlL3Byb3ZpZGVyJztcbmltcG9ydCB7XG4gIENyZWF0ZU11bHRpc2lnUmVzcG9uc2UsXG4gIGZpbmFsaXplUFNCVFJlc3BvbnNlLFxuICBGaW5hbmNlV2FsbGV0UHJvdmlkZXIsXG4gIElucHV0LFxuICBPdXRwdXQsXG59IGZyb20gJ0BhdG9taWNmaW5hbmNlL3R5cGVzJztcbmltcG9ydCB7IEJpdGNvaW5OZXR3b3JrIH0gZnJvbSAnQGxpcXVhbGl0eS9iaXRjb2luLW5ldHdvcmtzJztcbmltcG9ydCB7XG4gIGRlY29kZVJhd1RyYW5zYWN0aW9uLFxuICBub3JtYWxpemVUcmFuc2FjdGlvbk9iamVjdCxcbiAgc2VsZWN0Q29pbnMsXG59IGZyb20gJ0BsaXF1YWxpdHkvYml0Y29pbi11dGlscyc7XG5pbXBvcnQgeyBBZGRyZXNzLCBiaXRjb2luIGFzIGJULCBUcmFuc2FjdGlvbiB9IGZyb20gJ0BsaXF1YWxpdHkvdHlwZXMnO1xuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0ICogYXMgYml0Y29pbiBmcm9tICdiaXRjb2luanMtbGliJztcbmltcG9ydCBzZWNwMjU2azEgZnJvbSAnc2VjcDI1NmsxJztcblxuY29uc3QgRkVFX1BFUl9CWVRFX0ZBTExCQUNLID0gNTtcbmNvbnN0IEFERFJFU1NfR0FQID0gMjA7XG5jb25zdCBOT05DSEFOR0VfQUREUkVTUyA9IDA7XG5jb25zdCBDSEFOR0VfQUREUkVTUyA9IDE7XG5jb25zdCBOT05DSEFOR0VfT1JfQ0hBTkdFX0FERFJFU1MgPSAyO1xuXG50eXBlIFVudXNlZEFkZHJlc3Nlc0JsYWNrbGlzdCA9IHtcbiAgW2FkZHJlc3M6IHN0cmluZ106IHRydWU7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCaXRjb2luV2FsbGV0UHJvdmlkZXJcbiAgZXh0ZW5kcyBQcm92aWRlclxuICBpbXBsZW1lbnRzIFBhcnRpYWw8RmluYW5jZVdhbGxldFByb3ZpZGVyPiB7XG4gIF9uZXR3b3JrOiBCaXRjb2luTmV0d29yaztcbiAgX3VudXNlZEFkZHJlc3Nlc0JsYWNrbGlzdDogVW51c2VkQWRkcmVzc2VzQmxhY2tsaXN0O1xuICBfbWF4QWRkcmVzc2VzVG9EZXJpdmU6IG51bWJlcjtcblxuICBjb25zdHJ1Y3RvcihuZXR3b3JrOiBCaXRjb2luTmV0d29yaykge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLl9uZXR3b3JrID0gbmV0d29yaztcbiAgICB0aGlzLl91bnVzZWRBZGRyZXNzZXNCbGFja2xpc3QgPSB7fTtcbiAgICB0aGlzLl9tYXhBZGRyZXNzZXNUb0Rlcml2ZSA9IDUwMDA7XG4gIH1cblxuICBhc3luYyBidWlsZFN3ZWVwVHJhbnNhY3Rpb25XaXRoU2V0T3V0cHV0cyhcbiAgICBleHRlcm5hbENoYW5nZUFkZHJlc3M6IHN0cmluZyxcbiAgICBmZWVQZXJCeXRlOiBudW1iZXIsXG4gICAgX291dHB1dHM6IE91dHB1dFtdLFxuICAgIGZpeGVkSW5wdXRzOiBJbnB1dFtdLFxuICApIHtcbiAgICByZXR1cm4gdGhpcy5fYnVpbGRTd2VlcFRyYW5zYWN0aW9uKFxuICAgICAgZXh0ZXJuYWxDaGFuZ2VBZGRyZXNzLFxuICAgICAgZmVlUGVyQnl0ZSxcbiAgICAgIF9vdXRwdXRzLFxuICAgICAgZml4ZWRJbnB1dHMsXG4gICAgKTtcbiAgfVxuXG4gIGdldFVudXNlZEFkZHJlc3Nlc0JsYWNrbGlzdCgpOiBVbnVzZWRBZGRyZXNzZXNCbGFja2xpc3Qge1xuICAgIHJldHVybiB0aGlzLl91bnVzZWRBZGRyZXNzZXNCbGFja2xpc3Q7XG4gIH1cblxuICBzZXRVbnVzZWRBZGRyZXNzZXNCbGFja2xpc3QoXG4gICAgdW51c2VkQWRkcmVzc2VzQmxhY2tsaXN0OiBVbnVzZWRBZGRyZXNzZXNCbGFja2xpc3QsXG4gICkge1xuICAgIHRoaXMuX3VudXNlZEFkZHJlc3Nlc0JsYWNrbGlzdCA9IHVudXNlZEFkZHJlc3Nlc0JsYWNrbGlzdDtcbiAgfVxuXG4gIHNldE1heEFkZHJlc3Nlc1RvRGVyaXZlKG1heEFkZHJlc3Nlc1RvRGVyaXZlOiBudW1iZXIpIHtcbiAgICB0aGlzLl9tYXhBZGRyZXNzZXNUb0Rlcml2ZSA9IG1heEFkZHJlc3Nlc1RvRGVyaXZlO1xuICB9XG5cbiAgZ2V0TWF4QWRkcmVzc2VzVG9EZXJpdmUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX21heEFkZHJlc3Nlc1RvRGVyaXZlO1xuICB9XG5cbiAgX2NyZWF0ZU11bHRpc2lnUGF5bWVudChtOiBudW1iZXIsIHB1YmtleXM6IHN0cmluZ1tdKTogYml0Y29pbi5QYXltZW50IHtcbiAgICBpZiAobSA+IHB1YmtleXMubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBub3QgZW5vdWdoIGtleXMgc3VwcGxpZWQgKGdvdCAke3B1YmtleXMubGVuZ3RofSBrZXlzLCBidXQgbmVlZCBhdCBsZWFzdCAke219IHRvIHJlZGVlbSlgLFxuICAgICAgKTtcbiAgICB9XG4gICAgLy8gQ3JlYXRlIG0tb2YtbiBtdWx0aXNpZ1xuICAgIGNvbnN0IHAybXMgPSBiaXRjb2luLnBheW1lbnRzLnAybXMoe1xuICAgICAgbTogbSxcbiAgICAgIHB1YmtleXM6IHB1YmtleXMubWFwKChrZXk6IHN0cmluZykgPT4gQnVmZmVyLmZyb20oa2V5LCAnaGV4JykpLFxuICAgICAgbmV0d29yazogdGhpcy5fbmV0d29yayxcbiAgICB9KTtcblxuICAgIC8vIENyZWF0ZSBwMndzaCBmb3IgbXVsdGlzaWdcbiAgICBjb25zdCBwMndzaCA9IGJpdGNvaW4ucGF5bWVudHMucDJ3c2goe1xuICAgICAgcmVkZWVtOiBwMm1zLFxuICAgICAgbmV0d29yazogdGhpcy5fbmV0d29yayxcbiAgICB9KTtcblxuICAgIHJldHVybiBwMndzaDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmF0aXZlLXNlZ3dpdCBtdWx0aS1zaWduYXR1cmUgYWRkcmVzcyAoUDJNUyBpbiBQMldTSCkgd2l0aCBuIHNpZ25hdHVyZXMgb2YgbSByZXF1aXJlZCBrZXlzXG4gICAqIGh0dHBzOi8vZGV2ZWxvcGVyLmJpdGNvaW4ub3JnL3JlZmVyZW5jZS9ycGMvY3JlYXRlbXVsdGlzaWcuaHRtbFxuICAgKiBAcGFyYW0gbSB0aGUgbnVtYmVyIG9mIHJlcXVpcmVkIHNpZ25hdHVyZXNcbiAgICogQHBhcmFtIHB1YmtleXMgbiBwb3NzaWJsZSBwdWJrZXlzIGluIHRvdGFsXG4gICAqIEByZXR1cm5zIGEganNvbiBvYmplY3QgY29udGFpbmluZyB0aGUgYGFkZHJlc3NgIGFuZCBgcmVkZWVtU2NyaXB0YFxuICAgKi9cbiAgY3JlYXRlTXVsdGlzaWcobTogbnVtYmVyLCBwdWJrZXlzOiBzdHJpbmdbXSk6IENyZWF0ZU11bHRpc2lnUmVzcG9uc2Uge1xuICAgIGNvbnN0IHAyd3NoID0gdGhpcy5fY3JlYXRlTXVsdGlzaWdQYXltZW50KG0sIHB1YmtleXMpO1xuICAgIHJldHVybiB7XG4gICAgICBhZGRyZXNzOiBwMndzaC5hZGRyZXNzLFxuICAgICAgcmVkZWVtU2NyaXB0OiBwMndzaC5yZWRlZW0/Lm91dHB1dD8udG9TdHJpbmcoJ2hleCcpLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIFBTQlQgb2YgYSBuYXRpdmUtc2Vnd2l0IG11bHRpLXNpZ25hdHVyZSBhZGRyZXNzIChQMk1TIGluIFAyV1NIKSB3aXRoIG4gc2lnbmF0dXJlcyBvZiBtIHJlcXVpcmVkIGtleXNcbiAgICogaHR0cHM6Ly9kZXZlbG9wZXIuYml0Y29pbi5vcmcvcmVmZXJlbmNlL3JwYy9jcmVhdGVtdWx0aXNpZy5odG1sXG4gICAqIGh0dHBzOi8vZGV2ZWxvcGVyLmJpdGNvaW4ub3JnL3JlZmVyZW5jZS9ycGMvY3JlYXRlcHNidC5odG1sXG4gICAqIEBwYXJhbSBtIHRoZSBudW1iZXIgb2YgcmVxdWlyZWQgc2lnbmF0dXJlc1xuICAgKiBAcGFyYW0gcHVia2V5cyBuIHBvc3NpYmxlIHB1YmtleXMgaW4gdG90YWxcbiAgICogQHBhcmFtIGlucHV0cyB0aGUgSW5wdXRzIHRvIHRoZSBQU0JUXG4gICAqIEBwYXJhbSBvdXB1dHMgdGhlIE91dHB1dHMgdG8gdGhlIFBTQlRcbiAgICogQHJldHVybnMgYSBiYXNlNjQgZW5jb2RlZCBwc2J0IHN0cmluZ1xuICAgKi9cbiAgYnVpbGRNdWx0aXNpZ1BTQlQoXG4gICAgbTogbnVtYmVyLFxuICAgIHB1YmtleXM6IHN0cmluZ1tdLFxuICAgIGlucHV0czogSW5wdXRbXSxcbiAgICBvdXRwdXRzOiBPdXRwdXRbXSxcbiAgKTogc3RyaW5nIHtcbiAgICBhc3NlcnQoaW5wdXRzLmxlbmd0aCA+IDAsICdubyBpbnB1dHMgZm91bmQnKTtcbiAgICBhc3NlcnQob3V0cHV0cy5sZW5ndGggPiAwLCAnbm8gb3V0cHV0cyBmb3VuZCcpO1xuXG4gICAgY29uc3QgcDJ3c2ggPSB0aGlzLl9jcmVhdGVNdWx0aXNpZ1BheW1lbnQobSwgcHVia2V5cyk7XG5cbiAgICAvLyBWZXJpZnkgcHVia2V5aGFzaCBmb3IgYWxsIGlucHV0cyBtYXRjaGVzIHRoZSBwMndzaCBoYXNoXG4gICAgYXNzZXJ0KFxuICAgICAgaW5wdXRzLmV2ZXJ5KFxuICAgICAgICAoaW5wdXQ6IElucHV0KSA9PiBwMndzaC5vdXRwdXQudG9TdHJpbmcoJ2hleCcpID09PSBpbnB1dC5zY3JpcHRQdWJLZXksXG4gICAgICApLFxuICAgICAgJ2FkZHJlc3MgcHVia2V5aGFzaCBkb2VzIG5vdCBtYXRjaCBpbnB1dCBzY3JpcHRQdWJLZXknLFxuICAgICk7XG5cbiAgICAvLyBjcmVhdG9yXG4gICAgY29uc3QgcHNidCA9IG5ldyBiaXRjb2luLlBzYnQoeyBuZXR3b3JrOiB0aGlzLl9uZXR3b3JrIH0pO1xuXG4gICAgLy8gdXBkYXRlclxuICAgIGlucHV0cy5mb3JFYWNoKChpbnB1dDogSW5wdXQpID0+IHtcbiAgICAgIHBzYnQuYWRkSW5wdXQoe1xuICAgICAgICBoYXNoOiBpbnB1dC50eGlkLFxuICAgICAgICBpbmRleDogaW5wdXQudm91dCxcbiAgICAgICAgd2l0bmVzc1V0eG86IHsgc2NyaXB0OiBwMndzaC5vdXRwdXQsIHZhbHVlOiBpbnB1dC52YWx1ZSB9LFxuICAgICAgICB3aXRuZXNzU2NyaXB0OiBwMndzaC5yZWRlZW0ub3V0cHV0LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBvdXRwdXRzLmZvckVhY2goKG91dHB1dDogT3V0cHV0KSA9PiB7XG4gICAgICBwc2J0LmFkZE91dHB1dCh7XG4gICAgICAgIGFkZHJlc3M6IG91dHB1dC50byxcbiAgICAgICAgdmFsdWU6IG91dHB1dC52YWx1ZSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHBzYnQudG9CYXNlNjQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGUgYSBQU0JUIHdpdGggaW5wdXQgaW5mb3JtYXRpb24gZnJvbSBvdXIgd2FsbGV0IGFuZCB0aGVuIHNpZ24gaW5wdXRzIHRoYXQgd2UgY2FuIHNpZ24gZm9yXG4gICAqIGh0dHBzOi8vZGV2ZWxvcGVyLmJpdGNvaW4ub3JnL3JlZmVyZW5jZS9ycGMvd2FsbGV0cHJvY2Vzc3BzYnQuaHRtbFxuICAgKiBAcGFyYW0gcHNidCBhIGJhc2U2NCBlbmNvZGVkIHBzYnQgc3RyaW5nIChQMldTSCBvbmx5KVxuICAgKiBAcmV0dXJucyBhIGJhc2U2NCBlbmNvZGVkIHNpZ25lZCBwc2J0IHN0cmluZ1xuICAgKi9cbiAgYXN5bmMgd2FsbGV0UHJvY2Vzc1BTQlQocHNidFN0cmluZzogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICBjb25zdCBwc2J0ID0gYml0Y29pbi5Qc2J0LmZyb21CYXNlNjQocHNidFN0cmluZyk7XG5cbiAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIHBzYnQuZGF0YS5pbnB1dHMubWFwKGFzeW5jIChpbnB1dCwgaTogbnVtYmVyKSA9PiB7XG4gICAgICAgIGFzc2VydChcbiAgICAgICAgICBwc2J0LmdldElucHV0VHlwZShpKS5zbGljZSgwLCA1KSA9PT0gJ3Ayd3NoJyxcbiAgICAgICAgICAnb25seSBhY2NlcHRzIFAyV1NIIGlucHV0cycsXG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3Qgc2NyaXB0U3RhY2sgPSBiaXRjb2luLnNjcmlwdC5kZWNvbXBpbGUoaW5wdXQud2l0bmVzc1NjcmlwdCk7XG4gICAgICAgIGNvbnN0IHB1YmtleXMgPSBzY3JpcHRTdGFjay5maWx0ZXIoXG4gICAgICAgICAgKGRhdGEpID0+IEJ1ZmZlci5pc0J1ZmZlcihkYXRhKSAmJiBzZWNwMjU2azEucHVibGljS2V5VmVyaWZ5KGRhdGEpLFxuICAgICAgICApO1xuXG4gICAgICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICAgIHB1YmtleXMubWFwKGFzeW5jIChrZXkpID0+IHtcbiAgICAgICAgICAgIC8vIGNyZWF0ZSBhZGRyZXNzIHVzaW5nIHB1YmtleVxuICAgICAgICAgICAgY29uc3QgeyBhZGRyZXNzOiBhZGRyZXNzU3RyaW5nIH0gPSBiaXRjb2luLnBheW1lbnRzLnAyd3BraCh7XG4gICAgICAgICAgICAgIHB1YmtleToga2V5IGFzIEJ1ZmZlcixcbiAgICAgICAgICAgICAgbmV0d29yazogdGhpcy5fbmV0d29yayxcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAvLyBSZXRyaWV2ZSBhZGRyZXNzIG9iamVjdCBmcm9tIHdhbGxldCB1c2luZyBhZGRyZXNzXG4gICAgICAgICAgICBjb25zdCBhZGRyZXNzOiBBZGRyZXNzID0gYXdhaXQgdGhpcy5xdWlja0ZpbmRBZGRyZXNzKFtcbiAgICAgICAgICAgICAgYWRkcmVzc1N0cmluZyxcbiAgICAgICAgICAgIF0pO1xuXG4gICAgICAgICAgICAvLyBleGl0IGlmIGFkZHJlc3MgZG9lc24ndCBleGlzdCBpbiB3YWxsZXRcbiAgICAgICAgICAgIGlmICghYWRkcmVzcykgcmV0dXJuO1xuXG4gICAgICAgICAgICAvLyBkZXJpdmUga2V5cGFpclxuICAgICAgICAgICAgY29uc3Qga2V5UGFpciA9IGF3YWl0IHRoaXMuZ2V0TWV0aG9kKCdrZXlQYWlyJykoXG4gICAgICAgICAgICAgIGFkZHJlc3MuZGVyaXZhdGlvblBhdGgsXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAvLyBzaWduIFBTQlQgdXNpbmcga2V5cGFpclxuICAgICAgICAgICAgcHNidC5zaWduSW5wdXQoaSwga2V5UGFpcik7XG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgICB9KSxcbiAgICApO1xuXG4gICAgcHNidC52YWxpZGF0ZVNpZ25hdHVyZXNPZkFsbElucHV0cygpOyAvLyBlbnN1cmUgYWxsIHNpZ25hdHVyZXMgYXJlIHZhbGlkIVxuICAgIHJldHVybiBwc2J0LnRvQmFzZTY0KCk7XG4gIH1cblxuICAvKipcbiAgICogRmluYWxpemUgdGhlIGlucHV0cyBvZiBhIFBTQlQuIElmIHRoZSB0cmFuc2FjdGlvbiBpcyBmdWxseSBzaWduZWQsIGl0IHdpbGxcbiAgICogcHJvZHVjZSBhIG5ldHdvcmsgc2VyaWFsaXplZCB0cmFuc2FjdGlvbiB3aGljaCBjYW4gYmUgYnJvYWRjYXN0IHdpdGggc2VuZHJhd3RyYW5zYWN0aW9uXG4gICAqIGh0dHBzOi8vZGV2ZWxvcGVyLmJpdGNvaW4ub3JnL3JlZmVyZW5jZS9ycGMvZmluYWxpemVwc2J0Lmh0bWxcbiAgICogQHBhcmFtIHBzYnQgYSBiYXNlNjQgZW5jb2RlZCBwc2J0IHN0cmluZ1xuICAgKiBAcmV0dXJucyBhIGpzb24gb2JqZWN0IGNvbnRhaW5pbmcgYHBzYnRgIGluIGJhc2U2NCwgYGhleGAgZm9yIHRyYW5zYWN0aW9uIGFuZCBgY29tcGxldGVgIGZvciBpZlxuICAgKiB0aGUgdHJhbnNhY3Rpb24gaGFzIGEgY29tcGxldGUgc2V0IG9mIHNpZ25hdHVyZXNcbiAgICovXG4gIGZpbmFsaXplUFNCVChwc2J0U3RyaW5nOiBzdHJpbmcpOiBmaW5hbGl6ZVBTQlRSZXNwb25zZSB7XG4gICAgY29uc3QgcHNidCA9IGJpdGNvaW4uUHNidC5mcm9tQmFzZTY0KHBzYnRTdHJpbmcpO1xuXG4gICAgdHJ5IHtcbiAgICAgIHBzYnQudmFsaWRhdGVTaWduYXR1cmVzT2ZBbGxJbnB1dHMoKTsgLy8gZW5zdXJlIGFsbCBzaWduYXR1cmVzIGFyZSB2YWxpZCFcbiAgICAgIHBzYnQuZmluYWxpemVBbGxJbnB1dHMoKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcHNidDogcHNidC50b0Jhc2U2NCgpLFxuICAgICAgICBjb21wbGV0ZTogZmFsc2UsXG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgcHNidDogcHNidC50b0Jhc2U2NCgpLFxuICAgICAgaGV4OiBwc2J0LmV4dHJhY3RUcmFuc2FjdGlvbigpLnRvSGV4KCksXG4gICAgICBjb21wbGV0ZTogdHJ1ZSxcbiAgICB9O1xuICB9XG5cbiAgYXN5bmMgZ2V0VW51c2VkQWRkcmVzcyhjaGFuZ2UgPSBmYWxzZSwgbnVtQWRkcmVzc1BlckNhbGwgPSAxMDApIHtcbiAgICBjb25zdCBhZGRyZXNzVHlwZSA9IGNoYW5nZSA/IENIQU5HRV9BRERSRVNTIDogTk9OQ0hBTkdFX0FERFJFU1M7XG4gICAgY29uc3Qga2V5ID0gY2hhbmdlID8gJ2NoYW5nZScgOiAnbm9uQ2hhbmdlJztcblxuICAgIGNvbnN0IGFkZHJlc3MgPSBhd2FpdCB0aGlzLl9nZXRVc2VkVW51c2VkQWRkcmVzc2VzKFxuICAgICAgbnVtQWRkcmVzc1BlckNhbGwsXG4gICAgICBhZGRyZXNzVHlwZSxcbiAgICApLnRoZW4oKHsgdW51c2VkQWRkcmVzcyB9KSA9PiB1bnVzZWRBZGRyZXNzW2tleV0pO1xuICAgIHRoaXMuX3VudXNlZEFkZHJlc3Nlc0JsYWNrbGlzdFthZGRyZXNzLmFkZHJlc3NdID0gdHJ1ZTtcblxuICAgIHJldHVybiBhZGRyZXNzO1xuICB9XG5cbiAgYXN5bmMgX2dldFVzZWRVbnVzZWRBZGRyZXNzZXMobnVtQWRkcmVzc1BlckNhbGwgPSAxMDAsIGFkZHJlc3NUeXBlKSB7XG4gICAgY29uc3QgdXNlZEFkZHJlc3NlcyA9IFtdO1xuICAgIGNvbnN0IGFkZHJlc3NDb3VudE1hcCA9IHsgY2hhbmdlOiAwLCBub25DaGFuZ2U6IDAgfTtcbiAgICBjb25zdCB1bnVzZWRBZGRyZXNzTWFwID0geyBjaGFuZ2U6IG51bGwsIG5vbkNoYW5nZTogbnVsbCB9O1xuXG4gICAgbGV0IGFkZHJMaXN0O1xuICAgIGxldCBhZGRyZXNzSW5kZXggPSAwO1xuICAgIGxldCBjaGFuZ2VBZGRyZXNzZXM6IEFkZHJlc3NbXSA9IFtdO1xuICAgIGxldCBub25DaGFuZ2VBZGRyZXNzZXM6IEFkZHJlc3NbXSA9IFtdO1xuXG4gICAgLyogZXNsaW50LWRpc2FibGUgbm8tdW5tb2RpZmllZC1sb29wLWNvbmRpdGlvbiAqL1xuICAgIHdoaWxlIChcbiAgICAgIChhZGRyZXNzVHlwZSA9PT0gTk9OQ0hBTkdFX09SX0NIQU5HRV9BRERSRVNTICYmXG4gICAgICAgIChhZGRyZXNzQ291bnRNYXAuY2hhbmdlIDwgQUREUkVTU19HQVAgfHxcbiAgICAgICAgICBhZGRyZXNzQ291bnRNYXAubm9uQ2hhbmdlIDwgQUREUkVTU19HQVApKSB8fFxuICAgICAgKGFkZHJlc3NUeXBlID09PSBOT05DSEFOR0VfQUREUkVTUyAmJlxuICAgICAgICBhZGRyZXNzQ291bnRNYXAubm9uQ2hhbmdlIDwgQUREUkVTU19HQVApIHx8XG4gICAgICAoYWRkcmVzc1R5cGUgPT09IENIQU5HRV9BRERSRVNTICYmIGFkZHJlc3NDb3VudE1hcC5jaGFuZ2UgPCBBRERSRVNTX0dBUClcbiAgICApIHtcbiAgICAgIC8qIGVzbGludC1lbmFibGUgbm8tdW5tb2RpZmllZC1sb29wLWNvbmRpdGlvbiAqL1xuICAgICAgYWRkckxpc3QgPSBbXTtcblxuICAgICAgaWYgKFxuICAgICAgICAoYWRkcmVzc1R5cGUgPT09IE5PTkNIQU5HRV9PUl9DSEFOR0VfQUREUkVTUyB8fFxuICAgICAgICAgIGFkZHJlc3NUeXBlID09PSBDSEFOR0VfQUREUkVTUykgJiZcbiAgICAgICAgYWRkcmVzc0NvdW50TWFwLmNoYW5nZSA8IEFERFJFU1NfR0FQXG4gICAgICApIHtcbiAgICAgICAgLy8gU2Nhbm5pbmcgZm9yIGNoYW5nZSBhZGRyXG4gICAgICAgIGNoYW5nZUFkZHJlc3NlcyA9IGF3YWl0IHRoaXMuY2xpZW50LndhbGxldC5nZXRBZGRyZXNzZXMoXG4gICAgICAgICAgYWRkcmVzc0luZGV4LFxuICAgICAgICAgIG51bUFkZHJlc3NQZXJDYWxsLFxuICAgICAgICAgIHRydWUsXG4gICAgICAgICk7XG4gICAgICAgIGFkZHJMaXN0ID0gYWRkckxpc3QuY29uY2F0KGNoYW5nZUFkZHJlc3Nlcyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjaGFuZ2VBZGRyZXNzZXMgPSBbXTtcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICAoYWRkcmVzc1R5cGUgPT09IE5PTkNIQU5HRV9PUl9DSEFOR0VfQUREUkVTUyB8fFxuICAgICAgICAgIGFkZHJlc3NUeXBlID09PSBOT05DSEFOR0VfQUREUkVTUykgJiZcbiAgICAgICAgYWRkcmVzc0NvdW50TWFwLm5vbkNoYW5nZSA8IEFERFJFU1NfR0FQXG4gICAgICApIHtcbiAgICAgICAgLy8gU2Nhbm5pbmcgZm9yIG5vbiBjaGFuZ2UgYWRkclxuICAgICAgICBub25DaGFuZ2VBZGRyZXNzZXMgPSBhd2FpdCB0aGlzLnF1aWNrR2V0QWRkcmVzc2VzKFxuICAgICAgICAgIGFkZHJlc3NJbmRleCxcbiAgICAgICAgICBudW1BZGRyZXNzUGVyQ2FsbCxcbiAgICAgICAgICBmYWxzZSxcbiAgICAgICAgKTtcbiAgICAgICAgYWRkckxpc3QgPSBhZGRyTGlzdC5jb25jYXQobm9uQ2hhbmdlQWRkcmVzc2VzKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgdHJhbnNhY3Rpb25Db3VudHMgPSBhd2FpdCB0aGlzLmdldE1ldGhvZChcbiAgICAgICAgJ2dldEFkZHJlc3NUcmFuc2FjdGlvbkNvdW50cycsXG4gICAgICApKGFkZHJMaXN0KTtcblxuICAgICAgZm9yIChjb25zdCBhZGRyZXNzIG9mIGFkZHJMaXN0KSB7XG4gICAgICAgIGNvbnN0IGlzVXNlZCA9XG4gICAgICAgICAgdHJhbnNhY3Rpb25Db3VudHNbYWRkcmVzcy5hZGRyZXNzXSA+IDAgfHxcbiAgICAgICAgICB0aGlzLl91bnVzZWRBZGRyZXNzZXNCbGFja2xpc3RbYWRkcmVzcy5hZGRyZXNzXTtcbiAgICAgICAgY29uc3QgaXNDaGFuZ2VBZGRyZXNzID0gY2hhbmdlQWRkcmVzc2VzLmZpbmQoXG4gICAgICAgICAgKGEpID0+IGFkZHJlc3MuYWRkcmVzcyA9PT0gYS5hZGRyZXNzLFxuICAgICAgICApO1xuICAgICAgICBjb25zdCBrZXkgPSBpc0NoYW5nZUFkZHJlc3MgPyAnY2hhbmdlJyA6ICdub25DaGFuZ2UnO1xuXG4gICAgICAgIGlmIChpc1VzZWQpIHtcbiAgICAgICAgICB1c2VkQWRkcmVzc2VzLnB1c2goYWRkcmVzcyk7XG4gICAgICAgICAgYWRkcmVzc0NvdW50TWFwW2tleV0gPSAwO1xuICAgICAgICAgIHVudXNlZEFkZHJlc3NNYXBba2V5XSA9IG51bGw7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYWRkcmVzc0NvdW50TWFwW2tleV0rKztcblxuICAgICAgICAgIGlmICghdW51c2VkQWRkcmVzc01hcFtrZXldKSB7XG4gICAgICAgICAgICB1bnVzZWRBZGRyZXNzTWFwW2tleV0gPSBhZGRyZXNzO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBhZGRyZXNzSW5kZXggKz0gbnVtQWRkcmVzc1BlckNhbGw7XG4gICAgfVxuXG4gICAgbGV0IGZpcnN0VW51c2VkQWRkcmVzcztcbiAgICBjb25zdCBpbmRleE5vbkNoYW5nZSA9IHVudXNlZEFkZHJlc3NNYXAubm9uQ2hhbmdlXG4gICAgICA/IHVudXNlZEFkZHJlc3NNYXAubm9uQ2hhbmdlLmluZGV4XG4gICAgICA6IEluZmluaXR5O1xuICAgIGNvbnN0IGluZGV4Q2hhbmdlID0gdW51c2VkQWRkcmVzc01hcC5jaGFuZ2VcbiAgICAgID8gdW51c2VkQWRkcmVzc01hcC5jaGFuZ2UuaW5kZXhcbiAgICAgIDogSW5maW5pdHk7XG5cbiAgICBpZiAoaW5kZXhOb25DaGFuZ2UgPD0gaW5kZXhDaGFuZ2UpXG4gICAgICBmaXJzdFVudXNlZEFkZHJlc3MgPSB1bnVzZWRBZGRyZXNzTWFwLm5vbkNoYW5nZTtcbiAgICBlbHNlIGZpcnN0VW51c2VkQWRkcmVzcyA9IHVudXNlZEFkZHJlc3NNYXAuY2hhbmdlO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHVzZWRBZGRyZXNzZXMsXG4gICAgICB1bnVzZWRBZGRyZXNzOiB1bnVzZWRBZGRyZXNzTWFwLFxuICAgICAgZmlyc3RVbnVzZWRBZGRyZXNzLFxuICAgIH07XG4gIH1cblxuICBhc3luYyBzZW5kU3dlZXBUcmFuc2FjdGlvbldpdGhTZXRPdXRwdXRzKFxuICAgIGV4dGVybmFsQ2hhbmdlQWRkcmVzczogc3RyaW5nLFxuICAgIGZlZVBlckJ5dGU6IG51bWJlcixcbiAgICBfb3V0cHV0czogT3V0cHV0W10sXG4gICAgZml4ZWRJbnB1dHM6IElucHV0W10sXG4gICk6IFByb21pc2U8VHJhbnNhY3Rpb248YlQuVHJhbnNhY3Rpb24+PiB7XG4gICAgY29uc3QgeyBoZXgsIGZlZSB9ID0gYXdhaXQgdGhpcy5fYnVpbGRTd2VlcFRyYW5zYWN0aW9uKFxuICAgICAgZXh0ZXJuYWxDaGFuZ2VBZGRyZXNzLFxuICAgICAgZmVlUGVyQnl0ZSxcbiAgICAgIF9vdXRwdXRzLFxuICAgICAgZml4ZWRJbnB1dHMsXG4gICAgKTtcbiAgICBhd2FpdCB0aGlzLmdldE1ldGhvZCgnc2VuZFJhd1RyYW5zYWN0aW9uJykoaGV4KTtcbiAgICByZXR1cm4gbm9ybWFsaXplVHJhbnNhY3Rpb25PYmplY3QoXG4gICAgICBkZWNvZGVSYXdUcmFuc2FjdGlvbihoZXgsIHRoaXMuX25ldHdvcmspLFxuICAgICAgZmVlLFxuICAgICk7XG4gIH1cblxuICBhc3luYyBfYnVpbGRTd2VlcFRyYW5zYWN0aW9uKFxuICAgIGV4dGVybmFsQ2hhbmdlQWRkcmVzczogc3RyaW5nLFxuICAgIGZlZVBlckJ5dGU6IG51bWJlcixcbiAgICBfb3V0cHV0czogT3V0cHV0W10gPSBbXSxcbiAgICBmaXhlZElucHV0czogSW5wdXRbXSxcbiAgKSB7XG4gICAgY29uc3QgX2ZlZVBlckJ5dGUgPVxuICAgICAgZmVlUGVyQnl0ZSB8fFxuICAgICAgKGF3YWl0IHRoaXMuZ2V0TWV0aG9kKCdnZXRGZWVQZXJCeXRlJykoKSkgfHxcbiAgICAgIEZFRV9QRVJfQllURV9GQUxMQkFDSztcbiAgICBjb25zdCBpbnB1dHM6IElucHV0W10gPSBbXTtcbiAgICBjb25zdCBvdXRwdXRzOiBPdXRwdXRbXSA9IFtdO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBpbnB1dHNGb3JBbW91bnQgPSBhd2FpdCB0aGlzLmdldE1ldGhvZCgnZ2V0SW5wdXRzRm9yQW1vdW50JykoXG4gICAgICAgIF9vdXRwdXRzLFxuICAgICAgICBfZmVlUGVyQnl0ZSxcbiAgICAgICAgZml4ZWRJbnB1dHMsXG4gICAgICAgIDEwMCxcbiAgICAgICAgdHJ1ZSxcbiAgICAgICk7XG4gICAgICBpZiAoaW5wdXRzRm9yQW1vdW50LmNoYW5nZSkge1xuICAgICAgICB0aHJvdyBFcnJvcignVGhlcmUgc2hvdWxkIG5vdCBiZSBhbnkgY2hhbmdlIGZvciBzd2VlcGluZyB0cmFuc2FjdGlvbicpO1xuICAgICAgfVxuICAgICAgaW5wdXRzLnB1c2goLi4uKGlucHV0c0ZvckFtb3VudC5pbnB1dHMgfHwgW10pKTtcbiAgICAgIG91dHB1dHMucHVzaCguLi4oaW5wdXRzRm9yQW1vdW50Lm91dHB1dHMgfHwgW10pKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBpZiAoZml4ZWRJbnB1dHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRocm93IEVycm9yKFxuICAgICAgICAgIGBJbnB1dHMgZm9yIGFtb3VudCBkb2Vzbid0IGV4aXN0IGFuZCBubyBmaXhlZElucHV0cyBwcm92aWRlZGAsXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGlucHV0c0ZvckFtb3VudCA9IGF3YWl0IHRoaXMuX2dldElucHV0Rm9yQW1vdW50V2l0aG91dFV0eG9DaGVjayhcbiAgICAgICAgX291dHB1dHMsXG4gICAgICAgIF9mZWVQZXJCeXRlLFxuICAgICAgICBmaXhlZElucHV0cyxcbiAgICAgICk7XG4gICAgICBpbnB1dHMucHVzaChcbiAgICAgICAgLi4uKGlucHV0c0ZvckFtb3VudC5pbnB1dHMubWFwKCh1dHhvKSA9PiBJbnB1dC5mcm9tVVRYTyh1dHhvKSkgfHwgW10pLFxuICAgICAgKTtcbiAgICAgIG91dHB1dHMucHVzaCguLi4oaW5wdXRzRm9yQW1vdW50Lm91dHB1dHMgfHwgW10pKTtcbiAgICB9XG4gICAgX291dHB1dHMuZm9yRWFjaCgob3V0cHV0KSA9PiB7XG4gICAgICBjb25zdCBzcGxpY2VJbmRleCA9IG91dHB1dHMuZmluZEluZGV4KFxuICAgICAgICAoc3dlZXBPdXRwdXQ6IE91dHB1dCkgPT4gb3V0cHV0LnZhbHVlID09PSBzd2VlcE91dHB1dC52YWx1ZSxcbiAgICAgICk7XG4gICAgICBvdXRwdXRzLnNwbGljZShzcGxpY2VJbmRleCwgMSk7XG4gICAgfSk7XG4gICAgX291dHB1dHMucHVzaCh7XG4gICAgICB0bzogZXh0ZXJuYWxDaGFuZ2VBZGRyZXNzLFxuICAgICAgdmFsdWU6IG91dHB1dHNbMF0udmFsdWUsXG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXMuX2J1aWxkVHJhbnNhY3Rpb25XaXRob3V0VXR4b0NoZWNrKFxuICAgICAgX291dHB1dHMsXG4gICAgICBfZmVlUGVyQnl0ZSxcbiAgICAgIGlucHV0cyxcbiAgICApO1xuICB9XG5cbiAgX2dldElucHV0Rm9yQW1vdW50V2l0aG91dFV0eG9DaGVjayhcbiAgICBfb3V0cHV0czogT3V0cHV0W10sXG4gICAgX2ZlZVBlckJ5dGU6IG51bWJlcixcbiAgICBmaXhlZElucHV0czogSW5wdXRbXSxcbiAgKToge1xuICAgIGlucHV0czogYlQuVVRYT1tdO1xuICAgIG91dHB1dHM6IHsgdmFsdWU6IG51bWJlcjsgaWQ/OiBzdHJpbmcgfVtdO1xuICAgIGZlZTogbnVtYmVyO1xuICAgIGNoYW5nZTogeyB2YWx1ZTogbnVtYmVyOyBpZD86IHN0cmluZyB9O1xuICB9IHtcbiAgICBjb25zdCB1dHhvQmFsYW5jZSA9IGZpeGVkSW5wdXRzLnJlZHVjZSgoYSwgYikgPT4gYSArIChiWyd2YWx1ZSddIHx8IDApLCAwKTtcbiAgICBjb25zdCBvdXRwdXRCYWxhbmNlID0gX291dHB1dHMucmVkdWNlKChhLCBiKSA9PiBhICsgKGJbJ3ZhbHVlJ10gfHwgMCksIDApO1xuICAgIGNvbnN0IGFtb3VudFRvU2VuZCA9XG4gICAgICB1dHhvQmFsYW5jZSAtXG4gICAgICBfZmVlUGVyQnl0ZSAqICgoX291dHB1dHMubGVuZ3RoICsgMSkgKiAzOSArIGZpeGVkSW5wdXRzLmxlbmd0aCAqIDE1Myk7IC8vIHRvZG8gYmV0dGVyIGNhbGN1bGF0aW9uXG5cbiAgICBjb25zdCB0YXJnZXRzID0gX291dHB1dHMubWFwKCh0YXJnZXQsIGkpID0+ICh7XG4gICAgICBpZDogJ21haW4nLFxuICAgICAgdmFsdWU6IHRhcmdldC52YWx1ZSxcbiAgICB9KSk7XG4gICAgaWYgKGFtb3VudFRvU2VuZCAtIG91dHB1dEJhbGFuY2UgPiAwKSB7XG4gICAgICB0YXJnZXRzLnB1c2goeyBpZDogJ21haW4nLCB2YWx1ZTogYW1vdW50VG9TZW5kIC0gb3V0cHV0QmFsYW5jZSB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gc2VsZWN0Q29pbnMoXG4gICAgICBmaXhlZElucHV0cyxcbiAgICAgIHRhcmdldHMsXG4gICAgICBNYXRoLmNlaWwoX2ZlZVBlckJ5dGUpLFxuICAgICAgZml4ZWRJbnB1dHMsXG4gICAgKTtcbiAgfVxuXG4gIGFzeW5jIF9idWlsZFRyYW5zYWN0aW9uV2l0aG91dFV0eG9DaGVjayhcbiAgICBvdXRwdXRzOiBPdXRwdXRbXSxcbiAgICBmZWVQZXJCeXRlOiBudW1iZXIsXG4gICAgZml4ZWRJbnB1dHM6IElucHV0W10sXG4gICkge1xuICAgIGNvbnN0IG5ldHdvcmsgPSB0aGlzLl9uZXR3b3JrO1xuXG4gICAgY29uc3QgeyBmZWUgfSA9IHRoaXMuX2dldElucHV0Rm9yQW1vdW50V2l0aG91dFV0eG9DaGVjayhcbiAgICAgIG91dHB1dHMsXG4gICAgICBmZWVQZXJCeXRlLFxuICAgICAgZml4ZWRJbnB1dHMsXG4gICAgKTtcbiAgICBjb25zdCBpbnB1dHMgPSBmaXhlZElucHV0cztcblxuICAgIGNvbnN0IHR4YiA9IG5ldyBiaXRjb2luLlRyYW5zYWN0aW9uQnVpbGRlcihuZXR3b3JrKTtcblxuICAgIGZvciAoY29uc3Qgb3V0cHV0IG9mIG91dHB1dHMpIHtcbiAgICAgIGNvbnN0IHRvID0gb3V0cHV0LnRvOyAvLyBBbGxvdyBmb3IgT1BfUkVUVVJOXG4gICAgICB0eGIuYWRkT3V0cHV0KHRvLCBvdXRwdXQudmFsdWUpO1xuICAgIH1cblxuICAgIGNvbnN0IHByZXZPdXRTY3JpcHRUeXBlID0gJ3Ayd3BraCc7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGlucHV0cy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3Qgd2FsbGV0ID0gYXdhaXQgdGhpcy5nZXRNZXRob2QoJ2dldFdhbGxldEFkZHJlc3MnKShcbiAgICAgICAgaW5wdXRzW2ldLmFkZHJlc3MsXG4gICAgICApO1xuICAgICAgY29uc3Qga2V5UGFpciA9IGF3YWl0IHRoaXMuZ2V0TWV0aG9kKCdrZXlQYWlyJykod2FsbGV0LmRlcml2YXRpb25QYXRoKTtcbiAgICAgIGNvbnN0IHBheW1lbnRWYXJpYW50ID0gdGhpcy5nZXRNZXRob2QoJ2dldFBheW1lbnRWYXJpYW50RnJvbVB1YmxpY0tleScpKFxuICAgICAgICBrZXlQYWlyLnB1YmxpY0tleSxcbiAgICAgICk7XG5cbiAgICAgIHR4Yi5hZGRJbnB1dChpbnB1dHNbaV0udHhpZCwgaW5wdXRzW2ldLnZvdXQsIDAsIHBheW1lbnRWYXJpYW50Lm91dHB1dCk7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbnB1dHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHdhbGxldCA9IGF3YWl0IHRoaXMuZ2V0TWV0aG9kKCdnZXRXYWxsZXRBZGRyZXNzJykoXG4gICAgICAgIGlucHV0c1tpXS5hZGRyZXNzLFxuICAgICAgKTtcbiAgICAgIGNvbnN0IGtleVBhaXIgPSBhd2FpdCB0aGlzLmdldE1ldGhvZCgna2V5UGFpcicpKHdhbGxldC5kZXJpdmF0aW9uUGF0aCk7XG4gICAgICBjb25zdCBwYXltZW50VmFyaWFudCA9IHRoaXMuZ2V0TWV0aG9kKCdnZXRQYXltZW50VmFyaWFudEZyb21QdWJsaWNLZXknKShcbiAgICAgICAga2V5UGFpci5wdWJsaWNLZXksXG4gICAgICApO1xuICAgICAgY29uc3QgbmVlZHNXaXRuZXNzID0gdHJ1ZTtcblxuICAgICAgY29uc3Qgc2lnblBhcmFtcyA9IHtcbiAgICAgICAgcHJldk91dFNjcmlwdFR5cGUsXG4gICAgICAgIHZpbjogaSxcbiAgICAgICAga2V5UGFpcixcbiAgICAgICAgd2l0bmVzc1ZhbHVlOiAwLFxuICAgICAgfTtcblxuICAgICAgaWYgKG5lZWRzV2l0bmVzcykge1xuICAgICAgICBzaWduUGFyYW1zLndpdG5lc3NWYWx1ZSA9IGlucHV0c1tpXS52YWx1ZTtcbiAgICAgIH1cblxuICAgICAgdHhiLnNpZ24oc2lnblBhcmFtcyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgaGV4OiB0eGIuYnVpbGQoKS50b0hleCgpLCBmZWUgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBxdWlja0dldEFkZHJlc3NlcyBpcyBhbiBvcHRpbWl6ZWQgdmVyc2lvbiBvZiBnZXRBZGRyZXNzZXMuXG4gICAqIEl0IHJlbW92ZXMgdGhlIGNhbGwgdG8gYGFzeW5jU2V0SW1tZWRpYXRlKClgLCBzcGVlZGluZyB1cCB0aGUgZnVuY3Rpb24gYnkgYSBmYWN0b3Igb2YgNnguXG4gICAqXG4gICAqIEBwYXJhbSBzdGFydGluZ0luZGV4XG4gICAqIEBwYXJhbSBudW1BZGRyZXNzZXNcbiAgICogQHBhcmFtIGNoYW5nZVxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxBZGRyZXNzW10+fVxuICAgKi9cbiAgYXN5bmMgcXVpY2tHZXRBZGRyZXNzZXMoXG4gICAgc3RhcnRpbmdJbmRleCA9IDAsXG4gICAgbnVtQWRkcmVzc2VzID0gMSxcbiAgICBjaGFuZ2UgPSBmYWxzZSxcbiAgKTogUHJvbWlzZTxBZGRyZXNzW10+IHtcbiAgICBpZiAobnVtQWRkcmVzc2VzIDwgMSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdZb3UgbXVzdCByZXR1cm4gYXQgbGVhc3Qgb25lIGFkZHJlc3MnKTtcbiAgICB9XG5cbiAgICBjb25zdCBhZGRyZXNzZXMgPSBbXTtcbiAgICBjb25zdCBsYXN0SW5kZXggPSBzdGFydGluZ0luZGV4ICsgbnVtQWRkcmVzc2VzO1xuICAgIGNvbnN0IGNoYW5nZVZhbCA9IGNoYW5nZSA/ICcxJyA6ICcwJztcblxuICAgIC8vIE9yaWdpbmFsIHdhbGxldCBwcm92aWRlciBpcyBmZXRjaGVkIHRvIGdldCB0aGUgYmFzZSBkZXJpdmF0aW9uIHBhdGhcbiAgICBjb25zdCBvcmlnaW5hbFByb3ZpZGVyID0gdGhpcy5jbGllbnQuZ2V0UHJvdmlkZXJGb3JNZXRob2QoJ2dldEFkZHJlc3NlcycpO1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgY29uc3QgYmFzZURlcml2YXRpb25QYXRoID0gKG9yaWdpbmFsUHJvdmlkZXIgYXMgYW55KVxuICAgICAgLl9iYXNlRGVyaXZhdGlvblBhdGggYXMgc3RyaW5nO1xuXG4gICAgY29uc3QgZ2V0RGVyaXZhdGlvblBhdGhBZGRyZXNzRm46IChcbiAgICAgIHBhdGg6IHN0cmluZyxcbiAgICApID0+IFByb21pc2U8QWRkcmVzcz4gPSB0aGlzLmNsaWVudC5nZXRNZXRob2QoJ2dldERlcml2YXRpb25QYXRoQWRkcmVzcycpO1xuXG4gICAgZm9yIChcbiAgICAgIGxldCBjdXJyZW50SW5kZXggPSBzdGFydGluZ0luZGV4O1xuICAgICAgY3VycmVudEluZGV4IDwgbGFzdEluZGV4O1xuICAgICAgY3VycmVudEluZGV4KytcbiAgICApIHtcbiAgICAgIGNvbnN0IHN1YlBhdGggPSBjaGFuZ2VWYWwgKyAnLycgKyBjdXJyZW50SW5kZXg7XG4gICAgICBjb25zdCBwYXRoID0gYmFzZURlcml2YXRpb25QYXRoICsgJy8nICsgc3ViUGF0aDtcbiAgICAgIGNvbnN0IGFkZHJlc3NPYmplY3QgPSBhd2FpdCBnZXREZXJpdmF0aW9uUGF0aEFkZHJlc3NGbihwYXRoKTtcbiAgICAgIGFkZHJlc3Nlcy5wdXNoKGFkZHJlc3NPYmplY3QpO1xuICAgIH1cblxuICAgIHJldHVybiBhZGRyZXNzZXM7XG4gIH1cblxuICAvKipcbiAgICogcXVpY2tGaW5kQWRkcmVzcyBpcyBhbiBvcHRpbWl6ZWQgdmVyc2lvbiBvZiBmaW5kQWRkcmVzcy5cbiAgICpcbiAgICogSXQgc2VhcmNoZXMgdGhyb3VnaCBib3RoIGNoYW5nZSBhbmQgbm9uLWNoYW5nZSBhZGRyZXNzZXMgZWFjaCBpdGVyYXRpb24uXG4gICAqXG4gICAqIFRoaXMgaXMgaW4gY29udHJhc3QgdG8gdGhlIG9yaWdpbmFsIGZpbmRBZGRyZXNzIGZ1bmN0aW9uIHdoaWNoIHNlYXJjaGVzXG4gICAqIHRocm91Z2ggYWxsIG5vbi1jaGFuZ2UgYWRkcmVzc2VzIGJlZm9yZSBtb3Zpbmcgb24gdG8gY2hhbmdlIGFkZHJlc3Nlcy5cbiAgICpcbiAgICogQHBhcmFtIGFkZHJlc3Nlc1xuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxBZGRyZXNzW10+fVxuICAgKi9cbiAgYXN5bmMgcXVpY2tGaW5kQWRkcmVzcyhhZGRyZXNzZXM6IHN0cmluZ1tdKTogUHJvbWlzZTxBZGRyZXNzPiB7XG4gICAgY29uc3QgYWRkcmVzc2VzUGVyQ2FsbCA9IDIwO1xuICAgIGxldCBpbmRleCA9IDA7XG5cbiAgICB3aGlsZSAoaW5kZXggPCB0aGlzLl9tYXhBZGRyZXNzZXNUb0Rlcml2ZSkge1xuICAgICAgY29uc3Qgd2FsbGV0Tm9uQ2hhbmdlQWRkcmVzc2VzID0gYXdhaXQgdGhpcy5xdWlja0dldEFkZHJlc3NlcyhcbiAgICAgICAgaW5kZXgsXG4gICAgICAgIGFkZHJlc3Nlc1BlckNhbGwsXG4gICAgICAgIHRydWUsXG4gICAgICApO1xuICAgICAgY29uc3Qgd2FsbGV0Q2hhbmdlQWRkcmVzc2VzID0gYXdhaXQgdGhpcy5xdWlja0dldEFkZHJlc3NlcyhcbiAgICAgICAgaW5kZXgsXG4gICAgICAgIGFkZHJlc3Nlc1BlckNhbGwsXG4gICAgICAgIGZhbHNlLFxuICAgICAgKTtcbiAgICAgIGNvbnN0IHdhbGxldEFkZHJlc3NlcyA9IFtcbiAgICAgICAgLi4ud2FsbGV0Tm9uQ2hhbmdlQWRkcmVzc2VzLFxuICAgICAgICAuLi53YWxsZXRDaGFuZ2VBZGRyZXNzZXMsXG4gICAgICBdO1xuICAgICAgY29uc3Qgd2FsbGV0QWRkcmVzcyA9IHdhbGxldEFkZHJlc3Nlcy5maW5kKCh3YWxsZXRBZGRyKSA9PlxuICAgICAgICBhZGRyZXNzZXMuZmluZCgoYWRkcikgPT4gd2FsbGV0QWRkci5hZGRyZXNzID09PSBhZGRyKSxcbiAgICAgICk7XG5cbiAgICAgIGlmICh3YWxsZXRBZGRyZXNzKSB7XG4gICAgICAgIC8vIEluY3JlbWVudCBtYXggYWRkcmVzc2VzIHRvIGRlcml2ZSBieSAxMDAgaWYgZm91bmQgd2l0aGluIDEwMCBhZGRyZXNzZXMgb2YgbWF4QWRkcmVzc2VzVG9EZXJpdmVcbiAgICAgICAgdGhpcy5fbWF4QWRkcmVzc2VzVG9EZXJpdmUgPSBNYXRoLm1heChcbiAgICAgICAgICB0aGlzLl9tYXhBZGRyZXNzZXNUb0Rlcml2ZSxcbiAgICAgICAgICBpbmRleCArIDEwMCxcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIHdhbGxldEFkZHJlc3M7XG4gICAgICB9XG4gICAgICBpbmRleCArPSBhZGRyZXNzZXNQZXJDYWxsO1xuICAgIH1cbiAgfVxufVxuIl0sIm5hbWVzIjpbImJpdGNvaW4iLCJGRUVfUEVSX0JZVEVfRkFMTEJBQ0siLCJBRERSRVNTX0dBUCIsIk5PTkNIQU5HRV9BRERSRVNTIiwiQ0hBTkdFX0FERFJFU1MiLCJOT05DSEFOR0VfT1JfQ0hBTkdFX0FERFJFU1MiLCJCaXRjb2luV2FsbGV0UHJvdmlkZXIiLCJQcm92aWRlciIsImJ1aWxkU3dlZXBUcmFuc2FjdGlvbldpdGhTZXRPdXRwdXRzIiwiZXh0ZXJuYWxDaGFuZ2VBZGRyZXNzIiwiZmVlUGVyQnl0ZSIsIl9vdXRwdXRzIiwiZml4ZWRJbnB1dHMiLCJfYnVpbGRTd2VlcFRyYW5zYWN0aW9uIiwiZ2V0VW51c2VkQWRkcmVzc2VzQmxhY2tsaXN0IiwiX3VudXNlZEFkZHJlc3Nlc0JsYWNrbGlzdCIsInNldFVudXNlZEFkZHJlc3Nlc0JsYWNrbGlzdCIsInVudXNlZEFkZHJlc3Nlc0JsYWNrbGlzdCIsInNldE1heEFkZHJlc3Nlc1RvRGVyaXZlIiwibWF4QWRkcmVzc2VzVG9EZXJpdmUiLCJfbWF4QWRkcmVzc2VzVG9EZXJpdmUiLCJnZXRNYXhBZGRyZXNzZXNUb0Rlcml2ZSIsIl9jcmVhdGVNdWx0aXNpZ1BheW1lbnQiLCJtIiwicHVia2V5cyIsImxlbmd0aCIsIkVycm9yIiwicDJtcyIsInBheW1lbnRzIiwibWFwIiwia2V5IiwiQnVmZmVyIiwiZnJvbSIsIm5ldHdvcmsiLCJfbmV0d29yayIsInAyd3NoIiwicmVkZWVtIiwiY3JlYXRlTXVsdGlzaWciLCJhZGRyZXNzIiwicmVkZWVtU2NyaXB0Iiwib3V0cHV0IiwidG9TdHJpbmciLCJidWlsZE11bHRpc2lnUFNCVCIsImlucHV0cyIsIm91dHB1dHMiLCJhc3NlcnQiLCJldmVyeSIsImlucHV0Iiwic2NyaXB0UHViS2V5IiwicHNidCIsIlBzYnQiLCJmb3JFYWNoIiwiYWRkSW5wdXQiLCJoYXNoIiwidHhpZCIsImluZGV4Iiwidm91dCIsIndpdG5lc3NVdHhvIiwic2NyaXB0IiwidmFsdWUiLCJ3aXRuZXNzU2NyaXB0IiwiYWRkT3V0cHV0IiwidG8iLCJ0b0Jhc2U2NCIsIndhbGxldFByb2Nlc3NQU0JUIiwicHNidFN0cmluZyIsImZyb21CYXNlNjQiLCJQcm9taXNlIiwiYWxsIiwiZGF0YSIsImkiLCJnZXRJbnB1dFR5cGUiLCJzbGljZSIsInNjcmlwdFN0YWNrIiwiZGVjb21waWxlIiwiZmlsdGVyIiwiaXNCdWZmZXIiLCJzZWNwMjU2azEiLCJwdWJsaWNLZXlWZXJpZnkiLCJhZGRyZXNzU3RyaW5nIiwicDJ3cGtoIiwicHVia2V5IiwicXVpY2tGaW5kQWRkcmVzcyIsImtleVBhaXIiLCJnZXRNZXRob2QiLCJkZXJpdmF0aW9uUGF0aCIsInNpZ25JbnB1dCIsInZhbGlkYXRlU2lnbmF0dXJlc09mQWxsSW5wdXRzIiwiZmluYWxpemVQU0JUIiwiZmluYWxpemVBbGxJbnB1dHMiLCJlcnJvciIsImNvbXBsZXRlIiwiaGV4IiwiZXh0cmFjdFRyYW5zYWN0aW9uIiwidG9IZXgiLCJnZXRVbnVzZWRBZGRyZXNzIiwiY2hhbmdlIiwibnVtQWRkcmVzc1BlckNhbGwiLCJhZGRyZXNzVHlwZSIsIl9nZXRVc2VkVW51c2VkQWRkcmVzc2VzIiwidGhlbiIsInVudXNlZEFkZHJlc3MiLCJ1c2VkQWRkcmVzc2VzIiwiYWRkcmVzc0NvdW50TWFwIiwibm9uQ2hhbmdlIiwidW51c2VkQWRkcmVzc01hcCIsImFkZHJMaXN0IiwiYWRkcmVzc0luZGV4IiwiY2hhbmdlQWRkcmVzc2VzIiwibm9uQ2hhbmdlQWRkcmVzc2VzIiwiY2xpZW50Iiwid2FsbGV0IiwiZ2V0QWRkcmVzc2VzIiwiY29uY2F0IiwicXVpY2tHZXRBZGRyZXNzZXMiLCJ0cmFuc2FjdGlvbkNvdW50cyIsImlzVXNlZCIsImlzQ2hhbmdlQWRkcmVzcyIsImZpbmQiLCJhIiwicHVzaCIsImZpcnN0VW51c2VkQWRkcmVzcyIsImluZGV4Tm9uQ2hhbmdlIiwiSW5maW5pdHkiLCJpbmRleENoYW5nZSIsInNlbmRTd2VlcFRyYW5zYWN0aW9uV2l0aFNldE91dHB1dHMiLCJmZWUiLCJub3JtYWxpemVUcmFuc2FjdGlvbk9iamVjdCIsImRlY29kZVJhd1RyYW5zYWN0aW9uIiwiX2ZlZVBlckJ5dGUiLCJpbnB1dHNGb3JBbW91bnQiLCJlIiwiX2dldElucHV0Rm9yQW1vdW50V2l0aG91dFV0eG9DaGVjayIsInV0eG8iLCJJbnB1dCIsImZyb21VVFhPIiwic3BsaWNlSW5kZXgiLCJmaW5kSW5kZXgiLCJzd2VlcE91dHB1dCIsInNwbGljZSIsIl9idWlsZFRyYW5zYWN0aW9uV2l0aG91dFV0eG9DaGVjayIsInV0eG9CYWxhbmNlIiwicmVkdWNlIiwiYiIsIm91dHB1dEJhbGFuY2UiLCJhbW91bnRUb1NlbmQiLCJ0YXJnZXRzIiwidGFyZ2V0IiwiaWQiLCJzZWxlY3RDb2lucyIsIk1hdGgiLCJjZWlsIiwidHhiIiwiVHJhbnNhY3Rpb25CdWlsZGVyIiwicHJldk91dFNjcmlwdFR5cGUiLCJwYXltZW50VmFyaWFudCIsInB1YmxpY0tleSIsIm5lZWRzV2l0bmVzcyIsInNpZ25QYXJhbXMiLCJ2aW4iLCJ3aXRuZXNzVmFsdWUiLCJzaWduIiwiYnVpbGQiLCJzdGFydGluZ0luZGV4IiwibnVtQWRkcmVzc2VzIiwiYWRkcmVzc2VzIiwibGFzdEluZGV4IiwiY2hhbmdlVmFsIiwib3JpZ2luYWxQcm92aWRlciIsImdldFByb3ZpZGVyRm9yTWV0aG9kIiwiYmFzZURlcml2YXRpb25QYXRoIiwiX2Jhc2VEZXJpdmF0aW9uUGF0aCIsImdldERlcml2YXRpb25QYXRoQWRkcmVzc0ZuIiwiY3VycmVudEluZGV4Iiwic3ViUGF0aCIsInBhdGgiLCJhZGRyZXNzT2JqZWN0IiwiYWRkcmVzc2VzUGVyQ2FsbCIsIndhbGxldE5vbkNoYW5nZUFkZHJlc3NlcyIsIndhbGxldENoYW5nZUFkZHJlc3NlcyIsIndhbGxldEFkZHJlc3NlcyIsIndhbGxldEFkZHJlc3MiLCJ3YWxs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
409
+ //# sourceMappingURL=BitcoinWalletProvider.js.map