@bitgo-beta/sdk-coin-canton 1.0.1-beta.62 → 1.0.1-beta.621
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/canton.d.ts +22 -1
- package/dist/src/canton.d.ts.map +1 -1
- package/dist/src/canton.js +267 -10
- package/dist/src/cantonToken.d.ts +19 -0
- package/dist/src/cantonToken.d.ts.map +1 -0
- package/dist/src/cantonToken.js +52 -0
- 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/allocationAllocateBuilder.d.ts +126 -0
- package/dist/src/lib/allocationAllocateBuilder.d.ts.map +1 -0
- package/dist/src/lib/allocationAllocateBuilder.js +250 -0
- package/dist/src/lib/allocationAllocateWithdrawnBuilder.d.ts +67 -0
- package/dist/src/lib/allocationAllocateWithdrawnBuilder.d.ts.map +1 -0
- package/dist/src/lib/allocationAllocateWithdrawnBuilder.js +130 -0
- package/dist/src/lib/allocationRejectBuilder.d.ts +51 -0
- package/dist/src/lib/allocationRejectBuilder.d.ts.map +1 -0
- package/dist/src/lib/allocationRejectBuilder.js +107 -0
- package/dist/src/lib/allocationRequestBuilder.d.ts +116 -0
- package/dist/src/lib/allocationRequestBuilder.d.ts.map +1 -0
- package/dist/src/lib/allocationRequestBuilder.js +248 -0
- package/dist/src/lib/cantonCommandBuilder.d.ts +72 -0
- package/dist/src/lib/cantonCommandBuilder.d.ts.map +1 -0
- package/dist/src/lib/cantonCommandBuilder.js +173 -0
- package/dist/src/lib/clearSigning.d.ts +58 -0
- package/dist/src/lib/clearSigning.d.ts.map +1 -0
- package/dist/src/lib/clearSigning.js +66 -0
- package/dist/src/lib/constant.d.ts +2 -0
- package/dist/src/lib/constant.d.ts.map +1 -1
- package/dist/src/lib/constant.js +4 -2
- package/dist/src/lib/cosignDelegationAcceptBuilder.d.ts +56 -0
- package/dist/src/lib/cosignDelegationAcceptBuilder.d.ts.map +1 -0
- package/dist/src/lib/cosignDelegationAcceptBuilder.js +112 -0
- package/dist/src/lib/cosignDelegationProposalBuilder.d.ts +60 -0
- package/dist/src/lib/cosignDelegationProposalBuilder.d.ts.map +1 -0
- package/dist/src/lib/cosignDelegationProposalBuilder.js +111 -0
- package/dist/src/lib/iface.d.ts +143 -2
- package/dist/src/lib/iface.d.ts.map +1 -1
- package/dist/src/lib/iface.js +3 -1
- package/dist/src/lib/index.d.ts +13 -0
- package/dist/src/lib/index.d.ts.map +1 -1
- package/dist/src/lib/index.js +29 -2
- package/dist/src/lib/messages/cantonBaseMessage.d.ts +16 -0
- package/dist/src/lib/messages/cantonBaseMessage.d.ts.map +1 -0
- package/dist/src/lib/messages/cantonBaseMessage.js +28 -0
- package/dist/src/lib/messages/cantonSignTopology/cantonSignTopologyMessage.d.ts +14 -0
- package/dist/src/lib/messages/cantonSignTopology/cantonSignTopologyMessage.d.ts.map +1 -0
- package/dist/src/lib/messages/cantonSignTopology/cantonSignTopologyMessage.js +23 -0
- package/dist/src/lib/messages/cantonSignTopology/cantonSignTopologyMessageBuilder.d.ts +17 -0
- package/dist/src/lib/messages/cantonSignTopology/cantonSignTopologyMessageBuilder.d.ts.map +1 -0
- package/dist/src/lib/messages/cantonSignTopology/cantonSignTopologyMessageBuilder.js +25 -0
- package/dist/src/lib/messages/cantonSignTopology/index.d.ts +3 -0
- package/dist/src/lib/messages/cantonSignTopology/index.d.ts.map +1 -0
- package/dist/src/lib/messages/cantonSignTopology/index.js +19 -0
- package/dist/src/lib/messages/cantonSignTransaction/cantonSignTransactionMessage.d.ts +13 -0
- package/dist/src/lib/messages/cantonSignTransaction/cantonSignTransactionMessage.d.ts.map +1 -0
- package/dist/src/lib/messages/cantonSignTransaction/cantonSignTransactionMessage.js +22 -0
- package/dist/src/lib/messages/cantonSignTransaction/cantonSignTransactionMessageBuilder.d.ts +14 -0
- package/dist/src/lib/messages/cantonSignTransaction/cantonSignTransactionMessageBuilder.d.ts.map +1 -0
- package/dist/src/lib/messages/cantonSignTransaction/cantonSignTransactionMessageBuilder.js +22 -0
- package/dist/src/lib/messages/cantonSignTransaction/index.d.ts +3 -0
- package/dist/src/lib/messages/cantonSignTransaction/index.d.ts.map +1 -0
- package/dist/src/lib/messages/cantonSignTransaction/index.js +19 -0
- package/dist/src/lib/messages/index.d.ts +5 -0
- package/dist/src/lib/messages/index.d.ts.map +1 -0
- package/dist/src/lib/messages/index.js +21 -0
- package/dist/src/lib/messages/messageBuilderFactory.d.ts +7 -0
- package/dist/src/lib/messages/messageBuilderFactory.d.ts.map +1 -0
- package/dist/src/lib/messages/messageBuilderFactory.js +23 -0
- package/dist/src/lib/oneStepPreApprovalBuilder.d.ts +11 -1
- package/dist/src/lib/oneStepPreApprovalBuilder.d.ts.map +1 -1
- package/dist/src/lib/oneStepPreApprovalBuilder.js +29 -1
- package/dist/src/lib/resourcesInterface.d.ts +1 -1
- package/dist/src/lib/resourcesInterface.d.ts.map +1 -1
- package/dist/src/lib/resourcesInterface.js +1 -1
- package/dist/src/lib/transaction/transaction.d.ts +21 -2
- package/dist/src/lib/transaction/transaction.d.ts.map +1 -1
- package/dist/src/lib/transaction/transaction.js +330 -9
- package/dist/src/lib/transactionBuilder.d.ts +3 -3
- package/dist/src/lib/transactionBuilder.d.ts.map +1 -1
- package/dist/src/lib/transactionBuilder.js +1 -5
- package/dist/src/lib/transactionBuilderFactory.d.ts +22 -1
- package/dist/src/lib/transactionBuilderFactory.d.ts.map +1 -1
- package/dist/src/lib/transactionBuilderFactory.js +78 -2
- package/dist/src/lib/transferAcceptanceBuilder.d.ts +7 -5
- package/dist/src/lib/transferAcceptanceBuilder.d.ts.map +1 -1
- package/dist/src/lib/transferAcceptanceBuilder.js +20 -6
- package/dist/src/lib/transferAcknowledgeBuilder.d.ts +72 -0
- package/dist/src/lib/transferAcknowledgeBuilder.d.ts.map +1 -0
- package/dist/src/lib/transferAcknowledgeBuilder.js +133 -0
- package/dist/src/lib/transferBuilder.d.ts +87 -3
- package/dist/src/lib/transferBuilder.d.ts.map +1 -1
- package/dist/src/lib/transferBuilder.js +169 -1
- package/dist/src/lib/transferOfferWithdrawnBuilder.d.ts +67 -0
- package/dist/src/lib/transferOfferWithdrawnBuilder.d.ts.map +1 -0
- package/dist/src/lib/transferOfferWithdrawnBuilder.js +130 -0
- package/dist/src/lib/transferRejectionBuilder.d.ts +59 -0
- package/dist/src/lib/transferRejectionBuilder.d.ts.map +1 -0
- package/dist/src/lib/transferRejectionBuilder.js +116 -0
- package/dist/src/lib/utils.d.ts +51 -3
- package/dist/src/lib/utils.d.ts.map +1 -1
- package/dist/src/lib/utils.js +751 -44
- package/dist/src/lib/walletInitBuilder.d.ts +2 -1
- package/dist/src/lib/walletInitBuilder.d.ts.map +1 -1
- package/dist/src/lib/walletInitBuilder.js +4 -1
- package/dist/src/lib/walletInitialization/walletInitTransaction.d.ts +2 -1
- package/dist/src/lib/walletInitialization/walletInitTransaction.d.ts.map +1 -1
- package/dist/src/lib/walletInitialization/walletInitTransaction.js +14 -1
- package/dist/src/register.d.ts.map +1 -1
- package/dist/src/register.js +5 -1
- package/dist/test/helper.d.ts +3 -0
- package/dist/test/helper.d.ts.map +1 -0
- package/dist/test/helper.js +9 -0
- package/dist/test/integration/canton.integration.d.ts +2 -0
- package/dist/test/integration/canton.integration.d.ts.map +1 -0
- package/dist/test/integration/canton.integration.js +157 -0
- package/dist/test/integration/canton.token.integration.d.ts +2 -0
- package/dist/test/integration/canton.token.integration.d.ts.map +1 -0
- package/dist/test/integration/canton.token.integration.js +51 -0
- package/dist/test/resources.d.ts +233 -2
- package/dist/test/resources.d.ts.map +1 -1
- package/dist/test/resources.js +238 -7
- package/dist/test/unit/builder/allocationAllocate/allocationAllocateBuilder.d.ts +2 -0
- package/dist/test/unit/builder/allocationAllocate/allocationAllocateBuilder.d.ts.map +1 -0
- package/dist/test/unit/builder/allocationAllocate/allocationAllocateBuilder.js +360 -0
- package/dist/test/unit/builder/allocationAllocateWithdrawn/allocationAllocateWithdrawnBuilder.d.ts +2 -0
- package/dist/test/unit/builder/allocationAllocateWithdrawn/allocationAllocateWithdrawnBuilder.d.ts.map +1 -0
- package/dist/test/unit/builder/allocationAllocateWithdrawn/allocationAllocateWithdrawnBuilder.js +133 -0
- package/dist/test/unit/builder/allocationReject/allocationRejectBuilder.d.ts +2 -0
- package/dist/test/unit/builder/allocationReject/allocationRejectBuilder.d.ts.map +1 -0
- package/dist/test/unit/builder/allocationReject/allocationRejectBuilder.js +121 -0
- package/dist/test/unit/builder/allocationRequest/allocationRequestBuilder.d.ts +2 -0
- package/dist/test/unit/builder/allocationRequest/allocationRequestBuilder.d.ts.map +1 -0
- package/dist/test/unit/builder/allocationRequest/allocationRequestBuilder.js +407 -0
- package/dist/test/unit/builder/cantonCommand/cantonCommandBuilder.d.ts +2 -0
- package/dist/test/unit/builder/cantonCommand/cantonCommandBuilder.d.ts.map +1 -0
- package/dist/test/unit/builder/cantonCommand/cantonCommandBuilder.js +340 -0
- package/dist/test/unit/builder/cosignDelegationAccept/cosignDelegationAcceptBuilder.d.ts +2 -0
- package/dist/test/unit/builder/cosignDelegationAccept/cosignDelegationAcceptBuilder.d.ts.map +1 -0
- package/dist/test/unit/builder/cosignDelegationAccept/cosignDelegationAcceptBuilder.js +104 -0
- package/dist/test/unit/builder/cosignDelegationProposal/cosignDelegationProposalBuilder.d.ts +2 -0
- package/dist/test/unit/builder/cosignDelegationProposal/cosignDelegationProposalBuilder.d.ts.map +1 -0
- package/dist/test/unit/builder/cosignDelegationProposal/cosignDelegationProposalBuilder.js +74 -0
- package/dist/test/unit/builder/oneStepEnablement/oneStepEnablementBuilder.js +25 -7
- package/dist/test/unit/builder/transfer/transferBuilder.d.ts +2 -0
- package/dist/test/unit/builder/transfer/transferBuilder.d.ts.map +1 -0
- package/dist/test/unit/builder/transfer/transferBuilder.js +84 -0
- package/dist/test/unit/builder/transferAccept/transferAcceptBuilder.js +65 -15
- package/dist/test/unit/builder/transferAcknowledge/transferAcknowledgeBuilder.d.ts +2 -0
- package/dist/test/unit/builder/transferAcknowledge/transferAcknowledgeBuilder.d.ts.map +1 -0
- package/dist/test/unit/builder/transferAcknowledge/transferAcknowledgeBuilder.js +32 -0
- package/dist/test/unit/builder/transferOfferWithdrawn/transferOfferWithdrawnBuilder.d.ts +2 -0
- package/dist/test/unit/builder/transferOfferWithdrawn/transferOfferWithdrawnBuilder.d.ts.map +1 -0
- package/dist/test/unit/builder/transferOfferWithdrawn/transferOfferWithdrawnBuilder.js +64 -0
- package/dist/test/unit/builder/transferReject/transferRejectBuilder.d.ts +2 -0
- package/dist/test/unit/builder/transferReject/transferRejectBuilder.d.ts.map +1 -0
- package/dist/test/unit/builder/transferReject/transferRejectBuilder.js +96 -0
- package/dist/test/unit/canton.d.ts +2 -0
- package/dist/test/unit/canton.d.ts.map +1 -0
- package/dist/test/unit/canton.js +705 -0
- package/dist/test/unit/index.d.ts +5 -0
- package/dist/test/unit/index.d.ts.map +1 -1
- package/dist/test/unit/index.js +6 -1
- package/dist/test/unit/messages/cantonSignTopologyMessage.d.ts +2 -0
- package/dist/test/unit/messages/cantonSignTopologyMessage.d.ts.map +1 -0
- package/dist/test/unit/messages/cantonSignTopologyMessage.js +46 -0
- package/dist/test/unit/messages/cantonSignTransactionMessage.d.ts +2 -0
- package/dist/test/unit/messages/cantonSignTransactionMessage.d.ts.map +1 -0
- package/dist/test/unit/messages/cantonSignTransactionMessage.js +48 -0
- package/dist/test/unit/messages/clearSigning.d.ts +2 -0
- package/dist/test/unit/messages/clearSigning.d.ts.map +1 -0
- package/dist/test/unit/messages/clearSigning.js +72 -0
- package/dist/test/unit/messages/messageBuilderFactory.d.ts +2 -0
- package/dist/test/unit/messages/messageBuilderFactory.d.ts.map +1 -0
- package/dist/test/unit/messages/messageBuilderFactory.js +52 -0
- package/dist/test/unit/utils.js +376 -5
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +8 -8
|
@@ -0,0 +1,705 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
require("should");
|
|
4
|
+
const sdk_api_1 = require("@bitgo-beta/sdk-api");
|
|
5
|
+
const sdk_test_1 = require("@bitgo-beta/sdk-test");
|
|
6
|
+
const statics_1 = require("@bitgo-beta/statics");
|
|
7
|
+
const src_1 = require("../../src");
|
|
8
|
+
const resources_1 = require("../resources");
|
|
9
|
+
/**
|
|
10
|
+
* Builds a base64-encoded raw transaction for a OneStepPreApproval (enable token flow).
|
|
11
|
+
* For TSS wallets (which Canton always is), verifyTransaction receives txParams.enableTokens,
|
|
12
|
+
* not txParams.recipients. The wallet SDK's buildTokenEnablements passes enableTokens through
|
|
13
|
+
* unchanged for TSS wallets rather than converting them to recipients.
|
|
14
|
+
*/
|
|
15
|
+
function buildOneStepPreApprovalRawTx(prepareResponse, commandId) {
|
|
16
|
+
const data = {
|
|
17
|
+
prepareCommandResponse: prepareResponse,
|
|
18
|
+
txType: 'OneStepPreApproval',
|
|
19
|
+
preparedTransaction: '',
|
|
20
|
+
partySignatures: { signatures: [] },
|
|
21
|
+
deduplicationPeriod: { Empty: {} },
|
|
22
|
+
submissionId: commandId,
|
|
23
|
+
hashingSchemeVersion: 'HASHING_SCHEME_VERSION_V2',
|
|
24
|
+
minLedgerTime: { time: { Empty: {} } },
|
|
25
|
+
};
|
|
26
|
+
return Buffer.from(JSON.stringify(data)).toString('base64');
|
|
27
|
+
}
|
|
28
|
+
/** Returns a mock wallet whose coinSpecific().rootAddress matches the given party ID. */
|
|
29
|
+
function walletWithRootAddress(rootAddress) {
|
|
30
|
+
return { coinSpecific: () => ({ rootAddress }) };
|
|
31
|
+
}
|
|
32
|
+
describe('Canton coin:', function () {
|
|
33
|
+
let bitgo;
|
|
34
|
+
let basecoin;
|
|
35
|
+
before(function () {
|
|
36
|
+
bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'mock' });
|
|
37
|
+
bitgo.safeRegister('canton', src_1.Canton.createInstance);
|
|
38
|
+
bitgo.safeRegister('tcanton', src_1.Tcanton.createInstance);
|
|
39
|
+
bitgo.initializeTestVars();
|
|
40
|
+
basecoin = bitgo.coin('tcanton');
|
|
41
|
+
});
|
|
42
|
+
describe('supportsMessageSigning', function () {
|
|
43
|
+
it('should return true', function () {
|
|
44
|
+
basecoin.supportsMessageSigning().should.equal(true);
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
describe('Canton verifyTransaction:', function () {
|
|
49
|
+
let bitgo;
|
|
50
|
+
let basecoin;
|
|
51
|
+
before(function () {
|
|
52
|
+
bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'mock' });
|
|
53
|
+
bitgo.safeRegister('canton', src_1.Canton.createInstance);
|
|
54
|
+
bitgo.safeRegister('tcanton', src_1.Tcanton.createInstance);
|
|
55
|
+
bitgo.initializeTestVars();
|
|
56
|
+
basecoin = bitgo.coin('tcanton');
|
|
57
|
+
});
|
|
58
|
+
describe('OneStepPreApproval (enable token flow):', function () {
|
|
59
|
+
it('should return true when txParams has no type (non-enabletoken flow)', async function () {
|
|
60
|
+
const txHex = buildOneStepPreApprovalRawTx(resources_1.OneStepPreApprovalPrepareResponse, resources_1.OneStepEnablement.commandId);
|
|
61
|
+
const result = await basecoin.verifyTransaction({
|
|
62
|
+
txPrebuild: { txHex },
|
|
63
|
+
txParams: {},
|
|
64
|
+
wallet: {},
|
|
65
|
+
});
|
|
66
|
+
result.should.equal(true);
|
|
67
|
+
});
|
|
68
|
+
it('should return true when enableTokens is absent', async function () {
|
|
69
|
+
const txHex = buildOneStepPreApprovalRawTx(resources_1.OneStepPreApprovalPrepareResponse, resources_1.OneStepEnablement.commandId);
|
|
70
|
+
const result = await basecoin.verifyTransaction({
|
|
71
|
+
txPrebuild: { txHex },
|
|
72
|
+
txParams: { type: 'enabletoken' },
|
|
73
|
+
wallet: {},
|
|
74
|
+
});
|
|
75
|
+
result.should.equal(true);
|
|
76
|
+
});
|
|
77
|
+
it('should return true when enableTokens is empty', async function () {
|
|
78
|
+
const txHex = buildOneStepPreApprovalRawTx(resources_1.OneStepPreApprovalPrepareResponse, resources_1.OneStepEnablement.commandId);
|
|
79
|
+
const result = await basecoin.verifyTransaction({
|
|
80
|
+
txPrebuild: { txHex },
|
|
81
|
+
txParams: { type: 'enabletoken', enableTokens: [] },
|
|
82
|
+
wallet: {},
|
|
83
|
+
});
|
|
84
|
+
result.should.equal(true);
|
|
85
|
+
});
|
|
86
|
+
describe('coin pre-approval (TransferPreapprovalProposal):', function () {
|
|
87
|
+
let txHex;
|
|
88
|
+
let receiver;
|
|
89
|
+
before(function () {
|
|
90
|
+
txHex = buildOneStepPreApprovalRawTx(resources_1.OneStepPreApprovalPrepareResponse, resources_1.OneStepEnablement.commandId);
|
|
91
|
+
// Dynamically derive receiver from parsed transaction to avoid hardcoding protobuf-decoded addresses
|
|
92
|
+
const txBuilder = new src_1.TransactionBuilderFactory(statics_1.coins.get('tcanton')).from(txHex);
|
|
93
|
+
receiver = txBuilder.transaction.toJson().receiver;
|
|
94
|
+
});
|
|
95
|
+
it('should return true when wallet has no coinSpecific (receiver check skipped)', async function () {
|
|
96
|
+
// Typical case: wallet mock has no coinSpecific() method, and no address in enableTokens
|
|
97
|
+
const result = await basecoin.verifyTransaction({
|
|
98
|
+
txPrebuild: { txHex },
|
|
99
|
+
txParams: {
|
|
100
|
+
type: 'enabletoken',
|
|
101
|
+
enableTokens: [{ name: 'canton' }],
|
|
102
|
+
},
|
|
103
|
+
wallet: {},
|
|
104
|
+
});
|
|
105
|
+
result.should.equal(true);
|
|
106
|
+
});
|
|
107
|
+
it('should return true when wallet rootAddress matches receiver', async function () {
|
|
108
|
+
// Typical UI flow: enableTokens has no address, receiver validated from wallet.coinSpecific().rootAddress
|
|
109
|
+
const result = await basecoin.verifyTransaction({
|
|
110
|
+
txPrebuild: { txHex },
|
|
111
|
+
txParams: {
|
|
112
|
+
type: 'enabletoken',
|
|
113
|
+
enableTokens: [{ name: 'canton' }],
|
|
114
|
+
},
|
|
115
|
+
wallet: walletWithRootAddress(receiver),
|
|
116
|
+
});
|
|
117
|
+
result.should.equal(true);
|
|
118
|
+
});
|
|
119
|
+
it('should return true when enableToken.address matches receiver (explicit address)', async function () {
|
|
120
|
+
const result = await basecoin.verifyTransaction({
|
|
121
|
+
txPrebuild: { txHex },
|
|
122
|
+
txParams: {
|
|
123
|
+
type: 'enabletoken',
|
|
124
|
+
enableTokens: [{ name: 'canton', address: receiver }],
|
|
125
|
+
},
|
|
126
|
+
wallet: {},
|
|
127
|
+
});
|
|
128
|
+
result.should.equal(true);
|
|
129
|
+
});
|
|
130
|
+
it('should throw when wallet rootAddress does not match receiver', async function () {
|
|
131
|
+
const wrongAddress = 'wrong-party::1220aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
|
|
132
|
+
await basecoin
|
|
133
|
+
.verifyTransaction({
|
|
134
|
+
txPrebuild: { txHex },
|
|
135
|
+
txParams: {
|
|
136
|
+
type: 'enabletoken',
|
|
137
|
+
enableTokens: [{ name: 'canton' }],
|
|
138
|
+
},
|
|
139
|
+
wallet: walletWithRootAddress(wrongAddress),
|
|
140
|
+
})
|
|
141
|
+
.should.be.rejectedWith(/OneStepPreApproval receiver mismatch/);
|
|
142
|
+
});
|
|
143
|
+
it('should throw when explicit enableToken.address does not match receiver', async function () {
|
|
144
|
+
const wrongAddress = 'wrong-party::1220aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
|
|
145
|
+
await basecoin
|
|
146
|
+
.verifyTransaction({
|
|
147
|
+
txPrebuild: { txHex },
|
|
148
|
+
txParams: {
|
|
149
|
+
type: 'enabletoken',
|
|
150
|
+
enableTokens: [{ name: 'canton', address: wrongAddress }],
|
|
151
|
+
},
|
|
152
|
+
wallet: {},
|
|
153
|
+
})
|
|
154
|
+
.should.be.rejectedWith(/OneStepPreApproval receiver mismatch/);
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
describe('token pre-approval (TransferPreapproval):', function () {
|
|
158
|
+
let txHex;
|
|
159
|
+
let receiver;
|
|
160
|
+
before(function () {
|
|
161
|
+
const commandId = '7d99789d-2f22-49e1-85cb-79d2ce5a69c1';
|
|
162
|
+
txHex = buildOneStepPreApprovalRawTx(resources_1.CantonTokenPreApprovalPrepareResponse, commandId);
|
|
163
|
+
const txBuilder = new src_1.TransactionBuilderFactory(statics_1.coins.get('tcanton')).from(txHex);
|
|
164
|
+
receiver = txBuilder.transaction.toJson().receiver;
|
|
165
|
+
});
|
|
166
|
+
it('should return true when wallet rootAddress matches receiver', async function () {
|
|
167
|
+
const result = await basecoin.verifyTransaction({
|
|
168
|
+
txPrebuild: { txHex },
|
|
169
|
+
txParams: {
|
|
170
|
+
type: 'enabletoken',
|
|
171
|
+
enableTokens: [{ name: 'tcanton:testcoin1' }],
|
|
172
|
+
},
|
|
173
|
+
wallet: walletWithRootAddress(receiver),
|
|
174
|
+
});
|
|
175
|
+
result.should.equal(true);
|
|
176
|
+
});
|
|
177
|
+
it('should return true when enableToken.address matches receiver (explicit address)', async function () {
|
|
178
|
+
const result = await basecoin.verifyTransaction({
|
|
179
|
+
txPrebuild: { txHex },
|
|
180
|
+
txParams: {
|
|
181
|
+
type: 'enabletoken',
|
|
182
|
+
enableTokens: [{ name: 'tcanton:testcoin1', address: receiver }],
|
|
183
|
+
},
|
|
184
|
+
wallet: {},
|
|
185
|
+
});
|
|
186
|
+
result.should.equal(true);
|
|
187
|
+
});
|
|
188
|
+
it('should throw when wallet rootAddress does not match receiver', async function () {
|
|
189
|
+
const wrongAddress = 'wrong-party::1220bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb';
|
|
190
|
+
await basecoin
|
|
191
|
+
.verifyTransaction({
|
|
192
|
+
txPrebuild: { txHex },
|
|
193
|
+
txParams: {
|
|
194
|
+
type: 'enabletoken',
|
|
195
|
+
enableTokens: [{ name: 'tcanton:testcoin1' }],
|
|
196
|
+
},
|
|
197
|
+
wallet: walletWithRootAddress(wrongAddress),
|
|
198
|
+
})
|
|
199
|
+
.should.be.rejectedWith(/OneStepPreApproval receiver mismatch/);
|
|
200
|
+
});
|
|
201
|
+
it('should throw when explicit enableToken.address does not match receiver', async function () {
|
|
202
|
+
const wrongAddress = 'wrong-party::1220bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb';
|
|
203
|
+
await basecoin
|
|
204
|
+
.verifyTransaction({
|
|
205
|
+
txPrebuild: { txHex },
|
|
206
|
+
txParams: {
|
|
207
|
+
type: 'enabletoken',
|
|
208
|
+
enableTokens: [{ name: 'tcanton:testcoin1', address: wrongAddress }],
|
|
209
|
+
},
|
|
210
|
+
wallet: {},
|
|
211
|
+
})
|
|
212
|
+
.should.be.rejectedWith(/OneStepPreApproval receiver mismatch/);
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
// --------------- ExerciseCommand verification tests ---------------
|
|
218
|
+
const CANTON_CMD_ACT_AS = 'RegRegistrar::1220508e54fb709dcb1a9b4096408ad415d2217d8881ad9034a9850752933ba88ad5';
|
|
219
|
+
const CANTON_CMD_TEMPLATE_ID = '7a75ef6e69f69395a4e60919e228528bb8f3881150ccfde3f31bcc73864b18ab:Utility.Registry.App.V0.Service.AllocationFactory:AllocationFactory';
|
|
220
|
+
const CANTON_CMD_CONTRACT_ID = '00f3afdce846a40c6f3f618c4b584b022a0197010057ecd59458200183ab27de0aca1212204aef7ede37a5f41b674a1d95446d42a404461c5558c4e6d1860b65560120ef18';
|
|
221
|
+
const CANTON_CMD_CHOICE = 'AllocationFactory_OfferMint';
|
|
222
|
+
function buildCantonCommandRawTx(prepareResponse, commandId) {
|
|
223
|
+
const data = {
|
|
224
|
+
prepareCommandResponse: prepareResponse,
|
|
225
|
+
txType: 'CantonCommand',
|
|
226
|
+
preparedTransaction: '',
|
|
227
|
+
partySignatures: { signatures: [] },
|
|
228
|
+
deduplicationPeriod: { Empty: {} },
|
|
229
|
+
submissionId: commandId,
|
|
230
|
+
hashingSchemeVersion: 'HASHING_SCHEME_VERSION_V2',
|
|
231
|
+
minLedgerTime: { time: { Empty: {} } },
|
|
232
|
+
};
|
|
233
|
+
return Buffer.from(JSON.stringify(data)).toString('base64');
|
|
234
|
+
}
|
|
235
|
+
describe('Canton verifyTransaction - CantonCommand:', function () {
|
|
236
|
+
let bitgo;
|
|
237
|
+
let basecoin;
|
|
238
|
+
before(function () {
|
|
239
|
+
bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'mock' });
|
|
240
|
+
bitgo.safeRegister('canton', src_1.Canton.createInstance);
|
|
241
|
+
bitgo.safeRegister('tcanton', src_1.Tcanton.createInstance);
|
|
242
|
+
bitgo.initializeTestVars();
|
|
243
|
+
basecoin = bitgo.coin('tcanton');
|
|
244
|
+
});
|
|
245
|
+
describe('Happy path tests:', function () {
|
|
246
|
+
let txHex;
|
|
247
|
+
before(function () {
|
|
248
|
+
txHex = buildCantonCommandRawTx(resources_1.CantonExerciseCommandPrepareResponse, 'test-canton-cmd-001');
|
|
249
|
+
});
|
|
250
|
+
it('should return true when cantonCommandParams is undefined (no user params to verify)', async function () {
|
|
251
|
+
const result = await basecoin.verifyTransaction({
|
|
252
|
+
txPrebuild: { txHex },
|
|
253
|
+
txParams: {},
|
|
254
|
+
wallet: {},
|
|
255
|
+
});
|
|
256
|
+
result.should.equal(true);
|
|
257
|
+
});
|
|
258
|
+
it('should return true for matching ExerciseCommand (templateId, choice, contractId, actAs, argument)', async function () {
|
|
259
|
+
const result = await basecoin.verifyTransaction({
|
|
260
|
+
txPrebuild: { txHex },
|
|
261
|
+
txParams: {
|
|
262
|
+
cantonCommandParams: {
|
|
263
|
+
command: {
|
|
264
|
+
ExerciseCommand: {
|
|
265
|
+
templateId: CANTON_CMD_TEMPLATE_ID,
|
|
266
|
+
contractId: CANTON_CMD_CONTRACT_ID,
|
|
267
|
+
choice: CANTON_CMD_CHOICE,
|
|
268
|
+
choiceArgument: {
|
|
269
|
+
expectedAdmin: CANTON_CMD_ACT_AS,
|
|
270
|
+
mint: {
|
|
271
|
+
instrumentId: {
|
|
272
|
+
admin: CANTON_CMD_ACT_AS,
|
|
273
|
+
id: 'TESTTOKEN',
|
|
274
|
+
},
|
|
275
|
+
amount: '100',
|
|
276
|
+
holder: 'RegIssuer::1220508e54fb709dcb1a9b4096408ad415d2217d8881ad9034a9850752933ba88ad5',
|
|
277
|
+
reference: 'test-prepare-mint',
|
|
278
|
+
},
|
|
279
|
+
},
|
|
280
|
+
},
|
|
281
|
+
},
|
|
282
|
+
actAs: [CANTON_CMD_ACT_AS],
|
|
283
|
+
readAs: [],
|
|
284
|
+
},
|
|
285
|
+
},
|
|
286
|
+
wallet: {},
|
|
287
|
+
});
|
|
288
|
+
result.should.equal(true);
|
|
289
|
+
});
|
|
290
|
+
it('should return true when contractId is omitted (IMS-resolved)', async function () {
|
|
291
|
+
const result = await basecoin.verifyTransaction({
|
|
292
|
+
txPrebuild: { txHex },
|
|
293
|
+
txParams: {
|
|
294
|
+
cantonCommandParams: {
|
|
295
|
+
command: {
|
|
296
|
+
ExerciseCommand: {
|
|
297
|
+
templateId: CANTON_CMD_TEMPLATE_ID,
|
|
298
|
+
choice: CANTON_CMD_CHOICE,
|
|
299
|
+
choiceArgument: {},
|
|
300
|
+
},
|
|
301
|
+
},
|
|
302
|
+
actAs: [CANTON_CMD_ACT_AS],
|
|
303
|
+
readAs: [],
|
|
304
|
+
},
|
|
305
|
+
},
|
|
306
|
+
wallet: {},
|
|
307
|
+
});
|
|
308
|
+
result.should.equal(true);
|
|
309
|
+
});
|
|
310
|
+
it('should return true with resolveContracts injectAs skipping contractId (empty contractId)', async function () {
|
|
311
|
+
const result = await basecoin.verifyTransaction({
|
|
312
|
+
txPrebuild: { txHex },
|
|
313
|
+
txParams: {
|
|
314
|
+
cantonCommandParams: {
|
|
315
|
+
command: {
|
|
316
|
+
ExerciseCommand: {
|
|
317
|
+
templateId: CANTON_CMD_TEMPLATE_ID,
|
|
318
|
+
contractId: '',
|
|
319
|
+
choice: CANTON_CMD_CHOICE,
|
|
320
|
+
choiceArgument: {},
|
|
321
|
+
},
|
|
322
|
+
},
|
|
323
|
+
actAs: [CANTON_CMD_ACT_AS],
|
|
324
|
+
readAs: [],
|
|
325
|
+
resolveContracts: [
|
|
326
|
+
{
|
|
327
|
+
templateId: CANTON_CMD_TEMPLATE_ID,
|
|
328
|
+
actAs: [CANTON_CMD_ACT_AS],
|
|
329
|
+
injectAs: 'command.ExerciseCommand.contractId',
|
|
330
|
+
},
|
|
331
|
+
],
|
|
332
|
+
},
|
|
333
|
+
},
|
|
334
|
+
wallet: {},
|
|
335
|
+
});
|
|
336
|
+
result.should.equal(true);
|
|
337
|
+
});
|
|
338
|
+
it('should return true with resolveContracts injectAs skipping non-empty contractId mismatch', async function () {
|
|
339
|
+
// User supplies a placeholder contractId that doesn't match what's on-chain;
|
|
340
|
+
// resolveContracts marks it as IMS-injected, so the mismatch must be ignored.
|
|
341
|
+
const result = await basecoin.verifyTransaction({
|
|
342
|
+
txPrebuild: { txHex },
|
|
343
|
+
txParams: {
|
|
344
|
+
cantonCommandParams: {
|
|
345
|
+
command: {
|
|
346
|
+
ExerciseCommand: {
|
|
347
|
+
templateId: CANTON_CMD_TEMPLATE_ID,
|
|
348
|
+
contractId: '00placeholder_contract_id_not_on_chain',
|
|
349
|
+
choice: CANTON_CMD_CHOICE,
|
|
350
|
+
choiceArgument: {},
|
|
351
|
+
},
|
|
352
|
+
},
|
|
353
|
+
actAs: [CANTON_CMD_ACT_AS],
|
|
354
|
+
readAs: [],
|
|
355
|
+
resolveContracts: [
|
|
356
|
+
{
|
|
357
|
+
templateId: CANTON_CMD_TEMPLATE_ID,
|
|
358
|
+
actAs: [CANTON_CMD_ACT_AS],
|
|
359
|
+
injectAs: 'command.ExerciseCommand.contractId',
|
|
360
|
+
},
|
|
361
|
+
],
|
|
362
|
+
},
|
|
363
|
+
},
|
|
364
|
+
wallet: {},
|
|
365
|
+
});
|
|
366
|
+
result.should.equal(true);
|
|
367
|
+
});
|
|
368
|
+
});
|
|
369
|
+
describe('Error cases:', function () {
|
|
370
|
+
let txHex;
|
|
371
|
+
before(function () {
|
|
372
|
+
txHex = buildCantonCommandRawTx(resources_1.CantonExerciseCommandPrepareResponse, 'test-canton-cmd-002');
|
|
373
|
+
});
|
|
374
|
+
it('should throw when preparedTransaction is missing on tx prebuild', async function () {
|
|
375
|
+
const emptyPrepare = { ...resources_1.CantonExerciseCommandPrepareResponse, preparedTransaction: undefined };
|
|
376
|
+
const badTx = buildCantonCommandRawTx(emptyPrepare, 'cmd-bad');
|
|
377
|
+
await basecoin
|
|
378
|
+
.verifyTransaction({
|
|
379
|
+
txPrebuild: { txHex: badTx },
|
|
380
|
+
txParams: {
|
|
381
|
+
cantonCommandParams: {
|
|
382
|
+
command: {
|
|
383
|
+
ExerciseCommand: { templateId: CANTON_CMD_TEMPLATE_ID, choice: CANTON_CMD_CHOICE, choiceArgument: {} },
|
|
384
|
+
},
|
|
385
|
+
actAs: [CANTON_CMD_ACT_AS],
|
|
386
|
+
},
|
|
387
|
+
},
|
|
388
|
+
wallet: {},
|
|
389
|
+
})
|
|
390
|
+
.should.be.rejectedWith(/missing preparedTransaction/);
|
|
391
|
+
});
|
|
392
|
+
it('should throw when user command has neither CreateCommand nor ExerciseCommand', async function () {
|
|
393
|
+
await basecoin
|
|
394
|
+
.verifyTransaction({
|
|
395
|
+
txPrebuild: { txHex },
|
|
396
|
+
txParams: {
|
|
397
|
+
cantonCommandParams: {
|
|
398
|
+
command: { UnknownCommand: {} },
|
|
399
|
+
actAs: [CANTON_CMD_ACT_AS],
|
|
400
|
+
},
|
|
401
|
+
},
|
|
402
|
+
wallet: {},
|
|
403
|
+
})
|
|
404
|
+
.should.be.rejectedWith(/must contain a CreateCommand or ExerciseCommand/);
|
|
405
|
+
});
|
|
406
|
+
it('should throw when user command contains both CreateCommand and ExerciseCommand', async function () {
|
|
407
|
+
await basecoin
|
|
408
|
+
.verifyTransaction({
|
|
409
|
+
txPrebuild: { txHex },
|
|
410
|
+
txParams: {
|
|
411
|
+
cantonCommandParams: {
|
|
412
|
+
command: {
|
|
413
|
+
CreateCommand: { templateId: CANTON_CMD_TEMPLATE_ID, createArguments: {} },
|
|
414
|
+
ExerciseCommand: { templateId: CANTON_CMD_TEMPLATE_ID, choice: CANTON_CMD_CHOICE, choiceArgument: {} },
|
|
415
|
+
},
|
|
416
|
+
actAs: [CANTON_CMD_ACT_AS],
|
|
417
|
+
},
|
|
418
|
+
},
|
|
419
|
+
wallet: {},
|
|
420
|
+
})
|
|
421
|
+
.should.be.rejectedWith(/exactly one of CreateCommand or ExerciseCommand/);
|
|
422
|
+
});
|
|
423
|
+
it('should throw on invalid user templateId format', async function () {
|
|
424
|
+
await basecoin
|
|
425
|
+
.verifyTransaction({
|
|
426
|
+
txPrebuild: { txHex },
|
|
427
|
+
txParams: {
|
|
428
|
+
cantonCommandParams: {
|
|
429
|
+
command: {
|
|
430
|
+
ExerciseCommand: {
|
|
431
|
+
templateId: 'InvalidFormat',
|
|
432
|
+
choice: CANTON_CMD_CHOICE,
|
|
433
|
+
choiceArgument: {},
|
|
434
|
+
},
|
|
435
|
+
},
|
|
436
|
+
actAs: [CANTON_CMD_ACT_AS],
|
|
437
|
+
},
|
|
438
|
+
},
|
|
439
|
+
wallet: {},
|
|
440
|
+
})
|
|
441
|
+
.should.be.rejectedWith(/invalid user templateId/);
|
|
442
|
+
});
|
|
443
|
+
it('should throw on templateId module/entity mismatch', async function () {
|
|
444
|
+
await basecoin
|
|
445
|
+
.verifyTransaction({
|
|
446
|
+
txPrebuild: { txHex },
|
|
447
|
+
txParams: {
|
|
448
|
+
cantonCommandParams: {
|
|
449
|
+
command: {
|
|
450
|
+
ExerciseCommand: {
|
|
451
|
+
templateId: 'SomePkg:Wrong.Module:WrongEntity',
|
|
452
|
+
choice: CANTON_CMD_CHOICE,
|
|
453
|
+
choiceArgument: {},
|
|
454
|
+
},
|
|
455
|
+
},
|
|
456
|
+
actAs: [CANTON_CMD_ACT_AS],
|
|
457
|
+
},
|
|
458
|
+
},
|
|
459
|
+
wallet: {},
|
|
460
|
+
})
|
|
461
|
+
.should.be.rejectedWith(/templateId mismatch/);
|
|
462
|
+
});
|
|
463
|
+
it('should throw on submitterInfo.actAs mismatch', async function () {
|
|
464
|
+
await basecoin
|
|
465
|
+
.verifyTransaction({
|
|
466
|
+
txPrebuild: { txHex },
|
|
467
|
+
txParams: {
|
|
468
|
+
cantonCommandParams: {
|
|
469
|
+
command: {
|
|
470
|
+
ExerciseCommand: {
|
|
471
|
+
templateId: CANTON_CMD_TEMPLATE_ID,
|
|
472
|
+
choice: CANTON_CMD_CHOICE,
|
|
473
|
+
choiceArgument: {},
|
|
474
|
+
},
|
|
475
|
+
},
|
|
476
|
+
actAs: ['WrongParty::1220aaaa'],
|
|
477
|
+
},
|
|
478
|
+
},
|
|
479
|
+
wallet: {},
|
|
480
|
+
})
|
|
481
|
+
.should.be.rejectedWith(/submitterInfo.actAs.*does not match user actAs/);
|
|
482
|
+
});
|
|
483
|
+
it('should throw on choice mismatch for ExerciseCommand', async function () {
|
|
484
|
+
await basecoin
|
|
485
|
+
.verifyTransaction({
|
|
486
|
+
txPrebuild: { txHex },
|
|
487
|
+
txParams: {
|
|
488
|
+
cantonCommandParams: {
|
|
489
|
+
command: {
|
|
490
|
+
ExerciseCommand: {
|
|
491
|
+
templateId: CANTON_CMD_TEMPLATE_ID,
|
|
492
|
+
choice: 'WrongChoice',
|
|
493
|
+
choiceArgument: {},
|
|
494
|
+
},
|
|
495
|
+
},
|
|
496
|
+
actAs: [CANTON_CMD_ACT_AS],
|
|
497
|
+
},
|
|
498
|
+
},
|
|
499
|
+
wallet: {},
|
|
500
|
+
})
|
|
501
|
+
.should.be.rejectedWith(/choice mismatch/);
|
|
502
|
+
});
|
|
503
|
+
it('should throw on contractId mismatch when user provides explicit contractId', async function () {
|
|
504
|
+
await basecoin
|
|
505
|
+
.verifyTransaction({
|
|
506
|
+
txPrebuild: { txHex },
|
|
507
|
+
txParams: {
|
|
508
|
+
cantonCommandParams: {
|
|
509
|
+
command: {
|
|
510
|
+
ExerciseCommand: {
|
|
511
|
+
templateId: CANTON_CMD_TEMPLATE_ID,
|
|
512
|
+
contractId: '00wrongcontractid',
|
|
513
|
+
choice: CANTON_CMD_CHOICE,
|
|
514
|
+
choiceArgument: {},
|
|
515
|
+
},
|
|
516
|
+
},
|
|
517
|
+
actAs: [CANTON_CMD_ACT_AS],
|
|
518
|
+
},
|
|
519
|
+
},
|
|
520
|
+
wallet: {},
|
|
521
|
+
})
|
|
522
|
+
.should.be.rejectedWith(/contractId mismatch/);
|
|
523
|
+
});
|
|
524
|
+
it('should throw on argument deep mismatch', async function () {
|
|
525
|
+
await basecoin
|
|
526
|
+
.verifyTransaction({
|
|
527
|
+
txPrebuild: { txHex },
|
|
528
|
+
txParams: {
|
|
529
|
+
cantonCommandParams: {
|
|
530
|
+
command: {
|
|
531
|
+
ExerciseCommand: {
|
|
532
|
+
templateId: CANTON_CMD_TEMPLATE_ID,
|
|
533
|
+
choice: CANTON_CMD_CHOICE,
|
|
534
|
+
choiceArgument: {
|
|
535
|
+
expectedAdmin: 'WrongParty::totally-different',
|
|
536
|
+
},
|
|
537
|
+
},
|
|
538
|
+
},
|
|
539
|
+
actAs: [CANTON_CMD_ACT_AS],
|
|
540
|
+
},
|
|
541
|
+
},
|
|
542
|
+
wallet: {},
|
|
543
|
+
})
|
|
544
|
+
.should.be.rejectedWith(/mismatch/);
|
|
545
|
+
});
|
|
546
|
+
});
|
|
547
|
+
});
|
|
548
|
+
// --------------- CreateCommand verification tests ---------------
|
|
549
|
+
const CREATE_CMD_ACT_AS = 'RegProvider::1220508e54fb709dcb1a9b4096408ad415d2217d8881ad9034a9850752933ba88ad5';
|
|
550
|
+
const CREATE_CMD_TEMPLATE_ID = '7a75ef6e69f69395a4e60919e228528bb8f3881150ccfde3f31bcc73864b18ab:Utility.Registry.App.V0.Service.Provider:ProviderServiceRequest';
|
|
551
|
+
const CREATE_CMD_OPERATOR = 'RegOperator::1220508e54fb709dcb1a9b4096408ad415d2217d8881ad9034a9850752933ba88ad5';
|
|
552
|
+
describe('Canton verifyTransaction - CreateCommand:', function () {
|
|
553
|
+
let bitgo;
|
|
554
|
+
let basecoin;
|
|
555
|
+
before(function () {
|
|
556
|
+
bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'mock' });
|
|
557
|
+
bitgo.safeRegister('canton', src_1.Canton.createInstance);
|
|
558
|
+
bitgo.safeRegister('tcanton', src_1.Tcanton.createInstance);
|
|
559
|
+
bitgo.initializeTestVars();
|
|
560
|
+
basecoin = bitgo.coin('tcanton');
|
|
561
|
+
});
|
|
562
|
+
describe('Happy path tests:', function () {
|
|
563
|
+
let txHex;
|
|
564
|
+
before(function () {
|
|
565
|
+
txHex = buildCantonCommandRawTx(resources_1.CantonCreateCommandPrepareResponse, 'test-create-cmd-001');
|
|
566
|
+
});
|
|
567
|
+
it('should return true for matching CreateCommand (templateId, createArguments, actAs)', async function () {
|
|
568
|
+
const result = await basecoin.verifyTransaction({
|
|
569
|
+
txPrebuild: { txHex },
|
|
570
|
+
txParams: {
|
|
571
|
+
cantonCommandParams: {
|
|
572
|
+
command: {
|
|
573
|
+
CreateCommand: {
|
|
574
|
+
templateId: CREATE_CMD_TEMPLATE_ID,
|
|
575
|
+
createArguments: {
|
|
576
|
+
operator: CREATE_CMD_OPERATOR,
|
|
577
|
+
provider: CREATE_CMD_ACT_AS,
|
|
578
|
+
},
|
|
579
|
+
},
|
|
580
|
+
},
|
|
581
|
+
actAs: [CREATE_CMD_ACT_AS],
|
|
582
|
+
readAs: [],
|
|
583
|
+
},
|
|
584
|
+
},
|
|
585
|
+
wallet: {},
|
|
586
|
+
});
|
|
587
|
+
result.should.equal(true);
|
|
588
|
+
});
|
|
589
|
+
it('should return true when createArguments is empty (no deep-compare)', async function () {
|
|
590
|
+
const result = await basecoin.verifyTransaction({
|
|
591
|
+
txPrebuild: { txHex },
|
|
592
|
+
txParams: {
|
|
593
|
+
cantonCommandParams: {
|
|
594
|
+
command: {
|
|
595
|
+
CreateCommand: {
|
|
596
|
+
templateId: CREATE_CMD_TEMPLATE_ID,
|
|
597
|
+
createArguments: {},
|
|
598
|
+
},
|
|
599
|
+
},
|
|
600
|
+
actAs: [CREATE_CMD_ACT_AS],
|
|
601
|
+
readAs: [],
|
|
602
|
+
},
|
|
603
|
+
},
|
|
604
|
+
wallet: {},
|
|
605
|
+
});
|
|
606
|
+
result.should.equal(true);
|
|
607
|
+
});
|
|
608
|
+
it('should return true with resolveContracts injectAs skipping createArguments field', async function () {
|
|
609
|
+
const result = await basecoin.verifyTransaction({
|
|
610
|
+
txPrebuild: { txHex },
|
|
611
|
+
txParams: {
|
|
612
|
+
cantonCommandParams: {
|
|
613
|
+
command: {
|
|
614
|
+
CreateCommand: {
|
|
615
|
+
templateId: CREATE_CMD_TEMPLATE_ID,
|
|
616
|
+
createArguments: {
|
|
617
|
+
operator: 'placeholder-operator-id',
|
|
618
|
+
provider: CREATE_CMD_ACT_AS,
|
|
619
|
+
},
|
|
620
|
+
},
|
|
621
|
+
},
|
|
622
|
+
actAs: [CREATE_CMD_ACT_AS],
|
|
623
|
+
readAs: [],
|
|
624
|
+
resolveContracts: [
|
|
625
|
+
{
|
|
626
|
+
templateId: 'some-template',
|
|
627
|
+
actAs: [CREATE_CMD_ACT_AS],
|
|
628
|
+
injectAs: 'command.CreateCommand.createArguments.operator',
|
|
629
|
+
},
|
|
630
|
+
],
|
|
631
|
+
},
|
|
632
|
+
},
|
|
633
|
+
wallet: {},
|
|
634
|
+
});
|
|
635
|
+
result.should.equal(true);
|
|
636
|
+
});
|
|
637
|
+
});
|
|
638
|
+
describe('Error cases:', function () {
|
|
639
|
+
let txHex;
|
|
640
|
+
before(function () {
|
|
641
|
+
txHex = buildCantonCommandRawTx(resources_1.CantonCreateCommandPrepareResponse, 'test-create-cmd-err');
|
|
642
|
+
});
|
|
643
|
+
it('should throw on templateId mismatch for CreateCommand', async function () {
|
|
644
|
+
await basecoin
|
|
645
|
+
.verifyTransaction({
|
|
646
|
+
txPrebuild: { txHex },
|
|
647
|
+
txParams: {
|
|
648
|
+
cantonCommandParams: {
|
|
649
|
+
command: {
|
|
650
|
+
CreateCommand: {
|
|
651
|
+
templateId: 'WrongPkg:Wrong.Module:WrongEntity',
|
|
652
|
+
createArguments: {},
|
|
653
|
+
},
|
|
654
|
+
},
|
|
655
|
+
actAs: [CREATE_CMD_ACT_AS],
|
|
656
|
+
},
|
|
657
|
+
},
|
|
658
|
+
wallet: {},
|
|
659
|
+
})
|
|
660
|
+
.should.be.rejectedWith(/templateId mismatch/);
|
|
661
|
+
});
|
|
662
|
+
it('should throw on createArguments deep mismatch', async function () {
|
|
663
|
+
await basecoin
|
|
664
|
+
.verifyTransaction({
|
|
665
|
+
txPrebuild: { txHex },
|
|
666
|
+
txParams: {
|
|
667
|
+
cantonCommandParams: {
|
|
668
|
+
command: {
|
|
669
|
+
CreateCommand: {
|
|
670
|
+
templateId: CREATE_CMD_TEMPLATE_ID,
|
|
671
|
+
createArguments: {
|
|
672
|
+
operator: 'WrongOperator::totally-different',
|
|
673
|
+
provider: CREATE_CMD_ACT_AS,
|
|
674
|
+
},
|
|
675
|
+
},
|
|
676
|
+
},
|
|
677
|
+
actAs: [CREATE_CMD_ACT_AS],
|
|
678
|
+
},
|
|
679
|
+
},
|
|
680
|
+
wallet: {},
|
|
681
|
+
})
|
|
682
|
+
.should.be.rejectedWith(/mismatch/);
|
|
683
|
+
});
|
|
684
|
+
it('should throw on actAs mismatch for CreateCommand', async function () {
|
|
685
|
+
await basecoin
|
|
686
|
+
.verifyTransaction({
|
|
687
|
+
txPrebuild: { txHex },
|
|
688
|
+
txParams: {
|
|
689
|
+
cantonCommandParams: {
|
|
690
|
+
command: {
|
|
691
|
+
CreateCommand: {
|
|
692
|
+
templateId: CREATE_CMD_TEMPLATE_ID,
|
|
693
|
+
createArguments: {},
|
|
694
|
+
},
|
|
695
|
+
},
|
|
696
|
+
actAs: ['WrongParty::1220aaaa'],
|
|
697
|
+
},
|
|
698
|
+
},
|
|
699
|
+
wallet: {},
|
|
700
|
+
})
|
|
701
|
+
.should.be.rejectedWith(/submitterInfo.actAs.*does not match user actAs/);
|
|
702
|
+
});
|
|
703
|
+
});
|
|
704
|
+
});
|
|
705
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FudG9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdGVzdC91bml0L2NhbnRvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLGtCQUFnQjtBQUNoQixpREFBK0M7QUFDL0MsbURBQStEO0FBRS9ELGlEQUE0QztBQUU1QyxtQ0FBZ0c7QUFFaEcsNENBTXNCO0FBRXRCOzs7OztHQUtHO0FBQ0gsU0FBUyw0QkFBNEIsQ0FDbkMsZUFBeUQsRUFDekQsU0FBaUI7SUFFakIsTUFBTSxJQUFJLEdBQUc7UUFDWCxzQkFBc0IsRUFBRSxlQUFlO1FBQ3ZDLE1BQU0sRUFBRSxvQkFBb0I7UUFDNUIsbUJBQW1CLEVBQUUsRUFBRTtRQUN2QixlQUFlLEVBQUUsRUFBRSxVQUFVLEVBQUUsRUFBRSxFQUFFO1FBQ25DLG1CQUFtQixFQUFFLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRTtRQUNsQyxZQUFZLEVBQUUsU0FBUztRQUN2QixvQkFBb0IsRUFBRSwyQkFBMkI7UUFDakQsYUFBYSxFQUFFLEVBQUUsSUFBSSxFQUFFLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRSxFQUFFO0tBQ3ZDLENBQUM7SUFDRixPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUM5RCxDQUFDO0FBRUQseUZBQXlGO0FBQ3pGLFNBQVMscUJBQXFCLENBQUMsV0FBbUI7SUFDaEQsT0FBTyxFQUFFLFlBQVksRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUUsV0FBVyxFQUFFLENBQUMsRUFBd0IsQ0FBQztBQUN6RSxDQUFDO0FBRUQsUUFBUSxDQUFDLGNBQWMsRUFBRTtJQUN2QixJQUFJLEtBQW1CLENBQUM7SUFDeEIsSUFBSSxRQUFnQixDQUFDO0lBRXJCLE1BQU0sQ0FBQztRQUNMLEtBQUssR0FBRyxvQkFBUyxDQUFDLFFBQVEsQ0FBQyxrQkFB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QUNSLG1CQUFtQixFQUFFO3dCQUNuQixPQUFPLEVBQUU7NEJBQ1AsYUFBYSxFQUFFO2dDQUNiLFVBQVUsRUFBRSxzQkFBc0I7Z0NBQ2xDLGVBQWUsRUFBRTtvQ0FDZixRQUFRLEVBQUUsa0NBQWtDO29DQUM1QyxRQUFRLEVBQUUsaUJBQWlCO2lDQUM1Qjs2QkFDRjt5QkFDRjt3QkFDRCxLQUFLLEVBQUUsQ0FBQyxpQkFBaUIsQ0FBQztxQkFDM0I7aUJBQ3lCO2dCQUM1QixNQUFNLEVBQUUsRUFBYTthQUN0QixDQUFDO2lCQUNELE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3hDLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLGtEQUFrRCxFQUFFLEtBQUs7WUFDMUQsTUFBTSxRQUFRO2lCQUNYLGlCQUFpQixDQUFDO2dCQUNqQixVQUFVLEVBQUUsRUFBRSxLQUFLLEVBQUU7Z0JBQ3JCLFFBQVEsRUFBRTtvQkFDUixtQkFBbUIsRUFBRTt3QkFDbkIsT0FBTyxFQUFFOzRCQUNQLGFBQWEsRUFBRTtnQ0FDYixVQUFVLEVBQUUsc0JBQXNCO2dDQUNsQyxlQUFlLEVBQUUsRUFBRTs2QkFDcEI7eUJBQ0Y7d0JBQ0QsS0FBSyxFQUFFLENBQUMsc0JBQXNCLENBQUM7cUJBQ2hDO2lCQUN5QjtnQkFDNUIsTUFBTSxFQUFFLEVBQWE7YUFDdEIsQ0FBQztpQkFDRCxNQUFNLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxnREFBZ0QsQ0FBQyxDQUFDO1FBQzlFLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAnc2hvdWxkJztcbmltcG9ydCB7IEJpdEdvQVBJIH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWFwaSc7XG5pbXBvcnQgeyBUZXN0Qml0R28sIFRlc3RCaXRHb0FQSSB9IGZyb20gJ0BiaXRnby1iZXRhL3Nkay10ZXN0JztcbmltcG9ydCB7IENhbnRvbkNvbW1hbmQsIElXYWxsZXQgfSBmcm9tICdAYml0Z28tYmV0YS9zZGstY29yZSc7XG5pbXBvcnQgeyBjb2lucyB9IGZyb20gJ0BiaXRnby1iZXRhL3N0YXRpY3MnO1xuXG5pbXBvcnQgeyBDYW50b24sIENhbnRvblRyYW5zYWN0aW9uUGFyYW1zLCBUY2FudG9uLCBUcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5IH0gZnJvbSAnLi4vLi4vc3JjJztcbmltcG9ydCB7IENhbnRvblByZXBhcmVDb21tYW5kUmVzcG9uc2UgfSBmcm9tICcuLi8uLi9zcmMvbGliL2lmYWNlJztcbmltcG9ydCB7XG4gIENhbnRvbkV4ZXJjaXNlQ29tbWFuZFByZXBhcmVSZXNwb25zZSxcbiAgQ2FudG9uQ3JlYXRlQ29tbWFuZFByZXBhcmVSZXNwb25zZSxcbiAgQ2FudG9uVG9rZW5QcmVBcHByb3ZhbFByZXBhcmVSZXNwb25zZSxcbiAgT25lU3RlcEVuYWJsZW1lbnQsXG4gIE9uZVN0ZXBQcmVBcHByb3ZhbFByZXBhcmVSZXNwb25zZSxcbn0gZnJvbSAnLi4vcmVzb3VyY2VzJztcblxuLyoqXG4gKiBCdWlsZHMgYSBiYXNlNjQtZW5jb2RlZCByYXcgdHJhbnNhY3Rpb24gZm9yIGEgT25lU3RlcFByZUFwcHJvdmFsIChlbmFibGUgdG9rZW4gZmxvdykuXG4gKiBGb3IgVFNTIHdhbGxldHMgKHdoaWNoIENhbnRvbiBhbHdheXMgaXMpLCB2ZXJpZnlUcmFuc2FjdGlvbiByZWNlaXZlcyB0eFBhcmFtcy5lbmFibGVUb2tlbnMsXG4gKiBub3QgdHhQYXJhbXMucmVjaXBpZW50cy4gVGhlIHdhbGxldCBTREsncyBidWlsZFRva2VuRW5hYmxlbWVudHMgcGFzc2VzIGVuYWJsZVRva2VucyB0aHJvdWdoXG4gKiB1bmNoYW5nZWQgZm9yIFRTUyB3YWxsZXRzIHJhdGhlciB0aGFuIGNvbnZlcnRpbmcgdGhlbSB0byByZWNpcGllbnRzLlxuICovXG5mdW5jdGlvbiBidWlsZE9uZVN0ZXBQcmVBcHByb3ZhbFJhd1R4KFxuICBwcmVwYXJlUmVzcG9uc2U6IHR5cGVvZiBPbmVTdGVwUHJlQXBwcm92YWxQcmVwYXJlUmVzcG9uc2UsXG4gIGNvbW1hbmRJZDogc3RyaW5nXG4pOiBzdHJpbmcge1xuICBjb25zdCBkYXRhID0ge1xuICAgIHByZXBhcmVDb21tYW5kUmVzcG9uc2U6IHByZXBhcmVSZXNwb25zZSxcbiAgICB0eFR5cGU6ICdPbmVTdGVwUHJlQXBwcm92YWwnLFxuICAgIHByZXBhcmVkVHJhbnNhY3Rpb246ICcnLFxuICAgIHBhcnR5U2lnbmF0dXJlczogeyBzaWduYXR1cmVzOiBbXSB9LFxuICAgIGRlZHVwbGljYXRpb25QZXJpb2Q6IHsgRW1wdHk6IHt9IH0sXG4gICAgc3VibWlzc2lvbklkOiBjb21tYW5kSWQsXG4gICAgaGFzaGluZ1NjaGVtZVZlcnNpb246ICdIQVNISU5HX1NDSEVNRV9WRVJTSU9OX1YyJyxcbiAgICBtaW5MZWRnZXJUaW1lOiB7IHRpbWU6IHsgRW1wdHk6IHt9IH0gfSxcbiAgfTtcbiAgcmV0dXJuIEJ1ZmZlci5mcm9tKEpTT04uc3RyaW5naWZ5KGRhdGEpKS50b1N0cmluZygnYmFzZTY0Jyk7XG59XG5cbi8qKiBSZXR1cm5zIGEgbW9jayB3YWxsZXQgd2hvc2UgY29pblNwZWNpZmljKCkucm9vdEFkZHJlc3MgbWF0Y2hlcyB0aGUgZ2l2ZW4gcGFydHkgSUQuICovXG5mdW5jdGlvbiB3YWxsZXRXaXRoUm9vdEFkZHJlc3Mocm9vdEFkZHJlc3M6IHN0cmluZyk6IElXYWxsZXQge1xuICByZXR1cm4geyBjb2luU3BlY2lmaWM6ICgpID0+ICh7IHJvb3RBZGRyZXNzIH0pIH0gYXMgdW5rbm93biBhcyBJV2FsbGV0O1xufVxuXG5kZXNjcmliZSgnQ2FudG9uIGNvaW46JywgZnVuY3Rpb24gKCkge1xuICBsZXQgYml0Z286IFRlc3RCaXRHb0FQSTtcbiAgbGV0IGJhc2Vjb2luOiBDYW50b247XG5cbiAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHb0FQSSwgeyBlbnY6ICdtb2NrJyB9KTtcbiAgICBiaXRnby5zYWZlUmVnaXN0ZXIoJ2NhbnRvbicsIENhbnRvbi5jcmVhdGVJbnN0YW5jZSk7XG4gICAgYml0Z28uc2FmZVJlZ2lzdGVyKCd0Y2FudG9uJywgVGNhbnRvbi5jcmVhdGVJbnN0YW5jZSk7XG4gICAgYml0Z28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gICAgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0Y2FudG9uJykgYXMgQ2FudG9uO1xuICB9KTtcblxuICBkZXNjcmliZSgnc3VwcG9ydHNNZXNzYWdlU2lnbmluZycsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlJywgZnVuY3Rpb24gKCkge1xuICAgICAgYmFzZWNvaW4uc3VwcG9ydHNNZXNzYWdlU2lnbmluZygpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcblxuZGVzY3JpYmUoJ0NhbnRvbiB2ZXJpZnlUcmFuc2FjdGlvbjonLCBmdW5jdGlvbiAoKSB7XG4gIGxldCBiaXRnbzogVGVzdEJpdEdvQVBJO1xuICBsZXQgYmFzZWNvaW46IENhbnRvbjtcblxuICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgIGJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvQVBJLCB7IGVudjogJ21vY2snIH0pO1xuICAgIGJpdGdvLnNhZmVSZWdpc3RlcignY2FudG9uJywgQ2FudG9uLmNyZWF0ZUluc3RhbmNlKTtcbiAgICBiaXRnby5zYWZlUmVnaXN0ZXIoJ3RjYW50b24nLCBUY2FudG9uLmNyZWF0ZUluc3RhbmNlKTtcbiAgICBiaXRnby5pbml0aWFsaXplVGVzdFZhcnMoKTtcbiAgICBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ3RjYW50b24nKSBhcyBDYW50b247XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdPbmVTdGVwUHJlQXBwcm92YWwgKGVuYWJsZSB0b2tlbiBmbG93KTonLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSB3aGVuIHR4UGFyYW1zIGhhcyBubyB0eXBlIChub24tZW5hYmxldG9rZW4gZmxvdyknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eEhleCA9IGJ1aWxkT25lU3RlcFByZUFwcHJvdmFsUmF3VHgoT25lU3RlcFByZUFwcHJvdmFsUHJlcGFyZVJlc3BvbnNlLCBPbmVTdGVwRW5hYmxlbWVudC5jb21tYW5kSWQpO1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFByZWJ1aWxkOiB7IHR4SGV4IH0sXG4gICAgICAgIHR4UGFyYW1zOiB7fSxcbiAgICAgICAgd2FsbGV0OiB7fSBhcyBhbnksXG4gICAgICB9KTtcbiAgICAgIHJlc3VsdC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIHdoZW4gZW5hYmxlVG9rZW5zIGlzIGFic2VudCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4SGV4ID0gYnVpbGRPbmVTdGVwUHJlQXBwcm92YWxSYXdUeChPbmVTdGVwUHJlQXBwcm92YWxQcmVwYXJlUmVzcG9uc2UsIE9uZVN0ZXBFbmFibGVtZW50LmNvbW1hbmRJZCk7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UHJlYnVpbGQ6IHsgdHhIZXggfSxcbiAgICAgICAgdHhQYXJhbXM6IHsgdHlwZTogJ2VuYWJsZXRva2VuJyB9LFxuICAgICAgICB3YWxsZXQ6IHt9IGFzIGFueSxcbiAgICAgIH0pO1xuICAgICAgcmVzdWx0LnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgd2hlbiBlbmFibGVUb2tlbnMgaXMgZW1wdHknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eEhleCA9IGJ1aWxkT25lU3RlcFByZUFwcHJvdmFsUmF3VHgoT25lU3RlcFByZUFwcHJvdmFsUHJlcGFyZVJlc3BvbnNlLCBPbmVTdGVwRW5hYmxlbWVudC5jb21tYW5kSWQpO1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFByZWJ1aWxkOiB7IHR4SGV4IH0sXG4gICAgICAgIHR4UGFyYW1zOiB7IHR5cGU6ICdlbmFibGV0b2tlbicsIGVuYWJsZVRva2VuczogW10gfSxcbiAgICAgICAgd2FsbGV0OiB7fSBhcyBhbnksXG4gICAgICB9KTtcbiAgICAgIHJlc3VsdC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnY29pbiBwcmUtYXBwcm92YWwgKFRyYW5zZmVyUHJlYXBwcm92YWxQcm9wb3NhbCk6JywgZnVuY3Rpb24gKCkge1xuICAgICAgbGV0IHR4SGV4OiBzdHJpbmc7XG4gICAgICBsZXQgcmVjZWl2ZXI6IHN0cmluZztcblxuICAgICAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdHhIZXggPSBidWlsZE9uZVN0ZXBQcmVBcHByb3ZhbFJhd1R4KE9uZVN0ZXBQcmVBcHByb3ZhbFByZXBhcmVSZXNwb25zZSwgT25lU3RlcEVuYWJsZW1lbnQuY29tbWFuZElkKTtcbiAgICAgICAgLy8gRHluYW1pY2FsbHkgZGVyaXZlIHJlY2VpdmVyIGZyb20gcGFyc2VkIHRyYW5zYWN0aW9uIHRvIGF2b2lkIGhhcmRjb2RpbmcgcHJvdG9idWYtZGVjb2RlZCBhZGRyZXNzZXNcbiAgICAgICAgY29uc3QgdHhCdWlsZGVyID0gbmV3IFRyYW5zYWN0aW9uQnVpbGRlckZhY3RvcnkoY29pbnMuZ2V0KCd0Y2FudG9uJykpLmZyb20odHhIZXgpO1xuICAgICAgICByZWNlaXZlciA9ICh0eEJ1aWxkZXIudHJhbnNhY3Rpb24gYXMgYW55KS50b0pzb24oKS5yZWNlaXZlciBhcyBzdHJpbmc7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSB3aGVuIHdhbGxldCBoYXMgbm8gY29pblNwZWNpZmljIChyZWNlaXZlciBjaGVjayBza2lwcGVkKScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gVHlwaWNhbCBjYXNlOiB3YWxsZXQgbW9jayBoYXMgbm8gY29pblNwZWNpZmljKCkgbWV0aG9kLCBhbmQgbm8gYWRkcmVzcyBpbiBlbmFibGVUb2tlbnNcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UHJlYnVpbGQ6IHsgdHhIZXggfSxcbiAgICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgICAgdHlwZTogJ2VuYWJsZXRva2VuJyxcbiAgICAgICAgICAgIGVuYWJsZVRva2VuczogW3sgbmFtZTogJ2NhbnRvbicgfV0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICB3YWxsZXQ6IHt9IGFzIGFueSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJlc3VsdC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSB3aGVuIHdhbGxldCByb290QWRkcmVzcyBtYXRjaGVzIHJlY2VpdmVyJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyBUeXBpY2FsIFVJIGZsb3c6IGVuYWJsZVRva2VucyBoYXMgbm8gYWRkcmVzcywgcmVjZWl2ZXIgdmFsaWRhdGVkIGZyb20gd2FsbGV0LmNvaW5TcGVjaWZpYygpLnJvb3RBZGRyZXNzXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0eFByZWJ1aWxkOiB7IHR4SGV4IH0sXG4gICAgICAgICAgdHhQYXJhbXM6IHtcbiAgICAgICAgICAgIHR5cGU6ICdlbmFibGV0b2tlbicsXG4gICAgICAgICAgICBlbmFibGVUb2tlbnM6IFt7IG5hbWU6ICdjYW50b24nIH1dLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgd2FsbGV0OiB3YWxsZXRXaXRoUm9vdEFkZHJlc3MocmVjZWl2ZXIpLFxuICAgICAgICB9KTtcbiAgICAgICAgcmVzdWx0LnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIHdoZW4gZW5hYmxlVG9rZW4uYWRkcmVzcyBtYXRjaGVzIHJlY2VpdmVyIChleHBsaWNpdCBhZGRyZXNzKScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UHJlYnVpbGQ6IHsgdHhIZXggfSxcbiAgICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgICAgdHlwZTogJ2VuYWJsZXRva2VuJyxcbiAgICAgICAgICAgIGVuYWJsZVRva2VuczogW3sgbmFtZTogJ2NhbnRvbicsIGFkZHJlc3M6IHJlY2VpdmVyIH1dLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgd2FsbGV0OiB7fSBhcyBhbnksXG4gICAgICAgIH0pO1xuICAgICAgICByZXN1bHQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgd2hlbiB3YWxsZXQgcm9vdEFkZHJlc3MgZG9lcyBub3QgbWF0Y2ggcmVjZWl2ZXInLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHdyb25nQWRkcmVzcyA9ICd3cm9uZy1wYXJ0eTo6MTIyMGFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEnO1xuICAgICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgICB0eFByZWJ1aWxkOiB7IHR4SGV4IH0sXG4gICAgICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgICAgICB0eXBlOiAnZW5hYmxldG9rZW4nLFxuICAgICAgICAgICAgICBlbmFibGVUb2tlbnM6IFt7IG5hbWU6ICdjYW50b24nIH1dLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHdhbGxldDogd2FsbGV0V2l0aFJvb3RBZGRyZXNzKHdyb25nQWRkcmVzcyksXG4gICAgICAgICAgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvT25lU3RlcFByZUFwcHJvdmFsIHJlY2VpdmVyIG1pc21hdGNoLyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyB3aGVuIGV4cGxpY2l0IGVuYWJsZVRva2VuLmFkZHJlc3MgZG9lcyBub3QgbWF0Y2ggcmVjZWl2ZXInLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHdyb25nQWRkcmVzcyA9ICd3cm9uZy1wYXJ0eTo6MTIyMGFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEnO1xuICAgICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgICB0eFByZWJ1aWxkOiB7IHR4SGV4IH0sXG4gICAgICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgICAgICB0eXBlOiAnZW5hYmxldG9rZW4nLFxuICAgICAgICAgICAgICBlbmFibGVUb2tlbnM6IFt7IG5hbWU6ICdjYW50b24nLCBhZGRyZXNzOiB3cm9uZ0FkZHJlc3MgfV0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgd2FsbGV0OiB7fSBhcyBhbnksXG4gICAgICAgICAgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvT25lU3RlcFByZUFwcHJvdmFsIHJlY2VpdmVyIG1pc21hdGNoLyk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCd0b2tlbiBwcmUtYXBwcm92YWwgKFRyYW5zZmVyUHJlYXBwcm92YWwpOicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGxldCB0eEhleDogc3RyaW5nO1xuICAgICAgbGV0IHJlY2VpdmVyOiBzdHJpbmc7XG5cbiAgICAgIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGNvbW1hbmRJZCA9ICc3ZDk5Nzg5ZC0yZjIyLTQ5ZTEtODVjYi03OWQyY2U1YTY5YzEnO1xuICAgICAgICB0eEhleCA9IGJ1aWxkT25lU3RlcFByZUFwcHJvdmFsUmF3VHgoQ2FudG9uVG9rZW5QcmVBcHByb3ZhbFByZXBhcmVSZXNwb25zZSwgY29tbWFuZElkKTtcbiAgICAgICAgY29uc3QgdHhCdWlsZGVyID0gbmV3IFRyYW5zYWN0aW9uQnVpbGRlckZhY3RvcnkoY29pbnMuZ2V0KCd0Y2FudG9uJykpLmZyb20odHhIZXgpO1xuICAgICAgICByZWNlaXZlciA9ICh0eEJ1aWxkZXIudHJhbnNhY3Rpb24gYXMgYW55KS50b0pzb24oKS5yZWNlaXZlciBhcyBzdHJpbmc7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSB3aGVuIHdhbGxldCByb290QWRkcmVzcyBtYXRjaGVzIHJlY2VpdmVyJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhQcmVidWlsZDogeyB0eEhleCB9LFxuICAgICAgICAgIHR4UGFyYW1zOiB7XG4gICAgICAgICAgICB0eXBlOiAnZW5hYmxldG9rZW4nLFxuICAgICAgICAgICAgZW5hYmxlVG9rZW5zOiBbeyBuYW1lOiAndGNhbnRvbjp0ZXN0Y29pbjEnIH1dLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgd2FsbGV0OiB3YWxsZXRXaXRoUm9vdEFkZHJlc3MocmVjZWl2ZXIpLFxuICAgICAgICB9KTtcbiAgICAgICAgcmVzdWx0LnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIHdoZW4gZW5hYmxlVG9rZW4uYWRkcmVzcyBtYXRjaGVzIHJlY2VpdmVyIChleHBsaWNpdCBhZGRyZXNzKScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UHJlYnVpbGQ6IHsgdHhIZXggfSxcbiAgICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgICAgdHlwZTogJ2VuYWJsZXRva2VuJyxcbiAgICAgICAgICAgIGVuYWJsZVRva2VuczogW3sgbmFtZTogJ3RjYW50b246dGVzdGNvaW4xJywgYWRkcmVzczogcmVjZWl2ZXIgfV0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICB3YWxsZXQ6IHt9IGFzIGFueSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJlc3VsdC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyB3aGVuIHdhbGxldCByb290QWRkcmVzcyBkb2VzIG5vdCBtYXRjaCByZWNlaXZlcicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgd3JvbmdBZGRyZXNzID0gJ3dyb25nLXBhcnR5OjoxMjIwYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmInO1xuICAgICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgICB0eFByZWJ1aWxkOiB7IHR4SGV4IH0sXG4gICAgICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgICAgICB0eXBlOiAnZW5hYmxldG9rZW4nLFxuICAgICAgICAgICAgICBlbmFibGVUb2tlbnM6IFt7IG5hbWU6ICd0Y2FudG9uOnRlc3Rjb2luMScgfV0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgd2FsbGV0OiB3YWxsZXRXaXRoUm9vdEFkZHJlc3Mod3JvbmdBZGRyZXNzKSxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKC9PbmVTdGVwUHJlQXBwcm92YWwgcmVjZWl2ZXIgbWlzbWF0Y2gvKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IHdoZW4gZXhwbGljaXQgZW5hYmxlVG9rZW4uYWRkcmVzcyBkb2VzIG5vdCBtYXRjaCByZWNlaXZlcicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgd3JvbmdBZGRyZXNzID0gJ3dyb25nLXBhcnR5OjoxMjIwYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmInO1xuICAgICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgICB0eFByZWJ1aWxkOiB7IHR4SGV4IH0sXG4gICAgICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgICAgICB0eXBlOiAnZW5hYmxldG9rZW4nLFxuICAgICAgICAgICAgICBlbmFibGVUb2tlbnM6IFt7IG5hbWU6ICd0Y2FudG9uOnRlc3Rjb2luMScsIGFkZHJlc3M6IHdyb25nQWRkcmVzcyB9XSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB3YWxsZXQ6IHt9IGFzIGFueSxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKC9PbmVTdGVwUHJlQXBwcm92YWwgcmVjZWl2ZXIgbWlzbWF0Y2gvKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuXG4vLyAtLS0tLS0tLS0tLS0tLS0gRXhlcmNpc2VDb21tYW5kIHZlcmlmaWNhdGlvbiB0ZXN0cyAtLS0tLS0tLS0tLS0tLS1cblxuY29uc3QgQ0FOVE9OX0NNRF9BQ1RfQVMgPSAnUmVnUmVnaXN0cmFyOjoxMjIwNTA4ZTU0ZmI3MDlkY2IxYTliNDA5NjQwOGFkNDE1ZDIyMTdkODg4MWFkOTAzNGE5ODUwNzUyOTMzYmE4OGFkNSc7XG5jb25zdCBDQU5UT05fQ01EX1RFTVBMQVRFX0lEID1cbiAgJzdhNzVlZjZlNjlmNjkzOTVhNGU2MDkxOWUyMjg1MjhiYjhmMzg4MTE1MGNjZmRlM2YzMWJjYzczODY0YjE4YWI6VXRpbGl0eS5SZWdpc3RyeS5BcHAuVjAuU2VydmljZS5BbGxvY2F0aW9uRmFjdG9yeTpBbGxvY2F0aW9uRmFjdG9yeSc7XG5jb25zdCBDQU5UT05fQ01EX0NPTlRSQUNUX0lEID1cbiAgJzAwZjNhZmRjZTg0NmE0MGM2ZjNmNjE4YzRiNTg0YjAyMmEwMTk3MDEwMDU3ZWNkNTk0NTgyMDAxODNhYjI3ZGUwYWNhMTIxMjIwNGFlZjdlZGUzN2E1ZjQxYjY3NGExZDk1NDQ2ZDQyYTQwNDQ2MWM1NTU4YzRlNmQxODYwYjY1NTYwMTIwZWYxOCc7XG5jb25zdCBDQU5UT05fQ01EX0NIT0lDRSA9ICdBbGxvY2F0aW9uRmFjdG9yeV9PZmZlck1pbnQnO1xuXG5mdW5jdGlvbiBidWlsZENhbnRvbkNvbW1hbmRSYXdUeChwcmVwYXJlUmVzcG9uc2U6IFBhcnRpYWw8Q2FudG9uUHJlcGFyZUNvbW1hbmRSZXNwb25zZT4sIGNvbW1hbmRJZDogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgZGF0YSA9IHtcbiAgICBwcmVwYXJlQ29tbWFuZFJlc3BvbnNlOiBwcmVwYXJlUmVzcG9uc2UsXG4gICAgdHhUeXBlOiAnQ2FudG9uQ29tbWFuZCcsXG4gICAgcHJlcGFyZWRUcmFuc2FjdGlvbjogJycsXG4gICAgcGFydHlTaWduYXR1cmVzOiB7IHNpZ25hdHVyZXM6IFtdIH0sXG4gICAgZGVkdXBsaWNhdGlvblBlcmlvZDogeyBFbXB0eToge30gfSxcbiAgICBzdWJtaXNzaW9uSWQ6IGNvbW1hbmRJZCxcbiAgICBoYXNoaW5nU2NoZW1lVmVyc2lvbjogJ0hBU0hJTkdfU0NIRU1FX1ZFUlNJT05fVjInLFxuICAgIG1pbkxlZGdlclRpbWU6IHsgdGltZTogeyBFbXB0eToge30gfSB9LFxuICB9O1xuICByZXR1cm4gQnVmZmVyLmZyb20oSlNPTi5zdHJpbmdpZnkoZGF0YSkpLnRvU3RyaW5nKCdiYXNlNjQnKTtcbn1cblxuZGVzY3JpYmUoJ0NhbnRvbiB2ZXJpZnlUcmFuc2FjdGlvbiAtIENhbnRvbkNvbW1hbmQ6JywgZnVuY3Rpb24gKCkge1xuICBsZXQgYml0Z286IFRlc3RCaXRHb0FQSTtcbiAgbGV0IGJhc2Vjb2luOiBDYW50b247XG5cbiAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHb0FQSSwgeyBlbnY6ICdtb2NrJyB9KTtcbiAgICBiaXRnby5zYWZlUmVnaXN0ZXIoJ2NhbnRvbicsIENhbnRvbi5jcmVhdGVJbnN0YW5jZSk7XG4gICAgYml0Z28uc2FmZVJlZ2lzdGVyKCd0Y2FudG9uJywgVGNhbnRvbi5jcmVhdGVJbnN0YW5jZSk7XG4gICAgYml0Z28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gICAgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0Y2FudG9uJykgYXMgQ2FudG9uO1xuICB9KTtcblxuICBkZXNjcmliZSgnSGFwcHkgcGF0aCB0ZXN0czonLCBmdW5jdGlvbiAoKSB7XG4gICAgbGV0IHR4SGV4OiBzdHJpbmc7XG5cbiAgICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgICAgdHhIZXggPSBidWlsZENhbnRvbkNvbW1hbmRSYXdUeChDYW50b25FeGVyY2lzZUNvbW1hbmRQcmVwYXJlUmVzcG9uc2UsICd0ZXN0LWNhbnRvbi1jbWQtMDAxJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIHdoZW4gY2FudG9uQ29tbWFuZFBhcmFtcyBpcyB1bmRlZmluZWQgKG5vIHVzZXIgcGFyYW1zIHRvIHZlcmlmeSknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UHJlYnVpbGQ6IHsgdHhIZXggfSxcbiAgICAgICAgdHhQYXJhbXM6IHt9LFxuICAgICAgICB3YWxsZXQ6IHt9IGFzIElXYWxsZXQsXG4gICAgICB9KTtcbiAgICAgIHJlc3VsdC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciBtYXRjaGluZyBFeGVyY2lzZUNvbW1hbmQgKHRlbXBsYXRlSWQsIGNob2ljZSwgY29udHJhY3RJZCwgYWN0QXMsIGFyZ3VtZW50KScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQcmVidWlsZDogeyB0eEhleCB9LFxuICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgIGNhbnRvbkNvbW1hbmRQYXJhbXM6IHtcbiAgICAgICAgICAgIGNvbW1hbmQ6IHtcbiAgICAgICAgICAgICAgRXhlcmNpc2VDb21tYW5kOiB7XG4gICAgICAgICAgICAgICAgdGVtcGxhdGVJZDogQ0FOVE9OX0NNRF9URU1QTEFURV9JRCxcbiAgICAgICAgICAgICAgICBjb250cmFjdElkOiBDQU5UT05fQ01EX0NPTlRSQUNUX0lELFxuICAgICAgICAgICAgICAgIGNob2ljZTogQ0FOVE9OX0NNRF9DSE9JQ0UsXG4gICAgICAgICAgICAgICAgY2hvaWNlQXJndW1lbnQ6IHtcbiAgICAgICAgICAgICAgICAgIGV4cGVjdGVkQWRtaW46IENBTlRPTl9DTURfQUNUX0FTLFxuICAgICAgICAgICAgICAgICAgbWludDoge1xuICAgICAgICAgICAgICAgICAgICBpbnN0cnVtZW50SWQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICBhZG1pbjogQ0FOVE9OX0NNRF9BQ1RfQVMsXG4gICAgICAgICAgICAgICAgICAgICAgaWQ6ICdURVNUVE9LRU4nLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBhbW91bnQ6ICcxMDAnLFxuICAgICAgICAgICAgICAgICAgICBob2xkZXI6ICdSZWdJc3N1ZXI6OjEyMjA1MDhlNTRmYjcwOWRjYjFhOWI0MDk2NDA4YWQ0MTVkMjIxN2Q4ODgxYWQ5MDM0YTk4NTA3NTI5MzNiYTg4YWQ1JyxcbiAgICAgICAgICAgICAgICAgICAgcmVmZXJlbmNlOiAndGVzdC1wcmVwYXJlLW1pbnQnLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFjdEFzOiBbQ0FOVE9OX0NNRF9BQ1RfQVNdLFxuICAgICAgICAgICAgcmVhZEFzOiBbXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9IGFzIENhbnRvblRyYW5zYWN0aW9uUGFyYW1zLFxuICAgICAgICB3YWxsZXQ6IHt9IGFzIElXYWxsZXQsXG4gICAgICB9KTtcbiAgICAgIHJlc3VsdC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIHdoZW4gY29udHJhY3RJZCBpcyBvbWl0dGVkIChJTVMtcmVzb2x2ZWQpJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFByZWJ1aWxkOiB7IHR4SGV4IH0sXG4gICAgICAgIHR4UGFyYW1zOiB7XG4gICAgICAgICAgY2FudG9uQ29tbWFuZFBhcmFtczoge1xuICAgICAgICAgICAgY29tbWFuZDoge1xuICAgICAgICAgICAgICBFeGVyY2lzZUNvbW1hbmQ6IHtcbiAgICAgICAgICAgICAgICB0ZW1wbGF0ZUlkOiBDQU5UT05fQ01EX1RFTVBMQVRFX0lELFxuICAgICAgICAgICAgICAgIGNob2ljZTogQ0FOVE9OX0NNRF9DSE9JQ0UsXG4gICAgICAgICAgICAgICAgY2hvaWNlQXJndW1lbnQ6IHt9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFjdEFzOiBbQ0FOVE9OX0NNRF9BQ1RfQVNdLFxuICAgICAgICAgICAgcmVhZEFzOiBbXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9IGFzIENhbnRvblRyYW5zYWN0aW9uUGFyYW1zLFxuICAgICAgICB3YWxsZXQ6IHt9IGFzIElXYWxsZXQsXG4gICAgICB9KTtcbiAgICAgIHJlc3VsdC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIHdpdGggcmVzb2x2ZUNvbnRyYWN0cyBpbmplY3RBcyBza2lwcGluZyBjb250cmFjdElkIChlbXB0eSBjb250cmFjdElkKScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQcmVidWlsZDogeyB0eEhleCB9LFxuICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgIGNhbnRvbkNvbW1hbmRQYXJhbXM6IHtcbiAgICAgICAgICAgIGNvbW1hbmQ6IHtcbiAgICAgICAgICAgICAgRXhlcmNpc2VDb21tYW5kOiB7XG4gICAgICAgICAgICAgICAgdGVtcGxhdGVJZDogQ0FOVE9OX0NNRF9URU1QTEFURV9JRCxcbiAgICAgICAgICAgICAgICBjb250cmFjdElkOiAnJyxcbiAgICAgICAgICAgICAgICBjaG9pY2U6IENBTlRPTl9DTURfQ0hPSUNFLFxuICAgICAgICAgICAgICAgIGNob2ljZUFyZ3VtZW50OiB7fSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBhY3RBczogW0NBTlRPTl9DTURfQUNUX0FTXSxcbiAgICAgICAgICAgIHJlYWRBczogW10sXG4gICAgICAgICAgICByZXNvbHZlQ29udHJhY3RzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0ZW1wbGF0ZUlkOiBDQU5UT05fQ01EX1RFTVBMQVRFX0lELFxuICAgICAgICAgICAgICAgIGFjdEFzOiBbQ0FOVE9OX0NNRF9BQ1RfQVNdLFxuICAgICAgICAgICAgICAgIGluamVjdEFzOiAnY29tbWFuZC5FeGVyY2lzZUNvbW1hbmQuY29udHJhY3RJZCcsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0gYXMgQ2FudG9uVHJhbnNhY3Rpb25QYXJhbXMsXG4gICAgICAgIHdhbGxldDoge30gYXMgSVdhbGxldCxcbiAgICAgIH0pO1xuICAgICAgcmVzdWx0LnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgd2l0aCByZXNvbHZlQ29udHJhY3RzIGluamVjdEFzIHNraXBwaW5nIG5vbi1lbXB0eSBjb250cmFjdElkIG1pc21hdGNoJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgLy8gVXNlciBzdXBwbGllcyBhIHBsYWNlaG9sZGVyIGNvbnRyYWN0SWQgdGhhdCBkb2Vzbid0IG1hdGNoIHdoYXQncyBvbi1jaGFpbjtcbiAgICAgIC8vIHJlc29sdmVDb250cmFjdHMgbWFya3MgaXQgYXMgSU1TLWluamVjdGVkLCBzbyB0aGUgbWlzbWF0Y2ggbXVzdCBiZSBpZ25vcmVkLlxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFByZWJ1aWxkOiB7IHR4SGV4IH0sXG4gICAgICAgIHR4UGFyYW1zOiB7XG4gICAgICAgICAgY2FudG9uQ29tbWFuZFBhcmFtczoge1xuICAgICAgICAgICAgY29tbWFuZDoge1xuICAgICAgICAgICAgICBFeGVyY2lzZUNvbW1hbmQ6IHtcbiAgICAgICAgICAgICAgICB0ZW1wbGF0ZUlkOiBDQU5UT05fQ01EX1RFTVBMQVRFX0lELFxuICAgICAgICAgICAgICAgIGNvbnRyYWN0SWQ6ICcwMHBsYWNlaG9sZGVyX2NvbnRyYWN0X2lkX25vdF9vbl9jaGFpbicsXG4gICAgICAgICAgICAgICAgY2hvaWNlOiBDQU5UT05fQ01EX0NIT0lDRSxcbiAgICAgICAgICAgICAgICBjaG9pY2VBcmd1bWVudDoge30sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYWN0QXM6IFtDQU5UT05fQ01EX0FDVF9BU10sXG4gICAgICAgICAgICByZWFkQXM6IFtdLFxuICAgICAgICAgICAgcmVzb2x2ZUNvbnRyYWN0czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdGVtcGxhdGVJZDogQ0FOVE9OX0NNRF9URU1QTEFURV9JRCxcbiAgICAgICAgICAgICAgICBhY3RBczogW0NBTlRPTl9DTURfQUNUX0FTXSxcbiAgICAgICAgICAgICAgICBpbmplY3RBczogJ2NvbW1hbmQuRXhlcmNpc2VDb21tYW5kLmNvbnRyYWN0SWQnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9IGFzIENhbnRvblRyYW5zYWN0aW9uUGFyYW1zLFxuICAgICAgICB3YWxsZXQ6IHt9IGFzIElXYWxsZXQsXG4gICAgICB9KTtcbiAgICAgIHJlc3VsdC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdFcnJvciBjYXNlczonLCBmdW5jdGlvbiAoKSB7XG4gICAgbGV0IHR4SGV4OiBzdHJpbmc7XG5cbiAgICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgICAgdHhIZXggPSBidWlsZENhbnRvbkNvbW1hbmRSYXdUeChDYW50b25FeGVyY2lzZUNvbW1hbmRQcmVwYXJlUmVzcG9uc2UsICd0ZXN0LWNhbnRvbi1jbWQtMDAyJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IHdoZW4gcHJlcGFyZWRUcmFuc2FjdGlvbiBpcyBtaXNzaW5nIG9uIHR4IHByZWJ1aWxkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZW1wdHlQcmVwYXJlID0geyAuLi5DYW50b25FeGVyY2lzZUNvbW1hbmRQcmVwYXJlUmVzcG9uc2UsIHByZXBhcmVkVHJhbnNhY3Rpb246IHVuZGVmaW5lZCB9O1xuICAgICAgY29uc3QgYmFkVHggPSBidWlsZENhbnRvbkNvbW1hbmRSYXdUeChlbXB0eVByZXBhcmUsICdjbWQtYmFkJyk7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UHJlYnVpbGQ6IHsgdHhIZXg6IGJhZFR4IH0sXG4gICAgICAgICAgdHhQYXJhbXM6IHtcbiAgICAgICAgICAgIGNhbnRvbkNvbW1hbmRQYXJhbXM6IHtcbiAgICAgICAgICAgICAgY29tbWFuZDoge1xuICAgICAgICAgICAgICAgIEV4ZXJjaXNlQ29tbWFuZDogeyB0ZW1wbGF0ZUlkOiBDQU5UT05fQ01EX1RFTVBMQVRFX0lELCBjaG9pY2U6IENBTlRPTl9DTURfQ0hPSUNFLCBjaG9pY2VBcmd1bWVudDoge30gfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgYWN0QXM6IFtDQU5UT05fQ01EX0FDVF9BU10sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0gYXMgQ2FudG9uVHJhbnNhY3Rpb25QYXJhbXMsXG4gICAgICAgICAgd2FsbGV0OiB7fSBhcyBJV2FsbGV0LFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvbWlzc2luZyBwcmVwYXJlZFRyYW5zYWN0aW9uLyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IHdoZW4gdXNlciBjb21tYW5kIGhhcyBuZWl0aGVyIENyZWF0ZUNvbW1hbmQgbm9yIEV4ZXJjaXNlQ29tbWFuZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhQcmVidWlsZDogeyB0eEhleCB9LFxuICAgICAgICAgIHR4UGFyYW1zOiB7XG4gICAgICAgICAgICBjYW50b25Db21tYW5kUGFyYW1zOiB7XG4gICAgICAgICAgICAgIGNvbW1hbmQ6IHsgVW5rbm93bkNvbW1hbmQ6IHt9IH0gYXMgdW5rbm93biBhcyBDYW50b25Db21tYW5kLFxuICAgICAgICAgICAgICBhY3RBczogW0NBTlRPTl9DTURfQUNUX0FTXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSBhcyBDYW50b25UcmFuc2FjdGlvblBhcmFtcyxcbiAgICAgICAgICB3YWxsZXQ6IHt9IGFzIElXYWxsZXQsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKC9tdXN0IGNvbnRhaW4gYSBDcmVhdGVDb21tYW5kIG9yIEV4ZXJjaXNlQ29tbWFuZC8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyB3aGVuIHVzZXIgY29tbWFuZCBjb250YWlucyBib3RoIENyZWF0ZUNvbW1hbmQgYW5kIEV4ZXJjaXNlQ29tbWFuZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhQcmVidWlsZDogeyB0eEhleCB9LFxuICAgICAgICAgIHR4UGFyYW1zOiB7XG4gICAgICAgICAgICBjYW50b25Db21tYW5kUGFyYW1zOiB7XG4gICAgICAgICAgICAgIGNvbW1hbmQ6IHtcbiAgICAgICAgICAgICAgICBDcmVhdGVDb21tYW5kOiB7IHRlbXBsYXRlSWQ6IENBTlRPTl9DTURfVEVNUExBVEVfSUQsIGNyZWF0ZUFyZ3VtZW50czoge30gfSxcbiAgICAgICAgICAgICAgICBFeGVyY2lzZUNvbW1hbmQ6IHsgdGVtcGxhdGVJZDogQ0FOVE9OX0NNRF9URU1QTEFURV9JRCwgY2hvaWNlOiBDQU5UT05fQ01EX0NIT0lDRSwgY2hvaWNlQXJndW1lbnQ6IHt9IH0sXG4gICAgICAgICAgICAgIH0gYXMgdW5rbm93biBhcyBDYW50b25Db21tYW5kLFxuICAgICAgICAgICAgICBhY3RBczogW0NBTlRPTl9DTURfQUNUX0FTXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSBhcyBDYW50b25UcmFuc2FjdGlvblBhcmFtcyxcbiAgICAgICAgICB3YWxsZXQ6IHt9IGFzIElXYWxsZXQsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKC9leGFjdGx5IG9uZSBvZiBDcmVhdGVDb21tYW5kIG9yIEV4ZXJjaXNlQ29tbWFuZC8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBvbiBpbnZhbGlkIHVzZXIgdGVtcGxhdGVJZCBmb3JtYXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UHJlYnVpbGQ6IHsgdHhIZXggfSxcbiAgICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgICAgY2FudG9uQ29tbWFuZFBhcmFtczoge1xuICAgICAgICAgICAgICBjb21tYW5kOiB7XG4gICAgICAgICAgICAgICAgRXhlcmNpc2VDb21tYW5kOiB7XG4gICAgICAgICAgICAgICAgICB0ZW1wbGF0ZUlkOiAnSW52YWxpZEZvcm1hdCcsXG4gICAgICAgICAgICAgICAgICBjaG9pY2U6IENBTlRPTl9DTURfQ0hPSUNFLFxuICAgICAgICAgICAgICAgICAgY2hvaWNlQXJndW1lbnQ6IHt9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIGFjdEFzOiBbQ0FOVE9OX0NNRF9BQ1RfQVNdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9IGFzIENhbnRvblRyYW5zYWN0aW9uUGFyYW1zLFxuICAgICAgICAgIHdhbGxldDoge30gYXMgSVdhbGxldCxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoL2ludmFsaWQgdXNlciB0ZW1wbGF0ZUlkLyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IG9uIHRlbXBsYXRlSWQgbW9kdWxlL2VudGl0eSBtaXNtYXRjaCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhQcmVidWlsZDogeyB0eEhleCB9LFxuICAgICAgICAgIHR4UGFyYW1zOiB7XG4gICAgICAgICAgICBjYW50b25Db21tYW5kUGFyYW1zOiB7XG4gICAgICAgICAgICAgIGNvbW1hbmQ6IHtcbiAgICAgICAgICAgICAgICBFeGVyY2lzZUNvbW1hbmQ6IHtcbiAgICAgICAgICAgICAgICAgIHRlbXBsYXRlSWQ6ICdTb21lUGtnOldyb25nLk1vZHVsZTpXcm9uZ0VudGl0eScsXG4gICAgICAgICAgICAgICAgICBjaG9pY2U6IENBTlRPTl9DTURfQ0hPSUNFLFxuICAgICAgICAgICAgICAgICAgY2hvaWNlQXJndW1lbnQ6IHt9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIGFjdEFzOiBbQ0FOVE9OX0NNRF9BQ1RfQVNdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9IGFzIENhbnRvblRyYW5zYWN0aW9uUGFyYW1zLFxuICAgICAgICAgIHdhbGxldDoge30gYXMgSVdhbGxldCxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoL3RlbXBsYXRlSWQgbWlzbWF0Y2gvKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgb24gc3VibWl0dGVySW5mby5hY3RBcyBtaXNtYXRjaCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhQcmVidWlsZDogeyB0eEhleCB9LFxuICAgICAgICAgIHR4UGFyYW1zOiB7XG4gICAgICAgICAgICBjYW50b25Db21tYW5kUGFyYW1zOiB7XG4gICAgICAgICAgICAgIGNvbW1hbmQ6IHtcbiAgICAgICAgICAgICAgICBFeGVyY2lzZUNvbW1hbmQ6IHtcbiAgICAgICAgICAgICAgICAgIHRlbXBsYXRlSWQ6IENBTlRPTl9DTURfVEVNUExBVEVfSUQsXG4gICAgICAgICAgICAgICAgICBjaG9pY2U6IENBTlRPTl9DTURfQ0hPSUNFLFxuICAgICAgICAgICAgICAgICAgY2hvaWNlQXJndW1lbnQ6IHt9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIGFjdEFzOiBbJ1dyb25nUGFydHk6OjEyMjBhYWFhJ10sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0gYXMgQ2FudG9uVHJhbnNhY3Rpb25QYXJhbXMsXG4gICAgICAgICAgd2FsbGV0OiB7fSBhcyBJV2FsbGV0LFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvc3VibWl0dGVySW5mby5hY3RBcy4qZG9lcyBub3QgbWF0Y2ggdXNlciBhY3RBcy8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBvbiBjaG9pY2UgbWlzbWF0Y2ggZm9yIEV4ZXJjaXNlQ29tbWFuZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhQcmVidWlsZDogeyB0eEhleCB9LFxuICAgICAgICAgIHR4UGFyYW1zOiB7XG4gICAgICAgICAgICBjYW50b25Db21tYW5kUGFyYW1zOiB7XG4gICAgICAgICAgICAgIGNvbW1hbmQ6IHtcbiAgICAgICAgICAgICAgICBFeGVyY2lzZUNvbW1hbmQ6IHtcbiAgICAgICAgICAgICAgICAgIHRlbXBsYXRlSWQ6IENBTlRPTl9DTURfVEVNUExBVEVfSUQsXG4gICAgICAgICAgICAgICAgICBjaG9pY2U6ICdXcm9uZ0Nob2ljZScsXG4gICAgICAgICAgICAgICAgICBjaG9pY2VBcmd1bWVudDoge30sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgYWN0QXM6IFtDQU5UT05fQ01EX0FDVF9BU10sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0gYXMgQ2FudG9uVHJhbnNhY3Rpb25QYXJhbXMsXG4gICAgICAgICAgd2FsbGV0OiB7fSBhcyBJV2FsbGV0LFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvY2hvaWNlIG1pc21hdGNoLyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IG9uIGNvbnRyYWN0SWQgbWlzbWF0Y2ggd2hlbiB1c2VyIHByb3ZpZGVzIGV4cGxpY2l0IGNvbnRyYWN0SWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UHJlYnVpbGQ6IHsgdHhIZXggfSxcbiAgICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgICAgY2FudG9uQ29tbWFuZFBhcmFtczoge1xuICAgICAgICAgICAgICBjb21tYW5kOiB7XG4gICAgICAgICAgICAgICAgRXhlcmNpc2VDb21tYW5kOiB7XG4gICAgICAgICAgICAgICAgICB0ZW1wbGF0ZUlkOiBDQU5UT05fQ01EX1RFTVBMQVRFX0lELFxuICAgICAgICAgICAgICAgICAgY29udHJhY3RJZDogJzAwd3Jvbmdjb250cmFjdGlkJyxcbiAgICAgICAgICAgICAgICAgIGNob2ljZTogQ0FOVE9OX0NNRF9DSE9JQ0UsXG4gICAgICAgICAgICAgICAgICBjaG9pY2VBcmd1bWVudDoge30sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgYWN0QXM6IFtDQU5UT05fQ01EX0FDVF9BU10sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0gYXMgQ2FudG9uVHJhbnNhY3Rpb25QYXJhbXMsXG4gICAgICAgICAgd2FsbGV0OiB7fSBhcyBJV2FsbGV0LFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvY29udHJhY3RJZCBtaXNtYXRjaC8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBvbiBhcmd1bWVudCBkZWVwIG1pc21hdGNoJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0eFByZWJ1aWxkOiB7IHR4SGV4IH0sXG4gICAgICAgICAgdHhQYXJhbXM6IHtcbiAgICAgICAgICAgIGNhbnRvbkNvbW1hbmRQYXJhbXM6IHtcbiAgICAgICAgICAgICAgY29tbWFuZDoge1xuICAgICAgICAgICAgICAgIEV4ZXJjaXNlQ29tbWFuZDoge1xuICAgICAgICAgICAgICAgICAgdGVtcGxhdGVJZDogQ0FOVE9OX0NNRF9URU1QTEFURV9JRCxcbiAgICAgICAgICAgICAgICAgIGNob2ljZTogQ0FOVE9OX0NNRF9DSE9JQ0UsXG4gICAgICAgICAgICAgICAgICBjaG9pY2VBcmd1bWVudDoge1xuICAgICAgICAgICAgICAgICAgICBleHBlY3RlZEFkbWluOiAnV3JvbmdQYXJ0eTo6dG90YWxseS1kaWZmZXJlbnQnLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBhY3RBczogW0NBTlRPTl9DTURfQUNUX0FTXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSBhcyBDYW50b25UcmFuc2FjdGlvblBhcmFtcyxcbiAgICAgICAgICB3YWxsZXQ6IHt9IGFzIElXYWxsZXQsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKC9taXNtYXRjaC8pO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuXG4vLyAtLS0tLS0tLS0tLS0tLS0gQ3JlYXRlQ29tbWFuZCB2ZXJpZmljYXRpb24gdGVzdHMgLS0tLS0tLS0tLS0tLS0tXG5cbmNvbnN0IENSRUFURV9DTURfQUNUX0FTID0gJ1JlZ1Byb3ZpZGVyOjoxMjIwNTA4ZTU0ZmI3MDlkY2IxYTliNDA5NjQwOGFkNDE1ZDIyMTdkODg4MWFkOTAzNGE5ODUwNzUyOTMzYmE4OGFkNSc7XG5jb25zdCBDUkVBVEVfQ01EX1RFTVBMQVRFX0lEID1cbiAgJzdhNzVlZjZlNjlmNjkzOTVhNGU2MDkxOWUyMjg1MjhiYjhmMzg4MTE1MGNjZmRlM2YzMWJjYzczODY0YjE4YWI6VXRpbGl0eS5SZWdpc3RyeS5BcHAuVjAuU2VydmljZS5Qcm92aWRlcjpQcm92aWRlclNlcnZpY2VSZXF1ZXN0JztcbmNvbnN0IENSRUFURV9DTURfT1BFUkFUT1IgPSAnUmVnT3BlcmF0b3I6OjEyMjA1MDhlNTRmYjcwOWRjYjFhOWI0MDk2NDA4YWQ0MTVkMjIxN2Q4ODgxYWQ5MDM0YTk4NTA3NTI5MzNiYTg4YWQ1JztcblxuZGVzY3JpYmUoJ0NhbnRvbiB2ZXJpZnlUcmFuc2FjdGlvbiAtIENyZWF0ZUNvbW1hbmQ6JywgZnVuY3Rpb24gKCkge1xuICBsZXQgYml0Z286IFRlc3RCaXRHb0FQSTtcbiAgbGV0IGJhc2Vjb2luOiBDYW50b247XG5cbiAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHb0FQSSwgeyBlbnY6ICdtb2NrJyB9KTtcbiAgICBiaXRnby5zYWZlUmVnaXN0ZXIoJ2NhbnRvbicsIENhbnRvbi5jcmVhdGVJbnN0YW5jZSk7XG4gICAgYml0Z28uc2FmZVJlZ2lzdGVyKCd0Y2FudG9uJywgVGNhbnRvbi5jcmVhdGVJbnN0YW5jZSk7XG4gICAgYml0Z28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gICAgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0Y2FudG9uJykgYXMgQ2FudG9uO1xuICB9KTtcblxuICBkZXNjcmliZSgnSGFwcHkgcGF0aCB0ZXN0czonLCBmdW5jdGlvbiAoKSB7XG4gICAgbGV0IHR4SGV4OiBzdHJpbmc7XG5cbiAgICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgICAgdHhIZXggPSBidWlsZENhbnRvbkNvbW1hbmRSYXdUeChDYW50b25DcmVhdGVDb21tYW5kUHJlcGFyZVJlc3BvbnNlLCAndGVzdC1jcmVhdGUtY21kLTAwMScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgbWF0Y2hpbmcgQ3JlYXRlQ29tbWFuZCAodGVtcGxhdGVJZCwgY3JlYXRlQXJndW1lbnRzLCBhY3RBcyknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UHJlYnVpbGQ6IHsgdHhIZXggfSxcbiAgICAgICAgdHhQYXJhbXM6IHtcbiAgICAgICAgICBjYW50b25Db21tYW5kUGFyYW1zOiB7XG4gICAgICAgICAgICBjb21tYW5kOiB7XG4gICAgICAgICAgICAgIENyZWF0ZUNvbW1hbmQ6IHtcbiAgICAgICAgICAgICAgICB0ZW1wbGF0ZUlkOiBDUkVBVEVfQ01EX1RFTVBMQVRFX0lELFxuICAgICAgICAgICAgICAgIGNyZWF0ZUFyZ3VtZW50czoge1xuICAgICAgICAgICAgICAgICAgb3BlcmF0b3I6IENSRUFURV9DTURfT1BFUkFUT1IsXG4gICAgICAgICAgICAgICAgICBwcm92aWRlcjogQ1JFQVRFX0NNRF9BQ1RfQVMsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBhY3RBczogW0NSRUFURV9DTURfQUNUX0FTXSxcbiAgICAgICAgICAgIHJlYWRBczogW10sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSBhcyBDYW50b25UcmFuc2FjdGlvblBhcmFtcyxcbiAgICAgICAgd2FsbGV0OiB7fSBhcyBJV2FsbGV0LFxuICAgICAgfSk7XG4gICAgICByZXN1bHQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSB3aGVuIGNyZWF0ZUFyZ3VtZW50cyBpcyBlbXB0eSAobm8gZGVlcC1jb21wYXJlKScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQcmVidWlsZDogeyB0eEhleCB9LFxuICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgIGNhbnRvbkNvbW1hbmRQYXJhbXM6IHtcbiAgICAgICAgICAgIGNvbW1hbmQ6IHtcbiAgICAgICAgICAgICAgQ3JlYXRlQ29tbWFuZDoge1xuICAgICAgICAgICAgICAgIHRlbXBsYXRlSWQ6IENSRUFURV9DTURfVEVNUExBVEVfSUQsXG4gICAgICAgICAgICAgICAgY3JlYXRlQXJndW1lbnRzOiB7fSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBhY3RBczogW0NSRUFURV9DTURfQUNUX0FTXSxcbiAgICAgICAgICAgIHJlYWRBczogW10sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSBhcyBDYW50b25UcmFuc2FjdGlvblBhcmFtcyxcbiAgICAgICAgd2FsbGV0OiB7fSBhcyBJV2FsbGV0LFxuICAgICAgfSk7XG4gICAgICByZXN1bHQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSB3aXRoIHJlc29sdmVDb250cmFjdHMgaW5qZWN0QXMgc2tpcHBpbmcgY3JlYXRlQXJndW1lbnRzIGZpZWxkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFByZWJ1aWxkOiB7IHR4SGV4IH0sXG4gICAgICAgIHR4UGFyYW1zOiB7XG4gICAgICAgICAgY2FudG9uQ29tbWFuZFBhcmFtczoge1xuICAgICAgICAgICAgY29tbWFuZDoge1xuICAgICAgICAgICAgICBDcmVhdGVDb21tYW5kOiB7XG4gICAgICAgICAgICAgICAgdGVtcGxhdGVJZDogQ1JFQVRFX0NNRF9URU1QTEFURV9JRCxcbiAgICAgICAgICAgICAgICBjcmVhdGVBcmd1bWVudHM6IHtcbiAgICAgICAgICAgICAgICAgIG9wZXJhdG9yOiAncGxhY2Vob2xkZXItb3BlcmF0b3ItaWQnLFxuICAgICAgICAgICAgICAgICAgcHJvdmlkZXI6IENSRUFURV9DTURfQUNUX0FTLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYWN0QXM6IFtDUkVBVEVfQ01EX0FDVF9BU10sXG4gICAgICAgICAgICByZWFkQXM6IFtdLFxuICAgICAgICAgICAgcmVzb2x2ZUNvbnRyYWN0czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdGVtcGxhdGVJZDogJ3NvbWUtdGVtcGxhdGUnLFxuICAgICAgICAgICAgICAgIGFjdEFzOiBbQ1JFQVRFX0NNRF9BQ1RfQVNdLFxuICAgICAgICAgICAgICAgIGluamVjdEFzOiAnY29tbWFuZC5DcmVhdGVDb21tYW5kLmNyZWF0ZUFyZ3VtZW50cy5vcGVyYXRvcicsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0gYXMgQ2FudG9uVHJhbnNhY3Rpb25QYXJhbXMsXG4gICAgICAgIHdhbGxldDoge30gYXMgSVdhbGxldCxcbiAgICAgIH0pO1xuICAgICAgcmVzdWx0LnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0Vycm9yIGNhc2VzOicsIGZ1bmN0aW9uICgpIHtcbiAgICBsZXQgdHhIZXg6IHN0cmluZztcblxuICAgIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgICB0eEhleCA9IGJ1aWxkQ2FudG9uQ29tbWFuZFJhd1R4KENhbnRvbkNyZWF0ZUNvbW1hbmRQcmVwYXJlUmVzcG9uc2UsICd0ZXN0LWNyZWF0ZS1jbWQtZXJyJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IG9uIHRlbXBsYXRlSWQgbWlzbWF0Y2ggZm9yIENyZWF0ZUNvbW1hbmQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UHJlYnVpbGQ6IHsgdHhIZXggfSxcbiAgICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgICAgY2FudG9uQ29tbWFuZFBhcmFtczoge1xuICAgICAgICAgICAgICBjb21tYW5kOiB7XG4gICAgICAgICAgICAgICAgQ3JlYXRlQ29tbWFuZDoge1xuICAgICAgICAgICAgICAgICAgdGVtcGxhdGVJZDogJ1dyb25nUGtnOldyb25nLk1vZHVsZTpXcm9uZ0VudGl0eScsXG4gICAgICAgICAgICAgICAgICBjcmVhdGVBcmd1bWVudHM6IHt9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIGFjdEFzOiBbQ1JFQVRFX0NNRF9BQ1RfQVNdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9IGFzIENhbnRvblRyYW5zYWN0aW9uUGFyYW1zLFxuICAgICAgICAgIHdhbGxldDoge30gYXMgSVdhbGxldCxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoL3RlbXBsYXRlSWQgbWlzbWF0Y2gvKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgb24gY3JlYXRlQXJndW1lbnRzIGRlZXAgbWlzbWF0Y2gnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UHJlYnVpbGQ6IHsgdHhIZXggfSxcbiAgICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgICAgY2FudG9uQ29tbWFuZFBhcmFtczoge1xuICAgICAgICAgICAgICBjb21tYW5kOiB7XG4gICAgICAgICAgICAgICAgQ3JlYXRlQ29tbWFuZDoge1xuICAgICAgICAgICAgICAgICAgdGVtcGxhdGVJZDogQ1JFQVRFX0NNRF9URU1QTEFURV9JRCxcbiAgICAgICAgICAgICAgICAgIGNyZWF0ZUFyZ3VtZW50czoge1xuICAgICAgICAgICAgICAgICAgICBvcGVyYXRvcjogJ1dyb25nT3BlcmF0b3I6OnRvdGFsbHktZGlmZmVyZW50JyxcbiAgICAgICAgICAgICAgICAgICAgcHJvdmlkZXI6IENSRUFURV9DTURfQUNUX0FTLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBhY3RBczogW0NSRUFURV9DTURfQUNUX0FTXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSBhcyBDYW50b25UcmFuc2FjdGlvblBhcmFtcyxcbiAgICAgICAgICB3YWxsZXQ6IHt9IGFzIElXYWxsZXQsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKC9taXNtYXRjaC8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBvbiBhY3RBcyBtaXNtYXRjaCBmb3IgQ3JlYXRlQ29tbWFuZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhQcmVidWlsZDogeyB0eEhleCB9LFxuICAgICAgICAgIHR4UGFyYW1zOiB7XG4gICAgICAgICAgICBjYW50b25Db21tYW5kUGFyYW1zOiB7XG4gICAgICAgICAgICAgIGNvbW1hbmQ6IHtcbiAgICAgICAgICAgICAgICBDcmVhdGVDb21tYW5kOiB7XG4gICAgICAgICAgICAgICAgICB0ZW1wbGF0ZUlkOiBDUkVBVEVfQ01EX1RFTVBMQVRFX0lELFxuICAgICAgICAgICAgICAgICAgY3JlYXRlQXJndW1lbnRzOiB7fSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBhY3RBczogWydXcm9uZ1BhcnR5OjoxMjIwYWFhYSddLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9IGFzIENhbnRvblRyYW5zYWN0aW9uUGFyYW1zLFxuICAgICAgICAgIHdhbGxldDoge30gYXMgSVdhbGxldCxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoL3N1Ym1pdHRlckluZm8uYWN0QXMuKmRvZXMgbm90IG1hdGNoIHVzZXIgYWN0QXMvKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==
|