@bitgo-beta/sdk-coin-eth 4.4.1-beta.182 → 4.4.1-beta.1821
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/erc20Token.d.ts +1 -1
- package/dist/src/erc20Token.d.ts.map +1 -1
- package/dist/src/erc20Token.js +49 -28
- package/dist/src/erc721Token.d.ts +60 -0
- package/dist/src/erc721Token.d.ts.map +1 -0
- package/dist/src/erc721Token.js +334 -0
- package/dist/src/erc7984Token.d.ts +94 -0
- package/dist/src/erc7984Token.d.ts.map +1 -0
- package/dist/src/erc7984Token.js +328 -0
- package/dist/src/eth.d.ts +10 -8
- package/dist/src/eth.d.ts.map +1 -1
- package/dist/src/eth.js +49 -35
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +8 -2
- package/dist/src/lib/index.d.ts +1 -0
- package/dist/src/lib/index.d.ts.map +1 -1
- package/dist/src/lib/index.js +7 -2
- package/dist/src/lib/messages/index.d.ts +3 -0
- package/dist/src/lib/messages/index.d.ts.map +1 -0
- package/dist/src/lib/messages/index.js +6 -0
- package/dist/src/lib/transactionBuilder.d.ts +10 -5
- package/dist/src/lib/transactionBuilder.d.ts.map +1 -1
- package/dist/src/lib/transactionBuilder.js +17 -7
- package/dist/src/lib/transferBuilders/index.d.ts +2 -2
- package/dist/src/lib/transferBuilders/index.d.ts.map +1 -1
- package/dist/src/lib/transferBuilders/index.js +3 -2
- package/dist/src/register.d.ts +2 -0
- package/dist/src/register.d.ts.map +1 -1
- package/dist/src/register.js +36 -2
- package/dist/test/fixtures/eth.d.ts +39 -0
- package/dist/test/fixtures/eth.d.ts.map +1 -0
- package/dist/test/fixtures/eth.js +262 -0
- package/dist/test/resources/erc1155Abi.d.ts +40 -0
- package/dist/test/resources/erc1155Abi.d.ts.map +1 -0
- package/dist/test/resources/erc1155Abi.js +329 -0
- package/dist/test/resources/erc721Abi.d.ts +12 -0
- package/dist/test/resources/erc721Abi.d.ts.map +1 -0
- package/dist/test/resources/erc721Abi.js +34 -0
- package/dist/test/resources/eth.d.ts +51 -0
- package/dist/test/resources/eth.d.ts.map +1 -0
- package/dist/test/resources/eth.js +72 -0
- package/dist/test/resources/nftEncodings.d.ts +4 -0
- package/dist/test/resources/nftEncodings.d.ts.map +1 -0
- package/dist/test/resources/nftEncodings.js +7 -0
- package/dist/test/resources/walletSimpleAbi.d.ts +12 -0
- package/dist/test/resources/walletSimpleAbi.d.ts.map +1 -0
- package/dist/test/resources/walletSimpleAbi.js +44 -0
- package/dist/test/unit/erc7984Token.d.ts +2 -0
- package/dist/test/unit/erc7984Token.d.ts.map +1 -0
- package/dist/test/unit/erc7984Token.js +743 -0
- package/dist/test/unit/eth.d.ts +2 -0
- package/dist/test/unit/eth.d.ts.map +1 -0
- package/dist/test/unit/eth.js +2442 -0
- package/dist/test/unit/ethWallet.d.ts +2 -0
- package/dist/test/unit/ethWallet.d.ts.map +1 -0
- package/dist/test/unit/ethWallet.js +472 -0
- package/dist/test/unit/fixtures/ethMultiSigBackupKey.d.ts +4 -0
- package/dist/test/unit/fixtures/ethMultiSigBackupKey.d.ts.map +1 -0
- package/dist/test/unit/fixtures/ethMultiSigBackupKey.js +10 -0
- package/dist/test/unit/fixtures/ethTssBackupKey.d.ts +5 -0
- package/dist/test/unit/fixtures/ethTssBackupKey.d.ts.map +1 -0
- package/dist/test/unit/fixtures/ethTssBackupKey.js +25 -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/keyPair.d.ts +2 -0
- package/dist/test/unit/keyPair.d.ts.map +1 -0
- package/dist/test/unit/keyPair.js +175 -0
- package/dist/test/unit/register.d.ts +2 -0
- package/dist/test/unit/register.d.ts.map +1 -0
- package/dist/test/unit/register.js +73 -0
- package/dist/test/unit/transaction.d.ts +2 -0
- package/dist/test/unit/transaction.d.ts.map +1 -0
- package/dist/test/unit/transaction.js +117 -0
- package/dist/test/unit/transactionBuilder/addressInitialization.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/addressInitialization.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/addressInitialization.js +101 -0
- package/dist/test/unit/transactionBuilder/contractCall.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/contractCall.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/contractCall.js +101 -0
- package/dist/test/unit/transactionBuilder/decryptionDelegation.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/decryptionDelegation.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/decryptionDelegation.js +59 -0
- package/dist/test/unit/transactionBuilder/decryptionDelegationTxBuilder.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/decryptionDelegationTxBuilder.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/decryptionDelegationTxBuilder.js +136 -0
- package/dist/test/unit/transactionBuilder/flushCoins.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/flushCoins.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/flushCoins.js +133 -0
- package/dist/test/unit/transactionBuilder/flushTokens.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/flushTokens.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/flushTokens.js +281 -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 +331 -0
- package/dist/test/unit/transactionBuilder/sendERC7984Token.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/sendERC7984Token.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/sendERC7984Token.js +361 -0
- package/dist/test/unit/transactionBuilder/sendNFT.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/sendNFT.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/sendNFT.js +295 -0
- package/dist/test/unit/transactionBuilder/singleSigSend.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/singleSigSend.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/singleSigSend.js +196 -0
- package/dist/test/unit/transactionBuilder/walletInitialization.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/walletInitialization.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/walletInitialization.js +436 -0
- package/dist/test/unit/transferBuilder.d.ts +2 -0
- package/dist/test/unit/transferBuilder.d.ts.map +1 -0
- package/dist/test/unit/transferBuilder.js +124 -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 +74 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +17 -13
- package/.eslintignore +0 -5
- package/.mocharc.yml +0 -8
- package/CHANGELOG.md +0 -609
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ethWallet.d.ts","sourceRoot":"","sources":["../../../test/unit/ethWallet.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,472 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
const should_1 = __importDefault(require("should"));
|
|
40
|
+
const secp256k1_1 = require("@bitgo-beta/secp256k1");
|
|
41
|
+
const secp256k1 = __importStar(require("secp256k1"));
|
|
42
|
+
const nock_1 = __importDefault(require("nock"));
|
|
43
|
+
const sinon_1 = __importDefault(require("sinon"));
|
|
44
|
+
const sdk_core_1 = require("@bitgo-beta/sdk-core");
|
|
45
|
+
const sdk_test_1 = require("@bitgo-beta/sdk-test");
|
|
46
|
+
const tx_1 = require("@ethereumjs/tx");
|
|
47
|
+
const fixtures = require('../fixtures/eth');
|
|
48
|
+
const sdk_api_1 = require("@bitgo-beta/sdk-api");
|
|
49
|
+
const src_1 = require("../../src");
|
|
50
|
+
const getBuilder_1 = require("./getBuilder");
|
|
51
|
+
describe('Sign ETH Transaction', async function () {
|
|
52
|
+
let bitgo;
|
|
53
|
+
let ethWallet;
|
|
54
|
+
let recipients;
|
|
55
|
+
let tx;
|
|
56
|
+
before(function () {
|
|
57
|
+
bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'test' });
|
|
58
|
+
bitgo.initializeTestVars();
|
|
59
|
+
bitgo.safeRegister('teth', src_1.Teth.createInstance);
|
|
60
|
+
const coin = bitgo.coin('teth');
|
|
61
|
+
ethWallet = coin.newWalletObject({});
|
|
62
|
+
recipients = [
|
|
63
|
+
{
|
|
64
|
+
address: '0xe59dfe5c67114b39a5662cc856be536c614124c0',
|
|
65
|
+
amount: '100000',
|
|
66
|
+
},
|
|
67
|
+
];
|
|
68
|
+
tx = { recipients, nextContractSequenceId: 0 };
|
|
69
|
+
});
|
|
70
|
+
it('should read transaction recipients from txPrebuild even if none are specified as top-level params', async function () {
|
|
71
|
+
sinon_1.default.stub(sdk_core_1.Util, 'xprvToEthPrivateKey');
|
|
72
|
+
sinon_1.default.stub(sdk_core_1.Util, 'ethSignMsgHash');
|
|
73
|
+
sinon_1.default.stub(ethWallet.getOperationSha3ForExecuteAndConfirm);
|
|
74
|
+
const { halfSigned } = (await ethWallet.signTransaction({ txPrebuild: tx, prv: 'my_user_prv' }));
|
|
75
|
+
halfSigned.should.have.property('recipients', recipients);
|
|
76
|
+
sinon_1.default.restore();
|
|
77
|
+
});
|
|
78
|
+
it('should throw an error if no recipients are in the txPrebuild and none are specified as params', async function () {
|
|
79
|
+
await ethWallet
|
|
80
|
+
.signTransaction({ txPrebuild: {}, prv: 'my_user_prv' })
|
|
81
|
+
.should.be.rejectedWith('recipients missing or not array');
|
|
82
|
+
});
|
|
83
|
+
it('should throw an error if the recipients param is not an array', async function () {
|
|
84
|
+
await ethWallet
|
|
85
|
+
.signTransaction({ txPrebuild: { recipients: 'not-array' }, prv: 'my_user_prv' })
|
|
86
|
+
.should.be.rejectedWith('recipients missing or not array');
|
|
87
|
+
});
|
|
88
|
+
it('should set isBatch to false if single recipient', async function () {
|
|
89
|
+
sinon_1.default.stub(sdk_core_1.Util, 'xprvToEthPrivateKey');
|
|
90
|
+
sinon_1.default.stub(sdk_core_1.Util, 'ethSignMsgHash');
|
|
91
|
+
sinon_1.default.stub(ethWallet.getOperationSha3ForExecuteAndConfirm);
|
|
92
|
+
const singleRecipientsTx = { recipients: recipients, nextContractSequenceId: 0, isBatch: false };
|
|
93
|
+
const { halfSigned } = (await ethWallet.signTransaction({
|
|
94
|
+
txPrebuild: singleRecipientsTx,
|
|
95
|
+
prv: 'my_user_prv',
|
|
96
|
+
}));
|
|
97
|
+
halfSigned.should.have.property('recipients', recipients);
|
|
98
|
+
halfSigned.should.have.property('isBatch', false);
|
|
99
|
+
sinon_1.default.restore();
|
|
100
|
+
});
|
|
101
|
+
it('should set isBatch to true if multiple recipients', async function () {
|
|
102
|
+
const multipleRecipients = [
|
|
103
|
+
{
|
|
104
|
+
address: '0x0c7f3bc5d2b2c0dbee1b45536b82569f41b54331',
|
|
105
|
+
amount: '200',
|
|
106
|
+
data: '0xcf4c58e2000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000431745b89e73230b3bc8a19e019194efb4b99efd000000000000000000000000431745b89e73230b3bc8a19e019194efb4b99efd000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000064',
|
|
107
|
+
},
|
|
108
|
+
];
|
|
109
|
+
const multipleRecipientsTx = { recipients: multipleRecipients, nextContractSequenceId: 0, isBatch: true };
|
|
110
|
+
sinon_1.default.stub(sdk_core_1.Util, 'xprvToEthPrivateKey');
|
|
111
|
+
sinon_1.default.stub(sdk_core_1.Util, 'ethSignMsgHash');
|
|
112
|
+
sinon_1.default.stub(ethWallet.getOperationSha3ForExecuteAndConfirm);
|
|
113
|
+
const { halfSigned } = (await ethWallet.signTransaction({
|
|
114
|
+
txPrebuild: multipleRecipientsTx,
|
|
115
|
+
prv: 'my_user_prv',
|
|
116
|
+
}));
|
|
117
|
+
halfSigned.should.have.property('isBatch', true);
|
|
118
|
+
sinon_1.default.restore();
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
describe('Ethereum Hop Transactions', function () {
|
|
122
|
+
let bitgo;
|
|
123
|
+
let ethWallet;
|
|
124
|
+
let tx;
|
|
125
|
+
let txid;
|
|
126
|
+
let bitgoSignature;
|
|
127
|
+
let bitgoKeyXprv;
|
|
128
|
+
let bgUrl;
|
|
129
|
+
let env;
|
|
130
|
+
const userKeypair = {
|
|
131
|
+
xprv: 'xprv9s21ZrQH143K2fJ91S4BRsupcYrE6mmY96fcX5HkhoTrrwmwjd16Cn87cWinJjByrfpojjx7ezsJLx7TAKLT8m8hM5Kax9YcoxnBeJZ3t2k',
|
|
132
|
+
xpub: 'xpub661MyMwAqRbcF9Nc7TbBo1rZAagiWEVPWKbDKThNG8zqjk76HAKLkaSbTn6dK2dQPfuD7xjicxCZVWvj67fP5nQ9W7QURmoMVAX8m6jZsGp',
|
|
133
|
+
rawPub: '02c103ac74481874b5ef0f385d12725e4f14aedc9e00bc814ce96f47f62ce7adf2',
|
|
134
|
+
rawPrv: '936c5af3f8af81f75cdad1b08f29e7d9c01e598e2db2d7be18b9e5a8646e87c6',
|
|
135
|
+
path: 'm',
|
|
136
|
+
walletSubPath: '/0/0',
|
|
137
|
+
};
|
|
138
|
+
before(function () {
|
|
139
|
+
tx =
|
|
140
|
+
'0xf86c82015285012a05f200825208945208d8e80c6d1aef9be37b4bd19a9cf75ed93dc886b5e620f480008026a00e13f9e0e11337b2b0227e3412211d3625e43f1083fda399cc361dd4bf89083ba06c801a761e0aa3bc8db0ac2568d575b0fb306a1f04f4d5ba82ba3cc0ea0a83bd';
|
|
141
|
+
txid = '0x0ac669c5fef8294443c75a31e32c44b97bbc9e43a18ea8beabcc2a3b45eb6ffa';
|
|
142
|
+
bitgoKeyXprv =
|
|
143
|
+
'xprv9s21ZrQH143K3tpWBHWe31sLoXNRQ9AvRYJgitkKxQ4ATFQMwvr7hHNqYRUnS7PsjzB7aK1VxqHLuNQjj1sckJ2Jwo2qxmsvejwECSpFMfC';
|
|
144
|
+
const bitgoKey = secp256k1_1.bip32.fromBase58(bitgoKeyXprv);
|
|
145
|
+
if (!bitgoKey.privateKey) {
|
|
146
|
+
throw new Error('no privateKey');
|
|
147
|
+
}
|
|
148
|
+
const bitgoXpub = bitgoKey.neutered().toBase58();
|
|
149
|
+
bitgoSignature =
|
|
150
|
+
'0xaa' +
|
|
151
|
+
Buffer.from(secp256k1.ecdsaSign(Buffer.from(txid.slice(2), 'hex'), bitgoKey.privateKey).signature).toString('hex');
|
|
152
|
+
env = 'test';
|
|
153
|
+
bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env });
|
|
154
|
+
bitgo.safeRegister('teth', src_1.Teth.createInstance);
|
|
155
|
+
sdk_core_1.common.Environments[env].hsmXpub = bitgoXpub;
|
|
156
|
+
bitgo.initializeTestVars();
|
|
157
|
+
bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
|
|
158
|
+
const coin = bitgo.coin('teth');
|
|
159
|
+
ethWallet = coin.newWalletObject({ keys: ['user', 'backup', 'bitgo'] });
|
|
160
|
+
});
|
|
161
|
+
describe('Verify HSM Hop prebuild', function () {
|
|
162
|
+
let prebuild;
|
|
163
|
+
let buildParams;
|
|
164
|
+
let finalRecipient;
|
|
165
|
+
let sendAmount;
|
|
166
|
+
before(function () {
|
|
167
|
+
finalRecipient = '0x5208d8e80c6d1aef9be37b4bd19a9cf75ed93dc8';
|
|
168
|
+
sendAmount = '200000000000000';
|
|
169
|
+
prebuild = {
|
|
170
|
+
tx,
|
|
171
|
+
id: txid,
|
|
172
|
+
signature: bitgoSignature,
|
|
173
|
+
};
|
|
174
|
+
buildParams = {
|
|
175
|
+
recipients: [
|
|
176
|
+
{
|
|
177
|
+
address: finalRecipient,
|
|
178
|
+
amount: sendAmount,
|
|
179
|
+
},
|
|
180
|
+
],
|
|
181
|
+
};
|
|
182
|
+
});
|
|
183
|
+
it('should accept a valid hop prebuild', async function () {
|
|
184
|
+
await ethWallet.baseCoin.validateHopPrebuild(ethWallet, prebuild, buildParams).should.be.resolved();
|
|
185
|
+
});
|
|
186
|
+
it('should fail if the HSM prebuild recipient is wrong', async function () {
|
|
187
|
+
const badBuildParams = JSON.parse(JSON.stringify(buildParams));
|
|
188
|
+
badBuildParams.recipients[0].address = '0x54bf1609aeed804aa231f08c53dbb18f7d374615';
|
|
189
|
+
await ethWallet.baseCoin
|
|
190
|
+
.validateHopPrebuild(ethWallet, prebuild, badBuildParams)
|
|
191
|
+
.should.be.rejectedWith(/does not equal original recipient/);
|
|
192
|
+
});
|
|
193
|
+
it('should fail if the HSM prebuild tx amount is wrong', async function () {
|
|
194
|
+
const badBuildParams = JSON.parse(JSON.stringify(buildParams));
|
|
195
|
+
badBuildParams.recipients[0].amount = '50000000';
|
|
196
|
+
await ethWallet.baseCoin
|
|
197
|
+
.validateHopPrebuild(ethWallet, prebuild, badBuildParams)
|
|
198
|
+
.should.be.rejectedWith(/does not equal original amount/);
|
|
199
|
+
});
|
|
200
|
+
it('should fail if the HSM signature is invalid', async function () {
|
|
201
|
+
// Mocking a different BitGo key means the signing key should be wrong (it maps to a different address than this xpub)
|
|
202
|
+
const goodXpub = sdk_core_1.common.Environments[env].hsmXpub;
|
|
203
|
+
sdk_core_1.common.Environments[env].hsmXpub =
|
|
204
|
+
'xpub661MyMwAqRbcErFqVXGiUFv9YeoPbhN72UiNCUdj9nj3T6M8h7iKNmbCYpMVWVZP7LA2ma3HWcPngz1gRTm4FPdtm9mHfrNvU93MCoszsGL';
|
|
205
|
+
await ethWallet.baseCoin
|
|
206
|
+
.validateHopPrebuild(ethWallet, prebuild, buildParams)
|
|
207
|
+
.should.be.rejectedWith(/Hop txid signature invalid/);
|
|
208
|
+
sdk_core_1.common.Environments[env].hsmXpub = goodXpub;
|
|
209
|
+
});
|
|
210
|
+
it('should fail if the HSM signature signed the wrong HSM commitment digest', async function () {
|
|
211
|
+
const badTxid = '0xb4b3827a529c9166786e796528017889ac5027255b65b3fa2a3d3ad91244a12b';
|
|
212
|
+
const badTxidBuffer = Buffer.from(badTxid.slice(2), 'hex');
|
|
213
|
+
const xprvNode = secp256k1_1.bip32.fromBase58(bitgoKeyXprv);
|
|
214
|
+
if (!xprvNode.privateKey) {
|
|
215
|
+
throw new Error('no privateKey');
|
|
216
|
+
}
|
|
217
|
+
const badSignature = '0xaa' + Buffer.from(secp256k1.ecdsaSign(badTxidBuffer, xprvNode.privateKey).signature).toString('hex');
|
|
218
|
+
const badPrebuild = JSON.parse(JSON.stringify(prebuild));
|
|
219
|
+
badPrebuild.signature = badSignature;
|
|
220
|
+
await ethWallet.baseCoin
|
|
221
|
+
.validateHopPrebuild(ethWallet, badPrebuild, buildParams)
|
|
222
|
+
.should.be.rejectedWith(/Hop txid signature invalid/);
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
describe('Prebuild hop transaction', function () {
|
|
226
|
+
let prebuild;
|
|
227
|
+
let buildParams;
|
|
228
|
+
let finalRecipient;
|
|
229
|
+
let sendAmount;
|
|
230
|
+
let gasLimitEstimate;
|
|
231
|
+
let gasPrice;
|
|
232
|
+
const nockUserKey = function () {
|
|
233
|
+
(0, nock_1.default)(bgUrl)
|
|
234
|
+
.get(`/api/v2/teth/key/user`)
|
|
235
|
+
.reply(200, {
|
|
236
|
+
encryptedPrv: bitgo.encrypt({ input: userKeypair.xprv, password: sdk_test_1.TestBitGo.TEST_WALLET1_PASSCODE }),
|
|
237
|
+
path: userKeypair.path + userKeypair.walletSubPath,
|
|
238
|
+
});
|
|
239
|
+
};
|
|
240
|
+
const nockFees = function () {
|
|
241
|
+
const scope = (0, nock_1.default)(bgUrl)
|
|
242
|
+
.get('/api/v2/teth/tx/fee')
|
|
243
|
+
.query(true)
|
|
244
|
+
.reply(200, {
|
|
245
|
+
gasLimitEstimate: gasLimitEstimate,
|
|
246
|
+
feeEstimate: gasLimitEstimate * gasPrice,
|
|
247
|
+
});
|
|
248
|
+
return scope;
|
|
249
|
+
};
|
|
250
|
+
const nockBuild = function (walletId) {
|
|
251
|
+
(0, nock_1.default)(bgUrl)
|
|
252
|
+
.post('/api/v2/teth/wallet/' + walletId + '/tx/build')
|
|
253
|
+
.reply(200, { hopTransaction: prebuild, buildParams });
|
|
254
|
+
};
|
|
255
|
+
before(function () {
|
|
256
|
+
gasLimitEstimate = 100000;
|
|
257
|
+
gasPrice = 50000000;
|
|
258
|
+
finalRecipient = '0x5208d8e80c6d1aef9be37b4bd19a9cf75ed93dc8';
|
|
259
|
+
sendAmount = '200000000000000';
|
|
260
|
+
prebuild = {
|
|
261
|
+
tx,
|
|
262
|
+
id: txid,
|
|
263
|
+
signature: bitgoSignature,
|
|
264
|
+
};
|
|
265
|
+
buildParams = {
|
|
266
|
+
recipients: [
|
|
267
|
+
{
|
|
268
|
+
address: finalRecipient,
|
|
269
|
+
amount: sendAmount,
|
|
270
|
+
},
|
|
271
|
+
],
|
|
272
|
+
hop: true,
|
|
273
|
+
walletPassphrase: sdk_test_1.TestBitGo.TEST_WALLET1_PASSCODE,
|
|
274
|
+
};
|
|
275
|
+
});
|
|
276
|
+
it('should prebuild a hop transaction if given the correct args', async function () {
|
|
277
|
+
nockUserKey();
|
|
278
|
+
const feeScope = nockFees();
|
|
279
|
+
nockBuild(ethWallet.id());
|
|
280
|
+
const res = (await ethWallet.prebuildTransaction(buildParams));
|
|
281
|
+
should_1.default.exist(res.hopTransaction);
|
|
282
|
+
should_1.default.exist(res.hopTransaction.tx);
|
|
283
|
+
should_1.default.exist(res.hopTransaction.tx);
|
|
284
|
+
should_1.default.exist(res.hopTransaction.id);
|
|
285
|
+
should_1.default.exist(res.hopTransaction.signature);
|
|
286
|
+
should_1.default.not.exist(res.wallet);
|
|
287
|
+
should_1.default.not.exist(res.buildParams);
|
|
288
|
+
feeScope.isDone().should.equal(true);
|
|
289
|
+
const feeReq = feeScope.interceptors[0].req;
|
|
290
|
+
feeReq.path.should.containEql('hop=true');
|
|
291
|
+
feeReq.path.should.containEql('recipient=' + finalRecipient);
|
|
292
|
+
feeReq.path.should.containEql('amount=' + sendAmount);
|
|
293
|
+
});
|
|
294
|
+
});
|
|
295
|
+
});
|
|
296
|
+
describe('Add final signature to ETH tx from offline vault', function () {
|
|
297
|
+
let paramsFromVault, expectedResult, bitgo, coin;
|
|
298
|
+
before(function () {
|
|
299
|
+
const vals = fixtures.getHalfSignedTethFromVault();
|
|
300
|
+
paramsFromVault = vals.paramsFromVault;
|
|
301
|
+
expectedResult = vals.expectedResult;
|
|
302
|
+
bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'test' });
|
|
303
|
+
coin = bitgo.coin('teth');
|
|
304
|
+
});
|
|
305
|
+
it('should successfully fully sign a half-signed transaction from the offline vault', async function () {
|
|
306
|
+
const response = (await coin.signTransaction(paramsFromVault));
|
|
307
|
+
const expectedTx = tx_1.Transaction.fromSerializedTx(Buffer.from(expectedResult.txHex, 'hex'));
|
|
308
|
+
const actualTx = tx_1.Transaction.fromSerializedTx(Buffer.from(response.txHex, 'hex'));
|
|
309
|
+
actualTx.nonce.toString().should.deepEqual(expectedTx.nonce.toString());
|
|
310
|
+
should_1.default.exist(actualTx.to);
|
|
311
|
+
actualTx.to?.should.deepEqual(expectedTx.to);
|
|
312
|
+
actualTx.value.should.deepEqual(expectedTx.value);
|
|
313
|
+
actualTx.data.should.deepEqual(expectedTx.data);
|
|
314
|
+
actualTx.isSigned().should.equal(true);
|
|
315
|
+
actualTx.supports(tx_1.Capability.EIP155ReplayProtection).should.equal(false);
|
|
316
|
+
actualTx.verifySignature().should.equal(true);
|
|
317
|
+
should_1.default.exist(actualTx.v);
|
|
318
|
+
actualTx?.v?.toString().should.deepEqual(expectedTx?.v?.toString());
|
|
319
|
+
actualTx?.r?.toString().should.deepEqual(expectedTx?.r?.toString());
|
|
320
|
+
actualTx?.s?.toString().should.deepEqual(expectedTx?.s?.toString());
|
|
321
|
+
actualTx.gasPrice.toString().should.deepEqual(expectedTx.gasPrice.toString());
|
|
322
|
+
actualTx.gasLimit.toString().should.deepEqual(expectedTx.gasLimit.toString());
|
|
323
|
+
response.txHex.toString().should.equal(expectedResult.txHex.toString());
|
|
324
|
+
});
|
|
325
|
+
});
|
|
326
|
+
describe('Add signature to EIP1559 tx from offline vault', function () {
|
|
327
|
+
let bitgo;
|
|
328
|
+
let paramsFromVault, expectedResult, coin;
|
|
329
|
+
before(function () {
|
|
330
|
+
const vals = fixtures.getUnsignedEip1559TethFromVault();
|
|
331
|
+
paramsFromVault = vals.paramsFromVault;
|
|
332
|
+
expectedResult = vals.expectedResult;
|
|
333
|
+
bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'test' });
|
|
334
|
+
bitgo.safeRegister('teth', src_1.Teth.createInstance);
|
|
335
|
+
coin = bitgo.coin('teth');
|
|
336
|
+
});
|
|
337
|
+
it('should successfully sign an unsigned transaction from the offline vault', async function* () {
|
|
338
|
+
const response = await coin.signTransaction(paramsFromVault);
|
|
339
|
+
should_1.default.exist(response.halfSigned);
|
|
340
|
+
response.halfSigned.eip1559.should.deepEqual(expectedResult.halfSigned.eip1559);
|
|
341
|
+
response.halfSigned.recipients.should.deepEqual(expectedResult.halfSigned.recipients);
|
|
342
|
+
});
|
|
343
|
+
});
|
|
344
|
+
describe('prebuildTransaction', function () {
|
|
345
|
+
let bitgo;
|
|
346
|
+
let ethWallet;
|
|
347
|
+
let recipients;
|
|
348
|
+
let bgUrl;
|
|
349
|
+
let gasLimit;
|
|
350
|
+
before(function () {
|
|
351
|
+
bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'test' });
|
|
352
|
+
src_1.Erc20Token.createTokenConstructors().forEach(({ name, coinConstructor }) => {
|
|
353
|
+
bitgo.safeRegister(name, coinConstructor);
|
|
354
|
+
});
|
|
355
|
+
bitgo.safeRegister('teth', src_1.Teth.createInstance);
|
|
356
|
+
bitgo.initializeTestVars();
|
|
357
|
+
const coin = bitgo.coin('teth');
|
|
358
|
+
ethWallet = coin.newWalletObject({});
|
|
359
|
+
gasLimit = 2100000;
|
|
360
|
+
recipients = [
|
|
361
|
+
{
|
|
362
|
+
address: '0xe59dfe5c67114b39a5662cc856be536c614124c0',
|
|
363
|
+
amount: '100000',
|
|
364
|
+
},
|
|
365
|
+
];
|
|
366
|
+
bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
|
|
367
|
+
});
|
|
368
|
+
it('should successfully accept gasLimit as a param', async function () {
|
|
369
|
+
const scope = (0, nock_1.default)(bgUrl)
|
|
370
|
+
.post('/api/v2/teth/wallet/' + ethWallet.id() + '/tx/build', {
|
|
371
|
+
recipients,
|
|
372
|
+
gasLimit,
|
|
373
|
+
})
|
|
374
|
+
.reply(200, { success: true });
|
|
375
|
+
const prebuild = await ethWallet.prebuildTransaction({ recipients, gasLimit });
|
|
376
|
+
scope.isDone().should.equal(true);
|
|
377
|
+
prebuild.success.should.equal(true);
|
|
378
|
+
});
|
|
379
|
+
it('should reject hop param for an erc20 token build', async function () {
|
|
380
|
+
const token = bitgo.coin('terc');
|
|
381
|
+
const tokenWallet = token.newWalletObject({});
|
|
382
|
+
recipients = [
|
|
383
|
+
{
|
|
384
|
+
address: '0xe59dfe5c67114b39a5662cc856be536c614124c0',
|
|
385
|
+
amount: '100',
|
|
386
|
+
},
|
|
387
|
+
];
|
|
388
|
+
await tokenWallet
|
|
389
|
+
.prebuildTransaction({ recipients, hop: true, walletPassphrase: 'hi' })
|
|
390
|
+
.should.be.rejectedWith(`Hop transactions are not enabled for ERC-20 tokens, nor are they necessary. Please remove the 'hop' parameter and try again.`);
|
|
391
|
+
});
|
|
392
|
+
});
|
|
393
|
+
describe('final-sign transaction from WRW', function () {
|
|
394
|
+
it('should add a second signature to unsigned sweep for teth', async function () {
|
|
395
|
+
const bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'test' });
|
|
396
|
+
const basecoin = bitgo.coin('teth');
|
|
397
|
+
const gasPrice = 200000000000;
|
|
398
|
+
const gasLimit = 500000;
|
|
399
|
+
const prv = 'xprv9s21ZrQH143K3D8TXfvAJgHVfTEeQNW5Ys9wZtnUZkqPzFzSjbEJrWC1vZ4GnXCvR7rQL2UFX3RSuYeU9MrERm1XBvACow7c36vnz5iYyj2'; // placeholder test prv
|
|
400
|
+
const tx = {
|
|
401
|
+
txPrebuild: fixtures.WRWUnsignedSweepETHTx,
|
|
402
|
+
prv,
|
|
403
|
+
};
|
|
404
|
+
// sign transaction once
|
|
405
|
+
const halfSigned = await basecoin.signTransaction(tx);
|
|
406
|
+
const wrapper = {};
|
|
407
|
+
wrapper.txPrebuild = halfSigned;
|
|
408
|
+
wrapper.txPrebuild.recipients = halfSigned.halfSigned.recipients;
|
|
409
|
+
wrapper.txPrebuild.gasPrice = gasPrice.toString();
|
|
410
|
+
wrapper.txPrebuild.gasLimit = gasLimit.toString();
|
|
411
|
+
wrapper.isLastSignature = true;
|
|
412
|
+
wrapper.walletContractAddress = fixtures.WRWUnsignedSweepETHTx.walletContractAddress;
|
|
413
|
+
wrapper.prv = prv;
|
|
414
|
+
// sign transaction twice with the "isLastSignature" flag
|
|
415
|
+
const finalSignedTx = await basecoin.signTransaction(wrapper);
|
|
416
|
+
finalSignedTx.should.have.property('txHex');
|
|
417
|
+
const txBuilder = (0, getBuilder_1.getBuilder)('eth');
|
|
418
|
+
txBuilder.from('0x' + finalSignedTx.txHex); // add a 0x in front of this txhex
|
|
419
|
+
const rebuiltTx = await txBuilder.build();
|
|
420
|
+
const outputs = rebuiltTx.outputs.map((output) => {
|
|
421
|
+
return {
|
|
422
|
+
address: output.address,
|
|
423
|
+
amount: output.value,
|
|
424
|
+
};
|
|
425
|
+
});
|
|
426
|
+
rebuiltTx.signature.length.should.equal(2);
|
|
427
|
+
outputs.length.should.equal(1);
|
|
428
|
+
outputs[0].address.should.equal(fixtures.WRWUnsignedSweepETHTx.recipient.address);
|
|
429
|
+
outputs[0].amount.should.equal(fixtures.WRWUnsignedSweepETHTx.recipient.amount);
|
|
430
|
+
});
|
|
431
|
+
it('should add a second signature to unsigned sweep for erc20 token', async function () {
|
|
432
|
+
const bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'test' });
|
|
433
|
+
src_1.Erc20Token.createTokenConstructors().forEach(({ name, coinConstructor }) => {
|
|
434
|
+
bitgo.safeRegister(name, coinConstructor);
|
|
435
|
+
});
|
|
436
|
+
const basecoin = bitgo.coin('tdai');
|
|
437
|
+
const gasPrice = 200000000000;
|
|
438
|
+
const gasLimit = 500000;
|
|
439
|
+
const prv = 'xprv9s21ZrQH143K3399QBVvbmhs4RB5QzXD8XiW3NwtaeTem93QGd5VNjukUnwJQ94nUgugHSVzSVVe3RP16Urv1ZyijpYdyDamsxf2Shbq4w1'; // placeholder test prv
|
|
440
|
+
const tx = {
|
|
441
|
+
txPrebuild: fixtures.WRWUnsignedSweepERC20Tx,
|
|
442
|
+
prv,
|
|
443
|
+
};
|
|
444
|
+
// sign transaction once
|
|
445
|
+
const halfSigned = await basecoin.signTransaction(tx);
|
|
446
|
+
const wrapper = {};
|
|
447
|
+
wrapper.txPrebuild = halfSigned;
|
|
448
|
+
wrapper.txPrebuild.recipients = halfSigned.halfSigned.recipients;
|
|
449
|
+
wrapper.txPrebuild.gasPrice = gasPrice.toString();
|
|
450
|
+
wrapper.txPrebuild.gasLimit = gasLimit.toString();
|
|
451
|
+
wrapper.isLastSignature = true;
|
|
452
|
+
wrapper.walletContractAddress = fixtures.WRWUnsignedSweepERC20Tx.walletContractAddress;
|
|
453
|
+
wrapper.prv = prv;
|
|
454
|
+
// sign transaction twice with the "isLastSignature" flag
|
|
455
|
+
const finalSignedTx = await basecoin.signTransaction(wrapper);
|
|
456
|
+
finalSignedTx.should.have.property('txHex');
|
|
457
|
+
const txBuilder = (0, getBuilder_1.getBuilder)('eth');
|
|
458
|
+
txBuilder.from('0x' + finalSignedTx.txHex); // add a 0x in front of this txhex
|
|
459
|
+
const rebuiltTx = await txBuilder.build();
|
|
460
|
+
const outputs = rebuiltTx.outputs.map((output) => {
|
|
461
|
+
return {
|
|
462
|
+
address: output.address,
|
|
463
|
+
amount: output.value,
|
|
464
|
+
};
|
|
465
|
+
});
|
|
466
|
+
rebuiltTx.signature.length.should.equal(2);
|
|
467
|
+
outputs.length.should.equal(1);
|
|
468
|
+
outputs[0].address.should.equal(fixtures.WRWUnsignedSweepERC20Tx.recipient.address);
|
|
469
|
+
outputs[0].amount.should.equal(fixtures.WRWUnsignedSweepERC20Tx.recipient.amount);
|
|
470
|
+
});
|
|
471
|
+
});
|
|
472
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXRoV2FsbGV0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdGVzdC91bml0L2V0aFdhbGxldC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLG9EQUE0QjtBQUM1QixxREFBOEM7QUFDOUMscURBQXVDO0FBQ3ZDLGdEQUF3QjtBQUN4QixrREFBMEI7QUFDMUIsbURBQW9EO0FBRXBELG1EQUErRDtBQUUvRCx1Q0FBa0U7QUFDbEUsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLGlCQUFpQixDQUFDLENBQUM7QUFFNUMsaURBQStDO0FBQy9DLG1DQUFxRTtBQUNyRSw2Q0FBMEM7QUFFMUMsUUFBUSxDQUFDLHNCQUFzQixFQUFFLEtBQUs7SUFDcEMsSUFBSSxLQUFtQixDQUFDO0lBQ3hCLElBQUksU0FBUyxDQUFDO0lBQ2QsSUFBSSxVQUFVLENBQUM7SUFDZixJQUFJLEVBQUUsQ0FBQztJQUVQLE1BQU0sQ0FBQztRQUNMLEtBQUssR0FBRyxvQkFBUyxDQUFDLFFBQVEsQ0FBQyxrQkFBUSxFQUFFLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDdEQsS0FBSyxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFDM0IsS0FBSyxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsVUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ2hELE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDaEMsU0FBUyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDckMsVUFBVSxHQUFHO1lBQ1g7Z0JBQ0UsT0FBTyxFQUFFLDRDQUE0QztnQkFDckQsTUFBTSxFQUFFLFFBQVE7YUFDakI7U0FDRixDQUFDO1FBQ0YsRUFBRSxHQUFHLEVBQUUsVUFBVSxFQUFFLHNCQUFzQixFQUFFLENBQUMsRUFBRSxDQUFD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RSxFQUFFLE1BQU0sQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQzdDLFFBQVEsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDbEQsUUFBUSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNoRCxRQUFRLENBQUMsUUFBUSxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN2QyxRQUFRLENBQUMsUUFBUSxDQUFDLGVBQVUsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDekUsUUFBUSxDQUFDLGVBQWUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDOUMsZ0JBQU0sQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3pCLFFBQVEsRUFBRSxDQUFDLEVBQUUsUUFBUSxFQUFFLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFDcEUsUUFBUSxFQUFFLENBQUMsRUFBRSxRQUFRLEVBQUUsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLFVBQVUsRUFBRSxDQUFDLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQztRQUNwRSxRQUFRLEVBQUUsQ0FBQyxFQUFFLFFBQVEsRUFBRSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsVUFBVSxFQUFFLENBQUMsRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDO1FBQ3BFLFFBQVEsQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFDOUUsUUFBUSxDQUFDLFFBQVEsQ0FBQyxRQUFR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aW1wb3J0IHsgYmlwMzIgfSBmcm9tICdAYml0Z28tYmV0YS9zZWNwMjU2azEnO1xuaW1wb3J0ICogYXMgc2VjcDI1NmsxIGZyb20gJ3NlY3AyNTZrMSc7XG5pbXBvcnQgbm9jayBmcm9tICdub2NrJztcbmltcG9ydCBzaW5vbiBmcm9tICdzaW5vbic7XG5pbXBvcnQgeyBjb21tb24sIFV0aWwgfSBmcm9tICdAYml0Z28tYmV0YS9zZGstY29yZSc7XG5cbmltcG9ydCB7IFRlc3RCaXRHbywgVGVzdEJpdEdvQVBJIH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLXRlc3QnO1xuXG5pbXBvcnQgeyBDYXBhYmlsaXR5LCBUcmFuc2FjdGlvbiBhcyBFdGhUeCB9IGZyb20gJ0BldGhlcmV1bWpzL3R4JztcbmNvbnN0IGZpeHR1cmVzID0gcmVxdWlyZSgnLi4vZml4dHVyZXMvZXRoJyk7XG5cbmltcG9ydCB7IEJpdEdvQVBJIH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWFwaSc7XG5pbXBvcnQgeyBFcmMyMFRva2VuLCBTaWduVHJhbnNhY3Rpb25PcHRpb25zLCBUZXRoIH0gZnJvbSAnLi4vLi4vc3JjJztcbmltcG9ydCB7IGdldEJ1aWxkZXIgfSBmcm9tICcuL2dldEJ1aWxkZXInO1xuXG5kZXNjcmliZSgnU2lnbiBFVEggVHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gIGxldCBiaXRnbzogVGVzdEJpdEdvQVBJO1xuICBsZXQgZXRoV2FsbGV0O1xuICBsZXQgcmVjaXBpZW50cztcbiAgbGV0IHR4O1xuXG4gIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgYml0Z28gPSBUZXN0Qml0R28uZGVjb3JhdGUoQml0R29BUEksIHsgZW52OiAndGVzdCcgfSk7XG4gICAgYml0Z28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gICAgYml0Z28uc2FmZVJlZ2lzdGVyKCd0ZXRoJywgVGV0aC5jcmVhdGVJbnN0YW5jZSk7XG4gICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKTtcbiAgICBldGhXYWxsZXQgPSBjb2luLm5ld1dhbGxldE9iamVjdCh7fSk7XG4gICAgcmVjaXBpZW50cyA9IFtcbiAgICAgIHtcbiAgICAgICAgYWRkcmVzczogJzB4ZTU5ZGZlNWM2NzExNGIzOWE1NjYyY2M4NTZiZTUzNmM2MTQxMjRjMCcsXG4gICAgICAgIGFtb3VudDogJzEwMDAwMCcsXG4gICAgICB9LFxuICAgIF07XG4gICAgdHggPSB7IHJlY2lwaWVudHMsIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAgfTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCByZWFkIHRyYW5zYWN0aW9uIHJlY2lwaWVudHMgZnJvbSB0eFByZWJ1aWxkIGV2ZW4gaWYgbm9uZSBhcmUgc3BlY2lmaWVkIGFzIHRvcC1sZXZlbCBwYXJhbXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgc2lub24uc3R1YihVdGlsLCAneHBydlRvRXRoUHJpdmF0ZUtleScpO1xuICAgIHNpbm9uLnN0dWIoVXRpbCwgJ2V0aFNpZ25Nc2dIYXNoJyk7XG4gICAgc2lub24uc3R1YihldGhXYWxsZXQuZ2V0T3BlcmF0aW9uU2hhM0ZvckV4ZWN1dGVBbmRDb25maXJtKTtcblxuICAgIGNvbnN0IHsgaGFsZlNpZ25lZCB9ID0gKGF3YWl0IGV0aFdhbGxldC5zaWduVHJhbnNhY3Rpb24oeyB0eFByZWJ1aWxkOiB0eCwgcHJ2OiAnbXlfdXNlcl9wcnYnIH0pKSBhcyBhbnk7XG4gICAgaGFsZlNpZ25lZC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncmVjaXBpZW50cycsIHJlY2lwaWVudHMpO1xuICAgIHNpbm9uLnJlc3RvcmUoKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCB0aHJvdyBhbiBlcnJvciBpZiBubyByZWNpcGllbnRzIGFyZSBpbiB0aGUgdHhQcmVidWlsZCBhbmQgbm9uZSBhcmUgc3BlY2lmaWVkIGFzIHBhcmFtcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBhd2FpdCBldGhXYWxsZXRcbiAgICAgIC5zaWduVHJhbnNhY3Rpb24oeyB0eFByZWJ1aWxkOiB7fSwgcHJ2OiAnbXlfdXNlcl9wcnYnIH0pXG4gICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgncmVjaXBpZW50cyBtaXNzaW5nIG9yIG5vdCBhcnJheScpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHRocm93IGFuIGVycm9yIGlmIHRoZSByZWNpcGllbnRzIHBhcmFtIGlzIG5vdCBhbiBhcnJheScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBhd2FpdCBldGhXYWxsZXRcbiAgICAgIC5zaWduVHJhbnNhY3Rpb24oeyB0eFByZWJ1aWxkOiB7IHJlY2lwaWVudHM6ICdub3QtYXJyYXknIH0sIHBydjogJ215X3VzZXJfcHJ2JyB9KVxuICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ3JlY2lwaWVudHMgbWlzc2luZyBvciBub3QgYXJyYXknKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBzZXQgaXNCYXRjaCB0byBmYWxzZSBpZiBzaW5nbGUgcmVjaXBpZW50JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIHNpbm9uLnN0dWIoVXRpbCwgJ3hwcnZUb0V0aFByaXZhdGVLZXknKTtcbiAgICBzaW5vbi5zdHViKFV0aWwsICdldGhTaWduTXNnSGFzaCcpO1xuICAgIHNpbm9uLnN0dWIoZXRoV2FsbGV0LmdldE9wZXJhdGlvblNoYTNGb3JFeGVjdXRlQW5kQ29uZmlybSk7XG4gICAgY29uc3Qgc2luZ2xlUmVjaXBpZW50c1R4ID0geyByZWNpcGllbnRzOiByZWNpcGllbnRzLCBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAwLCBpc0JhdGNoOiBmYWxzZSB9O1xuICAgIGNvbnN0IHsgaGFsZlNpZ25lZCB9ID0gKGF3YWl0IGV0aFdhbGxldC5zaWduVHJhbnNhY3Rpb24oe1xuICAgICAgdHhQcmVidWlsZDogc2luZ2xlUmVjaXBpZW50c1R4LFxuICAgICAgcHJ2OiAnbXlfdXNlcl9wcnYnLFxuICAgIH0pKSBhcyBhbnk7XG4gICAgaGFsZlNpZ25lZC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncmVjaXBpZW50cycsIHJlY2lwaWVudHMpO1xuICAgIGhhbGZTaWduZWQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2lzQmF0Y2gnLCBmYWxzZSk7XG4gICAgc2lub24ucmVzdG9yZSgpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHNldCBpc0JhdGNoIHRvIHRydWUgaWYgbXVsdGlwbGUgcmVjaXBpZW50cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBtdWx0aXBsZVJlY2lwaWVudHMgPSBbXG4gICAgICB7XG4gICAgICAgIGFkZHJlc3M6ICcweDBjN2YzYmM1ZDJiMmMwZGJlZTFiNDU1MzZiODI1NjlmNDFiNTQzMzEnLFxuICAgICAgICBhbW91bnQ6ICcyMDAnLFxuICAgICAgICBkYXRhOiAnMHhjZjRjNThlMjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwNDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMGEwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDQzMTc0NWI4OWU3MzIzMGIzYmM4YTE5ZTAxOTE5NGVmYjRiOTllZmQwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA0MzE3NDViODllNzMyMzBiM2JjOGExOWUwMTkxOTRlZmI0Yjk5ZWZkMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwNjQwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDY0JyxcbiAgICAgIH0sXG4gICAgXTtcblxuICAgIGNvbnN0IG11bHRpcGxlUmVjaXBpZW50c1R4ID0geyByZWNpcGllbnRzOiBtdWx0aXBsZVJlY2lwaWVudHMsIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsIGlzQmF0Y2g6IHRydWUgfTtcblxuICAgIHNpbm9uLnN0dWIoVXRpbCwgJ3hwcnZUb0V0aFByaXZhdGVLZXknKTtcbiAgICBzaW5vbi5zdHViKFV0aWwsICdldGhTaWduTXNnSGFzaCcpO1xuICAgIHNpbm9uLnN0dWIoZXRoV2FsbGV0LmdldE9wZXJhdGlvblNoYTNGb3JFeGVjdXRlQW5kQ29uZmlybSk7XG4gICAgY29uc3QgeyBoYWxmU2lnbmVkIH0gPSAoYXdhaXQgZXRoV2FsbGV0LnNpZ25UcmFuc2FjdGlvbih7XG4gICAgICB0eFByZWJ1aWxkOiBtdWx0aXBsZVJlY2lwaWVudHNUeCxcbiAgICAgIHBydjogJ215X3VzZXJfcHJ2JyxcbiAgICB9KSkgYXMgYW55O1xuICAgIGhhbGZTaWduZWQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2lzQmF0Y2gnLCB0cnVlKTtcbiAgICBzaW5vbi5yZXN0b3JlKCk7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKCdFdGhlcmV1bSBIb3AgVHJhbnNhY3Rpb25zJywgZnVuY3Rpb24gKCkge1xuICBsZXQgYml0Z286IFRlc3RCaXRHb0FQSTtcbiAgbGV0IGV0aFdhbGxldDtcbiAgbGV0IHR4O1xuICBsZXQgdHhpZDtcbiAgbGV0IGJpdGdvU2lnbmF0dXJlO1xuICBsZXQgYml0Z29LZXlYcHJ2O1xuICBsZXQgYmdVcmw7XG4gIGxldCBlbnY7XG5cbiAgY29uc3QgdXNlcktleXBhaXIgPSB7XG4gICAgeHBydjogJ3hwcnY5czIxWnJRSDE0M0syZko5MVM0QlJzdXBjWXJFNm1tWTk2ZmNYNUhraG9UcnJ3bXdqZDE2Q244N2NXaW5KakJ5cmZwb2pqeDdlenNKTHg3VEFLTFQ4bThoTTVLYXg5WWNveG5CZUpaM3QyaycsXG4gICAgeHB1YjogJ3hwdWI2NjFNeU13QXFSYmNGOU5jN1RiQm8xclpBYWdpV0VWUFdLYkRLVGhORzh6cWprNzZIQUtMa2FTYlRuNmRLMmRRUGZ1RDd4amljeENaVld2ajY3ZlA1blE5VzdRVVJtb01WQVg4bTZqWnNHcCcsXG4gICAgcmF3UHViOiAnMDJjMTAzYWM3NDQ4MTg3NGI1ZWYwZjM4NWQxMjcyNWU0ZjE0YWVkYzllMDBiYzgxNGNlOTZmNDdmNjJjZTdhZGYyJyxcbiAgICByYXdQcnY6ICc5MzZjNWFmM2Y4YWY4MWY3NWNkYWQxYjA4ZjI5ZTdkOWMwMWU1OThlMmRiMmQ3YmUxOGI5ZTVhODY0NmU4N2M2JyxcbiAgICBwYXRoOiAnbScsXG4gICAgd2FsbGV0U3ViUGF0aDogJy8wLzAnLFxuICB9O1xuXG4gIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgdHggPVxuICAgICAgJzB4Zjg2YzgyMDE1Mjg1MDEyYTA1ZjIwMDgyNTIwODk0NTIwOGQ4ZTgwYzZkMWFlZjliZTM3YjRiZDE5YTljZjc1ZWQ5M2RjODg2YjVlNjIwZjQ4MDAwODAyNmEwMGUxM2Y5ZTBlMTEzMzdiMmIwMjI3ZTM0MTIyMTFkMzYyNWU0M2YxMDgzZmRhMzk5Y2MzNjFkZDRiZjg5MDgzYmEwNmM4MDFhNzYxZTBhYTNiYzhkYjBhYzI1NjhkNTc1YjBmYjMwNmExZjA0ZjRkNWJhODJiYTNjYzBlYTBhODNiZCc7XG4gICAgdHhpZCA9ICcweDBhYzY2OWM1ZmVmODI5NDQ0M2M3NWEzMWUzMmM0NGI5N2JiYzllNDNhMThlYThiZWFiY2MyYTNiNDVlYjZmZmEnO1xuICAgIGJpdGdvS2V5WHBydiA9XG4gICAgICAneHBydjlzMjFaclFIMTQzSzN0cFdCSFdlMzFzTG9YTlJROUF2UllKZ2l0a0t4UTRBVEZRTXd2cjdoSE5xWVJVblM3UHNqekI3YUsxVnhxSEx1TlFqajFzY2tKMkp3bzJxeG1zdmVqd0VDU3BGTWZDJztcbiAgICBjb25zdCBiaXRnb0tleSA9IGJpcDMyLmZyb21CYXNlNTgoYml0Z29LZXlYcHJ2KTtcbiAgICBpZiAoIWJpdGdvS2V5LnByaXZhdGVLZXkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbm8gcHJpdmF0ZUtleScpO1xuICAgIH1cbiAgICBjb25zdCBiaXRnb1hwdWIgPSBiaXRnb0tleS5uZXV0ZXJlZCgpLnRvQmFzZTU4KCk7XG4gICAgYml0Z29TaWduYXR1cmUgPVxuICAgICAgJzB4YWEnICtcbiAgICAgIEJ1ZmZlci5mcm9tKHNlY3AyNTZrMS5lY2RzYVNpZ24oQnVmZmVyLmZyb20odHhpZC5zbGljZSgyKSwgJ2hleCcpLCBiaXRnb0tleS5wcml2YXRlS2V5KS5zaWduYXR1cmUpLnRvU3RyaW5nKFxuICAgICAgICAnaGV4J1xuICAgICAgKTtcblxuICAgIGVudiA9ICd0ZXN0JztcbiAgICBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHb0FQSSwgeyBlbnYgfSk7XG4gICAgYml0Z28uc2FmZVJlZ2lzdGVyKCd0ZXRoJywgVGV0aC5jcmVhdGVJbnN0YW5jZSk7XG4gICAgY29tbW9uLkVudmlyb25tZW50c1tlbnZdLmhzbVhwdWIgPSBiaXRnb1hwdWI7XG4gICAgYml0Z28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gICAgYmdVcmwgPSBjb21tb24uRW52aXJvbm1lbnRzW2JpdGdvLmdldEVudigpXS51cmk7XG4gICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKTtcbiAgICBldGhXYWxsZXQgPSBjb2luLm5ld1dhbGxldE9iamVjdCh7IGtleXM6IFsndXNlcicsICdiYWNrdXAnLCAnYml0Z28nXSB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1ZlcmlmeSBIU00gSG9wIHByZWJ1aWxkJywgZnVuY3Rpb24gKCkge1xuICAgIGxldCBwcmVidWlsZDtcbiAgICBsZXQgYnVpbGRQYXJhbXM7XG4gICAgbGV0IGZpbmFsUmVjaXBpZW50O1xuICAgIGxldCBzZW5kQW1vdW50O1xuXG4gICAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICAgIGZpbmFsUmVjaXBpZW50ID0gJzB4NTIwOGQ4ZTgwYzZkMWFlZjliZTM3YjRiZDE5YTljZjc1ZWQ5M2RjOCc7XG4gICAgICBzZW5kQW1vdW50ID0gJzIwMDAwMDAwMDAwMDAwMCc7XG4gICAgICBwcmVidWlsZCA9IHtcbiAgICAgICAgdHgsXG4gICAgICAgIGlkOiB0eGlkLFxuICAgICAgICBzaWduYXR1cmU6IGJpdGdvU2lnbmF0dXJlLFxuICAgICAgfTtcbiAgICAgIGJ1aWxkUGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogZmluYWxSZWNpcGllbnQsXG4gICAgICAgICAgICBhbW91bnQ6IHNlbmRBbW91bnQsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGFjY2VwdCBhIHZhbGlkIGhvcCBwcmVidWlsZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IGV0aFdhbGxldC5iYXNlQ29pbi52YWxpZGF0ZUhvcFByZWJ1aWxkKGV0aFdhbGxldCwgcHJlYnVpbGQsIGJ1aWxkUGFyYW1zKS5zaG91bGQuYmUucmVzb2x2ZWQoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCBpZiB0aGUgSFNNIHByZWJ1aWxkIHJlY2lwaWVudCBpcyB3cm9uZycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJhZEJ1aWxkUGFyYW1zID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShidWlsZFBhcmFtcykpO1xuICAgICAgYmFkQnVpbGRQYXJhbXMucmVjaXBpZW50c1swXS5hZGRyZXNzID0gJzB4NTRiZjE2MDlhZWVkODA0YWEyMzFmMDhjNTNkYmIxOGY3ZDM3NDYxNSc7XG5cbiAgICAgIGF3YWl0IGV0aFdhbGxldC5iYXNlQ29pblxuICAgICAgICAudmFsaWRhdGVIb3BQcmVidWlsZChldGhXYWxsZXQsIHByZWJ1aWxkLCBiYWRCdWlsZFBhcmFtcylcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoL2RvZXMgbm90IGVxdWFsIG9yaWdpbmFsIHJlY2lwaWVudC8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIGlmIHRoZSBIU00gcHJlYnVpbGQgdHggYW1vdW50IGlzIHdyb25nJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYmFkQnVpbGRQYXJhbXMgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGJ1aWxkUGFyYW1zKSk7XG4gICAgICBiYWRCdWlsZFBhcmFtcy5yZWNpcGllbnRzWzBdLmFtb3VudCA9ICc1MDAwMDAwMCc7XG5cbiAgICAgIGF3YWl0IGV0aFdhbGxldC5iYXNlQ29pblxuICAgICAgICAudmFsaWRhdGVIb3BQcmVidWlsZChldGhXYWxsZXQsIHByZWJ1aWxkLCBiYWRCdWlsZFBhcmFtcylcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoL2RvZXMgbm90IGVxdWFsIG9yaWdpbmFsIGFtb3VudC8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIGlmIHRoZSBIU00gc2lnbmF0dXJlIGlzIGludmFsaWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBNb2NraW5nIGEgZGlmZmVyZW50IEJpdEdvIGtleSBtZWFucyB0aGUgc2lnbmluZyBrZXkgc2hvdWxkIGJlIHdyb25nIChpdCBtYXBzIHRvIGEgZGlmZmVyZW50IGFkZHJlc3MgdGhhbiB0aGlzIHhwdWIpXG4gICAgICBjb25zdCBnb29kWHB1YiA9IGNvbW1vbi5FbnZpcm9ubWVudHNbZW52XS5oc21YcHViO1xuICAgICAgY29tbW9uLkVudmlyb25tZW50c1tlbnZdLmhzbVhwdWIgPVxuICAgICAgICAneHB1YjY2MU15TXdBcVJiY0VyRnFWWEdpVUZ2OVllb1BiaE43MlVpTkNVZGo5bmozVDZNOGg3aUtObWJDWXBNVldWWlA3TEEybWEzSFdjUG5nejFnUlRtNEZQZHRtOW1IZnJOdlU5M01Db3N6c0dMJztcblxuICAgICAgYXdhaXQgZXRoV2FsbGV0LmJhc2VDb2luXG4gICAgICAgIC52YWxpZGF0ZUhvcFByZWJ1aWxkKGV0aFdhbGxldCwgcHJlYnVpbGQsIGJ1aWxkUGFyYW1zKVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvSG9wIHR4aWQgc2lnbmF0dXJlIGludmFsaWQvKTtcbiAgICAgIGNvbW1vbi5FbnZpcm9ubWVudHNbZW52XS5oc21YcHViID0gZ29vZFhwdWI7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgaWYgdGhlIEhTTSBzaWduYXR1cmUgc2lnbmVkIHRoZSB3cm9uZyBIU00gY29tbWl0bWVudCBkaWdlc3QnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBiYWRUeGlkID0gJzB4YjRiMzgyN2E1MjljOTE2Njc4NmU3OTY1MjgwMTc4ODlhYzUwMjcyNTViNjViM2ZhMmEzZDNhZDkxMjQ0YTEyYic7XG4gICAgICBjb25zdCBiYWRUeGlkQnVmZmVyID0gQnVmZmVyLmZyb20oYmFkVHhpZC5zbGljZSgyKSwgJ2hleCcpO1xuICAgICAgY29uc3QgeHBydk5vZGUgPSBiaXAzMi5mcm9tQmFzZTU4KGJpdGdvS2V5WHBydik7XG4gICAgICBpZiAoIXhwcnZOb2RlLnByaXZhdGVLZXkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdubyBwcml2YXRlS2V5Jyk7XG4gICAgICB9XG4gICAgICBjb25zdCBiYWRTaWduYXR1cmUgPVxuICAgICAgICAnMHhhYScgKyBCdWZmZXIuZnJvbShzZWNwMjU2azEuZWNkc2FTaWduKGJhZFR4aWRCdWZmZXIsIHhwcnZOb2RlLnByaXZhdGVLZXkpLnNpZ25hdHVyZSkudG9TdHJpbmcoJ2hleCcpO1xuICAgICAgY29uc3QgYmFkUHJlYnVpbGQgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHByZWJ1aWxkKSk7XG4gICAgICBiYWRQcmVidWlsZC5zaWduYXR1cmUgPSBiYWRTaWduYXR1cmU7XG5cbiAgICAgIGF3YWl0IGV0aFdhbGxldC5iYXNlQ29pblxuICAgICAgICAudmFsaWRhdGVIb3BQcmVidWlsZChldGhXYWxsZXQsIGJhZFByZWJ1aWxkLCBidWlsZFBhcmFtcylcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoL0hvcCB0eGlkIHNpZ25hdHVyZSBpbnZhbGlkLyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdQcmVidWlsZCBob3AgdHJhbnNhY3Rpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgbGV0IHByZWJ1aWxkO1xuICAgIGxldCBidWlsZFBhcmFtcztcbiAgICBsZXQgZmluYWxSZWNpcGllbnQ7XG4gICAgbGV0IHNlbmRBbW91bnQ7XG4gICAgbGV0IGdhc0xpbWl0RXN0aW1hdGU7XG4gICAgbGV0IGdhc1ByaWNlO1xuXG4gICAgY29uc3Qgbm9ja1VzZXJLZXkgPSBmdW5jdGlvbiAoKSB7XG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAuZ2V0KGAvYXBpL3YyL3RldGgva2V5L3VzZXJgKVxuICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgZW5jcnlwdGVkUHJ2OiBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6IHVzZXJLZXlwYWlyLnhwcnYsIHBhc3N3b3JkOiBUZXN0Qml0R28uVEVTVF9XQUxMRVQxX1BBU1NDT0RFIH0pLFxuICAgICAgICAgIHBhdGg6IHVzZXJLZXlwYWlyLnBhdGggKyB1c2VyS2V5cGFpci53YWxsZXRTdWJQYXRoLFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIGNvbnN0IG5vY2tGZWVzID0gZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2NvcGUgPSBub2NrKGJnVXJsKVxuICAgICAgICAuZ2V0KCcvYXBpL3YyL3RldGgvdHgvZmVlJylcbiAgICAgICAgLnF1ZXJ5KHRydWUpXG4gICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICBnYXNMaW1pdEVzdGltYXRlOiBnYXNMaW1pdEVzdGltYXRlLFxuICAgICAgICAgIGZlZUVzdGltYXRlOiBnYXNMaW1pdEVzdGltYXRlICogZ2FzUHJpY2UsXG4gICAgICAgIH0pO1xuICAgICAgcmV0dXJuIHNjb3BlO1xuICAgIH07XG5cbiAgICBjb25zdCBub2NrQnVpbGQgPSBmdW5jdGlvbiAod2FsbGV0SWQpIHtcbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL3RldGgvd2FsbGV0LycgKyB3YWxsZXRJZCArICcvdHgvYnVpbGQnKVxuICAgICAgICAucmVwbHkoMjAwLCB7IGhvcFRyYW5zYWN0aW9uOiBwcmVidWlsZCwgYnVpbGRQYXJhbXMgfSk7XG4gICAgfTtcblxuICAgIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgICBnYXNMaW1pdEVzdGltYXRlID0gMTAwMDAwO1xuICAgICAgZ2FzUHJpY2UgPSA1MDAwMDAwMDtcbiAgICAgIGZpbmFsUmVjaXBpZW50ID0gJzB4NTIwOGQ4ZTgwYzZkMWFlZjliZTM3YjRiZDE5YTljZjc1ZWQ5M2RjOCc7XG4gICAgICBzZW5kQW1vdW50ID0gJzIwMDAwMDAwMDAwMDAwMCc7XG4gICAgICBwcmVidWlsZCA9IHtcbiAgICAgICAgdHgsXG4gICAgICAgIGlkOiB0eGlkLFxuICAgICAgICBzaWduYXR1cmU6IGJpdGdvU2lnbmF0dXJlLFxuICAgICAgfTtcbiAgICAgIGJ1aWxkUGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogZmluYWxSZWNpcGllbnQsXG4gICAgICAgICAgICBhbW91bnQ6IHNlbmRBbW91bnQsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgaG9wOiB0cnVlLFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiBUZXN0Qml0R28uVEVTVF9XQUxMRVQxX1BBU1NDT0RFLFxuICAgICAgfTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcHJlYnVpbGQgYSBob3AgdHJhbnNhY3Rpb24gaWYgZ2l2ZW4gdGhlIGNvcnJlY3QgYXJncycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIG5vY2tVc2VyS2V5KCk7XG4gICAgICBjb25zdCBmZWVTY29wZSA9IG5vY2tGZWVzKCk7XG4gICAgICBub2NrQnVpbGQoZXRoV2FsbGV0LmlkKCkpO1xuICAgICAgY29uc3QgcmVzID0gKGF3YWl0IGV0aFdhbGxldC5wcmVidWlsZFRyYW5zYWN0aW9uKGJ1aWxkUGFyYW1zKSkgYXMgYW55O1xuICAgICAgc2hvdWxkLmV4aXN0KHJlcy5ob3BUcmFuc2FjdGlvbik7XG4gICAgICBzaG91bGQuZXhpc3QocmVzLmhvcFRyYW5zYWN0aW9uLnR4KTtcbiAgICAgIHNob3VsZC5leGlzdChyZXMuaG9wVHJhbnNhY3Rpb24udHgpO1xuICAgICAgc2hvdWxkLmV4aXN0KHJlcy5ob3BUcmFuc2FjdGlvbi5pZCk7XG4gICAgICBzaG91bGQuZXhpc3QocmVzLmhvcFRyYW5zYWN0aW9uLnNpZ25hdHVyZSk7XG4gICAgICBzaG91bGQubm90LmV4aXN0KHJlcy53YWxsZXQpO1xuICAgICAgc2hvdWxkLm5vdC5leGlzdChyZXMuYnVpbGRQYXJhbXMpO1xuICAgICAgZmVlU2NvcGUuaXNEb25lKCkuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgY29uc3QgZmVlUmVxID0gKGZlZVNjb3BlIGFzIGFueSkuaW50ZXJjZXB0b3JzWzBdLnJlcTtcbiAgICAgIGZlZVJlcS5wYXRoLnNob3VsZC5jb250YWluRXFsKCdob3A9dHJ1ZScpO1xuICAgICAgZmVlUmVxLnBhdGguc2hvdWxkLmNvbnRhaW5FcWwoJ3JlY2lwaWVudD0nICsgZmluYWxSZWNpcGllbnQpO1xuICAgICAgZmVlUmVxLnBhdGguc2hvdWxkLmNvbnRhaW5FcWwoJ2Ftb3VudD0nICsgc2VuZEFtb3VudCk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKCdBZGQgZmluYWwgc2lnbmF0dXJlIHRvIEVUSCB0eCBmcm9tIG9mZmxpbmUgdmF1bHQnLCBmdW5jdGlvbiAoKSB7XG4gIGxldCBwYXJhbXNGcm9tVmF1bHQsIGV4cGVjdGVkUmVzdWx0LCBiaXRnbywgY29pbjtcbiAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCB2YWxzID0gZml4dHVyZXMuZ2V0SGFsZlNpZ25lZFRldGhGcm9tVmF1bHQoKTtcbiAgICBwYXJhbXNGcm9tVmF1bHQgPSB2YWxzLnBhcmFtc0Zyb21WYXVsdDtcbiAgICBleHBlY3RlZFJlc3VsdCA9IHZhbHMuZXhwZWN0ZWRSZXN1bHQ7XG4gICAgYml0Z28gPSBUZXN0Qml0R28uZGVjb3JhdGUoQml0R29BUEksIHsgZW52OiAndGVzdCcgfSk7XG4gICAgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBzdWNjZXNzZnVsbHkgZnVsbHkgc2lnbiBhIGhhbGYtc2lnbmVkIHRyYW5zYWN0aW9uIGZyb20gdGhlIG9mZmxpbmUgdmF1bHQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSAoYXdhaXQgY29pbi5zaWduVHJhbnNhY3Rpb24ocGFyYW1zRnJvbVZhdWx0KSkgYXMgYW55O1xuICAgIGNvbnN0IGV4cGVjdGVkVHggPSBFdGhUeC5mcm9tU2VyaWFsaXplZFR4KEJ1ZmZlci5mcm9tKGV4cGVjdGVkUmVzdWx0LnR4SGV4LCAnaGV4JykpO1xuICAgIGNvbnN0IGFjdHVhbFR4ID0gRXRoVHguZnJvbVNlcmlhbGl6ZWRUeChCdWZmZXIuZnJvbShyZXNwb25zZS50eEhleCwgJ2hleCcpKTtcbiAgICBhY3R1YWxUeC5ub25jZS50b1N0cmluZygpLnNob3VsZC5kZWVwRXF1YWwoZXhwZWN0ZWRUeC5ub25jZS50b1N0cmluZygpKTtcbiAgICBzaG91bGQuZXhpc3QoYWN0dWFsVHgudG8pO1xuICAgIGFjdHVhbFR4LnRvPy5zaG91bGQuZGVlcEVxdWFsKGV4cGVjdGVkVHgudG8pO1xuICAgIGFjdHVhbFR4LnZhbHVlLnNob3VsZC5kZWVwRXF1YWwoZXhwZWN0ZWRUeC52YWx1ZSk7XG4gICAgYWN0dWFsVHguZGF0YS5zaG91bGQuZGVlcEVxdWFsKGV4cGVjdGVkVHguZGF0YSk7XG4gICAgYWN0dWFsVHguaXNTaWduZWQoKS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgYWN0dWFsVHguc3VwcG9ydHMoQ2FwYWJpbGl0eS5FSVAxNTVSZXBsYXlQcm90ZWN0aW9uKS5zaG91bGQuZXF1YWwoZmFsc2UpO1xuICAgIGFjdHVhbFR4LnZlcmlmeVNpZ25hdHVyZSgpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICBzaG91bGQuZXhpc3QoYWN0dWFsVHgudik7XG4gICAgYWN0dWFsVHg/LnY/LnRvU3RyaW5nKCkuc2hvdWxkLmRlZXBFcXVhbChleHBlY3RlZFR4Py52Py50b1N0cmluZygpKTtcbiAgICBhY3R1YWxUeD8ucj8udG9TdHJpbmcoKS5zaG91bGQuZGVlcEVxdWFsKGV4cGVjdGVkVHg/LnI/LnRvU3RyaW5nKCkpO1xuICAgIGFjdHVhbFR4Py5zPy50b1N0cmluZygpLnNob3VsZC5kZWVwRXF1YWwoZXhwZWN0ZWRUeD8ucz8udG9TdHJpbmcoKSk7XG4gICAgYWN0dWFsVHguZ2FzUHJpY2UudG9TdHJpbmcoKS5zaG91bGQuZGVlcEVxdWFsKGV4cGVjdGVkVHguZ2FzUHJpY2UudG9TdHJpbmcoKSk7XG4gICAgYWN0dWFsVHguZ2FzTGltaXQudG9TdHJpbmcoKS5zaG91bGQuZGVlcEVxdWFsKGV4cGVjdGVkVHguZ2FzTGltaXQudG9TdHJpbmcoKSk7XG4gICAgcmVzcG9uc2UudHhIZXgudG9TdHJpbmcoKS5zaG91bGQuZXF1YWwoZXhwZWN0ZWRSZXN1bHQudHhIZXgudG9TdHJpbmcoKSk7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKCdBZGQgc2lnbmF0dXJlIHRvIEVJUDE1NTkgdHggZnJvbSBvZmZsaW5lIHZhdWx0JywgZnVuY3Rpb24gKCkge1xuICBsZXQgYml0Z286IFRlc3RCaXRHb0FQSTtcbiAgbGV0IHBhcmFtc0Zyb21WYXVsdCwgZXhwZWN0ZWRSZXN1bHQsIGNvaW47XG4gIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgdmFscyA9IGZpeHR1cmVzLmdldFVuc2lnbmVkRWlwMTU1OVRldGhGcm9tVmF1bHQoKTtcbiAgICBwYXJhbXNGcm9tVmF1bHQgPSB2YWxzLnBhcmFtc0Zyb21WYXVsdDtcbiAgICBleHBlY3RlZFJlc3VsdCA9IHZhbHMuZXhwZWN0ZWRSZXN1bHQ7XG4gICAgYml0Z28gPSBUZXN0Qml0R28uZGVjb3JhdGUoQml0R29BUEksIHsgZW52OiAndGVzdCcgfSk7XG4gICAgYml0Z28uc2FmZVJlZ2lzdGVyKCd0ZXRoJywgVGV0aC5jcmVhdGVJbnN0YW5jZSk7XG4gICAgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBzdWNjZXNzZnVsbHkgc2lnbiBhbiB1bnNpZ25lZCB0cmFuc2FjdGlvbiBmcm9tIHRoZSBvZmZsaW5lIHZhdWx0JywgYXN5bmMgZnVuY3Rpb24qICgpIHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGNvaW4uc2lnblRyYW5zYWN0aW9uKHBhcmFtc0Zyb21WYXVsdCk7XG4gICAgc2hvdWxkLmV4aXN0KHJlc3BvbnNlLmhhbGZTaWduZWQpO1xuICAgIHJlc3BvbnNlLmhhbGZTaWduZWQuZWlwMTU1OS5zaG91bGQuZGVlcEVxdWFsKGV4cGVjdGVkUmVzdWx0LmhhbGZTaWduZWQuZWlwMTU1OSk7XG4gICAgcmVzcG9uc2UuaGFsZlNpZ25lZC5yZWNpcGllbnRzLnNob3VsZC5kZWVwRXF1YWwoZXhwZWN0ZWRSZXN1bHQuaGFsZlNpZ25lZC5yZWNpcGllbnRzKTtcbiAgfSk7XG59KTtcblxuZGVzY3JpYmUoJ3ByZWJ1aWxkVHJhbnNhY3Rpb24nLCBmdW5jdGlvbiAoKSB7XG4gIGxldCBiaXRnbzogVGVzdEJpdEdvQVBJO1xuICBsZXQgZXRoV2FsbGV0O1xuICBsZXQgcmVjaXBpZW50cztcbiAgbGV0IGJnVXJsO1xuICBsZXQgZ2FzTGltaXQ7XG5cbiAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHb0FQSSwgeyBlbnY6ICd0ZXN0JyB9KTtcbiAgICBFcmMyMFRva2VuLmNyZWF0ZVRva2VuQ29uc3RydWN0b3JzKCkuZm9yRWFjaCgoeyBuYW1lLCBjb2luQ29uc3RydWN0b3IgfSkgPT4ge1xuICAgICAgYml0Z28uc2FmZVJlZ2lzdGVyKG5hbWUsIGNvaW5Db25zdHJ1Y3Rvcik7XG4gICAgfSk7XG4gICAgYml0Z28uc2FmZVJlZ2lzdGVyKCd0ZXRoJywgVGV0aC5jcmVhdGVJbnN0YW5jZSk7XG4gICAgYml0Z28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKTtcbiAgICBldGhXYWxsZXQgPSBjb2luLm5ld1dhbGxldE9iamVjdCh7fSk7XG4gICAgZ2FzTGltaXQgPSAyMTAwMDAwO1xuICAgIHJlY2lwaWVudHMgPSBbXG4gICAgICB7XG4gICAgICAgIGFkZHJlc3M6ICcweGU1OWRmZTVjNjcxMTRiMzlhNTY2MmNjODU2YmU1MzZjNjE0MTI0YzAnLFxuICAgICAgICBhbW91bnQ6ICcxMDAwMDAnLFxuICAgICAgfSxcbiAgICBdO1xuICAgIGJnVXJsID0gY29tbW9uLkVudmlyb25tZW50c1tiaXRnby5nZXRFbnYoKV0udXJpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHN1Y2Nlc3NmdWxseSBhY2NlcHQgZ2FzTGltaXQgYXMgYSBwYXJhbScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBzY29wZSA9IG5vY2soYmdVcmwpXG4gICAgICAucG9zdCgnL2FwaS92Mi90ZXRoL3dhbGxldC8nICsgZXRoV2FsbGV0LmlkKCkgKyAnL3R4L2J1aWxkJywge1xuICAgICAgICByZWNpcGllbnRzLFxuICAgICAgICBnYXNMaW1pdCxcbiAgICAgIH0pXG4gICAgICAucmVwbHkoMjAwLCB7IHN1Y2Nlc3M6IHRydWUgfSk7XG4gICAgY29uc3QgcHJlYnVpbGQgPSBhd2FpdCBldGhXYWxsZXQucHJlYnVpbGRUcmFuc2FjdGlvbih7IHJlY2lwaWVudHMsIGdhc0xpbWl0IH0pO1xuICAgIHNjb3BlLmlzRG9uZSgpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICBwcmVidWlsZC5zdWNjZXNzLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCByZWplY3QgaG9wIHBhcmFtIGZvciBhbiBlcmMyMCB0b2tlbiBidWlsZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCB0b2tlbiA9IGJpdGdvLmNvaW4oJ3RlcmMnKTtcbiAgICBjb25zdCB0b2tlbldhbGxldCA9IHRva2VuLm5ld1dhbGxldE9iamVjdCh7fSk7XG4gICAgcmVjaXBpZW50cyA9IFtcbiAgICAgIHtcbiAgICAgICAgYWRkcmVzczogJzB4ZTU5ZGZlNWM2NzExNGIzOWE1NjYyY2M4NTZiZTUzNmM2MTQxMjRjMCcsXG4gICAgICAgIGFtb3VudDogJzEwMCcsXG4gICAgICB9LFxuICAgIF07XG4gICAgYXdhaXQgdG9rZW5XYWxsZXRcbiAgICAgIC5wcmVidWlsZFRyYW5zYWN0aW9uKHsgcmVjaXBpZW50cywgaG9wOiB0cnVlLCB3YWxsZXRQYXNzcGhyYXNlOiAnaGknIH0pXG4gICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChcbiAgICAgICAgYEhvcCB0cmFuc2FjdGlvbnMgYXJlIG5vdCBlbmFibGVkIGZvciBFUkMtMjAgdG9rZW5zLCBub3IgYXJlIHRoZXkgbmVjZXNzYXJ5LiBQbGVhc2UgcmVtb3ZlIHRoZSAnaG9wJyBwYXJhbWV0ZXIgYW5kIHRyeSBhZ2Fpbi5gXG4gICAgICApO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZSgnZmluYWwtc2lnbiB0cmFuc2FjdGlvbiBmcm9tIFdSVycsIGZ1bmN0aW9uICgpIHtcbiAgaXQoJ3Nob3VsZCBhZGQgYSBzZWNvbmQgc2lnbmF0dXJlIHRvIHVuc2lnbmVkIHN3ZWVwIGZvciB0ZXRoJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvQVBJLCB7IGVudjogJ3Rlc3QnIH0pO1xuXG4gICAgY29uc3QgYmFzZWNvaW46IGFueSA9IGJpdGdvLmNvaW4oJ3RldGgnKTtcbiAgICBjb25zdCBnYXNQcmljZSA9IDIwMDAwMDAwMDAwMDtcbiAgICBjb25zdCBnYXNMaW1pdCA9IDUwMDAwMDtcbiAgICBjb25zdCBwcnYgPVxuICAgICAgJ3hwcnY5czIxWnJRSDE0M0szRDhUWGZ2QUpnSFZmVEVlUU5XNVlzOXdadG5VWmtxUHpGelNqYkVKcldDMXZaNEduWEN2UjdyUUwyVUZYM1JTdVllVTlNckVSbTFYQnZBQ293N2MzNnZuejVpWXlqMic7IC8vIHBsYWNlaG9sZGVyIHRlc3QgcHJ2XG4gICAgY29uc3QgdHggPSB7XG4gICAgICB0eFByZWJ1aWxkOiBmaXh0dXJlcy5XUldVbnNpZ25lZFN3ZWVwRVRIVHgsXG4gICAgICBwcnYsXG4gICAgfTtcbiAgICAvLyBzaWduIHRyYW5zYWN0aW9uIG9uY2VcbiAgICBjb25zdCBoYWxmU2lnbmVkID0gYXdhaXQgYmFzZWNvaW4uc2lnblRyYW5zYWN0aW9uKHR4KTtcblxuICAgIGNvbnN0IHdyYXBwZXIgPSB7fSBhcyBTaWduVHJhbnNhY3Rpb25PcHRpb25zO1xuICAgIHdyYXBwZXIudHhQcmVidWlsZCA9IGhhbGZTaWduZWQ7XG4gICAgd3JhcHBlci50eFByZWJ1aWxkLnJlY2lwaWVudHMgPSBoYWxmU2lnbmVkLmhhbGZTaWduZWQucmVjaXBpZW50cztcbiAgICB3cmFwcGVyLnR4UHJlYnVpbGQuZ2FzUHJpY2UgPSBnYXNQcmljZS50b1N0cmluZygpO1xuICAgIHdyYXBwZXIudHhQcmVidWlsZC5nYXNMaW1pdCA9IGdhc0xpbWl0LnRvU3RyaW5nKCk7XG4gICAgd3JhcHBlci5pc0xhc3RTaWduYXR1cmUgPSB0cnVlO1xuICAgIHdyYXBwZXIud2FsbGV0Q29udHJhY3RBZGRyZXNzID0gZml4dHVyZXMuV1JXVW5zaWduZWRTd2VlcEVUSFR4LndhbGxldENvbnRyYWN0QWRkcmVzcztcbiAgICB3cmFwcGVyLnBydiA9IHBydjtcblxuICAgIC8vIHNpZ24gdHJhbnNhY3Rpb24gdHdpY2Ugd2l0aCB0aGUgXCJpc0xhc3RTaWduYXR1cmVcIiBmbGFnXG4gICAgY29uc3QgZmluYWxTaWduZWRUeCA9IGF3YWl0IGJhc2Vjb2luLnNpZ25UcmFuc2FjdGlvbih3cmFwcGVyKTtcbiAgICBmaW5hbFNpZ25lZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eEhleCcpO1xuICAgIGNvbnN0IHR4QnVpbGRlciA9IGdldEJ1aWxkZXIoJ2V0aCcpO1xuICAgIHR4QnVpbGRlci5mcm9tKCcweCcgKyBmaW5hbFNpZ25lZFR4LnR4SGV4KTsgLy8gYWRkIGEgMHggaW4gZnJvbnQgb2YgdGhpcyB0eGhleFxuICAgIGNvbnN0IHJlYnVpbHRUeCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgIGNvbnN0IG91dHB1dHMgPSByZWJ1aWx0VHgub3V0cHV0cy5tYXAoKG91dHB1dCkgPT4ge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgYWRkcmVzczogb3V0cHV0LmFkZHJlc3MsXG4gICAgICAgIGFtb3VudDogb3V0cHV0LnZhbHVlLFxuICAgICAgfTtcbiAgICB9KTtcbiAgICByZWJ1aWx0VHguc2lnbmF0dXJlLmxlbmd0aC5zaG91bGQuZXF1YWwoMik7XG4gICAgb3V0cHV0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuICAgIG91dHB1dHNbMF0uYWRkcmVzcy5zaG91bGQuZXF1YWwoZml4dHVyZXMuV1JXVW5zaWduZWRTd2VlcEVUSFR4LnJlY2lwaWVudC5hZGRyZXNzKTtcbiAgICBvdXRwdXRzWzBdLmFtb3VudC5zaG91bGQuZXF1YWwoZml4dHVyZXMuV1JXVW5zaWduZWRTd2VlcEVUSFR4LnJlY2lwaWVudC5hbW91bnQpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGFkZCBhIHNlY29uZCBzaWduYXR1cmUgdG8gdW5zaWduZWQgc3dlZXAgZm9yIGVyYzIwIHRva2VuJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvQVBJLCB7IGVudjogJ3Rlc3QnIH0pO1xuICAgIEVyYzIwVG9rZW4uY3JlYXRlVG9rZW5Db25zdHJ1Y3RvcnMoKS5mb3JFYWNoKCh7IG5hbWUsIGNvaW5Db25zdHJ1Y3RvciB9KSA9PiB7XG4gICAgICBiaXRnby5zYWZlUmVnaXN0ZXIobmFtZSwgY29pbkNvbnN0cnVjdG9yKTtcbiAgICB9KTtcbiAgICBjb25zdCBiYXNlY29pbjogYW55ID0gYml0Z28uY29pbigndGRhaScpO1xuICAgIGNvbnN0IGdhc1ByaWNlID0gMjAwMDAwMDAwMDAwO1xuICAgIGNvbnN0IGdhc0xpbWl0ID0gNTAwMDAwO1xuICAgIGNvbnN0IHBydiA9XG4gICAgICAneHBydjlzMjFaclFIMTQzSzMzOTlRQlZ2Ym1oczRSQjVRelhEOFhpVzNOd3RhZVRlbTkzUUdkNVZOanVrVW53SlE5NG5VZ3VnSFNWelNWVmUzUlAxNlVydjFaeWlqcFlkeURhbXN4ZjJTaGJxNHcxJzsgLy8gcGxhY2Vob2xkZXIgdGVzdCBwcnZcbiAgICBjb25zdCB0eCA9IHtcbiAgICAgIHR4UHJlYnVpbGQ6IGZpeHR1cmVzLldSV1Vuc2lnbmVkU3dlZXBFUkMyMFR4LFxuICAgICAgcHJ2LFxuICAgIH07XG4gICAgLy8gc2lnbiB0cmFuc2FjdGlvbiBvbmNlXG4gICAgY29uc3QgaGFsZlNpZ25lZCA9IGF3YWl0IGJhc2Vjb2luLnNpZ25UcmFuc2FjdGlvbih0eCk7XG5cbiAgICBjb25zdCB3cmFwcGVyID0ge30gYXMgU2lnblRyYW5zYWN0aW9uT3B0aW9ucztcbiAgICB3cmFwcGVyLnR4UHJlYnVpbGQgPSBoYWxmU2lnbmVkO1xuICAgIHdyYXBwZXIudHhQcmVidWlsZC5yZWNpcGllbnRzID0gaGFsZlNpZ25lZC5oYWxmU2lnbmVkLnJlY2lwaWVudHM7XG4gICAgd3JhcHBlci50eFByZWJ1aWxkLmdhc1ByaWNlID0gZ2FzUHJpY2UudG9TdHJpbmcoKTtcbiAgICB3cmFwcGVyLnR4UHJlYnVpbGQuZ2FzTGltaXQgPSBnYXNMaW1pdC50b1N0cmluZygpO1xuICAgIHdyYXBwZXIuaXNMYXN0U2lnbmF0dXJlID0gdHJ1ZTtcbiAgICB3cmFwcGVyLndhbGxldENvbnRyYWN0QWRkcmVzcyA9IGZpeHR1cmVzLldSV1Vuc2lnbmVkU3dlZXBFUkMyMFR4LndhbGxldENvbnRyYWN0QWRkcmVzcztcbiAgICB3cmFwcGVyLnBydiA9IHBydjtcblxuICAgIC8vIHNpZ24gdHJhbnNhY3Rpb24gdHdpY2Ugd2l0aCB0aGUgXCJpc0xhc3RTaWduYXR1cmVcIiBmbGFnXG4gICAgY29uc3QgZmluYWxTaWduZWRUeCA9IGF3YWl0IGJhc2Vjb2luLnNpZ25UcmFuc2FjdGlvbih3cmFwcGVyKTtcbiAgICBmaW5hbFNpZ25lZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eEhleCcpO1xuICAgIGNvbnN0IHR4QnVpbGRlciA9IGdldEJ1aWxkZXIoJ2V0aCcpO1xuICAgIHR4QnVpbGRlci5mcm9tKCcweCcgKyBmaW5hbFNpZ25lZFR4LnR4SGV4KTsgLy8gYWRkIGEgMHggaW4gZnJvbnQgb2YgdGhpcyB0eGhleFxuICAgIGNvbnN0IHJlYnVpbHRUeCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgIGNvbnN0IG91dHB1dHMgPSByZWJ1aWx0VHgub3V0cHV0cy5tYXAoKG91dHB1dCkgPT4ge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgYWRkcmVzczogb3V0cHV0LmFkZHJlc3MsXG4gICAgICAgIGFtb3VudDogb3V0cHV0LnZhbHVlLFxuICAgICAgfTtcbiAgICB9KTtcbiAgICByZWJ1aWx0VHguc2lnbmF0dXJlLmxlbmd0aC5zaG91bGQuZXF1YWwoMik7XG4gICAgb3V0cHV0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuICAgIG91dHB1dHNbMF0uYWRkcmVzcy5zaG91bGQuZXF1YWwoZml4dHVyZXMuV1JXVW5zaWduZWRTd2VlcEVSQzIwVHgucmVjaXBpZW50LmFkZHJlc3MpO1xuICAgIG91dHB1dHNbMF0uYW1vdW50LnNob3VsZC5lcXVhbChmaXh0dXJlcy5XUldVbnNpZ25lZFN3ZWVwRVJDMjBUeC5yZWNpcGllbnQuYW1vdW50KTtcbiAgfSk7XG59KTtcbiJdfQ==
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ethMultiSigBackupKey.d.ts","sourceRoot":"","sources":["../../../../test/unit/fixtures/ethMultiSigBackupKey.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB;;CAMhC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ethMultiSigBackupKey = void 0;
|
|
4
|
+
exports.ethMultiSigBackupKey = {
|
|
5
|
+
key: '{"iv":"aT3q3wZuRF1KZmAwBgbTAg==","v":1,"iter":10000,"ks":256,"ts":64,"mode"\n' +
|
|
6
|
+
':"ccm","adata":"","cipher":"aes","salt":"CcVKl6CewXI=","ct":"C2vf/Cnf2H8UW9\n' +
|
|
7
|
+
'RsMnlUUOlXa8bzVUhCLGDL0Oulv1RDHl6iM8otzokdmz8IPMENjJf9z0qua1jnbiwPjW7FP14FV\n' +
|
|
8
|
+
'M1ku0v8lUFtYPGj/rzA5aSm2pPqAKe1uutC1tvG0aEWg+V5h02EXxvleFUfCsrVMqOez/0="}',
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXRoTXVsdGlTaWdCYWNrdXBLZXkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L3VuaXQvZml4dHVyZXMvZXRoTXVsdGlTaWdCYWNrdXBLZXkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQWEsUUFBQSxvQkFBb0IsR0FBRztJQUNsQyxHQUFHLEVBQ0QsK0VBQStFO1FBQy9FLCtFQUErRTtRQUMvRSwrRUFBK0U7UUFDL0UsMkVBQTJFO0NBQzlFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgY29uc3QgZXRoTXVsdGlTaWdCYWNrdXBLZXkgPSB7XG4gIGtleTpcbiAgICAne1wiaXZcIjpcImFUM3Ezd1p1UkYxS1ptQXdCZ2JUQWc9PVwiLFwidlwiOjEsXCJpdGVyXCI6MTAwMDAsXCJrc1wiOjI1NixcInRzXCI6NjQsXCJtb2RlXCJcXG4nICtcbiAgICAnOlwiY2NtXCIsXCJhZGF0YVwiOlwiXCIsXCJjaXBoZXJcIjpcImFlc1wiLFwic2FsdFwiOlwiQ2NWS2w2Q2V3WEk9XCIsXCJjdFwiOlwiQzJ2Zi9DbmYySDhVVzlcXG4nICtcbiAgICAnUnNNbmxVVU9sWGE4YnpWVWhDTEdETDBPdWx2MVJESGw2aU04b3R6b2tkbXo4SVBNRU5qSmY5ejBxdWExam5iaXdQalc3RlAxNEZWXFxuJyArXG4gICAgJ00xa3UwdjhsVUZ0WVBHai9yekE1YVNtMnBQcUFLZTF1dXRDMXR2RzBhRVdnK1Y1aDAyRVh4dmxlRlVmQ3NyVk1xT2V6LzA9XCJ9Jyxcbn07XG4iXX0=
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ethTssBackupKey.d.ts","sourceRoot":"","sources":["../../../../test/unit/fixtures/ethTssBackupKey.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe;;;CAsB3B,CAAC"}
|