@bitgo-beta/sdk-coin-xdc 1.0.1-beta.142 → 1.0.1-beta.1421
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/index.d.ts +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -1
- package/dist/src/lib/XDCValidatorABI.json +431 -0
- package/dist/src/lib/index.d.ts +4 -0
- package/dist/src/lib/index.d.ts.map +1 -1
- package/dist/src/lib/index.js +12 -2
- package/dist/src/lib/transactionBuilder.d.ts +24 -2
- package/dist/src/lib/transactionBuilder.d.ts.map +1 -1
- package/dist/src/lib/transactionBuilder.js +55 -3
- package/dist/src/lib/uploadKycBuilder.d.ts +73 -0
- package/dist/src/lib/uploadKycBuilder.d.ts.map +1 -0
- package/dist/src/lib/uploadKycBuilder.js +110 -0
- package/dist/src/lib/validatorContract.d.ts +136 -0
- package/dist/src/lib/validatorContract.d.ts.map +1 -0
- package/dist/src/lib/validatorContract.js +62 -0
- package/dist/src/lib/xdcKycMessage.d.ts +26 -0
- package/dist/src/lib/xdcKycMessage.d.ts.map +1 -0
- package/dist/src/lib/xdcKycMessage.js +38 -0
- package/dist/src/register.d.ts.map +1 -1
- package/dist/src/register.js +5 -1
- package/dist/src/xdc.d.ts +2 -1
- package/dist/src/xdc.d.ts.map +1 -1
- package/dist/src/xdc.js +4 -1
- package/dist/src/xdcToken.d.ts +27 -0
- package/dist/src/xdcToken.d.ts.map +1 -0
- package/dist/src/xdcToken.js +50 -0
- package/dist/test/resources.d.ts +45 -0
- package/dist/test/resources.d.ts.map +1 -0
- package/dist/test/resources.js +107 -0
- package/dist/test/unit/getBuilder.d.ts +3 -0
- package/dist/test/unit/getBuilder.d.ts.map +1 -0
- package/dist/test/unit/getBuilder.js +10 -0
- package/dist/test/unit/transactionBuilder/send.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/send.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/send.js +19 -0
- package/dist/test/unit/transactionBuilder/uploadKyc.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/uploadKyc.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/uploadKyc.js +215 -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 +27 -0
- package/dist/test/unit/xdc.d.ts +2 -0
- package/dist/test/unit/xdc.d.ts.map +1 -0
- package/dist/test/unit/xdc.js +321 -0
- package/dist/test/unit/xdcKycMessage.d.ts +2 -0
- package/dist/test/unit/xdcKycMessage.d.ts.map +1 -0
- package/dist/test/unit/xdcKycMessage.js +104 -0
- package/dist/test/unit/xdcToken.d.ts +2 -0
- package/dist/test/unit/xdcToken.d.ts.map +1 -0
- package/dist/test/unit/xdcToken.js +189 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +17 -11
- package/.eslintignore +0 -5
- package/.mocharc.yml +0 -8
- package/CHANGELOG.md +0 -74
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
require("should");
|
|
4
|
+
const sdk_test_1 = require("@bitgo-beta/sdk-test");
|
|
5
|
+
const sdk_api_1 = require("@bitgo-beta/sdk-api");
|
|
6
|
+
const sdk_core_1 = require("@bitgo-beta/sdk-core");
|
|
7
|
+
const src_1 = require("../../src");
|
|
8
|
+
const getBuilder_1 = require("./getBuilder");
|
|
9
|
+
/** Encode ERC-20 transfer(address,uint256) calldata without ethereumjs-abi. */
|
|
10
|
+
function encodeErc20Transfer(to, amount) {
|
|
11
|
+
const address = to.toLowerCase().replace(/^0x/, '').padStart(64, '0');
|
|
12
|
+
const value = BigInt(amount).toString(16).padStart(64, '0');
|
|
13
|
+
return `0xa9059cbb${address}${value}`;
|
|
14
|
+
}
|
|
15
|
+
describe('XDC Token:', function () {
|
|
16
|
+
let bitgo;
|
|
17
|
+
let xdcTokenCoin;
|
|
18
|
+
const tokenName = 'xdc:usdc';
|
|
19
|
+
before(function () {
|
|
20
|
+
bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'prod' });
|
|
21
|
+
(0, src_1.register)(bitgo);
|
|
22
|
+
bitgo.initializeTestVars();
|
|
23
|
+
xdcTokenCoin = bitgo.coin(tokenName);
|
|
24
|
+
});
|
|
25
|
+
it('should return constants', function () {
|
|
26
|
+
xdcTokenCoin.getChain().should.equal('xdc:usdc');
|
|
27
|
+
xdcTokenCoin.getBaseChain().should.equal('xdc');
|
|
28
|
+
xdcTokenCoin.getFullName().should.equal('XDC Token');
|
|
29
|
+
xdcTokenCoin.getBaseFactor().should.equal(1e6);
|
|
30
|
+
xdcTokenCoin.type.should.equal(tokenName);
|
|
31
|
+
xdcTokenCoin.name.should.equal('USD Coin');
|
|
32
|
+
xdcTokenCoin.coin.should.equal('xdc');
|
|
33
|
+
xdcTokenCoin.network.should.equal('Mainnet');
|
|
34
|
+
xdcTokenCoin.decimalPlaces.should.equal(6);
|
|
35
|
+
});
|
|
36
|
+
describe('Token Registration and TransactionBuilder', function () {
|
|
37
|
+
const mainnetTokens = ['xdc:usdc', 'xdc:lbt', 'xdc:gama', 'xdc:srx', 'xdc:weth'];
|
|
38
|
+
const testnetTokens = ['txdc:tmt'];
|
|
39
|
+
describe('Mainnet tokens', function () {
|
|
40
|
+
mainnetTokens.forEach((tokenName) => {
|
|
41
|
+
it(`${tokenName} should be registered as XdcToken`, function () {
|
|
42
|
+
const token = bitgo.coin(tokenName);
|
|
43
|
+
token.should.be.instanceOf(src_1.XdcToken);
|
|
44
|
+
});
|
|
45
|
+
it(`${tokenName} should create TransactionBuilder without error`, function () {
|
|
46
|
+
const token = bitgo.coin(tokenName);
|
|
47
|
+
// @ts-expect-error - accessing protected method for testing
|
|
48
|
+
(() => token.getTransactionBuilder()).should.not.throw();
|
|
49
|
+
});
|
|
50
|
+
it(`${tokenName} should use XDC-specific TransactionBuilder`, function () {
|
|
51
|
+
const token = bitgo.coin(tokenName);
|
|
52
|
+
// @ts-expect-error - accessing protected method for testing
|
|
53
|
+
const builder = token.getTransactionBuilder();
|
|
54
|
+
builder.should.have.property('_common');
|
|
55
|
+
// Verify it's using XDC's getCommon, not EVM's
|
|
56
|
+
// XDC's TransactionBuilder should create successfully without SHARED_EVM_SDK feature
|
|
57
|
+
builder.constructor.name.should.equal('TransactionBuilder');
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
describe('Testnet tokens', function () {
|
|
62
|
+
testnetTokens.forEach((tokenName) => {
|
|
63
|
+
it(`${tokenName} should be registered as XdcToken`, function () {
|
|
64
|
+
const token = bitgo.coin(tokenName);
|
|
65
|
+
token.should.be.instanceOf(src_1.XdcToken);
|
|
66
|
+
});
|
|
67
|
+
it(`${tokenName} should create TransactionBuilder without error`, function () {
|
|
68
|
+
const token = bitgo.coin(tokenName);
|
|
69
|
+
// @ts-expect-error - accessing protected method for testing
|
|
70
|
+
(() => token.getTransactionBuilder()).should.not.throw();
|
|
71
|
+
});
|
|
72
|
+
it(`${tokenName} should use XDC-specific TransactionBuilder`, function () {
|
|
73
|
+
const token = bitgo.coin(tokenName);
|
|
74
|
+
// @ts-expect-error - accessing protected method for testing
|
|
75
|
+
const builder = token.getTransactionBuilder();
|
|
76
|
+
builder.should.have.property('_common');
|
|
77
|
+
builder.constructor.name.should.equal('TransactionBuilder');
|
|
78
|
+
});
|
|
79
|
+
it(`${tokenName} should have correct base chain`, function () {
|
|
80
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
81
|
+
const token = bitgo.coin(tokenName);
|
|
82
|
+
token.getBaseChain().should.equal('txdc');
|
|
83
|
+
});
|
|
84
|
+
it(`${tokenName} should not throw "Cannot use common sdk module" error`, function () {
|
|
85
|
+
const token = bitgo.coin(tokenName);
|
|
86
|
+
let errorThrown = false;
|
|
87
|
+
let errorMessage = '';
|
|
88
|
+
try {
|
|
89
|
+
// @ts-expect-error - accessing protected method for testing
|
|
90
|
+
const builder = token.getTransactionBuilder();
|
|
91
|
+
// Try to use the builder to ensure it's fully functional
|
|
92
|
+
// @ts-expect-error - type expects TransactionType enum
|
|
93
|
+
builder.type('Send');
|
|
94
|
+
}
|
|
95
|
+
catch (e) {
|
|
96
|
+
errorThrown = true;
|
|
97
|
+
errorMessage = e.message;
|
|
98
|
+
}
|
|
99
|
+
errorThrown.should.equal(false);
|
|
100
|
+
errorMessage.should.not.match(/Cannot use common sdk module/);
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
it('should verify all XDC tokens use XdcToken class, not EthLikeErc20Token', function () {
|
|
105
|
+
const allTokens = [...mainnetTokens, ...testnetTokens];
|
|
106
|
+
allTokens.forEach((tokenName) => {
|
|
107
|
+
const token = bitgo.coin(tokenName);
|
|
108
|
+
token.should.be.instanceOf(src_1.XdcToken);
|
|
109
|
+
token.constructor.name.should.equal('XdcToken');
|
|
110
|
+
token.constructor.name.should.not.equal('EthLikeErc20Token');
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
describe('verifyTssTransaction', function () {
|
|
115
|
+
const recipientAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
|
|
116
|
+
const wrongAddress = '0x7e85bdc27c050e3905ebf4b8e634d9ad6edd0de6';
|
|
117
|
+
const tokenContractAddress = '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48';
|
|
118
|
+
it('should accept an ERC-20 transfer where calldata matches declared recipient', async function () {
|
|
119
|
+
const token = bitgo.coin('txdc:tmt');
|
|
120
|
+
const erc20TransferData = encodeErc20Transfer(recipientAddress, '10000000');
|
|
121
|
+
const txBuilder = (0, getBuilder_1.getBuilder)('txdc');
|
|
122
|
+
txBuilder.type(sdk_core_1.TransactionType.ContractCall);
|
|
123
|
+
txBuilder.fee({ fee: '10', gasLimit: '60000' });
|
|
124
|
+
txBuilder.counter(1);
|
|
125
|
+
txBuilder.contract(tokenContractAddress);
|
|
126
|
+
txBuilder.data(erc20TransferData);
|
|
127
|
+
const tx = await txBuilder.build();
|
|
128
|
+
const txHex = tx.toBroadcastFormat();
|
|
129
|
+
const wallet = new sdk_core_1.Wallet(bitgo, token, { coinSpecific: { baseAddress: recipientAddress } });
|
|
130
|
+
const result = await token.verifyTssTransaction({
|
|
131
|
+
txParams: {
|
|
132
|
+
type: 'transfer',
|
|
133
|
+
recipients: [{ address: recipientAddress, amount: '10000000' }],
|
|
134
|
+
},
|
|
135
|
+
txPrebuild: { txHex, coin: 'txdc:tmt', walletId: 'fakeWalletId' },
|
|
136
|
+
wallet,
|
|
137
|
+
});
|
|
138
|
+
result.should.equal(true);
|
|
139
|
+
});
|
|
140
|
+
it('should reject an ERC-20 transfer when calldata recipient does not match declared recipient', async function () {
|
|
141
|
+
const token = bitgo.coin('txdc:tmt');
|
|
142
|
+
const erc20TransferData = encodeErc20Transfer(wrongAddress, '10000000');
|
|
143
|
+
const txBuilder = (0, getBuilder_1.getBuilder)('txdc');
|
|
144
|
+
txBuilder.type(sdk_core_1.TransactionType.ContractCall);
|
|
145
|
+
txBuilder.fee({ fee: '10', gasLimit: '60000' });
|
|
146
|
+
txBuilder.counter(1);
|
|
147
|
+
txBuilder.contract(tokenContractAddress);
|
|
148
|
+
txBuilder.data(erc20TransferData);
|
|
149
|
+
const tx = await txBuilder.build();
|
|
150
|
+
const txHex = tx.toBroadcastFormat();
|
|
151
|
+
const wallet = new sdk_core_1.Wallet(bitgo, token, { coinSpecific: { baseAddress: recipientAddress } });
|
|
152
|
+
await token
|
|
153
|
+
.verifyTssTransaction({
|
|
154
|
+
txParams: {
|
|
155
|
+
type: 'transfer',
|
|
156
|
+
recipients: [{ address: recipientAddress, amount: '10000000' }],
|
|
157
|
+
},
|
|
158
|
+
txPrebuild: { txHex, coin: 'txdc:tmt', walletId: 'fakeWalletId' },
|
|
159
|
+
wallet,
|
|
160
|
+
})
|
|
161
|
+
.should.be.rejectedWith('destination address does not match with the recipient address');
|
|
162
|
+
});
|
|
163
|
+
it('should throw error when txParams.recipients is missing and no valid type', async function () {
|
|
164
|
+
const token = bitgo.coin('txdc:tmt');
|
|
165
|
+
const wallet = new sdk_core_1.Wallet(bitgo, token, { coinSpecific: { baseAddress: recipientAddress } });
|
|
166
|
+
await token
|
|
167
|
+
.verifyTssTransaction({
|
|
168
|
+
txParams: {},
|
|
169
|
+
txPrebuild: { txHex: '0x00', coin: 'txdc:tmt', walletId: 'fakeWalletId' },
|
|
170
|
+
wallet,
|
|
171
|
+
})
|
|
172
|
+
.should.be.rejectedWith('missing txParams');
|
|
173
|
+
});
|
|
174
|
+
it('should throw error when wallet is missing', async function () {
|
|
175
|
+
const token = bitgo.coin('txdc:tmt');
|
|
176
|
+
await token
|
|
177
|
+
.verifyTssTransaction({
|
|
178
|
+
txParams: {
|
|
179
|
+
type: 'transfer',
|
|
180
|
+
recipients: [{ address: recipientAddress, amount: '10000000' }],
|
|
181
|
+
},
|
|
182
|
+
txPrebuild: { txHex: '0x00', coin: 'txdc:tmt', walletId: 'fakeWalletId' },
|
|
183
|
+
wallet: undefined,
|
|
184
|
+
})
|
|
185
|
+
.should.be.rejectedWith('missing params');
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoieGRjVG9rZW4uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90ZXN0L3VuaXQveGRjVG9rZW4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxrQkFBZ0I7QUFDaEIsbURBQStEO0FBQy9ELGlEQUErQztBQUMvQyxtREFBK0Q7QUFFL0QsbUNBQStDO0FBRS9DLDZDQUEwQztBQUUxQywrRUFBK0U7QUFDL0UsU0FBUyxtQkFBbUIsQ0FBQyxFQUFVLEVBQUUsTUFBYztJQUNyRCxNQUFNLE9BQU8sR0FBRyxFQUFFLENBQUMsV0FBVyxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ3RFLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUM1RCxPQUFPLGFBQWEsT0FBTyxHQUFHLEtBQUssRUFBRSxDQUFDO0FBQ3hDLENBQUM7QUFFRCxRQUFRLENBQUMsWUFBWSxFQUFFO0lBQ3JCLElBQUksS0FBbUIsQ0FBQztJQUN4QixJQUFJLFlBQVksQ0FBQztJQUNqQixNQUFNLFNBQVMsR0FBRyxVQUFVLENBQUM7SUFFN0IsTUFBTSxDQUFDO1FBQ0wsS0FBSyxHQUFHLG9CQUFTLENBQUMsUUFBUSxDQUFDLGtCQUFRLEVBQUUsRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUN0RCxJQUFBLGNBQVEsRUFBQyxLQUFLLENBQUMsQ0FBQztRQUNoQixLQUFLLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUMzQixZQUFZLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUN2QyxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyx5QkFBeUIsRUFBRTtRQUM1QixZQUFZLENB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QUFhLENBQUM7WUFFakQsTUFBTSxLQUFLO2lCQUNSLG9CQUFvQixDQUFDO2dCQUNwQixRQUFRLEVBQUU7b0JBQ1IsSUFBSSxFQUFFLFVBQVU7b0JBQ2hCLFVBQVUsRUFBRSxDQUFDLEVBQUUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsQ0FBQztpQkFDekQ7Z0JBQ1IsVUFBVSxFQUFFLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxjQUFjLEVBQVM7Z0JBQ2hGLE1BQU0sRUFBRSxTQUE4QjthQUN2QyxDQUFDO2lCQUNELE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDOUMsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICdzaG91bGQnO1xuaW1wb3J0IHsgVGVzdEJpdEdvLCBUZXN0Qml0R29BUEkgfSBmcm9tICdAYml0Z28tYmV0YS9zZGstdGVzdCc7XG5pbXBvcnQgeyBCaXRHb0FQSSB9IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1hcGknO1xuaW1wb3J0IHsgVHJhbnNhY3Rpb25UeXBlLCBXYWxsZXQgfSBmcm9tICdAYml0Z28tYmV0YS9zZGstY29yZSc7XG5cbmltcG9ydCB7IHJlZ2lzdGVyLCBYZGNUb2tlbiB9IGZyb20gJy4uLy4uL3NyYyc7XG5pbXBvcnQgeyBUcmFuc2FjdGlvbkJ1aWxkZXIgfSBmcm9tICcuLi8uLi9zcmMvbGliJztcbmltcG9ydCB7IGdldEJ1aWxkZXIgfSBmcm9tICcuL2dldEJ1aWxkZXInO1xuXG4vKiogRW5jb2RlIEVSQy0yMCB0cmFuc2ZlcihhZGRyZXNzLHVpbnQyNTYpIGNhbGxkYXRhIHdpdGhvdXQgZXRoZXJldW1qcy1hYmkuICovXG5mdW5jdGlvbiBlbmNvZGVFcmMyMFRyYW5zZmVyKHRvOiBzdHJpbmcsIGFtb3VudDogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgYWRkcmVzcyA9IHRvLnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvXjB4LywgJycpLnBhZFN0YXJ0KDY0LCAnMCcpO1xuICBjb25zdCB2YWx1ZSA9IEJpZ0ludChhbW91bnQpLnRvU3RyaW5nKDE2KS5wYWRTdGFydCg2NCwgJzAnKTtcbiAgcmV0dXJuIGAweGE5MDU5Y2JiJHthZGRyZXNzfSR7dmFsdWV9YDtcbn1cblxuZGVzY3JpYmUoJ1hEQyBUb2tlbjonLCBmdW5jdGlvbiAoKSB7XG4gIGxldCBiaXRnbzogVGVzdEJpdEdvQVBJO1xuICBsZXQgeGRjVG9rZW5Db2luO1xuICBjb25zdCB0b2tlbk5hbWUgPSAneGRjOnVzZGMnO1xuXG4gIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgYml0Z28gPSBUZXN0Qml0R28uZGVjb3JhdGUoQml0R29BUEksIHsgZW52OiAncHJvZCcgfSk7XG4gICAgcmVnaXN0ZXIoYml0Z28pO1xuICAgIGJpdGdvLmluaXRpYWxpemVUZXN0VmFycygpO1xuICAgIHhkY1Rva2VuQ29pbiA9IGJpdGdvLmNvaW4odG9rZW5OYW1lKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCByZXR1cm4gY29uc3RhbnRzJywgZnVuY3Rpb24gKCkge1xuICAgIHhkY1Rva2VuQ29pbi5nZXRDaGFpbigpLnNob3VsZC5lcXVhbCgneGRjOnVzZGMnKTtcbiAgICB4ZGNUb2tlbkNvaW4uZ2V0QmFzZUNoYWluKCkuc2hvdWxkLmVxdWFsKCd4ZGMnKTtcbiAgICB4ZGNUb2tlbkNvaW4uZ2V0RnVsbE5hbWUoKS5zaG91bGQuZXF1YWwoJ1hEQyBUb2tlbicpO1xuICAgIHhkY1Rva2VuQ29pbi5nZXRCYXNlRmFjdG9yKCkuc2hvdWxkLmVxdWFsKDFlNik7XG4gICAgeGRjVG9rZW5Db2luLnR5cGUuc2hvdWxkLmVxdWFsKHRva2VuTmFtZSk7XG4gICAgeGRjVG9rZW5Db2luLm5hbWUuc2hvdWxkLmVxdWFsKCdVU0QgQ29pbicpO1xuICAgIHhkY1Rva2VuQ29pbi5jb2luLnNob3VsZC5lcXVhbCgneGRjJyk7XG4gICAgeGRjVG9rZW5Db2luLm5ldHdvcmsuc2hvdWxkLmVxdWFsKCdNYWlubmV0Jyk7XG4gICAgeGRjVG9rZW5Db2luLmRlY2ltYWxQbGFjZXMuc2hvdWxkLmVxdWFsKDYpO1xuICB9KTtcblxuICBkZXNjcmliZSgnVG9rZW4gUmVnaXN0cmF0aW9uIGFuZCBUcmFuc2FjdGlvbkJ1aWxkZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgbWFpbm5ldFRva2VucyA9IFsneGRjOnVzZGMnLCAneGRjOmxidCcsICd4ZGM6Z2FtYScsICd4ZGM6c3J4JywgJ3hkYzp3ZXRoJ107XG4gICAgY29uc3QgdGVzdG5ldFRva2VucyA9IFsndHhkYzp0bXQnXTtcblxuICAgIGRlc2NyaWJlKCdNYWlubmV0IHRva2VucycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIG1haW5uZXRUb2tlbnMuZm9yRWFjaCgodG9rZW5OYW1lKSA9PiB7XG4gICAgICAgIGl0KGAke3Rva2VuTmFtZX0gc2hvdWxkIGJlIHJlZ2lzdGVyZWQgYXMgWGRjVG9rZW5gLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3QgdG9rZW4gPSBiaXRnby5jb2luKHRva2VuTmFtZSk7XG4gICAgICAgICAgdG9rZW4uc2hvdWxkLmJlLmluc3RhbmNlT2YoWGRjVG9rZW4pO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdChgJHt0b2tlbk5hbWV9IHNob3VsZCBjcmVhdGUgVHJhbnNhY3Rpb25CdWlsZGVyIHdpdGhvdXQgZXJyb3JgLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3QgdG9rZW4gPSBiaXRnby5jb2luKHRva2VuTmFtZSkgYXMgWGRjVG9rZW47XG4gICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciAtIGFjY2Vzc2luZyBwcm90ZWN0ZWQgbWV0aG9kIGZvciB0ZXN0aW5nXG4gICAgICAgICAgKCgpID0+IHRva2VuLmdldFRyYW5zYWN0aW9uQnVpbGRlcigpKS5zaG91bGQubm90LnRocm93KCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KGAke3Rva2VuTmFtZX0gc2hvdWxkIHVzZSBYREMtc3BlY2lmaWMgVHJhbnNhY3Rpb25CdWlsZGVyYCwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IHRva2VuID0gYml0Z28uY29pbih0b2tlbk5hbWUpIGFzIFhkY1Rva2VuO1xuICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgLSBhY2Nlc3NpbmcgcHJvdGVjdGVkIG1ldGhvZCBmb3IgdGVzdGluZ1xuICAgICAgICAgIGNvbnN0IGJ1aWxkZXIgPSB0b2tlbi5nZXRUcmFuc2FjdGlvbkJ1aWxkZXIoKTtcbiAgICAgICAgICBidWlsZGVyLnNob3VsZC5oYXZlLnByb3BlcnR5KCdfY29tbW9uJyk7XG4gICAgICAgICAgLy8gVmVyaWZ5IGl0J3MgdXNpbmcgWERDJ3MgZ2V0Q29tbW9uLCBub3QgRVZNJ3NcbiAgICAgICAgICAvLyBYREMncyBUcmFuc2FjdGlvbkJ1aWxkZXIgc2hvdWxkIGNyZWF0ZSBzdWNjZXNzZnVsbHkgd2l0aG91dCBTSEFSRURfRVZNX1NESyBmZWF0dXJlXG4gICAgICAgICAgYnVpbGRlci5jb25zdHJ1Y3Rvci5uYW1lLnNob3VsZC5lcXVhbCgnVHJhbnNhY3Rpb25CdWlsZGVyJyk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnVGVzdG5ldCB0b2tlbnMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICB0ZXN0bmV0VG9rZW5zLmZvckVhY2goKHRva2VuTmFtZSkgPT4ge1xuICAgICAgICBpdChgJHt0b2tlbk5hbWV9IHNob3VsZCBiZSByZWdpc3RlcmVkIGFzIFhkY1Rva2VuYCwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IHRva2VuID0gYml0Z28uY29pbih0b2tlbk5hbWUpO1xuICAgICAgICAgIHRva2VuLnNob3VsZC5iZS5pbnN0YW5jZU9mKFhkY1Rva2VuKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoYCR7dG9rZW5OYW1lfSBzaG91bGQgY3JlYXRlIFRyYW5zYWN0aW9uQnVpbGRlciB3aXRob3V0IGVycm9yYCwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IHRva2VuID0gYml0Z28uY29pbih0b2tlbk5hbWUpIGFzIFhkY1Rva2VuO1xuICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgLSBhY2Nlc3NpbmcgcHJvdGVjdGVkIG1ldGhvZCBmb3IgdGVzdGluZ1xuICAgICAgICAgICgoKSA9PiB0b2tlbi5nZXRUcmFuc2FjdGlvbkJ1aWxkZXIoKSkuc2hvdWxkLm5vdC50aHJvdygpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdChgJHt0b2tlbk5hbWV9IHNob3VsZCB1c2UgWERDLXNwZWNpZmljIFRyYW5zYWN0aW9uQnVpbGRlcmAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCB0b2tlbiA9IGJpdGdvLmNvaW4odG9rZW5OYW1lKSBhcyBYZGNUb2tlbjtcbiAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIC0gYWNjZXNzaW5nIHByb3RlY3RlZCBtZXRob2QgZm9yIHRlc3RpbmdcbiAgICAgICAgICBjb25zdCBidWlsZGVyID0gdG9rZW4uZ2V0VHJhbnNhY3Rpb25CdWlsZGVyKCk7XG4gICAgICAgICAgYnVpbGRlci5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnX2NvbW1vbicpO1xuICAgICAgICAgIGJ1aWxkZXIuY29uc3RydWN0b3IubmFtZS5zaG91bGQuZXF1YWwoJ1RyYW5zYWN0aW9uQnVpbGRlcicpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdChgJHt0b2tlbk5hbWV9IHNob3VsZCBoYXZlIGNvcnJlY3QgYmFzZSBjaGFpbmAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgICAgIGNvbnN0IHRva2VuOiBhbnkgPSBiaXRnby5jb2luKHRva2VuTmFtZSk7XG4gICAgICAgICAgdG9rZW4uZ2V0QmFzZUNoYWluKCkuc2hvdWxkLmVxdWFsKCd0eGRjJyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KGAke3Rva2VuTmFtZX0gc2hvdWxkIG5vdCB0aHJvdyBcIkNhbm5vdCB1c2UgY29tbW9uIHNkayBtb2R1bGVcIiBlcnJvcmAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCB0b2tlbiA9IGJpdGdvLmNvaW4odG9rZW5OYW1lKSBhcyBYZGNUb2tlbjtcbiAgICAgICAgICBsZXQgZXJyb3JUaHJvd24gPSBmYWxzZTtcbiAgICAgICAgICBsZXQgZXJyb3JNZXNzYWdlID0gJyc7XG5cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciAtIGFjY2Vzc2luZyBwcm90ZWN0ZWQgbWV0aG9kIGZvciB0ZXN0aW5nXG4gICAgICAgICAgICBjb25zdCBidWlsZGVyID0gdG9rZW4uZ2V0VHJhbnNhY3Rpb25CdWlsZGVyKCk7XG4gICAgICAgICAgICAvLyBUcnkgdG8gdXNlIHRoZSBidWlsZGVyIHRvIGVuc3VyZSBpdCdzIGZ1bGx5IGZ1bmN0aW9uYWxcbiAgICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgLSB0eXBlIGV4cGVjdHMgVHJhbnNhY3Rpb25UeXBlIGVudW1cbiAgICAgICAgICAgIGJ1aWxkZXIudHlwZSgnU2VuZCcpO1xuICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGVycm9yVGhyb3duID0gdHJ1ZTtcbiAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IChlIGFzIEVycm9yKS5tZXNzYWdlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGVycm9yVGhyb3duLnNob3VsZC5lcXVhbChmYWxzZSk7XG4gICAgICAgICAgZXJyb3JNZXNzYWdlLnNob3VsZC5ub3QubWF0Y2goL0Nhbm5vdCB1c2UgY29tbW9uIHNkayBtb2R1bGUvKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IGFsbCBYREMgdG9rZW5zIHVzZSBYZGNUb2tlbiBjbGFzcywgbm90IEV0aExpa2VFcmMyMFRva2VuJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWxsVG9rZW5zID0gWy4uLm1haW5uZXRUb2tlbnMsIC4uLnRlc3RuZXRUb2tlbnNdO1xuXG4gICAgICBhbGxUb2tlbnMuZm9yRWFjaCgodG9rZW5OYW1lKSA9PiB7XG4gICAgICAgIGNvbnN0IHRva2VuID0gYml0Z28uY29pbih0b2tlbk5hbWUpO1xuICAgICAgICB0b2tlbi5zaG91bGQuYmUuaW5zdGFuY2VPZihYZGNUb2tlbik7XG4gICAgICAgIHRva2VuLmNvbnN0cnVjdG9yLm5hbWUuc2hvdWxkLmVxdWFsKCdYZGNUb2tlbicpO1xuICAgICAgICB0b2tlbi5jb25zdHJ1Y3Rvci5uYW1lLnNob3VsZC5ub3QuZXF1YWwoJ0V0aExpa2VFcmMyMFRva2VuJyk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3ZlcmlmeVRzc1RyYW5zYWN0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHJlY2lwaWVudEFkZHJlc3MgPSAnMHgxNzRjZmQ4MjNhZjhjZTI3ZWQwYWZlZTNmY2YzYzNiYTI1OTExNmJlJztcbiAgICBjb25zdCB3cm9uZ0FkZHJlc3MgPSAnMHg3ZTg1YmRjMjdjMDUwZTM5MDVlYmY0YjhlNjM0ZDlhZDZlZGQwZGU2JztcbiAgICBjb25zdCB0b2tlbkNvbnRyYWN0QWRkcmVzcyA9ICcweGEwYjg2OTkxYzYyMThiMzZjMWQxOWQ0YTJlOWViMGNlMzYwNmViNDgnO1xuXG4gICAgaXQoJ3Nob3VsZCBhY2NlcHQgYW4gRVJDLTIwIHRyYW5zZmVyIHdoZXJlIGNhbGxkYXRhIG1hdGNoZXMgZGVjbGFyZWQgcmVjaXBpZW50JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdG9rZW4gPSBiaXRnby5jb2luKCd0eGRjOnRtdCcpIGFzIFhkY1Rva2VuO1xuXG4gICAgICBjb25zdCBlcmMyMFRyYW5zZmVyRGF0YSA9IGVuY29kZUVyYzIwVHJhbnNmZXIocmVjaXBpZW50QWRkcmVzcywgJzEwMDAwMDAwJyk7XG5cbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGdldEJ1aWxkZXIoJ3R4ZGMnKSBhcyBUcmFuc2FjdGlvbkJ1aWxkZXI7XG4gICAgICB0eEJ1aWxkZXIudHlwZShUcmFuc2FjdGlvblR5cGUuQ29udHJhY3RDYWxsKTtcbiAgICAgIHR4QnVpbGRlci5mZWUoeyBmZWU6ICcxMCcsIGdhc0xpbWl0OiAnNjAwMDAnIH0pO1xuICAgICAgdHhCdWlsZGVyLmNvdW50ZXIoMSk7XG4gICAgICB0eEJ1aWxkZXIuY29udHJhY3QodG9rZW5Db250cmFjdEFkZHJlc3MpO1xuICAgICAgdHhCdWlsZGVyLmRhdGEoZXJjMjBUcmFuc2ZlckRhdGEpO1xuICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHR4SGV4ID0gdHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcblxuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgdG9rZW4sIHsgY29pblNwZWNpZmljOiB7IGJhc2VBZGRyZXNzOiByZWNpcGllbnRBZGRyZXNzIH0gfSk7XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRva2VuLnZlcmlmeVRzc1RyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQYXJhbXM6IHtcbiAgICAgICAgICB0eXBlOiAndHJhbnNmZXInLFxuICAgICAgICAgIHJlY2lwaWVudHM6IFt7IGFkZHJlc3M6IHJlY2lwaWVudEFkZHJlc3MsIGFtb3VudDogJzEwMDAwMDAwJyB9XSxcbiAgICAgICAgfSBhcyBhbnksXG4gICAgICAgIHR4UHJlYnVpbGQ6IHsgdHhIZXgsIGNvaW46ICd0eGRjOnRtdCcsIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyB9IGFzIGFueSxcbiAgICAgICAgd2FsbGV0LFxuICAgICAgfSk7XG4gICAgICByZXN1bHQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgYW4gRVJDLTIwIHRyYW5zZmVyIHdoZW4gY2FsbGRhdGEgcmVjaXBpZW50IGRvZXMgbm90IG1hdGNoIGRlY2xhcmVkIHJlY2lwaWVudCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHRva2VuID0gYml0Z28uY29pbigndHhkYzp0bXQnKSBhcyBYZGNUb2tlbjtcblxuICAgICAgY29uc3QgZXJjMjBUcmFuc2ZlckRhdGEgPSBlbmNvZGVFcmMyMFRyYW5zZmVyKHdyb25nQWRkcmVzcywgJzEwMDAwMDAwJyk7XG5cbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGdldEJ1aWxkZXIoJ3R4ZGMnKSBhcyBUcmFuc2FjdGlvbkJ1aWxkZXI7XG4gICAgICB0eEJ1aWxkZXIudHlwZShUcmFuc2FjdGlvblR5cGUuQ29udHJhY3RDYWxsKTtcbiAgICAgIHR4QnVpbGRlci5mZWUoeyBmZWU6ICcxMCcsIGdhc0xpbWl0OiAnNjAwMDAnIH0pO1xuICAgICAgdHhCdWlsZGVyLmNvdW50ZXIoMSk7XG4gICAgICB0eEJ1aWxkZXIuY29udHJhY3QodG9rZW5Db250cmFjdEFkZHJlc3MpO1xuICAgICAgdHhCdWlsZGVyLmRhdGEoZXJjMjBUcmFuc2ZlckRhdGEpO1xuICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHR4SGV4ID0gdHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcblxuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgdG9rZW4sIHsgY29pblNwZWNpZmljOiB7IGJhc2VBZGRyZXNzOiByZWNpcGllbnRBZGRyZXNzIH0gfSk7XG5cbiAgICAgIGF3YWl0IHRva2VuXG4gICAgICAgIC52ZXJpZnlUc3NUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhQYXJhbXM6IHtcbiAgICAgICAgICAgIHR5cGU6ICd0cmFuc2ZlcicsXG4gICAgICAgICAgICByZWNpcGllbnRzOiBbeyBhZGRyZXNzOiByZWNpcGllbnRBZGRyZXNzLCBhbW91bnQ6ICcxMDAwMDAwMCcgfV0sXG4gICAgICAgICAgfSBhcyBhbnksXG4gICAgICAgICAgdHhQcmVidWlsZDogeyB0eEhleCwgY29pbjogJ3R4ZGM6dG10Jywgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnIH0gYXMgYW55LFxuICAgICAgICAgIHdhbGxldCxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2Rlc3RpbmF0aW9uIGFkZHJlc3MgZG9lcyBub3QgbWF0Y2ggd2l0aCB0aGUgcmVjaXBpZW50IGFkZHJlc3MnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3Igd2hlbiB0eFBhcmFtcy5yZWNpcGllbnRzIGlzIG1pc3NpbmcgYW5kIG5vIHZhbGlkIHR5cGUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0b2tlbiA9IGJpdGdvLmNvaW4oJ3R4ZGM6dG10JykgYXMgWGRjVG9rZW47XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCB0b2tlbiwgeyBjb2luU3BlY2lmaWM6IHsgYmFzZUFkZHJlc3M6IHJlY2lwaWVudEFkZHJlc3MgfSB9KTtcblxuICAgICAgYXdhaXQgdG9rZW5cbiAgICAgICAgLnZlcmlmeVRzc1RyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0eFBhcmFtczoge30sXG4gICAgICAgICAgdHhQcmVidWlsZDogeyB0eEhleDogJzB4MDAnLCBjb2luOiAndHhkYzp0bXQnLCB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcgfSBhcyBhbnksXG4gICAgICAgICAgd2FsbGV0LFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnbWlzc2luZyB0eFBhcmFtcycpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciB3aGVuIHdhbGxldCBpcyBtaXNzaW5nJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdG9rZW4gPSBiaXRnby5jb2luKCd0eGRjOnRtdCcpIGFzIFhkY1Rva2VuO1xuXG4gICAgICBhd2FpdCB0b2tlblxuICAgICAgICAudmVyaWZ5VHNzVHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UGFyYW1zOiB7XG4gICAgICAgICAgICB0eXBlOiAndHJhbnNmZXInLFxuICAgICAgICAgICAgcmVjaXBpZW50czogW3sgYWRkcmVzczogcmVjaXBpZW50QWRkcmVzcywgYW1vdW50OiAnMTAwMDAwMDAnIH1dLFxuICAgICAgICAgIH0gYXMgYW55LFxuICAgICAgICAgIHR4UHJlYnVpbGQ6IHsgdHhIZXg6ICcweDAwJywgY29pbjogJ3R4ZGM6dG10Jywgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnIH0gYXMgYW55LFxuICAgICAgICAgIHdhbGxldDogdW5kZWZpbmVkIGFzIHVua25vd24gYXMgV2FsbGV0LFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnbWlzc2luZyBwYXJhbXMnKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==
|