@bitgo-beta/sdk-coin-avaxp 0.0.0-semantic-release-managed
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/.eslintignore +5 -0
- package/.eslintrc.json +7 -0
- package/.mocharc.yml +8 -0
- package/CHANGELOG.md +1091 -0
- package/LICENSE +191 -0
- package/README.md +39 -0
- package/dist/src/avaxp.d.ts +91 -0
- package/dist/src/avaxp.d.ts.map +1 -0
- package/dist/src/avaxp.js +343 -0
- package/dist/src/iface.d.ts +42 -0
- package/dist/src/iface.d.ts.map +1 -0
- package/dist/src/iface.js +3 -0
- package/dist/src/index.d.ts +6 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +45 -0
- package/dist/src/lib/atomicInCTransactionBuilder.d.ts +21 -0
- package/dist/src/lib/atomicInCTransactionBuilder.d.ts.map +1 -0
- package/dist/src/lib/atomicInCTransactionBuilder.js +49 -0
- package/dist/src/lib/atomicTransactionBuilder.d.ts +38 -0
- package/dist/src/lib/atomicTransactionBuilder.d.ts.map +1 -0
- package/dist/src/lib/atomicTransactionBuilder.js +129 -0
- package/dist/src/lib/delegatorTxBuilder.d.ts +95 -0
- package/dist/src/lib/delegatorTxBuilder.d.ts.map +1 -0
- package/dist/src/lib/delegatorTxBuilder.js +285 -0
- package/dist/src/lib/deprecatedTransaction.d.ts +98 -0
- package/dist/src/lib/deprecatedTransaction.d.ts.map +1 -0
- package/dist/src/lib/deprecatedTransaction.js +344 -0
- package/dist/src/lib/deprecatedTransactionBuilder.d.ts +114 -0
- package/dist/src/lib/deprecatedTransactionBuilder.d.ts.map +1 -0
- package/dist/src/lib/deprecatedTransactionBuilder.js +210 -0
- package/dist/src/lib/errors.d.ts +8 -0
- package/dist/src/lib/errors.d.ts.map +1 -0
- package/dist/src/lib/errors.js +19 -0
- package/dist/src/lib/exportInCTxBuilder.d.ts +55 -0
- package/dist/src/lib/exportInCTxBuilder.d.ts.map +1 -0
- package/dist/src/lib/exportInCTxBuilder.js +159 -0
- package/dist/src/lib/exportTxBuilder.d.ts +33 -0
- package/dist/src/lib/exportTxBuilder.d.ts.map +1 -0
- package/dist/src/lib/exportTxBuilder.js +88 -0
- package/dist/src/lib/iface.d.ts +68 -0
- package/dist/src/lib/iface.d.ts.map +1 -0
- package/dist/src/lib/iface.js +20 -0
- package/dist/src/lib/importInCTxBuilder.d.ts +44 -0
- package/dist/src/lib/importInCTxBuilder.d.ts.map +1 -0
- package/dist/src/lib/importInCTxBuilder.js +131 -0
- package/dist/src/lib/importTxBuilder.d.ts +18 -0
- package/dist/src/lib/importTxBuilder.d.ts.map +1 -0
- package/dist/src/lib/importTxBuilder.js +67 -0
- package/dist/src/lib/index.d.ts +11 -0
- package/dist/src/lib/index.d.ts.map +1 -0
- package/dist/src/lib/index.js +37 -0
- package/dist/src/lib/keyPair.d.ts +58 -0
- package/dist/src/lib/keyPair.d.ts.map +1 -0
- package/dist/src/lib/keyPair.js +150 -0
- package/dist/src/lib/permissionlessValidatorTxBuilder.d.ts +154 -0
- package/dist/src/lib/permissionlessValidatorTxBuilder.d.ts.map +1 -0
- package/dist/src/lib/permissionlessValidatorTxBuilder.js +452 -0
- package/dist/src/lib/transaction.d.ts +78 -0
- package/dist/src/lib/transaction.d.ts.map +1 -0
- package/dist/src/lib/transaction.js +254 -0
- package/dist/src/lib/transactionBuilder.d.ts +71 -0
- package/dist/src/lib/transactionBuilder.d.ts.map +1 -0
- package/dist/src/lib/transactionBuilder.js +138 -0
- package/dist/src/lib/transactionBuilderFactory.d.ts +57 -0
- package/dist/src/lib/transactionBuilderFactory.d.ts.map +1 -0
- package/dist/src/lib/transactionBuilderFactory.js +178 -0
- package/dist/src/lib/utils.d.ts +184 -0
- package/dist/src/lib/utils.d.ts.map +1 -0
- package/dist/src/lib/utils.js +378 -0
- package/dist/src/lib/utxoEngine.d.ts +53 -0
- package/dist/src/lib/utxoEngine.d.ts.map +1 -0
- package/dist/src/lib/utxoEngine.js +112 -0
- package/dist/src/lib/validatorTxBuilder.d.ts +37 -0
- package/dist/src/lib/validatorTxBuilder.d.ts.map +1 -0
- package/dist/src/lib/validatorTxBuilder.js +69 -0
- package/dist/src/register.d.ts +3 -0
- package/dist/src/register.d.ts.map +1 -0
- package/dist/src/register.js +11 -0
- package/dist/src/tavaxp.d.ts +9 -0
- package/dist/src/tavaxp.d.ts.map +1 -0
- package/dist/src/tavaxp.js +14 -0
- package/dist/test/resources/avaxp.d.ts +259 -0
- package/dist/test/resources/avaxp.d.ts.map +1 -0
- package/dist/test/resources/avaxp.js +1093 -0
- package/dist/test/resources/errors.d.ts +19 -0
- package/dist/test/resources/errors.d.ts.map +1 -0
- package/dist/test/resources/errors.js +22 -0
- package/dist/test/resources/keychains.d.ts +18 -0
- package/dist/test/resources/keychains.d.ts.map +1 -0
- package/dist/test/resources/keychains.js +30 -0
- package/dist/test/resources/tx/exportC.d.ts +14 -0
- package/dist/test/resources/tx/exportC.d.ts.map +1 -0
- package/dist/test/resources/tx/exportC.js +21 -0
- package/dist/test/resources/tx/importC.d.ts +29 -0
- package/dist/test/resources/tx/importC.d.ts.map +1 -0
- package/dist/test/resources/tx/importC.js +42 -0
- package/dist/test/resources/tx/importP.d.ts +29 -0
- package/dist/test/resources/tx/importP.d.ts.map +1 -0
- package/dist/test/resources/tx/importP.js +42 -0
- package/dist/test/unit/avaxp.d.ts +2 -0
- package/dist/test/unit/avaxp.d.ts.map +1 -0
- package/dist/test/unit/avaxp.js +732 -0
- package/dist/test/unit/lib/exportC2PTxBuilder.d.ts +2 -0
- package/dist/test/unit/lib/exportC2PTxBuilder.d.ts.map +1 -0
- package/dist/test/unit/lib/exportC2PTxBuilder.js +125 -0
- package/dist/test/unit/lib/exportP2CTxBuilder.d.ts +2 -0
- package/dist/test/unit/lib/exportP2CTxBuilder.d.ts.map +1 -0
- package/dist/test/unit/lib/exportP2CTxBuilder.js +183 -0
- package/dist/test/unit/lib/importC2PTxBuilder.d.ts +2 -0
- package/dist/test/unit/lib/importC2PTxBuilder.d.ts.map +1 -0
- package/dist/test/unit/lib/importC2PTxBuilder.js +99 -0
- package/dist/test/unit/lib/importP2CTxBuilder.d.ts +2 -0
- package/dist/test/unit/lib/importP2CTxBuilder.d.ts.map +1 -0
- package/dist/test/unit/lib/importP2CTxBuilder.js +137 -0
- package/dist/test/unit/lib/keyPair.d.ts +2 -0
- package/dist/test/unit/lib/keyPair.d.ts.map +1 -0
- package/dist/test/unit/lib/keyPair.js +186 -0
- package/dist/test/unit/lib/permissionlessValidatorTxBuilder.d.ts +2 -0
- package/dist/test/unit/lib/permissionlessValidatorTxBuilder.d.ts.map +1 -0
- package/dist/test/unit/lib/permissionlessValidatorTxBuilder.js +341 -0
- package/dist/test/unit/lib/signFlowTestSuit.d.ts +20 -0
- package/dist/test/unit/lib/signFlowTestSuit.d.ts.map +1 -0
- package/dist/test/unit/lib/signFlowTestSuit.js +80 -0
- package/dist/test/unit/lib/transactionBuilderFactory.d.ts +2 -0
- package/dist/test/unit/lib/transactionBuilderFactory.d.ts.map +1 -0
- package/dist/test/unit/lib/transactionBuilderFactory.js +179 -0
- package/dist/test/unit/lib/utils.d.ts +2 -0
- package/dist/test/unit/lib/utils.d.ts.map +1 -0
- package/dist/test/unit/lib/utils.js +83 -0
- package/dist/test/unit/lib/utxoEngine.d.ts +2 -0
- package/dist/test/unit/lib/utxoEngine.d.ts.map +1 -0
- package/dist/test/unit/lib/utxoEngine.js +168 -0
- package/dist/test/unit/lib/validateTxBuilder.d.ts +2 -0
- package/dist/test/unit/lib/validateTxBuilder.d.ts.map +1 -0
- package/dist/test/unit/lib/validateTxBuilder.js +327 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.AtomicTransactionBuilder = void 0;
|
|
7
|
+
const avalanche_1 = require("avalanche");
|
|
8
|
+
const utils_1 = __importDefault(require("./utils"));
|
|
9
|
+
const deprecatedTransactionBuilder_1 = require("./deprecatedTransactionBuilder");
|
|
10
|
+
const platformvm_1 = require("avalanche/dist/apis/platformvm");
|
|
11
|
+
const sdk_core_1 = require("@bitgo-beta/sdk-core");
|
|
12
|
+
const iface_1 = require("./iface");
|
|
13
|
+
/**
|
|
14
|
+
* Cross-chain transactions (export and import) are atomic operations.
|
|
15
|
+
*/
|
|
16
|
+
class AtomicTransactionBuilder extends deprecatedTransactionBuilder_1.DeprecatedTransactionBuilder {
|
|
17
|
+
constructor(_coinConfig) {
|
|
18
|
+
super(_coinConfig);
|
|
19
|
+
this.transaction._fee.fee = this.fixedFee;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* The internal chain is the one set for the coin in coinConfig.network. The external chain is the other chain involved.
|
|
23
|
+
* The external chain id is the source on import and the destination on export.
|
|
24
|
+
*
|
|
25
|
+
* @param {string} chainId - id of the external chain
|
|
26
|
+
*/
|
|
27
|
+
externalChainId(chainId) {
|
|
28
|
+
const newTargetChainId = typeof chainId === 'string' ? utils_1.default.cb58Decode(chainId) : avalanche_1.Buffer.from(chainId);
|
|
29
|
+
this.validateChainId(newTargetChainId);
|
|
30
|
+
this._externalChainId = newTargetChainId;
|
|
31
|
+
return this;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Fee is fix for AVM atomic tx.
|
|
35
|
+
*
|
|
36
|
+
* @returns network.txFee
|
|
37
|
+
* @protected
|
|
38
|
+
*/
|
|
39
|
+
get fixedFee() {
|
|
40
|
+
return this.transaction._network.txFee;
|
|
41
|
+
}
|
|
42
|
+
// region utxo engine
|
|
43
|
+
/**
|
|
44
|
+
* Threshold must be 2 and since output always get reordered we want to make sure we can always add signatures in the correct location
|
|
45
|
+
* To find the correct location for the signature, we use the output's addresses to create the signatureIdx in the order that we desire
|
|
46
|
+
* 0: user key, 1: hsm key, 2: recovery key
|
|
47
|
+
* @protected
|
|
48
|
+
*/
|
|
49
|
+
createInputOutput(amount) {
|
|
50
|
+
const inputs = [];
|
|
51
|
+
const outputs = [];
|
|
52
|
+
// amount spent so far
|
|
53
|
+
let currentTotal = new avalanche_1.BN(0);
|
|
54
|
+
// delegating and validating have no fees
|
|
55
|
+
const totalTarget = amount.clone();
|
|
56
|
+
const credentials = [];
|
|
57
|
+
/*
|
|
58
|
+
A = user key
|
|
59
|
+
B = hsm key
|
|
60
|
+
C = backup key
|
|
61
|
+
bitgoAddresses = bitgo addresses [ A, B, C ]
|
|
62
|
+
utxo.addresses = IMS addresses [ B, C, A ]
|
|
63
|
+
utxo.addressesIndex = [ 2, 0, 1 ]
|
|
64
|
+
we pick 0, 1 for non-recovery
|
|
65
|
+
we pick 1, 2 for recovery
|
|
66
|
+
*/
|
|
67
|
+
this.transaction._utxos.forEach((utxo) => {
|
|
68
|
+
// in WP, output.addressesIndex is empty, so fill it
|
|
69
|
+
if (!utxo.addressesIndex || utxo.addressesIndex.length === 0) {
|
|
70
|
+
const utxoAddresses = utxo.addresses.map((a) => utils_1.default.parseAddress(a));
|
|
71
|
+
utxo.addressesIndex = this.transaction._fromAddresses.map((a) => utxoAddresses.findIndex((u) => a.equals(u)));
|
|
72
|
+
}
|
|
73
|
+
// in OVC, output.addressesIndex is defined correctly from the previous iteration
|
|
74
|
+
});
|
|
75
|
+
// validate the utxos
|
|
76
|
+
this.transaction._utxos.forEach((utxo) => {
|
|
77
|
+
if (!utxo) {
|
|
78
|
+
throw new sdk_core_1.BuildTransactionError('Utxo is undefined');
|
|
79
|
+
}
|
|
80
|
+
// addressesIndex should never have a mismatch
|
|
81
|
+
if (utxo.addressesIndex?.includes(-1)) {
|
|
82
|
+
throw new sdk_core_1.BuildTransactionError('Addresses are inconsistent: ' + utxo.txid);
|
|
83
|
+
}
|
|
84
|
+
if (utxo.threshold !== this.transaction._threshold) {
|
|
85
|
+
throw new sdk_core_1.BuildTransactionError('Threshold is inconsistent');
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
this.transaction._utxos.forEach((utxo, i) => {
|
|
89
|
+
if (utxo.outputID === iface_1.SECP256K1_Transfer_Output) {
|
|
90
|
+
const txidBuf = utils_1.default.cb58Decode(utxo.txid);
|
|
91
|
+
const amt = new avalanche_1.BN(utxo.amount);
|
|
92
|
+
const outputidx = utils_1.default.outputidxNumberToBuffer(utxo.outputidx);
|
|
93
|
+
const addressesIndex = utxo.addressesIndex ?? [];
|
|
94
|
+
// either user (0) or recovery (2)
|
|
95
|
+
const firstIndex = this.recoverSigner ? 2 : 0;
|
|
96
|
+
const bitgoIndex = 1;
|
|
97
|
+
currentTotal = currentTotal.add(amt);
|
|
98
|
+
const secpTransferInput = new platformvm_1.SECPTransferInput(amt);
|
|
99
|
+
// if user/backup > bitgo
|
|
100
|
+
if (addressesIndex[bitgoIndex] < addressesIndex[firstIndex]) {
|
|
101
|
+
secpTransferInput.addSignatureIdx(addressesIndex[bitgoIndex], this.transaction._fromAddresses[bitgoIndex]);
|
|
102
|
+
secpTransferInput.addSignatureIdx(addressesIndex[firstIndex], this.transaction._fromAddresses[firstIndex]);
|
|
103
|
+
credentials.push((0, platformvm_1.SelectCredentialClass)(secpTransferInput.getCredentialID(), // 9
|
|
104
|
+
['', this.transaction._fromAddresses[firstIndex].toString('hex')].map(utils_1.default.createSig)));
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
secpTransferInput.addSignatureIdx(addressesIndex[firstIndex], this.transaction._fromAddresses[firstIndex]);
|
|
108
|
+
secpTransferInput.addSignatureIdx(addressesIndex[bitgoIndex], this.transaction._fromAddresses[bitgoIndex]);
|
|
109
|
+
credentials.push((0, platformvm_1.SelectCredentialClass)(secpTransferInput.getCredentialID(), [this.transaction._fromAddresses[firstIndex].toString('hex'), ''].map(utils_1.default.createSig)));
|
|
110
|
+
}
|
|
111
|
+
const input = new platformvm_1.TransferableInput(txidBuf, outputidx, this.transaction._assetId, secpTransferInput);
|
|
112
|
+
inputs.push(input);
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
if (currentTotal.lt(totalTarget)) {
|
|
116
|
+
throw new sdk_core_1.BuildTransactionError(`Utxo outputs get ${currentTotal.toString()} and ${totalTarget.toString()} is required`);
|
|
117
|
+
}
|
|
118
|
+
else if (currentTotal.gt(totalTarget)) {
|
|
119
|
+
outputs.push(new platformvm_1.TransferableOutput(this.transaction._assetId, new platformvm_1.SECPTransferOutput(currentTotal.sub(totalTarget), this.transaction._fromAddresses, this.transaction._locktime, this.transaction._threshold)));
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
inputs,
|
|
123
|
+
outputs,
|
|
124
|
+
credentials,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
exports.AtomicTransactionBuilder = AtomicTransactionBuilder;
|
|
129
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXRvbWljVHJhbnNhY3Rpb25CdWlsZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpYi9hdG9taWNUcmFuc2FjdGlvbkJ1aWxkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQ0EseUNBQXFEO0FBQ3JELG9EQUE0QjtBQUM1QixpRkFBOEU7QUFDOUUsK0RBTXdDO0FBRXhDLG1EQUE2RDtBQUM3RCxtQ0FBb0Q7QUFFcEQ7O0dBRUc7QUFDSCxNQUFzQix3QkFBeUIsU0FBUSwyREFBNEI7SUFHakYsWUFBWSxXQUFpQztRQUMzQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDbkIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7SUFDNUMsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsZUFBZSxDQUFDLE9BQXdCO1FBQ3RDLE1BQU0sZ0JBQWdCLEdBQUcsT0FBTyxPQUFPLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxlQUFLLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxrQkFBVSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUM1RyxJQUFJLENBQUMsZUFBZSxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDdkMsSUFBSSxDQUFDLGdCQUFnQixHQUFHLGdCQUFnQixDQUFDO1FBQ3pDLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsSUFBYyxRQUFRO1FBQ3BCLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDO0lBQ3pDLENBQUM7SUFFRCxxQkFBcUI7SUFDckI7Ozs7O09BS0c7SUFDTyxpQkFBaUIsQ0FBQyxNQUFVO1FBS3BDLE1BQU0sTUFBTSxHQUF3QixFQUFFLENBQUM7UUFDdkMsTUFBTSxPQUFPLEdBQXlCLEVBQUUsQ0FBQztRQUV6QyxzQkFB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RCxNQUFNLEtBQUssR0FBc0IsSUFBSSw4QkFBaUIsQ0FDcEQsT0FBTyxFQUNQLFNBQVMsRUFDVCxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFDekIsaUJBQWlCLENBQ2xCLENBQUM7Z0JBQ0YsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNyQixDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLFlBQVksQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQztZQUNqQyxNQUFNLElBQUksZ0NBQXFCLENBQzdCLG9CQUFvQixZQUFZLENBQUMsUUFBUSxFQUFFLFFBQVEsV0FBVyxDQUFDLFFBQVEsRUFBRSxjQUFjLENBQ3hGLENBQUM7UUFDSixDQUFDO2FBQU0sSUFBSSxZQUFZLENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUM7WUFDeEMsT0FBTyxDQUFDLElBQUksQ0FDVixJQUFJLCtCQUFrQixDQUNwQixJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFDekIsSUFBSSwrQkFBa0IsQ0FDcEIsWUFBWSxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsRUFDN0IsSUFBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLEVBQy9CLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxFQUMxQixJQUFJLENBQUMsV0FBVyxDQUFDLFVBQVUsQ0FDNUIsQ0FDRixDQUNGLENBQUM7UUFDSixDQUFDO1FBQ0QsT0FBTztZQUNMLE1BQU07WUFDTixPQUFPO1lBQ1AsV0FBVztTQUNaLENBQUM7SUFDSixDQUFDO0NBR0Y7QUE3SkQsNERBNkpDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQmFzZUNvaW4gYXMgQ29pbkNvbmZpZyB9IGZyb20gJ0BiaXRnby1iZXRhL3N0YXRpY3MnO1xuaW1wb3J0IHsgQk4sIEJ1ZmZlciBhcyBCdWZmZXJBdmF4IH0gZnJvbSAnYXZhbGFuY2hlJztcbmltcG9ydCB1dGlscyBmcm9tICcuL3V0aWxzJztcbmltcG9ydCB7IERlcHJlY2F0ZWRUcmFuc2FjdGlvbkJ1aWxkZXIgfSBmcm9tICcuL2RlcHJlY2F0ZWRUcmFuc2FjdGlvbkJ1aWxkZXInO1xuaW1wb3J0IHtcbiAgU0VDUFRyYW5zZmVySW5wdXQsXG4gIFNFQ1BUcmFuc2Zlck91dHB1dCxcbiAgU2VsZWN0Q3JlZGVudGlhbENsYXNzLFxuICBUcmFuc2ZlcmFibGVJbnB1dCxcbiAgVHJhbnNmZXJhYmxlT3V0cHV0LFxufSBmcm9tICdhdmFsYW5jaGUvZGlzdC9hcGlzL3BsYXRmb3Jtdm0nO1xuaW1wb3J0IHsgQ3JlZGVudGlhbCB9IGZyb20gJ2F2YWxhbmNoZS9kaXN0L2NvbW1vbic7XG5pbXBvcnQgeyBCdWlsZFRyYW5zYWN0aW9uRXJyb3IgfSBmcm9tICdAYml0Z28tYmV0YS9zZGstY29yZSc7XG5pbXBvcnQgeyBTRUNQMjU2SzFfVHJhbnNmZXJfT3V0cHV0IH0gZnJvbSAnLi9pZmFjZSc7XG5cbi8qKlxuICogQ3Jvc3MtY2hhaW4gdHJhbnNhY3Rpb25zIChleHBvcnQgYW5kIGltcG9ydCkgYXJlIGF0b21pYyBvcGVyYXRpb25zLlxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQXRvbWljVHJhbnNhY3Rpb25CdWlsZGVyIGV4dGVuZHMgRGVwcmVjYXRlZFRyYW5zYWN0aW9uQnVpbGRlciB7XG4gIHByb3RlY3RlZCBfZXh0ZXJuYWxDaGFpbklkOiBCdWZmZXJBdmF4O1xuXG4gIGNvbnN0cnVjdG9yKF9jb2luQ29uZmlnOiBSZWFkb25seTxDb2luQ29uZmlnPikge1xuICAgIHN1cGVyKF9jb2luQ29uZmlnKTtcbiAgICB0aGlzLnRyYW5zYWN0aW9uLl9mZWUuZmVlID0gdGhpcy5maXhlZEZlZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgaW50ZXJuYWwgY2hhaW4gaXMgdGhlIG9uZSBzZXQgZm9yIHRoZSBjb2luIGluIGNvaW5Db25maWcubmV0d29yay4gVGhlIGV4dGVybmFsIGNoYWluIGlzIHRoZSBvdGhlciBjaGFpbiBpbnZvbHZlZC5cbiAgICogVGhlIGV4dGVybmFsIGNoYWluIGlkIGlzIHRoZSBzb3VyY2Ugb24gaW1wb3J0IGFuZCB0aGUgZGVzdGluYXRpb24gb24gZXhwb3J0LlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gY2hhaW5JZCAtIGlkIG9mIHRoZSBleHRlcm5hbCBjaGFpblxuICAgKi9cbiAgZXh0ZXJuYWxDaGFpbklkKGNoYWluSWQ6IHN0cmluZyB8IEJ1ZmZlcik6IHRoaXMge1xuICAgIGNvbnN0IG5ld1RhcmdldENoYWluSWQgPSB0eXBlb2YgY2hhaW5JZCA9PT0gJ3N0cmluZycgPyB1dGlscy5jYjU4RGVjb2RlKGNoYWluSWQpIDogQnVmZmVyQXZheC5mcm9tKGNoYWluSWQpO1xuICAgIHRoaXMudmFsaWRhdGVDaGFpbklkKG5ld1RhcmdldENoYWluSWQpO1xuICAgIHRoaXMuX2V4dGVybmFsQ2hhaW5JZCA9IG5ld1RhcmdldENoYWluSWQ7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogRmVlIGlzIGZpeCBmb3IgQVZNIGF0b21pYyB0eC5cbiAgICpcbiAgICogQHJldHVybnMgbmV0d29yay50eEZlZVxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0IGZpeGVkRmVlKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMudHJhbnNhY3Rpb24uX25ldHdvcmsudHhGZWU7XG4gIH1cblxuICAvLyByZWdpb24gdXR4byBlbmdpbmVcbiAgLyoqXG4gICAqIFRocmVzaG9sZCBtdXN0IGJlIDIgYW5kIHNpbmNlIG91dHB1dCBhbHdheXMgZ2V0IHJlb3JkZXJlZCB3ZSB3YW50IHRvIG1ha2Ugc3VyZSB3ZSBjYW4gYWx3YXlzIGFkZCBzaWduYXR1cmVzIGluIHRoZSBjb3JyZWN0IGxvY2F0aW9uXG4gICAqIFRvIGZpbmQgdGhlIGNvcnJlY3QgbG9jYXRpb24gZm9yIHRoZSBzaWduYXR1cmUsIHdlIHVzZSB0aGUgb3V0cHV0J3MgYWRkcmVzc2VzIHRvIGNyZWF0ZSB0aGUgc2lnbmF0dXJlSWR4IGluIHRoZSBvcmRlciB0aGF0IHdlIGRlc2lyZVxuICAgKiAwOiB1c2VyIGtleSwgMTogaHNtIGtleSwgMjogcmVjb3Zlcnkga2V5XG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG4gIHByb3RlY3RlZCBjcmVhdGVJbnB1dE91dHB1dChhbW91bnQ6IEJOKToge1xuICAgIGlucHV0czogVHJhbnNmZXJhYmxlSW5wdXRbXTtcbiAgICBvdXRwdXRzOiBUcmFuc2ZlcmFibGVPdXRwdXRbXTtcbiAgICBjcmVkZW50aWFsczogQ3JlZGVudGlhbFtdO1xuICB9IHtcbiAgICBjb25zdCBpbnB1dHM6IFRyYW5zZmVyYWJsZUlucHV0W10gPSBbXTtcbiAgICBjb25zdCBvdXRwdXRzOiBUcmFuc2ZlcmFibGVPdXRwdXRbXSA9IFtdO1xuXG4gICAgLy8gYW1vdW50IHNwZW50IHNvIGZhclxuICAgIGxldCBjdXJyZW50VG90YWw6IEJOID0gbmV3IEJOKDApO1xuXG4gICAgLy8gZGVsZWdhdGluZyBhbmQgdmFsaWRhdGluZyBoYXZlIG5vIGZlZXNcbiAgICBjb25zdCB0b3RhbFRhcmdldCA9IGFtb3VudC5jbG9uZSgpO1xuXG4gICAgY29uc3QgY3JlZGVudGlhbHM6IENyZWRlbnRpYWxbXSA9IFtdO1xuXG4gICAgLypcbiAgICBBID0gdXNlciBrZXlcbiAgICBCID0gaHNtIGtleVxuICAgIEMgPSBiYWNrdXAga2V5XG4gICAgYml0Z29BZGRyZXNzZXMgPSBiaXRnbyBhZGRyZXNzZXMgWyBBLCBCLCBDIF1cbiAgICB1dHhvLmFkZHJlc3NlcyA9IElNUyBhZGRyZXNzZXMgWyBCLCBDLCBBIF1cbiAgICB1dHhvLmFkZHJlc3Nlc0luZGV4ID0gWyAyLCAwLCAxIF1cbiAgICB3ZSBwaWNrIDAsIDEgZm9yIG5vbi1yZWNvdmVyeVxuICAgIHdlIHBpY2sgMSwgMiBmb3IgcmVjb3ZlcnlcbiAgICAqL1xuICAgIHRoaXMudHJhbnNhY3Rpb24uX3V0eG9zLmZvckVhY2goKHV0eG8pID0+IHtcbiAgICAgIC8vIGluIFdQLCBvdXRwdXQuYWRkcmVzc2VzSW5kZXggaXMgZW1wdHksIHNvIGZpbGwgaXRcbiAgICAgIGlmICghdXR4by5hZGRyZXNzZXNJbmRleCB8fCB1dHhvLmFkZHJlc3Nlc0luZGV4Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBjb25zdCB1dHhvQWRkcmVzc2VzOiBCdWZmZXJBdmF4W10gPSB1dHhvLmFkZHJlc3Nlcy5tYXAoKGEpID0+IHV0aWxzLnBhcnNlQWRkcmVzcyhhKSk7XG4gICAgICAgIHV0eG8uYWRkcmVzc2VzSW5kZXggPSB0aGlzLnRyYW5zYWN0aW9uLl9mcm9tQWRkcmVzc2VzLm1hcCgoYSkgPT4gdXR4b0FkZHJlc3Nlcy5maW5kSW5kZXgoKHUpID0+IGEuZXF1YWxzKHUpKSk7XG4gICAgICB9XG4gICAgICAvLyBpbiBPVkMsIG91dHB1dC5hZGRyZXNzZXNJbmRleCBpcyBkZWZpbmVkIGNvcnJlY3RseSBmcm9tIHRoZSBwcmV2aW91cyBpdGVyYXRpb25cbiAgICB9KTtcblxuICAgIC8vIHZhbGlkYXRlIHRoZSB1dHhvc1xuICAgIHRoaXMudHJhbnNhY3Rpb24uX3V0eG9zLmZvckVhY2goKHV0eG8pID0+IHtcbiAgICAgIGlmICghdXR4bykge1xuICAgICAgICB0aHJvdyBuZXcgQnVpbGRUcmFuc2FjdGlvbkVycm9yKCdVdHhvIGlzIHVuZGVmaW5lZCcpO1xuICAgICAgfVxuICAgICAgLy8gYWRkcmVzc2VzSW5kZXggc2hvdWxkIG5ldmVyIGhhdmUgYSBtaXNtYXRjaFxuICAgICAgaWYgKHV0eG8uYWRkcmVzc2VzSW5kZXg/LmluY2x1ZGVzKC0xKSkge1xuICAgICAgICB0aHJvdyBuZXcgQnVpbGRUcmFuc2FjdGlvbkVycm9yKCdBZGRyZXNzZXMgYXJlIGluY29uc2lzdGVudDogJyArIHV0eG8udHhpZCk7XG4gICAgICB9XG4gICAgICBpZiAodXR4by50aHJlc2hvbGQgIT09IHRoaXMudHJhbnNhY3Rpb24uX3RocmVzaG9sZCkge1xuICAgICAgICB0aHJvdyBuZXcgQnVpbGRUcmFuc2FjdGlvbkVycm9yKCdUaHJlc2hvbGQgaXMgaW5jb25zaXN0ZW50Jyk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB0aGlzLnRyYW5zYWN0aW9uLl91dHhvcy5mb3JFYWNoKCh1dHhvLCBpKSA9PiB7XG4gICAgICBpZiAodXR4by5vdXRwdXRJRCA9PT0gU0VDUDI1NksxX1RyYW5zZmVyX091dHB1dCkge1xuICAgICAgICBjb25zdCB0eGlkQnVmID0gdXRpbHMuY2I1OERlY29kZSh1dHhvLnR4aWQpO1xuICAgICAgICBjb25zdCBhbXQ6IEJOID0gbmV3IEJOKHV0eG8uYW1vdW50KTtcbiAgICAgICAgY29uc3Qgb3V0cHV0aWR4ID0gdXRpbHMub3V0cHV0aWR4TnVtYmVyVG9CdWZmZXIodXR4by5vdXRwdXRpZHgpO1xuICAgICAgICBjb25zdCBhZGRyZXNzZXNJbmRleCA9IHV0eG8uYWRkcmVzc2VzSW5kZXggPz8gW107XG5cbiAgICAgICAgLy8gZWl0aGVyIHVzZXIgKDApIG9yIHJlY292ZXJ5ICgyKVxuICAgICAgICBjb25zdCBmaXJzdEluZGV4ID0gdGhpcy5yZWNvdmVyU2lnbmVyID8gMiA6IDA7XG4gICAgICAgIGNvbnN0IGJpdGdvSW5kZXggPSAxO1xuICAgICAgICBjdXJyZW50VG90YWwgPSBjdXJyZW50VG90YWwuYWRkKGFtdCk7XG5cbiAgICAgICAgY29uc3Qgc2VjcFRyYW5zZmVySW5wdXQgPSBuZXcgU0VDUFRyYW5zZmVySW5wdXQoYW10KTtcblxuICAgICAgICAvLyBpZiB1c2VyL2JhY2t1cCA+IGJpdGdvXG4gICAgICAgIGlmIChhZGRyZXNzZXNJbmRleFtiaXRnb0luZGV4XSA8IGFkZHJlc3Nlc0luZGV4W2ZpcnN0SW5kZXhdKSB7XG4gICAgICAgICAgc2VjcFRyYW5zZmVySW5wdXQuYWRkU2lnbmF0dXJlSWR4KGFkZHJlc3Nlc0luZGV4W2JpdGdvSW5kZXhdLCB0aGlzLnRyYW5zYWN0aW9uLl9mcm9tQWRkcmVzc2VzW2JpdGdvSW5kZXhdKTtcbiAgICAgICAgICBzZWNwVHJhbnNmZXJJbnB1dC5hZGRTaWduYXR1cmVJZHgoYWRkcmVzc2VzSW5kZXhbZmlyc3RJbmRleF0sIHRoaXMudHJhbnNhY3Rpb24uX2Zyb21BZGRyZXNzZXNbZmlyc3RJbmRleF0pO1xuICAgICAgICAgIGNyZWRlbnRpYWxzLnB1c2goXG4gICAgICAgICAgICBTZWxlY3RDcmVkZW50aWFsQ2xhc3MoXG4gICAgICAgICAgICAgIHNlY3BUcmFuc2ZlcklucHV0LmdldENyZWRlbnRpYWxJRCgpLCAvLyA5XG4gICAgICAgICAgICAgIFsnJywgdGhpcy50cmFuc2FjdGlvbi5fZnJvbUFkZHJlc3Nlc1tmaXJzdEluZGV4XS50b1N0cmluZygnaGV4JyldLm1hcCh1dGlscy5jcmVhdGVTaWcpXG4gICAgICAgICAgICApXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzZWNwVHJhbnNmZXJJbnB1dC5hZGRTaWduYXR1cmVJZHgoYWRkcmVzc2VzSW5kZXhbZmlyc3RJbmRleF0sIHRoaXMudHJhbnNhY3Rpb24uX2Zyb21BZGRyZXNzZXNbZmlyc3RJbmRleF0pO1xuICAgICAgICAgIHNlY3BUcmFuc2ZlcklucHV0LmFkZFNpZ25hdHVyZUlkeChhZGRyZXNzZXNJbmRleFtiaXRnb0luZGV4XSwgdGhpcy50cmFuc2FjdGlvbi5fZnJvbUFkZHJlc3Nlc1tiaXRnb0luZGV4XSk7XG4gICAgICAgICAgY3JlZGVudGlhbHMucHVzaChcbiAgICAgICAgICAgIFNlbGVjdENyZWRlbnRpYWxDbGFzcyhcbiAgICAgICAgICAgICAgc2VjcFRyYW5zZmVySW5wdXQuZ2V0Q3JlZGVudGlhbElEKCksXG4gICAgICAgICAgICAgIFt0aGlzLnRyYW5zYWN0aW9uLl9mcm9tQWRkcmVzc2VzW2ZpcnN0SW5kZXhdLnRvU3RyaW5nKCdoZXgnKSwgJyddLm1hcCh1dGlscy5jcmVhdGVTaWcpXG4gICAgICAgICAgICApXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGlucHV0OiBUcmFuc2ZlcmFibGVJbnB1dCA9IG5ldyBUcmFuc2ZlcmFibGVJbnB1dChcbiAgICAgICAgICB0eGlkQnVmLFxuICAgICAgICAgIG91dHB1dGlkeCxcbiAgICAgICAgICB0aGlzLnRyYW5zYWN0aW9uLl9hc3NldElkLFxuICAgICAgICAgIHNlY3BUcmFuc2ZlcklucHV0XG4gICAgICAgICk7XG4gICAgICAgIGlucHV0cy5wdXNoKGlucHV0KTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGlmIChjdXJyZW50VG90YWwubHQodG90YWxUYXJnZXQpKSB7XG4gICAgICB0aHJvdyBuZXcgQnVpbGRUcmFuc2FjdGlvbkVycm9yKFxuICAgICAgICBgVXR4byBvdXRwdXRzIGdldCAke2N1cnJlbnRUb3RhbC50b1N0cmluZygpfSBhbmQgJHt0b3RhbFRhcmdldC50b1N0cmluZygpfSBpcyByZXF1aXJlZGBcbiAgICAgICk7XG4gICAgfSBlbHNlIGlmIChjdXJyZW50VG90YWwuZ3QodG90YWxUYXJnZXQpKSB7XG4gICAgICBvdXRwdXRzLnB1c2goXG4gICAgICAgIG5ldyBUcmFuc2ZlcmFibGVPdXRwdXQoXG4gICAgICAgICAgdGhpcy50cmFuc2FjdGlvbi5fYXNzZXRJZCxcbiAgICAgICAgICBuZXcgU0VDUFRyYW5zZmVyT3V0cHV0KFxuICAgICAgICAgICAgY3VycmVudFRvdGFsLnN1Yih0b3RhbFRhcmdldCksXG4gICAgICAgICAgICB0aGlzLnRyYW5zYWN0aW9uLl9mcm9tQWRkcmVzc2VzLFxuICAgICAgICAgICAgdGhpcy50cmFuc2FjdGlvbi5fbG9ja3RpbWUsXG4gICAgICAgICAgICB0aGlzLnRyYW5zYWN0aW9uLl90aHJlc2hvbGRcbiAgICAgICAgICApXG4gICAgICAgIClcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBpbnB1dHMsXG4gICAgICBvdXRwdXRzLFxuICAgICAgY3JlZGVudGlhbHMsXG4gICAgfTtcbiAgfVxuXG4gIC8vIGVuZHJlZ2lvblxufVxuIl19
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { TransactionType } from '@bitgo-beta/sdk-core';
|
|
2
|
+
import { BaseCoin as CoinConfig } from '@bitgo-beta/statics';
|
|
3
|
+
import { DeprecatedTransactionBuilder } from './deprecatedTransactionBuilder';
|
|
4
|
+
import { AddDelegatorTx, ParseableOutput, TransferableInput, TransferableOutput } from 'avalanche/dist/apis/platformvm';
|
|
5
|
+
import { BN } from 'avalanche';
|
|
6
|
+
import { DeprecatedTx, DeprecatedBaseTx } from './iface';
|
|
7
|
+
import { Credential } from 'avalanche/dist/common';
|
|
8
|
+
export declare class DelegatorTxBuilder extends DeprecatedTransactionBuilder {
|
|
9
|
+
protected _nodeID: string;
|
|
10
|
+
protected _startTime: BN;
|
|
11
|
+
protected _endTime: BN;
|
|
12
|
+
protected _stakeAmount: BN;
|
|
13
|
+
/**
|
|
14
|
+
*
|
|
15
|
+
* @param coinConfig
|
|
16
|
+
*/
|
|
17
|
+
constructor(coinConfig: Readonly<CoinConfig>);
|
|
18
|
+
/**
|
|
19
|
+
* get transaction type
|
|
20
|
+
* @protected
|
|
21
|
+
*/
|
|
22
|
+
protected get transactionType(): TransactionType;
|
|
23
|
+
/**
|
|
24
|
+
* Addresses where reward should be deposit
|
|
25
|
+
* @param {string | string[]} address - single address or array of addresses to receive rewards
|
|
26
|
+
*/
|
|
27
|
+
rewardAddresses(address: string | string[]): this;
|
|
28
|
+
/**
|
|
29
|
+
*
|
|
30
|
+
* @param nodeID
|
|
31
|
+
*/
|
|
32
|
+
nodeID(value: string): this;
|
|
33
|
+
/**
|
|
34
|
+
* start time of staking period
|
|
35
|
+
* @param value
|
|
36
|
+
*/
|
|
37
|
+
startTime(value: string | number): this;
|
|
38
|
+
/**
|
|
39
|
+
* end time of staking period
|
|
40
|
+
* @param value
|
|
41
|
+
*/
|
|
42
|
+
endTime(value: string | number): this;
|
|
43
|
+
/**
|
|
44
|
+
*
|
|
45
|
+
* @param value
|
|
46
|
+
*/
|
|
47
|
+
stakeAmount(value: BN | string): this;
|
|
48
|
+
/**
|
|
49
|
+
* validates a correct NodeID is used
|
|
50
|
+
* @param nodeID
|
|
51
|
+
*/
|
|
52
|
+
validateNodeID(nodeID: string): void;
|
|
53
|
+
/**
|
|
54
|
+
*
|
|
55
|
+
* protected _startTime: Date;
|
|
56
|
+
* protected _endTime: Date;
|
|
57
|
+
* 2 weeks = 1209600
|
|
58
|
+
* 1 year = 31556926
|
|
59
|
+
* unix time stamp based off seconds
|
|
60
|
+
*/
|
|
61
|
+
validateStakeDuration(startTime: BN, endTime: BN): void;
|
|
62
|
+
/**
|
|
63
|
+
*
|
|
64
|
+
* @param amount
|
|
65
|
+
*/
|
|
66
|
+
validateStakeAmount(amount: BN): void;
|
|
67
|
+
/** @inheritdoc */
|
|
68
|
+
initBuilder(tx: DeprecatedTx): this;
|
|
69
|
+
static verifyTxType(baseTx: DeprecatedBaseTx): baseTx is AddDelegatorTx;
|
|
70
|
+
verifyTxType(baseTx: DeprecatedBaseTx): baseTx is AddDelegatorTx;
|
|
71
|
+
/**
|
|
72
|
+
*
|
|
73
|
+
* @protected
|
|
74
|
+
*/
|
|
75
|
+
protected buildAvaxTransaction(): void;
|
|
76
|
+
/**
|
|
77
|
+
* Create the StakeOut where the recipient address are the sender.
|
|
78
|
+
* @protected
|
|
79
|
+
*
|
|
80
|
+
*/
|
|
81
|
+
protected stakeTransferOut(): TransferableOutput;
|
|
82
|
+
protected rewardOwnersOutput(): ParseableOutput;
|
|
83
|
+
/**
|
|
84
|
+
* Threshold must be 2 and since output always get reordered we want to make sure we can always add signatures in the correct location
|
|
85
|
+
* To find the correct location for the signature, we use the ouput's addresses to create the signatureIdx in the order that we desire
|
|
86
|
+
* 0: user key, 1: hsm key, 2: recovery key
|
|
87
|
+
* @protected
|
|
88
|
+
*/
|
|
89
|
+
protected createInputOutput(): {
|
|
90
|
+
inputs: TransferableInput[];
|
|
91
|
+
outputs: TransferableOutput[];
|
|
92
|
+
credentials: Credential[];
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=delegatorTxBuilder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delegatorTxBuilder.d.ts","sourceRoot":"","sources":["../../../src/lib/delegatorTxBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuC,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5F,OAAO,EAAoB,QAAQ,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC/E,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAC9E,OAAO,EACL,cAAc,EAEd,eAAe,EAMf,iBAAiB,EACjB,kBAAkB,EAGnB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAY,EAAE,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAA6B,YAAY,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEpF,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGnD,qBAAa,kBAAmB,SAAQ,4BAA4B;IAClE,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,UAAU,EAAE,EAAE,CAAC;IACzB,SAAS,CAAC,QAAQ,EAAE,EAAE,CAAC;IACvB,SAAS,CAAC,YAAY,EAAE,EAAE,CAAC;IAE3B;;;OAGG;gBACS,UAAU,EAAE,QAAQ,CAAC,UAAU,CAAC;IAM5C;;;OAGG;IACH,SAAS,KAAK,eAAe,IAAI,eAAe,CAE/C;IAED;;;OAGG;IACH,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI;IAMjD;;;OAGG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAM3B;;;OAGG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAKvC;;;OAGG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAKrC;;;OAGG;IACH,WAAW,CAAC,KAAK,EAAE,EAAE,GAAG,MAAM,GAAG,IAAI;IAQrC;;;OAGG;IACH,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAYpC;;;;;;;OAOG;IACH,qBAAqB,CAAC,SAAS,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,GAAG,IAAI;IAgBvD;;;OAGG;IACH,mBAAmB,CAAC,MAAM,EAAE,EAAE,GAAG,IAAI;IASrC,kBAAkB;IAClB,WAAW,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI;IA6BnC,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,IAAI,cAAc;IAIvE,YAAY,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,IAAI,cAAc;IAIhE;;;OAGG;IACH,SAAS,CAAC,oBAAoB,IAAI,IAAI;IAyBtC;;;;OAIG;IACH,SAAS,CAAC,gBAAgB,IAAI,kBAAkB;IAYhD,SAAS,CAAC,kBAAkB,IAAI,eAAe;IAW/C;;;;;OAKG;IACH,SAAS,CAAC,iBAAiB,IAAI;QAC7B,MAAM,EAAE,iBAAiB,EAAE,CAAC;QAC5B,OAAO,EAAE,kBAAkB,EAAE,CAAC;QAC9B,WAAW,EAAE,UAAU,EAAE,CAAC;KAC3B;CAkIF"}
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.DelegatorTxBuilder = void 0;
|
|
7
|
+
const sdk_core_1 = require("@bitgo-beta/sdk-core");
|
|
8
|
+
const deprecatedTransactionBuilder_1 = require("./deprecatedTransactionBuilder");
|
|
9
|
+
const platformvm_1 = require("avalanche/dist/apis/platformvm");
|
|
10
|
+
const avalanche_1 = require("avalanche");
|
|
11
|
+
const iface_1 = require("./iface");
|
|
12
|
+
const utils_1 = __importDefault(require("./utils"));
|
|
13
|
+
const utxoEngine_1 = require("./utxoEngine");
|
|
14
|
+
class DelegatorTxBuilder extends deprecatedTransactionBuilder_1.DeprecatedTransactionBuilder {
|
|
15
|
+
/**
|
|
16
|
+
*
|
|
17
|
+
* @param coinConfig
|
|
18
|
+
*/
|
|
19
|
+
constructor(coinConfig) {
|
|
20
|
+
super(coinConfig);
|
|
21
|
+
const network = coinConfig.network;
|
|
22
|
+
this._stakeAmount = new avalanche_1.BN(network.minStake);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* get transaction type
|
|
26
|
+
* @protected
|
|
27
|
+
*/
|
|
28
|
+
get transactionType() {
|
|
29
|
+
return sdk_core_1.TransactionType.AddDelegator;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Addresses where reward should be deposit
|
|
33
|
+
* @param {string | string[]} address - single address or array of addresses to receive rewards
|
|
34
|
+
*/
|
|
35
|
+
rewardAddresses(address) {
|
|
36
|
+
const rewardAddresses = address instanceof Array ? address : [address];
|
|
37
|
+
this.transaction._rewardAddresses = rewardAddresses.map(utils_1.default.parseAddress);
|
|
38
|
+
return this;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
*
|
|
42
|
+
* @param nodeID
|
|
43
|
+
*/
|
|
44
|
+
nodeID(value) {
|
|
45
|
+
this.validateNodeID(value);
|
|
46
|
+
this._nodeID = value;
|
|
47
|
+
return this;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* start time of staking period
|
|
51
|
+
* @param value
|
|
52
|
+
*/
|
|
53
|
+
startTime(value) {
|
|
54
|
+
this._startTime = new avalanche_1.BN(value);
|
|
55
|
+
return this;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* end time of staking period
|
|
59
|
+
* @param value
|
|
60
|
+
*/
|
|
61
|
+
endTime(value) {
|
|
62
|
+
this._endTime = new avalanche_1.BN(value);
|
|
63
|
+
return this;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
*
|
|
67
|
+
* @param value
|
|
68
|
+
*/
|
|
69
|
+
stakeAmount(value) {
|
|
70
|
+
const valueBN = avalanche_1.BN.isBN(value) ? value : new avalanche_1.BN(value);
|
|
71
|
+
this.validateStakeAmount(valueBN);
|
|
72
|
+
this._stakeAmount = valueBN;
|
|
73
|
+
return this;
|
|
74
|
+
}
|
|
75
|
+
// region Validators
|
|
76
|
+
/**
|
|
77
|
+
* validates a correct NodeID is used
|
|
78
|
+
* @param nodeID
|
|
79
|
+
*/
|
|
80
|
+
validateNodeID(nodeID) {
|
|
81
|
+
if (!nodeID) {
|
|
82
|
+
throw new sdk_core_1.BuildTransactionError('Invalid transaction: missing nodeID');
|
|
83
|
+
}
|
|
84
|
+
if (nodeID.slice(0, 6) !== 'NodeID') {
|
|
85
|
+
throw new sdk_core_1.BuildTransactionError('Invalid transaction: invalid NodeID tag');
|
|
86
|
+
}
|
|
87
|
+
const bintools = avalanche_1.BinTools.getInstance();
|
|
88
|
+
if (!(bintools.b58ToBuffer(nodeID.slice(7)).length === 24)) {
|
|
89
|
+
throw new sdk_core_1.BuildTransactionError('Invalid transaction: NodeID is not in cb58 format');
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
*
|
|
94
|
+
* protected _startTime: Date;
|
|
95
|
+
* protected _endTime: Date;
|
|
96
|
+
* 2 weeks = 1209600
|
|
97
|
+
* 1 year = 31556926
|
|
98
|
+
* unix time stamp based off seconds
|
|
99
|
+
*/
|
|
100
|
+
validateStakeDuration(startTime, endTime) {
|
|
101
|
+
const oneDayLater = new avalanche_1.BN(Date.now()).add(new avalanche_1.BN(86400));
|
|
102
|
+
if (!startTime.gt(oneDayLater)) {
|
|
103
|
+
throw new sdk_core_1.BuildTransactionError('Start time needs to be one day greater than current time');
|
|
104
|
+
}
|
|
105
|
+
if (endTime < startTime) {
|
|
106
|
+
throw new sdk_core_1.BuildTransactionError('End date cannot be less than start date');
|
|
107
|
+
}
|
|
108
|
+
if (startTime.add(new avalanche_1.BN(this.transaction._network.minStakeDuration)).gt(endTime)) {
|
|
109
|
+
throw new sdk_core_1.BuildTransactionError('End date must be greater than or equal to two weeks');
|
|
110
|
+
}
|
|
111
|
+
if (endTime.gt(startTime.add(new avalanche_1.BN(this.transaction._network.maxStakeDuration)))) {
|
|
112
|
+
throw new sdk_core_1.BuildTransactionError('End date must be less than or equal to one year');
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
*
|
|
117
|
+
* @param amount
|
|
118
|
+
*/
|
|
119
|
+
validateStakeAmount(amount) {
|
|
120
|
+
const minStake = new avalanche_1.BN(this.transaction._network.minStake);
|
|
121
|
+
if (amount.lt(minStake)) {
|
|
122
|
+
throw new sdk_core_1.BuildTransactionError('Minimum staking amount is ' + Number(minStake) / 1000000000 + ' AVAX.');
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// endregion
|
|
126
|
+
/** @inheritdoc */
|
|
127
|
+
initBuilder(tx) {
|
|
128
|
+
super.initBuilder(tx);
|
|
129
|
+
const baseTx = tx.getUnsignedTx().getTransaction();
|
|
130
|
+
if (!this.verifyTxType(baseTx)) {
|
|
131
|
+
throw new sdk_core_1.NotSupported('Transaction cannot be parsed or has an unsupported transaction type');
|
|
132
|
+
}
|
|
133
|
+
// The StakeOuts is a {@link stakeTransferOut} result.
|
|
134
|
+
// It's expected to have only one outputs with the addresses of the sender.
|
|
135
|
+
const outputs = baseTx.getStakeOuts();
|
|
136
|
+
if (outputs.length != 1) {
|
|
137
|
+
throw new sdk_core_1.BuildTransactionError('Transaction can have one external output');
|
|
138
|
+
}
|
|
139
|
+
const output = outputs[0];
|
|
140
|
+
if (!output.getAssetID().equals(this.transaction._assetId)) {
|
|
141
|
+
throw new Error('The Asset ID of the output does not match the transaction');
|
|
142
|
+
}
|
|
143
|
+
const secpOut = output.getOutput();
|
|
144
|
+
this.transaction._locktime = secpOut.getLocktime();
|
|
145
|
+
this.transaction._threshold = secpOut.getThreshold();
|
|
146
|
+
// output addresses are the sender addresses
|
|
147
|
+
this.transaction._fromAddresses = secpOut.getAddresses();
|
|
148
|
+
this._nodeID = baseTx.getNodeIDString();
|
|
149
|
+
this._startTime = baseTx.getStartTime();
|
|
150
|
+
this._endTime = baseTx.getEndTime();
|
|
151
|
+
this._stakeAmount = baseTx.getStakeAmount();
|
|
152
|
+
this.transaction._utxos = (0, utxoEngine_1.deprecatedRecoverUtxos)(baseTx.getIns());
|
|
153
|
+
return this;
|
|
154
|
+
}
|
|
155
|
+
static verifyTxType(baseTx) {
|
|
156
|
+
return baseTx.getTypeID() === platformvm_1.PlatformVMConstants.ADDVALIDATORTX;
|
|
157
|
+
}
|
|
158
|
+
verifyTxType(baseTx) {
|
|
159
|
+
return DelegatorTxBuilder.verifyTxType(baseTx);
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
*
|
|
163
|
+
* @protected
|
|
164
|
+
*/
|
|
165
|
+
buildAvaxTransaction() {
|
|
166
|
+
this.validateStakeDuration(this._startTime, this._endTime);
|
|
167
|
+
const { inputs, outputs, credentials } = this.createInputOutput();
|
|
168
|
+
this.transaction.setTransaction(new platformvm_1.Tx(new platformvm_1.UnsignedTx(new platformvm_1.AddDelegatorTx(this.transaction._networkID, this.transaction._blockchainID, outputs, inputs, undefined, utils_1.default.NodeIDStringToBuffer(this._nodeID), this._startTime, this._endTime, this._stakeAmount, [this.stakeTransferOut()], this.rewardOwnersOutput())), credentials));
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Create the StakeOut where the recipient address are the sender.
|
|
172
|
+
* @protected
|
|
173
|
+
*
|
|
174
|
+
*/
|
|
175
|
+
stakeTransferOut() {
|
|
176
|
+
return new platformvm_1.TransferableOutput(this.transaction._assetId, new platformvm_1.SECPTransferOutput(this._stakeAmount, this.transaction._fromAddresses, this.transaction._locktime, this.transaction._threshold));
|
|
177
|
+
}
|
|
178
|
+
rewardOwnersOutput() {
|
|
179
|
+
// if there are no reward addresses, the sender gets the rewards
|
|
180
|
+
if (!this.transaction._rewardAddresses || this.transaction._rewardAddresses.length === 0) {
|
|
181
|
+
this.transaction._rewardAddresses = this.transaction._fromAddresses;
|
|
182
|
+
}
|
|
183
|
+
return new platformvm_1.ParseableOutput(new platformvm_1.SECPOwnerOutput(this.transaction._rewardAddresses, this.transaction._locktime, this.transaction._threshold));
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Threshold must be 2 and since output always get reordered we want to make sure we can always add signatures in the correct location
|
|
187
|
+
* To find the correct location for the signature, we use the ouput's addresses to create the signatureIdx in the order that we desire
|
|
188
|
+
* 0: user key, 1: hsm key, 2: recovery key
|
|
189
|
+
* @protected
|
|
190
|
+
*/
|
|
191
|
+
createInputOutput() {
|
|
192
|
+
const inputs = [];
|
|
193
|
+
const outputs = [];
|
|
194
|
+
// amount spent so far
|
|
195
|
+
let currentTotal = new avalanche_1.BN(0);
|
|
196
|
+
// delegating and validating have no fees
|
|
197
|
+
const totalTarget = this._stakeAmount.clone();
|
|
198
|
+
const credentials = [];
|
|
199
|
+
// convert fromAddresses to string
|
|
200
|
+
// fromAddresses = bitgo order if we are in WP
|
|
201
|
+
// fromAddresses = onchain order if we are in from
|
|
202
|
+
const bitgoAddresses = this.transaction._fromAddresses.map((b) => utils_1.default.addressToString(this.transaction._network.hrp, this.transaction._network.alias, b));
|
|
203
|
+
/*
|
|
204
|
+
A = user key
|
|
205
|
+
B = hsm key
|
|
206
|
+
C = backup key
|
|
207
|
+
bitgoAddresses = bitgo addresses [ A, B, C ]
|
|
208
|
+
utxo.addresses = IMS addresses [ B, C, A ]
|
|
209
|
+
utxo.addressesIndex = [ 2, 0, 1 ]
|
|
210
|
+
we pick 0, 1 for non-recovery
|
|
211
|
+
we pick 1, 2 for recovery
|
|
212
|
+
*/
|
|
213
|
+
this.transaction._utxos.forEach((utxo) => {
|
|
214
|
+
// in WP, output.addressesIndex is empty, so fill it
|
|
215
|
+
if (!utxo.addressesIndex || utxo.addressesIndex.length === 0) {
|
|
216
|
+
utxo.addressesIndex = bitgoAddresses.map((a) => utxo.addresses.indexOf(a));
|
|
217
|
+
}
|
|
218
|
+
// in OVC, output.addressesIndex is defined correctly from the previous iteration
|
|
219
|
+
});
|
|
220
|
+
// validate the utxos
|
|
221
|
+
this.transaction._utxos.forEach((utxo) => {
|
|
222
|
+
if (!utxo) {
|
|
223
|
+
throw new sdk_core_1.BuildTransactionError('Utxo is undefined');
|
|
224
|
+
}
|
|
225
|
+
// addressesIndex should neve have a mismatch
|
|
226
|
+
if (utxo.addressesIndex?.includes(-1)) {
|
|
227
|
+
throw new sdk_core_1.BuildTransactionError('Addresses are inconsistent');
|
|
228
|
+
}
|
|
229
|
+
if (utxo.threshold !== this.transaction._threshold) {
|
|
230
|
+
throw new sdk_core_1.BuildTransactionError('Threshold is inconsistent');
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
// if we are in OVC, none of the utxos will have addresses since they come from
|
|
234
|
+
// deserialized inputs (which don't have addresses), not the IMS
|
|
235
|
+
const buildOutputs = this.transaction._utxos[0].addresses.length !== 0;
|
|
236
|
+
this.transaction._utxos.forEach((utxo, i) => {
|
|
237
|
+
if (utxo.outputID === iface_1.SECP256K1_Transfer_Output) {
|
|
238
|
+
const txidBuf = utils_1.default.cb58Decode(utxo.txid);
|
|
239
|
+
const amt = new avalanche_1.BN(utxo.amount);
|
|
240
|
+
const outputidx = utils_1.default.outputidxNumberToBuffer(utxo.outputidx);
|
|
241
|
+
const addressesIndex = utxo.addressesIndex ?? [];
|
|
242
|
+
// either user (0) or recovery (2)
|
|
243
|
+
const firstIndex = this.recoverSigner ? 2 : 0;
|
|
244
|
+
const bitgoIndex = 1;
|
|
245
|
+
currentTotal = currentTotal.add(amt);
|
|
246
|
+
const secpTransferInput = new platformvm_1.SECPTransferInput(amt);
|
|
247
|
+
if (!buildOutputs) {
|
|
248
|
+
addressesIndex.forEach((i) => secpTransferInput.addSignatureIdx(i, this.transaction._fromAddresses[i]));
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
// if user/backup > bitgo
|
|
252
|
+
if (addressesIndex[bitgoIndex] < addressesIndex[firstIndex]) {
|
|
253
|
+
secpTransferInput.addSignatureIdx(addressesIndex[bitgoIndex], this.transaction._fromAddresses[bitgoIndex]);
|
|
254
|
+
secpTransferInput.addSignatureIdx(addressesIndex[firstIndex], this.transaction._fromAddresses[firstIndex]);
|
|
255
|
+
credentials.push((0, platformvm_1.SelectCredentialClass)(secpTransferInput.getCredentialID(), // 9
|
|
256
|
+
['', this.transaction._fromAddresses[firstIndex].toString('hex')].map(utils_1.default.createSig)));
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
secpTransferInput.addSignatureIdx(addressesIndex[firstIndex], this.transaction._fromAddresses[firstIndex]);
|
|
260
|
+
secpTransferInput.addSignatureIdx(addressesIndex[bitgoIndex], this.transaction._fromAddresses[bitgoIndex]);
|
|
261
|
+
credentials.push((0, platformvm_1.SelectCredentialClass)(secpTransferInput.getCredentialID(), [this.transaction._fromAddresses[firstIndex].toString('hex'), ''].map(utils_1.default.createSig)));
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
const input = new platformvm_1.TransferableInput(txidBuf, outputidx, this.transaction._assetId, secpTransferInput);
|
|
265
|
+
inputs.push(input);
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
if (buildOutputs) {
|
|
269
|
+
if (currentTotal.lt(totalTarget)) {
|
|
270
|
+
throw new sdk_core_1.BuildTransactionError(`Utxo outputs get ${currentTotal.toString()} and ${totalTarget.toString()} is required`);
|
|
271
|
+
}
|
|
272
|
+
else if (currentTotal.gt(totalTarget)) {
|
|
273
|
+
outputs.push(new platformvm_1.TransferableOutput(this.transaction._assetId, new platformvm_1.SECPTransferOutput(currentTotal.sub(totalTarget), this.transaction._fromAddresses, this.transaction._locktime, this.transaction._threshold)));
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
// get outputs and credentials from the deserialized transaction if we are in OVC
|
|
277
|
+
return {
|
|
278
|
+
inputs,
|
|
279
|
+
outputs: !buildOutputs ? this.transaction.avaxPTransaction.getOuts() : outputs,
|
|
280
|
+
credentials: credentials.length === 0 ? this.transaction.credentials : credentials,
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
exports.DelegatorTxBuilder = DelegatorTxBuilder;
|
|
285
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVsZWdhdG9yVHhCdWlsZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpYi9kZWxlZ2F0b3JUeEJ1aWxkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsbURBQTRGO0FBRTVGLGlGQUE4RTtBQUM5RSwrREFhd0M7QUFDeEMseUNBQXlDO0FBQ3pDLG1DQUFvRjtBQUNwRixvREFBNEI7QUFFNUIsNkNBQXNEO0FBRXRELE1BQWEsa0JBQW1CLFNBQVEsMkRBQTRCO0lBTWxFOzs7T0FHRztJQUNILFlBQVksVUFBZ0M7UUFDMUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ2xCLE1BQU0sT0FBTyxHQUFHLFVBQVUsQ0FBQyxPQUEyQixDQUFDO1FBQ3ZELElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxjQUFFLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQy9DLENBQUM7SUFFRDs7O09BR0c7SUFDSCxJQUFjLGVBQWU7UUFDM0IsT0FBTywwQkFBZSxDQUFDLFlBQVksQ0FBQztJQUN0QyxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsZUFBZSxDQUFDLE9BQTBCO1FBQ3hDLE1BQU0sZUFBZSxHQUFHLE9BQU8sWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUN2RSxJQUFJLENBQUMsV0FBVyxDQUFDLGdCQUFnQixHQUFHLGVBQWUsQ0FBQyxHQUFHLENBQUMsZUFBSyxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQzVFLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVEOzs7T0FHRztJQUNILE1BQU0sQ0FBQyxLQUFhO1FBQ2xCLElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDM0IsSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7UUFDckIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQ7OztPQUdH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QUUsQ0FBQztnQkFDeEMsT0FBTyxDQUFDLElBQUksQ0FDVixJQUFJLCtCQUFrQixDQUNwQixJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFDekIsSUFBSSwrQkFBa0IsQ0FDcEIsWUFBWSxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsRUFDN0IsSUFBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLEVBQy9CLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxFQUMxQixJQUFJLENBQUMsV0FBVyxDQUFDLFVBQVUsQ0FDNUIsQ0FDRixDQUNGLENBQUM7WUFDSixDQUFDO1FBQ0gsQ0FBQztRQUNELGlGQUFpRjtRQUNqRixPQUFPO1lBQ0wsTUFBTTtZQUNOLE9BQU8sRUFBRSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxnQkFBOEIsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTztZQUM3RixXQUFXLEVBQUUsV0FBVyxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxXQUFXO1NBQ25GLENBQUM7SUFDSixDQUFDO0NBQ0Y7QUExV0QsZ0RBMFdDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQnVpbGRUcmFuc2FjdGlvbkVycm9yLCBOb3RTdXBwb3J0ZWQsIFRyYW5zYWN0aW9uVHlwZSB9IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1jb3JlJztcbmltcG9ydCB7IEF2YWxhbmNoZU5ldHdvcmssIEJhc2VDb2luIGFzIENvaW5Db25maWcgfSBmcm9tICdAYml0Z28tYmV0YS9zdGF0aWNzJztcbmltcG9ydCB7IERlcHJlY2F0ZWRUcmFuc2FjdGlvbkJ1aWxkZXIgfSBmcm9tICcuL2RlcHJlY2F0ZWRUcmFuc2FjdGlvbkJ1aWxkZXInO1xuaW1wb3J0IHtcbiAgQWRkRGVsZWdhdG9yVHgsXG4gIEJhc2VUeCBhcyBQVk1CYXNlVHgsXG4gIFBhcnNlYWJsZU91dHB1dCxcbiAgUGxhdGZvcm1WTUNvbnN0YW50cyxcbiAgU0VDUE93bmVyT3V0cHV0LFxuICBTRUNQVHJhbnNmZXJJbnB1dCxcbiAgU0VDUFRyYW5zZmVyT3V0cHV0LFxuICBTZWxlY3RDcmVkZW50aWFsQ2xhc3MsXG4gIFRyYW5zZmVyYWJsZUlucHV0LFxuICBUcmFuc2ZlcmFibGVPdXRwdXQsXG4gIFR4IGFzIFBWTVR4LFxuICBVbnNpZ25lZFR4LFxufSBmcm9tICdhdmFsYW5jaGUvZGlzdC9hcGlzL3BsYXRmb3Jtdm0nO1xuaW1wb3J0IHsgQmluVG9vbHMsIEJOIH0gZnJvbSAnYXZhbGFuY2hlJztcbmltcG9ydCB7IFNFQ1AyNTZLMV9UcmFuc2Zlcl9PdXRwdXQsIERlcHJlY2F0ZWRUeCwgRGVwcmVjYXRlZEJhc2VUeCB9IGZyb20gJy4vaWZhY2UnO1xuaW1wb3J0IHV0aWxzIGZyb20gJy4vdXRpbHMnO1xuaW1wb3J0IHsgQ3JlZGVudGlhbCB9IGZyb20gJ2F2YWxhbmNoZS9kaXN0L2NvbW1vbic7XG5pbXBvcnQgeyBkZXByZWNhdGVkUmVjb3ZlclV0eG9zIH0gZnJvbSAnLi91dHhvRW5naW5lJztcblxuZXhwb3J0IGNsYXNzIERlbGVnYXRvclR4QnVpbGRlciBleHRlbmRzIERlcHJlY2F0ZWRUcmFuc2FjdGlvbkJ1aWxkZXIge1xuICBwcm90ZWN0ZWQgX25vZGVJRDogc3RyaW5nO1xuICBwcm90ZWN0ZWQgX3N0YXJ0VGltZTogQk47XG4gIHByb3RlY3RlZCBfZW5kVGltZTogQk47XG4gIHByb3RlY3RlZCBfc3Rha2VBbW91bnQ6IEJOO1xuXG4gIC8qKlxuICAgKlxuICAgKiBAcGFyYW0gY29pbkNvbmZpZ1xuICAgKi9cbiAgY29uc3RydWN0b3IoY29pbkNvbmZpZzogUmVhZG9ubHk8Q29pbkNvbmZpZz4pIHtcbiAgICBzdXBlcihjb2luQ29uZmlnKTtcbiAgICBjb25zdCBuZXR3b3JrID0gY29pbkNvbmZpZy5uZXR3b3JrIGFzIEF2YWxhbmNoZU5ldHdvcms7XG4gICAgdGhpcy5fc3Rha2VBbW91bnQgPSBuZXcgQk4obmV0d29yay5taW5TdGFrZSk7XG4gIH1cblxuICAvKipcbiAgICogZ2V0IHRyYW5zYWN0aW9uIHR5cGVcbiAgICogQHByb3RlY3RlZFxuICAgKi9cbiAgcHJvdGVjdGVkIGdldCB0cmFuc2FjdGlvblR5cGUoKTogVHJhbnNhY3Rpb25UeXBlIHtcbiAgICByZXR1cm4gVHJhbnNhY3Rpb25UeXBlLkFkZERlbGVnYXRvcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRyZXNzZXMgd2hlcmUgcmV3YXJkIHNob3VsZCBiZSBkZXBvc2l0XG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgc3RyaW5nW119IGFkZHJlc3MgLSBzaW5nbGUgYWRkcmVzcyBvciBhcnJheSBvZiBhZGRyZXNzZXMgdG8gcmVjZWl2ZSByZXdhcmRzXG4gICAqL1xuICByZXdhcmRBZGRyZXNzZXMoYWRkcmVzczogc3RyaW5nIHwgc3RyaW5nW10pOiB0aGlzIHtcbiAgICBjb25zdCByZXdhcmRBZGRyZXNzZXMgPSBhZGRyZXNzIGluc3RhbmNlb2YgQXJyYXkgPyBhZGRyZXNzIDogW2FkZHJlc3NdO1xuICAgIHRoaXMudHJhbnNhY3Rpb24uX3Jld2FyZEFkZHJlc3NlcyA9IHJld2FyZEFkZHJlc3Nlcy5tYXAodXRpbHMucGFyc2VBZGRyZXNzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKlxuICAgKiBAcGFyYW0gbm9kZUlEXG4gICAqL1xuICBub2RlSUQodmFsdWU6IHN0cmluZyk6IHRoaXMge1xuICAgIHRoaXMudmFsaWRhdGVOb2RlSUQodmFsdWUpO1xuICAgIHRoaXMuX25vZGVJRCA9IHZhbHVlO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIHN0YXJ0IHRpbWUgb2Ygc3Rha2luZyBwZXJpb2RcbiAgICogQHBhcmFtIHZhbHVlXG4gICAqL1xuICBzdGFydFRpbWUodmFsdWU6IHN0cmluZyB8IG51bWJlcik6IHRoaXMge1xuICAgIHRoaXMuX3N0YXJ0VGltZSA9IG5ldyBCTih2YWx1ZSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogZW5kIHRpbWUgb2Ygc3Rha2luZyBwZXJpb2RcbiAgICogQHBhcmFtIHZhbHVlXG4gICAqL1xuICBlbmRUaW1lKHZhbHVlOiBzdHJpbmcgfCBudW1iZXIpOiB0aGlzIHtcbiAgICB0aGlzLl9lbmRUaW1lID0gbmV3IEJOKHZhbHVlKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWVcbiAgICovXG4gIHN0YWtlQW1vdW50KHZhbHVlOiBCTiB8IHN0cmluZyk6IHRoaXMge1xuICAgIGNvbnN0IHZhbHVlQk4gPSBCTi5pc0JOKHZhbHVlKSA/IHZhbHVlIDogbmV3IEJOKHZhbHVlKTtcbiAgICB0aGlzLnZhbGlkYXRlU3Rha2VBbW91bnQodmFsdWVCTik7XG4gICAgdGhpcy5fc3Rha2VBbW91bnQgPSB2YWx1ZUJOO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gcmVnaW9uIFZhbGlkYXRvcnNcbiAgLyoqXG4gICAqIHZhbGlkYXRlcyBhIGNvcnJlY3QgTm9kZUlEIGlzIHVzZWRcbiAgICogQHBhcmFtIG5vZGVJRFxuICAgKi9cbiAgdmFsaWRhdGVOb2RlSUQobm9kZUlEOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAoIW5vZGVJRCkge1xuICAgICAgdGhyb3cgbmV3IEJ1aWxkVHJhbnNhY3Rpb25FcnJvcignSW52YWxpZCB0cmFuc2FjdGlvbjogbWlzc2luZyBub2RlSUQnKTtcbiAgICB9XG4gICAgaWYgKG5vZGVJRC5zbGljZSgwLCA2KSAhPT0gJ05vZGVJRCcpIHtcbiAgICAgIHRocm93IG5ldyBCdWlsZFRyYW5zYWN0aW9uRXJyb3IoJ0ludmFsaWQgdHJhbnNhY3Rpb246IGludmFsaWQgTm9kZUlEIHRhZycpO1xuICAgIH1cbiAgICBjb25zdCBiaW50b29scyA9IEJpblRvb2xzLmdldEluc3RhbmNlKCk7XG4gICAgaWYgKCEoYmludG9vbHMuYjU4VG9CdWZmZXIobm9kZUlELnNsaWNlKDcpKS5sZW5ndGggPT09IDI0KSkge1xuICAgICAgdGhyb3cgbmV3IEJ1aWxkVHJhbnNhY3Rpb25FcnJvcignSW52YWxpZCB0cmFuc2FjdGlvbjogTm9kZUlEIGlzIG5vdCBpbiBjYjU4IGZvcm1hdCcpO1xuICAgIH1cbiAgfVxuICAvKipcbiAgICpcbiAgICogICBwcm90ZWN0ZWQgX3N0YXJ0VGltZTogRGF0ZTtcbiAgICogICBwcm90ZWN0ZWQgX2VuZFRpbWU6IERhdGU7XG4gICAqICAgMiB3ZWVrcyA9IDEyMDk2MDBcbiAgICogICAxIHllYXIgPSAzMTU1NjkyNlxuICAgKiAgIHVuaXggdGltZSBzdGFtcCBiYXNlZCBvZmYgc2Vjb25kc1xuICAgKi9cbiAgdmFsaWRhdGVTdGFrZUR1cmF0aW9uKHN0YXJ0VGltZTogQk4sIGVuZFRpbWU6IEJOKTogdm9pZCB7XG4gICAgY29uc3Qgb25lRGF5TGF0ZXIgPSBuZXcgQk4oRGF0ZS5ub3coKSkuYWRkKG5ldyBCTig4NjQwMCkpO1xuICAgIGlmICghc3RhcnRUaW1lLmd0KG9uZURheUxhdGVyKSkge1xuICAgICAgdGhyb3cgbmV3IEJ1aWxkVHJhbnNhY3Rpb25FcnJvcignU3RhcnQgdGltZSBuZWVkcyB0byBiZSBvbmUgZGF5IGdyZWF0ZXIgdGhhbiBjdXJyZW50IHRpbWUnKTtcbiAgICB9XG4gICAgaWYgKGVuZFRpbWUgPCBzdGFydFRpbWUpIHtcbiAgICAgIHRocm93IG5ldyBCdWlsZFRyYW5zYWN0aW9uRXJyb3IoJ0VuZCBkYXRlIGNhbm5vdCBiZSBsZXNzIHRoYW4gc3RhcnQgZGF0ZScpO1xuICAgIH1cbiAgICBpZiAoc3RhcnRUaW1lLmFkZChuZXcgQk4odGhpcy50cmFuc2FjdGlvbi5fbmV0d29yay5taW5TdGFrZUR1cmF0aW9uKSkuZ3QoZW5kVGltZSkpIHtcbiAgICAgIHRocm93IG5ldyBCdWlsZFRyYW5zYWN0aW9uRXJyb3IoJ0VuZCBkYXRlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHR3byB3ZWVrcycpO1xuICAgIH1cbiAgICBpZiAoZW5kVGltZS5ndChzdGFydFRpbWUuYWRkKG5ldyBCTih0aGlzLnRyYW5zYWN0aW9uLl9uZXR3b3JrLm1heFN0YWtlRHVyYXRpb24pKSkpIHtcbiAgICAgIHRocm93IG5ldyBCdWlsZFRyYW5zYWN0aW9uRXJyb3IoJ0VuZCBkYXRlIG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIG9uZSB5ZWFyJyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqXG4gICAqIEBwYXJhbSBhbW91bnRcbiAgICovXG4gIHZhbGlkYXRlU3Rha2VBbW91bnQoYW1vdW50OiBCTik6IHZvaWQge1xuICAgIGNvbnN0IG1pblN0YWtlID0gbmV3IEJOKHRoaXMudHJhbnNhY3Rpb24uX25ldHdvcmsubWluU3Rha2UpO1xuICAgIGlmIChhbW91bnQubHQobWluU3Rha2UpKSB7XG4gICAgICB0aHJvdyBuZXcgQnVpbGRUcmFuc2FjdGlvbkVycm9yKCdNaW5pbXVtIHN0YWtpbmcgYW1vdW50IGlzICcgKyBOdW1iZXIobWluU3Rha2UpIC8gMTAwMDAwMDAwMCArICcgQVZBWC4nKTtcbiAgICB9XG4gIH1cblxuICAvLyBlbmRyZWdpb25cblxuICAvKiogQGluaGVyaXRkb2MgKi9cbiAgaW5pdEJ1aWxkZXIodHg6IERlcHJlY2F0ZWRUeCk6IHRoaXMge1xuICAgIHN1cGVyLmluaXRCdWlsZGVyKHR4KTtcbiAgICBjb25zdCBiYXNlVHg6IERlcHJlY2F0ZWRCYXNlVHggPSB0eC5nZXRVbnNpZ25lZFR4KCkuZ2V0VHJhbnNhY3Rpb24oKTtcbiAgICBpZiAoIXRoaXMudmVyaWZ5VHhUeXBlKGJhc2VUeCkpIHtcbiAgICAgIHRocm93IG5ldyBOb3RTdXBwb3J0ZWQoJ1RyYW5zYWN0aW9uIGNhbm5vdCBiZSBwYXJzZWQgb3IgaGFzIGFuIHVuc3VwcG9ydGVkIHRyYW5zYWN0aW9uIHR5cGUnKTtcbiAgICB9XG4gICAgLy8gVGhlIFN0YWtlT3V0cyBpcyBhIHtAbGluayBzdGFrZVRyYW5zZmVyT3V0fSByZXN1bHQuXG4gICAgLy8gSXQncyBleHBlY3RlZCB0byBoYXZlIG9ubHkgb25lIG91dHB1dHMgd2l0aCB0aGUgYWRkcmVzc2VzIG9mIHRoZSBzZW5kZXIuXG4gICAgY29uc3Qgb3V0cHV0cyA9IGJhc2VUeC5nZXRTdGFrZU91dHMoKTtcbiAgICBpZiAob3V0cHV0cy5sZW5ndGggIT0gMSkge1xuICAgICAgdGhyb3cgbmV3IEJ1aWxkVHJhbnNhY3Rpb25FcnJvcignVHJhbnNhY3Rpb24gY2FuIGhhdmUgb25lIGV4dGVybmFsIG91dHB1dCcpO1xuICAgIH1cbiAgICBjb25zdCBvdXRwdXQgPSBvdXRwdXRzWzBdO1xuICAgIGlmICghb3V0cHV0LmdldEFzc2V0SUQoKS5lcXVhbHModGhpcy50cmFuc2FjdGlvbi5fYXNzZXRJZCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIEFzc2V0IElEIG9mIHRoZSBvdXRwdXQgZG9lcyBub3QgbWF0Y2ggdGhlIHRyYW5zYWN0aW9uJyk7XG4gICAgfVxuICAgIGNvbnN0IHNlY3BPdXQgPSBvdXRwdXQuZ2V0T3V0cHV0KCk7XG4gICAgdGhpcy50cmFuc2FjdGlvbi5fbG9ja3RpbWUgPSBzZWNwT3V0LmdldExvY2t0aW1lKCk7XG4gICAgdGhpcy50cmFuc2FjdGlvbi5fdGhyZXNob2xkID0gc2VjcE91dC5nZXRUaHJlc2hvbGQoKTtcbiAgICAvLyBvdXRwdXQgYWRkcmVzc2VzIGFyZSB0aGUgc2VuZGVyIGFkZHJlc3Nlc1xuICAgIHRoaXMudHJhbnNhY3Rpb24uX2Zyb21BZGRyZXNzZXMgPSBzZWNwT3V0LmdldEFkZHJlc3NlcygpO1xuICAgIHRoaXMuX25vZGVJRCA9IGJhc2VUeC5nZXROb2RlSURTdHJpbmcoKTtcbiAgICB0aGlzLl9zdGFydFRpbWUgPSBiYXNlVHguZ2V0U3RhcnRUaW1lKCk7XG4gICAgdGhpcy5fZW5kVGltZSA9IGJhc2VUeC5nZXRFbmRUaW1lKCk7XG4gICAgdGhpcy5fc3Rha2VBbW91bnQgPSBiYXNlVHguZ2V0U3Rha2VBbW91bnQoKTtcbiAgICB0aGlzLnRyYW5zYWN0aW9uLl91dHhvcyA9IGRlcHJlY2F0ZWRSZWNvdmVyVXR4b3MoYmFzZVR4LmdldElucygpKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHN0YXRpYyB2ZXJpZnlUeFR5cGUoYmFzZVR4OiBEZXByZWNhdGVkQmFzZVR4KTogYmFzZVR4IGlzIEFkZERlbGVnYXRvclR4IHtcbiAgICByZXR1cm4gYmFzZVR4LmdldFR5cGVJRCgpID09PSBQbGF0Zm9ybVZNQ29uc3RhbnRzLkFERFZBTElEQVRPUlRYO1xuICB9XG5cbiAgdmVyaWZ5VHhUeXBlKGJhc2VUeDogRGVwcmVjYXRlZEJhc2VUeCk6IGJhc2VUeCBpcyBBZGREZWxlZ2F0b3JUeCB7XG4gICAgcmV0dXJuIERlbGVnYXRvclR4QnVpbGRlci52ZXJpZnlUeFR5cGUoYmFzZVR4KTtcbiAgfVxuXG4gIC8qKlxuICAgKlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuICBwcm90ZWN0ZWQgYnVpbGRBdmF4VHJhbnNhY3Rpb24oKTogdm9pZCB7XG4gICAgdGhpcy52YWxpZGF0ZVN0YWtlRHVyYXRpb24odGhpcy5fc3RhcnRUaW1lLCB0aGlzLl9lbmRUaW1lKTtcbiAgICBjb25zdCB7IGlucHV0cywgb3V0cHV0cywgY3JlZGVudGlhbHMgfSA9IHRoaXMuY3JlYXRlSW5wdXRPdXRwdXQoKTtcbiAgICB0aGlzLnRyYW5zYWN0aW9uLnNldFRyYW5zYWN0aW9uKFxuICAgICAgbmV3IFBWTVR4KFxuICAgICAgICBuZXcgVW5zaWduZWRUeChcbiAgICAgICAgICBuZXcgQWRkRGVsZWdhdG9yVHgoXG4gICAgICAgICAgICB0aGlzLnRyYW5zYWN0aW9uLl9uZXR3b3JrSUQsXG4gICAgICAgICAgICB0aGlzLnRyYW5zYWN0aW9uLl9ibG9ja2NoYWluSUQsXG4gICAgICAgICAgICBvdXRwdXRzLFxuICAgICAgICAgICAgaW5wdXRzLFxuICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAgdXRpbHMuTm9kZUlEU3RyaW5nVG9CdWZmZXIodGhpcy5fbm9kZUlEKSxcbiAgICAgICAgICAgIHRoaXMuX3N0YXJ0VGltZSxcbiAgICAgICAgICAgIHRoaXMuX2VuZFRpbWUsXG4gICAgICAgICAgICB0aGlzLl9zdGFrZUFtb3VudCxcbiAgICAgICAgICAgIFt0aGlzLnN0YWtlVHJhbnNmZXJPdXQoKV0sXG4gICAgICAgICAgICB0aGlzLnJld2FyZE93bmVyc091dHB1dCgpXG4gICAgICAgICAgKVxuICAgICAgICApLFxuICAgICAgICBjcmVkZW50aWFsc1xuICAgICAgKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIHRoZSBTdGFrZU91dCB3aGVyZSB0aGUgcmVjaXBpZW50IGFkZHJlc3MgYXJlIHRoZSBzZW5kZXIuXG4gICAqIEBwcm90ZWN0ZWRcbiAgICpcbiAgICovXG4gIHByb3RlY3RlZCBzdGFrZVRyYW5zZmVyT3V0KCk6IFRyYW5zZmVyYWJsZU91dHB1dCB7XG4gICAgcmV0dXJuIG5ldyBUcmFuc2ZlcmFibGVPdXRwdXQoXG4gICAgICB0aGlzLnRyYW5zYWN0aW9uLl9hc3NldElkLFxuICAgICAgbmV3IFNFQ1BUcmFuc2Zlck91dHB1dChcbiAgICAgICAgdGhpcy5fc3Rha2VBbW91bnQsXG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb24uX2Zyb21BZGRyZXNzZXMsXG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb24uX2xvY2t0aW1lLFxuICAgICAgICB0aGlzLnRyYW5zYWN0aW9uLl90aHJlc2hvbGRcbiAgICAgIClcbiAgICApO1xuICB9XG5cbiAgcHJvdGVjdGVkIHJld2FyZE93bmVyc091dHB1dCgpOiBQYXJzZWFibGVPdXRwdXQge1xuICAgIC8vIGlmIHRoZXJlIGFyZSBubyByZXdhcmQgYWRkcmVzc2VzLCB0aGUgc2VuZGVyIGdldHMgdGhlIHJld2FyZHNcbiAgICBpZiAoIXRoaXMudHJhbnNhY3Rpb24uX3Jld2FyZEFkZHJlc3NlcyB8fCB0aGlzLnRyYW5zYWN0aW9uLl9yZXdhcmRBZGRyZXNzZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aGlzLnRyYW5zYWN0aW9uLl9yZXdhcmRBZGRyZXNzZXMgPSB0aGlzLnRyYW5zYWN0aW9uLl9mcm9tQWRkcmVzc2VzO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgUGFyc2VhYmxlT3V0cHV0KFxuICAgICAgbmV3IFNFQ1BPd25lck91dHB1dCh0aGlzLnRyYW5zYWN0aW9uLl9yZXdhcmRBZGRyZXNzZXMsIHRoaXMudHJhbnNhY3Rpb24uX2xvY2t0aW1lLCB0aGlzLnRyYW5zYWN0aW9uLl90aHJlc2hvbGQpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaHJlc2hvbGQgbXVzdCBiZSAyIGFuZCBzaW5jZSBvdXRwdXQgYWx3YXlzIGdldCByZW9yZGVyZWQgd2Ugd2FudCB0byBtYWtlIHN1cmUgd2UgY2FuIGFsd2F5cyBhZGQgc2lnbmF0dXJlcyBpbiB0aGUgY29ycmVjdCBsb2NhdGlvblxuICAgKiBUbyBmaW5kIHRoZSBjb3JyZWN0IGxvY2F0aW9uIGZvciB0aGUgc2lnbmF0dXJlLCB3ZSB1c2UgdGhlIG91cHV0J3MgYWRkcmVzc2VzIHRvIGNyZWF0ZSB0aGUgc2lnbmF0dXJlSWR4IGluIHRoZSBvcmRlciB0aGF0IHdlIGRlc2lyZVxuICAgKiAwOiB1c2VyIGtleSwgMTogaHNtIGtleSwgMjogcmVjb3Zlcnkga2V5XG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG4gIHByb3RlY3RlZCBjcmVhdGVJbnB1dE91dHB1dCgpOiB7XG4gICAgaW5wdXRzOiBUcmFuc2ZlcmFibGVJbnB1dFtdO1xuICAgIG91dHB1dHM6IFRyYW5zZmVyYWJsZU91dHB1dFtdO1xuICAgIGNyZWRlbnRpYWxzOiBDcmVkZW50aWFsW107XG4gIH0ge1xuICAgIGNvbnN0IGlucHV0czogVHJhbnNmZXJhYmxlSW5wdXRbXSA9IFtdO1xuICAgIGNvbnN0IG91dHB1dHM6IFRyYW5zZmVyYWJsZU91dHB1dFtdID0gW107XG5cbiAgICAvLyBhbW91bnQgc3BlbnQgc28gZmFyXG4gICAgbGV0IGN1cnJlbnRUb3RhbDogQk4gPSBuZXcgQk4oMCk7XG5cbiAgICAvLyBkZWxlZ2F0aW5nIGFuZCB2YWxpZGF0aW5nIGhhdmUgbm8gZmVlc1xuICAgIGNvbnN0IHRvdGFsVGFyZ2V0ID0gdGhpcy5fc3Rha2VBbW91bnQuY2xvbmUoKTtcblxuICAgIGNvbnN0IGNyZWRlbnRpYWxzOiBDcmVkZW50aWFsW10gPSBbXTtcblxuICAgIC8vIGNvbnZlcnQgZnJvbUFkZHJlc3NlcyB0byBzdHJpbmdcbiAgICAvLyBmcm9tQWRkcmVzc2VzID0gYml0Z28gb3JkZXIgaWYgd2UgYXJlIGluIFdQXG4gICAgLy8gZnJvbUFkZHJlc3NlcyA9IG9uY2hhaW4gb3JkZXIgaWYgd2UgYXJlIGluIGZyb21cbiAgICBjb25zdCBiaXRnb0FkZHJlc3NlcyA9IHRoaXMudHJhbnNhY3Rpb24uX2Zyb21BZGRyZXNzZXMubWFwKChiKSA9PlxuICAgICAgdXRpbHMuYWRkcmVzc1RvU3RyaW5nKHRoaXMudHJhbnNhY3Rpb24uX25ldHdvcmsuaHJwLCB0aGlzLnRyYW5zYWN0aW9uLl9uZXR3b3JrLmFsaWFzLCBiKVxuICAgICk7XG5cbiAgICAvKlxuICAgIEEgPSB1c2VyIGtleVxuICAgIEIgPSBoc20ga2V5XG4gICAgQyA9IGJhY2t1cCBrZXlcbiAgICBiaXRnb0FkZHJlc3NlcyA9IGJpdGdvIGFkZHJlc3NlcyBbIEEsIEIsIEMgXVxuICAgIHV0eG8uYWRkcmVzc2VzID0gSU1TIGFkZHJlc3NlcyBbIEIsIEMsIEEgXVxuICAgIHV0eG8uYWRkcmVzc2VzSW5kZXggPSBbIDIsIDAsIDEgXVxuICAgIHdlIHBpY2sgMCwgMSBmb3Igbm9uLXJlY292ZXJ5XG4gICAgd2UgcGljayAxLCAyIGZvciByZWNvdmVyeVxuICAgICovXG4gICAgdGhpcy50cmFuc2FjdGlvbi5fdXR4b3MuZm9yRWFjaCgodXR4bykgPT4ge1xuICAgICAgLy8gaW4gV1AsIG91dHB1dC5hZGRyZXNzZXNJbmRleCBpcyBlbXB0eSwgc28gZmlsbCBpdFxuICAgICAgaWYgKCF1dHhvLmFkZHJlc3Nlc0luZGV4IHx8IHV0eG8uYWRkcmVzc2VzSW5kZXgubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHV0eG8uYWRkcmVzc2VzSW5kZXggPSBiaXRnb0FkZHJlc3Nlcy5tYXAoKGEpID0+IHV0eG8uYWRkcmVzc2VzLmluZGV4T2YoYSkpO1xuICAgICAgfVxuICAgICAgLy8gaW4gT1ZDLCBvdXRwdXQuYWRkcmVzc2VzSW5kZXggaXMgZGVmaW5lZCBjb3JyZWN0bHkgZnJvbSB0aGUgcHJldmlvdXMgaXRlcmF0aW9uXG4gICAgfSk7XG5cbiAgICAvLyB2YWxpZGF0ZSB0aGUgdXR4b3NcbiAgICB0aGlzLnRyYW5zYWN0aW9uLl91dHhvcy5mb3JFYWNoKCh1dHhvKSA9PiB7XG4gICAgICBpZiAoIXV0eG8pIHtcbiAgICAgICAgdGhyb3cgbmV3IEJ1aWxkVHJhbnNhY3Rpb25FcnJvcignVXR4byBpcyB1bmRlZmluZWQnKTtcbiAgICAgIH1cbiAgICAgIC8vIGFkZHJlc3Nlc0luZGV4IHNob3VsZCBuZXZlIGhhdmUgYSBtaXNtYXRjaFxuICAgICAgaWYgKHV0eG8uYWRkcmVzc2VzSW5kZXg/LmluY2x1ZGVzKC0xKSkge1xuICAgICAgICB0aHJvdyBuZXcgQnVpbGRUcmFuc2FjdGlvbkVycm9yKCdBZGRyZXNzZXMgYXJlIGluY29uc2lzdGVudCcpO1xuICAgICAgfVxuICAgICAgaWYgKHV0eG8udGhyZXNob2xkICE9PSB0aGlzLnRyYW5zYWN0aW9uLl90aHJlc2hvbGQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEJ1aWxkVHJhbnNhY3Rpb25FcnJvcignVGhyZXNob2xkIGlzIGluY29uc2lzdGVudCcpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gaWYgd2UgYXJlIGluIE9WQywgbm9uZSBvZiB0aGUgdXR4b3Mgd2lsbCBoYXZlIGFkZHJlc3NlcyBzaW5jZSB0aGV5IGNvbWUgZnJvbVxuICAgIC8vIGRlc2VyaWFsaXplZCBpbnB1dHMgKHdoaWNoIGRvbid0IGhhdmUgYWRkcmVzc2VzKSwgbm90IHRoZSBJTVNcbiAgICBjb25zdCBidWlsZE91dHB1dHMgPSB0aGlzLnRyYW5zYWN0aW9uLl91dHhvc1swXS5hZGRyZXNzZXMubGVuZ3RoICE9PSAwO1xuXG4gICAgdGhpcy50cmFuc2FjdGlvbi5fdXR4b3MuZm9yRWFjaCgodXR4bywgaSkgPT4ge1xuICAgICAgaWYgKHV0eG8ub3V0cHV0SUQgPT09IFNFQ1AyNTZLMV9UcmFuc2Zlcl9PdXRwdXQpIHtcbiAgICAgICAgY29uc3QgdHhpZEJ1ZiA9IHV0aWxzLmNiNThEZWNvZGUodXR4by50eGlkKTtcbiAgICAgICAgY29uc3QgYW10OiBCTiA9IG5ldyBCTih1dHhvLmFtb3VudCk7XG4gICAgICAgIGNvbnN0IG91dHB1dGlkeCA9IHV0aWxzLm91dHB1dGlkeE51bWJlclRvQnVmZmVyKHV0eG8ub3V0cHV0aWR4KTtcbiAgICAgICAgY29uc3QgYWRkcmVzc2VzSW5kZXggPSB1dHhvLmFkZHJlc3Nlc0luZGV4ID8/IFtdO1xuXG4gICAgICAgIC8vIGVpdGhlciB1c2VyICgwKSBvciByZWNvdmVyeSAoMilcbiAgICAgICAgY29uc3QgZmlyc3RJbmRleCA9IHRoaXMucmVjb3ZlclNpZ25lciA/IDIgOiAwO1xuICAgICAgICBjb25zdCBiaXRnb0luZGV4ID0gMTtcbiAgICAgICAgY3VycmVudFRvdGFsID0gY3VycmVudFRvdGFsLmFkZChhbXQpO1xuXG4gICAgICAgIGNvbnN0IHNlY3BUcmFuc2ZlcklucHV0ID0gbmV3IFNFQ1BUcmFuc2ZlcklucHV0KGFtdCk7XG5cbiAgICAgICAgaWYgKCFidWlsZE91dHB1dHMpIHtcbiAgICAgICAgICBhZGRyZXNzZXNJbmRleC5mb3JFYWNoKChpKSA9PiBzZWNwVHJhbnNmZXJJbnB1dC5hZGRTaWduYXR1cmVJZHgoaSwgdGhpcy50cmFuc2FjdGlvbi5fZnJvbUFkZHJlc3Nlc1tpXSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIGlmIHVzZXIvYmFja3VwID4gYml0Z29cbiAgICAgICAgICBpZiAoYWRkcmVzc2VzSW5kZXhbYml0Z29JbmRleF0gPCBhZGRyZXNzZXNJbmRleFtmaXJzdEluZGV4XSkge1xuICAgICAgICAgICAgc2VjcFRyYW5zZmVySW5wdXQuYWRkU2lnbmF0dXJlSWR4KGFkZHJlc3Nlc0luZGV4W2JpdGdvSW5kZXhdLCB0aGlzLnRyYW5zYWN0aW9uLl9mcm9tQWRkcmVzc2VzW2JpdGdvSW5kZXhdKTtcbiAgICAgICAgICAgIHNlY3BUcmFuc2ZlcklucHV0LmFkZFNpZ25hdHVyZUlkeChhZGRyZXNzZXNJbmRleFtmaXJzdEluZGV4XSwgdGhpcy50cmFuc2FjdGlvbi5fZnJvbUFkZHJlc3Nlc1tmaXJzdEluZGV4XSk7XG4gICAgICAgICAgICBjcmVkZW50aWFscy5wdXNoKFxuICAgICAgICAgICAgICBTZWxlY3RDcmVkZW50aWFsQ2xhc3MoXG4gICAgICAgICAgICAgICAgc2VjcFRyYW5zZmVySW5wdXQuZ2V0Q3JlZGVudGlhbElEKCksIC8vIDlcbiAgICAgICAgICAgICAgICBbJycsIHRoaXMudHJhbnNhY3Rpb24uX2Zyb21BZGRyZXNzZXNbZmlyc3RJbmRleF0udG9TdHJpbmcoJ2hleCcpXS5tYXAodXRpbHMuY3JlYXRlU2lnKVxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzZWNwVHJhbnNmZXJJbnB1dC5hZGRTaWduYXR1cmVJZHgoYWRkcmVzc2VzSW5kZXhbZmlyc3RJbmRleF0sIHRoaXMudHJhbnNhY3Rpb24uX2Zyb21BZGRyZXNzZXNbZmlyc3RJbmRleF0pO1xuICAgICAgICAgICAgc2VjcFRyYW5zZmVySW5wdXQuYWRkU2lnbmF0dXJlSWR4KGFkZHJlc3Nlc0luZGV4W2JpdGdvSW5kZXhdLCB0aGlzLnRyYW5zYWN0aW9uLl9mcm9tQWRkcmVzc2VzW2JpdGdvSW5kZXhdKTtcbiAgICAgICAgICAgIGNyZWRlbnRpYWxzLnB1c2goXG4gICAgICAgICAgICAgIFNlbGVjdENyZWRlbnRpYWxDbGFzcyhcbiAgICAgICAgICAgICAgICBzZWNwVHJhbnNmZXJJbnB1dC5nZXRDcmVkZW50aWFsSUQoKSxcbiAgICAgICAgICAgICAgICBbdGhpcy50cmFuc2FjdGlvbi5fZnJvbUFkZHJlc3Nlc1tmaXJzdEluZGV4XS50b1N0cmluZygnaGV4JyksICcnXS5tYXAodXRpbHMuY3JlYXRlU2lnKVxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGlucHV0OiBUcmFuc2ZlcmFibGVJbnB1dCA9IG5ldyBUcmFuc2ZlcmFibGVJbnB1dChcbiAgICAgICAgICB0eGlkQnVmLFxuICAgICAgICAgIG91dHB1dGlkeCxcbiAgICAgICAgICB0aGlzLnRyYW5zYWN0aW9uLl9hc3NldElkLFxuICAgICAgICAgIHNlY3BUcmFuc2ZlcklucHV0XG4gICAgICAgICk7XG4gICAgICAgIGlucHV0cy5wdXNoKGlucHV0KTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGlmIChidWlsZE91dHB1dHMpIHtcbiAgICAgIGlmIChjdXJyZW50VG90YWwubHQodG90YWxUYXJnZXQpKSB7XG4gICAgICAgIHRocm93IG5ldyBCdWlsZFRyYW5zYWN0aW9uRXJyb3IoXG4gICAgICAgICAgYFV0eG8gb3V0cHV0cyBnZXQgJHtjdXJyZW50VG90YWwudG9TdHJpbmcoKX0gYW5kICR7dG90YWxUYXJnZXQudG9TdHJpbmcoKX0gaXMgcmVxdWlyZWRgXG4gICAgICAgICk7XG4gICAgICB9IGVsc2UgaWYgKGN1cnJlbnRUb3RhbC5ndCh0b3RhbFRhcmdldCkpIHtcbiAgICAgICAgb3V0cHV0cy5wdXNoKFxuICAgICAgICAgIG5ldyBUcmFuc2ZlcmFibGVPdXRwdXQoXG4gICAgICAgICAgICB0aGlzLnRyYW5zYWN0aW9uLl9hc3NldElkLFxuICAgICAgICAgICAgbmV3IFNFQ1BUcmFuc2Zlck91dHB1dChcbiAgICAgICAgICAgICAgY3VycmVudFRvdGFsLnN1Yih0b3RhbFRhcmdldCksXG4gICAgICAgICAgICAgIHRoaXMudHJhbnNhY3Rpb24uX2Zyb21BZGRyZXNzZXMsXG4gICAgICAgICAgICAgIHRoaXMudHJhbnNhY3Rpb24uX2xvY2t0aW1lLFxuICAgICAgICAgICAgICB0aGlzLnRyYW5zYWN0aW9uLl90aHJlc2hvbGRcbiAgICAgICAgICAgIClcbiAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIGdldCBvdXRwdXRzIGFuZCBjcmVkZW50aWFscyBmcm9tIHRoZSBkZXNlcmlhbGl6ZWQgdHJhbnNhY3Rpb24gaWYgd2UgYXJlIGluIE9WQ1xuICAgIHJldHVybiB7XG4gICAgICBpbnB1dHMsXG4gICAgICBvdXRwdXRzOiAhYnVpbGRPdXRwdXRzID8gKHRoaXMudHJhbnNhY3Rpb24uYXZheFBUcmFuc2FjdGlvbiBhcyBQVk1CYXNlVHgpLmdldE91dHMoKSA6IG91dHB1dHMsXG4gICAgICBjcmVkZW50aWFsczogY3JlZGVudGlhbHMubGVuZ3RoID09PSAwID8gdGhpcy50cmFuc2FjdGlvbi5jcmVkZW50aWFscyA6IGNyZWRlbnRpYWxzLFxuICAgIH07XG4gIH1cbn1cbiJdfQ==
|