@bitgo/sdk-coin-ada 5.0.12 → 5.1.0

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.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=plutusPledgeBuilder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plutusPledgeBuilder.d.ts","sourceRoot":"","sources":["../../../test/unit/plutusPledgeBuilder.ts"],"names":[],"mappings":""}
@@ -0,0 +1,162 @@
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 CardanoWasm = __importStar(require("@emurgo/cardano-serialization-lib-nodejs"));
40
+ const should_1 = __importDefault(require("should"));
41
+ const statics_1 = require("@bitgo/statics");
42
+ const src_1 = require("../../src");
43
+ const resources_1 = require("../resources");
44
+ const TEST_ADDRESS = 'addr_test1vr8rakm66rcfv4fcxqykg5lf0yv7lsyk9mvapx369jpvtcgfcuk7f';
45
+ /**
46
+ * Builds a synthetic Plutus transaction analogous to CBOR WP would hand BitGoJS
47
+ * for RealFi pledge (parse -> sign -> re-serialize) flows.
48
+ */
49
+ function buildPlutusFixtureHex(includeAuxiliaryData = false) {
50
+ const addr = CardanoWasm.Address.from_bech32(TEST_ADDRESS);
51
+ const inputs = CardanoWasm.TransactionInputs.new();
52
+ inputs.add(CardanoWasm.TransactionInput.new(CardanoWasm.TransactionHash.from_bytes(Buffer.alloc(32, 1)), 0));
53
+ const datum = CardanoWasm.PlutusData.new_bytes(Buffer.from('deadbeef', 'hex'));
54
+ const outputs = CardanoWasm.TransactionOutputs.new();
55
+ const outputBuilder = CardanoWasm.TransactionOutputBuilder.new().with_address(addr).with_plutus_data(datum);
56
+ const mainOutput = outputBuilder.next().with_coin(CardanoWasm.BigNum.from_str('2000000')).build();
57
+ outputs.add(mainOutput);
58
+ const body = CardanoWasm.TransactionBody.new_tx_body(inputs, outputs, CardanoWasm.BigNum.from_str('200000'));
59
+ const collateral = CardanoWasm.TransactionInputs.new();
60
+ collateral.add(CardanoWasm.TransactionInput.new(CardanoWasm.TransactionHash.from_bytes(Buffer.alloc(32, 2)), 0));
61
+ body.set_collateral(collateral);
62
+ const collateralReturn = CardanoWasm.TransactionOutput.new(addr, CardanoWasm.Value.new(CardanoWasm.BigNum.from_str('1000000')));
63
+ body.set_collateral_return(collateralReturn);
64
+ body.set_total_collateral(CardanoWasm.BigNum.from_str('1000000'));
65
+ const referenceInputs = CardanoWasm.TransactionInputs.new();
66
+ referenceInputs.add(CardanoWasm.TransactionInput.new(CardanoWasm.TransactionHash.from_bytes(Buffer.alloc(32, 3)), 0));
67
+ body.set_reference_inputs(referenceInputs);
68
+ body.set_script_data_hash(CardanoWasm.ScriptDataHash.from_bytes(Buffer.alloc(32, 4)));
69
+ const witnessSet = CardanoWasm.TransactionWitnessSet.new();
70
+ const plutusScripts = CardanoWasm.PlutusScripts.new();
71
+ plutusScripts.add(CardanoWasm.PlutusScript.new(Buffer.from('510100003222253330033371e00c', 'hex')));
72
+ witnessSet.set_plutus_scripts(plutusScripts);
73
+ const plutusDataList = CardanoWasm.PlutusList.new();
74
+ plutusDataList.add(datum);
75
+ witnessSet.set_plutus_data(plutusDataList);
76
+ const redeemers = CardanoWasm.Redeemers.new();
77
+ redeemers.add(CardanoWasm.Redeemer.new(CardanoWasm.RedeemerTag.new_spend(), CardanoWasm.BigNum.from_str('0'), datum, CardanoWasm.ExUnits.new(CardanoWasm.BigNum.from_str('1000000'), CardanoWasm.BigNum.from_str('500000'))));
78
+ witnessSet.set_redeemers(redeemers);
79
+ let auxiliaryData;
80
+ if (includeAuxiliaryData) {
81
+ const metadata = CardanoWasm.GeneralTransactionMetadata.new();
82
+ metadata.insert(CardanoWasm.BigNum.from_str('674'), CardanoWasm.TransactionMetadatum.new_text('realfi-test'));
83
+ auxiliaryData = CardanoWasm.AuxiliaryData.new();
84
+ auxiliaryData.set_metadata(metadata);
85
+ body.set_auxiliary_data_hash(CardanoWasm.hash_auxiliary_data(auxiliaryData));
86
+ }
87
+ const tx = auxiliaryData !== undefined
88
+ ? CardanoWasm.Transaction.new(body, witnessSet, auxiliaryData)
89
+ : CardanoWasm.Transaction.new(body, witnessSet);
90
+ return Buffer.from(tx.to_bytes()).toString('hex');
91
+ }
92
+ describe('ADA Plutus Passthrough Builder', () => {
93
+ const plutusFixtureHex = buildPlutusFixtureHex();
94
+ it('should detect plutus data on the parsed transaction', () => {
95
+ const tx = new src_1.Transaction(statics_1.coins.get('tada'));
96
+ tx.fromRawTransaction(plutusFixtureHex);
97
+ tx.hasPlutusData().should.be.true();
98
+ const plainTx = new src_1.Transaction(statics_1.coins.get('tada'));
99
+ plainTx.fromRawTransaction(resources_1.rawTx.unsignedNewPledgeTx);
100
+ plainTx.hasPlutusData().should.be.false();
101
+ });
102
+ it('should round-trip a plutus transaction byte-for-byte with no new signature', async () => {
103
+ const factory = new src_1.TransactionBuilderFactory(statics_1.coins.get('tada'));
104
+ const txBuilder = factory.from(plutusFixtureHex);
105
+ const tx = (await txBuilder.build());
106
+ tx.toBroadcastFormat().should.equal(plutusFixtureHex);
107
+ });
108
+ it('should preserve plutus fields and produce a valid vkey for the body hash', async () => {
109
+ const factory = new src_1.TransactionBuilderFactory(statics_1.coins.get('tada'));
110
+ const txBuilder = factory.from(plutusFixtureHex);
111
+ txBuilder.sign({ key: resources_1.privateKeys.prvKey4 });
112
+ const tx = (await txBuilder.build());
113
+ const broadcastHex = tx.toBroadcastFormat();
114
+ broadcastHex.should.not.equal(plutusFixtureHex);
115
+ const reparsed = CardanoWasm.Transaction.from_bytes(Buffer.from(broadcastHex, 'hex'));
116
+ const body = reparsed.body();
117
+ const witnessSet = reparsed.witness_set();
118
+ should_1.default.exist(body.collateral());
119
+ should_1.default.exist(body.collateral_return());
120
+ should_1.default.exist(body.total_collateral());
121
+ should_1.default.exist(body.reference_inputs());
122
+ should_1.default.exist(body.script_data_hash());
123
+ body.outputs().get(0).has_plutus_data().should.be.true();
124
+ should_1.default.exist(witnessSet.plutus_scripts());
125
+ should_1.default.exist(witnessSet.plutus_data());
126
+ should_1.default.exist(witnessSet.redeemers());
127
+ const originalTx = CardanoWasm.Transaction.from_bytes(Buffer.from(plutusFixtureHex, 'hex'));
128
+ body.collateral().to_bytes().should.deepEqual(originalTx.body().collateral().to_bytes());
129
+ body.collateral_return().to_bytes().should.deepEqual(originalTx.body().collateral_return().to_bytes());
130
+ body.total_collateral().to_bytes().should.deepEqual(originalTx.body().total_collateral().to_bytes());
131
+ body.reference_inputs().to_bytes().should.deepEqual(originalTx.body().reference_inputs().to_bytes());
132
+ body.script_data_hash().to_bytes().should.deepEqual(originalTx.body().script_data_hash().to_bytes());
133
+ witnessSet.plutus_scripts().to_bytes().should.deepEqual(originalTx.witness_set().plutus_scripts().to_bytes());
134
+ witnessSet.plutus_data().to_bytes().should.deepEqual(originalTx.witness_set().plutus_data().to_bytes());
135
+ witnessSet.redeemers().to_bytes().should.deepEqual(originalTx.witness_set().redeemers().to_bytes());
136
+ const keyPair = new src_1.KeyPair({ prv: resources_1.privateKeys.prvKey4 });
137
+ const expected = CardanoWasm.make_vkey_witness(CardanoWasm.hash_transaction(body), CardanoWasm.PrivateKey.from_normal_bytes(Buffer.from(keyPair.getKeys().prv, 'hex')));
138
+ const vkeys = witnessSet.vkeys();
139
+ should_1.default.exist(vkeys);
140
+ vkeys.len().should.equal(1);
141
+ vkeys.get(0).vkey().public_key().to_hex().should.equal(keyPair.getKeys().pub);
142
+ vkeys.get(0).signature().to_hex().should.equal(expected.signature().to_hex());
143
+ });
144
+ it('should preserve auxiliary data through the passthrough path', async () => {
145
+ const fixtureWithAux = buildPlutusFixtureHex(true);
146
+ const factory = new src_1.TransactionBuilderFactory(statics_1.coins.get('tada'));
147
+ const txBuilder = factory.from(fixtureWithAux);
148
+ txBuilder.sign({ key: resources_1.privateKeys.prvKey4 });
149
+ const tx = (await txBuilder.build());
150
+ const reparsed = CardanoWasm.Transaction.from_bytes(Buffer.from(tx.toBroadcastFormat(), 'hex'));
151
+ const original = CardanoWasm.Transaction.from_bytes(Buffer.from(fixtureWithAux, 'hex'));
152
+ should_1.default.exist(reparsed.auxiliary_data());
153
+ reparsed.auxiliary_data().to_bytes().should.deepEqual(original.auxiliary_data().to_bytes());
154
+ should_1.default.exist(reparsed.body().auxiliary_data_hash());
155
+ reparsed
156
+ .body()
157
+ .auxiliary_data_hash()
158
+ .to_bytes()
159
+ .should.deepEqual(original.body().auxiliary_data_hash().to_bytes());
160
+ });
161
+ });
162
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1dHVzUGxlZGdlQnVpbGRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Rlc3QvdW5pdC9wbHV0dXNQbGVkZ2VCdWlsZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsc0ZBQXdFO0FBQ3hFLG9EQUE0QjtBQUM1Qiw0Q0FBdUM7QUFDdkMsbUNBQTRFO0FBQzVFLDRDQUFrRDtBQUVsRCxNQUFNLFlBQVksR0FBRyxpRUFBaUUsQ0FBQztBQUV2Rjs7O0dBR0c7QUFDSCxTQUFTLHFCQUFxQixDQUFDLG9CQUFvQixHQUFHLEtBQUs7SUFDekQsTUFBTSxJQUFJLEdBQUcsV0FBVyxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsWUFBWSxDQUFDLENBQUM7SUFFM0QsTUFBTSxNQUFNLEdBQUcsV0FBVyxDQUFDLGlCQUFpQixDQUFDLEdBQUcsRUFBRSxDQUFDO0lBQ25ELE1BQU0sQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsZUFBZSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFN0csTUFBTSxLQUFLLEdBQUcsV0FBVyxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztJQUUvRSxNQUFNLE9BQU8sR0FBRyxXQUFXLENBQUMsa0JBQWtCLENBQUMsR0FBRyxFQUFFLENBQUM7SUFDckQsTUFBTSxhQUFhLEdBQUcsV0FBVyxDQUFDLHdCQUF3QixDQUFDLEdBQUcsRUFBRSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUM1RyxNQUFNLFVBQVUsR0FBRyxh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LFFBQVEsRUFBRSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLGNBQWMsRUFBRyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFDOUYsZ0JBQU0sQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxDQUFDLG1CQUFtQixFQUFFLENBQUMsQ0FBQztRQUNwRCxRQUFRO2FBQ0wsSUFBSSxFQUFFO2FBQ04sbUJBQW1CLEVBQUc7YUFDdEIsUUFBUSxFQUFFO2FBQ1YsTUFBTSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUMsbUJBQW1CLEVBQUcsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO0lBQ3pFLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBDYXJkYW5vV2FzbSBmcm9tICdAZW11cmdvL2NhcmRhbm8tc2VyaWFsaXphdGlvbi1saWItbm9kZWpzJztcbmltcG9ydCBzaG91bGQgZnJvbSAnc2hvdWxkJztcbmltcG9ydCB7IGNvaW5zIH0gZnJvbSAnQGJpdGdvL3N0YXRpY3MnO1xuaW1wb3J0IHsgS2V5UGFpciwgVHJhbnNhY3Rpb24sIFRyYW5zYWN0aW9uQnVpbGRlckZhY3RvcnkgfSBmcm9tICcuLi8uLi9zcmMnO1xuaW1wb3J0IHsgcHJpdmF0ZUtleXMsIHJhd1R4IH0gZnJvbSAnLi4vcmVzb3VyY2VzJztcblxuY29uc3QgVEVTVF9BRERSRVNTID0gJ2FkZHJfdGVzdDF2cjhyYWttNjZyY2Z2NGZjeHF5a2c1bGYweXY3bHN5azltdmFweDM2OWpwdnRjZ2ZjdWs3Zic7XG5cbi8qKlxuICogQnVpbGRzIGEgc3ludGhldGljIFBsdXR1cyB0cmFuc2FjdGlvbiBhbmFsb2dvdXMgdG8gQ0JPUiBXUCB3b3VsZCBoYW5kIEJpdEdvSlNcbiAqIGZvciBSZWFsRmkgcGxlZGdlIChwYXJzZSAtPiBzaWduIC0+IHJlLXNlcmlhbGl6ZSkgZmxvd3MuXG4gKi9cbmZ1bmN0aW9uIGJ1aWxkUGx1dHVzRml4dHVyZUhleChpbmNsdWRlQXV4aWxpYXJ5RGF0YSA9IGZhbHNlKTogc3RyaW5nIHtcbiAgY29uc3QgYWRkciA9IENhcmRhbm9XYXNtLkFkZHJlc3MuZnJvbV9iZWNoMzIoVEVTVF9BRERSRVNTKTtcblxuICBjb25zdCBpbnB1dHMgPSBDYXJkYW5vV2FzbS5UcmFuc2FjdGlvbklucHV0cy5uZXcoKTtcbiAgaW5wdXRzLmFkZChDYXJkYW5vV2FzbS5UcmFuc2FjdGlvbklucHV0Lm5ldyhDYXJkYW5vV2FzbS5UcmFuc2FjdGlvbkhhc2guZnJvbV9ieXRlcyhCdWZmZXIuYWxsb2MoMzIsIDEpKSwgMCkpO1xuXG4gIGNvbnN0IGRhdHVtID0gQ2FyZGFub1dhc20uUGx1dHVzRGF0YS5uZXdfYnl0ZXMoQnVmZmVyLmZyb20oJ2RlYWRiZWVmJywgJ2hleCcpKTtcblxuICBjb25zdCBvdXRwdXRzID0gQ2FyZGFub1dhc20uVHJhbnNhY3Rpb25PdXRwdXRzLm5ldygpO1xuICBjb25zdCBvdXRwdXRCdWlsZGVyID0gQ2FyZGFub1dhc20uVHJhbnNhY3Rpb25PdXRwdXRCdWlsZGVyLm5ldygpLndpdGhfYWRkcmVzcyhhZGRyKS53aXRoX3BsdXR1c19kYXRhKGRhdHVtKTtcbiAgY29uc3QgbWFpbk91dHB1dCA9IG91dHB1dEJ1aWxkZXIubmV4dCgpLndpdGhfY29pbihDYXJkYW5vV2FzbS5CaWdOdW0uZnJvbV9zdHIoJzIwMDAwMDAnKSkuYnVpbGQoKTtcbiAgb3V0cHV0cy5hZGQobWFpbk91dHB1dCk7XG5cbiAgY29uc3QgYm9keSA9IENhcmRhbm9XYXNtLlRyYW5zYWN0aW9uQm9keS5uZXdfdHhfYm9keShpbnB1dHMsIG91dHB1dHMsIENhcmRhbm9XYXNtLkJpZ051bS5mcm9tX3N0cignMjAwMDAwJykpO1xuXG4gIGNvbnN0IGNvbGxhdGVyYWwgPSBDYXJkYW5vV2FzbS5UcmFuc2FjdGlvbklucHV0cy5uZXcoKTtcbiAgY29sbGF0ZXJhbC5hZGQoQ2FyZGFub1dhc20uVHJhbnNhY3Rpb25JbnB1dC5uZXcoQ2FyZGFub1dhc20uVHJhbnNhY3Rpb25IYXNoLmZyb21fYnl0ZXMoQnVmZmVyLmFsbG9jKDMyLCAyKSksIDApKTtcbiAgYm9keS5zZXRfY29sbGF0ZXJhbChjb2xsYXRlcmFsKTtcblxuICBjb25zdCBjb2xsYXRlcmFsUmV0dXJuID0gQ2FyZGFub1dhc20uVHJhbnNhY3Rpb25PdXRwdXQubmV3KFxuICAgIGFkZHIsXG4gICAgQ2FyZGFub1dhc20uVmFsdWUubmV3KENhcmRhbm9XYXNtLkJpZ051bS5mcm9tX3N0cignMTAwMDAwMCcpKVxuICApO1xuICBib2R5LnNldF9jb2xsYXRlcmFsX3JldHVybihjb2xsYXRlcmFsUmV0dXJuKTtcbiAgYm9keS5zZXRfdG90YWxfY29sbGF0ZXJhbChDYXJkYW5vV2FzbS5CaWdOdW0uZnJvbV9zdHIoJzEwMDAwMDAnKSk7XG5cbiAgY29uc3QgcmVmZXJlbmNlSW5wdXRzID0gQ2FyZGFub1dhc20uVHJhbnNhY3Rpb25JbnB1dHMubmV3KCk7XG4gIHJlZmVyZW5jZUlucHV0cy5hZGQoQ2FyZGFub1dhc20uVHJhbnNhY3Rpb25JbnB1dC5uZXcoQ2FyZGFub1dhc20uVHJhbnNhY3Rpb25IYXNoLmZyb21fYnl0ZXMoQnVmZmVyLmFsbG9jKDMyLCAzKSksIDApKTtcbiAgYm9keS5zZXRfcmVmZXJlbmNlX2lucHV0cyhyZWZlcmVuY2VJbnB1dHMpO1xuICBib2R5LnNldF9zY3JpcHRfZGF0YV9oYXNoKENhcmRhbm9XYXNtLlNjcmlwdERhdGFIYXNoLmZyb21fYnl0ZXMoQnVmZmVyLmFsbG9jKDMyLCA0KSkpO1xuXG4gIGNvbnN0IHdpdG5lc3NTZXQgPSBDYXJkYW5vV2FzbS5UcmFuc2FjdGlvbldpdG5lc3NTZXQubmV3KCk7XG5cbiAgY29uc3QgcGx1dHVzU2NyaXB0cyA9IENhcmRhbm9XYXNtLlBsdXR1c1NjcmlwdHMubmV3KCk7XG4gIHBsdXR1c1NjcmlwdHMuYWRkKENhcmRhbm9XYXNtLlBsdXR1c1NjcmlwdC5uZXcoQnVmZmVyLmZyb20oJzUxMDEwMDAwMzIyMjI1MzMzMDAzMzM3MWUwMGMnLCAnaGV4JykpKTtcbiAgd2l0bmVzc1NldC5zZXRfcGx1dHVzX3NjcmlwdHMocGx1dHVzU2NyaXB0cyk7XG5cbiAgY29uc3QgcGx1dHVzRGF0YUxpc3QgPSBDYXJkYW5vV2FzbS5QbHV0dXNMaXN0Lm5ldygpO1xuICBwbHV0dXNEYXRhTGlzdC5hZGQoZGF0dW0pO1xuICB3aXRuZXNzU2V0LnNldF9wbHV0dXNfZGF0YShwbHV0dXNEYXRhTGlzdCk7XG5cbiAgY29uc3QgcmVkZWVtZXJzID0gQ2FyZGFub1dhc20uUmVkZWVtZXJzLm5ldygpO1xuICByZWRlZW1lcnMuYWRkKFxuICAgIENhcmRhbm9XYXNtLlJlZGVlbWVyLm5ldyhcbiAgICAgIENhcmRhbm9XYXNtLlJlZGVlbWVyVGFnLm5ld19zcGVuZCgpLFxuICAgICAgQ2FyZGFub1dhc20uQmlnTnVtLmZyb21fc3RyKCcwJyksXG4gICAgICBkYXR1bSxcbiAgICAgIENhcmRhbm9XYXNtLkV4VW5pdHMubmV3KENhcmRhbm9XYXNtLkJpZ051bS5mcm9tX3N0cignMTAwMDAwMCcpLCBDYXJkYW5vV2FzbS5CaWdOdW0uZnJvbV9zdHIoJzUwMDAwMCcpKVxuICAgIClcbiAgKTtcbiAgd2l0bmVzc1NldC5zZXRfcmVkZWVtZXJzKHJlZGVlbWVycyk7XG5cbiAgbGV0IGF1eGlsaWFyeURhdGE6IENhcmRhbm9XYXNtLkF1eGlsaWFyeURhdGEgfCB1bmRlZmluZWQ7XG4gIGlmIChpbmNsdWRlQXV4aWxpYXJ5RGF0YSkge1xuICAgIGNvbnN0IG1ldGFkYXRhID0gQ2FyZGFub1dhc20uR2VuZXJhbFRyYW5zYWN0aW9uTWV0YWRhdGEubmV3KCk7XG4gICAgbWV0YWRhdGEuaW5zZXJ0KENhcmRhbm9XYXNtLkJpZ051bS5mcm9tX3N0cignNjc0JyksIENhcmRhbm9XYXNtLlRyYW5zYWN0aW9uTWV0YWRhdHVtLm5ld190ZXh0KCdyZWFsZmktdGVzdCcpKTtcbiAgICBhdXhpbGlhcnlEYXRhID0gQ2FyZGFub1dhc20uQXV4aWxpYXJ5RGF0YS5uZXcoKTtcbiAgICBhdXhpbGlhcnlEYXRhLnNldF9tZXRhZGF0YShtZXRhZGF0YSk7XG4gICAgYm9keS5zZXRfYXV4aWxpYXJ5X2RhdGFfaGFzaChDYXJkYW5vV2FzbS5oYXNoX2F1eGlsaWFyeV9kYXRhKGF1eGlsaWFyeURhdGEpKTtcbiAgfVxuXG4gIGNvbnN0IHR4ID1cbiAgICBhdXhpbGlhcnlEYXRhICE9PSB1bmRlZmluZWRcbiAgICAgID8gQ2FyZGFub1dhc20uVHJhbnNhY3Rpb24ubmV3KGJvZHksIHdpdG5lc3NTZXQsIGF1eGlsaWFyeURhdGEpXG4gICAgICA6IENhcmRhbm9XYXNtLlRyYW5zYWN0aW9uLm5ldyhib2R5LCB3aXRuZXNzU2V0KTtcbiAgcmV0dXJuIEJ1ZmZlci5mcm9tKHR4LnRvX2J5dGVzKCkpLnRvU3RyaW5nKCdoZXgnKTtcbn1cblxuZGVzY3JpYmUoJ0FEQSBQbHV0dXMgUGFzc3Rocm91Z2ggQnVpbGRlcicsICgpID0+IHtcbiAgY29uc3QgcGx1dHVzRml4dHVyZUhleCA9IGJ1aWxkUGx1dHVzRml4dHVyZUhleCgpO1xuXG4gIGl0KCdzaG91bGQgZGV0ZWN0IHBsdXR1cyBkYXRhIG9uIHRoZSBwYXJzZWQgdHJhbnNhY3Rpb24nLCAoKSA9PiB7XG4gICAgY29uc3QgdHggPSBuZXcgVHJhbnNhY3Rpb24oY29pbnMuZ2V0KCd0YWRhJykpO1xuICAgIHR4LmZyb21SYXdUcmFuc2FjdGlvbihwbHV0dXNGaXh0dXJlSGV4KTtcbiAgICB0eC5oYXNQbHV0dXNEYXRhKCkuc2hvdWxkLmJlLnRydWUoKTtcblxuICAgIGNvbnN0IHBsYWluVHggPSBuZXcgVHJhbnNhY3Rpb24oY29pbnMuZ2V0KCd0YWRhJykpO1xuICAgIHBsYWluVHguZnJvbVJhd1RyYW5zYWN0aW9uKHJhd1R4LnVuc2lnbmVkTmV3UGxlZGdlVHgpO1xuICAgIHBsYWluVHguaGFzUGx1dHVzRGF0YSgpLnNob3VsZC5iZS5mYWxzZSgpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHJvdW5kLXRyaXAgYSBwbHV0dXMgdHJhbnNhY3Rpb24gYnl0ZS1mb3ItYnl0ZSB3aXRoIG5vIG5ldyBzaWduYXR1cmUnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgZmFjdG9yeSA9IG5ldyBUcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5KGNvaW5zLmdldCgndGFkYScpKTtcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmZyb20ocGx1dHVzRml4dHVyZUhleCk7XG4gICAgY29uc3QgdHggPSAoYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCkpIGFzIFRyYW5zYWN0aW9uO1xuICAgIHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCkuc2hvdWxkLmVxdWFsKHBsdXR1c0ZpeHR1cmVIZXgpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHByZXNlcnZlIHBsdXR1cyBmaWVsZHMgYW5kIHByb2R1Y2UgYSB2YWxpZCB2a2V5IGZvciB0aGUgYm9keSBoYXNoJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGZhY3RvcnkgPSBuZXcgVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeShjb2lucy5nZXQoJ3RhZGEnKSk7XG4gICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5mcm9tKHBsdXR1c0ZpeHR1cmVIZXgpO1xuICAgIHR4QnVpbGRlci5zaWduKHsga2V5OiBwcml2YXRlS2V5cy5wcnZLZXk0IH0pO1xuICAgIGNvbnN0IHR4ID0gKGF3YWl0IHR4QnVpbGRlci5idWlsZCgpKSBhcyBUcmFuc2FjdGlvbjtcbiAgICBjb25zdCBicm9hZGNhc3RIZXggPSB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuICAgIGJyb2FkY2FzdEhleC5zaG91bGQubm90LmVxdWFsKHBsdXR1c0ZpeHR1cmVIZXgpO1xuXG4gICAgY29uc3QgcmVwYXJzZWQgPSBDYXJkYW5vV2FzbS5UcmFuc2FjdGlvbi5mcm9tX2J5dGVzKEJ1ZmZlci5mcm9tKGJyb2FkY2FzdEhleCwgJ2hleCcpKTtcbiAgICBjb25zdCBib2R5ID0gcmVwYXJzZWQuYm9keSgpO1xuICAgIGNvbnN0IHdpdG5lc3NTZXQgPSByZXBhcnNlZC53aXRuZXNzX3NldCgpO1xuXG4gICAgc2hvdWxkLmV4aXN0KGJvZHkuY29sbGF0ZXJhbCgpKTtcbiAgICBzaG91bGQuZXhpc3QoYm9keS5jb2xsYXRlcmFsX3JldHVybigpKTtcbiAgICBzaG91bGQuZXhpc3QoYm9keS50b3RhbF9jb2xsYXRlcmFsKCkpO1xuICAgIHNob3VsZC5leGlzdChib2R5LnJlZmVyZW5jZV9pbnB1dHMoKSk7XG4gICAgc2hvdWxkLmV4aXN0KGJvZHkuc2NyaXB0X2RhdGFfaGFzaCgpKTtcbiAgICBib2R5Lm91dHB1dHMoKS5nZXQoMCkuaGFzX3BsdXR1c19kYXRhKCkuc2hvdWxkLmJlLnRydWUoKTtcblxuICAgIHNob3VsZC5leGlzdCh3aXRuZXNzU2V0LnBsdXR1c19zY3JpcHRzKCkpO1xuICAgIHNob3VsZC5leGlzdCh3aXRuZXNzU2V0LnBsdXR1c19kYXRhKCkpO1xuICAgIHNob3VsZC5leGlzdCh3aXRuZXNzU2V0LnJlZGVlbWVycygpKTtcblxuICAgIGNvbnN0IG9yaWdpbmFsVHggPSBDYXJkYW5vV2FzbS5UcmFuc2FjdGlvbi5mcm9tX2J5dGVzKEJ1ZmZlci5mcm9tKHBsdXR1c0ZpeHR1cmVIZXgsICdoZXgnKSk7XG4gICAgYm9keS5jb2xsYXRlcmFsKCkhLnRvX2J5dGVzKCkuc2hvdWxkLmRlZXBFcXVhbChvcmlnaW5hbFR4LmJvZHkoKS5jb2xsYXRlcmFsKCkhLnRvX2J5dGVzKCkpO1xuICAgIGJvZHkuY29sbGF0ZXJhbF9yZXR1cm4oKSEudG9fYnl0ZXMoKS5zaG91bGQuZGVlcEVxdWFsKG9yaWdpbmFsVHguYm9keSgpLmNvbGxhdGVyYWxfcmV0dXJuKCkhLnRvX2J5dGVzKCkpO1xuICAgIGJvZHkudG90YWxfY29sbGF0ZXJhbCgpIS50b19ieXRlcygpLnNob3VsZC5kZWVwRXF1YWwob3JpZ2luYWxUeC5ib2R5KCkudG90YWxfY29sbGF0ZXJhbCgpIS50b19ieXRlcygpKTtcbiAgICBib2R5LnJlZmVyZW5jZV9pbnB1dHMoKSEudG9fYnl0ZXMoKS5zaG91bGQuZGVlcEVxdWFsKG9yaWdpbmFsVHguYm9keSgpLnJlZmVyZW5jZV9pbnB1dHMoKSEudG9fYnl0ZXMoKSk7XG4gICAgYm9keS5zY3JpcHRfZGF0YV9oYXNoKCkhLnRvX2J5dGVzKCkuc2hvdWxkLmRlZXBFcXVhbChvcmlnaW5hbFR4LmJvZHkoKS5zY3JpcHRfZGF0YV9oYXNoKCkhLnRvX2J5dGVzKCkpO1xuICAgIHdpdG5lc3NTZXQucGx1dHVzX3NjcmlwdHMoKSEudG9fYnl0ZXMoKS5zaG91bGQuZGVlcEVxdWFsKG9yaWdpbmFsVHgud2l0bmVzc19zZXQoKS5wbHV0dXNfc2NyaXB0cygpIS50b19ieXRlcygpKTtcbiAgICB3aXRuZXNzU2V0LnBsdXR1c19kYXRhKCkhLnRvX2J5dGVzKCkuc2hvdWxkLmRlZXBFcXVhbChvcmlnaW5hbFR4LndpdG5lc3Nfc2V0KCkucGx1dHVzX2RhdGEoKSEudG9fYnl0ZXMoKSk7XG4gICAgd2l0bmVzc1NldC5yZWRlZW1lcnMoKSEudG9fYnl0ZXMoKS5zaG91bGQuZGVlcEVxdWFsKG9yaWdpbmFsVHgud2l0bmVzc19zZXQoKS5yZWRlZW1lcnMoKSEudG9fYnl0ZXMoKSk7XG5cbiAgICBjb25zdCBrZXlQYWlyID0gbmV3IEtleVBhaXIoeyBwcnY6IHByaXZhdGVLZXlzLnBydktleTQgfSk7XG4gICAgY29uc3QgZXhwZWN0ZWQgPSBDYXJkYW5vV2FzbS5tYWtlX3ZrZXlfd2l0bmVzcyhcbiAgICAgIENhcmRhbm9XYXNtLmhhc2hfdHJhbnNhY3Rpb24oYm9keSksXG4gICAgICBDYXJkYW5vV2FzbS5Qcml2YXRlS2V5LmZyb21fbm9ybWFsX2J5dGVzKEJ1ZmZlci5mcm9tKGtleVBhaXIuZ2V0S2V5cygpLnBydiEsICdoZXgnKSlcbiAgICApO1xuICAgIGNvbnN0IHZrZXlzID0gd2l0bmVzc1NldC52a2V5cygpO1xuICAgIHNob3VsZC5leGlzdCh2a2V5cyk7XG4gICAgdmtleXMhLmxlbigpLnNob3VsZC5lcXVhbCgxKTtcbiAgICB2a2V5cyEuZ2V0KDApLnZrZXkoKS5wdWJsaWNfa2V5KCkudG9faGV4KCkuc2hvdWxkLmVxdWFsKGtleVBhaXIuZ2V0S2V5cygpLnB1Yik7XG4gICAgdmtleXMhLmdldCgwKS5zaWduYXR1cmUoKS50b19oZXgoKS5zaG91bGQuZXF1YWwoZXhwZWN0ZWQuc2lnbmF0dXJlKCkudG9faGV4KCkpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHByZXNlcnZlIGF1eGlsaWFyeSBkYXRhIHRocm91Z2ggdGhlIHBhc3N0aHJvdWdoIHBhdGgnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgZml4dHVyZVdpdGhBdXggPSBidWlsZFBsdXR1c0ZpeHR1cmVIZXgodHJ1ZSk7XG4gICAgY29uc3QgZmFjdG9yeSA9IG5ldyBUcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5KGNvaW5zLmdldCgndGFkYScpKTtcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmZyb20oZml4dHVyZVdpdGhBdXgpO1xuICAgIHR4QnVpbGRlci5zaWduKHsga2V5OiBwcml2YXRlS2V5cy5wcnZLZXk0IH0pO1xuICAgIGNvbnN0IHR4ID0gKGF3YWl0IHR4QnVpbGRlci5idWlsZCgpKSBhcyBUcmFuc2FjdGlvbjtcblxuICAgIGNvbnN0IHJlcGFyc2VkID0gQ2FyZGFub1dhc20uVHJhbnNhY3Rpb24uZnJvbV9ieXRlcyhCdWZmZXIuZnJvbSh0eC50b0Jyb2FkY2FzdEZvcm1hdCgpLCAnaGV4JykpO1xuICAgIGNvbnN0IG9yaWdpbmFsID0gQ2FyZGFub1dhc20uVHJhbnNhY3Rpb24uZnJvbV9ieXRlcyhCdWZmZXIuZnJvbShmaXh0dXJlV2l0aEF1eCwgJ2hleCcpKTtcbiAgICBzaG91bGQuZXhpc3QocmVwYXJzZWQuYXV4aWxpYXJ5X2RhdGEoKSk7XG4gICAgcmVwYXJzZWQuYXV4aWxpYXJ5X2RhdGEoKSEudG9fYnl0ZXMoKS5zaG91bGQuZGVlcEVxdWFsKG9yaWdpbmFsLmF1eGlsaWFyeV9kYXRhKCkhLnRvX2J5dGVzKCkpO1xuICAgIHNob3VsZC5leGlzdChyZXBhcnNlZC5ib2R5KCkuYXV4aWxpYXJ5X2RhdGFfaGFzaCgpKTtcbiAgICByZXBhcnNlZFxuICAgICAgLmJvZHkoKVxuICAgICAgLmF1eGlsaWFyeV9kYXRhX2hhc2goKSFcbiAgICAgIC50b19ieXRlcygpXG4gICAgICAuc2hvdWxkLmRlZXBFcXVhbChvcmlnaW5hbC5ib2R5KCkuYXV4aWxpYXJ5X2RhdGFfaGFzaCgpIS50b19ieXRlcygpKTtcbiAgfSk7XG59KTtcbiJdfQ==