@bitgo/sdk-core 36.40.0 → 36.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/dist/src/bitgo/baseCoin/iBaseCoin.d.ts +2 -2
  2. package/dist/src/bitgo/baseCoin/iBaseCoin.d.ts.map +1 -1
  3. package/dist/src/bitgo/baseCoin/iBaseCoin.js +1 -1
  4. package/dist/src/bitgo/bitgoBase.d.ts +1 -0
  5. package/dist/src/bitgo/bitgoBase.d.ts.map +1 -1
  6. package/dist/src/bitgo/bitgoBase.js +1 -1
  7. package/dist/src/bitgo/environments.d.ts +1 -0
  8. package/dist/src/bitgo/environments.d.ts.map +1 -1
  9. package/dist/src/bitgo/environments.js +9 -1
  10. package/dist/src/bitgo/keychain/iKeychains.d.ts +7 -0
  11. package/dist/src/bitgo/keychain/iKeychains.d.ts.map +1 -1
  12. package/dist/src/bitgo/keychain/iKeychains.js +1 -1
  13. package/dist/src/bitgo/keychain/keychains.d.ts.map +1 -1
  14. package/dist/src/bitgo/keychain/keychains.js +11 -19
  15. package/dist/src/bitgo/pendingApproval/pendingApproval.d.ts.map +1 -1
  16. package/dist/src/bitgo/pendingApproval/pendingApproval.js +11 -4
  17. package/dist/src/bitgo/trading/iTradingAccount.d.ts +6 -1
  18. package/dist/src/bitgo/trading/iTradingAccount.d.ts.map +1 -1
  19. package/dist/src/bitgo/trading/iTradingAccount.js +1 -1
  20. package/dist/src/bitgo/trading/network/network.d.ts +1 -1
  21. package/dist/src/bitgo/trading/network/network.d.ts.map +1 -1
  22. package/dist/src/bitgo/trading/network/network.js +3 -5
  23. package/dist/src/bitgo/trading/network/types.d.ts +1 -1
  24. package/dist/src/bitgo/trading/network/types.d.ts.map +1 -1
  25. package/dist/src/bitgo/trading/network/types.js +1 -1
  26. package/dist/src/bitgo/trading/tradingAccount.d.ts +13 -1
  27. package/dist/src/bitgo/trading/tradingAccount.d.ts.map +1 -1
  28. package/dist/src/bitgo/trading/tradingAccount.js +32 -2
  29. package/dist/src/bitgo/tss/bitgoPubKeys.d.ts +11 -0
  30. package/dist/src/bitgo/tss/bitgoPubKeys.d.ts.map +1 -1
  31. package/dist/src/bitgo/tss/bitgoPubKeys.js +15 -1
  32. package/dist/src/bitgo/tss/ecdsa/ecdsaMPCv2.d.ts.map +1 -1
  33. package/dist/src/bitgo/tss/ecdsa/ecdsaMPCv2.js +8 -3
  34. package/dist/src/bitgo/utils/codecs.d.ts +11 -0
  35. package/dist/src/bitgo/utils/codecs.d.ts.map +1 -0
  36. package/dist/src/bitgo/utils/codecs.js +59 -0
  37. package/dist/src/bitgo/utils/index.d.ts +1 -0
  38. package/dist/src/bitgo/utils/index.d.ts.map +1 -1
  39. package/dist/src/bitgo/utils/index.js +2 -1
  40. package/dist/src/bitgo/utils/opengpgUtils.d.ts +1 -0
  41. package/dist/src/bitgo/utils/opengpgUtils.d.ts.map +1 -1
  42. package/dist/src/bitgo/utils/opengpgUtils.js +11 -2
  43. package/dist/src/bitgo/utils/tss/baseTSSUtils.d.ts +9 -3
  44. package/dist/src/bitgo/utils/tss/baseTSSUtils.d.ts.map +1 -1
  45. package/dist/src/bitgo/utils/tss/baseTSSUtils.js +18 -8
  46. package/dist/src/bitgo/utils/tss/baseTypes.d.ts +2 -1
  47. package/dist/src/bitgo/utils/tss/baseTypes.d.ts.map +1 -1
  48. package/dist/src/bitgo/utils/tss/baseTypes.js +1 -1
  49. package/dist/src/bitgo/utils/tss/ecdsa/ecdsa.d.ts.map +1 -1
  50. package/dist/src/bitgo/utils/tss/ecdsa/ecdsa.js +7 -4
  51. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.d.ts.map +1 -1
  52. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.js +9 -4
  53. package/dist/src/bitgo/utils/tss/eddsa/base.d.ts +18 -0
  54. package/dist/src/bitgo/utils/tss/eddsa/base.d.ts.map +1 -0
  55. package/dist/src/bitgo/utils/tss/eddsa/base.js +64 -0
  56. package/dist/src/bitgo/utils/tss/eddsa/eddsa.d.ts.map +1 -1
  57. package/dist/src/bitgo/utils/tss/eddsa/eddsa.js +3 -7
  58. package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2.d.ts +22 -0
  59. package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2.d.ts.map +1 -0
  60. package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2.js +215 -0
  61. package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2KeyGenSender.d.ts +6 -0
  62. package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2KeyGenSender.d.ts.map +1 -0
  63. package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2KeyGenSender.js +13 -0
  64. package/dist/src/bitgo/utils/tss/eddsa/index.d.ts +3 -0
  65. package/dist/src/bitgo/utils/tss/eddsa/index.d.ts.map +1 -1
  66. package/dist/src/bitgo/utils/tss/eddsa/index.js +7 -1
  67. package/dist/src/bitgo/utils/tss/eddsa/typesEddsaMPCv2.d.ts +40 -0
  68. package/dist/src/bitgo/utils/tss/eddsa/typesEddsaMPCv2.d.ts.map +1 -0
  69. package/dist/src/bitgo/utils/tss/eddsa/typesEddsaMPCv2.js +44 -0
  70. package/dist/src/bitgo/utils/tss/recipientUtils.d.ts +20 -0
  71. package/dist/src/bitgo/utils/tss/recipientUtils.d.ts.map +1 -0
  72. package/dist/src/bitgo/utils/tss/recipientUtils.js +46 -0
  73. package/dist/src/bitgo/wallet/iWallet.d.ts +3 -2
  74. package/dist/src/bitgo/wallet/iWallet.d.ts.map +1 -1
  75. package/dist/src/bitgo/wallet/iWallet.js +1 -1
  76. package/dist/src/bitgo/wallet/iWallets.d.ts +13 -6
  77. package/dist/src/bitgo/wallet/iWallets.d.ts.map +1 -1
  78. package/dist/src/bitgo/wallet/iWallets.js +1 -1
  79. package/dist/src/bitgo/wallet/wallet.d.ts.map +1 -1
  80. package/dist/src/bitgo/wallet/wallet.js +18 -5
  81. package/dist/src/bitgo/wallet/wallets.d.ts.map +1 -1
  82. package/dist/src/bitgo/wallet/wallets.js +15 -1
  83. package/dist/src/coins/fiat.d.ts +45 -0
  84. package/dist/src/coins/fiat.d.ts.map +1 -0
  85. package/dist/src/coins/fiat.js +94 -0
  86. package/dist/src/coins/index.d.ts +1 -12
  87. package/dist/src/coins/index.d.ts.map +1 -1
  88. package/dist/src/coins/index.js +2 -13
  89. package/dist/src/coins/ofc.d.ts +15 -1
  90. package/dist/src/coins/ofc.d.ts.map +1 -1
  91. package/dist/src/coins/ofc.js +8 -1
  92. package/dist/src/coins/ofcToken.d.ts +5 -3
  93. package/dist/src/coins/ofcToken.d.ts.map +1 -1
  94. package/dist/src/coins/ofcToken.js +14 -4
  95. package/dist/test/unit/bitgo/trading/tradingAccount.d.ts +2 -0
  96. package/dist/test/unit/bitgo/trading/tradingAccount.d.ts.map +1 -0
  97. package/dist/test/unit/bitgo/trading/tradingAccount.js +113 -0
  98. package/dist/test/unit/bitgo/utils/tss/recipientUtils.d.ts +2 -0
  99. package/dist/test/unit/bitgo/utils/tss/recipientUtils.d.ts.map +1 -0
  100. package/dist/test/unit/bitgo/utils/tss/recipientUtils.js +137 -0
  101. package/dist/test/unit/bitgo/wallet/ofcWalletSignTransaction.d.ts +2 -0
  102. package/dist/test/unit/bitgo/wallet/ofcWalletSignTransaction.d.ts.map +1 -0
  103. package/dist/test/unit/bitgo/wallet/ofcWalletSignTransaction.js +70 -0
  104. package/dist/test/unit/bitgo/wallet/walletsWebauthn.d.ts +2 -0
  105. package/dist/test/unit/bitgo/wallet/walletsWebauthn.d.ts.map +1 -0
  106. package/dist/test/unit/bitgo/wallet/walletsWebauthn.js +197 -0
  107. package/dist/test/unit/coins/ofc.d.ts +2 -0
  108. package/dist/test/unit/coins/ofc.d.ts.map +1 -0
  109. package/dist/test/unit/coins/ofc.js +124 -0
  110. package/dist/tsconfig.tsbuildinfo +1 -1
  111. package/package.json +5 -5
  112. package/dist/src/coins/fiataed.d.ts +0 -32
  113. package/dist/src/coins/fiataed.d.ts.map +0 -1
  114. package/dist/src/coins/fiataed.js +0 -61
  115. package/dist/src/coins/fiateur.d.ts +0 -32
  116. package/dist/src/coins/fiateur.d.ts.map +0 -1
  117. package/dist/src/coins/fiateur.js +0 -61
  118. package/dist/src/coins/fiatgbp.d.ts +0 -32
  119. package/dist/src/coins/fiatgbp.d.ts.map +0 -1
  120. package/dist/src/coins/fiatgbp.js +0 -61
  121. package/dist/src/coins/fiatinr.d.ts +0 -32
  122. package/dist/src/coins/fiatinr.d.ts.map +0 -1
  123. package/dist/src/coins/fiatinr.js +0 -61
  124. package/dist/src/coins/fiatsgd.d.ts +0 -32
  125. package/dist/src/coins/fiatsgd.d.ts.map +0 -1
  126. package/dist/src/coins/fiatsgd.js +0 -61
  127. package/dist/src/coins/fiatusd.d.ts +0 -32
  128. package/dist/src/coins/fiatusd.d.ts.map +0 -1
  129. package/dist/src/coins/fiatusd.js +0 -61
  130. package/dist/src/coins/tfiataed.d.ts +0 -11
  131. package/dist/src/coins/tfiataed.d.ts.map +0 -1
  132. package/dist/src/coins/tfiataed.js +0 -17
  133. package/dist/src/coins/tfiateur.d.ts +0 -11
  134. package/dist/src/coins/tfiateur.d.ts.map +0 -1
  135. package/dist/src/coins/tfiateur.js +0 -17
  136. package/dist/src/coins/tfiatgbp.d.ts +0 -11
  137. package/dist/src/coins/tfiatgbp.d.ts.map +0 -1
  138. package/dist/src/coins/tfiatgbp.js +0 -17
  139. package/dist/src/coins/tfiatinr.d.ts +0 -11
  140. package/dist/src/coins/tfiatinr.d.ts.map +0 -1
  141. package/dist/src/coins/tfiatinr.js +0 -17
  142. package/dist/src/coins/tfiatsgd.d.ts +0 -11
  143. package/dist/src/coins/tfiatsgd.d.ts.map +0 -1
  144. package/dist/src/coins/tfiatsgd.js +0 -17
  145. package/dist/src/coins/tfiatusd.d.ts +0 -11
  146. package/dist/src/coins/tfiatusd.d.ts.map +0 -1
  147. package/dist/src/coins/tfiatusd.js +0 -17
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ /**
7
+ * @prettier
8
+ */
9
+ const sinon_1 = __importDefault(require("sinon"));
10
+ require("should");
11
+ const ofc_1 = require("../../../src/coins/ofc");
12
+ const ofcToken_1 = require("../../../src/coins/ofcToken");
13
+ const baseCoin_1 = require("../../../src/bitgo/baseCoin/baseCoin");
14
+ const src_1 = require("../../../src");
15
+ const TEST_TOKEN_CONFIG = {
16
+ coin: 'ofcusdt',
17
+ decimalPlaces: 6,
18
+ name: 'OFCUSDT',
19
+ type: 'ofcusdt',
20
+ backingCoin: 'usdt',
21
+ isFiat: false,
22
+ };
23
+ describe('Ofc / OfcToken', function () {
24
+ let mockBitGo;
25
+ beforeEach(function () {
26
+ mockBitGo = { url: sinon_1.default.stub().returns('https://test.bitgo.com') };
27
+ });
28
+ afterEach(function () {
29
+ sinon_1.default.restore();
30
+ });
31
+ describe('signMessage', function () {
32
+ let ofc;
33
+ beforeEach(function () {
34
+ ofc = new ofc_1.Ofc(mockBitGo);
35
+ });
36
+ describe('with a Wallet instance', function () {
37
+ it('should delegate to wallet.toTradingAccount().signPayload() and return a Buffer', async function () {
38
+ const hexSignature = 'deadbeef';
39
+ const signPayloadStub = sinon_1.default.stub().resolves(hexSignature);
40
+ const mockBaseCoin = { supportsTss: sinon_1.default.stub().returns(false), getMPCAlgorithm: sinon_1.default.stub() };
41
+ const walletData = {
42
+ id: 'wallet-id',
43
+ keys: ['key1', 'key2', 'key3'],
44
+ multisigType: 'onchain',
45
+ enterprise: 'ent-id',
46
+ };
47
+ const wallet = new src_1.Wallet(mockBitGo, mockBaseCoin, walletData);
48
+ sinon_1.default.stub(wallet, 'toTradingAccount').returns({ signPayload: signPayloadStub });
49
+ const message = 'test message';
50
+ const result = await ofc.signMessage(wallet, message);
51
+ signPayloadStub.calledOnceWith({ payload: message }).should.be.true();
52
+ result.should.deepEqual(Buffer.from(hexSignature, 'hex'));
53
+ });
54
+ });
55
+ describe('with a prv key', function () {
56
+ it('should delegate to the base class signMessage', async function () {
57
+ const expectedResult = Buffer.from('basesignature', 'hex');
58
+ const superSignMessageStub = sinon_1.default.stub(baseCoin_1.BaseCoin.prototype, 'signMessage').resolves(expectedResult);
59
+ const key = {
60
+ prv: 'xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqhuCo36EkzGH6qiT9mJHBvuPKtLRYD4NxFb5hgXMQBB2LLT6mxLDHHo',
61
+ };
62
+ const message = 'test message';
63
+ const result = await ofc.signMessage(key, message);
64
+ superSignMessageStub.calledOnceWith(key, message).should.be.true();
65
+ result.should.equal(expectedResult);
66
+ });
67
+ });
68
+ });
69
+ describe('signTransaction (OfcToken)', function () {
70
+ let ofcToken;
71
+ const payload = '{"amount":"100","from":"alice","to":"bob"}';
72
+ beforeEach(function () {
73
+ ofcToken = new ofcToken_1.OfcToken(mockBitGo, TEST_TOKEN_CONFIG);
74
+ });
75
+ describe('with wallet and no prv (BitGo remote signing)', function () {
76
+ it('should call wallet.toTradingAccount().signPayload() without a passphrase', async function () {
77
+ const hexSignature = 'aabbccdd';
78
+ const signPayloadStub = sinon_1.default.stub().resolves(hexSignature);
79
+ const mockWallet = { toTradingAccount: sinon_1.default.stub().returns({ signPayload: signPayloadStub }) };
80
+ const result = await ofcToken.signTransaction({ txPrebuild: { payload }, wallet: mockWallet });
81
+ signPayloadStub.calledOnceWith({ payload, walletPassphrase: undefined }).should.be.true();
82
+ result.should.deepEqual({ halfSigned: { payload, signature: hexSignature } });
83
+ });
84
+ });
85
+ describe('with wallet and prv (local signing routed through wallet)', function () {
86
+ it('should call wallet.toTradingAccount().signPayload() with the wallet passphrase', async function () {
87
+ const hexSignature = 'aabbccdd';
88
+ const passphrase = 'test-passphrase';
89
+ const signPayloadStub = sinon_1.default.stub().resolves(hexSignature);
90
+ const mockWallet = { toTradingAccount: sinon_1.default.stub().returns({ signPayload: signPayloadStub }) };
91
+ const result = await ofcToken.signTransaction({
92
+ txPrebuild: { payload },
93
+ wallet: mockWallet,
94
+ prv: passphrase,
95
+ });
96
+ signPayloadStub.calledOnceWith({ payload, walletPassphrase: passphrase }).should.be.true();
97
+ result.should.deepEqual({ halfSigned: { payload, signature: hexSignature } });
98
+ });
99
+ });
100
+ describe('with prv only (local signing without wallet)', function () {
101
+ it('should sign locally and return the correct halfSigned result', async function () {
102
+ const signatureBytes = Buffer.from('ccddee', 'hex');
103
+ sinon_1.default.stub(baseCoin_1.BaseCoin.prototype, 'signMessage').resolves(signatureBytes);
104
+ const result = await ofcToken.signTransaction({ txPrebuild: { payload }, prv: 'test-prv' });
105
+ result.should.deepEqual({ halfSigned: { payload, signature: signatureBytes.toString('hex') } });
106
+ });
107
+ it('should pass the prv to signMessage', async function () {
108
+ const signatureBytes = Buffer.from('ccddee', 'hex');
109
+ const superSignMessageStub = sinon_1.default.stub(baseCoin_1.BaseCoin.prototype, 'signMessage').resolves(signatureBytes);
110
+ const prv = 'test-prv';
111
+ await ofcToken.signTransaction({ txPrebuild: { payload }, prv });
112
+ superSignMessageStub.calledOnceWith({ prv }, payload).should.be.true();
113
+ });
114
+ });
115
+ describe('with neither wallet nor prv', function () {
116
+ it('should throw an error', async function () {
117
+ await ofcToken
118
+ .signTransaction({ txPrebuild: { payload } })
119
+ .should.be.rejectedWith('You must pass in either one of wallet or prv');
120
+ });
121
+ });
122
+ });
123
+ });
124
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib2ZjLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC91bml0L2NvaW5zL29mYy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBOztHQUVHO0FBQ0gsa0RBQTBCO0FBQzFCLGtCQUFnQjtBQUNoQixnREFBNkM7QUFDN0MsMERBQXVEO0FBQ3ZELG1FQUFnRTtBQUNoRSxzQ0FBc0M7QUFFdEMsTUFBTSxpQkFBaUIsR0FBRztJQUN4QixJQUFJLEVBQUUsU0FBUztJQUNmLGFBQWEsRUFBRSxDQUFDO0lBQ2hCLElBQUksRUFBRSxTQUFTO0lBQ2YsSUFBSSxFQUFFLFNBQVM7SUFDZixXQUFXLEVBQUUsTUFBTTtJQUNuQixNQUFNLEVBQUUsS0FBSztDQUNkLENBQUM7QUFFRixRQUFRLENBQUMsZ0JBQWdCLEVBQUU7SUFDekIsSUFBSSxTQUFjLENBQUM7SUFFbkIsVUFBVSxDQUFDO1FBQ1QsU0FBUyxHQUFHLEVBQUUsR0FBRyxFQUFFLGVBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxPQUFPLENBQUMsd0JBQXdCLENBQUMsRUFBRSxDQUFDO0lBQ3RFLENBQUMsQ0FBQyxDQUFDO0lBRUgsU0FBUyxDQUFDO1FBQ1IsZUFBSyxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ2xCLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLGFBQWEsRUFBRTtRQUN0QixJQUFJLEdBQVEsQ0FBQztRQUViLFVBQVUsQ0FBQztZQUNULEdBQUcsR0FBRyxJQUFJLFNBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUMzQixDQUFDLENBQUMsQ0FBQztRQUVILFFBQVEsQ0FBQyx3QkFBd0IsRUFBRTtZQUNqQyxFQUFFLENBQUMsZ0ZBQWdGLEVBQUUsS0FBSztnQkFDeEYsTUFBTSxZQUFZLEdBQUcsVUFBVSxDQUFDO2dCQUNoQyxNQUFNLGVBQWUsR0FBRyxlQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDO2dCQUU1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QztnQkFFdkIsTUFBTSxRQUFRLENBQUMsZUFBZSxDQUFDLEVBQUUsVUFBVSxFQUFFLEVBQUUsT0FBTyxFQUFFLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztnQkFFakUsb0JBQW9CLENBQUMsY0FBYyxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUUsT0FBTyxDQUFDLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUN6RSxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsUUFBUSxDQUFDLDZCQUE2QixFQUFFO1lBQ3RDLEVBQUUsQ0FBQyx1QkFBdUIsRUFBRSxLQUFLO2dCQUMvQixNQUFNLFFBQVE7cUJBQ1gsZUFBZSxDQUFDLEVBQUUsVUFBVSxFQUFFLEVBQUUsT0FBTyxFQUFFLEVBQUUsQ0FBQztxQkFDNUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsOENBQThDLENBQUMsQ0FBQztZQUM1RSxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQHByZXR0aWVyXG4gKi9cbmltcG9ydCBzaW5vbiBmcm9tICdzaW5vbic7XG5pbXBvcnQgJ3Nob3VsZCc7XG5pbXBvcnQgeyBPZmMgfSBmcm9tICcuLi8uLi8uLi9zcmMvY29pbnMvb2ZjJztcbmltcG9ydCB7IE9mY1Rva2VuIH0gZnJvbSAnLi4vLi4vLi4vc3JjL2NvaW5zL29mY1Rva2VuJztcbmltcG9ydCB7IEJhc2VDb2luIH0gZnJvbSAnLi4vLi4vLi4vc3JjL2JpdGdvL2Jhc2VDb2luL2Jhc2VDb2luJztcbmltcG9ydCB7IFdhbGxldCB9IGZyb20gJy4uLy4uLy4uL3NyYyc7XG5cbmNvbnN0IFRFU1RfVE9LRU5fQ09ORklHID0ge1xuICBjb2luOiAnb2ZjdXNkdCcsXG4gIGRlY2ltYWxQbGFjZXM6IDYsXG4gIG5hbWU6ICdPRkNVU0RUJyxcbiAgdHlwZTogJ29mY3VzZHQnLFxuICBiYWNraW5nQ29pbjogJ3VzZHQnLFxuICBpc0ZpYXQ6IGZhbHNlLFxufTtcblxuZGVzY3JpYmUoJ09mYyAvIE9mY1Rva2VuJywgZnVuY3Rpb24gKCkge1xuICBsZXQgbW9ja0JpdEdvOiBhbnk7XG5cbiAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgbW9ja0JpdEdvID0geyB1cmw6IHNpbm9uLnN0dWIoKS5yZXR1cm5zKCdodHRwczovL3Rlc3QuYml0Z28uY29tJykgfTtcbiAgfSk7XG5cbiAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICBzaW5vbi5yZXN0b3JlKCk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdzaWduTWVzc2FnZScsIGZ1bmN0aW9uICgpIHtcbiAgICBsZXQgb2ZjOiBPZmM7XG5cbiAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIG9mYyA9IG5ldyBPZmMobW9ja0JpdEdvKTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCd3aXRoIGEgV2FsbGV0IGluc3RhbmNlJywgZnVuY3Rpb24gKCkge1xuICAgICAgaXQoJ3Nob3VsZCBkZWxlZ2F0ZSB0byB3YWxsZXQudG9UcmFkaW5nQWNjb3VudCgpLnNpZ25QYXlsb2FkKCkgYW5kIHJldHVybiBhIEJ1ZmZlcicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgaGV4U2lnbmF0dXJlID0gJ2RlYWRiZWVmJztcbiAgICAgICAgY29uc3Qgc2lnblBheWxvYWRTdHViID0gc2lub24uc3R1YigpLnJlc29sdmVzKGhleFNpZ25hdHVyZSk7XG5cbiAgICAgICAgY29uc3QgbW9ja0Jhc2VDb2luID0geyBzdXBwb3J0c1Rzczogc2lub24uc3R1YigpLnJldHVybnMoZmFsc2UpLCBnZXRNUENBbGdvcml0aG06IHNpbm9uLnN0dWIoKSB9O1xuICAgICAgICBjb25zdCB3YWxsZXREYXRhID0ge1xuICAgICAgICAgIGlkOiAnd2FsbGV0LWlkJyxcbiAgICAgICAgICBrZXlzOiBbJ2tleTEnLCAna2V5MicsICdrZXkzJ10sXG4gICAgICAgICAgbXVsdGlzaWdUeXBlOiAnb25jaGFpbicsXG4gICAgICAgICAgZW50ZXJwcmlzZTogJ2VudC1pZCcsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQobW9ja0JpdEdvLCBtb2NrQmFzZUNvaW4gYXMgYW55LCB3YWxsZXREYXRhKTtcbiAgICAgICAgc2lub24uc3R1Yih3YWxsZXQsICd0b1RyYWRpbmdBY2NvdW50JykucmV0dXJucyh7IHNpZ25QYXlsb2FkOiBzaWduUGF5bG9hZFN0dWIgfSBhcyBhbnkpO1xuXG4gICAgICAgIGNvbnN0IG1lc3NhZ2UgPSAndGVzdCBtZXNzYWdlJztcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgb2ZjLnNpZ25NZXNzYWdlKHdhbGxldCwgbWVzc2FnZSk7XG5cbiAgICAgICAgc2lnblBheWxvYWRTdHViLmNhbGxlZE9uY2VXaXRoKHsgcGF5bG9hZDogbWVzc2FnZSB9KS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgICByZXN1bHQuc2hvdWxkLmRlZXBFcXVhbChCdWZmZXIuZnJvbShoZXhTaWduYXR1cmUsICdoZXgnKSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCd3aXRoIGEgcHJ2IGtleScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGl0KCdzaG91bGQgZGVsZWdhdGUgdG8gdGhlIGJhc2UgY2xhc3Mgc2lnbk1lc3NhZ2UnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGV4cGVjdGVkUmVzdWx0ID0gQnVmZmVyLmZyb20oJ2Jhc2VzaWduYXR1cmUnLCAnaGV4Jyk7XG4gICAgICAgIGNvbnN0IHN1cGVyU2lnbk1lc3NhZ2VTdHViID0gc2lub24uc3R1YihCYXNlQ29pbi5wcm90b3R5cGUsICdzaWduTWVzc2FnZScpLnJlc29sdmVzKGV4cGVjdGVkUmVzdWx0KTtcblxuICAgICAgICBjb25zdCBrZXkgPSB7XG4gICAgICAgICAgcHJ2OiAneHBydjlzMjFaclFIMTQzSzNRVERMNExYdzJGN0hFSzN3SlVEMm5XMm5SazRzdGJQeTZjcTNqUFBxaHVDbzM2RWt6R0g2cWlUOW1KSEJ2dVBLdExSWUQ0TnhGYjVoZ1hNUUJCMkxMVDZteExESEhvJyxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgbWVzc2FnZSA9ICd0ZXN0IG1lc3NhZ2UnO1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBvZmMuc2lnbk1lc3NhZ2Uoa2V5LCBtZXNzYWdlKTtcblxuICAgICAgICBzdXBlclNpZ25NZXNzYWdlU3R1Yi5jYWxsZWRPbmNlV2l0aChrZXksIG1lc3NhZ2UpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICAgIHJlc3VsdC5zaG91bGQuZXF1YWwoZXhwZWN0ZWRSZXN1bHQpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdzaWduVHJhbnNhY3Rpb24gKE9mY1Rva2VuKScsIGZ1bmN0aW9uICgpIHtcbiAgICBsZXQgb2ZjVG9rZW46IE9mY1Rva2VuO1xuICAgIGNvbnN0IHBheWxvYWQgPSAne1wiYW1vdW50XCI6XCIxMDBcIixcImZyb21cIjpcImFsaWNlXCIsXCJ0b1wiOlwiYm9iXCJ9JztcblxuICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgb2ZjVG9rZW4gPSBuZXcgT2ZjVG9rZW4obW9ja0JpdEdvLCBURVNUX1RPS0VOX0NPTkZJRyk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnd2l0aCB3YWxsZXQgYW5kIG5vIHBydiAoQml0R28gcmVtb3RlIHNpZ25pbmcpJywgZnVuY3Rpb24gKCkge1xuICAgICAgaXQoJ3Nob3VsZCBjYWxsIHdhbGxldC50b1RyYWRpbmdBY2NvdW50KCkuc2lnblBheWxvYWQoKSB3aXRob3V0IGEgcGFzc3BocmFzZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgaGV4U2lnbmF0dXJlID0gJ2FhYmJjY2RkJztcbiAgICAgICAgY29uc3Qgc2lnblBheWxvYWRTdHViID0gc2lub24uc3R1YigpLnJlc29sdmVzKGhleFNpZ25hdHVyZSk7XG4gICAgICAgIGNvbnN0IG1vY2tXYWxsZXQgPSB7IHRvVHJhZGluZ0FjY291bnQ6IHNpbm9uLnN0dWIoKS5yZXR1cm5zKHsgc2lnblBheWxvYWQ6IHNpZ25QYXlsb2FkU3R1YiB9KSB9O1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IG9mY1Rva2VuLnNpZ25UcmFuc2FjdGlvbih7IHR4UHJlYnVpbGQ6IHsgcGF5bG9hZCB9LCB3YWxsZXQ6IG1vY2tXYWxsZXQgYXMgYW55IH0pO1xuXG4gICAgICAgIHNpZ25QYXlsb2FkU3R1Yi5jYWxsZWRPbmNlV2l0aCh7IHBheWxvYWQsIHdhbGxldFBhc3NwaHJhc2U6IHVuZGVmaW5lZCB9KS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgICByZXN1bHQuc2hvdWxkLmRlZXBFcXVhbCh7IGhhbGZTaWduZWQ6IHsgcGF5bG9hZCwgc2lnbmF0dXJlOiBoZXhTaWduYXR1cmUgfSB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3dpdGggd2FsbGV0IGFuZCBwcnYgKGxvY2FsIHNpZ25pbmcgcm91dGVkIHRocm91Z2ggd2FsbGV0KScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGl0KCdzaG91bGQgY2FsbCB3YWxsZXQudG9UcmFkaW5nQWNjb3VudCgpLnNpZ25QYXlsb2FkKCkgd2l0aCB0aGUgd2FsbGV0IHBhc3NwaHJhc2UnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGhleFNpZ25hdHVyZSA9ICdhYWJiY2NkZCc7XG4gICAgICAgIGNvbnN0IHBhc3NwaHJhc2UgPSAndGVzdC1wYXNzcGhyYXNlJztcbiAgICAgICAgY29uc3Qgc2lnblBheWxvYWRTdHViID0gc2lub24uc3R1YigpLnJlc29sdmVzKGhleFNpZ25hdHVyZSk7XG4gICAgICAgIGNvbnN0IG1vY2tXYWxsZXQgPSB7IHRvVHJhZGluZ0FjY291bnQ6IHNpbm9uLnN0dWIoKS5yZXR1cm5zKHsgc2lnblBheWxvYWQ6IHNpZ25QYXlsb2FkU3R1YiB9KSB9O1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IG9mY1Rva2VuLnNpZ25UcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhQcmVidWlsZDogeyBwYXlsb2FkIH0sXG4gICAgICAgICAgd2FsbGV0OiBtb2NrV2FsbGV0IGFzIGFueSxcbiAgICAgICAgICBwcnY6IHBhc3NwaHJhc2UsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHNpZ25QYXlsb2FkU3R1Yi5jYWxsZWRPbmNlV2l0aCh7IHBheWxvYWQsIHdhbGxldFBhc3NwaHJhc2U6IHBhc3NwaHJhc2UgfSkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgICAgcmVzdWx0LnNob3VsZC5kZWVwRXF1YWwoeyBoYWxmU2lnbmVkOiB7IHBheWxvYWQsIHNpZ25hdHVyZTogaGV4U2lnbmF0dXJlIH0gfSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCd3aXRoIHBydiBvbmx5IChsb2NhbCBzaWduaW5nIHdpdGhvdXQgd2FsbGV0KScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGl0KCdzaG91bGQgc2lnbiBsb2NhbGx5IGFuZCByZXR1cm4gdGhlIGNvcnJlY3QgaGFsZlNpZ25lZCByZXN1bHQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHNpZ25hdHVyZUJ5dGVzID0gQnVmZmVyLmZyb20oJ2NjZGRlZScsICdoZXgnKTtcbiAgICAgICAgc2lub24uc3R1YihCYXNlQ29pbi5wcm90b3R5cGUsICdzaWduTWVzc2FnZScpLnJlc29sdmVzKHNpZ25hdHVyZUJ5dGVzKTtcblxuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBvZmNUb2tlbi5zaWduVHJhbnNhY3Rpb24oeyB0eFByZWJ1aWxkOiB7IHBheWxvYWQgfSwgcHJ2OiAndGVzdC1wcnYnIH0pO1xuXG4gICAgICAgIHJlc3VsdC5zaG91bGQuZGVlcEVxdWFsKHsgaGFsZlNpZ25lZDogeyBwYXlsb2FkLCBzaWduYXR1cmU6IHNpZ25hdHVyZUJ5dGVzLnRvU3RyaW5nKCdoZXgnKSB9IH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcGFzcyB0aGUgcHJ2IHRvIHNpZ25NZXNzYWdlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBzaWduYXR1cmVCeXRlcyA9IEJ1ZmZlci5mcm9tKCdjY2RkZWUnLCAnaGV4Jyk7XG4gICAgICAgIGNvbnN0IHN1cGVyU2lnbk1lc3NhZ2VTdHViID0gc2lub24uc3R1YihCYXNlQ29pbi5wcm90b3R5cGUsICdzaWduTWVzc2FnZScpLnJlc29sdmVzKHNpZ25hdHVyZUJ5dGVzKTtcbiAgICAgICAgY29uc3QgcHJ2ID0gJ3Rlc3QtcHJ2JztcblxuICAgICAgICBhd2FpdCBvZmNUb2tlbi5zaWduVHJhbnNhY3Rpb24oeyB0eFByZWJ1aWxkOiB7IHBheWxvYWQgfSwgcHJ2IH0pO1xuXG4gICAgICAgIHN1cGVyU2lnbk1lc3NhZ2VTdHViLmNhbGxlZE9uY2VXaXRoKHsgcHJ2IH0sIHBheWxvYWQpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCd3aXRoIG5laXRoZXIgd2FsbGV0IG5vciBwcnYnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBpdCgnc2hvdWxkIHRocm93IGFuIGVycm9yJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBhd2FpdCBvZmNUb2tlblxuICAgICAgICAgIC5zaWduVHJhbnNhY3Rpb24oeyB0eFByZWJ1aWxkOiB7IHBheWxvYWQgfSB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdZb3UgbXVzdCBwYXNzIGluIGVpdGhlciBvbmUgb2Ygd2FsbGV0IG9yIHBydicpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=