@bitgo-beta/sdk-coin-flr 1.0.1-beta.82 → 1.0.1-beta.821

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 (40) hide show
  1. package/dist/src/flr.d.ts +145 -3
  2. package/dist/src/flr.d.ts.map +1 -1
  3. package/dist/src/flr.js +464 -3
  4. package/dist/src/flrToken.d.ts +26 -0
  5. package/dist/src/flrToken.d.ts.map +1 -0
  6. package/dist/src/flrToken.js +49 -0
  7. package/dist/src/iface.d.ts +148 -0
  8. package/dist/src/iface.d.ts.map +1 -0
  9. package/dist/src/iface.js +3 -0
  10. package/dist/src/index.d.ts +2 -0
  11. package/dist/src/index.d.ts.map +1 -1
  12. package/dist/src/index.js +3 -1
  13. package/dist/src/lib/transactionBuilder.d.ts +2 -0
  14. package/dist/src/lib/transactionBuilder.d.ts.map +1 -1
  15. package/dist/src/lib/transactionBuilder.js +5 -1
  16. package/dist/src/register.d.ts.map +1 -1
  17. package/dist/src/register.js +5 -1
  18. package/dist/test/resources.d.ts +42 -0
  19. package/dist/test/resources.d.ts.map +1 -0
  20. package/dist/test/resources.js +117 -0
  21. package/dist/test/unit/flr.d.ts +2 -0
  22. package/dist/test/unit/flr.d.ts.map +1 -0
  23. package/dist/test/unit/flr.js +1040 -0
  24. package/dist/test/unit/flrToken.d.ts +2 -0
  25. package/dist/test/unit/flrToken.d.ts.map +1 -0
  26. package/dist/test/unit/flrToken.js +30 -0
  27. package/dist/test/unit/getBuilder.d.ts +3 -0
  28. package/dist/test/unit/getBuilder.d.ts.map +1 -0
  29. package/dist/test/unit/getBuilder.js +10 -0
  30. package/dist/test/unit/transactionBuilder/send.d.ts +2 -0
  31. package/dist/test/unit/transactionBuilder/send.d.ts.map +1 -0
  32. package/dist/test/unit/transactionBuilder/send.js +19 -0
  33. package/dist/test/unit/utils.d.ts +2 -0
  34. package/dist/test/unit/utils.d.ts.map +1 -0
  35. package/dist/test/unit/utils.js +29 -0
  36. package/dist/tsconfig.tsbuildinfo +1 -0
  37. package/package.json +22 -10
  38. package/.eslintignore +0 -5
  39. package/.mocharc.yml +0 -8
  40. package/CHANGELOG.md +0 -44
package/dist/src/flr.js CHANGED
@@ -7,12 +7,55 @@
7
7
  * @coinFullName Flare
8
8
  * @coinWebsite https://flare-explorer.flare.network
9
9
  */
10
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ var desc = Object.getOwnPropertyDescriptor(m, k);
13
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
14
+ desc = { enumerable: true, get: function() { return m[k]; } };
15
+ }
16
+ Object.defineProperty(o, k2, desc);
17
+ }) : (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ o[k2] = m[k];
20
+ }));
21
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
22
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
23
+ }) : function(o, v) {
24
+ o["default"] = v;
25
+ });
26
+ var __importStar = (this && this.__importStar) || (function () {
27
+ var ownKeys = function(o) {
28
+ ownKeys = Object.getOwnPropertyNames || function (o) {
29
+ var ar = [];
30
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
31
+ return ar;
32
+ };
33
+ return ownKeys(o);
34
+ };
35
+ return function (mod) {
36
+ if (mod && mod.__esModule) return mod;
37
+ var result = {};
38
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
39
+ __setModuleDefault(result, mod);
40
+ return result;
41
+ };
42
+ })();
43
+ var __importDefault = (this && this.__importDefault) || function (mod) {
44
+ return (mod && mod.__esModule) ? mod : { "default": mod };
45
+ };
10
46
  Object.defineProperty(exports, "__esModule", { value: true });
11
47
  exports.Flr = void 0;
48
+ const bignumber_js_1 = require("bignumber.js");
49
+ const secp256k1_1 = require("@bitgo-beta/secp256k1");
50
+ const keccak_1 = __importDefault(require("keccak"));
51
+ const secp256k1 = __importStar(require("secp256k1"));
52
+ const _ = __importStar(require("lodash"));
12
53
  const sdk_core_1 = require("@bitgo-beta/sdk-core");
13
54
  const statics_1 = require("@bitgo-beta/statics");
14
55
  const abstract_eth_1 = require("@bitgo-beta/abstract-eth");
15
56
  const lib_1 = require("./lib");
57
+ const sdk_coin_flrp_1 = require("@bitgo-beta/sdk-coin-flrp");
58
+ const ethereumjs_util_1 = require("ethereumjs-util");
16
59
  class Flr extends abstract_eth_1.AbstractEthLikeNewCoins {
17
60
  constructor(bitgo, staticsCoin) {
18
61
  super(bitgo, staticsCoin);
@@ -27,15 +70,433 @@ class Flr extends abstract_eth_1.AbstractEthLikeNewCoins {
27
70
  supportsTss() {
28
71
  return true;
29
72
  }
73
+ /** inherited doc */
74
+ getDefaultMultisigType() {
75
+ return sdk_core_1.multisigTypes.tss;
76
+ }
30
77
  /** @inheritDoc */
31
78
  getMPCAlgorithm() {
32
79
  return 'ecdsa';
33
80
  }
34
- async recoveryBlockchainExplorerQuery(query) {
35
- const apiToken = sdk_core_1.common.Environments[this.bitgo.getEnv()].flrExplorerApiToken;
81
+ /** @inheritDoc */
82
+ supportsMessageSigning() {
83
+ return true;
84
+ }
85
+ /** @inheritDoc */
86
+ supportsSigningTypedData() {
87
+ return true;
88
+ }
89
+ async buildUnsignedSweepTxnTSS(params) {
90
+ return this.buildUnsignedSweepTxnMPCv2(params);
91
+ }
92
+ /**
93
+ * Validates if an address is valid for FLR
94
+ * Also validates P-chain addresses for cross-chain transactions
95
+ * @param {string} address - address to validate
96
+ * @returns {boolean} - validation result
97
+ */
98
+ isValidAddress(address) {
99
+ // also validate p-chain address for cross-chain txs
100
+ return !!address && (super.isValidAddress(address) || sdk_coin_flrp_1.FlrPLib.Utils.isValidAddress(address));
101
+ }
102
+ /**
103
+ * Get the corresponding P-chain coin name
104
+ * @returns {string} flrp or tflrp depending on mainnet/testnet
105
+ */
106
+ getFlrP() {
107
+ return this.getChain().toString() === 'flr' ? 'flrp' : 'tflrp';
108
+ }
109
+ /**
110
+ * Get the atomic transaction builder factory for cross-chain operations
111
+ * @returns {FlrPLib.TransactionBuilderFactory} the atomic builder factory
112
+ */
113
+ getAtomicBuilder() {
114
+ return new sdk_coin_flrp_1.FlrPLib.TransactionBuilderFactory(statics_1.coins.get(this.getFlrP()));
115
+ }
116
+ /**
117
+ * Check if this coin is a token
118
+ * @returns {boolean} false for FLR (base chain)
119
+ */
120
+ isToken() {
121
+ return false;
122
+ }
123
+ /**
124
+ * Explains an atomic transaction using atomic builder.
125
+ * @param {string} txHex - the transaction hex
126
+ * @returns {Promise<AtomicTransactionExplanation>} the transaction explanation
127
+ * @private
128
+ */
129
+ async explainAtomicTransaction(txHex) {
130
+ const txBuilder = this.getAtomicBuilder().from(txHex);
131
+ const tx = await txBuilder.build();
132
+ return tx.explainTransaction();
133
+ }
134
+ /**
135
+ * Verify signature for an atomic transaction using atomic builder.
136
+ * @param {string} txHex - the transaction hex
137
+ * @returns {Promise<boolean>} true if signature is from the input address
138
+ * @private
139
+ */
140
+ async verifySignatureForAtomicTransaction(txHex) {
141
+ const txBuilder = this.getAtomicBuilder().from(txHex);
142
+ const tx = await txBuilder.build();
143
+ const payload = tx.signablePayload;
144
+ const signatures = tx.signature.map((s) => Buffer.from(sdk_coin_flrp_1.FlrPLib.Utils.removeHexPrefix(s), 'hex'));
145
+ const network = _.get(tx, '_network');
146
+ const recoverPubkey = signatures.map((s) => sdk_coin_flrp_1.FlrPLib.Utils.recoverySignature(network, payload, s));
147
+ const expectedSenders = recoverPubkey.map((r) => (0, ethereumjs_util_1.pubToAddress)(r, true));
148
+ const senders = tx.inputs.map((i) => sdk_coin_flrp_1.FlrPLib.Utils.parseAddress(i.address));
149
+ return expectedSenders.every((e) => senders.some((sender) => e.equals(sender)));
150
+ }
151
+ /**
152
+ * Explain a transaction from txHex, overriding BaseCoins
153
+ * transaction can be either atomic or eth txn.
154
+ * @param {ExplainTransactionOptions} params The options with which to explain the transaction
155
+ * @returns {Promise<TransactionExplanation>} the transaction explanation
156
+ */
157
+ async explainTransaction(params) {
158
+ const txHex = params.txHex || (params.halfSigned && params.halfSigned.txHex);
159
+ if (!txHex) {
160
+ throw new Error('missing txHex in explain tx parameters');
161
+ }
162
+ if (params.crossChainType) {
163
+ return this.explainAtomicTransaction(txHex);
164
+ }
165
+ if (!params.feeInfo) {
166
+ throw new Error('missing feeInfo in explain tx parameters');
167
+ }
168
+ const txBuilder = this.getTransactionBuilder();
169
+ txBuilder.from(txHex);
170
+ const tx = await txBuilder.build();
171
+ return Object.assign(this.explainEVMTransaction(tx), { fee: params.feeInfo });
172
+ }
173
+ /**
174
+ * Explains an EVM transaction using regular eth txn builder
175
+ * @param {BaseTransaction} tx - the transaction to explain
176
+ * @returns {Object} the transaction explanation
177
+ * @private
178
+ */
179
+ explainEVMTransaction(tx) {
180
+ const outputs = tx.outputs.map((output) => {
181
+ return {
182
+ address: output.address,
183
+ amount: output.value,
184
+ };
185
+ });
186
+ const displayOrder = ['id', 'outputAmount', 'changeAmount', 'outputs', 'changeOutputs', 'fee'];
187
+ return {
188
+ displayOrder,
189
+ id: tx.id,
190
+ outputs: outputs,
191
+ outputAmount: outputs
192
+ .reduce((accumulator, output) => accumulator.plus(output.amount), new bignumber_js_1.BigNumber('0'))
193
+ .toFixed(0),
194
+ changeOutputs: [], // account based does not use change outputs
195
+ changeAmount: '0', // account base does not make change
196
+ };
197
+ }
198
+ /**
199
+ * Verify that a transaction prebuild complies with the original intention
200
+ *
201
+ * @param {VerifyFlrTransactionOptions} params
202
+ * @param params.txParams params object passed to send
203
+ * @param params.txPrebuild prebuild object returned by server
204
+ * @param params.wallet Wallet object to obtain keys to verify against
205
+ * @returns {Promise<boolean>}
206
+ */
207
+ async verifyTransaction(params) {
208
+ const { txParams, txPrebuild, wallet, walletType } = params;
209
+ // For TSS wallets, use the parent class's TSS-specific verification
210
+ if (walletType === 'tss') {
211
+ return super.verifyTransaction(params);
212
+ }
213
+ if (!txParams?.recipients || !txPrebuild?.recipients || !wallet) {
214
+ throw new Error(`missing params`);
215
+ }
216
+ if (txParams.hop && txParams.recipients.length > 1) {
217
+ throw new Error(`tx cannot be both a batch and hop transaction`);
218
+ }
219
+ if (txPrebuild.recipients.length > 1) {
220
+ throw new Error(`${this.getChain()} doesn't support sending to more than 1 destination address within a single transaction. Try again, using only a single recipient.`);
221
+ }
222
+ if (txParams.hop && txPrebuild.hopTransaction) {
223
+ // Check recipient amount for hop transaction
224
+ if (txParams.recipients.length !== 1) {
225
+ throw new Error(`hop transaction only supports 1 recipient but ${txParams.recipients.length} found`);
226
+ }
227
+ // Check tx sends to hop address
228
+ let expectedHopAddress;
229
+ if (txPrebuild.hopTransaction.type === 'Export') {
230
+ const decodedHopTx = await this.explainAtomicTransaction(txPrebuild.hopTransaction.tx);
231
+ expectedHopAddress = abstract_eth_1.optionalDeps.ethUtil.stripHexPrefix(decodedHopTx.inputs[0].address);
232
+ }
233
+ else {
234
+ const decodedHopTx = abstract_eth_1.optionalDeps.EthTx.TransactionFactory.fromSerializedData(abstract_eth_1.optionalDeps.ethUtil.toBuffer(txPrebuild.hopTransaction.tx));
235
+ expectedHopAddress = abstract_eth_1.optionalDeps.ethUtil.stripHexPrefix(decodedHopTx.getSenderAddress().toString());
236
+ }
237
+ const actualHopAddress = abstract_eth_1.optionalDeps.ethUtil.stripHexPrefix(txPrebuild.recipients[0].address);
238
+ if (expectedHopAddress.toLowerCase() !== actualHopAddress.toLowerCase()) {
239
+ throw new Error('recipient address of txPrebuild does not match hop address');
240
+ }
241
+ // Convert TransactionRecipient array to Recipient array
242
+ const recipients = txParams.recipients.map((r) => {
243
+ return {
244
+ address: r.address,
245
+ amount: typeof r.amount === 'number' ? r.amount.toString() : r.amount,
246
+ };
247
+ });
248
+ // Check destination address and amount
249
+ await this.validateHopPrebuild(wallet, txPrebuild.hopTransaction, { recipients });
250
+ }
251
+ else if (txParams.recipients.length > 1) {
252
+ // Check total amount for batch transaction
253
+ let expectedTotalAmount = new bignumber_js_1.BigNumber(0);
254
+ for (let i = 0; i < txParams.recipients.length; i++) {
255
+ expectedTotalAmount = expectedTotalAmount.plus(txParams.recipients[i].amount);
256
+ }
257
+ if (!expectedTotalAmount.isEqualTo(txPrebuild.recipients[0].amount)) {
258
+ throw new Error('batch transaction amount in txPrebuild received from BitGo servers does not match txParams supplied by client');
259
+ }
260
+ }
261
+ else {
262
+ // Check recipient address and amount for normal transaction
263
+ if (txParams.recipients.length !== 1) {
264
+ throw new Error(`normal transaction only supports 1 recipient but ${txParams.recipients.length} found`);
265
+ }
266
+ const expectedAmount = new bignumber_js_1.BigNumber(txParams.recipients[0].amount);
267
+ if (!expectedAmount.isEqualTo(txPrebuild.recipients[0].amount)) {
268
+ throw new Error('normal transaction amount in txPrebuild received from BitGo servers does not match txParams supplied by client');
269
+ }
270
+ if (Flr.isFLRAddress(txParams.recipients[0].address) &&
271
+ txParams.recipients[0].address !== txPrebuild.recipients[0].address) {
272
+ throw new Error('destination address in normal txPrebuild does not match that in txParams supplied by client');
273
+ }
274
+ }
275
+ // Check coin is correct for all transaction types
276
+ if (!this.verifyCoin(txPrebuild)) {
277
+ throw new Error(`coin in txPrebuild did not match that in txParams supplied by client`);
278
+ }
279
+ return true;
280
+ }
281
+ /**
282
+ * Check if an address is a FLR C-chain address (0x format)
283
+ * @param {string} address - the address to check
284
+ * @returns {boolean} true if it's a C-chain address
285
+ * @private
286
+ */
287
+ static isFLRAddress(address) {
288
+ return !!address.match(/0x[a-fA-F0-9]{40}/);
289
+ }
290
+ /**
291
+ * Verify that the coin matches in the prebuild
292
+ * @param {TransactionPrebuild} txPrebuild - the transaction prebuild
293
+ * @returns {boolean} true if coin matches
294
+ */
295
+ verifyCoin(txPrebuild) {
296
+ return txPrebuild.coin === this.getChain();
297
+ }
298
+ /**
299
+ * Coin-specific things done before signing a transaction, i.e. verification
300
+ * @param {PresignTransactionOptions} params - the presign options
301
+ * @returns {Promise<PresignTransactionOptions>}
302
+ */
303
+ async presignTransaction(params) {
304
+ if (!_.isUndefined(params.hopTransaction) && !_.isUndefined(params.wallet) && !_.isUndefined(params.buildParams)) {
305
+ await this.validateHopPrebuild(params.wallet, params.hopTransaction);
306
+ }
307
+ return params;
308
+ }
309
+ /**
310
+ * Modify prebuild after receiving it from the server. Add things like nlocktime
311
+ * @param {TransactionPrebuild} params - the transaction prebuild
312
+ * @returns {Promise<TransactionPrebuild>}
313
+ */
314
+ async postProcessPrebuild(params) {
315
+ if (!_.isUndefined(params.hopTransaction) && !_.isUndefined(params.wallet) && !_.isUndefined(params.buildParams)) {
316
+ await this.validateHopPrebuild(params.wallet, params.hopTransaction, params.buildParams);
317
+ }
318
+ return params;
319
+ }
320
+ /**
321
+ * Validates that the hop prebuild from the HSM is valid and correct
322
+ * @param {IWallet} wallet The wallet that the prebuild is for
323
+ * @param {HopPrebuild} hopPrebuild The prebuild to validate
324
+ * @param {Object} originalParams The original parameters passed to prebuildTransaction
325
+ * @returns {Promise<void>}
326
+ * @throws Error if The prebuild is invalid
327
+ */
328
+ async validateHopPrebuild(wallet, hopPrebuild, originalParams) {
329
+ const { tx, id, signature } = hopPrebuild;
330
+ // first, validate the HSM signature
331
+ const serverXpub = sdk_core_1.common.Environments[this.bitgo.getEnv()].hsmXpub;
332
+ const serverPubkeyBuffer = secp256k1_1.bip32.fromBase58(serverXpub).publicKey;
333
+ const signatureBuffer = Buffer.from(abstract_eth_1.optionalDeps.ethUtil.stripHexPrefix(signature), 'hex');
334
+ const messageBuffer = hopPrebuild.type === 'Export' ? Flr.getTxHash(tx) : Buffer.from(abstract_eth_1.optionalDeps.ethUtil.stripHexPrefix(id), 'hex');
335
+ const sig = new Uint8Array(signatureBuffer.length === 64 ? signatureBuffer : signatureBuffer.slice(1));
336
+ const isValidSignature = secp256k1.ecdsaVerify(sig, messageBuffer, serverPubkeyBuffer);
337
+ if (!isValidSignature) {
338
+ throw new Error(`Hop txid signature invalid`);
339
+ }
340
+ if (hopPrebuild.type === 'Export') {
341
+ const explainHopExportTx = await this.explainAtomicTransaction(tx);
342
+ // If original params are given, we can check them against the transaction prebuild params
343
+ if (!_.isNil(originalParams)) {
344
+ const { recipients } = originalParams;
345
+ // Then validate that the tx params actually equal the requested params to nano flr plus import tx fee.
346
+ const originalAmount = new bignumber_js_1.BigNumber(recipients[0].amount).div(1e9).plus(1e6).toFixed(0);
347
+ const originalDestination = recipients[0].address;
348
+ const hopAmount = explainHopExportTx.outputAmount;
349
+ const hopDestination = explainHopExportTx.outputs[0].address;
350
+ if (originalAmount !== hopAmount) {
351
+ throw new Error(`Hop amount: ${hopAmount} does not equal original amount: ${originalAmount}`);
352
+ }
353
+ if (originalDestination && hopDestination.toLowerCase() !== originalDestination.toLowerCase()) {
354
+ throw new Error(`Hop destination: ${hopDestination} does not equal original recipient: ${originalDestination}`);
355
+ }
356
+ }
357
+ if (!(await this.verifySignatureForAtomicTransaction(tx))) {
358
+ throw new Error(`Invalid hop transaction signature, txid: ${id}`);
359
+ }
360
+ }
361
+ else {
362
+ const builtHopTx = abstract_eth_1.optionalDeps.EthTx.TransactionFactory.fromSerializedData(abstract_eth_1.optionalDeps.ethUtil.toBuffer(tx));
363
+ // If original params are given, we can check them against the transaction prebuild params
364
+ if (!_.isNil(originalParams)) {
365
+ const { recipients } = originalParams;
366
+ // Then validate that the tx params actually equal the requested params
367
+ const originalAmount = new bignumber_js_1.BigNumber(recipients[0].amount);
368
+ const originalDestination = recipients[0].address;
369
+ const hopAmount = new bignumber_js_1.BigNumber(abstract_eth_1.optionalDeps.ethUtil.bufferToHex(builtHopTx.value));
370
+ if (!builtHopTx.to) {
371
+ throw new Error(`Transaction does not have a destination address`);
372
+ }
373
+ const hopDestination = builtHopTx.to.toString();
374
+ if (!hopAmount.eq(originalAmount)) {
375
+ throw new Error(`Hop amount: ${hopAmount} does not equal original amount: ${originalAmount}`);
376
+ }
377
+ if (hopDestination.toLowerCase() !== originalDestination.toLowerCase()) {
378
+ throw new Error(`Hop destination: ${hopDestination} does not equal original recipient: ${originalDestination}`);
379
+ }
380
+ }
381
+ if (!builtHopTx.verifySignature()) {
382
+ // We don't want to continue at all in this case, at risk of FLR being stuck on the hop address
383
+ throw new Error(`Invalid hop transaction signature, txid: ${id}`);
384
+ }
385
+ if (abstract_eth_1.optionalDeps.ethUtil.addHexPrefix(builtHopTx.hash().toString('hex')) !== id) {
386
+ throw new Error(`Signed hop txid does not equal actual txid`);
387
+ }
388
+ }
389
+ }
390
+ /**
391
+ * Modify prebuild before sending it to the server. Add things like hop transaction params
392
+ * @param {BuildOptions} buildParams The whitelisted parameters for this prebuild
393
+ * @param {boolean} buildParams.hop True if this should prebuild a hop tx, else false
394
+ * @param {Recipient[]} buildParams.recipients The recipients array of this transaction
395
+ * @param {Wallet} buildParams.wallet The wallet sending this tx
396
+ * @param {string} buildParams.walletPassphrase the passphrase for this wallet
397
+ * @returns {Promise<BuildOptions>}
398
+ */
399
+ async getExtraPrebuildParams(buildParams) {
400
+ if (!_.isUndefined(buildParams.hop) &&
401
+ buildParams.hop &&
402
+ !_.isUndefined(buildParams.wallet) &&
403
+ !_.isUndefined(buildParams.recipients)) {
404
+ if (this.isToken()) {
405
+ throw new Error(`Hop transactions are not enabled for FLR tokens, nor are they necessary. Please remove the 'hop' parameter and try again.`);
406
+ }
407
+ return (await this.createHopTransactionParams({
408
+ recipients: buildParams.recipients,
409
+ type: buildParams.type,
410
+ }));
411
+ }
412
+ return {};
413
+ }
414
+ /**
415
+ * Creates the extra parameters needed to build a hop transaction
416
+ * @param {HopTransactionBuildOptions} params The original build parameters
417
+ * @returns {Promise<HopParams>} extra parameters object to merge with the original build parameters object and send to the platform
418
+ */
419
+ async createHopTransactionParams({ recipients, type }) {
420
+ if (!recipients || !Array.isArray(recipients)) {
421
+ throw new Error('expecting array of recipients');
422
+ }
423
+ // Right now we only support 1 recipient
424
+ if (recipients.length !== 1) {
425
+ throw new Error('must send to exactly 1 recipient');
426
+ }
427
+ const recipientAddress = recipients[0].address;
428
+ const recipientAmount = recipients[0].amount;
429
+ const feeEstimateParams = {
430
+ recipient: recipientAddress,
431
+ amount: recipientAmount,
432
+ hop: true,
433
+ type,
434
+ };
435
+ const feeEstimate = await this.feeEstimate(feeEstimateParams);
436
+ const gasLimit = feeEstimate.gasLimitEstimate;
437
+ // Even if `feeEstimate < gasLimit`, we shouldn't end up with `gasPrice === 0`.
438
+ const gasPrice = Math.max(Math.round(feeEstimate.feeEstimate / gasLimit), 1);
439
+ const gasPriceMax = gasPrice * 5;
440
+ // Payment id is a random number so its different for every tx
441
+ const paymentId = Math.floor(Math.random() * 10000000000).toString();
442
+ const userReqSig = '0x';
443
+ return {
444
+ hopParams: {
445
+ userReqSig,
446
+ gasPriceMax,
447
+ paymentId,
448
+ gasLimit,
449
+ },
450
+ };
451
+ }
452
+ /**
453
+ * Fetch fee estimate information from the server
454
+ * @param {FeeEstimateOptions} params The params passed into the function
455
+ * @param {Boolean} [params.hop] True if we should estimate fee for a hop transaction
456
+ * @param {String} [params.recipient] The recipient of the transaction to estimate a send to
457
+ * @param {String} [params.data] The data to estimate a send for
458
+ * @returns {Promise<FeeEstimate>} The fee info returned from the server
459
+ */
460
+ async feeEstimate(params) {
461
+ const query = {};
462
+ if (params && params.hop) {
463
+ query.hop = params.hop;
464
+ }
465
+ if (params && params.recipient) {
466
+ query.recipient = params.recipient;
467
+ }
468
+ if (params && params.data) {
469
+ query.data = params.data;
470
+ }
471
+ if (params && params.amount) {
472
+ query.amount = params.amount;
473
+ }
474
+ if (params && params.type) {
475
+ query.type = params.type;
476
+ }
477
+ return await this.bitgo.get(this.url('/tx/fee')).query(query).result();
478
+ }
479
+ /**
480
+ * Calculate tx hash like evm from tx hex.
481
+ * @param {string} tx - the transaction hex
482
+ * @returns {Buffer} tx hash
483
+ */
484
+ static getTxHash(tx) {
485
+ const hash = (0, keccak_1.default)('keccak256');
486
+ hash.update(abstract_eth_1.optionalDeps.ethUtil.stripHexPrefix(tx), 'hex');
487
+ return hash.digest();
488
+ }
489
+ /**
490
+ * Make a query to Flare explorer for information such as balance, token balance, solidity calls
491
+ * @param {Object} query key-value pairs of parameters to append after /api
492
+ * @param {string} apiKey optional API key to use instead of the one from the environment
493
+ * @returns {Promise<Object>} response from Flare explorer
494
+ */
495
+ async recoveryBlockchainExplorerQuery(query, apiKey) {
496
+ const apiToken = apiKey || sdk_core_1.common.Environments[this.bitgo.getEnv()].flrExplorerApiToken;
36
497
  const explorerUrl = sdk_core_1.common.Environments[this.bitgo.getEnv()].flrExplorerBaseUrl;
37
498
  return await (0, abstract_eth_1.recoveryBlockchainExplorerQuery)(query, explorerUrl, apiToken);
38
499
  }
39
500
  }
40
501
  exports.Flr = Flr;
41
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmxyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2Zsci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7R0FPRzs7O0FBRUgsbURBQWlGO0FBQ2pGLGlEQUF5RTtBQUN6RSwyREFBb0c7QUFDcEcsK0JBQTJDO0FBRTNDLE1BQWEsR0FBSSxTQUFRLHNDQUF1QjtJQUM5QyxZQUFzQixLQUFnQixFQUFFLFdBQXVDO1FBQzdFLEtBQUssQ0FBQyxLQUFLLEVBQUUsV0FBVyxDQUFDLENBQUM7SUFDNUIsQ0FBQztJQUVELE1BQU0sQ0FBQyxjQUFjLENBQUMsS0FBZ0IsRUFBRSxXQUF1QztRQUM3RSxPQUFPLElBQUksR0FBRyxDQUFDLEtBQUssRUFBRSxXQUFXLENBQUMsQ0FBQztJQUNyQyxDQUFDO0lBRVMscUJBQXFCO1FBQzdCLE9BQU8sSUFBSSx3QkFBa0IsQ0FBQyxlQUFLLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDaEUsQ0FBQztJQUVELGtCQUFrQjtJQUNsQixXQUFXO1FBQ1QsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsa0JBQWtCO0lBQ2xCLGVBQWU7UUFDYixPQUFPLE9BQU8sQ0FBQztJQUNqQixDQUFDO0lBRUQsS0FBSyxDQUFDLCtCQUErQixDQUFDLEtBQTZCO1FBQ2pFLE1BQU0sUUFBUSxHQUFHLGlCQUFNLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxtQkFBbUIsQ0FBQztRQUM5RSxNQUFNLFdBQVcsR0FBRyxpQkFBTSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsa0JBQWtCLENBQUM7UUFDaEYsT0FBTyxNQUFNLElBQUEsOENBQStCLEVBQUMsS0FBSyxFQUFFLFdBQXFCLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDdkYsQ0FBQztDQUNGO0FBNUJELGtCQTRCQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKipcbiAqIEBkZXZlbG9wZXJSZWZlcmVuY2VzXG4gKiAtIERldmVsb3BlciBIdWI6IGh0dHBzOi8vZGV2LmZsYXJlLm5ldHdvcmsvXG4gKiAtIERvYzogaHR0cHM6Ly9kb2NzLmZsYXJlLm5ldHdvcmsvdXNlci93YWxsZXRzL1xuICpcbiAqIEBjb2luRnVsbE5hbWUgRmxhcmVcbiAqIEBjb2luV2Vic2l0ZSBodHRwczovL2ZsYXJlLWV4cGxvcmVyLmZsYXJlLm5ldHdvcmtcbiAqL1xuXG5pbXBvcnQgeyBCYXNlQ29pbiwgQml0R29CYXNlLCBjb21tb24sIE1QQ0FsZ29yaXRobSB9IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1jb3JlJztcbmltcG9ydCB7IEJhc2VDb2luIGFzIFN0YXRpY3NCYXNlQ29pbiwgY29pbnMgfSBmcm9tICdAYml0Z28tYmV0YS9zdGF0aWNzJztcbmltcG9ydCB7IEFic3RyYWN0RXRoTGlrZU5ld0NvaW5zLCByZWNvdmVyeUJsb2NrY2hhaW5FeHBsb3JlclF1ZXJ5IH0gZnJvbSAnQGJpdGdvLWJldGEvYWJzdHJhY3QtZXRoJztcbmltcG9ydCB7IFRyYW5zYWN0aW9uQnVpbGRlciB9IGZyb20gJy4vbGliJztcblxuZXhwb3J0IGNsYXNzIEZsciBleHRlbmRzIEFic3RyYWN0RXRoTGlrZU5ld0NvaW5zIHtcbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKGJpdGdvOiBCaXRHb0Jhc2UsIHN0YXRpY3NDb2luPzogUmVhZG9ubHk8U3RhdGljc0Jhc2VDb2luPikge1xuICAgIHN1cGVyKGJpdGdvLCBzdGF0aWNzQ29pbik7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlSW5zdGFuY2UoYml0Z286IEJpdEdvQmFzZSwgc3RhdGljc0NvaW4/OiBSZWFkb25seTxTdGF0aWNzQmFzZUNvaW4+KTogQmFzZUNvaW4ge1xuICAgIHJldHVybiBuZXcgRmxyKGJpdGdvLCBzdGF0aWNzQ29pbik7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0VHJhbnNhY3Rpb25CdWlsZGVyKCk6IFRyYW5zYWN0aW9uQnVpbGRlciB7XG4gICAgcmV0dXJuIG5ldyBUcmFuc2FjdGlvbkJ1aWxkZXIoY29pbnMuZ2V0KHRoaXMuZ2V0QmFzZUNoYWluKCkpKTtcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdERvYyAqL1xuICBzdXBwb3J0c1RzcygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdERvYyAqL1xuICBnZXRNUENBbGdvcml0aG0oKTogTVBDQWxnb3JpdGhtIHtcbiAgICByZXR1cm4gJ2VjZHNhJztcbiAgfVxuXG4gIGFzeW5jIHJlY292ZXJ5QmxvY2tjaGFpbkV4cGxvcmVyUXVlcnkocXVlcnk6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4pOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIHVua25vd24+PiB7XG4gICAgY29uc3QgYXBpVG9rZW4gPSBjb21tb24uRW52aXJvbm1lbnRzW3RoaXMuYml0Z28uZ2V0RW52KCldLmZsckV4cGxvcmVyQXBpVG9rZW47XG4gICAgY29uc3QgZXhwbG9yZXJVcmwgPSBjb21tb24uRW52aXJvbm1lbnRzW3RoaXMuYml0Z28uZ2V0RW52KCldLmZsckV4cGxvcmVyQmFzZVVybDtcbiAgICByZXR1cm4gYXdhaXQgcmVjb3ZlcnlCbG9ja2NoYWluRXhwbG9yZXJRdWVyeShxdWVyeSwgZXhwbG9yZXJVcmwgYXMgc3RyaW5nLCBhcGlUb2tlbik7XG4gIH1cbn1cbiJdfQ==
502
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmxyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2Zsci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7R0FPRzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBRUgsK0NBQXlDO0FBQ3pDLHFEQUE4QztBQUM5QyxvREFBNEI7QUFDNUIscURBQXVDO0FBQ3ZDLDBDQUE0QjtBQUM1QixtREFhOEI7QUFDOUIsaURBQXVGO0FBQ3ZGLDJEQU9rQztBQUNsQywrQkFBMkM7QUFDM0MsNkRBQW9EO0FBQ3BELHFEQUErQztBQW9CL0MsTUFBYSxHQUFJLFNBQVEsc0NBQXVCO0lBQzlDLFlBQXNCLEtBQWdCLEVBQUUsV0FBdUM7UUFDN0UsS0FBSyxDQUFDLEtBQUssRUFBRSxXQUFXLENBQUMsQ0FBQztJQUM1QixDQUFDO0lBRUQsTUFBTSxDQUFDLGNBQWMsQ0FBQyxLQUFnQixFQUFFLFdBQXVDO1FBQzdFLE9BQU8sSUFBSSxHQUFHLENBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQyxDQUFDO0lBQ3JDLENBQUM7SUFFUyxxQkFBcUI7UUFDN0IsT0FBTyxJQUFJLHdCQUFrQixDQUFDLGVBQUssQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNoRSxDQUFDO0lBRUQsa0JBQWtCO0lBQ2xCLFdBQVc7UUFDVCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxvQkFBb0I7SUFDcEIsc0JBQXNCO1FBQ3BCLE9BQU8sd0JBQWEsQ0FBQyxHQUFHLENBQUM7SUFDM0IsQ0FBQztJQUVELGtCQUFrQjtJQUNsQixlQUFlO1FBQ2IsT0FBTyxPQUFPLENBQUM7SUFDakIsQ0FBQztJQUVELGtCQUFrQjtJQUNsQixzQkFBc0I7UUFDcEIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsa0JBQWtCO0lBQ2xCLHdCQUF3QjtRQUN0QixPQUFPLElBQUksQ0FBQztJQUNkLENB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QUFTLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUN6RSxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILE1BQU0sQ0FBQyxTQUFTLENBQUMsRUFBVTtRQUN6QixNQUFNLElBQUksR0FBRyxJQUFBLGdCQUFNLEVBQUMsV0FBVyxDQUFDLENBQUM7UUFDakMsSUFBSSxDQUFDLE1BQU0sQ0FBQywyQkFBWSxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDNUQsT0FBTyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7SUFDdkIsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsS0FBSyxDQUFDLCtCQUErQixDQUNuQyxLQUE2QixFQUM3QixNQUFlO1FBRWYsTUFBTSxRQUFRLEdBQUcsTUFBTSxJQUFJLGlCQUFNLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxtQkFBbUIsQ0FBQztRQUN4RixNQUFNLFdBQVcsR0FBRyxpQkFBTSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsa0JBQWtCLENBQUM7UUFDaEYsT0FBTyxNQUFNLElBQUEsOENBQStCLEVBQUMsS0FBSyxFQUFFLFdBQXFCLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDdkYsQ0FBQztDQUNGO0FBNWZELGtCQTRmQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKipcbiAqIEBkZXZlbG9wZXJSZWZlcmVuY2VzXG4gKiAtIERldmVsb3BlciBIdWI6IGh0dHBzOi8vZGV2LmZsYXJlLm5ldHdvcmsvXG4gKiAtIERvYzogaHR0cHM6Ly9kb2NzLmZsYXJlLm5ldHdvcmsvdXNlci93YWxsZXRzL1xuICpcbiAqIEBjb2luRnVsbE5hbWUgRmxhcmVcbiAqIEBjb2luV2Vic2l0ZSBodHRwczovL2ZsYXJlLWV4cGxvcmVyLmZsYXJlLm5ldHdvcmtcbiAqL1xuXG5pbXBvcnQgeyBCaWdOdW1iZXIgfSBmcm9tICdiaWdudW1iZXIuanMnO1xuaW1wb3J0IHsgYmlwMzIgfSBmcm9tICdAYml0Z28tYmV0YS9zZWNwMjU2azEnO1xuaW1wb3J0IEtlY2NhayBmcm9tICdrZWNjYWsnO1xuaW1wb3J0ICogYXMgc2VjcDI1NmsxIGZyb20gJ3NlY3AyNTZrMSc7XG5pbXBvcnQgKiBhcyBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQge1xuICBCYXNlQ29pbixcbiAgQmFzZVRyYW5zYWN0aW9uLFxuICBCaXRHb0Jhc2UsXG4gIGNvbW1vbixcbiAgRmVlRXN0aW1hdGVPcHRpb25zLFxuICBJV2FsbGV0LFxuICBNUENBbGdvcml0aG0sXG4gIE11bHRpc2lnVHlwZSxcbiAgbXVsdGlzaWdUeXBlcyxcbiAgUmVjaXBpZW50LFxuICBUcmFuc2FjdGlvbkV4cGxhbmF0aW9uLFxuICBFbnRyeSxcbn0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWNvcmUnO1xuaW1wb3J0IHsgQmFzZUNvaW4gYXMgU3RhdGljc0Jhc2VDb2luLCBjb2lucywgRmxhcmVOZXR3b3JrIH0gZnJvbSAnQGJpdGdvLWJldGEvc3RhdGljcyc7XG5pbXBvcnQge1xuICBBYnN0cmFjdEV0aExpa2VOZXdDb2lucyxcbiAgb3B0aW9uYWxEZXBzLFxuICByZWNvdmVyeUJsb2NrY2hhaW5FeHBsb3JlclF1ZXJ5LFxuICBVbnNpZ25lZFN3ZWVwVHhNUEN2MixcbiAgUmVjb3Zlck9wdGlvbnMsXG4gIE9mZmxpbmVWYXVsdFR4SW5mbyxcbn0gZnJvbSAnQGJpdGdvLWJldGEvYWJzdHJhY3QtZXRoJztcbmltcG9ydCB7IFRyYW5zYWN0aW9uQnVpbGRlciB9IGZyb20gJy4vbGliJztcbmltcG9ydCB7IEZsclBMaWIgfSBmcm9tICdAYml0Z28tYmV0YS9zZGstY29pbi1mbHJwJztcbmltcG9ydCB7IHB1YlRvQWRkcmVzcyB9IGZyb20gJ2V0aGVyZXVtanMtdXRpbCc7XG5pbXBvcnQge1xuICBCdWlsZE9wdGlvbnMsXG4gIEV4cGxhaW5UcmFuc2FjdGlvbk9wdGlvbnMsXG4gIEZlZUVzdGltYXRlLFxuICBIb3BQYXJhbXMsXG4gIEhvcFByZWJ1aWxkLFxuICBIb3BUcmFuc2FjdGlvbkJ1aWxkT3B0aW9ucyxcbiAgUHJlc2lnblRyYW5zYWN0aW9uT3B0aW9ucyxcbiAgVHJhbnNhY3Rpb25QcmVidWlsZCxcbiAgVmVyaWZ5RmxyVHJhbnNhY3Rpb25PcHRpb25zLFxufSBmcm9tICcuL2lmYWNlJztcblxuLyoqXG4gKiBFeHRlbmRlZCBUcmFuc2FjdGlvbkV4cGxhbmF0aW9uIGludGVyZmFjZSB3aXRoIGlucHV0cyBmb3IgYXRvbWljIHRyYW5zYWN0aW9uc1xuICovXG5pbnRlcmZhY2UgQXRvbWljVHJhbnNhY3Rpb25FeHBsYW5hdGlvbiBleHRlbmRzIFRyYW5zYWN0aW9uRXhwbGFuYXRpb24ge1xuICBpbnB1dHM6IEVudHJ5W107XG59XG5cbmV4cG9ydCBjbGFzcyBGbHIgZXh0ZW5kcyBBYnN0cmFjdEV0aExpa2VOZXdDb2lucyB7XG4gIHByb3RlY3RlZCBjb25zdHJ1Y3RvcihiaXRnbzogQml0R29CYXNlLCBzdGF0aWNzQ29pbj86IFJlYWRvbmx5PFN0YXRpY3NCYXNlQ29pbj4pIHtcbiAgICBzdXBlcihiaXRnbywgc3RhdGljc0NvaW4pO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZUluc3RhbmNlKGJpdGdvOiBCaXRHb0Jhc2UsIHN0YXRpY3NDb2luPzogUmVhZG9ubHk8U3RhdGljc0Jhc2VDb2luPik6IEJhc2VDb2luIHtcbiAgICByZXR1cm4gbmV3IEZscihiaXRnbywgc3RhdGljc0NvaW4pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGdldFRyYW5zYWN0aW9uQnVpbGRlcigpOiBUcmFuc2FjdGlvbkJ1aWxkZXIge1xuICAgIHJldHVybiBuZXcgVHJhbnNhY3Rpb25CdWlsZGVyKGNvaW5zLmdldCh0aGlzLmdldEJhc2VDaGFpbigpKSk7XG4gIH1cblxuICAvKiogQGluaGVyaXREb2MgKi9cbiAgc3VwcG9ydHNUc3MoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKiogaW5oZXJpdGVkIGRvYyAqL1xuICBnZXREZWZhdWx0TXVsdGlzaWdUeXBlKCk6IE11bHRpc2lnVHlwZSB7XG4gICAgcmV0dXJuIG11bHRpc2lnVHlwZXMudHNzO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0RG9jICovXG4gIGdldE1QQ0FsZ29yaXRobSgpOiBNUENBbGdvcml0aG0ge1xuICAgIHJldHVybiAnZWNkc2EnO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0RG9jICovXG4gIHN1cHBvcnRzTWVzc2FnZVNpZ25pbmcoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKiogQGluaGVyaXREb2MgKi9cbiAgc3VwcG9ydHNTaWduaW5nVHlwZWREYXRhKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGJ1aWxkVW5zaWduZWRTd2VlcFR4blRTUyhwYXJhbXM6IFJlY292ZXJPcHRpb25zKTogUHJvbWlzZTxPZmZsaW5lVmF1bHRUeEluZm8gfCBVbnNpZ25lZFN3ZWVwVHhNUEN2Mj4ge1xuICAgIHJldHVybiB0aGlzLmJ1aWxkVW5zaWduZWRTd2VlcFR4bk1QQ3YyKHBhcmFtcyk7XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGVzIGlmIGFuIGFkZHJlc3MgaXMgdmFsaWQgZm9yIEZMUlxuICAgKiBBbHNvIHZhbGlkYXRlcyBQLWNoYWluIGFkZHJlc3NlcyBmb3IgY3Jvc3MtY2hhaW4gdHJhbnNhY3Rpb25zXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhZGRyZXNzIC0gYWRkcmVzcyB0byB2YWxpZGF0ZVxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSB2YWxpZGF0aW9uIHJlc3VsdFxuICAgKi9cbiAgaXNWYWxpZEFkZHJlc3MoYWRkcmVzczogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgLy8gYWxzbyB2YWxpZGF0ZSBwLWNoYWluIGFkZHJlc3MgZm9yIGNyb3NzLWNoYWluIHR4c1xuICAgIHJldHVybiAhIWFkZHJlc3MgJiYgKHN1cGVyLmlzVmFsaWRBZGRyZXNzKGFkZHJlc3MpIHx8IEZsclBMaWIuVXRpbHMuaXNWYWxpZEFkZHJlc3MoYWRkcmVzcykpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgY29ycmVzcG9uZGluZyBQLWNoYWluIGNvaW4gbmFtZVxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBmbHJwIG9yIHRmbHJwIGRlcGVuZGluZyBvbiBtYWlubmV0L3Rlc3RuZXRcbiAgICovXG4gIGdldEZsclAoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5nZXRDaGFpbigpLnRvU3RyaW5nKCkgPT09ICdmbHInID8gJ2ZscnAnIDogJ3RmbHJwJztcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIGF0b21pYyB0cmFuc2FjdGlvbiBidWlsZGVyIGZhY3RvcnkgZm9yIGNyb3NzLWNoYWluIG9wZXJhdGlvbnNcbiAgICogQHJldHVybnMge0ZsclBMaWIuVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeX0gdGhlIGF0b21pYyBidWlsZGVyIGZhY3RvcnlcbiAgICovXG4gIHByb3RlY3RlZCBnZXRBdG9taWNCdWlsZGVyKCk6IEZsclBMaWIuVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeSB7XG4gICAgcmV0dXJuIG5ldyBGbHJQTGliLlRyYW5zYWN0aW9uQnVpbGRlckZhY3RvcnkoY29pbnMuZ2V0KHRoaXMuZ2V0RmxyUCgpKSk7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgdGhpcyBjb2luIGlzIGEgdG9rZW5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IGZhbHNlIGZvciBGTFIgKGJhc2UgY2hhaW4pXG4gICAqL1xuICBpc1Rva2VuKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeHBsYWlucyBhbiBhdG9taWMgdHJhbnNhY3Rpb24gdXNpbmcgYXRvbWljIGJ1aWxkZXIuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0eEhleCAtIHRoZSB0cmFuc2FjdGlvbiBoZXhcbiAgICogQHJldHVybnMge1Byb21pc2U8QXRvbWljVHJhbnNhY3Rpb25FeHBsYW5hdGlvbj59IHRoZSB0cmFuc2FjdGlvbiBleHBsYW5hdGlvblxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBleHBsYWluQXRvbWljVHJhbnNhY3Rpb24odHhIZXg6IHN0cmluZyk6IFByb21pc2U8QXRvbWljVHJhbnNhY3Rpb25FeHBsYW5hdGlvbj4ge1xuICAgIGNvbnN0IHR4QnVpbGRlciA9IHRoaXMuZ2V0QXRvbWljQnVpbGRlcigpLmZyb20odHhIZXgpO1xuICAgIGNvbnN0IHR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgcmV0dXJuIHR4LmV4cGxhaW5UcmFuc2FjdGlvbigpIGFzIEF0b21pY1RyYW5zYWN0aW9uRXhwbGFuYXRpb247XG4gIH1cblxuICAvKipcbiAgICogVmVyaWZ5IHNpZ25hdHVyZSBmb3IgYW4gYXRvbWljIHRyYW5zYWN0aW9uIHVzaW5nIGF0b21pYyBidWlsZGVyLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdHhIZXggLSB0aGUgdHJhbnNhY3Rpb24gaGV4XG4gICAqIEByZXR1cm5zIHtQcm9taXNlPGJvb2xlYW4+fSB0cnVlIGlmIHNpZ25hdHVyZSBpcyBmcm9tIHRoZSBpbnB1dCBhZGRyZXNzXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHZlcmlmeVNpZ25hdHVyZUZvckF0b21pY1RyYW5zYWN0aW9uKHR4SGV4OiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSB0aGlzLmdldEF0b21pY0J1aWxkZXIoKS5mcm9tKHR4SGV4KTtcbiAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgIGNvbnN0IHBheWxvYWQgPSB0eC5zaWduYWJsZVBheWxvYWQ7XG4gICAgY29uc3Qgc2lnbmF0dXJlcyA9IHR4LnNpZ25hdHVyZS5tYXAoKHMpID0+IEJ1ZmZlci5mcm9tKEZsclBMaWIuVXRpbHMucmVtb3ZlSGV4UHJlZml4KHMpLCAnaGV4JykpO1xuICAgIGNvbnN0IG5ldHdvcmsgPSBfLmdldCh0eCwgJ19uZXR3b3JrJyk7XG4gICAgY29uc3QgcmVjb3ZlclB1YmtleSA9IHNpZ25hdHVyZXMubWFwKChzKSA9PlxuICAgICAgRmxyUExpYi5VdGlscy5yZWNvdmVyeVNpZ25hdHVyZShuZXR3b3JrIGFzIHVua25vd24gYXMgRmxhcmVOZXR3b3JrLCBwYXlsb2FkLCBzKVxuICAgICk7XG4gICAgY29uc3QgZXhwZWN0ZWRTZW5kZXJzID0gcmVjb3ZlclB1YmtleS5tYXAoKHIpID0+IHB1YlRvQWRkcmVzcyhyLCB0cnVlKSk7XG4gICAgY29uc3Qgc2VuZGVycyA9IHR4LmlucHV0cy5tYXAoKGkpID0+IEZsclBMaWIuVXRpbHMucGFyc2VBZGRyZXNzKGkuYWRkcmVzcykpO1xuICAgIHJldHVybiBleHBlY3RlZFNlbmRlcnMuZXZlcnkoKGUpID0+IHNlbmRlcnMuc29tZSgoc2VuZGVyKSA9PiBlLmVxdWFscyhzZW5kZXIpKSk7XG4gIH1cblxuICAvKipcbiAgICogRXhwbGFpbiBhIHRyYW5zYWN0aW9uIGZyb20gdHhIZXgsIG92ZXJyaWRpbmcgQmFzZUNvaW5zXG4gICAqIHRyYW5zYWN0aW9uIGNhbiBiZSBlaXRoZXIgYXRvbWljIG9yIGV0aCB0eG4uXG4gICAqIEBwYXJhbSB7RXhwbGFpblRyYW5zYWN0aW9uT3B0aW9uc30gcGFyYW1zIFRoZSBvcHRpb25zIHdpdGggd2hpY2ggdG8gZXhwbGFpbiB0aGUgdHJhbnNhY3Rpb25cbiAgICogQHJldHVybnMge1Byb21pc2U8VHJhbnNhY3Rpb25FeHBsYW5hdGlvbj59IHRoZSB0cmFuc2FjdGlvbiBleHBsYW5hdGlvblxuICAgKi9cbiAgYXN5bmMgZXhwbGFpblRyYW5zYWN0aW9uKHBhcmFtczogRXhwbGFpblRyYW5zYWN0aW9uT3B0aW9ucyk6IFByb21pc2U8VHJhbnNhY3Rpb25FeHBsYW5hdGlvbj4ge1xuICAgIGNvbnN0IHR4SGV4ID0gcGFyYW1zLnR4SGV4IHx8IChwYXJhbXMuaGFsZlNpZ25lZCAmJiBwYXJhbXMuaGFsZlNpZ25lZC50eEhleCk7XG4gICAgaWYgKCF0eEhleCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHR4SGV4IGluIGV4cGxhaW4gdHggcGFyYW1ldGVycycpO1xuICAgIH1cbiAgICBpZiAocGFyYW1zLmNyb3NzQ2hhaW5UeXBlKSB7XG4gICAgICByZXR1cm4gdGhpcy5leHBsYWluQXRvbWljVHJhbnNhY3Rpb24odHhIZXgpO1xuICAgIH1cbiAgICBpZiAoIXBhcmFtcy5mZWVJbmZvKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgZmVlSW5mbyBpbiBleHBsYWluIHR4IHBhcmFtZXRlcnMnKTtcbiAgICB9XG4gICAgY29uc3QgdHhCdWlsZGVyID0gdGhpcy5nZXRUcmFuc2FjdGlvbkJ1aWxkZXIoKTtcbiAgICB0eEJ1aWxkZXIuZnJvbSh0eEhleCk7XG4gICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih0aGlzLmV4cGxhaW5FVk1UcmFuc2FjdGlvbih0eCksIHsgZmVlOiBwYXJhbXMuZmVlSW5mbyB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeHBsYWlucyBhbiBFVk0gdHJhbnNhY3Rpb24gdXNpbmcgcmVndWxhciBldGggdHhuIGJ1aWxkZXJcbiAgICogQHBhcmFtIHtCYXNlVHJhbnNhY3Rpb259IHR4IC0gdGhlIHRyYW5zYWN0aW9uIHRvIGV4cGxhaW5cbiAgICogQHJldHVybnMge09iamVjdH0gdGhlIHRyYW5zYWN0aW9uIGV4cGxhbmF0aW9uXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIGV4cGxhaW5FVk1UcmFuc2FjdGlvbih0eDogQmFzZVRyYW5zYWN0aW9uKSB7XG4gICAgY29uc3Qgb3V0cHV0cyA9IHR4Lm91dHB1dHMubWFwKChvdXRwdXQpID0+IHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGFkZHJlc3M6IG91dHB1dC5hZGRyZXNzLFxuICAgICAgICBhbW91bnQ6IG91dHB1dC52YWx1ZSxcbiAgICAgIH07XG4gICAgfSk7XG4gICAgY29uc3QgZGlzcGxheU9yZGVyID0gWydpZCcsICdvdXRwdXRBbW91bnQnLCAnY2hhbmdlQW1vdW50JywgJ291dHB1dHMnLCAnY2hhbmdlT3V0cHV0cycsICdmZWUnXTtcbiAgICByZXR1cm4ge1xuICAgICAgZGlzcGxheU9yZGVyLFxuICAgICAgaWQ6IHR4LmlkLFxuICAgICAgb3V0cHV0czogb3V0cHV0cyxcbiAgICAgIG91dHB1dEFtb3VudDogb3V0cHV0c1xuICAgICAgICAucmVkdWNlKChhY2N1bXVsYXRvciwgb3V0cHV0KSA9PiBhY2N1bXVsYXRvci5wbHVzKG91dHB1dC5hbW91bnQpLCBuZXcgQmlnTnVtYmVyKCcwJykpXG4gICAgICAgIC50b0ZpeGVkKDApLFxuICAgICAgY2hhbmdlT3V0cHV0czogW10sIC8vIGFjY291bnQgYmFzZWQgZG9lcyBub3QgdXNlIGNoYW5nZSBvdXRwdXRzXG4gICAgICBjaGFuZ2VBbW91bnQ6ICcwJywgLy8gYWNjb3VudCBiYXNlIGRvZXMgbm90IG1ha2UgY2hhbmdlXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWZXJpZnkgdGhhdCBhIHRyYW5zYWN0aW9uIHByZWJ1aWxkIGNvbXBsaWVzIHdpdGggdGhlIG9yaWdpbmFsIGludGVudGlvblxuICAgKlxuICAgKiBAcGFyYW0ge1ZlcmlmeUZsclRyYW5zYWN0aW9uT3B0aW9uc30gcGFyYW1zXG4gICAqIEBwYXJhbSBwYXJhbXMudHhQYXJhbXMgcGFyYW1zIG9iamVjdCBwYXNzZWQgdG8gc2VuZFxuICAgKiBAcGFyYW0gcGFyYW1zLnR4UHJlYnVpbGQgcHJlYnVpbGQgb2JqZWN0IHJldHVybmVkIGJ5IHNlcnZlclxuICAgKiBAcGFyYW0gcGFyYW1zLndhbGxldCBXYWxsZXQgb2JqZWN0IHRvIG9idGFpbiBrZXlzIHRvIHZlcmlmeSBhZ2FpbnN0XG4gICAqIEByZXR1cm5zIHtQcm9taXNlPGJvb2xlYW4+fVxuICAgKi9cbiAgYXN5bmMgdmVyaWZ5VHJhbnNhY3Rpb24ocGFyYW1zOiBWZXJpZnlGbHJUcmFuc2FjdGlvbk9wdGlvbnMpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCB7IHR4UGFyYW1zLCB0eFByZWJ1aWxkLCB3YWxsZXQsIHdhbGxldFR5cGUgfSA9IHBhcmFtcztcblxuICAgIC8vIEZvciBUU1Mgd2FsbGV0cywgdXNlIHRoZSBwYXJlbnQgY2xhc3MncyBUU1Mtc3BlY2lmaWMgdmVyaWZpY2F0aW9uXG4gICAgaWYgKHdhbGxldFR5cGUgPT09ICd0c3MnKSB7XG4gICAgICByZXR1cm4gc3VwZXIudmVyaWZ5VHJhbnNhY3Rpb24ocGFyYW1zKTtcbiAgICB9XG5cbiAgICBpZiAoIXR4UGFyYW1zPy5yZWNpcGllbnRzIHx8ICF0eFByZWJ1aWxkPy5yZWNpcGllbnRzIHx8ICF3YWxsZXQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgbWlzc2luZyBwYXJhbXNgKTtcbiAgICB9XG4gICAgaWYgKHR4UGFyYW1zLmhvcCAmJiB0eFBhcmFtcy5yZWNpcGllbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgdHggY2Fubm90IGJlIGJvdGggYSBiYXRjaCBhbmQgaG9wIHRyYW5zYWN0aW9uYCk7XG4gICAgfVxuICAgIGlmICh0eFByZWJ1aWxkLnJlY2lwaWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgJHt0aGlzLmdldENoYWluKCl9IGRvZXNuJ3Qgc3VwcG9ydCBzZW5kaW5nIHRvIG1vcmUgdGhhbiAxIGRlc3RpbmF0aW9uIGFkZHJlc3Mgd2l0aGluIGEgc2luZ2xlIHRyYW5zYWN0aW9uLiBUcnkgYWdhaW4sIHVzaW5nIG9ubHkgYSBzaW5nbGUgcmVjaXBpZW50LmBcbiAgICAgICk7XG4gICAgfVxuICAgIGlmICh0eFBhcmFtcy5ob3AgJiYgdHhQcmVidWlsZC5ob3BUcmFuc2FjdGlvbikge1xuICAgICAgLy8gQ2hlY2sgcmVjaXBpZW50IGFtb3VudCBmb3IgaG9wIHRyYW5zYWN0aW9uXG4gICAgICBpZiAodHhQYXJhbXMucmVjaXBpZW50cy5sZW5ndGggIT09IDEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBob3AgdHJhbnNhY3Rpb24gb25seSBzdXBwb3J0cyAxIHJlY2lwaWVudCBidXQgJHt0eFBhcmFtcy5yZWNpcGllbnRzLmxlbmd0aH0gZm91bmRgKTtcbiAgICAgIH1cbiAgICAgIC8vIENoZWNrIHR4IHNlbmRzIHRvIGhvcCBhZGRyZXNzXG4gICAgICBsZXQgZXhwZWN0ZWRIb3BBZGRyZXNzO1xuICAgICAgaWYgKHR4UHJlYnVpbGQuaG9wVHJhbnNhY3Rpb24udHlwZSA9PT0gJ0V4cG9ydCcpIHtcbiAgICAgICAgY29uc3QgZGVjb2RlZEhvcFR4ID0gYXdhaXQgdGhpcy5leHBsYWluQXRvbWljVHJhbnNhY3Rpb24odHhQcmVidWlsZC5ob3BUcmFuc2FjdGlvbi50eCk7XG4gICAgICAgIGV4cGVjdGVkSG9wQWRkcmVzcyA9IG9wdGlvbmFsRGVwcy5ldGhVdGlsLnN0cmlwSGV4UHJlZml4KGRlY29kZWRIb3BUeC5pbnB1dHNbMF0uYWRkcmVzcyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBkZWNvZGVkSG9wVHggPSBvcHRpb25hbERlcHMuRXRoVHguVHJhbnNhY3Rpb25GYWN0b3J5LmZyb21TZXJpYWxpemVkRGF0YShcbiAgICAgICAgICBvcHRpb25hbERlcHMuZXRoVXRpbC50b0J1ZmZlcih0eFByZWJ1aWxkLmhvcFRyYW5zYWN0aW9uLnR4KVxuICAgICAgICApO1xuICAgICAgICBleHBlY3RlZEhvcEFkZHJlc3MgPSBvcHRpb25hbERlcHMuZXRoVXRpbC5zdHJpcEhleFByZWZpeChkZWNvZGVkSG9wVHguZ2V0U2VuZGVyQWRkcmVzcygpLnRvU3RyaW5nKCkpO1xuICAgICAgfVxuICAgICAgY29uc3QgYWN0dWFsSG9wQWRkcmVzcyA9IG9wdGlvbmFsRGVwcy5ldGhVdGlsLnN0cmlwSGV4UHJlZml4KHR4UHJlYnVpbGQucmVjaXBpZW50c1swXS5hZGRyZXNzKTtcbiAgICAgIGlmIChleHBlY3RlZEhvcEFkZHJlc3MudG9Mb3dlckNhc2UoKSAhPT0gYWN0dWFsSG9wQWRkcmVzcy50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigncmVjaXBpZW50IGFkZHJlc3Mgb2YgdHhQcmVidWlsZCBkb2VzIG5vdCBtYXRjaCBob3AgYWRkcmVzcycpO1xuICAgICAgfVxuXG4gICAgICAvLyBDb252ZXJ0IFRyYW5zYWN0aW9uUmVjaXBpZW50IGFycmF5IHRvIFJlY2lwaWVudCBhcnJheVxuICAgICAgY29uc3QgcmVjaXBpZW50czogUmVjaXBpZW50W10gPSB0eFBhcmFtcy5yZWNpcGllbnRzLm1hcCgocikgPT4ge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGFkZHJlc3M6IHIuYWRkcmVzcyxcbiAgICAgICAgICBhbW91bnQ6IHR5cGVvZiByLmFtb3VudCA9PT0gJ251bWJlcicgPyByLmFtb3VudC50b1N0cmluZygpIDogci5hbW91bnQsXG4gICAgICAgIH07XG4gICAgICB9KTtcblxuICAgICAgLy8gQ2hlY2sgZGVzdGluYXRpb24gYWRkcmVzcyBhbmQgYW1vdW50XG4gICAgICBhd2FpdCB0aGlzLnZhbGlkYXRlSG9wUHJlYnVpbGQod2FsbGV0LCB0eFByZWJ1aWxkLmhvcFRyYW5zYWN0aW9uLCB7IHJlY2lwaWVudHMgfSk7XG4gICAgfSBlbHNlIGlmICh0eFBhcmFtcy5yZWNpcGllbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgIC8vIENoZWNrIHRvdGFsIGFtb3VudCBmb3IgYmF0Y2ggdHJhbnNhY3Rpb25cbiAgICAgIGxldCBleHBlY3RlZFRvdGFsQW1vdW50ID0gbmV3IEJpZ051bWJlcigwKTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdHhQYXJhbXMucmVjaXBpZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICBleHBlY3RlZFRvdGFsQW1vdW50ID0gZXhwZWN0ZWRUb3RhbEFtb3VudC5wbHVzKHR4UGFyYW1zLnJlY2lwaWVudHNbaV0uYW1vdW50KTtcbiAgICAgIH1cbiAgICAgIGlmICghZXhwZWN0ZWRUb3RhbEFtb3VudC5pc0VxdWFsVG8odHhQcmVidWlsZC5yZWNpcGllbnRzWzBdLmFtb3VudCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICdiYXRjaCB0cmFuc2FjdGlvbiBhbW91bnQgaW4gdHhQcmVidWlsZCByZWNlaXZlZCBmcm9tIEJpdEdvIHNlcnZlcnMgZG9lcyBub3QgbWF0Y2ggdHhQYXJhbXMgc3VwcGxpZWQgYnkgY2xpZW50J1xuICAgICAgICApO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBDaGVjayByZWNpcGllbnQgYWRkcmVzcyBhbmQgYW1vdW50IGZvciBub3JtYWwgdHJhbnNhY3Rpb25cbiAgICAgIGlmICh0eFBhcmFtcy5yZWNpcGllbnRzLmxlbmd0aCAhPT0gMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYG5vcm1hbCB0cmFuc2FjdGlvbiBvbmx5IHN1cHBvcnRzIDEgcmVjaXBpZW50IGJ1dCAke3R4UGFyYW1zLnJlY2lwaWVudHMubGVuZ3RofSBmb3VuZGApO1xuICAgICAgfVxuICAgICAgY29uc3QgZXhwZWN0ZWRBbW91bnQgPSBuZXcgQmlnTnVtYmVyKHR4UGFyYW1zLnJlY2lwaWVudHNbMF0uYW1vdW50KTtcbiAgICAgIGlmICghZXhwZWN0ZWRBbW91bnQuaXNFcXVhbFRvKHR4UHJlYnVpbGQucmVjaXBpZW50c1swXS5hbW91bnQpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAnbm9ybWFsIHRyYW5zYWN0aW9uIGFtb3VudCBpbiB0eFByZWJ1aWxkIHJlY2VpdmVkIGZyb20gQml0R28gc2VydmVycyBkb2VzIG5vdCBtYXRjaCB0eFBhcmFtcyBzdXBwbGllZCBieSBjbGllbnQnXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZiAoXG4gICAgICAgIEZsci5pc0ZMUkFkZHJlc3ModHhQYXJhbXMucmVjaXBpZW50c1swXS5hZGRyZXNzKSAmJlxuICAgICAgICB0eFBhcmFtcy5yZWNpcGllbnRzWzBdLmFkZHJlc3MgIT09IHR4UHJlYnVpbGQucmVjaXBpZW50c1swXS5hZGRyZXNzXG4gICAgICApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdkZXN0aW5hdGlvbiBhZGRyZXNzIGluIG5vcm1hbCB0eFByZWJ1aWxkIGRvZXMgbm90IG1hdGNoIHRoYXQgaW4gdHhQYXJhbXMgc3VwcGxpZWQgYnkgY2xpZW50Jyk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIENoZWNrIGNvaW4gaXMgY29ycmVjdCBmb3IgYWxsIHRyYW5zYWN0aW9uIHR5cGVzXG4gICAgaWYgKCF0aGlzLnZlcmlmeUNvaW4odHhQcmVidWlsZCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgY29pbiBpbiB0eFByZWJ1aWxkIGRpZCBub3QgbWF0Y2ggdGhhdCBpbiB0eFBhcmFtcyBzdXBwbGllZCBieSBjbGllbnRgKTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgYW4gYWRkcmVzcyBpcyBhIEZMUiBDLWNoYWluIGFkZHJlc3MgKDB4IGZvcm1hdClcbiAgICogQHBhcmFtIHtzdHJpbmd9IGFkZHJlc3MgLSB0aGUgYWRkcmVzcyB0byBjaGVja1xuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gdHJ1ZSBpZiBpdCdzIGEgQy1jaGFpbiBhZGRyZXNzXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBpc0ZMUkFkZHJlc3MoYWRkcmVzczogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICEhYWRkcmVzcy5tYXRjaCgvMHhbYS1mQS1GMC05XXs0MH0vKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWZXJpZnkgdGhhdCB0aGUgY29pbiBtYXRjaGVzIGluIHRoZSBwcmVidWlsZFxuICAgKiBAcGFyYW0ge1RyYW5zYWN0aW9uUHJlYnVpbGR9IHR4UHJlYnVpbGQgLSB0aGUgdHJhbnNhY3Rpb24gcHJlYnVpbGRcbiAgICogQHJldHVybnMge2Jvb2xlYW59IHRydWUgaWYgY29pbiBtYXRjaGVzXG4gICAqL1xuICB2ZXJpZnlDb2luKHR4UHJlYnVpbGQ6IFRyYW5zYWN0aW9uUHJlYnVpbGQpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdHhQcmVidWlsZC5jb2luID09PSB0aGlzLmdldENoYWluKCk7XG4gIH1cblxuICAvKipcbiAgICogQ29pbi1zcGVjaWZpYyB0aGluZ3MgZG9uZSBiZWZvcmUgc2lnbmluZyBhIHRyYW5zYWN0aW9uLCBpLmUuIHZlcmlmaWNhdGlvblxuICAgKiBAcGFyYW0ge1ByZXNpZ25UcmFuc2FjdGlvbk9wdGlvbnN9IHBhcmFtcyAtIHRoZSBwcmVzaWduIG9wdGlvbnNcbiAgICogQHJldHVybnMge1Byb21pc2U8UHJlc2lnblRyYW5zYWN0aW9uT3B0aW9ucz59XG4gICAqL1xuICBhc3luYyBwcmVzaWduVHJhbnNhY3Rpb24ocGFyYW1zOiBQcmVzaWduVHJhbnNhY3Rpb25PcHRpb25zKTogUHJvbWlzZTxQcmVzaWduVHJhbnNhY3Rpb25PcHRpb25zPiB7XG4gICAgaWYgKCFfLmlzVW5kZWZpbmVkKHBhcmFtcy5ob3BUcmFuc2FjdGlvbikgJiYgIV8uaXNVbmRlZmluZWQocGFyYW1zLndhbGxldCkgJiYgIV8uaXNVbmRlZmluZWQocGFyYW1zLmJ1aWxkUGFyYW1zKSkge1xuICAgICAgYXdhaXQgdGhpcy52YWxpZGF0ZUhvcFByZWJ1aWxkKHBhcmFtcy53YWxsZXQsIHBhcmFtcy5ob3BUcmFuc2FjdGlvbik7XG4gICAgfVxuICAgIHJldHVybiBwYXJhbXM7XG4gIH1cblxuICAvKipcbiAgICogTW9kaWZ5IHByZWJ1aWxkIGFmdGVyIHJlY2VpdmluZyBpdCBmcm9tIHRoZSBzZXJ2ZXIuIEFkZCB0aGluZ3MgbGlrZSBubG9ja3RpbWVcbiAgICogQHBhcmFtIHtUcmFuc2FjdGlvblByZWJ1aWxkfSBwYXJhbXMgLSB0aGUgdHJhbnNhY3Rpb24gcHJlYnVpbGRcbiAgICogQHJldHVybnMge1Byb21pc2U8VHJhbnNhY3Rpb25QcmVidWlsZD59XG4gICAqL1xuICBhc3luYyBwb3N0UHJvY2Vzc1ByZWJ1aWxkKHBhcmFtczogVHJhbnNhY3Rpb25QcmVidWlsZCk6IFByb21pc2U8VHJhbnNhY3Rpb25QcmVidWlsZD4ge1xuICAgIGlmICghXy5pc1VuZGVmaW5lZChwYXJhbXMuaG9wVHJhbnNhY3Rpb24pICYmICFfLmlzVW5kZWZpbmVkKHBhcmFtcy53YWxsZXQpICYmICFfLmlzVW5kZWZpbmVkKHBhcmFtcy5idWlsZFBhcmFtcykpIHtcbiAgICAgIGF3YWl0IHRoaXMudmFsaWRhdGVIb3BQcmVidWlsZChwYXJhbXMud2FsbGV0LCBwYXJhbXMuaG9wVHJhbnNhY3Rpb24sIHBhcmFtcy5idWlsZFBhcmFtcyk7XG4gICAgfVxuICAgIHJldHVybiBwYXJhbXM7XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGVzIHRoYXQgdGhlIGhvcCBwcmVidWlsZCBmcm9tIHRoZSBIU00gaXMgdmFsaWQgYW5kIGNvcnJlY3RcbiAgICogQHBhcmFtIHtJV2FsbGV0fSB3YWxsZXQgVGhlIHdhbGxldCB0aGF0IHRoZSBwcmVidWlsZCBpcyBmb3JcbiAgICogQHBhcmFtIHtIb3BQcmVidWlsZH0gaG9wUHJlYnVpbGQgVGhlIHByZWJ1aWxkIHRvIHZhbGlkYXRlXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcmlnaW5hbFBhcmFtcyBUaGUgb3JpZ2luYWwgcGFyYW1ldGVycyBwYXNzZWQgdG8gcHJlYnVpbGRUcmFuc2FjdGlvblxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICogQHRocm93cyBFcnJvciBpZiBUaGUgcHJlYnVpbGQgaXMgaW52YWxpZFxuICAgKi9cbiAgYXN5bmMgdmFsaWRhdGVIb3BQcmVidWlsZChcbiAgICB3YWxsZXQ6IElXYWxsZXQsXG4gICAgaG9wUHJlYnVpbGQ6IEhvcFByZWJ1aWxkLFxuICAgIG9yaWdpbmFsUGFyYW1zPzogeyByZWNpcGllbnRzOiBSZWNpcGllbnRbXSB9XG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHsgdHgsIGlkLCBzaWduYXR1cmUgfSA9IGhvcFByZWJ1aWxkO1xuXG4gICAgLy8gZmlyc3QsIHZhbGlkYXRlIHRoZSBIU00gc2lnbmF0dXJlXG4gICAgY29uc3Qgc2VydmVyWHB1YiA9IGNvbW1vbi5FbnZpcm9ubWVudHNbdGhpcy5iaXRnby5nZXRFbnYoKV0uaHNtWHB1YjtcbiAgICBjb25zdCBzZXJ2ZXJQdWJrZXlCdWZmZXI6IEJ1ZmZlciA9IGJpcDMyLmZyb21CYXNlNTgoc2VydmVyWHB1YikucHVibGljS2V5O1xuICAgIGNvbnN0IHNpZ25hdHVyZUJ1ZmZlcjogQnVmZmVyID0gQnVmZmVyLmZyb20ob3B0aW9uYWxEZXBzLmV0aFV0aWwuc3RyaXBIZXhQcmVmaXgoc2lnbmF0dXJlKSwgJ2hleCcpO1xuICAgIGNvbnN0IG1lc3NhZ2VCdWZmZXI6IEJ1ZmZlciA9XG4gICAgICBob3BQcmVidWlsZC50eXBlID09PSAnRXhwb3J0JyA/IEZsci5nZXRUeEhhc2godHgpIDogQnVmZmVyLmZyb20ob3B0aW9uYWxEZXBzLmV0aFV0aWwuc3RyaXBIZXhQcmVmaXgoaWQpLCAnaGV4Jyk7XG5cbiAgICBjb25zdCBzaWcgPSBuZXcgVWludDhBcnJheShzaWduYXR1cmVCdWZmZXIubGVuZ3RoID09PSA2NCA/IHNpZ25hdHVyZUJ1ZmZlciA6IHNpZ25hdHVyZUJ1ZmZlci5zbGljZSgxKSk7XG4gICAgY29uc3QgaXNWYWxpZFNpZ25hdHVyZTogYm9vbGVhbiA9IHNlY3AyNTZrMS5lY2RzYVZlcmlmeShzaWcsIG1lc3NhZ2VCdWZmZXIsIHNlcnZlclB1YmtleUJ1ZmZlcik7XG4gICAgaWYgKCFpc1ZhbGlkU2lnbmF0dXJlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEhvcCB0eGlkIHNpZ25hdHVyZSBpbnZhbGlkYCk7XG4gICAgfVxuXG4gICAgaWYgKGhvcFByZWJ1aWxkLnR5cGUgPT09ICdFeHBvcnQnKSB7XG4gICAgICBjb25zdCBleHBsYWluSG9wRXhwb3J0VHggPSBhd2FpdCB0aGlzLmV4cGxhaW5BdG9taWNUcmFuc2FjdGlvbih0eCk7XG4gICAgICAvLyBJZiBvcmlnaW5hbCBwYXJhbXMgYXJlIGdpdmVuLCB3ZSBjYW4gY2hlY2sgdGhlbSBhZ2FpbnN0IHRoZSB0cmFuc2FjdGlvbiBwcmVidWlsZCBwYXJhbXNcbiAgICAgIGlmICghXy5pc05pbChvcmlnaW5hbFBhcmFtcykpIHtcbiAgICAgICAgY29uc3QgeyByZWNpcGllbnRzIH0gPSBvcmlnaW5hbFBhcmFtcztcblxuICAgICAgICAvLyBUaGVuIHZhbGlkYXRlIHRoYXQgdGhlIHR4IHBhcmFtcyBhY3R1YWxseSBlcXVhbCB0aGUgcmVxdWVzdGVkIHBhcmFtcyB0byBuYW5vIGZsciBwbHVzIGltcG9ydCB0eCBmZWUuXG4gICAgICAgIGNvbnN0IG9yaWdpbmFsQW1vdW50ID0gbmV3IEJpZ051bWJlcihyZWNpcGllbnRzWzBdLmFtb3VudCkuZGl2KDFlOSkucGx1cygxZTYpLnRvRml4ZWQoMCk7XG4gICAgICAgIGNvbnN0IG9yaWdpbmFsRGVzdGluYXRpb246IHN0cmluZyB8IHVuZGVmaW5lZCA9IHJlY2lwaWVudHNbMF0uYWRkcmVzcztcbiAgICAgICAgY29uc3QgaG9wQW1vdW50ID0gZXhwbGFpbkhvcEV4cG9ydFR4Lm91dHB1dEFtb3VudDtcbiAgICAgICAgY29uc3QgaG9wRGVzdGluYXRpb24gPSBleHBsYWluSG9wRXhwb3J0VHgub3V0cHV0c1swXS5hZGRyZXNzO1xuICAgICAgICBpZiAob3JpZ2luYWxBbW91bnQgIT09IGhvcEFtb3VudCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSG9wIGFtb3VudDogJHtob3BBbW91bnR9IGRvZXMgbm90IGVxdWFsIG9yaWdpbmFsIGFtb3VudDogJHtvcmlnaW5hbEFtb3VudH1gKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAob3JpZ2luYWxEZXN0aW5hdGlvbiAmJiBob3BEZXN0aW5hdGlvbi50b0xvd2VyQ2FzZSgpICE9PSBvcmlnaW5hbERlc3RpbmF0aW9uLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICBgSG9wIGRlc3RpbmF0aW9uOiAke2hvcERlc3RpbmF0aW9ufSBkb2VzIG5vdCBlcXVhbCBvcmlnaW5hbCByZWNpcGllbnQ6ICR7b3JpZ2luYWxEZXN0aW5hdGlvbn1gXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKCEoYXdhaXQgdGhpcy52ZXJpZnlTaWduYXR1cmVGb3JBdG9taWNUcmFuc2FjdGlvbih0eCkpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBob3AgdHJhbnNhY3Rpb24gc2lnbmF0dXJlLCB0eGlkOiAke2lkfWApO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBidWlsdEhvcFR4ID0gb3B0aW9uYWxEZXBzLkV0aFR4LlRyYW5zYWN0aW9uRmFjdG9yeS5mcm9tU2VyaWFsaXplZERhdGEob3B0aW9uYWxEZXBzLmV0aFV0aWwudG9CdWZmZXIodHgpKTtcbiAgICAgIC8vIElmIG9yaWdpbmFsIHBhcmFtcyBhcmUgZ2l2ZW4sIHdlIGNhbiBjaGVjayB0aGVtIGFnYWluc3QgdGhlIHRyYW5zYWN0aW9uIHByZWJ1aWxkIHBhcmFtc1xuICAgICAgaWYgKCFfLmlzTmlsKG9yaWdpbmFsUGFyYW1zKSkge1xuICAgICAgICBjb25zdCB7IHJlY2lwaWVudHMgfSA9IG9yaWdpbmFsUGFyYW1zO1xuXG4gICAgICAgIC8vIFRoZW4gdmFsaWRhdGUgdGhhdCB0aGUgdHggcGFyYW1zIGFjdHVhbGx5IGVxdWFsIHRoZSByZXF1ZXN0ZWQgcGFyYW1zXG4gICAgICAgIGNvbnN0IG9yaWdpbmFsQW1vdW50ID0gbmV3IEJpZ051bWJlcihyZWNpcGllbnRzWzBdLmFtb3VudCk7XG4gICAgICAgIGNvbnN0IG9yaWdpbmFsRGVzdGluYXRpb246IHN0cmluZyA9IHJlY2lwaWVudHNbMF0uYWRkcmVzcztcblxuICAgICAgICBjb25zdCBob3BBbW91bnQgPSBuZXcgQmlnTnVtYmVyKG9wdGlvbmFsRGVwcy5ldGhVdGlsLmJ1ZmZlclRvSGV4KGJ1aWx0SG9wVHgudmFsdWUgYXMgdW5rbm93biBhcyBCdWZmZXIpKTtcbiAgICAgICAgaWYgKCFidWlsdEhvcFR4LnRvKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBUcmFuc2FjdGlvbiBkb2VzIG5vdCBoYXZlIGEgZGVzdGluYXRpb24gYWRkcmVzc2ApO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGhvcERlc3RpbmF0aW9uID0gYnVpbHRIb3BUeC50by50b1N0cmluZygpO1xuICAgICAgICBpZiAoIWhvcEFtb3VudC5lcShvcmlnaW5hbEFtb3VudCkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEhvcCBhbW91bnQ6ICR7aG9wQW1vdW50fSBkb2VzIG5vdCBlcXVhbCBvcmlnaW5hbCBhbW91bnQ6ICR7b3JpZ2luYWxBbW91bnR9YCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGhvcERlc3RpbmF0aW9uLnRvTG93ZXJDYXNlKCkgIT09IG9yaWdpbmFsRGVzdGluYXRpb24udG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgIGBIb3AgZGVzdGluYXRpb246ICR7aG9wRGVzdGluYXRpb259IGRvZXMgbm90IGVxdWFsIG9yaWdpbmFsIHJlY2lwaWVudDogJHtvcmlnaW5hbERlc3RpbmF0aW9ufWBcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICghYnVpbHRIb3BUeC52ZXJpZnlTaWduYXR1cmUoKSkge1xuICAgICAgICAvLyBXZSBkb24ndCB3YW50IHRvIGNvbnRpbnVlIGF0IGFsbCBpbiB0aGlzIGNhc2UsIGF0IHJpc2sgb2YgRkxSIGJlaW5nIHN0dWNrIG9uIHRoZSBob3AgYWRkcmVzc1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgaG9wIHRyYW5zYWN0aW9uIHNpZ25hdHVyZSwgdHhpZDogJHtpZH1gKTtcbiAgICAgIH1cbiAgICAgIGlmIChvcHRpb25hbERlcHMuZXRoVXRpbC5hZGRIZXhQcmVmaXgoYnVpbHRIb3BUeC5oYXNoKCkudG9TdHJpbmcoJ2hleCcpKSAhPT0gaWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBTaWduZWQgaG9wIHR4aWQgZG9lcyBub3QgZXF1YWwgYWN0dWFsIHR4aWRgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTW9kaWZ5IHByZWJ1aWxkIGJlZm9yZSBzZW5kaW5nIGl0IHRvIHRoZSBzZXJ2ZXIuIEFkZCB0aGluZ3MgbGlrZSBob3AgdHJhbnNhY3Rpb24gcGFyYW1zXG4gICAqIEBwYXJhbSB7QnVpbGRPcHRpb25zfSBidWlsZFBhcmFtcyBUaGUgd2hpdGVsaXN0ZWQgcGFyYW1ldGVycyBmb3IgdGhpcyBwcmVidWlsZFxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IGJ1aWxkUGFyYW1zLmhvcCBUcnVlIGlmIHRoaXMgc2hvdWxkIHByZWJ1aWxkIGEgaG9wIHR4LCBlbHNlIGZhbHNlXG4gICAqIEBwYXJhbSB7UmVjaXBpZW50W119IGJ1aWxkUGFyYW1zLnJlY2lwaWVudHMgVGhlIHJlY2lwaWVudHMgYXJyYXkgb2YgdGhpcyB0cmFuc2FjdGlvblxuICAgKiBAcGFyYW0ge1dhbGxldH0gYnVpbGRQYXJhbXMud2FsbGV0IFRoZSB3YWxsZXQgc2VuZGluZyB0aGlzIHR4XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBidWlsZFBhcmFtcy53YWxsZXRQYXNzcGhyYXNlIHRoZSBwYXNzcGhyYXNlIGZvciB0aGlzIHdhbGxldFxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxCdWlsZE9wdGlvbnM+fVxuICAgKi9cbiAgYXN5bmMgZ2V0RXh0cmFQcmVidWlsZFBhcmFtcyhidWlsZFBhcmFtczogQnVpbGRPcHRpb25zKTogUHJvbWlzZTxCdWlsZE9wdGlvbnM+IHtcbiAgICBpZiAoXG4gICAgICAhXy5pc1VuZGVmaW5lZChidWlsZFBhcmFtcy5ob3ApICYmXG4gICAgICBidWlsZFBhcmFtcy5ob3AgJiZcbiAgICAgICFfLmlzVW5kZWZpbmVkKGJ1aWxkUGFyYW1zLndhbGxldCkgJiZcbiAgICAgICFfLmlzVW5kZWZpbmVkKGJ1aWxkUGFyYW1zLnJlY2lwaWVudHMpXG4gICAgKSB7XG4gICAgICBpZiAodGhpcy5pc1Rva2VuKCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIGBIb3AgdHJhbnNhY3Rpb25zIGFyZSBub3QgZW5hYmxlZCBmb3IgRkxSIHRva2Vucywgbm9yIGFyZSB0aGV5IG5lY2Vzc2FyeS4gUGxlYXNlIHJlbW92ZSB0aGUgJ2hvcCcgcGFyYW1ldGVyIGFuZCB0cnkgYWdhaW4uYFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIChhd2FpdCB0aGlzLmNyZWF0ZUhvcFRyYW5zYWN0aW9uUGFyYW1zKHtcbiAgICAgICAgcmVjaXBpZW50czogYnVpbGRQYXJhbXMucmVjaXBpZW50cyxcbiAgICAgICAgdHlwZTogYnVpbGRQYXJhbXMudHlwZSBhcyBIb3BUcmFuc2FjdGlvbkJ1aWxkT3B0aW9uc1sndHlwZSddLFxuICAgICAgfSkpIGFzIHVua25vd24gYXMgQnVpbGRPcHRpb25zO1xuICAgIH1cbiAgICByZXR1cm4ge307XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyB0aGUgZXh0cmEgcGFyYW1ldGVycyBuZWVkZWQgdG8gYnVpbGQgYSBob3AgdHJhbnNhY3Rpb25cbiAgICogQHBhcmFtIHtIb3BUcmFuc2FjdGlvbkJ1aWxkT3B0aW9uc30gcGFyYW1zIFRoZSBvcmlnaW5hbCBidWlsZCBwYXJhbWV0ZXJzXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPEhvcFBhcmFtcz59IGV4dHJhIHBhcmFtZXRlcnMgb2JqZWN0IHRvIG1lcmdlIHdpdGggdGhlIG9yaWdpbmFsIGJ1aWxkIHBhcmFtZXRlcnMgb2JqZWN0IGFuZCBzZW5kIHRvIHRoZSBwbGF0Zm9ybVxuICAgKi9cbiAgYXN5bmMgY3JlYXRlSG9wVHJhbnNhY3Rpb25QYXJhbXMoeyByZWNpcGllbnRzLCB0eXBlIH06IEhvcFRyYW5zYWN0aW9uQnVpbGRPcHRpb25zKTogUHJvbWlzZTxIb3BQYXJhbXM+IHtcbiAgICBpZiAoIXJlY2lwaWVudHMgfHwgIUFycmF5LmlzQXJyYXkocmVjaXBpZW50cykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZXhwZWN0aW5nIGFycmF5IG9mIHJlY2lwaWVudHMnKTtcbiAgICB9XG5cbiAgICAvLyBSaWdodCBub3cgd2Ugb25seSBzdXBwb3J0IDEgcmVjaXBpZW50XG4gICAgaWYgKHJlY2lwaWVudHMubGVuZ3RoICE9PSAxKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ211c3Qgc2VuZCB0byBleGFjdGx5IDEgcmVjaXBpZW50Jyk7XG4gICAgfVxuICAgIGNvbnN0IHJlY2lwaWVudEFkZHJlc3MgPSByZWNpcGllbnRzWzBdLmFkZHJlc3M7XG4gICAgY29uc3QgcmVjaXBpZW50QW1vdW50ID0gcmVjaXBpZW50c1swXS5hbW91bnQ7XG4gICAgY29uc3QgZmVlRXN0aW1hdGVQYXJhbXMgPSB7XG4gICAgICByZWNpcGllbnQ6IHJlY2lwaWVudEFkZHJlc3MsXG4gICAgICBhbW91bnQ6IHJlY2lwaWVudEFtb3VudCxcbiAgICAgIGhvcDogdHJ1ZSxcbiAgICAgIHR5cGUsXG4gICAgfTtcbiAgICBjb25zdCBmZWVFc3RpbWF0ZTogRmVlRXN0aW1hdGUgPSBhd2FpdCB0aGlzLmZlZUVzdGltYXRlKGZlZUVzdGltYXRlUGFyYW1zKTtcblxuICAgIGNvbnN0IGdhc0xpbWl0ID0gZmVlRXN0aW1hdGUuZ2FzTGltaXRFc3RpbWF0ZTtcbiAgICAvLyBFdmVuIGlmIGBmZWVFc3RpbWF0ZSA8IGdhc0xpbWl0YCwgd2Ugc2hvdWxkbid0IGVuZCB1cCB3aXRoIGBnYXNQcmljZSA9PT0gMGAuXG4gICAgY29uc3QgZ2FzUHJpY2UgPSBNYXRoLm1heChNYXRoLnJvdW5kKGZlZUVzdGltYXRlLmZlZUVzdGltYXRlIC8gZ2FzTGltaXQpLCAxKTtcbiAgICBjb25zdCBnYXNQcmljZU1heCA9IGdhc1ByaWNlICogNTtcbiAgICAvLyBQYXltZW50IGlkIGlzIGEgcmFuZG9tIG51bWJlciBzbyBpdHMgZGlmZmVyZW50IGZvciBldmVyeSB0eFxuICAgIGNvbnN0IHBheW1lbnRJZCA9IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIDEwMDAwMDAwMDAwKS50b1N0cmluZygpO1xuXG4gICAgY29uc3QgdXNlclJlcVNpZyA9ICcweCc7XG5cbiAgICByZXR1cm4ge1xuICAgICAgaG9wUGFyYW1zOiB7XG4gICAgICAgIHVzZXJSZXFTaWcsXG4gICAgICAgIGdhc1ByaWNlTWF4LFxuICAgICAgICBwYXltZW50SWQsXG4gICAgICAgIGdhc0xpbWl0LFxuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEZldGNoIGZlZSBlc3RpbWF0ZSBpbmZvcm1hdGlvbiBmcm9tIHRoZSBzZXJ2ZXJcbiAgICogQHBhcmFtIHtGZWVFc3RpbWF0ZU9wdGlvbnN9IHBhcmFtcyBUaGUgcGFyYW1zIHBhc3NlZCBpbnRvIHRoZSBmdW5jdGlvblxuICAgKiBAcGFyYW0ge0Jvb2xlYW59IFtwYXJhbXMuaG9wXSBUcnVlIGlmIHdlIHNob3VsZCBlc3RpbWF0ZSBmZWUgZm9yIGEgaG9wIHRyYW5zYWN0aW9uXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbcGFyYW1zLnJlY2lwaWVudF0gVGhlIHJlY2lwaWVudCBvZiB0aGUgdHJhbnNhY3Rpb24gdG8gZXN0aW1hdGUgYSBzZW5kIHRvXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbcGFyYW1zLmRhdGFdIFRoZSBkYXRhIHRvIGVzdGltYXRlIGEgc2VuZCBmb3JcbiAgICogQHJldHVybnMge1Byb21pc2U8RmVlRXN0aW1hdGU+fSBUaGUgZmVlIGluZm8gcmV0dXJuZWQgZnJvbSB0aGUgc2VydmVyXG4gICAqL1xuICBhc3luYyBmZWVFc3RpbWF0ZShwYXJhbXM6IEZlZUVzdGltYXRlT3B0aW9ucyk6IFByb21pc2U8RmVlRXN0aW1hdGU+IHtcbiAgICBjb25zdCBxdWVyeTogRmVlRXN0aW1hdGVPcHRpb25zID0ge307XG4gICAgaWYgKHBhcmFtcyAmJiBwYXJhbXMuaG9wKSB7XG4gICAgICBxdWVyeS5ob3AgPSBwYXJhbXMuaG9wO1xuICAgIH1cbiAgICBpZiAocGFyYW1zICYmIHBhcmFtcy5yZWNpcGllbnQpIHtcbiAgICAgIHF1ZXJ5LnJlY2lwaWVudCA9IHBhcmFtcy5yZWNpcGllbnQ7XG4gICAgfVxuICAgIGlmIChwYXJhbXMgJiYgcGFyYW1zLmRhdGEpIHtcbiAgICAgIHF1ZXJ5LmRhdGEgPSBwYXJhbXMuZGF0YTtcbiAgICB9XG4gICAgaWYgKHBhcmFtcyAmJiBwYXJhbXMuYW1vdW50KSB7XG4gICAgICBxdWVyeS5hbW91bnQgPSBwYXJhbXMuYW1vdW50O1xuICAgIH1cbiAgICBpZiAocGFyYW1zICYmIHBhcmFtcy50eXBlKSB7XG4gICAgICBxdWVyeS50eXBlID0gcGFyYW1zLnR5cGU7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuYml0Z28uZ2V0KHRoaXMudXJsKCcvdHgvZmVlJykpLnF1ZXJ5KHF1ZXJ5KS5yZXN1bHQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxjdWxhdGUgdHggaGFzaCBsaWtlIGV2bSBmcm9tIHR4IGhleC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHR4IC0gdGhlIHRyYW5zYWN0aW9uIGhleFxuICAgKiBAcmV0dXJucyB7QnVmZmVyfSB0eCBoYXNoXG4gICAqL1xuICBzdGF0aWMgZ2V0VHhIYXNoKHR4OiBzdHJpbmcpOiBCdWZmZXIge1xuICAgIGNvbnN0IGhhc2ggPSBLZWNjYWsoJ2tlY2NhazI1NicpO1xuICAgIGhhc2gudXBkYXRlKG9wdGlvbmFsRGVwcy5ldGhVdGlsLnN0cmlwSGV4UHJlZml4KHR4KSwgJ2hleCcpO1xuICAgIHJldHVybiBoYXNoLmRpZ2VzdCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ha2UgYSBxdWVyeSB0byBGbGFyZSBleHBsb3JlciBmb3IgaW5mb3JtYXRpb24gc3VjaCBhcyBiYWxhbmNlLCB0b2tlbiBiYWxhbmNlLCBzb2xpZGl0eSBjYWxsc1xuICAgKiBAcGFyYW0ge09iamVjdH0gcXVlcnkga2V5LXZhbHVlIHBhaXJzIG9mIHBhcmFtZXRlcnMgdG8gYXBwZW5kIGFmdGVyIC9hcGlcbiAgICogQHBhcmFtIHtzdHJpbmd9IGFwaUtleSBvcHRpb25hbCBBUEkga2V5IHRvIHVzZSBpbnN0ZWFkIG9mIHRoZSBvbmUgZnJvbSB0aGUgZW52aXJvbm1lbnRcbiAgICogQHJldHVybnMge1Byb21pc2U8T2JqZWN0Pn0gcmVzcG9uc2UgZnJvbSBGbGFyZSBleHBsb3JlclxuICAgKi9cbiAgYXN5bmMgcmVjb3ZlcnlCbG9ja2NoYWluRXhwbG9yZXJRdWVyeShcbiAgICBxdWVyeTogUmVjb3JkPHN0cmluZywgc3RyaW5nPixcbiAgICBhcGlLZXk/OiBzdHJpbmdcbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4ge1xuICAgIGNvbnN0IGFwaVRva2VuID0gYXBpS2V5IHx8IGNvbW1vbi5FbnZpcm9ubWVudHNbdGhpcy5iaXRnby5nZXRFbnYoKV0uZmxyRXhwbG9yZXJBcGlUb2tlbjtcbiAgICBjb25zdCBleHBsb3JlclVybCA9IGNvbW1vbi5FbnZpcm9ubWVudHNbdGhpcy5iaXRnby5nZXRFbnYoKV0uZmxyRXhwbG9yZXJCYXNlVXJsO1xuICAgIHJldHVybiBhd2FpdCByZWNvdmVyeUJsb2NrY2hhaW5FeHBsb3JlclF1ZXJ5KHF1ZXJ5LCBleHBsb3JlclVybCBhcyBzdHJpbmcsIGFwaVRva2VuKTtcbiAgfVxufVxuIl19
@@ -0,0 +1,26 @@
1
+ import { EthLikeTokenConfig } from '@bitgo-beta/statics';
2
+ import { BitGoBase, CoinConstructor, MPCAlgorithm, NamedCoinConstructor } from '@bitgo-beta/sdk-core';
3
+ import { CoinNames, EthLikeToken } from '@bitgo-beta/abstract-eth';
4
+ import { TransactionBuilder } from './lib';
5
+ export { EthLikeTokenConfig };
6
+ export declare class FlrToken extends EthLikeToken {
7
+ readonly tokenConfig: EthLikeTokenConfig;
8
+ static coinNames: CoinNames;
9
+ constructor(bitgo: BitGoBase, tokenConfig: EthLikeTokenConfig);
10
+ static createTokenConstructor(config: EthLikeTokenConfig): CoinConstructor;
11
+ static createTokenConstructors(): NamedCoinConstructor[];
12
+ protected getTransactionBuilder(): TransactionBuilder;
13
+ /** @inheritDoc **/
14
+ getMPCAlgorithm(): MPCAlgorithm;
15
+ /** @inheritDoc */
16
+ supportsTss(): boolean;
17
+ /**
18
+ * Make a query to Flare explorer for information such as balance, token balance, solidity calls
19
+ * @param {Object} query key-value pairs of parameters to append after /api
20
+ * @param {string} apiKey optional API key to use instead of the one from the environment
21
+ * @returns {Promise<Object>} response from Flare explorer
22
+ */
23
+ recoveryBlockchainExplorerQuery(query: Record<string, string>, apiKey?: string): Promise<Record<string, unknown>>;
24
+ getFullName(): string;
25
+ }
26
+ //# sourceMappingURL=flrToken.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flrToken.d.ts","sourceRoot":"","sources":["../../src/flrToken.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,eAAe,EAAU,YAAY,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC9G,OAAO,EAAE,SAAS,EAAE,YAAY,EAAmC,MAAM,0BAA0B,CAAC;AAEpG,OAAO,EAAE,kBAAkB,EAAE,MAAM,OAAO,CAAC;AAE3C,OAAO,EAAE,kBAAkB,EAAE,CAAC;AAE9B,qBAAa,QAAS,SAAQ,YAAY;IACxC,SAAgB,WAAW,EAAE,kBAAkB,CAAC;IAChD,MAAM,CAAC,SAAS,EAAE,SAAS,CAGzB;gBACU,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,kBAAkB;IAG7D,MAAM,CAAC,sBAAsB,CAAC,MAAM,EAAE,kBAAkB,GAAG,eAAe;IAI1E,MAAM,CAAC,uBAAuB,IAAI,oBAAoB,EAAE;IAIxD,SAAS,CAAC,qBAAqB,IAAI,kBAAkB;IAIrD,mBAAmB;IACnB,eAAe,IAAI,YAAY;IAI/B,kBAAkB;IAClB,WAAW,IAAI,OAAO;IAItB;;;;;OAKG;IACG,+BAA+B,CACnC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC7B,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAMnC,WAAW,IAAI,MAAM;CAGtB"}