@bitgo-beta/sdk-coin-flr 1.0.1-beta.82 → 1.0.1-beta.820
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/flr.d.ts +145 -3
- package/dist/src/flr.d.ts.map +1 -1
- package/dist/src/flr.js +464 -3
- package/dist/src/flrToken.d.ts +26 -0
- package/dist/src/flrToken.d.ts.map +1 -0
- package/dist/src/flrToken.js +49 -0
- package/dist/src/iface.d.ts +148 -0
- package/dist/src/iface.d.ts.map +1 -0
- package/dist/src/iface.js +3 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -1
- package/dist/src/lib/transactionBuilder.d.ts +2 -0
- package/dist/src/lib/transactionBuilder.d.ts.map +1 -1
- package/dist/src/lib/transactionBuilder.js +5 -1
- package/dist/src/register.d.ts.map +1 -1
- package/dist/src/register.js +5 -1
- package/dist/test/resources.d.ts +42 -0
- package/dist/test/resources.d.ts.map +1 -0
- package/dist/test/resources.js +117 -0
- package/dist/test/unit/flr.d.ts +2 -0
- package/dist/test/unit/flr.d.ts.map +1 -0
- package/dist/test/unit/flr.js +1040 -0
- package/dist/test/unit/flrToken.d.ts +2 -0
- package/dist/test/unit/flrToken.d.ts.map +1 -0
- package/dist/test/unit/flrToken.js +30 -0
- package/dist/test/unit/getBuilder.d.ts +3 -0
- package/dist/test/unit/getBuilder.d.ts.map +1 -0
- package/dist/test/unit/getBuilder.js +10 -0
- package/dist/test/unit/transactionBuilder/send.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/send.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/send.js +19 -0
- package/dist/test/unit/utils.d.ts +2 -0
- package/dist/test/unit/utils.d.ts.map +1 -0
- package/dist/test/unit/utils.js +29 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +22 -10
- package/.eslintignore +0 -5
- package/.mocharc.yml +0 -8
- 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
|
-
|
|
35
|
-
|
|
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"}
|