UNPKG

bitgo

Version:
238 lines • 39.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const nock = require("nock"); const should = require("should"); const goStakingWallet_1 = require("../../fixtures/staking/goStakingWallet"); const sdk_core_1 = require("@bitgo/sdk-core"); const sdk_test_1 = require("@bitgo/sdk-test"); const src_1 = require("../../../../src"); const sinon = require("sinon"); const coins_1 = require("../../../../src/v2/coins"); const statics_1 = require("@bitgo/statics"); describe('Go Staking Wallet Common', function () { const microservicesUri = sdk_core_1.Environments['mock'].uri; let bitgo; let baseCoin; let enterprise; let stakingWallet; const coin = 'tsol'; const ofcCoin = `ofc${coin}`; before(async function () { bitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock', microservicesUri }); bitgo.initializeTestVars(); baseCoin = bitgo.coin(ofcCoin); baseCoin.keychains(); const ofcToken = statics_1.tokens.testnet.ofc.tokens.filter((token) => token.type === `ofc${coin}`)[0]; const tokenConstructor = coins_1.OfcToken.createTokenConstructor(ofcToken); bitgo.register(ofcToken.type, tokenConstructor); enterprise = new sdk_core_1.Enterprise(bitgo, baseCoin, { id: '5cf940949449412d00f53b3d92dbcaa3', name: 'Test Enterprise' }); const walletData = { id: 'walletId', coin: ofcCoin, enterprise: enterprise.id, keys: ['5b3424f91bf349930e340175', '5b3424f91bf349930e340174', '5b3424f91bf349930e340173'], }; const wallet = new sdk_core_1.Wallet(bitgo, baseCoin, walletData); stakingWallet = wallet.toGoStakingWallet(); const encryptedStakingPrv = await bitgo.encrypt({ input: 'xprvA41z7zogVVwxVSgdKUHDy1SKmdb533PjDz7J6N6mV6uS3ze1ai8FHa8kmHScGpWmj4WggLyQjgPie1rFSruoUihUZREPSL39UNdE3BBDu76', password: 'passphrase', }); nock(microservicesUri).get(`/api/v2/${ofcCoin}/key/${stakingWallet.wallet.keyIds()[0]}`).reply(200, { id: stakingWallet.wallet.keyIds()[0], pub: 'xpub661MyMwAqRbcFq65dvGMeEVb81KKDRRkWkawSVesWcyevGc5gr8V27LjNfkktaMuKtM362jhgKy2eu35RdArcmmEAoULzAvgKkJpWQPvLXM', source: 'user', encryptedPrv: encryptedStakingPrv, coinSpecific: {}, }); nock(microservicesUri).get(`/api/v2/${ofcCoin}/key/${stakingWallet.wallet.keyIds()[1]}`).reply(200, { id: stakingWallet.wallet.keyIds()[1], pub: 'xpub661MyMwAqRbcFq65dvGMeEVb81KKDRRkWkawSVesWcyevGc5gr8V27LjNfkktaMuKtM362jhgKy2eu35RdArcmmEAoULzAvgKkJpWQPvLXM', source: 'user', encryptedPrv: encryptedStakingPrv, coinSpecific: {}, }); nock(microservicesUri).get(`/api/v2/${ofcCoin}/key/${stakingWallet.wallet.keyIds()[2]}`).reply(200, { id: stakingWallet.wallet.keyIds()[2], pub: 'xpub661MyMwAqRbcFq65dvGMeEVb81KKDRRkWkawSVesWcyevGc5gr8V27LjNfkktaMuKtM362jhgKy2eu35RdArcmmEAoULzAvgKkJpWQPvLXM', source: 'user', encryptedPrv: encryptedStakingPrv, coinSpecific: {}, }); }); const sandbox = sinon.createSandbox(); afterEach(function () { sandbox.verifyAndRestore(); }); describe('stake', function () { it('should call go-staking-service to stake', async function () { const preview = goStakingWallet_1.default.previewGoStakingRequest(coin); const msScope1 = nock(microservicesUri) .post(`/api/go-staking/v1/${ofcCoin}/accounts/${stakingWallet.accountId}/requests/preview`, { amount: '1', clientId: 'clientId', type: 'STAKE', }) .reply(201, preview); const expected = goStakingWallet_1.default.finalizeGoStakingRequest(coin, 'STAKE'); const msScope2 = nock(microservicesUri) .post(`/api/go-staking/v1/${ofcCoin}/accounts/${stakingWallet.accountId}/requests/finalize`, { amount: '1', clientId: 'clientId', frontTransferSendRequest: { halfSigned: { payload: preview.payload, signature: '1f4f7e789ef485363b33dca7273717a4a4413330f2badbcaf302758bc404ff8e930943db81aa2c77007738afa23166934c2a3136bae281bea037095be7183c0602', }, }, type: 'STAKE', }) .reply(201, expected); const stakingRequest = await stakingWallet.stake({ amount: '1', clientId: 'clientId', walletPassphrase: 'passphrase', }); should.exist(stakingRequest); stakingRequest.should.deepEqual(expected); msScope1.isDone().should.be.True(); msScope2.isDone().should.be.True(); }); it('should stake without a wallet passphrase for an OFC wallet that signs remotely (userKeySigningRequired === false)', async function () { // OFC wallet signs remotely via the BitGo key instead of decrypting the user key locally. const remoteWallet = new sdk_core_1.Wallet(bitgo, baseCoin, { id: 'remoteWalletId', coin: ofcCoin, enterprise: enterprise.id, keys: ['5b3424f91bf349930e340175', '5b3424f91bf349930e340174', '5b3424f91bf349930e340173'], coinSpecific: { userKeySigningRequired: false }, }); const remoteStakingWallet = remoteWallet.toGoStakingWallet(); // prebuildAndSignTransaction still fetches the user keychain (index 0), but with no passphrase // the decrypt check is skipped and the key is never used to sign. nock(microservicesUri).get(`/api/v2/${ofcCoin}/key/${remoteStakingWallet.wallet.keyIds()[0]}`).reply(200, { id: remoteStakingWallet.wallet.keyIds()[0], pub: 'xpub661MyMwAqRbcFq65dvGMeEVb81KKDRRkWkawSVesWcyevGc5gr8V27LjNfkktaMuKtM362jhgKy2eu35RdArcmmEAoULzAvgKkJpWQPvLXM', source: 'user', coinSpecific: {}, }); const preview = goStakingWallet_1.default.previewGoStakingRequest(coin); const msScope1 = nock(microservicesUri) .post(`/api/go-staking/v1/${ofcCoin}/accounts/${remoteStakingWallet.accountId}/requests/preview`, { amount: '1', clientId: 'clientId', type: 'STAKE', }) .reply(201, preview); // remote signing: the BitGo key signs the payload and returns the signature const signature = '1f4f7e789ef485363b33dca7273717a4a4413330f2badbcaf302758bc404ff8e930943db81aa2c77007738afa23166934c2a3136bae281bea037095be7183c0602'; const signScope = nock(microservicesUri) .post(`/api/v2/ofc/wallet/${remoteWallet.id()}/tx/sign`, { payload: preview.payload }) .reply(200, { signature }); const expected = goStakingWallet_1.default.finalizeGoStakingRequest(coin, 'STAKE'); const msScope2 = nock(microservicesUri) .post(`/api/go-staking/v1/${ofcCoin}/accounts/${remoteStakingWallet.accountId}/requests/finalize`, { amount: '1', clientId: 'clientId', frontTransferSendRequest: { halfSigned: { payload: preview.payload, signature, }, }, type: 'STAKE', }) .reply(201, expected); const stakingRequest = await remoteStakingWallet.stake({ amount: '1', clientId: 'clientId', }); should.exist(stakingRequest); stakingRequest.should.deepEqual(expected); msScope1.isDone().should.be.True(); signScope.isDone().should.be.True(); msScope2.isDone().should.be.True(); }); }); describe('unstake', function () { it('should call go-staking-service to unstake', async function () { const expected = goStakingWallet_1.default.finalizeGoStakingRequest(coin, 'UNSTAKE'); const msScope = nock(microservicesUri) .post(`/api/go-staking/v1/${ofcCoin}/accounts/${stakingWallet.accountId}/requests/finalize`, { amount: '1', clientId: 'clientId', type: 'UNSTAKE', }) .reply(201, expected); const stakingRequest = await stakingWallet.unstake({ amount: '1', clientId: 'clientId', }); should.exist(stakingRequest); stakingRequest.should.deepEqual(expected); msScope.isDone().should.be.True(); }); }); describe('getGoStakingRequest', function () { it('should call go-staking-service to get go staking request', async function () { const stakingRequestId = '8638284a-dab2-46b9-b07f-21109a6e7220'; const expected = goStakingWallet_1.default.finalizeGoStakingRequest(coin, 'STAKE'); const msScope = nock(microservicesUri) .get(`/api/go-staking/v1/${ofcCoin}/accounts/${stakingWallet.accountId}/requests/${stakingRequestId}`) .reply(200, expected); const stakingRequest = await stakingWallet.getGoStakingRequest(stakingRequestId); should.exist(stakingRequest); stakingRequest.should.deepEqual(expected); msScope.isDone().should.be.True(); }); }); describe('getGoStakingRequestsByCoin', function () { it('should call go-staking-service to get go staking requests by coin', async function () { const expected = goStakingWallet_1.default.getGoStakingRequestsByCoin(ofcCoin); const msScope = nock(microservicesUri) .get(`/api/go-staking/v1/${ofcCoin}/accounts/${stakingWallet.accountId}/requests`) .reply(200, expected); const stakingRequests = await stakingWallet.getGoStakingRequestsByWalletCoin(); should.exist(stakingRequests); stakingRequests.should.deepEqual(expected); msScope.isDone().should.be.True(); }); }); describe('getGoStakingRequests', function () { it('should call go-staking-service to get go staking requests', async function () { const expected = goStakingWallet_1.default.getGoStakingRequests([ofcCoin]); const msScope = nock(microservicesUri) .get(`/api/go-staking/v1/accounts/${stakingWallet.accountId}/requests`) .reply(200, expected); const stakingRequests = await stakingWallet.getGoStakingRequests(); should.exist(stakingRequests); stakingRequests.should.deepEqual(expected); msScope.isDone().should.be.True(); }); }); describe('getGoStakingWallets', function () { it('should call go-staking-service to get go staking wallets', async function () { const expected = goStakingWallet_1.default.getGoStakingWallets([ofcCoin]); const msScope = nock(microservicesUri) .get(`/api/go-staking/v1/accounts/${stakingWallet.accountId}/coins`) .reply(200, expected); const goStakingWallets = await stakingWallet.getGoStakingWallets(); should.exist(goStakingWallets); goStakingWallets.should.deepEqual(expected); msScope.isDone().should.be.True(); }); }); describe('getGoStakingWallet', function () { it('should call go-staking-service to get go staking wallet', async function () { const expected = goStakingWallet_1.default.getGoStakingWallet(ofcCoin); const msScope = nock(microservicesUri) .get(`/api/go-staking/v1/${ofcCoin}/accounts/${stakingWallet.accountId}/coins`) .reply(200, expected); const goStakingWallet = await stakingWallet.getGoStakingWallet(); should.exist(goStakingWallet); goStakingWallet.should.deepEqual(expected); msScope.isDone().should.be.True(); }); }); }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ29TdGFraW5nV2FsbGV0Q29tbW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vdGVzdC92Mi91bml0L3N0YWtpbmcvZ29TdGFraW5nV2FsbGV0Q29tbW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsNkJBQThCO0FBQzlCLGlDQUFrQztBQUNsQyw0RUFBOEQ7QUFFOUQsOENBQW9GO0FBQ3BGLDhDQUE0QztBQUM1Qyx5Q0FBd0M7QUFDeEMsK0JBQStCO0FBQy9CLG9EQUFvRDtBQUNwRCw0Q0FBd0M7QUFFeEMsUUFBUSxDQUFDLDBCQUEwQixFQUFFO0lBQ25DLE1BQU0sZ0JBQWdCLEdBQUcsdUJBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUM7SUFDbEQsSUFBSSxLQUFLLENBQUM7SUFDVixJQUFJLFFBQVEsQ0FBQztJQUNiLElBQUksVUFBVSxDQUFDO0lBQ2YsSUFBSSxhQUE4QixDQUFDO0lBQ25DLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQztJQUNwQixNQUFNLE9BQU8sR0FBRyxNQUFNLElBQUksRUFBRSxDQUFDO0lBRTdCLE1BQU0sQ0FBQyxLQUFLO1FBQ1YsS0FBSyxHQUFHLG9CQUFTLENBQUMsUUFBUSxDQUFDLFdBQUssRUFBRSxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsZ0JBQWdCLEVBQVMsQ0FBQyxDQUFDO1FBQzVFLEtBQUssQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1FBQzNCLFFBQVEsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQy9CLFFBQVEsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUNyQixNQUFNLFFBQVEsR0FBRyxnQkFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksS0FBSyxNQUFNLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFD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dCBub2NrID0gcmVxdWlyZSgnbm9jaycpO1xuaW1wb3J0IHNob3VsZCA9IHJlcXVpcmUoJ3Nob3VsZCcpO1xuaW1wb3J0IGZpeHR1cmVzIGZyb20gJy4uLy4uL2ZpeHR1cmVzL3N0YWtpbmcvZ29TdGFraW5nV2FsbGV0JztcblxuaW1wb3J0IHsgRW50ZXJwcmlzZSwgRW52aXJvbm1lbnRzLCBHb1N0YWtpbmdXYWxsZXQsIFdhbGxldCB9IGZyb20gJ0BiaXRnby9zZGstY29yZSc7XG5pbXBvcnQgeyBUZXN0Qml0R28gfSBmcm9tICdAYml0Z28vc2RrLXRlc3QnO1xuaW1wb3J0IHsgQml0R28gfSBmcm9tICcuLi8uLi8uLi8uLi9zcmMnO1xuaW1wb3J0ICogYXMgc2lub24gZnJvbSAnc2lub24nO1xuaW1wb3J0IHsgT2ZjVG9rZW4gfSBmcm9tICcuLi8uLi8uLi8uLi9zcmMvdjIvY29pbnMnO1xuaW1wb3J0IHsgdG9rZW5zIH0gZnJvbSAnQGJpdGdvL3N0YXRpY3MnO1xuXG5kZXNjcmliZSgnR28gU3Rha2luZyBXYWxsZXQgQ29tbW9uJywgZnVuY3Rpb24gKCkge1xuICBjb25zdCBtaWNyb3NlcnZpY2VzVXJpID0gRW52aXJvbm1lbnRzWydtb2NrJ10udXJpO1xuICBsZXQgYml0Z287XG4gIGxldCBiYXNlQ29pbjtcbiAgbGV0IGVudGVycHJpc2U7XG4gIGxldCBzdGFraW5nV2FsbGV0OiBHb1N0YWtpbmdXYWxsZXQ7XG4gIGNvbnN0IGNvaW4gPSAndHNvbCc7XG4gIGNvbnN0IG9mY0NvaW4gPSBgb2ZjJHtjb2lufWA7XG5cbiAgYmVmb3JlKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHbywgeyBlbnY6ICdtb2NrJywgbWljcm9zZXJ2aWNlc1VyaSB9IGFzIGFueSk7XG4gICAgYml0Z28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gICAgYmFzZUNvaW4gPSBiaXRnby5jb2luKG9mY0NvaW4pO1xuICAgIGJhc2VDb2luLmtleWNoYWlucygpO1xuICAgIGNvbnN0IG9mY1Rva2VuID0gdG9rZW5zLnRlc3RuZXQub2ZjLnRva2Vucy5maWx0ZXIoKHRva2VuKSA9PiB0b2tlbi50eXBlID09PSBgb2ZjJHtjb2lufWApWzBdO1xuICAgIGNvbnN0IHRva2VuQ29uc3RydWN0b3IgPSBPZmNUb2tlbi5jcmVhdGVUb2tlbkNvbnN0cnVjdG9yKG9mY1Rva2VuKTtcbiAgICBiaXRnby5yZWdpc3RlcihvZmNUb2tlbi50eXBlLCB0b2tlbkNvbnN0cnVjdG9yKTtcblxuICAgIGVudGVycHJpc2UgPSBuZXcgRW50ZXJwcmlzZShiaXRnbywgYmFzZUNvaW4sIHsgaWQ6ICc1Y2Y5NDA5NDk0NDk0MTJkMDBmNTNiM2Q5MmRiY2FhMycsIG5hbWU6ICdUZXN0IEVudGVycHJpc2UnIH0pO1xuICAgIGNvbnN0IHdhbGxldERhdGEgPSB7XG4gICAgICBpZDogJ3dhbGxldElkJyxcbiAgICAgIGNvaW46IG9mY0NvaW4sXG4gICAgICBlbnRlcnByaXNlOiBlbnRlcnByaXNlLmlkLFxuICAgICAga2V5czogWyc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzUnLCAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc0JywgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3MyddLFxuICAgIH07XG4gICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYmFzZUNvaW4sIHdhbGxldERhdGEpO1xuICAgIHN0YWtpbmdXYWxsZXQgPSB3YWxsZXQudG9Hb1N0YWtpbmdXYWxsZXQoKTtcbiAgICBjb25zdCBlbmNyeXB0ZWRTdGFraW5nUHJ2ID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7XG4gICAgICBpbnB1dDpcbiAgICAgICAgJ3hwcnZBNDF6N3pvZ1ZWd3hWU2dkS1VIRHkxU0ttZGI1MzNQakR6N0o2TjZtVjZ1UzN6ZTFhaThGSGE4a21IU2NHcFdtajRXZ2dMeVFqZ1BpZTFyRlNydW9VaWhVWlJFUFNMMzlVTmRFM0JCRHU3NicsXG4gICAgICBwYXNzd29yZDogJ3Bhc3NwaHJhc2UnLFxuICAgIH0pO1xuICAgIG5vY2sobWljcm9zZXJ2aWNlc1VyaSkuZ2V0KGAvYXBpL3YyLyR7b2ZjQ29pbn0va2V5LyR7c3Rha2luZ1dhbGxldC53YWxsZXQua2V5SWRzKClbMF19YCkucmVwbHkoMjAwLCB7XG4gICAgICBpZDogc3Rha2luZ1dhbGxldC53YWxsZXQua2V5SWRzKClbMF0sXG4gICAgICBwdWI6ICd4cHViNjYxTXlNd0FxUmJjRnE2NWR2R01lRVZiODFLS0RSUmtXa2F3U1Zlc1djeWV2R2M1Z3I4VjI3TGpOZmtrdGFNdUt0TTM2MmpoZ0t5MmV1MzVSZEFyY21tRUFvVUx6QXZnS2tKcFdRUHZMWE0nLFxuICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICBlbmNyeXB0ZWRQcnY6IGVuY3J5cHRlZFN0YWtpbmdQcnYsXG4gICAgICBjb2luU3BlY2lmaWM6IHt9LFxuICAgIH0pO1xuXG4gICAgbm9jayhtaWNyb3NlcnZpY2VzVXJpKS5nZXQoYC9hcGkvdjIvJHtvZmNDb2lufS9rZXkvJHtzdGFraW5nV2FsbGV0LndhbGxldC5rZXlJZHMoKVsxXX1gKS5yZXBseSgyMDAsIHtcbiAgICAgIGlkOiBzdGFraW5nV2FsbGV0LndhbGxldC5rZXlJZHMoKVsxXSxcbiAgICAgIHB1YjogJ3hwdWI2NjFNeU13QXFSYmNGcTY1ZHZHTWVFVmI4MUtLRFJSa1drYXdTVmVzV2N5ZXZHYzVncjhWMjdMak5ma2t0YU11S3RNMzYyamhnS3kyZXUzNVJkQXJjbW1FQW9VTHpBdmdLa0pwV1FQdkxYTScsXG4gICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgIGVuY3J5cHRlZFBydjogZW5jcnlwdGVkU3Rha2luZ1BydixcbiAgICAgIGNvaW5TcGVjaWZpYzoge30sXG4gICAgfSk7XG5cbiAgICBub2NrKG1pY3Jvc2VydmljZXNVcmkpLmdldChgL2FwaS92Mi8ke29mY0NvaW59L2tleS8ke3N0YWtpbmdXYWxsZXQud2FsbGV0LmtleUlkcygpWzJdfWApLnJlcGx5KDIwMCwge1xuICAgICAgaWQ6IHN0YWtpbmdXYWxsZXQud2FsbGV0LmtleUlkcygpWzJdLFxuICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0ZxNjVkdkdNZUVWYjgxS0tEUlJrV2thd1NWZXNXY3lldkdjNWdyOFYyN0xqTmZra3RhTXVLdE0zNjJqaGdLeTJldTM1UmRBcmNtbUVBb1VMekF2Z0trSnBXUVB2TFhNJyxcbiAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgZW5jcnlwdGVkUHJ2OiBlbmNyeXB0ZWRTdGFraW5nUHJ2LFxuICAgICAgY29pblNwZWNpZmljOiB7fSxcbiAgICB9KTtcbiAgfSk7XG5cbiAgY29uc3Qgc2FuZGJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcblxuICBhZnRlckVhY2goZnVuY3Rpb24gKCkge1xuICAgIHNhbmRib3gudmVyaWZ5QW5kUmVzdG9yZSgpO1xuICB9KTtcblxuICBkZXNjcmliZSgnc3Rha2UnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBjYWxsIGdvLXN0YWtpbmctc2VydmljZSB0byBzdGFrZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHByZXZpZXcgPSBmaXh0dXJlcy5wcmV2aWV3R29TdGFraW5nUmVxdWVzdChjb2luKTtcbiAgICAgIGNvbnN0IG1zU2NvcGUxID0gbm9jayhtaWNyb3NlcnZpY2VzVXJpKVxuICAgICAgICAucG9zdChgL2FwaS9nby1zdGFraW5nL3YxLyR7b2ZjQ29pbn0vYWNjb3VudHMvJHtzdGFraW5nV2FsbGV0LmFjY291bnRJZH0vcmVxdWVzdHMvcHJldmlld2AsIHtcbiAgICAgICAgICBhbW91bnQ6ICcxJyxcbiAgICAgICAgICBjbGllbnRJZDogJ2NsaWVudElkJyxcbiAgICAgICAgICB0eXBlOiAnU1RBS0UnLFxuICAgICAgICB9KVxuICAgICAgICAucmVwbHkoMjAxLCBwcmV2aWV3KTtcblxuICAgICAgY29uc3QgZXhwZWN0ZWQgPSBmaXh0dXJlcy5maW5hbGl6ZUdvU3Rha2luZ1JlcXVlc3QoY29pbiwgJ1NUQUtFJyk7XG4gICAgICBjb25zdCBtc1Njb3BlMiA9IG5vY2sobWljcm9zZXJ2aWNlc1VyaSlcbiAgICAgICAgLnBvc3QoYC9hcGkvZ28tc3Rha2luZy92MS8ke29mY0NvaW59L2FjY291bnRzLyR7c3Rha2luZ1dhbGxldC5hY2NvdW50SWR9L3JlcXVlc3RzL2ZpbmFsaXplYCwge1xuICAgICAgICAgIGFtb3VudDogJzEnLFxuICAgICAgICAgIGNsaWVudElkOiAnY2xpZW50SWQnLFxuICAgICAgICAgIGZyb250VHJhbnNmZXJTZW5kUmVxdWVzdDoge1xuICAgICAgICAgICAgaGFsZlNpZ25lZDoge1xuICAgICAgICAgICAgICBwYXlsb2FkOiBwcmV2aWV3LnBheWxvYWQsXG4gICAgICAgICAgICAgIHNpZ25hdHVyZTpcbiAgICAgICAgICAgICAgICAnMWY0ZjdlNzg5ZWY0ODUzNjNiMzNkY2E3MjczNzE3YTRhNDQxMzMzMGYyYmFkYmNhZjMwMjc1OGJjNDA0ZmY4ZTkzMDk0M2RiODFhYTJjNzcwMDc3MzhhZmEyMzE2NjkzNGMyYTMxMzZiYWUyODFiZWEwMzcwOTViZTcxODNjMDYwMicsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdHlwZTogJ1NUQUtFJyxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlcGx5KDIwMSwgZXhwZWN0ZWQpO1xuXG4gICAgICBjb25zdCBzdGFraW5nUmVxdWVzdCA9IGF3YWl0IHN0YWtpbmdXYWxsZXQuc3Rha2Uoe1xuICAgICAgICBhbW91bnQ6ICcxJyxcbiAgICAgICAgY2xpZW50SWQ6ICdjbGllbnRJZCcsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdwYXNzcGhyYXNlJyxcbiAgICAgIH0pO1xuXG4gICAgICBzaG91bGQuZXhpc3Qoc3Rha2luZ1JlcXVlc3QpO1xuXG4gICAgICBzdGFraW5nUmVxdWVzdC5zaG91bGQuZGVlcEVxdWFsKGV4cGVjdGVkKTtcbiAgICAgIG1zU2NvcGUxLmlzRG9uZSgpLnNob3VsZC5iZS5UcnVlKCk7XG4gICAgICBtc1Njb3BlMi5pc0RvbmUoKS5zaG91bGQuYmUuVHJ1ZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzdGFrZSB3aXRob3V0IGEgd2FsbGV0IHBhc3NwaHJhc2UgZm9yIGFuIE9GQyB3YWxsZXQgdGhhdCBzaWducyByZW1vdGVseSAodXNlcktleVNpZ25pbmdSZXF1aXJlZCA9PT0gZmFsc2UpJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgLy8gT0ZDIHdhbGxldCBzaWducyByZW1vdGVseSB2aWEgdGhlIEJpdEdvIGtleSBpbnN0ZWFkIG9mIGRlY3J5cHRpbmcgdGhlIHVzZXIga2V5IGxvY2FsbHkuXG4gICAgICBjb25zdCByZW1vdGVXYWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBiYXNlQ29pbiwge1xuICAgICAgICBpZDogJ3JlbW90ZVdhbGxldElkJyxcbiAgICAgICAgY29pbjogb2ZjQ29pbixcbiAgICAgICAgZW50ZXJwcmlzZTogZW50ZXJwcmlzZS5pZCxcbiAgICAgICAga2V5czogWyc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzUnLCAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc0JywgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3MyddLFxuICAgICAgICBjb2luU3BlY2lmaWM6IHsgdXNlcktleVNpZ25pbmdSZXF1aXJlZDogZmFsc2UgfSxcbiAgICAgIH0pO1xuICAgICAgY29uc3QgcmVtb3RlU3Rha2luZ1dhbGxldCA9IHJlbW90ZVdhbGxldC50b0dvU3Rha2luZ1dhbGxldCgpO1xuXG4gICAgICAvLyBwcmVidWlsZEFuZFNpZ25UcmFuc2FjdGlvbiBzdGlsbCBmZXRjaGVzIHRoZSB1c2VyIGtleWNoYWluIChpbmRleCAwKSwgYnV0IHdpdGggbm8gcGFzc3BocmFzZVxuICAgICAgLy8gdGhlIGRlY3J5cHQgY2hlY2sgaXMgc2tpcHBlZCBhbmQgdGhlIGtleSBpcyBuZXZlciB1c2VkIHRvIHNpZ24uXG4gICAgICBub2NrKG1pY3Jvc2VydmljZXNVcmkpLmdldChgL2FwaS92Mi8ke29mY0NvaW59L2tleS8ke3JlbW90ZVN0YWtpbmdXYWxsZXQud2FsbGV0LmtleUlkcygpWzBdfWApLnJlcGx5KDIwMCwge1xuICAgICAgICBpZDogcmVtb3RlU3Rha2luZ1dhbGxldC53YWxsZXQua2V5SWRzKClbMF0sXG4gICAgICAgIHB1YjogJ3hwdWI2NjFNeU13QXFSYmNGcTY1ZHZHTWVFVmI4MUtLRFJSa1drYXdTVmVzV2N5ZXZHYzVncjhWMjdMak5ma2t0YU11S3RNMzYyamhnS3kyZXUzNVJkQXJjbW1FQW9VTHpBdmdLa0pwV1FQdkxYTScsXG4gICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICBjb2luU3BlY2lmaWM6IHt9LFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHByZXZpZXcgPSBmaXh0dXJlcy5wcmV2aWV3R29TdGFraW5nUmVxdWVzdChjb2luKTtcbiAgICAgIGNvbnN0IG1zU2NvcGUxID0gbm9jayhtaWNyb3NlcnZpY2VzVXJpKVxuICAgICAgICAucG9zdChgL2FwaS9nby1zdGFraW5nL3YxLyR7b2ZjQ29pbn0vYWNjb3VudHMvJHtyZW1vdGVTdGFraW5nV2FsbGV0LmFjY291bnRJZH0vcmVxdWVzdHMvcHJldmlld2AsIHtcbiAgICAgICAgICBhbW91bnQ6ICcxJyxcbiAgICAgICAgICBjbGllbnRJZDogJ2NsaWVudElkJyxcbiAgICAgICAgICB0eXBlOiAnU1RBS0UnLFxuICAgICAgICB9KVxuICAgICAgICAucmVwbHkoMjAxLCBwcmV2aWV3KTtcblxuICAgICAgLy8gcmVtb3RlIHNpZ25pbmc6IHRoZSBCaXRHbyBrZXkgc2lnbnMgdGhlIHBheWxvYWQgYW5kIHJldHVybnMgdGhlIHNpZ25hdHVyZVxuICAgICAgY29uc3Qgc2lnbmF0dXJlID1cbiAgICAgICAgJzFmNGY3ZTc4OWVmNDg1MzYzYjMzZGNhNzI3MzcxN2E0YTQ0MTMzMzBmMmJhZGJjYWYzMDI3NThiYzQwNGZmOGU5MzA5NDNkYjgxYWEyYzc3MDA3NzM4YWZhMjMxNjY5MzRjMmEzMTM2YmFlMjgxYmVhMDM3MDk1YmU3MTgzYzA2MDInO1xuICAgICAgY29uc3Qgc2lnblNjb3BlID0gbm9jayhtaWNyb3NlcnZpY2VzVXJpKVxuICAgICAgICAucG9zdChgL2FwaS92Mi9vZmMvd2FsbGV0LyR7cmVtb3RlV2FsbGV0LmlkKCl9L3R4L3NpZ25gLCB7IHBheWxvYWQ6IHByZXZpZXcucGF5bG9hZCB9KVxuICAgICAgICAucmVwbHkoMjAwLCB7IHNpZ25hdHVyZSB9KTtcblxuICAgICAgY29uc3QgZXhwZWN0ZWQgPSBmaXh0dXJlcy5maW5hbGl6ZUdvU3Rha2luZ1JlcXVlc3QoY29pbiwgJ1NUQUtFJyk7XG4gICAgICBjb25zdCBtc1Njb3BlMiA9IG5vY2sobWljcm9zZXJ2aWNlc1VyaSlcbiAgICAgICAgLnBvc3QoYC9hcGkvZ28tc3Rha2luZy92MS8ke29mY0NvaW59L2FjY291bnRzLyR7cmVtb3RlU3Rha2luZ1dhbGxldC5hY2NvdW50SWR9L3JlcXVlc3RzL2ZpbmFsaXplYCwge1xuICAgICAgICAgIGFtb3VudDogJzEnLFxuICAgICAgICAgIGNsaWVudElkOiAnY2xpZW50SWQnLFxuICAgICAgICAgIGZyb250VHJhbnNmZXJTZW5kUmVxdWVzdDoge1xuICAgICAgICAgICAgaGFsZlNpZ25lZDoge1xuICAgICAgICAgICAgICBwYXlsb2FkOiBwcmV2aWV3LnBheWxvYWQsXG4gICAgICAgICAgICAgIHNpZ25hdHVyZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICB0eXBlOiAnU1RBS0UnLFxuICAgICAgICB9KVxuICAgICAgICAucmVwbHkoMjAxLCBleHBlY3RlZCk7XG5cbiAgICAgIGNvbnN0IHN0YWtpbmdSZXF1ZXN0ID0gYXdhaXQgcmVtb3RlU3Rha2luZ1dhbGxldC5zdGFrZSh7XG4gICAgICAgIGFtb3VudDogJzEnLFxuICAgICAgICBjbGllbnRJZDogJ2NsaWVudElkJyxcbiAgICAgIH0pO1xuXG4gICAgICBzaG91bGQuZXhpc3Qoc3Rha2luZ1JlcXVlc3QpO1xuXG4gICAgICBzdGFraW5nUmVxdWVzdC5zaG91bGQuZGVlcEVxdWFsKGV4cGVjdGVkKTtcbiAgICAgIG1zU2NvcGUxLmlzRG9uZSgpLnNob3VsZC5iZS5UcnVlKCk7XG4gICAgICBzaWduU2NvcGUuaXNEb25lKCkuc2hvdWxkLmJlLlRydWUoKTtcbiAgICAgIG1zU2NvcGUyLmlzRG9uZSgpLnNob3VsZC5iZS5UcnVlKCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCd1bnN0YWtlJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgY2FsbCBnby1zdGFraW5nLXNlcnZpY2UgdG8gdW5zdGFrZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGV4cGVjdGVkID0gZml4dHVyZXMuZmluYWxpemVHb1N0YWtpbmdSZXF1ZXN0KGNvaW4sICdVTlNUQUtFJyk7XG4gICAgICBjb25zdCBtc1Njb3BlID0gbm9jayhtaWNyb3NlcnZpY2VzVXJpKVxuICAgICAgICAucG9zdChgL2FwaS9nby1zdGFraW5nL3YxLyR7b2ZjQ29pbn0vYWNjb3VudHMvJHtzdGFraW5nV2FsbGV0LmFjY291bnRJZH0vcmVxdWVzdHMvZmluYWxpemVgLCB7XG4gICAgICAgICAgYW1vdW50OiAnMScsXG4gICAgICAgICAgY2xpZW50SWQ6ICdjbGllbnRJZCcsXG4gICAgICAgICAgdHlwZTogJ1VOU1RBS0UnLFxuICAgICAgICB9KVxuICAgICAgICAucmVwbHkoMjAxLCBleHBlY3RlZCk7XG5cbiAgICAgIGNvbnN0IHN0YWtpbmdSZXF1ZXN0ID0gYXdhaXQgc3Rha2luZ1dhbGxldC51bnN0YWtlKHtcbiAgICAgICAgYW1vdW50OiAnMScsXG4gICAgICAgIGNsaWVudElkOiAnY2xpZW50SWQnLFxuICAgICAgfSk7XG5cbiAgICAgIHNob3VsZC5leGlzdChzdGFraW5nUmVxdWVzdCk7XG5cbiAgICAgIHN0YWtpbmdSZXF1ZXN0LnNob3VsZC5kZWVwRXF1YWwoZXhwZWN0ZWQpO1xuICAgICAgbXNTY29wZS5pc0RvbmUoKS5zaG91bGQuYmUuVHJ1ZSgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnZ2V0R29TdGFraW5nUmVxdWVzdCcsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIGNhbGwgZ28tc3Rha2luZy1zZXJ2aWNlIHRvIGdldCBnbyBzdGFraW5nIHJlcXVlc3QnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzdGFraW5nUmVxdWVzdElkID0gJzg2MzgyODRhLWRhYjItNDZiOS1iMDdmLTIxMTA5YTZlNzIyMCc7XG4gICAgICBjb25zdCBleHBlY3RlZCA9IGZpeHR1cmVzLmZpbmFsaXplR29TdGFraW5nUmVxdWVzdChjb2luLCAnU1RBS0UnKTtcbiAgICAgIGNvbnN0IG1zU2NvcGUgPSBub2NrKG1pY3Jvc2VydmljZXNVcmkpXG4gICAgICAgIC5nZXQoYC9hcGkvZ28tc3Rha2luZy92MS8ke29mY0NvaW59L2FjY291bnRzLyR7c3Rha2luZ1dhbGxldC5hY2NvdW50SWR9L3JlcXVlc3RzLyR7c3Rha2luZ1JlcXVlc3RJZH1gKVxuICAgICAgICAucmVwbHkoMjAwLCBleHBlY3RlZCk7XG5cbiAgICAgIGNvbnN0IHN0YWtpbmdSZXF1ZXN0ID0gYXdhaXQgc3Rha2luZ1dhbGxldC5nZXRHb1N0YWtpbmdSZXF1ZXN0KHN0YWtpbmdSZXF1ZXN0SWQpO1xuXG4gICAgICBzaG91bGQuZXhpc3Qoc3Rha2luZ1JlcXVlc3QpO1xuXG4gICAgICBzdGFraW5nUmVxdWVzdC5zaG91bGQuZGVlcEVxdWFsKGV4cGVjdGVkKTtcbiAgICAgIG1zU2NvcGUuaXNEb25lKCkuc2hvdWxkLmJlLlRydWUoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2dldEdvU3Rha2luZ1JlcXVlc3RzQnlDb2luJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgY2FsbCBnby1zdGFraW5nLXNlcnZpY2UgdG8gZ2V0IGdvIHN0YWtpbmcgcmVxdWVzdHMgYnkgY29pbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGV4cGVjdGVkID0gZml4dHVyZXMuZ2V0R29TdGFraW5nUmVxdWVzdHNCeUNvaW4ob2ZjQ29pbik7XG4gICAgICBjb25zdCBtc1Njb3BlID0gbm9jayhtaWNyb3NlcnZpY2VzVXJpKVxuICAgICAgICAuZ2V0KGAvYXBpL2dvLXN0YWtpbmcvdjEvJHtvZmNDb2lufS9hY2NvdW50cy8ke3N0YWtpbmdXYWxsZXQuYWNjb3VudElkfS9yZXF1ZXN0c2ApXG4gICAgICAgIC5yZXBseSgyMDAsIGV4cGVjdGVkKTtcblxuICAgICAgY29uc3Qgc3Rha2luZ1JlcXVlc3RzID0gYXdhaXQgc3Rha2luZ1dhbGxldC5nZXRHb1N0YWtpbmdSZXF1ZXN0c0J5V2FsbGV0Q29pbigpO1xuXG4gICAgICBzaG91bGQuZXhpc3Qoc3Rha2luZ1JlcXVlc3RzKTtcblxuICAgICAgc3Rha2luZ1JlcXVlc3RzLnNob3VsZC5kZWVwRXF1YWwoZXhwZWN0ZWQpO1xuICAgICAgbXNTY29wZS5pc0RvbmUoKS5zaG91bGQuYmUuVHJ1ZSgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnZ2V0R29TdGFraW5nUmVxdWVzdHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBjYWxsIGdvLXN0YWtpbmctc2VydmljZSB0byBnZXQgZ28gc3Rha2luZyByZXF1ZXN0cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGV4cGVjdGVkID0gZml4dHVyZXMuZ2V0R29TdGFraW5nUmVxdWVzdHMoW29mY0NvaW5dKTtcbiAgICAgIGNvbnN0IG1zU2NvcGUgPSBub2NrKG1pY3Jvc2VydmljZXNVcmkpXG4gICAgICAgIC5nZXQoYC9hcGkvZ28tc3Rha2luZy92MS9hY2NvdW50cy8ke3N0YWtpbmdXYWxsZXQuYWNjb3VudElkfS9yZXF1ZXN0c2ApXG4gICAgICAgIC5yZXBseSgyMDAsIGV4cGVjdGVkKTtcblxuICAgICAgY29uc3Qgc3Rha2luZ1JlcXVlc3RzID0gYXdhaXQgc3Rha2luZ1dhbGxldC5nZXRHb1N0YWtpbmdSZXF1ZXN0cygpO1xuXG4gICAgICBzaG91bGQuZXhpc3Qoc3Rha2luZ1JlcXVlc3RzKTtcblxuICAgICAgc3Rha2luZ1JlcXVlc3RzLnNob3VsZC5kZWVwRXF1YWwoZXhwZWN0ZWQpO1xuICAgICAgbXNTY29wZS5pc0RvbmUoKS5zaG91bGQuYmUuVHJ1ZSgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnZ2V0R29TdGFraW5nV2FsbGV0cycsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIGNhbGwgZ28tc3Rha2luZy1zZXJ2aWNlIHRvIGdldCBnbyBzdGFraW5nIHdhbGxldHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBleHBlY3RlZCA9IGZpeHR1cmVzLmdldEdvU3Rha2luZ1dhbGxldHMoW29mY0NvaW5dKTtcbiAgICAgIGNvbnN0IG1zU2NvcGUgPSBub2NrKG1pY3Jvc2VydmljZXNVcmkpXG4gICAgICAgIC5nZXQoYC9hcGkvZ28tc3Rha2luZy92MS9hY2NvdW50cy8ke3N0YWtpbmdXYWxsZXQuYWNjb3VudElkfS9jb2luc2ApXG4gICAgICAgIC5yZXBseSgyMDAsIGV4cGVjdGVkKTtcblxuICAgICAgY29uc3QgZ29TdGFraW5nV2FsbGV0cyA9IGF3YWl0IHN0YWtpbmdXYWxsZXQuZ2V0R29TdGFraW5nV2FsbGV0cygpO1xuXG4gICAgICBzaG91bGQuZXhpc3QoZ29TdGFraW5nV2FsbGV0cyk7XG5cbiAgICAgIGdvU3Rha2luZ1dhbGxldHMuc2hvdWxkLmRlZXBFcXVhbChleHBlY3RlZCk7XG4gICAgICBtc1Njb3BlLmlzRG9uZSgpLnNob3VsZC5iZS5UcnVlKCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdnZXRHb1N0YWtpbmdXYWxsZXQnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBjYWxsIGdvLXN0YWtpbmctc2VydmljZSB0byBnZXQgZ28gc3Rha2luZyB3YWxsZXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBleHBlY3RlZCA9IGZpeHR1cmVzLmdldEdvU3Rha2luZ1dhbGxldChvZmNDb2luKTtcbiAgICAgIGNvbnN0IG1zU2NvcGUgPSBub2NrKG1pY3Jvc2VydmljZXNVcmkpXG4gICAgICAgIC5nZXQoYC9hcGkvZ28tc3Rha2luZy92MS8ke29mY0NvaW59L2FjY291bnRzLyR7c3Rha2luZ1dhbGxldC5hY2NvdW50SWR9L2NvaW5zYClcbiAgICAgICAgLnJlcGx5KDIwMCwgZXhwZWN0ZWQpO1xuXG4gICAgICBjb25zdCBnb1N0YWtpbmdXYWxsZXQgPSBhd2FpdCBzdGFraW5nV2FsbGV0LmdldEdvU3Rha2luZ1dhbGxldCgpO1xuXG4gICAgICBzaG91bGQuZXhpc3QoZ29TdGFraW5nV2FsbGV0KTtcblxuICAgICAgZ29TdGFraW5nV2FsbGV0LnNob3VsZC5kZWVwRXF1YWwoZXhwZWN0ZWQpO1xuICAgICAgbXNTY29wZS5pc0RvbmUoKS5zaG91bGQuYmUuVHJ1ZSgpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19