@bitgo-beta/sdk-coin-flrp 1.0.1-beta.36 → 1.0.1-beta.361
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/flrp.d.ts +10 -17
- package/dist/src/flrp.d.ts.map +1 -1
- package/dist/src/flrp.js +51 -77
- package/dist/src/index.d.ts +0 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -2
- package/dist/src/lib/ExportInCTxBuilder.d.ts +51 -0
- package/dist/src/lib/ExportInCTxBuilder.d.ts.map +1 -0
- package/dist/src/lib/ExportInCTxBuilder.js +190 -0
- package/dist/src/lib/ExportInPTxBuilder.d.ts +47 -0
- package/dist/src/lib/ExportInPTxBuilder.d.ts.map +1 -0
- package/dist/src/lib/ExportInPTxBuilder.js +277 -0
- package/dist/src/lib/ImportInCTxBuilder.d.ts +48 -0
- package/dist/src/lib/ImportInCTxBuilder.d.ts.map +1 -0
- package/dist/src/lib/ImportInCTxBuilder.js +268 -0
- package/dist/src/lib/ImportInPTxBuilder.d.ts +33 -0
- package/dist/src/lib/ImportInPTxBuilder.d.ts.map +1 -0
- package/dist/src/lib/ImportInPTxBuilder.js +192 -0
- package/dist/src/lib/atomicInCTransactionBuilder.d.ts +18 -16
- package/dist/src/lib/atomicInCTransactionBuilder.d.ts.map +1 -1
- package/dist/src/lib/atomicInCTransactionBuilder.js +38 -36
- package/dist/src/lib/atomicTransactionBuilder.d.ts +57 -71
- package/dist/src/lib/atomicTransactionBuilder.d.ts.map +1 -1
- package/dist/src/lib/atomicTransactionBuilder.js +246 -209
- package/dist/src/lib/iface.d.ts +38 -61
- package/dist/src/lib/iface.d.ts.map +1 -1
- package/dist/src/lib/iface.js +13 -14
- package/dist/src/lib/index.d.ts +5 -0
- package/dist/src/lib/index.d.ts.map +1 -1
- package/dist/src/lib/index.js +12 -2
- package/dist/src/lib/keyPair.d.ts +5 -5
- package/dist/src/lib/keyPair.d.ts.map +1 -1
- package/dist/src/lib/keyPair.js +17 -9
- package/dist/src/lib/permissionlessValidatorTxBuilder.d.ts +43 -0
- package/dist/src/lib/permissionlessValidatorTxBuilder.d.ts.map +1 -0
- package/dist/src/lib/permissionlessValidatorTxBuilder.js +132 -0
- package/dist/src/lib/transaction.d.ts +25 -65
- package/dist/src/lib/transaction.d.ts.map +1 -1
- package/dist/src/lib/transaction.js +341 -199
- package/dist/src/lib/transactionBuilder.d.ts +107 -0
- package/dist/src/lib/transactionBuilder.d.ts.map +1 -0
- package/dist/src/lib/transactionBuilder.js +210 -0
- package/dist/src/lib/transactionBuilderFactory.d.ts +50 -30
- package/dist/src/lib/transactionBuilderFactory.d.ts.map +1 -1
- package/dist/src/lib/transactionBuilderFactory.js +129 -72
- package/dist/src/lib/utils.d.ts +78 -147
- package/dist/src/lib/utils.d.ts.map +1 -1
- package/dist/src/lib/utils.js +238 -324
- package/dist/test/resources/account.d.ts +51 -0
- package/dist/test/resources/account.d.ts.map +1 -0
- package/dist/test/resources/account.js +54 -0
- package/dist/test/resources/transactionData/exportInC.d.ts +20 -0
- package/dist/test/resources/transactionData/exportInC.d.ts.map +1 -0
- package/dist/test/resources/transactionData/exportInC.js +39 -0
- package/dist/test/resources/transactionData/exportInP.d.ts +69 -0
- package/dist/test/resources/transactionData/exportInP.d.ts.map +1 -0
- package/dist/test/resources/transactionData/exportInP.js +140 -0
- package/dist/test/resources/transactionData/importInC.d.ts +27 -0
- package/dist/test/resources/transactionData/importInC.d.ts.map +1 -0
- package/dist/test/resources/transactionData/importInC.js +44 -0
- package/dist/test/resources/transactionData/importInP.d.ts +35 -0
- package/dist/test/resources/transactionData/importInP.d.ts.map +1 -0
- package/dist/test/resources/transactionData/importInP.js +58 -0
- package/dist/test/unit/flrp.js +446 -68
- package/dist/test/unit/lib/exportInCTxBuilder.d.ts +2 -0
- package/dist/test/unit/lib/exportInCTxBuilder.d.ts.map +1 -0
- package/dist/test/unit/lib/exportInCTxBuilder.js +192 -0
- package/dist/test/unit/lib/exportInPTxBuilder.d.ts +2 -0
- package/dist/test/unit/lib/exportInPTxBuilder.d.ts.map +1 -0
- package/dist/test/unit/lib/exportInPTxBuilder.js +325 -0
- package/dist/test/unit/lib/importInCTxBuilder.d.ts +2 -0
- package/dist/test/unit/lib/importInCTxBuilder.d.ts.map +1 -0
- package/dist/test/unit/lib/importInCTxBuilder.js +400 -0
- package/dist/test/unit/lib/importInPTxBuilder.d.ts +2 -0
- package/dist/test/unit/lib/importInPTxBuilder.d.ts.map +1 -0
- package/dist/test/unit/lib/importInPTxBuilder.js +307 -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 +158 -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 +83 -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 +60 -0
- package/dist/test/unit/lib/utils.js +539 -207
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +18 -10
- package/.eslintignore +0 -5
- package/.eslintrc.json +0 -7
- package/.mocharc.yml +0 -8
- package/CHANGELOG.md +0 -0
- package/dist/src/iface.d.ts +0 -25
- package/dist/src/iface.d.ts.map +0 -1
- package/dist/src/iface.js +0 -3
- package/dist/src/lib/constants.d.ts +0 -11
- package/dist/src/lib/constants.d.ts.map +0 -1
- package/dist/src/lib/constants.js +0 -17
- package/dist/src/lib/errors.d.ts +0 -8
- package/dist/src/lib/errors.d.ts.map +0 -1
- package/dist/src/lib/errors.js +0 -19
- package/dist/src/lib/exportInCTxBuilder.d.ts +0 -77
- package/dist/src/lib/exportInCTxBuilder.d.ts.map +0 -1
- package/dist/src/lib/exportInCTxBuilder.js +0 -170
- package/dist/src/lib/exportInPTxBuilder.d.ts +0 -30
- package/dist/src/lib/exportInPTxBuilder.d.ts.map +0 -1
- package/dist/src/lib/exportInPTxBuilder.js +0 -56
- package/dist/test/unit/lib/atomicTransactionBuilder.d.ts +0 -2
- package/dist/test/unit/lib/atomicTransactionBuilder.d.ts.map +0 -1
- package/dist/test/unit/lib/atomicTransactionBuilder.js +0 -222
- package/dist/test/unit/lib/exportTxBuilder.d.ts +0 -2
- package/dist/test/unit/lib/exportTxBuilder.d.ts.map +0 -1
- package/dist/test/unit/lib/exportTxBuilder.js +0 -45
- package/dist/test/unit/lib/transaction.d.ts +0 -2
- package/dist/test/unit/lib/transaction.d.ts.map +0 -1
- package/dist/test/unit/lib/transaction.js +0 -460
- package/dist/test/unit/smoke.d.ts +0 -2
- package/dist/test/unit/smoke.d.ts.map +0 -1
- package/dist/test/unit/smoke.js +0 -23
|
@@ -0,0 +1,325 @@
|
|
|
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
|
+
const assert_1 = __importDefault(require("assert"));
|
|
7
|
+
require("should");
|
|
8
|
+
const exportInP_1 = require("../../resources/transactionData/exportInP");
|
|
9
|
+
const lib_1 = require("../../../src/lib");
|
|
10
|
+
const statics_1 = require("@bitgo-beta/statics");
|
|
11
|
+
const signFlowTestSuit_1 = __importDefault(require("./signFlowTestSuit"));
|
|
12
|
+
describe('Flrp Export In P Tx Builder', () => {
|
|
13
|
+
const coinConfig = statics_1.coins.get('tflrp');
|
|
14
|
+
const factory = new lib_1.TransactionBuilderFactory(coinConfig);
|
|
15
|
+
describe('default fee', () => {
|
|
16
|
+
const FIXED_FEE = coinConfig.network.txFee;
|
|
17
|
+
it('should set fixedFee (1000000) by default in constructor', () => {
|
|
18
|
+
const txBuilder = factory.getExportInPBuilder();
|
|
19
|
+
// The fixedFee should be set from network.txFee = '1000000'
|
|
20
|
+
const transaction = txBuilder.transaction;
|
|
21
|
+
transaction._fee.fee.should.equal(FIXED_FEE);
|
|
22
|
+
});
|
|
23
|
+
it('should use default fixedFee when fee is not explicitly set', async () => {
|
|
24
|
+
// Create a UTXO with enough balance to cover amount + default fee
|
|
25
|
+
const amount = '500000000'; // 0.5 FLR
|
|
26
|
+
const utxoAmount = (BigInt(amount) + BigInt(FIXED_FEE)).toString(); // amount + fixedFee
|
|
27
|
+
const txBuilder = factory
|
|
28
|
+
.getExportInPBuilder()
|
|
29
|
+
.threshold(exportInP_1.EXPORT_IN_P.threshold)
|
|
30
|
+
.locktime(exportInP_1.EXPORT_IN_P.locktime)
|
|
31
|
+
.fromPubKey(exportInP_1.EXPORT_IN_P.pAddresses)
|
|
32
|
+
.amount(amount)
|
|
33
|
+
.externalChainId(exportInP_1.EXPORT_IN_P.sourceChainId)
|
|
34
|
+
// NOTE: .fee() is NOT called - should use default fixedFee
|
|
35
|
+
.utxos([
|
|
36
|
+
{
|
|
37
|
+
outputID: 0,
|
|
38
|
+
amount: utxoAmount,
|
|
39
|
+
txid: '21hcD64N9QzdayPjhKLsBQBa8FyXcsJGNStBZ3vCRdCCEsLru2',
|
|
40
|
+
outputidx: '0',
|
|
41
|
+
addresses: exportInP_1.EXPORT_IN_P.outputs[0].addresses,
|
|
42
|
+
threshold: exportInP_1.EXPORT_IN_P.threshold,
|
|
43
|
+
},
|
|
44
|
+
]);
|
|
45
|
+
const tx = (await txBuilder.build());
|
|
46
|
+
// Verify the fee in the built transaction equals the fixedFee
|
|
47
|
+
tx.fee.fee.should.equal(FIXED_FEE);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
describe('validate txBuilder fields', () => {
|
|
51
|
+
const txBuilder = factory.getExportInPBuilder();
|
|
52
|
+
it('should fail amount low than zero', () => {
|
|
53
|
+
assert_1.default.throws(() => {
|
|
54
|
+
txBuilder.amount('-1');
|
|
55
|
+
}, (e) => e.message === 'Amount must be greater than 0');
|
|
56
|
+
});
|
|
57
|
+
it('should fail target chain id length incorrect', () => {
|
|
58
|
+
assert_1.default.throws(() => {
|
|
59
|
+
txBuilder.externalChainId(Buffer.from(exportInP_1.EXPORT_IN_P.INVALID_CHAIN_ID.slice(2)));
|
|
60
|
+
}, (e) => e.message === 'Chain id are 32 byte size');
|
|
61
|
+
});
|
|
62
|
+
it('should fail target chain id not a valid base58 string', () => {
|
|
63
|
+
assert_1.default.throws(() => {
|
|
64
|
+
txBuilder.externalChainId(exportInP_1.EXPORT_IN_P.INVALID_CHAIN_ID);
|
|
65
|
+
}, (e) => e.message === 'Non-base58 character');
|
|
66
|
+
});
|
|
67
|
+
it('should fail target chain id cb58 invalid checksum', () => {
|
|
68
|
+
assert_1.default.throws(() => {
|
|
69
|
+
txBuilder.externalChainId(exportInP_1.EXPORT_IN_P.VALID_C_CHAIN_ID.slice(2));
|
|
70
|
+
}, (e) => e.message === 'Invalid checksum');
|
|
71
|
+
});
|
|
72
|
+
it('should fail validate Utxos empty string', () => {
|
|
73
|
+
assert_1.default.throws(() => {
|
|
74
|
+
txBuilder.validateUtxos([]);
|
|
75
|
+
}, (e) => e.message === 'UTXOs array cannot be empty');
|
|
76
|
+
});
|
|
77
|
+
it('should fail validate Utxos without amount field', () => {
|
|
78
|
+
assert_1.default.throws(() => {
|
|
79
|
+
txBuilder.validateUtxos([{ outputID: '' }]);
|
|
80
|
+
}, (e) => e.message === 'UTXO missing required field: amount');
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
(0, signFlowTestSuit_1.default)({
|
|
84
|
+
transactionType: 'Export P2C with changeoutput',
|
|
85
|
+
newTxFactory: () => new lib_1.TransactionBuilderFactory(statics_1.coins.get('tflrp')),
|
|
86
|
+
newTxBuilder: () => new lib_1.TransactionBuilderFactory(statics_1.coins.get('tflrp'))
|
|
87
|
+
.getExportInPBuilder()
|
|
88
|
+
.threshold(exportInP_1.EXPORT_IN_P.threshold)
|
|
89
|
+
.locktime(exportInP_1.EXPORT_IN_P.locktime)
|
|
90
|
+
.fromPubKey(exportInP_1.EXPORT_IN_P.pAddresses)
|
|
91
|
+
.amount(exportInP_1.EXPORT_IN_P.amount)
|
|
92
|
+
.externalChainId(exportInP_1.EXPORT_IN_P.sourceChainId)
|
|
93
|
+
.fee(exportInP_1.EXPORT_IN_P.fee)
|
|
94
|
+
.utxos(exportInP_1.EXPORT_IN_P.outputs),
|
|
95
|
+
unsignedTxHex: exportInP_1.EXPORT_IN_P.unsignedHex,
|
|
96
|
+
halfSignedTxHex: exportInP_1.EXPORT_IN_P.halfSigntxHex,
|
|
97
|
+
fullSignedTxHex: exportInP_1.EXPORT_IN_P.fullSigntxHex,
|
|
98
|
+
privateKey: {
|
|
99
|
+
prv1: exportInP_1.EXPORT_IN_P.privateKeys[0],
|
|
100
|
+
prv2: exportInP_1.EXPORT_IN_P.privateKeys[1],
|
|
101
|
+
},
|
|
102
|
+
txHash: exportInP_1.EXPORT_IN_P.txhash,
|
|
103
|
+
});
|
|
104
|
+
(0, signFlowTestSuit_1.default)({
|
|
105
|
+
transactionType: 'Export P2C with 2 UTXOs',
|
|
106
|
+
newTxFactory: () => new lib_1.TransactionBuilderFactory(statics_1.coins.get('tflrp')),
|
|
107
|
+
newTxBuilder: () => new lib_1.TransactionBuilderFactory(statics_1.coins.get('tflrp'))
|
|
108
|
+
.getExportInPBuilder()
|
|
109
|
+
.threshold(exportInP_1.EXPORT_IN_P_TWO_UTXOS.threshold)
|
|
110
|
+
.locktime(exportInP_1.EXPORT_IN_P_TWO_UTXOS.locktime)
|
|
111
|
+
.fromPubKey(exportInP_1.EXPORT_IN_P_TWO_UTXOS.pAddresses)
|
|
112
|
+
.amount(exportInP_1.EXPORT_IN_P_TWO_UTXOS.amount)
|
|
113
|
+
.externalChainId(exportInP_1.EXPORT_IN_P_TWO_UTXOS.sourceChainId)
|
|
114
|
+
.fee(exportInP_1.EXPORT_IN_P_TWO_UTXOS.fee)
|
|
115
|
+
.utxos(exportInP_1.EXPORT_IN_P_TWO_UTXOS.outputs),
|
|
116
|
+
unsignedTxHex: exportInP_1.EXPORT_IN_P_TWO_UTXOS.unsignedHex,
|
|
117
|
+
halfSignedTxHex: exportInP_1.EXPORT_IN_P_TWO_UTXOS.halfSigntxHex,
|
|
118
|
+
fullSignedTxHex: exportInP_1.EXPORT_IN_P_TWO_UTXOS.fullSigntxHex,
|
|
119
|
+
privateKey: {
|
|
120
|
+
prv1: exportInP_1.EXPORT_IN_P_TWO_UTXOS.privateKeys[0],
|
|
121
|
+
prv2: exportInP_1.EXPORT_IN_P_TWO_UTXOS.privateKeys[1],
|
|
122
|
+
},
|
|
123
|
+
txHash: exportInP_1.EXPORT_IN_P_TWO_UTXOS.txhash,
|
|
124
|
+
});
|
|
125
|
+
(0, signFlowTestSuit_1.default)({
|
|
126
|
+
transactionType: 'Export P2C with no change output',
|
|
127
|
+
newTxFactory: () => new lib_1.TransactionBuilderFactory(statics_1.coins.get('tflrp')),
|
|
128
|
+
newTxBuilder: () => new lib_1.TransactionBuilderFactory(statics_1.coins.get('tflrp'))
|
|
129
|
+
.getExportInPBuilder()
|
|
130
|
+
.threshold(exportInP_1.EXPORT_IN_P_NO_CHANGE.threshold)
|
|
131
|
+
.locktime(exportInP_1.EXPORT_IN_P_NO_CHANGE.locktime)
|
|
132
|
+
.fromPubKey(exportInP_1.EXPORT_IN_P_NO_CHANGE.pAddresses)
|
|
133
|
+
.amount(exportInP_1.EXPORT_IN_P_NO_CHANGE.amount)
|
|
134
|
+
.externalChainId(exportInP_1.EXPORT_IN_P_NO_CHANGE.sourceChainId)
|
|
135
|
+
.fee(exportInP_1.EXPORT_IN_P_NO_CHANGE.fee)
|
|
136
|
+
.utxos(exportInP_1.EXPORT_IN_P_NO_CHANGE.outputs),
|
|
137
|
+
unsignedTxHex: exportInP_1.EXPORT_IN_P_NO_CHANGE.unsignedHex,
|
|
138
|
+
halfSignedTxHex: exportInP_1.EXPORT_IN_P_NO_CHANGE.halfSigntxHex,
|
|
139
|
+
fullSignedTxHex: exportInP_1.EXPORT_IN_P_NO_CHANGE.fullSigntxHex,
|
|
140
|
+
privateKey: {
|
|
141
|
+
prv1: exportInP_1.EXPORT_IN_P_NO_CHANGE.privateKeys[0],
|
|
142
|
+
prv2: exportInP_1.EXPORT_IN_P_NO_CHANGE.privateKeys[1],
|
|
143
|
+
},
|
|
144
|
+
txHash: exportInP_1.EXPORT_IN_P_NO_CHANGE.txhash,
|
|
145
|
+
});
|
|
146
|
+
it('Should full sign a export tx from unsigned raw tx', () => {
|
|
147
|
+
const txBuilder = new lib_1.TransactionBuilderFactory(statics_1.coins.get('tflrp')).from(exportInP_1.EXPORT_IN_P.unsignedHex);
|
|
148
|
+
txBuilder.sign({ key: exportInP_1.EXPORT_IN_P.privateKeys[0] });
|
|
149
|
+
txBuilder
|
|
150
|
+
.build()
|
|
151
|
+
.then(() => assert_1.default.fail('it can sign'))
|
|
152
|
+
.catch((err) => {
|
|
153
|
+
err.message.should.be.equal('Private key cannot sign the transaction');
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
describe('on-chain verified transactions', () => {
|
|
157
|
+
it('should verify on-chain tx id for signed P-chain export', async () => {
|
|
158
|
+
const signedExportHex = '0x0000000000120000007200000000000000000000000000000000000000000000000000000000000000000000000158734f94af871c3d131b56131b6fb7a0291eacadd261e69dfb42a9cdf6f7fddd00000007000000001ac6e558000000000000000000000001000000033329be7d01cd3ebaae6654d7327dd9f17a2e15817e918a5e8083ae4c9f2f0ed77055c24bf3665001c7324437c96c7c8a6a152da2385c1db5c3ab1f9100000003862ce86ba2e28884e8b83f5d6266d274b33632a1cc213d4c12996037fc21b2020000000058734f94af871c3d131b56131b6fb7a0291eacadd261e69dfb42a9cdf6f7fddd00000005000000001d6c96c60000000100000000a4891dfbd024a53b8e4512427d919910568989b9b4846026ac7bcb8290494c260000000058734f94af871c3d131b56131b6fb7a0291eacadd261e69dfb42a9cdf6f7fddd0000000500000000003ffabc0000000100000000c1fb3b438f8f49e1bb657a59106be9f5f91d2efce5e0259fcbbb9458e271f80d0000000058734f94af871c3d131b56131b6fb7a0291eacadd261e69dfb42a9cdf6f7fddd000000050000000000400e7000000001000000000000000078db5c30bed04c05ce209179812850bbb3fe6d46d7eef3744d814c0da55524790000000158734f94af871c3d131b56131b6fb7a0291eacadd261e69dfb42a9cdf6f7fddd000000070000000002faf080000000000000000000000002000000033329be7d01cd3ebaae6654d7327dd9f17a2e15817e918a5e8083ae4c9f2f0ed77055c24bf3665001c7324437c96c7c8a6a152da2385c1db5c3ab1f91000000030000000900000001afdf0ac2bdbfb1735081dd859f4d263e587d81ba81c6bd2cb345ee5a66cef4e97a634c740f35ef6ba600796a5add1d91e69a14cfcb22b65e6ae0bcdfbcebfaba000000000900000001afdf0ac2bdbfb1735081dd859f4d263e587d81ba81c6bd2cb345ee5a66cef4e97a634c740f35ef6ba600796a5add1d91e69a14cfcb22b65e6ae0bcdfbcebfaba000000000900000001afdf0ac2bdbfb1735081dd859f4d263e587d81ba81c6bd2cb345ee5a66cef4e97a634c740f35ef6ba600796a5add1d91e69a14cfcb22b65e6ae0bcdfbcebfaba00';
|
|
159
|
+
const txBuilder = new lib_1.TransactionBuilderFactory(statics_1.coins.get('tflrp')).from(signedExportHex);
|
|
160
|
+
const tx = await txBuilder.build();
|
|
161
|
+
const rawTx = tx.toBroadcastFormat();
|
|
162
|
+
rawTx.should.equal(signedExportHex);
|
|
163
|
+
tx.id.should.equal('ka8at5CinmpUc6QMVr33dyUJi156LKMdodrJM59kS6EWr3vHg');
|
|
164
|
+
});
|
|
165
|
+
it('should FAIL with unsorted UTXO addresses - demonstrates AddressMap mismatch issue for export in P-chain tx', async () => {
|
|
166
|
+
// This test uses UTXO addresses in UNSORTED order to demonstrate the issue.
|
|
167
|
+
// With unsorted addresses, the current implementation will create AddressMaps incorrectly
|
|
168
|
+
// because it uses sorted addresses, not UTXO address order.
|
|
169
|
+
//
|
|
170
|
+
// Expected: AddressMap should map addresses to signature slots based on UTXO order (sigIndicies)
|
|
171
|
+
// Current (WRONG): AddressMap uses sorted addresses with sequential slots
|
|
172
|
+
//
|
|
173
|
+
// This test WILL FAIL with current implementation because AddressMaps don't match sigIndicies
|
|
174
|
+
// UTXO addresses in UNSORTED order (different from sorted)
|
|
175
|
+
// Sorted would be: [0x12cb... (smallest), 0xa6e0... (middle), 0xc386... (largest)]
|
|
176
|
+
// Unsorted: [0xc386... (largest), 0x12cb... (smallest), 0xa6e0... (middle)]
|
|
177
|
+
const unsortedUtxoAddresses = [
|
|
178
|
+
'0xc386d58d09a9ae77cf1cf07bf1c9de44ebb0c9f3', // Largest (would be index 2 if sorted)
|
|
179
|
+
'0x12cb32eaf92553064db98d271b56cba079ec78f5', // Smallest (would be index 0 if sorted)
|
|
180
|
+
'0xa6e0c1abd0132f70efb77e2274637ff336a29a57', // Middle (would be index 1 if sorted)
|
|
181
|
+
];
|
|
182
|
+
// Corresponding P-chain addresses (in same order as UTXO)
|
|
183
|
+
const pAddresses = [
|
|
184
|
+
'P-costwo15msvr27szvhhpmah0c38gcml7vm29xjh7tcek8', // Maps to 0xc386... (UTXO index 0)
|
|
185
|
+
'P-costwo1zt9n96hey4fsvnde35n3k4kt5pu7c784dzewzd', // Maps to 0x12cb... (UTXO index 1)
|
|
186
|
+
'P-costwo1cwrdtrgf4xh80ncu7palrjw7gn4mpj0n4dxghh', // Maps to 0xa6e0... (UTXO index 2)
|
|
187
|
+
];
|
|
188
|
+
// Create UTXO with UNSORTED addresses
|
|
189
|
+
// Amount must cover export amount + fee
|
|
190
|
+
const exportAmount = '50000000';
|
|
191
|
+
const fee = '1261000';
|
|
192
|
+
const utxoAmount = (BigInt(exportAmount) + BigInt(fee)).toString(); // amount + fee
|
|
193
|
+
const utxo = {
|
|
194
|
+
outputID: 0,
|
|
195
|
+
amount: utxoAmount,
|
|
196
|
+
txid: 'zstyYq5riDKYDSR3fUYKKkuXKJ1aJCe8WNrXKqEBJD4CGwzFw',
|
|
197
|
+
outputidx: '0',
|
|
198
|
+
addresses: unsortedUtxoAddresses, // UNSORTED order
|
|
199
|
+
threshold: 2,
|
|
200
|
+
};
|
|
201
|
+
// Build transaction
|
|
202
|
+
const txBuilder = factory
|
|
203
|
+
.getExportInPBuilder()
|
|
204
|
+
.threshold(2)
|
|
205
|
+
.locktime(0)
|
|
206
|
+
.fromPubKey(pAddresses)
|
|
207
|
+
.externalChainId(exportInP_1.EXPORT_IN_P.sourceChainId)
|
|
208
|
+
.amount(exportAmount)
|
|
209
|
+
.fee(fee)
|
|
210
|
+
.utxos([utxo]);
|
|
211
|
+
// Build unsigned transaction
|
|
212
|
+
const unsignedTx = await txBuilder.build();
|
|
213
|
+
const unsignedHex = unsignedTx.toBroadcastFormat();
|
|
214
|
+
// Parse it back to inspect AddressMaps and sigIndicies
|
|
215
|
+
const parsedBuilder = factory.from(unsignedHex);
|
|
216
|
+
const parsedTx = await parsedBuilder.build();
|
|
217
|
+
const flareTx = parsedTx._flareTransaction;
|
|
218
|
+
// Get the input to check sigIndicies
|
|
219
|
+
const exportTx = flareTx.tx;
|
|
220
|
+
const input = exportTx.baseTx.inputs[0];
|
|
221
|
+
const transferInput = input.input;
|
|
222
|
+
const sigIndicies = transferInput.sigIndicies();
|
|
223
|
+
// sigIndicies tells us: sigIndicies[slotIndex] = utxoAddressIndex
|
|
224
|
+
// For threshold=2, we need signatures for first 2 addresses in UTXO order
|
|
225
|
+
// UTXO order: [0xc386... (index 0), 0x12cb... (index 1), 0xa6e0... (index 2)]
|
|
226
|
+
// So sigIndicies should be [0, 1] meaning: slot 0 = UTXO index 0, slot 1 = UTXO index 1
|
|
227
|
+
// Verify sigIndicies are [0, 1] (first 2 addresses in UTXO order, NOT sorted order)
|
|
228
|
+
sigIndicies.length.should.equal(2);
|
|
229
|
+
sigIndicies[0].should.equal(0, 'First signature slot should be UTXO address index 0 (0xc386...)');
|
|
230
|
+
sigIndicies[1].should.equal(1, 'Second signature slot should be UTXO address index 1 (0x12cb...)');
|
|
231
|
+
// The critical test: Verify that signature slots have embedded addresses based on UTXO order
|
|
232
|
+
// With unsorted UTXO addresses, this will FAIL if AddressMaps don't match UTXO order
|
|
233
|
+
//
|
|
234
|
+
// sigIndicies tells us: sigIndicies[slotIndex] = utxoAddressIndex
|
|
235
|
+
// For threshold=2, we need signatures for first 2 addresses in UTXO order
|
|
236
|
+
// UTXO order: [0xc386... (index 0), 0x12cb... (index 1), 0xa6e0... (index 2)]
|
|
237
|
+
// So sigIndicies should be [0, 1] meaning: slot 0 = UTXO index 0, slot 1 = UTXO index 1
|
|
238
|
+
// Parse the credential to see which slots have which embedded addresses
|
|
239
|
+
const credential = flareTx.credentials[0];
|
|
240
|
+
const signatures = credential.getSignatures();
|
|
241
|
+
// Helper function to check if signature has embedded address (same logic as transaction.ts)
|
|
242
|
+
const testUtils2 = require('../../../src/lib/utils').default;
|
|
243
|
+
const isEmptySignature = (signature) => {
|
|
244
|
+
return !!signature && testUtils2.removeHexPrefix(signature).startsWith('0'.repeat(90));
|
|
245
|
+
};
|
|
246
|
+
const hasEmbeddedAddress = (signature) => {
|
|
247
|
+
if (!isEmptySignature(signature))
|
|
248
|
+
return false;
|
|
249
|
+
const cleanSig = testUtils2.removeHexPrefix(signature);
|
|
250
|
+
if (cleanSig.length < 130)
|
|
251
|
+
return false;
|
|
252
|
+
const embeddedPart = cleanSig.substring(90, 130);
|
|
253
|
+
// Check if embedded part is not all zeros
|
|
254
|
+
return embeddedPart !== '0'.repeat(40);
|
|
255
|
+
};
|
|
256
|
+
// Extract embedded addresses from signature slots
|
|
257
|
+
const embeddedAddresses = [];
|
|
258
|
+
signatures.forEach((sig, slotIndex) => {
|
|
259
|
+
if (hasEmbeddedAddress(sig)) {
|
|
260
|
+
// Extract embedded address (after position 90, 40 chars = 20 bytes)
|
|
261
|
+
const cleanSig = testUtils2.removeHexPrefix(sig);
|
|
262
|
+
const embeddedAddr = cleanSig.substring(90, 130).toLowerCase();
|
|
263
|
+
embeddedAddresses[slotIndex] = '0x' + embeddedAddr;
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
// Verify: Credentials only embed ONE address (user/recovery), not both
|
|
267
|
+
// The embedded address should be based on addressesIndex logic, not sorted order
|
|
268
|
+
//
|
|
269
|
+
// Compute addressesIndex to determine expected signature order
|
|
270
|
+
const utxoAddressBytes = unsortedUtxoAddresses.map((addr) => testUtils2.parseAddress(addr));
|
|
271
|
+
const pAddressBytes = pAddresses.map((addr) => testUtils2.parseAddress(addr));
|
|
272
|
+
const addressesIndex = [];
|
|
273
|
+
pAddressBytes.forEach((pAddr) => {
|
|
274
|
+
const utxoIndex = utxoAddressBytes.findIndex((uAddr) => Buffer.compare(Buffer.from(uAddr), Buffer.from(pAddr)) === 0);
|
|
275
|
+
addressesIndex.push(utxoIndex);
|
|
276
|
+
});
|
|
277
|
+
// firstIndex = 0 (user), bitgoIndex = 1
|
|
278
|
+
const firstIndex = 0;
|
|
279
|
+
const bitgoIndex = 1;
|
|
280
|
+
// Determine expected signature order based on addressesIndex
|
|
281
|
+
const userComesFirst = addressesIndex[bitgoIndex] > addressesIndex[firstIndex];
|
|
282
|
+
// Expected credential structure:
|
|
283
|
+
// - If user comes first: [userAddress, zeros]
|
|
284
|
+
// - If bitgo comes first: [zeros, userAddress]
|
|
285
|
+
const userAddressHex = Buffer.from(pAddressBytes[firstIndex]).toString('hex').toLowerCase();
|
|
286
|
+
const expectedUserAddr = '0x' + userAddressHex;
|
|
287
|
+
if (userComesFirst) {
|
|
288
|
+
// Expected: [userAddress, zeros]
|
|
289
|
+
// Slot 0 should have user address (pAddr0 = 0xc386... = UTXO index 0)
|
|
290
|
+
if (embeddedAddresses[0]) {
|
|
291
|
+
embeddedAddresses[0]
|
|
292
|
+
.toLowerCase()
|
|
293
|
+
.should.equal(expectedUserAddr, `Slot 0 should have user address (${expectedUserAddr}) because user comes first in UTXO order`);
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
throw new Error(`Slot 0 should have embedded user address, but is empty`);
|
|
297
|
+
}
|
|
298
|
+
// Slot 1 should be zeros (no embedded address)
|
|
299
|
+
if (embeddedAddresses[1]) {
|
|
300
|
+
throw new Error(`Slot 1 should be zeros, but has embedded address: ${embeddedAddresses[1]}`);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
// Expected: [zeros, userAddress]
|
|
305
|
+
// Slot 0 should be zeros
|
|
306
|
+
if (embeddedAddresses[0]) {
|
|
307
|
+
throw new Error(`Slot 0 should be zeros, but has embedded address: ${embeddedAddresses[0]}`);
|
|
308
|
+
}
|
|
309
|
+
// Slot 1 should have user address
|
|
310
|
+
if (embeddedAddresses[1]) {
|
|
311
|
+
embeddedAddresses[1]
|
|
312
|
+
.toLowerCase()
|
|
313
|
+
.should.equal(expectedUserAddr, `Slot 1 should have user address (${expectedUserAddr}) because bitgo comes first in UTXO order`);
|
|
314
|
+
}
|
|
315
|
+
else {
|
|
316
|
+
throw new Error(`Slot 1 should have embedded user address, but is empty`);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
// The key verification: AddressMaps should match the credential order
|
|
320
|
+
// With the fix, AddressMaps are created using the same addressesIndex logic as credentials
|
|
321
|
+
// This ensures signing works correctly even with unsorted UTXO addresses
|
|
322
|
+
});
|
|
323
|
+
});
|
|
324
|
+
});
|
|
325
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwb3J0SW5QVHhCdWlsZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC91bml0L2xpYi9leHBvcnRJblBUeEJ1aWxkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxvREFBNEI7QUFDNUIsa0JBQWdCO0FBQ2hCLHlFQUltRDtBQUNuRCwwQ0FBMEY7QUFDMUYsaURBQTBEO0FBQzFELDBFQUE4QztBQUU5QyxRQUFRLENBQUMsNkJBQTZCLEVBQUUsR0FBRyxFQUFFO0lBQzNDLE1BQU0sVUFBVSxHQUFHLGVBQUssQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDdEMsTUFBTSxPQUFPLEdBQUcsSUFBSSwrQkFBeUIsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUUxRCxRQUFRLENBQUMsYUFBYSxFQUFFLEdBQUcsRUFBRTtRQUMzQixNQUFNLFNBQVMsR0FBSSxVQUFVLENBQUMsT0FBd0IsQ0FBQyxLQUFLLENBQUM7UUFFN0QsRUFBRSxDQUFDLHlEQUF5RCxFQUFFLEdBQUcsRUFBRTtZQUNqRSxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztZQUNoRCw0REFBNEQ7WUFDNUQsTUFBTSxXQUFXLEdBQUksU0FBaUIsQ0FBQyxXQUFXLENBQUM7WUFDbkQsV0FBVyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUMvQyxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyw0REFBNEQsRUFBRSxLQUFLLElBQUksRUFBRTtZQUMxRSxrRUFBa0U7WUFDbEUsTUFBTSxNQUFNLEdBQUcsV0FBVyxDQUFDLENBQUMsVUFBVTtZQUN0QyxNQUFNLFVBQVUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLG9CQUFvQjtZ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QyxFQUFFLENBQUMsQ0FBQztnQkFDL0YsQ0FBQztnQkFDRCxrQ0FBa0M7Z0JBQ2xDLElBQUksaUJBQWlCLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztvQkFDekIsaUJBQWlCLENBQUMsQ0FBQyxDQUFDO3lCQUNqQixXQUFXLEVBQUU7eUJBQ2IsTUFBTSxDQUFDLEtBQUssQ0FDWCxnQkFBZ0IsRUFDaEIsb0NBQW9DLGdCQUFnQiwyQ0FBMkMsQ0FDaEcsQ0FBQztnQkFDTixDQUFDO3FCQUFNLENBQUM7b0JBQ04sTUFBTSxJQUFJLEtBQUssQ0FBQyx3REFBd0QsQ0FBQyxDQUFDO2dCQUM1RSxDQUFDO1lBQ0gsQ0FBQztZQUVELHNFQUFzRTtZQUN0RSwyRkFBMkY7WUFDM0YseUVBQXlFO1FBQzNFLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCAnc2hvdWxkJztcbmltcG9ydCB7XG4gIEVYUE9SVF9JTl9QIGFzIHRlc3REYXRhLFxuICBFWFBPUlRfSU5fUF9UV09fVVRYT1MgYXMgdHdvVXR4b1Rlc3REYXRhLFxuICBFWFBPUlRfSU5fUF9OT19DSEFOR0UgYXMgbm9DaGFuZ2VUZXN0RGF0YSxcbn0gZnJvbSAnLi4vLi4vcmVzb3VyY2VzL3RyYW5zYWN0aW9uRGF0YS9leHBvcnRJblAnO1xuaW1wb3J0IHsgVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeSwgRGVjb2RlZFV0eG9PYmosIFRyYW5zYWN0aW9uIH0gZnJvbSAnLi4vLi4vLi4vc3JjL2xpYic7XG5pbXBvcnQgeyBjb2lucywgRmxhcmVOZXR3b3JrIH0gZnJvbSAnQGJpdGdvLWJldGEvc3RhdGljcyc7XG5pbXBvcnQgc2lnbkZsb3dUZXN0IGZyb20gJy4vc2lnbkZsb3dUZXN0U3VpdCc7XG5cbmRlc2NyaWJlKCdGbHJwIEV4cG9ydCBJbiBQIFR4IEJ1aWxkZXInLCAoKSA9PiB7XG4gIGNvbnN0IGNvaW5Db25maWcgPSBjb2lucy5nZXQoJ3RmbHJwJyk7XG4gIGNvbnN0IGZhY3RvcnkgPSBuZXcgVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeShjb2luQ29uZmlnKTtcblxuICBkZXNjcmliZSgnZGVmYXVsdCBmZWUnLCAoKSA9PiB7XG4gICAgY29uc3QgRklYRURfRkVFID0gKGNvaW5Db25maWcubmV0d29yayBhcyBGbGFyZU5ldHdvcmspLnR4RmVlO1xuXG4gICAgaXQoJ3Nob3VsZCBzZXQgZml4ZWRGZWUgKDEwMDAwMDApIGJ5IGRlZmF1bHQgaW4gY29uc3RydWN0b3InLCAoKSA9PiB7XG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmdldEV4cG9ydEluUEJ1aWxkZXIoKTtcbiAgICAgIC8vIFRoZSBmaXhlZEZlZSBzaG91bGQgYmUgc2V0IGZyb20gbmV0d29yay50eEZlZSA9ICcxMDAwMDAwJ1xuICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSAodHhCdWlsZGVyIGFzIGFueSkudHJhbnNhY3Rpb247XG4gICAgICB0cmFuc2FjdGlvbi5fZmVlLmZlZS5zaG91bGQuZXF1YWwoRklYRURfRkVFKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdXNlIGRlZmF1bHQgZml4ZWRGZWUgd2hlbiBmZWUgaXMgbm90IGV4cGxpY2l0bHkgc2V0JywgYXN5bmMgKCkgPT4ge1xuICAgICAgLy8gQ3JlYXRlIGEgVVRYTyB3aXRoIGVub3VnaCBiYWxhbmNlIHRvIGNvdmVyIGFtb3VudCArIGRlZmF1bHQgZmVlXG4gICAgICBjb25zdCBhbW91bnQgPSAnNTAwMDAwMDAwJzsgLy8gMC41IEZMUlxuICAgICAgY29uc3QgdXR4b0Ftb3VudCA9IChCaWdJbnQoYW1vdW50KSArIEJpZ0ludChGSVhFRF9GRUUpKS50b1N0cmluZygpOyAvLyBhbW91bnQgKyBmaXhlZEZlZVxuXG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5XG4gICAgICAgIC5nZXRFeHBvcnRJblBCdWlsZGVyKClcbiAgICAgICAgLnRocmVzaG9sZCh0ZXN0RGF0YS50aHJlc2hvbGQpXG4gICAgICAgIC5sb2NrdGltZSh0ZXN0RGF0YS5sb2NrdGltZSlcbiAgICAgICAgLmZyb21QdWJLZXkodGVzdERhdGEucEFkZHJlc3NlcylcbiAgICAgICAgLmFtb3VudChhbW91bnQpXG4gICAgICAgIC5leHRlcm5hbENoYWluSWQodGVzdERhdGEuc291cmNlQ2hhaW5JZClcbiAgICAgICAgLy8gTk9URTogLmZlZSgpIGlzIE5PVCBjYWxsZWQgLSBzaG91bGQgdXNlIGRlZmF1bHQgZml4ZWRGZWVcbiAgICAgICAgLnV0eG9zKFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBvdXRwdXRJRDogMCxcbiAgICAgICAgICAgIGFtb3VudDogdXR4b0Ftb3VudCxcbiAgICAgICAgICAgIHR4aWQ6ICcyMWhjRDY0TjlRemRheVBqaEtMc0JRQmE4RnlYY3NKR05TdEJaM3ZDUmRDQ0VzTHJ1MicsXG4gICAgICAgICAgICBvdXRwdXRpZHg6ICcwJyxcbiAgICAgICAgICAgIGFkZHJlc3NlczogdGVzdERhdGEub3V0cHV0c1swXS5hZGRyZXNzZXMsXG4gICAgICAgICAgICB0aHJlc2hvbGQ6IHRlc3REYXRhLnRocmVzaG9sZCxcbiAgICAgICAgICB9LFxuICAgICAgICBdKTtcblxuICAgICAgY29uc3QgdHggPSAoYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCkpIGFzIFRyYW5zYWN0aW9uO1xuXG4gICAgICAvLyBWZXJpZnkgdGhlIGZlZSBpbiB0aGUgYnVpbHQgdHJhbnNhY3Rpb24gZXF1YWxzIHRoZSBmaXhlZEZlZVxuICAgICAgdHguZmVlLmZlZS5zaG91bGQuZXF1YWwoRklYRURfRkVFKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3ZhbGlkYXRlIHR4QnVpbGRlciBmaWVsZHMnLCAoKSA9PiB7XG4gICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5nZXRFeHBvcnRJblBCdWlsZGVyKCk7XG4gICAgaXQoJ3Nob3VsZCBmYWlsIGFtb3VudCBsb3cgdGhhbiB6ZXJvJywgKCkgPT4ge1xuICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgKCkgPT4ge1xuICAgICAgICAgIHR4QnVpbGRlci5hbW91bnQoJy0xJyk7XG4gICAgICAgIH0sXG4gICAgICAgIChlOiBhbnkpID0+IGUubWVzc2FnZSA9PT0gJ0Ftb3VudCBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAwJ1xuICAgICAgKTtcbiAgICB9KTtcbiAgICBpdCgnc2hvdWxkIGZhaWwgdGFyZ2V0IGNoYWluIGlkIGxlbmd0aCBpbmNvcnJlY3QnLCAoKSA9PiB7XG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgdHhCdWlsZGVyLmV4dGVybmFsQ2hhaW5JZChCdWZmZXIuZnJvbSh0ZXN0RGF0YS5JTlZBTElEX0NIQUlOX0lELnNsaWNlKDIpKSk7XG4gICAgICAgIH0sXG4gICAgICAgIChlOiBhbnkpID0+IGUubWVzc2FnZSA9PT0gJ0NoYWluIGlkIGFyZSAzMiBieXRlIHNpemUnXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHRhcmdldCBjaGFpbiBpZCBub3QgYSB2YWxpZCBiYXNlNTggc3RyaW5nJywgKCkgPT4ge1xuICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgKCkgPT4ge1xuICAgICAgICAgIHR4QnVpbGRlci5leHRlcm5hbENoYWluSWQodGVzdERhdGEuSU5WQUxJRF9DSEFJTl9JRCk7XG4gICAgICAgIH0sXG4gICAgICAgIChlOiBhbnkpID0+IGUubWVzc2FnZSA9PT0gJ05vbi1iYXNlNTggY2hhcmFjdGVyJ1xuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB0YXJnZXQgY2hhaW4gaWQgY2I1OCBpbnZhbGlkIGNoZWNrc3VtJywgKCkgPT4ge1xuICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgKCkgPT4ge1xuICAgICAgICAgIHR4QnVpbGRlci5leHRlcm5hbENoYWluSWQodGVzdERhdGEuVkFMSURfQ19DSEFJTl9JRC5zbGljZSgyKSk7XG4gICAgICAgIH0sXG4gICAgICAgIChlOiBhbnkpID0+IGUubWVzc2FnZSA9PT0gJ0ludmFsaWQgY2hlY2tzdW0nXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHZhbGlkYXRlIFV0eG9zIGVtcHR5IHN0cmluZycsICgpID0+IHtcbiAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICgpID0+IHtcbiAgICAgICAgICB0eEJ1aWxkZXIudmFsaWRhdGVVdHhvcyhbXSk7XG4gICAgICAgIH0sXG4gICAgICAgIChlOiBhbnkpID0+IGUubWVzc2FnZSA9PT0gJ1VUWE9zIGFycmF5IGNhbm5vdCBiZSBlbXB0eSdcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgdmFsaWRhdGUgVXR4b3Mgd2l0aG91dCBhbW91bnQgZmllbGQnLCAoKSA9PiB7XG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgdHhCdWlsZGVyLnZhbGlkYXRlVXR4b3MoW3sgb3V0cHV0SUQ6ICcnIH0gYXMgYW55IGFzIERlY29kZWRVdHhvT2JqXSk7XG4gICAgICAgIH0sXG4gICAgICAgIChlOiBhbnkpID0+IGUubWVzc2FnZSA9PT0gJ1VUWE8gbWlzc2luZyByZXF1aXJlZCBmaWVsZDogYW1vdW50J1xuICAgICAgKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgc2lnbkZsb3dUZXN0KHtcbiAgICB0cmFuc2FjdGlvblR5cGU6ICdFeHBvcnQgUDJDIHdpdGggY2hhbmdlb3V0cHV0JyxcbiAgICBuZXdUeEZhY3Rvcnk6ICgpID0+IG5ldyBUcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5KGNvaW5zLmdldCgndGZscnAnKSksXG4gICAgbmV3VHhCdWlsZGVyOiAoKSA9PlxuICAgICAgbmV3IFRyYW5zYWN0aW9uQnVpbGRlckZhY3RvcnkoY29pbnMuZ2V0KCd0ZmxycCcpKVxuICAgICAgICAuZ2V0RXhwb3J0SW5QQnVpbGRlcigpXG4gICAgICAgIC50aHJlc2hvbGQodGVzdERhdGEudGhyZXNob2xkKVxuICAgICAgICAubG9ja3RpbWUodGVzdERhdGEubG9ja3RpbWUpXG4gICAgICAgIC5mcm9tUHViS2V5KHRlc3REYXRhLnBBZGRyZXNzZXMpXG4gICAgICAgIC5hbW91bnQodGVzdERhdGEuYW1vdW50KVxuICAgICAgICAuZXh0ZXJuYWxDaGFpbklkKHRlc3REYXRhLnNvdXJjZUNoYWluSWQpXG4gICAgICAgIC5mZWUodGVzdERhdGEuZmVlKVxuICAgICAgICAudXR4b3ModGVzdERhdGEub3V0cHV0cyksXG4gICAgdW5zaWduZWRUeEhleDogdGVzdERhdGEudW5zaWduZWRIZXgsXG4gICAgaGFsZlNpZ25lZFR4SGV4OiB0ZXN0RGF0YS5oYWxmU2lnbnR4SGV4LFxuICAgIGZ1bGxTaWduZWRUeEhleDogdGVzdERhdGEuZnVsbFNpZ250eEhleCxcbiAgICBwcml2YXRlS2V5OiB7XG4gICAgICBwcnYxOiB0ZXN0RGF0YS5wcml2YXRlS2V5c1swXSxcbiAgICAgIHBydjI6IHRlc3REYXRhLnByaXZhdGVLZXlzWzFdLFxuICAgIH0sXG4gICAgdHhIYXNoOiB0ZXN0RGF0YS50eGhhc2gsXG4gIH0pO1xuXG4gIHNpZ25GbG93VGVzdCh7XG4gICAgdHJhbnNhY3Rpb25UeXBlOiAnRXhwb3J0IFAyQyB3aXRoIDIgVVRYT3MnLFxuICAgIG5ld1R4RmFjdG9yeTogKCkgPT4gbmV3IFRyYW5zYWN0aW9uQnVpbGRlckZhY3RvcnkoY29pbnMuZ2V0KCd0ZmxycCcpKSxcbiAgICBuZXdUeEJ1aWxkZXI6ICgpID0+XG4gICAgICBuZXcgVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeShjb2lucy5nZXQoJ3RmbHJwJykpXG4gICAgICAgIC5nZXRFeHBvcnRJblBCdWlsZGVyKClcbiAgICAgICAgLnRocmVzaG9sZCh0d29VdHhvVGVzdERhdGEudGhyZXNob2xkKVxuICAgICAgICAubG9ja3RpbWUodHdvVXR4b1Rlc3REYXRhLmxvY2t0aW1lKVxuICAgICAgICAuZnJvbVB1YktleSh0d29VdHhvVGVzdERhdGEucEFkZHJlc3NlcylcbiAgICAgICAgLmFtb3VudCh0d29VdHhvVGVzdERhdGEuYW1vdW50KVxuICAgICAgICAuZXh0ZXJuYWxDaGFpbklkKHR3b1V0eG9UZXN0RGF0YS5zb3VyY2VDaGFpbklkKVxuICAgICAgICAuZmVlKHR3b1V0eG9UZXN0RGF0YS5mZWUpXG4gICAgICAgIC51dHhvcyh0d29VdHhvVGVzdERhdGEub3V0cHV0cyksXG4gICAgdW5zaWduZWRUeEhleDogdHdvVXR4b1Rlc3REYXRhLnVuc2lnbmVkSGV4LFxuICAgIGhhbGZTaWduZWRUeEhleDogdHdvVXR4b1Rlc3REYXRhLmhhbGZTaWdudHhIZXgsXG4gICAgZnVsbFNpZ25lZFR4SGV4OiB0d29VdHhvVGVzdERhdGEuZnVsbFNpZ250eEhleCxcbiAgICBwcml2YXRlS2V5OiB7XG4gICAgICBwcnYxOiB0d29VdHhvVGVzdERhdGEucHJpdmF0ZUtleXNbMF0sXG4gICAgICBwcnYyOiB0d29VdHhvVGVzdERhdGEucHJpdmF0ZUtleXNbMV0sXG4gICAgfSxcbiAgICB0eEhhc2g6IHR3b1V0eG9UZXN0RGF0YS50eGhhc2gsXG4gIH0pO1xuXG4gIHNpZ25GbG93VGVzdCh7XG4gICAgdHJhbnNhY3Rpb25UeXBlOiAnRXhwb3J0IFAyQyB3aXRoIG5vIGNoYW5nZSBvdXRwdXQnLFxuICAgIG5ld1R4RmFjdG9yeTogKCkgPT4gbmV3IFRyYW5zYWN0aW9uQnVpbGRlckZhY3RvcnkoY29pbnMuZ2V0KCd0ZmxycCcpKSxcbiAgICBuZXdUeEJ1aWxkZXI6ICgpID0+XG4gICAgICBuZXcgVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeShjb2lucy5nZXQoJ3RmbHJwJykpXG4gICAgICAgIC5nZXRFeHBvcnRJblBCdWlsZGVyKClcbiAgICAgICAgLnRocmVzaG9sZChub0NoYW5nZVRlc3REYXRhLnRocmVzaG9sZClcbiAgICAgICAgLmxvY2t0aW1lKG5vQ2hhbmdlVGVzdERhdGEubG9ja3RpbWUpXG4gICAgICAgIC5mcm9tUHViS2V5KG5vQ2hhbmdlVGVzdERhdGEucEFkZHJlc3NlcylcbiAgICAgICAgLmFtb3VudChub0NoYW5nZVRlc3REYXRhLmFtb3VudClcbiAgICAgICAgLmV4dGVybmFsQ2hhaW5JZChub0NoYW5nZVRlc3REYXRhLnNvdXJjZUNoYWluSWQpXG4gICAgICAgIC5mZWUobm9DaGFuZ2VUZXN0RGF0YS5mZWUpXG4gICAgICAgIC51dHhvcyhub0NoYW5nZVRlc3REYXRhLm91dHB1dHMpLFxuICAgIHVuc2lnbmVkVHhIZXg6IG5vQ2hhbmdlVGVzdERhdGEudW5zaWduZWRIZXgsXG4gICAgaGFsZlNpZ25lZFR4SGV4OiBub0NoYW5nZVRlc3REYXRhLmhhbGZTaWdudHhIZXgsXG4gICAgZnVsbFNpZ25lZFR4SGV4OiBub0NoYW5nZVRlc3REYXRhLmZ1bGxTaWdudHhIZXgsXG4gICAgcHJpdmF0ZUtleToge1xuICAgICAgcHJ2MTogbm9DaGFuZ2VUZXN0RGF0YS5wcml2YXRlS2V5c1swXSxcbiAgICAgIHBydjI6IG5vQ2hhbmdlVGVzdERhdGEucHJpdmF0ZUtleXNbMV0sXG4gICAgfSxcbiAgICB0eEhhc2g6IG5vQ2hhbmdlVGVzdERhdGEudHhoYXNoLFxuICB9KTtcblxuICBpdCgnU2hvdWxkIGZ1bGwgc2lnbiBhIGV4cG9ydCB0eCBmcm9tIHVuc2lnbmVkIHJhdyB0eCcsICgpID0+IHtcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBuZXcgVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeShjb2lucy5nZXQoJ3RmbHJwJykpLmZyb20odGVzdERhdGEudW5zaWduZWRIZXgpO1xuICAgIHR4QnVpbGRlci5zaWduKHsga2V5OiB0ZXN0RGF0YS5wcml2YXRlS2V5c1swXSB9KTtcbiAgICB0eEJ1aWxkZXJcbiAgICAgIC5idWlsZCgpXG4gICAgICAudGhlbigoKSA9PiBhc3NlcnQuZmFpbCgnaXQgY2FuIHNpZ24nKSlcbiAgICAgIC5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgIGVyci5tZXNzYWdlLnNob3VsZC5iZS5lcXVhbCgnUHJpdmF0ZSBrZXkgY2Fubm90IHNpZ24gdGhlIHRyYW5zYWN0aW9uJyk7XG4gICAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ29uLWNoYWluIHZlcmlmaWVkIHRyYW5zYWN0aW9ucycsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIHZlcmlmeSBvbi1jaGFpbiB0eCBpZCBmb3Igc2lnbmVkIFAtY2hhaW4gZXhwb3J0JywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3Qgc2lnbmVkRXhwb3J0SGV4ID1cbiAgICAgICAgJzB4MDAwMDAwMDAwMDEyMDAwMDAwNzIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDE1ODczNGY5NGFmODcxYzNkMTMxYjU2MTMxYjZmYjdhMDI5MWVhY2FkZDI2MWU2OWRmYjQyYTljZGY2ZjdmZGRkMDAwMDAwMDcwMDAwMDAwMDFhYzZlNTU4MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxMDAwMDAwMDMzMzI5YmU3ZDAxY2QzZWJhYWU2NjU0ZDczMjdkZDlmMTdhMmUxNTgxN2U5MThhNWU4MDgzYWU0YzlmMmYwZWQ3NzA1NWMyNGJmMzY2NTAwMWM3MzI0NDM3Yzk2YzdjOGE2YTE1MmRhMjM4NWMxZGI1YzNhYjFmOTEwMDAwMDAwMzg2MmNlODZiYTJlMjg4ODRlOGI4M2Y1ZDYyNjZkMjc0YjMzNjMyYTFjYzIxM2Q0YzEyOTk2MDM3ZmMyMWIyMDIwMDAwMDAwMDU4NzM0Zjk0YWY4NzFjM2QxMzFiNTYxMzFiNmZiN2EwMjkxZWFjYWRkMjYxZTY5ZGZiNDJhOWNkZjZmN2ZkZGQwMDAwMDAwNTAwMDAwMDAwMWQ2Yzk2YzYwMDAwMDAwMTAwMDAwMDAwYTQ4OTFkZmJkMDI0YTUzYjhlNDUxMjQyN2Q5MTk5MTA1Njg5ODliOWI0ODQ2MDI2YWM3YmNiODI5MDQ5NGMyNjAwMDAwMDAwNTg3MzRmOTRhZjg3MWMzZDEzMWI1NjEzMWI2ZmI3YTAyOTFlYWNhZGQyNjFlNjlkZmI0MmE5Y2RmNmY3ZmRkZDAwMDAwMDA1MDAwMDAwMDAwMDNmZmFiYzAwMDAwMDAxMDAwMDAwMDBjMWZiM2I0MzhmOGY0OWUxYmI2NTdhNTkxMDZiZTlmNWY5MWQyZWZjZTVlMDI1OWZjYmJiOTQ1OGUyNzFmODBkMDAwMDAwMDA1ODczNGY5NGFmODcxYzNkMTMxYjU2MTMxYjZmYjdhMDI5MWVhY2FkZDI2MWU2OWRmYjQyYTljZGY2ZjdmZGRkMDAwMDAwMDUwMDAwMDAwMDAwNDAwZTcwMDAwMDAwMDEwMDAwMDAwMDAwMDAwMDAwNzhkYjVjMzBiZWQwNGMwNWNlMjA5MTc5ODEyODUwYmJiM2ZlNmQ0NmQ3ZWVmMzc0NGQ4MTRjMGRhNTU1MjQ3OTAwMDAwMDAxNTg3MzRmOTRhZjg3MWMzZDEzMWI1NjEzMWI2ZmI3YTAyOTFlYWNhZGQyNjFlNjlkZmI0MmE5Y2RmNmY3ZmRkZDAwMDAwMDA3MDAwMDAwMDAwMmZhZjA4MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMjAwMDAwMDAzMzMyOWJlN2QwMWNkM2ViYWFlNjY1NGQ3MzI3ZGQ5ZjE3YTJlMTU4MTdlOTE4YTVlODA4M2FlNGM5ZjJmMGVkNzcwNTVjMjRiZjM2NjUwMDFjNzMyNDQzN2M5NmM3YzhhNmExNTJkYTIzODVjMWRiNWMzYWIxZjkxMDAwMDAwMDMwMDAwMDAwOTAwMDAwMDAxYWZkZjBhYzJiZGJmYjE3MzUwODFkZDg1OWY0ZDI2M2U1ODdkODFiYTgxYzZiZDJjYjM0NWVlNWE2NmNlZjRlOTdhNjM0Yzc0MGYzNWVmNmJhNjAwNzk2YTVhZGQxZDkxZTY5YTE0Y2ZjYjIyYjY1ZTZhZTBiY2RmYmNlYmZhYmEwMDAwMDAwMDA5MDAwMDAwMDFhZmRmMGFjMmJkYmZiMTczNTA4MWRkODU5ZjRkMjYzZTU4N2Q4MWJhODFjNmJkMmNiMzQ1ZWU1YTY2Y2VmNGU5N2E2MzRjNzQwZjM1ZWY2YmE2MDA3OTZhNWFkZDFkOTFlNjlhMTRjZmNiMjJiNjVlNmFlMGJjZGZiY2ViZmFiYTAwMDAwMDAwMDkwMDAwMDAwMWFmZGYwYWMyYmRiZmIxNzM1MDgxZGQ4NTlmNGQyNjNlNTg3ZDgxYmE4MWM2YmQyY2IzNDVlZTVhNjZjZWY0ZTk3YTYzNGM3NDBmMzVlZjZiYTYwMDc5NmE1YWRkMWQ5MWU2OWExNGNmY2IyMmI2NWU2YWUwYmNkZmJjZWJmYWJhMDAnO1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gbmV3IFRyYW5zYWN0aW9uQnVpbGRlckZhY3RvcnkoY29pbnMuZ2V0KCd0ZmxycCcpKS5mcm9tKHNpZ25lZEV4cG9ydEhleCk7XG4gICAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgICAgY29uc3QgcmF3VHggPSB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuICAgICAgcmF3VHguc2hvdWxkLmVxdWFsKHNpZ25lZEV4cG9ydEhleCk7XG4gICAgICB0eC5pZC5zaG91bGQuZXF1YWwoJ2thOGF0NUNpbm1wVWM2UU1WcjMzZHlVSmkxNTZMS01kb2RySk01OWtTNkVXcjN2SGcnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgRkFJTCB3aXRoIHVuc29ydGVkIFVUWE8gYWRkcmVzc2VzIC0gZGVtb25zdHJhdGVzIEFkZHJlc3NNYXAgbWlzbWF0Y2ggaXNzdWUgZm9yIGV4cG9ydCBpbiBQLWNoYWluIHR4JywgYXN5bmMgKCkgPT4ge1xuICAgICAgLy8gVGhpcyB0ZXN0IHVzZXMgVVRYTyBhZGRyZXNzZXMgaW4gVU5TT1JURUQgb3JkZXIgdG8gZGVtb25zdHJhdGUgdGhlIGlzc3VlLlxuICAgICAgLy8gV2l0aCB1bnNvcnRlZCBhZGRyZXNzZXMsIHRoZSBjdXJyZW50IGltcGxlbWVudGF0aW9uIHdpbGwgY3JlYXRlIEFkZHJlc3NNYXBzIGluY29ycmVjdGx5XG4gICAgICAvLyBiZWNhdXNlIGl0IHVzZXMgc29ydGVkIGFkZHJlc3Nlcywgbm90IFVUWE8gYWRkcmVzcyBvcmRlci5cbiAgICAgIC8vXG4gICAgICAvLyBFeHBlY3RlZDogQWRkcmVzc01hcCBzaG91bGQgbWFwIGFkZHJlc3NlcyB0byBzaWduYXR1cmUgc2xvdHMgYmFzZWQgb24gVVRYTyBvcmRlciAoc2lnSW5kaWNpZXMpXG4gICAgICAvLyBDdXJyZW50IChXUk9ORyk6IEFkZHJlc3NNYXAgdXNlcyBzb3J0ZWQgYWRkcmVzc2VzIHdpdGggc2VxdWVudGlhbCBzbG90c1xuICAgICAgLy9cbiAgICAgIC8vIFRoaXMgdGVzdCBXSUxMIEZBSUwgd2l0aCBjdXJyZW50IGltcGxlbWVudGF0aW9uIGJlY2F1c2UgQWRkcmVzc01hcHMgZG9uJ3QgbWF0Y2ggc2lnSW5kaWNpZXNcblxuICAgICAgLy8gVVRYTyBhZGRyZXNzZXMgaW4gVU5TT1JURUQgb3JkZXIgKGRpZmZlcmVudCBmcm9tIHNvcnRlZClcbiAgICAgIC8vIFNvcnRlZCB3b3VsZCBiZTogWzB4MTJjYi4uLiAoc21hbGxlc3QpLCAweGE2ZTAuLi4gKG1pZGRsZSksIDB4YzM4Ni4uLiAobGFyZ2VzdCldXG4gICAgICAvLyBVbnNvcnRlZDogWzB4YzM4Ni4uLiAobGFyZ2VzdCksIDB4MTJjYi4uLiAoc21hbGxlc3QpLCAweGE2ZTAuLi4gKG1pZGRsZSldXG4gICAgICBjb25zdCB1bnNvcnRlZFV0eG9BZGRyZXNzZXMgPSBbXG4gICAgICAgICcweGMzODZkNThkMDlhOWFlNzdjZjFjZjA3YmYxYzlkZTQ0ZWJiMGM5ZjMnLCAvLyBMYXJnZXN0ICh3b3VsZCBiZSBpbmRleCAyIGlmIHNvcnRlZClcbiAgICAgICAgJzB4MTJjYjMyZWFmOTI1NTMwNjRkYjk4ZDI3MWI1NmNiYTA3OWVjNzhmNScsIC8vIFNtYWxsZXN0ICh3b3VsZCBiZSBpbmRleCAwIGlmIHNvcnRlZClcbiAgICAgICAgJzB4YTZlMGMxYWJkMDEzMmY3MGVmYjc3ZTIyNzQ2MzdmZjMzNmEyOWE1NycsIC8vIE1pZGRsZSAod291bGQgYmUgaW5kZXggMSBpZiBzb3J0ZWQpXG4gICAgICBdO1xuXG4gICAgICAvLyBDb3JyZXNwb25kaW5nIFAtY2hhaW4gYWRkcmVzc2VzIChpbiBzYW1lIG9yZGVyIGFzIFVUWE8pXG4gICAgICBjb25zdCBwQWRkcmVzc2VzID0gW1xuICAgICAgICAnUC1jb3N0d28xNW1zdnIyN3N6dmhocG1haDBjMzhnY21sN3ZtMjl4amg3dGNlazgnLCAvLyBNYXBzIHRvIDB4YzM4Ni4uLiAoVVRYTyBpbmRleCAwKVxuICAgICAgICAnUC1jb3N0d28xenQ5bjk2aGV5NGZzdm5kZTM1bjNrNGt0NXB1N2M3ODRkemV3emQnLCAvLyBNYXBzIHRvIDB4MTJjYi4uLiAoVVRYTyBpbmRleCAxKVxuICAgICAgICAnUC1jb3N0d28xY3dyZHRyZ2Y0eGg4MG5jdTdwYWxyanc3Z240bXBqMG40ZHhnaGgnLCAvLyBNYXBzIHRvIDB4YTZlMC4uLiAoVVRYTyBpbmRleCAyKVxuICAgICAgXTtcblxuICAgICAgLy8gQ3JlYXRlIFVUWE8gd2l0aCBVTlNPUlRFRCBhZGRyZXNzZXNcbiAgICAgIC8vIEFtb3VudCBtdXN0IGNvdmVyIGV4cG9ydCBhbW91bnQgKyBmZWVcbiAgICAgIGNvbnN0IGV4cG9ydEFtb3VudCA9ICc1MDAwMDAwMCc7XG4gICAgICBjb25zdCBmZWUgPSAnMTI2MTAwMCc7XG4gICAgICBjb25zdCB1dHhvQW1vdW50ID0gKEJpZ0ludChleHBvcnRBbW91bnQpICsgQmlnSW50KGZlZSkpLnRvU3RyaW5nKCk7IC8vIGFtb3VudCArIGZlZVxuXG4gICAgICBjb25zdCB1dHhvOiBEZWNvZGVkVXR4b09iaiA9IHtcbiAgICAgICAgb3V0cHV0SUQ6IDAsXG4gICAgICAgIGFtb3VudDogdXR4b0Ftb3VudCxcbiAgICAgICAgdHhpZDogJ3pzdHlZcTVyaURLWURTUjNmVVlLS2t1WEtKMWFKQ2U4V05yWEtxRUJKRDRDR3d6RncnLFxuICAgICAgICBvdXRwdXRpZHg6ICcwJyxcbiAgICAgICAgYWRkcmVzc2VzOiB1bnNvcnRlZFV0eG9BZGRyZXNzZXMsIC8vIFVOU09SVEVEIG9yZGVyXG4gICAgICAgIHRocmVzaG9sZDogMixcbiAgICAgIH07XG5cbiAgICAgIC8vIEJ1aWxkIHRyYW5zYWN0aW9uXG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5XG4gICAgICAgIC5nZXRFeHBvcnRJblBCdWlsZGVyKClcbiAgICAgICAgLnRocmVzaG9sZCgyKVxuICAgICAgICAubG9ja3RpbWUoMClcbiAgICAgICAgLmZyb21QdWJLZXkocEFkZHJlc3NlcylcbiAgICAgICAgLmV4dGVybmFsQ2hhaW5JZCh0ZXN0RGF0YS5zb3VyY2VDaGFpbklkKVxuICAgICAgICAuYW1vdW50KGV4cG9ydEFtb3VudClcbiAgICAgICAgLmZlZShmZWUpXG4gICAgICAgIC51dHhvcyhbdXR4b10pO1xuXG4gICAgICAvLyBCdWlsZCB1bnNpZ25lZCB0cmFuc2FjdGlvblxuICAgICAgY29uc3QgdW5zaWduZWRUeCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgICAgY29uc3QgdW5zaWduZWRIZXggPSB1bnNpZ25lZFR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG5cbiAgICAgIC8vIFBhcnNlIGl0IGJhY2sgdG8gaW5zcGVjdCBBZGRyZXNzTWFwcyBhbmQgc2lnSW5kaWNpZXNcbiAgICAgIGNvbnN0IHBhcnNlZEJ1aWxkZXIgPSBmYWN0b3J5LmZyb20odW5zaWduZWRIZXgpO1xuICAgICAgY29uc3QgcGFyc2VkVHggPSBhd2FpdCBwYXJzZWRCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICBjb25zdCBmbGFyZVR4ID0gKHBhcnNlZFR4IGFzIGFueSkuX2ZsYXJlVHJhbnNhY3Rpb247XG5cbiAgICAgIC8vIEdldCB0aGUgaW5wdXQgdG8gY2hlY2sgc2lnSW5kaWNpZXNcbiAgICAgIGNvbnN0IGV4cG9ydFR4ID0gZmxhcmVUeC50eCBhcyBhbnk7XG4gICAgICBjb25zdCBpbnB1dCA9IGV4cG9ydFR4LmJhc2VUeC5pbnB1dHNbMF07XG4gICAgICBjb25zdCB0cmFuc2ZlcklucHV0ID0gaW5wdXQuaW5wdXQ7XG4gICAgICBjb25zdCBzaWdJbmRpY2llcyA9IHRyYW5zZmVySW5wdXQuc2lnSW5kaWNpZXMoKTtcblxuICAgICAgLy8gc2lnSW5kaWNpZXMgdGVsbHMgdXM6IHNpZ0luZGljaWVzW3Nsb3RJbmRleF0gPSB1dHhvQWRkcmVzc0luZGV4XG4gICAgICAvLyBGb3IgdGhyZXNob2xkPTIsIHdlIG5lZWQgc2lnbmF0dXJlcyBmb3IgZmlyc3QgMiBhZGRyZXNzZXMgaW4gVVRYTyBvcmRlclxuICAgICAgLy8gVVRYTyBvcmRlcjogWzB4YzM4Ni4uLiAoaW5kZXggMCksIDB4MTJjYi4uLiAoaW5kZXggMSksIDB4YTZlMC4uLiAoaW5kZXggMildXG4gICAgICAvLyBTbyBzaWdJbmRpY2llcyBzaG91bGQgYmUgWzAsIDFdIG1lYW5pbmc6IHNsb3QgMCA9IFVUWE8gaW5kZXggMCwgc2xvdCAxID0gVVRYTyBpbmRleCAxXG5cbiAgICAgIC8vIFZlcmlmeSBzaWdJbmRpY2llcyBhcmUgWzAsIDFdIChmaXJzdCAyIGFkZHJlc3NlcyBpbiBVVFhPIG9yZGVyLCBOT1Qgc29ydGVkIG9yZGVyKVxuICAgICAgc2lnSW5kaWNpZXMubGVuZ3RoLnNob3VsZC5lcXVhbCgyKTtcbiAgICAgIHNpZ0luZGljaWVzWzBdLnNob3VsZC5lcXVhbCgwLCAnRmlyc3Qgc2lnbmF0dXJlIHNsb3Qgc2hvdWxkIGJlIFVUWE8gYWRkcmVzcyBpbmRleCAwICgweGMzODYuLi4pJyk7XG4gICAgICBzaWdJbmRpY2llc1sxXS5zaG91bGQuZXF1YWwoMSwgJ1NlY29uZCBzaWduYXR1cmUgc2xvdCBzaG91bGQgYmUgVVRYTyBhZGRyZXNzIGluZGV4IDEgKDB4MTJjYi4uLiknKTtcblxuICAgICAgLy8gVGhlIGNyaXRpY2FsIHRlc3Q6IFZlcmlmeSB0aGF0IHNpZ25hdHVyZSBzbG90cyBoYXZlIGVtYmVkZGVkIGFkZHJlc3NlcyBiYXNlZCBvbiBVVFhPIG9yZGVyXG4gICAgICAvLyBXaXRoIHVuc29ydGVkIFVUWE8gYWRkcmVzc2VzLCB0aGlzIHdpbGwgRkFJTCBpZiBBZGRyZXNzTWFwcyBkb24ndCBtYXRjaCBVVFhPIG9yZGVyXG4gICAgICAvL1xuICAgICAgLy8gc2lnSW5kaWNpZXMgdGVsbHMgdXM6IHNpZ0luZGljaWVzW3Nsb3RJbmRleF0gPSB1dHhvQWRkcmVzc0luZGV4XG4gICAgICAvLyBGb3IgdGhyZXNob2xkPTIsIHdlIG5lZWQgc2lnbmF0dXJlcyBmb3IgZmlyc3QgMiBhZGRyZXNzZXMgaW4gVVRYTyBvcmRlclxuICAgICAgLy8gVVRYTyBvcmRlcjogWzB4YzM4Ni4uLiAoaW5kZXggMCksIDB4MTJjYi4uLiAoaW5kZXggMSksIDB4YTZlMC4uLiAoaW5kZXggMildXG4gICAgICAvLyBTbyBzaWdJbmRpY2llcyBzaG91bGQgYmUgWzAsIDFdIG1lYW5pbmc6IHNsb3QgMCA9IFVUWE8gaW5kZXggMCwgc2xvdCAxID0gVVRYTyBpbmRleCAxXG5cbiAgICAgIC8vIFBhcnNlIHRoZSBjcmVkZW50aWFsIHRvIHNlZSB3aGljaCBzbG90cyBoYXZlIHdoaWNoIGVtYmVkZGVkIGFkZHJlc3Nlc1xuICAgICAgY29uc3QgY3JlZGVudGlhbCA9IGZsYXJlVHguY3JlZGVudGlhbHNbMF07XG4gICAgICBjb25zdCBzaWduYXR1cmVzID0gY3JlZGVudGlhbC5nZXRTaWduYXR1cmVzKCk7XG5cbiAgICAgIC8vIEhlbHBlciBmdW5jdGlvbiB0byBjaGVjayBpZiBzaWduYXR1cmUgaGFzIGVtYmVkZGVkIGFkZHJlc3MgKHNhbWUgbG9naWMgYXMgdHJhbnNhY3Rpb24udHMpXG4gICAgICBjb25zdCB0ZXN0VXRpbHMyID0gcmVxdWlyZSgnLi4vLi4vLi4vc3JjL2xpYi91dGlscycpLmRlZmF1bHQ7XG4gICAgICBjb25zdCBpc0VtcHR5U2lnbmF0dXJlID0gKHNpZ25hdHVyZTogc3RyaW5nKTogYm9vbGVhbiA9PiB7XG4gICAgICAgIHJldHVybiAhIXNpZ25hdHVyZSAmJiB0ZXN0VXRpbHMyLnJlbW92ZUhleFByZWZpeChzaWduYXR1cmUpLnN0YXJ0c1dpdGgoJzAnLnJlcGVhdCg5MCkpO1xuICAgICAgfTtcblxuICAgICAgY29uc3QgaGFzRW1iZWRkZWRBZGRyZXNzID0gKHNpZ25hdHVyZTogc3RyaW5nKTogYm9vbGVhbiA9PiB7XG4gICAgICAgIGlmICghaXNFbXB0eVNpZ25hdHVyZShzaWduYXR1cmUpKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIGNvbnN0IGNsZWFuU2lnID0gdGVzdFV0aWxzMi5yZW1vdmVIZXhQcmVmaXgoc2lnbmF0dXJlKTtcbiAgICAgICAgaWYgKGNsZWFuU2lnLmxlbmd0aCA8IDEzMCkgcmV0dXJuIGZhbHNlO1xuICAgICAgICBjb25zdCBlbWJlZGRlZFBhcnQgPSBjbGVhblNpZy5zdWJzdHJpbmcoOTAsIDEzMCk7XG4gICAgICAgIC8vIENoZWNrIGlmIGVtYmVkZGVkIHBhcnQgaXMgbm90IGFsbCB6ZXJvc1xuICAgICAgICByZXR1cm4gZW1iZWRkZWRQYXJ0ICE9PSAnMCcucmVwZWF0KDQwKTtcbiAgICAgIH07XG5cbiAgICAgIC8vIEV4dHJhY3QgZW1iZWRkZWQgYWRkcmVzc2VzIGZyb20gc2lnbmF0dXJlIHNsb3RzXG4gICAgICBjb25zdCBlbWJlZGRlZEFkZHJlc3Nlczogc3RyaW5nW10gPSBbXTtcblxuICAgICAgc2lnbmF0dXJlcy5mb3JFYWNoKChzaWc6IHN0cmluZywgc2xvdEluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgaWYgKGhhc0VtYmVkZGVkQWRkcmVzcyhzaWcpKSB7XG4gICAgICAgICAgLy8gRXh0cmFjdCBlbWJlZGRlZCBhZGRyZXNzIChhZnRlciBwb3NpdGlvbiA5MCwgNDAgY2hhcnMgPSAyMCBieXRlcylcbiAgICAgICAgICBjb25zdCBjbGVhblNpZyA9IHRlc3RVdGlsczIucmVtb3ZlSGV4UHJlZml4KHNpZyk7XG4gICAgICAgICAgY29uc3QgZW1iZWRkZWRBZGRyID0gY2xlYW5TaWcuc3Vic3RyaW5nKDkwLCAxMzApLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgICAgZW1iZWRkZWRBZGRyZXNzZXNbc2xvdEluZGV4XSA9ICcweCcgKyBlbWJlZGRlZEFkZHI7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICAvLyBWZXJpZnk6IENyZWRlbnRpYWxzIG9ubHkgZW1iZWQgT05FIGFkZHJlc3MgKHVzZXIvcmVjb3ZlcnkpLCBub3QgYm90aFxuICAgICAgLy8gVGhlIGVtYmVkZGVkIGFkZHJlc3Mgc2hvdWxkIGJlIGJhc2VkIG9uIGFkZHJlc3Nlc0luZGV4IGxvZ2ljLCBub3Qgc29ydGVkIG9yZGVyXG4gICAgICAvL1xuICAgICAgLy8gQ29tcHV0ZSBhZGRyZXNzZXNJbmRleCB0byBkZXRlcm1pbmUgZXhwZWN0ZWQgc2lnbmF0dXJlIG9yZGVyXG4gICAgICBjb25zdCB1dHhvQWRkcmVzc0J5dGVzID0gdW5zb3J0ZWRVdHhvQWRkcmVzc2VzLm1hcCgoYWRkcikgPT4gdGVzdFV0aWxzMi5wYXJzZUFkZHJlc3MoYWRkcikpO1xuICAgICAgY29uc3QgcEFkZHJlc3NCeXRlcyA9IHBBZGRyZXNzZXMubWFwKChhZGRyKSA9PiB0ZXN0VXRpbHMyLnBhcnNlQWRkcmVzcyhhZGRyKSk7XG5cbiAgICAgIGNvbnN0IGFkZHJlc3Nlc0luZGV4OiBudW1iZXJbXSA9IFtdO1xuICAgICAgcEFkZHJlc3NCeXRlcy5mb3JFYWNoKChwQWRkcikgPT4ge1xuICAgICAgICBjb25zdCB1dHhvSW5kZXggPSB1dHhvQWRkcmVzc0J5dGVzLmZpbmRJbmRleChcbiAgICAgICAgICAodUFkZHIpID0+IEJ1ZmZlci5jb21wYXJlKEJ1ZmZlci5mcm9tKHVBZGRyKSwgQnVmZmVyLmZyb20ocEFkZHIpKSA9PT0gMFxuICAgICAgICApO1xuICAgICAgICBhZGRyZXNzZXNJbmRleC5wdXNoKHV0eG9JbmRleCk7XG4gICAgICB9KTtcblxuICAgICAgLy8gZmlyc3RJbmRleCA9IDAgKHVzZXIpLCBiaXRnb0luZGV4ID0gMVxuICAgICAgY29uc3QgZmlyc3RJbmRleCA9IDA7XG4gICAgICBjb25zdCBiaXRnb0luZGV4ID0gMTtcblxuICAgICAgLy8gRGV0ZXJtaW5lIGV4cGVjdGVkIHNpZ25hdHVyZSBvcmRlciBiYXNlZCBvbiBhZGRyZXNzZXNJbmRleFxuICAgICAgY29uc3QgdXNlckNvbWVzRmlyc3QgPSBhZGRyZXNzZXNJbmRleFtiaXRnb0luZGV4XSA+IGFkZHJlc3Nlc0luZGV4W2ZpcnN0SW5kZXhdO1xuXG4gICAgICAvLyBFeHBlY3RlZCBjcmVkZW50aWFsIHN0cnVjdHVyZTpcbiAgICAgIC8vIC0gSWYgdXNlciBjb21lcyBmaXJzdDogW3VzZXJBZGRyZXNzLCB6ZXJvc11cbiAgICAgIC8vIC0gSWYgYml0Z28gY29tZXMgZmlyc3Q6IFt6ZXJvcywgdXNlckFkZHJlc3NdXG4gICAgICBjb25zdCB1c2VyQWRkcmVzc0hleCA9IEJ1ZmZlci5mcm9tKHBBZGRyZXNzQnl0ZXNbZmlyc3RJbmRleF0pLnRvU3RyaW5nKCdoZXgnKS50b0xvd2VyQ2FzZSgpO1xuICAgICAgY29uc3QgZXhwZWN0ZWRVc2VyQWRkciA9ICcweCcgKyB1c2VyQWRkcmVzc0hleDtcblxuICAgICAgaWYgKHVzZXJDb21lc0ZpcnN0KSB7XG4gICAgICAgIC8vIEV4cGVjdGVkOiBbdXNlckFkZHJlc3MsIHplcm9zXVxuICAgICAgICAvLyBTbG90IDAgc2hvdWxkIGhhdmUgdXNlciBhZGRyZXNzIChwQWRkcjAgPSAweGMzODYuLi4gPSBVVFhPIGluZGV4IDApXG4gICAgICAgIGlmIChlbWJlZGRlZEFkZHJlc3Nlc1swXSkge1xuICAgICAgICAgIGVtYmVkZGVkQWRkcmVzc2VzWzBdXG4gICAgICAgICAgICAudG9Mb3dlckNhc2UoKVxuICAgICAgICAgICAgLnNob3VsZC5lcXVhbChcbiAgICAgICAgICAgICAgZXhwZWN0ZWRVc2VyQWRkcixcbiAgICAgICAgICAgICAgYFNsb3QgMCBzaG91bGQgaGF2ZSB1c2VyIGFkZHJlc3MgKCR7ZXhwZWN0ZWRVc2VyQWRkcn0pIGJlY2F1c2UgdXNlciBjb21lcyBmaXJzdCBpbiBVVFhPIG9yZGVyYFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFNsb3QgMCBzaG91bGQgaGF2ZSBlbWJlZGRlZCB1c2VyIGFkZHJlc3MsIGJ1dCBpcyBlbXB0eWApO1xuICAgICAgICB9XG4gICAgICAgIC8vIFNsb3QgMSBzaG91bGQgYmUgemVyb3MgKG5vIGVtYmVkZGVkIGFkZHJlc3MpXG4gICAgICAgIGlmIChlbWJlZGRlZEFkZHJlc3Nlc1sxXSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgU2xvdCAxIHNob3VsZCBiZSB6ZXJvcywgYnV0IGhhcyBlbWJlZGRlZCBhZGRyZXNzOiAke2VtYmVkZGVkQWRkcmVzc2VzWzFdfWApO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBFeHBlY3RlZDogW3plcm9zLCB1c2VyQWRkcmVzc11cbiAgICAgICAgLy8gU2xvdCAwIHNob3VsZCBiZSB6ZXJvc1xuICAgICAgICBpZiAoZW1iZWRkZWRBZGRyZXNzZXNbMF0pIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFNsb3QgMCBzaG91bGQgYmUgemVyb3MsIGJ1dCBoYXMgZW1iZWRkZWQgYWRkcmVzczogJHtlbWJlZGRlZEFkZHJlc3Nlc1swXX1gKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBTbG90IDEgc2hvdWxkIGhhdmUgdXNlciBhZGRyZXNzXG4gICAgICAgIGlmIChlbWJlZGRlZEFkZHJlc3Nlc1sxXSkge1xuICAgICAgICAgIGVtYmVkZGVkQWRkcmVzc2VzWzFdXG4gICAgICAgICAgICAudG9Mb3dlckNhc2UoKVxuICAgICAgICAgICAgLnNob3VsZC5lcXVhbChcbiAgICAgICAgICAgICAgZXhwZWN0ZWRVc2VyQWRkcixcbiAgICAgICAgICAgICAgYFNsb3QgMSBzaG91bGQgaGF2ZSB1c2VyIGFkZHJlc3MgKCR7ZXhwZWN0ZWRVc2VyQWRkcn0pIGJlY2F1c2UgYml0Z28gY29tZXMgZmlyc3QgaW4gVVRYTyBvcmRlcmBcbiAgICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBTbG90IDEgc2hvdWxkIGhhdmUgZW1iZWRkZWQgdXNlciBhZGRyZXNzLCBidXQgaXMgZW1wdHlgKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBUaGUga2V5IHZlcmlmaWNhdGlvbjogQWRkcmVzc01hcHMgc2hvdWxkIG1hdGNoIHRoZSBjcmVkZW50aWFsIG9yZGVyXG4gICAgICAvLyBXaXRoIHRoZSBmaXgsIEFkZHJlc3NNYXBzIGFyZSBjcmVhdGVkIHVzaW5nIHRoZSBzYW1lIGFkZHJlc3Nlc0luZGV4IGxvZ2ljIGFzIGNyZWRlbnRpYWxzXG4gICAgICAvLyBUaGlzIGVuc3VyZXMgc2lnbmluZyB3b3JrcyBjb3JyZWN0bHkgZXZlbiB3aXRoIHVuc29ydGVkIFVUWE8gYWRkcmVzc2VzXG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"importInCTxBuilder.d.ts","sourceRoot":"","sources":["../../../../test/unit/lib/importInCTxBuilder.ts"],"names":[],"mappings":"AACA,OAAO,QAAQ,CAAC"}
|