@bitgo-beta/sdk-coin-icp 1.0.1-beta.84 → 1.0.1-beta.841

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 (67) hide show
  1. package/dist/resources/messageCompiled.d.ts +797 -0
  2. package/dist/resources/messageCompiled.js +1859 -0
  3. package/dist/src/icp.d.ts +64 -3
  4. package/dist/src/icp.d.ts.map +1 -1
  5. package/dist/src/icp.js +332 -10
  6. package/dist/src/lib/icpAgent.d.ts +36 -0
  7. package/dist/src/lib/icpAgent.d.ts.map +1 -0
  8. package/dist/src/lib/icpAgent.js +90 -0
  9. package/dist/src/lib/iface.d.ts +195 -0
  10. package/dist/src/lib/iface.d.ts.map +1 -0
  11. package/dist/src/lib/iface.js +44 -0
  12. package/dist/src/lib/index.d.ts +4 -0
  13. package/dist/src/lib/index.d.ts.map +1 -1
  14. package/dist/src/lib/index.js +12 -2
  15. package/dist/src/lib/signedTransactionBuilder.d.ts +9 -0
  16. package/dist/src/lib/signedTransactionBuilder.d.ts.map +1 -0
  17. package/dist/src/lib/signedTransactionBuilder.js +64 -0
  18. package/dist/src/lib/transaction.d.ts +54 -0
  19. package/dist/src/lib/transaction.d.ts.map +1 -0
  20. package/dist/src/lib/transaction.js +255 -0
  21. package/dist/src/lib/transactionBuilder.d.ts +58 -28
  22. package/dist/src/lib/transactionBuilder.d.ts.map +1 -1
  23. package/dist/src/lib/transactionBuilder.js +127 -40
  24. package/dist/src/lib/transactionBuilderFactory.d.ts +15 -14
  25. package/dist/src/lib/transactionBuilderFactory.d.ts.map +1 -1
  26. package/dist/src/lib/transactionBuilderFactory.js +43 -27
  27. package/dist/src/lib/transferBuilder.d.ts +7 -24
  28. package/dist/src/lib/transferBuilder.d.ts.map +1 -1
  29. package/dist/src/lib/transferBuilder.js +88 -43
  30. package/dist/src/lib/unsignedTransactionBuilder.d.ts +13 -0
  31. package/dist/src/lib/unsignedTransactionBuilder.d.ts.map +1 -0
  32. package/dist/src/lib/unsignedTransactionBuilder.js +90 -0
  33. package/dist/src/lib/utils.d.ts +286 -8
  34. package/dist/src/lib/utils.d.ts.map +1 -1
  35. package/dist/src/lib/utils.js +615 -53
  36. package/dist/src/ticp.d.ts +0 -4
  37. package/dist/src/ticp.d.ts.map +1 -1
  38. package/dist/src/ticp.js +1 -7
  39. package/dist/test/resources/icp.d.ts +268 -0
  40. package/dist/test/resources/icp.d.ts.map +1 -0
  41. package/dist/test/resources/icp.js +377 -0
  42. package/dist/test/unit/getBuilderFactory.d.ts +3 -0
  43. package/dist/test/unit/getBuilderFactory.d.ts.map +1 -0
  44. package/dist/test/unit/getBuilderFactory.js +10 -0
  45. package/dist/test/unit/icp.d.ts +2 -0
  46. package/dist/test/unit/icp.d.ts.map +1 -0
  47. package/dist/test/unit/icp.js +418 -0
  48. package/dist/test/unit/keyPair.d.ts +2 -0
  49. package/dist/test/unit/keyPair.d.ts.map +1 -0
  50. package/dist/test/unit/keyPair.js +107 -0
  51. package/dist/test/unit/transaction.d.ts +2 -0
  52. package/dist/test/unit/transaction.d.ts.map +1 -0
  53. package/dist/test/unit/transaction.js +109 -0
  54. package/dist/test/unit/transactionBuilder/transactionBuilder.d.ts +2 -0
  55. package/dist/test/unit/transactionBuilder/transactionBuilder.d.ts.map +1 -0
  56. package/dist/test/unit/transactionBuilder/transactionBuilder.js +274 -0
  57. package/dist/test/unit/transactionBuilder/transactionRecover.d.ts +2 -0
  58. package/dist/test/unit/transactionBuilder/transactionRecover.d.ts.map +1 -0
  59. package/dist/test/unit/transactionBuilder/transactionRecover.js +188 -0
  60. package/dist/test/unit/utils.d.ts +2 -0
  61. package/dist/test/unit/utils.d.ts.map +1 -0
  62. package/dist/test/unit/utils.js +206 -0
  63. package/dist/tsconfig.tsbuildinfo +1 -0
  64. package/package.json +23 -12
  65. package/.eslintignore +0 -4
  66. package/.mocharc.yml +0 -8
  67. package/CHANGELOG.md +0 -54
@@ -0,0 +1,188 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ const should_1 = __importDefault(require("should"));
40
+ const testData = __importStar(require("../../resources/icp"));
41
+ const sinon_1 = __importDefault(require("sinon"));
42
+ const sdk_test_1 = require("@bitgo-beta/sdk-test");
43
+ const sdk_api_1 = require("@bitgo-beta/sdk-api");
44
+ const nock_1 = __importDefault(require("nock"));
45
+ const index_1 = require("../../../src/index");
46
+ const icpAgent_1 = require("../../../src/lib/icpAgent");
47
+ const iface_1 = require("../../../src/lib/iface");
48
+ const principal_1 = require("@dfinity/principal");
49
+ const bignumber_js_1 = __importDefault(require("bignumber.js"));
50
+ const utils_1 = __importDefault(require("../../../src/lib/utils"));
51
+ describe('ICP transaction recovery', async () => {
52
+ let bitgo;
53
+ let recoveryParams;
54
+ let icp;
55
+ let broadcastEndpoint;
56
+ let broadcastResponse;
57
+ let nodeUrl;
58
+ // Helper functions for setting up stubs
59
+ const setupDefaultStubs = () => {
60
+ sinon_1.default.stub(icpAgent_1.IcpAgent.prototype, 'getBalance').resolves((0, bignumber_js_1.default)(1000000000));
61
+ sinon_1.default.stub(icpAgent_1.IcpAgent.prototype, 'getFee').resolves((0, bignumber_js_1.default)(10000));
62
+ sinon_1.default.stub(utils_1.default, 'getMetaData').returns({
63
+ metaData: testData.MetaDataWithDefaultMemo,
64
+ ingressEndTime: testData.MetaDataWithDefaultMemo.ingress_end ?? 0,
65
+ });
66
+ sinon_1.default.stub(icp, 'signatures').returns(testData.RecoverTransactionSignatureWithDefaultMemo);
67
+ };
68
+ const setupMemoStubs = () => {
69
+ sinon_1.default.stub(icpAgent_1.IcpAgent.prototype, 'getBalance').resolves((0, bignumber_js_1.default)(1000000000));
70
+ sinon_1.default.stub(icpAgent_1.IcpAgent.prototype, 'getFee').resolves((0, bignumber_js_1.default)(10000));
71
+ sinon_1.default.stub(utils_1.default, 'getMetaData').returns({
72
+ metaData: testData.MetaDataWithMemo,
73
+ ingressEndTime: testData.MetaDataWithMemo.ingress_end ?? 0,
74
+ });
75
+ sinon_1.default.stub(icp, 'signatures').returns(testData.RecoverTransactionSignatureWithMemo);
76
+ };
77
+ const setupLowBalanceStubs = () => {
78
+ sinon_1.default.stub(icpAgent_1.IcpAgent.prototype, 'getBalance').resolves((0, bignumber_js_1.default)(10));
79
+ sinon_1.default.stub(icpAgent_1.IcpAgent.prototype, 'getFee').resolves((0, bignumber_js_1.default)(10000));
80
+ sinon_1.default.stub(utils_1.default, 'getMetaData').returns({
81
+ metaData: testData.MetaDataWithDefaultMemo,
82
+ ingressEndTime: testData.MetaDataWithDefaultMemo.ingress_end ?? 0,
83
+ });
84
+ };
85
+ before(function () {
86
+ bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'test' });
87
+ bitgo.safeRegister('icp', index_1.Icp.createInstance);
88
+ bitgo.initializeTestVars();
89
+ recoveryParams = {
90
+ userKey: testData.WRWRecovery.userKey,
91
+ backupKey: testData.WRWRecovery.backupKey,
92
+ walletPassphrase: testData.WRWRecovery.walletPassphrase,
93
+ recoveryDestination: testData.Accounts.account2.address,
94
+ };
95
+ icp = bitgo.coin('icp');
96
+ nodeUrl = icp.getPublicNodeUrl();
97
+ const principal = principal_1.Principal.fromUint8Array(iface_1.LEDGER_CANISTER_ID);
98
+ const canisterIdHex = principal.toText();
99
+ broadcastEndpoint = `/api/v3/canister/${canisterIdHex}/call`;
100
+ broadcastResponse = Buffer.from(testData.PublicNodeApiBroadcastResponse, 'hex');
101
+ });
102
+ beforeEach(function () {
103
+ setupDefaultStubs();
104
+ // Set up default successful nock response
105
+ (0, nock_1.default)(nodeUrl).post(broadcastEndpoint).reply(200, broadcastResponse);
106
+ });
107
+ afterEach(function () {
108
+ recoveryParams = {
109
+ userKey: testData.WRWRecovery.userKey,
110
+ backupKey: testData.WRWRecovery.backupKey,
111
+ walletPassphrase: testData.WRWRecovery.walletPassphrase,
112
+ recoveryDestination: testData.Accounts.account2.address,
113
+ };
114
+ nock_1.default.cleanAll();
115
+ sinon_1.default.restore();
116
+ });
117
+ it('should recover a transaction with default memo successfully', async () => {
118
+ const recoverTxn = await icp.recover(recoveryParams);
119
+ recoverTxn.id.should.be.a.String();
120
+ should_1.default.equal(recoverTxn.id, testData.TxnIdWithDefaultMemo);
121
+ });
122
+ it('should recover a transaction with memo successfully', async () => {
123
+ sinon_1.default.restore();
124
+ setupMemoStubs();
125
+ recoveryParams.memo = testData.MetaDataWithMemo.memo;
126
+ const recoverTxn = await icp.recover(recoveryParams);
127
+ recoverTxn.id.should.be.a.String();
128
+ should_1.default.equal(recoverTxn.id, testData.TxnIdWithMemo);
129
+ });
130
+ it('should recover a unsigned sweep transaction successfully', async () => {
131
+ sinon_1.default.restore();
132
+ setupMemoStubs();
133
+ const unsignedSweepRecoveryParams = {
134
+ bitgoKey: '0310768736a005ea5364e1b5b5288cf553224dd28b2df8ced63b72a8020478967f05ec5bce1f26cd7eb009a4bea445bb55c2f54a30f2706c1a3747e8df2d288829',
135
+ recoveryDestination: testData.Accounts.account2.address,
136
+ };
137
+ const recoverTxn = await icp.recover(unsignedSweepRecoveryParams);
138
+ recoverTxn.txHex.should.be.a.String();
139
+ should_1.default.equal(recoverTxn.txHex, testData.UnsignedSweepTransaction);
140
+ });
141
+ it('should failed to recover a unsigned sweep transaction with wrong bitgo key', async () => {
142
+ sinon_1.default.restore();
143
+ setupMemoStubs();
144
+ const unsignedSweepRecoveryParams = {
145
+ bitgoKey: 'testKey',
146
+ recoveryDestination: testData.Accounts.account2.address,
147
+ };
148
+ await icp
149
+ .recover(unsignedSweepRecoveryParams)
150
+ .should.rejectedWith('Error during ICP recovery: Cannot convert 0x to a BigInt');
151
+ });
152
+ it('should failed to recover recover a unsigned sweep transaction without bitgo key', async () => {
153
+ sinon_1.default.restore();
154
+ setupMemoStubs();
155
+ const unsignedSweepRecoveryParams = {
156
+ recoveryDestination: testData.Accounts.account2.address,
157
+ };
158
+ await icp.recover(unsignedSweepRecoveryParams).should.rejectedWith('Error during ICP recovery: missing bitgoKey');
159
+ });
160
+ it('should fail to recover if broadcast API fails', async () => {
161
+ nock_1.default.cleanAll();
162
+ (0, nock_1.default)(nodeUrl).post(broadcastEndpoint).reply(500, 'Internal Server Error');
163
+ recoveryParams.memo = 0;
164
+ await icp
165
+ .recover(recoveryParams)
166
+ .should.rejectedWith('Error during ICP recovery: Transaction broadcast error: Request failed with status code 500');
167
+ });
168
+ it('should fail to recover txn if balance is low', async () => {
169
+ sinon_1.default.restore();
170
+ setupLowBalanceStubs();
171
+ await icp
172
+ .recover(recoveryParams)
173
+ .should.rejectedWith('Error during ICP recovery: Did not have enough funds to recover');
174
+ });
175
+ it('should fail to recover txn if userKey is not provided', async () => {
176
+ recoveryParams.userKey = '';
177
+ await icp.recover(recoveryParams).should.rejectedWith('Error during ICP recovery: missing userKey');
178
+ });
179
+ it('should fail to recover txn if backupKey is not provided', async () => {
180
+ recoveryParams.backupKey = '';
181
+ await icp.recover(recoveryParams).should.rejectedWith('Error during ICP recovery: missing backupKey');
182
+ });
183
+ it('should fail to recover txn if wallet passphrase is not provided', async () => {
184
+ recoveryParams.walletPassphrase = '';
185
+ await icp.recover(recoveryParams).should.rejectedWith('Error during ICP recovery: missing wallet passphrase');
186
+ });
187
+ });
188
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNhY3Rpb25SZWNvdmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC91bml0L3RyYW5zYWN0aW9uQnVpbGRlci90cmFuc2FjdGlvblJlY292ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxvREFBNEI7QUFDNUIsOERBQWdEO0FBQ2hELGtEQUEwQjtBQUMxQixtREFBaUQ7QUFDakQsaURBQStDO0FBQy9DLGdEQUF3QjtBQUN4Qiw4Q0FBeUM7QUFDekMsd0RBQXFEO0FBQ3JELGtEQUE2RTtBQUM3RSxrREFBK0M7QUFDL0MsZ0VBQXFDO0FBQ3JDLG1FQUEyQztBQUUzQyxRQUFRLENBQUMsMEJBQTBCLEVBQUUsS0FBSyxJQUFJLEVBQUU7SUFDOUMsSUFBSSxLQUFLLENBQUM7SUFDVixJQUFJLGNBQStCLENBQUM7SUFDcEMsSUFBSSxHQUFHLENBQUM7SUFDUixJQUFJLGlCQUF5QixDQUFDO0lBQzlCLElBQUksaUJBQXlCLENBQUM7SUFDOUIsSUFBSSxPQUFlLENBQUM7SUFFcEIsd0NBQXdDO0lBQ3hDLE1BQU0saUJBQWlCLEdBQUcsR0FBRyxFQUFFO1FBQzdCLGVBQUssQ0FBQyxJQUFJLENBQUMsbUJBQVEsQ0FBQyxTQUFTLEVBQUUsWUFBWSxDQUFDLENBQUMsUUFBUSxDQUFDLElBQUEsc0JBQVMsRUFBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO1FBQzdFLGVBQUssQ0FBQyxJQUFJLENBQUMsbUJBQVEsQ0FBQyxTQUFTLEVBQUUsUUFBUSxDQUFDLENBQUMsUUFBUSxDQUFDLElBQUEsc0JBQVMsRUFBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQ3BFLGVBQUssQ0FBQyxJQUFJLENBQUMsZUFBSyxFQUFFLGFBQWEsQ0FBQyxDQUFDLE9BQU8sQ0FBQztZQUN2QyxRQUFRLEVBQUUsUUFBUSxDQUFDLHVCQUF1QjtZQUMxQyxjQUFjLEVBQUUsUUFB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QUF1RCxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQ3JFLGNBQWMsQ0FBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO1FBQzVCLE1BQU0sR0FBRyxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLDRDQUE0QyxDQUFDLENBQUM7SUFDdEcsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMseURBQXlELEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDdkUsY0FBYyxDQUFDLFNBQVMsR0FBRyxFQUFFLENBQUM7UUFDOUIsTUFBTSxHQUFHLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsOENBQThDLENBQUMsQ0FBQztJQUN4RyxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxpRUFBaUUsRUFBRSxLQUFLLElBQUksRUFBRTtRQUMvRSxjQUFjLENBQUMsZ0JBQWdCLEdBQUcsRUFBRSxDQUFDO1FBQ3JDLE1BQU0sR0FBRyxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLHNEQUFzRCxDQUFDLENBQUM7SUFDaEgsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBzaG91bGQgZnJvbSAnc2hvdWxkJztcbmltcG9ydCAqIGFzIHRlc3REYXRhIGZyb20gJy4uLy4uL3Jlc291cmNlcy9pY3AnO1xuaW1wb3J0IHNpbm9uIGZyb20gJ3Npbm9uJztcbmltcG9ydCB7IFRlc3RCaXRHbyB9IGZyb20gJ0BiaXRnby1iZXRhL3Nkay10ZXN0JztcbmltcG9ydCB7IEJpdEdvQVBJIH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWFwaSc7XG5pbXBvcnQgbm9jayBmcm9tICdub2NrJztcbmltcG9ydCB7IEljcCB9IGZyb20gJy4uLy4uLy4uL3NyYy9pbmRleCc7XG5pbXBvcnQgeyBJY3BBZ2VudCB9IGZyb20gJy4uLy4uLy4uL3NyYy9saWIvaWNwQWdlbnQnO1xuaW1wb3J0IHsgUmVjb3ZlcnlPcHRpb25zLCBMRURHRVJfQ0FOSVNURVJfSUQgfSBmcm9tICcuLi8uLi8uLi9zcmMvbGliL2lmYWNlJztcbmltcG9ydCB7IFByaW5jaXBhbCB9IGZyb20gJ0BkZmluaXR5L3ByaW5jaXBhbCc7XG5pbXBvcnQgQmlnTnVtYmVyIGZyb20gJ2JpZ251bWJlci5qcyc7XG5pbXBvcnQgdXRpbHMgZnJvbSAnLi4vLi4vLi4vc3JjL2xpYi91dGlscyc7XG5cbmRlc2NyaWJlKCdJQ1AgdHJhbnNhY3Rpb24gcmVjb3ZlcnknLCBhc3luYyAoKSA9PiB7XG4gIGxldCBiaXRnbztcbiAgbGV0IHJlY292ZXJ5UGFyYW1zOiBSZWNvdmVyeU9wdGlvbnM7XG4gIGxldCBpY3A7XG4gIGxldCBicm9hZGNhc3RFbmRwb2ludDogc3RyaW5nO1xuICBsZXQgYnJvYWRjYXN0UmVzcG9uc2U6IEJ1ZmZlcjtcbiAgbGV0IG5vZGVVcmw6IHN0cmluZztcblxuICAvLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBzZXR0aW5nIHVwIHN0dWJzXG4gIGNvbnN0IHNldHVwRGVmYXVsdFN0dWJzID0gKCkgPT4ge1xuICAgIHNpbm9uLnN0dWIoSWNwQWdlbnQucHJvdG90eXBlLCAnZ2V0QmFsYW5jZScpLnJlc29sdmVzKEJpZ051bWJlcigxMDAwMDAwMDAwKSk7XG4gICAgc2lub24uc3R1YihJY3BBZ2VudC5wcm90b3R5cGUsICdnZXRGZWUnKS5yZXNvbHZlcyhCaWdOdW1iZXIoMTAwMDApKTtcbiAgICBzaW5vbi5zdHViKHV0aWxzLCAnZ2V0TWV0YURhdGEnKS5yZXR1cm5zKHtcbiAgICAgIG1ldGFEYXRhOiB0ZXN0RGF0YS5NZXRhRGF0YVdpdGhEZWZhdWx0TWVtbyxcbiAgICAgIGluZ3Jlc3NFbmRUaW1lOiB0ZXN0RGF0YS5NZXRhRGF0YVdpdGhEZWZhdWx0TWVtby5pbmdyZXNzX2VuZCA/PyAwLFxuICAgIH0pO1xuICAgIHNpbm9uLnN0dWIoaWNwLCAnc2lnbmF0dXJlcycpLnJldHVybnModGVzdERhdGEuUmVjb3ZlclRyYW5zYWN0aW9uU2lnbmF0dXJlV2l0aERlZmF1bHRNZW1vKTtcbiAgfTtcblxuICBjb25zdCBzZXR1cE1lbW9TdHVicyA9ICgpID0+IHtcbiAgICBzaW5vbi5zdHViKEljcEFnZW50LnByb3RvdHlwZSwgJ2dldEJhbGFuY2UnKS5yZXNvbHZlcyhCaWdOdW1iZXIoMTAwMDAwMDAwMCkpO1xuICAgIHNpbm9uLnN0dWIoSWNwQWdlbnQucHJvdG90eXBlLCAnZ2V0RmVlJykucmVzb2x2ZXMoQmlnTnVtYmVyKDEwMDAwKSk7XG4gICAgc2lub24uc3R1Yih1dGlscywgJ2dldE1ldGFEYXRhJykucmV0dXJucyh7XG4gICAgICBtZXRhRGF0YTogdGVzdERhdGEuTWV0YURhdGFXaXRoTWVtbyxcbiAgICAgIGluZ3Jlc3NFbmRUaW1lOiB0ZXN0RGF0YS5NZXRhRGF0YVdpdGhNZW1vLmluZ3Jlc3NfZW5kID8/IDAsXG4gICAgfSk7XG4gICAgc2lub24uc3R1YihpY3AsICdzaWduYXR1cmVzJykucmV0dXJucyh0ZXN0RGF0YS5SZWNvdmVyVHJhbnNhY3Rpb25TaWduYXR1cmVXaXRoTWVtbyk7XG4gIH07XG5cbiAgY29uc3Qgc2V0dXBMb3dCYWxhbmNlU3R1YnMgPSAoKSA9PiB7XG4gICAgc2lub24uc3R1YihJY3BBZ2VudC5wcm90b3R5cGUsICdnZXRCYWxhbmNlJykucmVzb2x2ZXMoQmlnTnVtYmVyKDEwKSk7XG4gICAgc2lub24uc3R1YihJY3BBZ2VudC5wcm90b3R5cGUsICdnZXRGZWUnKS5yZXNvbHZlcyhCaWdOdW1iZXIoMTAwMDApKTtcbiAgICBzaW5vbi5zdHViKHV0aWxzLCAnZ2V0TWV0YURhdGEnKS5yZXR1cm5zKHtcbiAgICAgIG1ldGFEYXRhOiB0ZXN0RGF0YS5NZXRhRGF0YVdpdGhEZWZhdWx0TWVtbyxcbiAgICAgIGluZ3Jlc3NFbmRUaW1lOiB0ZXN0RGF0YS5NZXRhRGF0YVdpdGhEZWZhdWx0TWVtby5pbmdyZXNzX2VuZCA/PyAwLFxuICAgIH0pO1xuICB9O1xuXG4gIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgYml0Z28gPSBUZXN0Qml0R28uZGVjb3JhdGUoQml0R29BUEksIHsgZW52OiAndGVzdCcgfSk7XG4gICAgYml0Z28uc2FmZVJlZ2lzdGVyKCdpY3AnLCBJY3AuY3JlYXRlSW5zdGFuY2UpO1xuICAgIGJpdGdvLmluaXRpYWxpemVUZXN0VmFycygpO1xuICAgIHJlY292ZXJ5UGFyYW1zID0ge1xuICAgICAgdXNlcktleTogdGVzdERhdGEuV1JXUmVjb3ZlcnkudXNlcktleSxcbiAgICAgIGJhY2t1cEtleTogdGVzdERhdGEuV1JXUmVjb3ZlcnkuYmFja3VwS2V5LFxuICAgICAgd2FsbGV0UGFzc3BocmFzZTogdGVzdERhdGEuV1JXUmVjb3Zlcnkud2FsbGV0UGFzc3BocmFzZSxcbiAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IHRlc3REYXRhLkFjY291bnRzLmFjY291bnQyLmFkZHJlc3MsXG4gICAgfTtcblxuICAgIGljcCA9IGJpdGdvLmNvaW4oJ2ljcCcpO1xuICAgIG5vZGVVcmwgPSBpY3AuZ2V0UHVibGljTm9kZVVybCgpO1xuICAgIGNvbnN0IHByaW5jaXBhbCA9IFByaW5jaXBhbC5mcm9tVWludDhBcnJheShMRURHRVJfQ0FOSVNURVJfSUQpO1xuICAgIGNvbnN0IGNhbmlzdGVySWRIZXggPSBwcmluY2lwYWwudG9UZXh0KCk7XG4gICAgYnJvYWRjYXN0RW5kcG9pbnQgPSBgL2FwaS92My9jYW5pc3Rlci8ke2NhbmlzdGVySWRIZXh9L2NhbGxgO1xuICAgIGJyb2FkY2FzdFJlc3BvbnNlID0gQnVmZmVyLmZyb20odGVzdERhdGEuUHVibGljTm9kZUFwaUJyb2FkY2FzdFJlc3BvbnNlLCAnaGV4Jyk7XG4gIH0pO1xuXG4gIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgIHNldHVwRGVmYXVsdFN0dWJzKCk7XG4gICAgLy8gU2V0IHVwIGRlZmF1bHQgc3VjY2Vzc2Z1bCBub2NrIHJlc3BvbnNlXG4gICAgbm9jayhub2RlVXJsKS5wb3N0KGJyb2FkY2FzdEVuZHBvaW50KS5yZXBseSgyMDAsIGJyb2FkY2FzdFJlc3BvbnNlKTtcbiAgfSk7XG5cbiAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICByZWNvdmVyeVBhcmFtcyA9IHtcbiAgICAgIHVzZXJLZXk6IHRlc3REYXRhLldSV1JlY292ZXJ5LnVzZXJLZXksXG4gICAgICBiYWNrdXBLZXk6IHRlc3REYXRhLldSV1JlY292ZXJ5LmJhY2t1cEtleSxcbiAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHRlc3REYXRhLldSV1JlY292ZXJ5LndhbGxldFBhc3NwaHJhc2UsXG4gICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiB0ZXN0RGF0YS5BY2NvdW50cy5hY2NvdW50Mi5hZGRyZXNzLFxuICAgIH07XG4gICAgbm9jay5jbGVhbkFsbCgpO1xuICAgIHNpbm9uLnJlc3RvcmUoKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCByZWNvdmVyIGEgdHJhbnNhY3Rpb24gd2l0aCBkZWZhdWx0IG1lbW8gc3VjY2Vzc2Z1bGx5JywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHJlY292ZXJUeG4gPSBhd2FpdCBpY3AucmVjb3ZlcihyZWNvdmVyeVBhcmFtcyk7XG4gICAgcmVjb3ZlclR4bi5pZC5zaG91bGQuYmUuYS5TdHJpbmcoKTtcbiAgICBzaG91bGQuZXF1YWwocmVjb3ZlclR4bi5pZCwgdGVzdERhdGEuVHhuSWRXaXRoRGVmYXVsdE1lbW8pO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHJlY292ZXIgYSB0cmFuc2FjdGlvbiB3aXRoIG1lbW8gc3VjY2Vzc2Z1bGx5JywgYXN5bmMgKCkgPT4ge1xuICAgIHNpbm9uLnJlc3RvcmUoKTtcbiAgICBzZXR1cE1lbW9TdHVicygpO1xuICAgIHJlY292ZXJ5UGFyYW1zLm1lbW8gPSB0ZXN0RGF0YS5NZXRhRGF0YVdpdGhNZW1vLm1lbW87XG4gICAgY29uc3QgcmVjb3ZlclR4biA9IGF3YWl0IGljcC5yZWNvdmVyKHJlY292ZXJ5UGFyYW1zKTtcbiAgICByZWNvdmVyVHhuLmlkLnNob3VsZC5iZS5hLlN0cmluZygpO1xuICAgIHNob3VsZC5lcXVhbChyZWNvdmVyVHhuLmlkLCB0ZXN0RGF0YS5UeG5JZFdpdGhNZW1vKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCByZWNvdmVyIGEgdW5zaWduZWQgc3dlZXAgdHJhbnNhY3Rpb24gc3VjY2Vzc2Z1bGx5JywgYXN5bmMgKCkgPT4ge1xuICAgIHNpbm9uLnJlc3RvcmUoKTtcbiAgICBzZXR1cE1lbW9TdHVicygpO1xuXG4gICAgY29uc3QgdW5zaWduZWRTd2VlcFJlY292ZXJ5UGFyYW1zID0ge1xuICAgICAgYml0Z29LZXk6XG4gICAgICAgICcwMzEwNzY4NzM2YTAwNWVhNTM2NGUxYjViNTI4OGNmNTUzMjI0ZGQyOGIyZGY4Y2VkNjNiNzJhODAyMDQ3ODk2N2YwNWVjNWJjZTFmMjZjZDdlYjAwOWE0YmVhNDQ1YmI1NWMyZjU0YTMwZjI3MDZjMWEzNzQ3ZThkZjJkMjg4ODI5JyxcbiAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IHRlc3REYXRhLkFjY291bnRzLmFjY291bnQyLmFkZHJlc3MsXG4gICAgfTtcbiAgICBjb25zdCByZWNvdmVyVHhuID0gYXdhaXQgaWNwLnJlY292ZXIodW5zaWduZWRTd2VlcFJlY292ZXJ5UGFyYW1zKTtcbiAgICByZWNvdmVyVHhuLnR4SGV4LnNob3VsZC5iZS5hLlN0cmluZygpO1xuICAgIHNob3VsZC5lcXVhbChyZWNvdmVyVHhuLnR4SGV4LCB0ZXN0RGF0YS5VbnNpZ25lZFN3ZWVwVHJhbnNhY3Rpb24pO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGZhaWxlZCB0byByZWNvdmVyIGEgdW5zaWduZWQgc3dlZXAgdHJhbnNhY3Rpb24gd2l0aCB3cm9uZyBiaXRnbyBrZXknLCBhc3luYyAoKSA9PiB7XG4gICAgc2lub24ucmVzdG9yZSgpO1xuICAgIHNldHVwTWVtb1N0dWJzKCk7XG5cbiAgICBjb25zdCB1bnNpZ25lZFN3ZWVwUmVjb3ZlcnlQYXJhbXMgPSB7XG4gICAgICBiaXRnb0tleTogJ3Rlc3RLZXknLFxuICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogdGVzdERhdGEuQWNjb3VudHMuYWNjb3VudDIuYWRkcmVzcyxcbiAgICB9O1xuICAgIGF3YWl0IGljcFxuICAgICAgLnJlY292ZXIodW5zaWduZWRTd2VlcFJlY292ZXJ5UGFyYW1zKVxuICAgICAgLnNob3VsZC5yZWplY3RlZFdpdGgoJ0Vycm9yIGR1cmluZyBJQ1AgcmVjb3Zlcnk6IENhbm5vdCBjb252ZXJ0IDB4IHRvIGEgQmlnSW50Jyk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgZmFpbGVkIHRvIHJlY292ZXIgcmVjb3ZlciBhIHVuc2lnbmVkIHN3ZWVwIHRyYW5zYWN0aW9uIHdpdGhvdXQgYml0Z28ga2V5JywgYXN5bmMgKCkgPT4ge1xuICAgIHNpbm9uLnJlc3RvcmUoKTtcbiAgICBzZXR1cE1lbW9TdHVicygpO1xuXG4gICAgY29uc3QgdW5zaWduZWRTd2VlcFJlY292ZXJ5UGFyYW1zID0ge1xuICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogdGVzdERhdGEuQWNjb3VudHMuYWNjb3VudDIuYWRkcmVzcyxcbiAgICB9O1xuICAgIGF3YWl0IGljcC5yZWNvdmVyKHVuc2lnbmVkU3dlZXBSZWNvdmVyeVBhcmFtcykuc2hvdWxkLnJlamVjdGVkV2l0aCgnRXJyb3IgZHVyaW5nIElDUCByZWNvdmVyeTogbWlzc2luZyBiaXRnb0tleScpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGZhaWwgdG8gcmVjb3ZlciBpZiBicm9hZGNhc3QgQVBJIGZhaWxzJywgYXN5bmMgKCkgPT4ge1xuICAgIG5vY2suY2xlYW5BbGwoKTtcbiAgICBub2NrKG5vZGVVcmwpLnBvc3QoYnJvYWRjYXN0RW5kcG9pbnQpLnJlcGx5KDUwMCwgJ0ludGVybmFsIFNlcnZlciBFcnJvcicpO1xuICAgIHJlY292ZXJ5UGFyYW1zLm1lbW8gPSAwO1xuICAgIGF3YWl0IGljcFxuICAgICAgLnJlY292ZXIocmVjb3ZlcnlQYXJhbXMpXG4gICAgICAuc2hvdWxkLnJlamVjdGVkV2l0aChcbiAgICAgICAgJ0Vycm9yIGR1cmluZyBJQ1AgcmVjb3Zlcnk6IFRyYW5zYWN0aW9uIGJyb2FkY2FzdCBlcnJvcjogUmVxdWVzdCBmYWlsZWQgd2l0aCBzdGF0dXMgY29kZSA1MDAnXG4gICAgICApO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGZhaWwgdG8gcmVjb3ZlciB0eG4gaWYgYmFsYW5jZSBpcyBsb3cnLCBhc3luYyAoKSA9PiB7XG4gICAgc2lub24ucmVzdG9yZSgpO1xuICAgIHNldHVwTG93QmFsYW5jZVN0dWJzKCk7XG4gICAgYXdhaXQgaWNwXG4gICAgICAucmVjb3ZlcihyZWNvdmVyeVBhcmFtcylcbiAgICAgIC5zaG91bGQucmVqZWN0ZWRXaXRoKCdFcnJvciBkdXJpbmcgSUNQIHJlY292ZXJ5OiBEaWQgbm90IGhhdmUgZW5vdWdoIGZ1bmRzIHRvIHJlY292ZXInKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBmYWlsIHRvIHJlY292ZXIgdHhuIGlmIHVzZXJLZXkgaXMgbm90IHByb3ZpZGVkJywgYXN5bmMgKCkgPT4ge1xuICAgIHJlY292ZXJ5UGFyYW1zLnVzZXJLZXkgPSAnJztcbiAgICBhd2FpdCBpY3AucmVjb3ZlcihyZWNvdmVyeVBhcmFtcykuc2hvdWxkLnJlamVjdGVkV2l0aCgnRXJyb3IgZHVyaW5nIElDUCByZWNvdmVyeTogbWlzc2luZyB1c2VyS2V5Jyk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgZmFpbCB0byByZWNvdmVyIHR4biBpZiBiYWNrdXBLZXkgaXMgbm90IHByb3ZpZGVkJywgYXN5bmMgKCkgPT4ge1xuICAgIHJlY292ZXJ5UGFyYW1zLmJhY2t1cEtleSA9ICcnO1xuICAgIGF3YWl0IGljcC5yZWNvdmVyKHJlY292ZXJ5UGFyYW1zKS5zaG91bGQucmVqZWN0ZWRXaXRoKCdFcnJvciBkdXJpbmcgSUNQIHJlY292ZXJ5OiBtaXNzaW5nIGJhY2t1cEtleScpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGZhaWwgdG8gcmVjb3ZlciB0eG4gaWYgd2FsbGV0IHBhc3NwaHJhc2UgaXMgbm90IHByb3ZpZGVkJywgYXN5bmMgKCkgPT4ge1xuICAgIHJlY292ZXJ5UGFyYW1zLndhbGxldFBhc3NwaHJhc2UgPSAnJztcbiAgICBhd2FpdCBpY3AucmVjb3ZlcihyZWNvdmVyeVBhcmFtcykuc2hvdWxkLnJlamVjdGVkV2l0aCgnRXJyb3IgZHVyaW5nIElDUCByZWNvdmVyeTogbWlzc2luZyB3YWxsZXQgcGFzc3BocmFzZScpO1xuICB9KTtcbn0pO1xuIl19
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../test/unit/utils.ts"],"names":[],"mappings":""}
@@ -0,0 +1,206 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const should_1 = __importDefault(require("should"));
7
+ const utils_1 = __importDefault(require("../../src/lib/utils"));
8
+ const icp_1 = require("../resources/icp");
9
+ const { encode } = require('cbor-x/index-no-eval');
10
+ const crypto_1 = require("crypto");
11
+ describe('utils', () => {
12
+ describe('isValidAddress()', () => {
13
+ it('should validate addresses correctly', () => {
14
+ should_1.default.equal(utils_1.default.isValidAddress(icp_1.Accounts.account1.address), true);
15
+ should_1.default.equal(utils_1.default.isValidAddress(icp_1.Accounts.account2.address), true);
16
+ should_1.default.equal(utils_1.default.isValidAddress(icp_1.Accounts.account3.address), true);
17
+ should_1.default.equal(utils_1.default.isValidAddress(icp_1.Accounts.account4.address), true);
18
+ should_1.default.equal(utils_1.default.isValidAddress(icp_1.Accounts.account5.address), true);
19
+ should_1.default.equal(utils_1.default.isValidAddress(icp_1.Accounts.account6.address), true);
20
+ });
21
+ it('should invalidate wrong addresses correctly', () => {
22
+ should_1.default.equal(utils_1.default.isValidAddress(icp_1.Accounts.errorsAccounts.account1.address), false);
23
+ should_1.default.equal(utils_1.default.isValidAddress(icp_1.Accounts.errorsAccounts.account2.address), false);
24
+ should_1.default.equal(utils_1.default.isValidAddress(icp_1.Accounts.errorsAccounts.account3.address), false);
25
+ should_1.default.equal(utils_1.default.isValidAddress(icp_1.Accounts.errorsAccounts.account4.address), false);
26
+ should_1.default.equal(utils_1.default.isValidAddress(icp_1.Accounts.errorsAccounts.account5.address), false);
27
+ should_1.default.equal(utils_1.default.isValidAddress(icp_1.Accounts.errorsAccounts.account6.address), false);
28
+ });
29
+ });
30
+ describe('isValidBlockId()', () => {
31
+ it('should validate block hashes correctly', () => {
32
+ should_1.default.equal(utils_1.default.isValidBlockId(icp_1.BlockHashes.validHashes.block1), true);
33
+ should_1.default.equal(utils_1.default.isValidBlockId(icp_1.BlockHashes.validHashes.block2), true);
34
+ should_1.default.equal(utils_1.default.isValidBlockId(icp_1.BlockHashes.validHashes.block3), true);
35
+ });
36
+ });
37
+ describe('isValidTransactionId()', () => {
38
+ it('should validate transaction hashes correctly', () => {
39
+ should_1.default.equal(utils_1.default.isValidBlockId(icp_1.TransactionHashes.validHashes.txId1), true);
40
+ should_1.default.equal(utils_1.default.isValidBlockId(icp_1.TransactionHashes.validHashes.txId2), true);
41
+ should_1.default.equal(utils_1.default.isValidBlockId(icp_1.TransactionHashes.validHashes.txId3), true);
42
+ });
43
+ });
44
+ describe('gasData()', () => {
45
+ it('should return correct gas data', () => {
46
+ should_1.default.equal(utils_1.default.feeData(), '-10000');
47
+ });
48
+ });
49
+ describe('isValidPublicKey()', () => {
50
+ it('should validate public key correctly', () => {
51
+ should_1.default.equal(utils_1.default.isValidPublicKey(icp_1.Accounts.account1.publicKey), true);
52
+ should_1.default.equal(utils_1.default.isValidPublicKey(icp_1.Accounts.account2.publicKey), true);
53
+ should_1.default.equal(utils_1.default.isValidPublicKey(icp_1.Accounts.account3.publicKey), true);
54
+ should_1.default.equal(utils_1.default.isValidPublicKey(icp_1.Accounts.account4.publicKey), true);
55
+ should_1.default.equal(utils_1.default.isValidPublicKey(icp_1.Accounts.account5.publicKey), true);
56
+ should_1.default.equal(utils_1.default.isValidPublicKey(icp_1.Accounts.account6.publicKey), true);
57
+ });
58
+ it('should invalidate public key correctly', () => {
59
+ should_1.default.equal(utils_1.default.isValidPublicKey(icp_1.Accounts.errorsAccounts.account1.publicKey), false);
60
+ should_1.default.equal(utils_1.default.isValidPublicKey(icp_1.Accounts.errorsAccounts.account2.publicKey), false);
61
+ should_1.default.equal(utils_1.default.isValidPublicKey(icp_1.Accounts.errorsAccounts.account3.publicKey), false);
62
+ should_1.default.equal(utils_1.default.isValidPublicKey(icp_1.Accounts.errorsAccounts.account4.publicKey), false);
63
+ should_1.default.equal(utils_1.default.isValidPublicKey(icp_1.Accounts.errorsAccounts.account5.publicKey), false);
64
+ should_1.default.equal(utils_1.default.isValidPublicKey(icp_1.Accounts.errorsAccounts.account6.publicKey), false);
65
+ });
66
+ });
67
+ describe('cborEncode()', () => {
68
+ it('should correctly encode an object', () => {
69
+ const value = { key: 'value' };
70
+ const expectedHex = Buffer.from(encode(value)).toString('hex');
71
+ should_1.default.equal(utils_1.default.cborEncode(value), expectedHex);
72
+ });
73
+ it('should encode and decode a big number correctly', () => {
74
+ const original = { number: BigInt(1740680777458000000) };
75
+ const encoded = encode(original);
76
+ const decoded = utils_1.default.cborDecode(encoded);
77
+ should_1.default.deepEqual(decoded, original);
78
+ });
79
+ });
80
+ describe('cborDecode()', () => {
81
+ it('should correctly decode a CBOR-encoded object', () => {
82
+ const original = { key: 'value', number: 100 };
83
+ const encoded = encode(original);
84
+ const decoded = utils_1.default.cborDecode(encoded);
85
+ should_1.default.deepEqual(decoded, original);
86
+ });
87
+ });
88
+ describe('isValidLength()', () => {
89
+ it('should return true for a valid compressed public key length (66 characters)', () => {
90
+ should_1.default.equal(utils_1.default.isValidLength('a'.repeat(66)), true);
91
+ });
92
+ });
93
+ describe('isValidHex()', () => {
94
+ it('should return true for a valid hexadecimal string', () => {
95
+ should_1.default.equal(utils_1.default.isValidHex('abcdef1234567890ABCDEF'), true);
96
+ });
97
+ });
98
+ describe('hexToBytes()', () => {
99
+ it('should correctly convert a valid hexadecimal string to a Uint8Array', () => {
100
+ const hex = 'abcdef123456';
101
+ const expected = new Uint8Array([0xab, 0xcd, 0xef, 0x12, 0x34, 0x56]);
102
+ should_1.default.deepEqual(utils_1.default.hexToBytes(hex), expected);
103
+ });
104
+ });
105
+ describe('isValidPrivateKey()', () => {
106
+ it('should validate private key correctly', () => {
107
+ should_1.default.equal(utils_1.default.isValidPrivateKey(icp_1.Accounts.account1.secretKey), true);
108
+ should_1.default.equal(utils_1.default.isValidPrivateKey(icp_1.Accounts.account2.secretKey), true);
109
+ should_1.default.equal(utils_1.default.isValidPrivateKey(icp_1.Accounts.account3.secretKey), true);
110
+ should_1.default.equal(utils_1.default.isValidPrivateKey(icp_1.Accounts.account4.secretKey), true);
111
+ should_1.default.equal(utils_1.default.isValidPrivateKey(icp_1.Accounts.account5.secretKey), true);
112
+ should_1.default.equal(utils_1.default.isValidPrivateKey(icp_1.Accounts.account6.secretKey), true);
113
+ });
114
+ it('should invalidate private key correctly', () => {
115
+ should_1.default.equal(utils_1.default.isValidPrivateKey(icp_1.Accounts.errorsAccounts.account1.secretKey), false);
116
+ should_1.default.equal(utils_1.default.isValidPrivateKey(icp_1.Accounts.errorsAccounts.account2.secretKey), false);
117
+ should_1.default.equal(utils_1.default.isValidPrivateKey(icp_1.Accounts.errorsAccounts.account3.secretKey), false);
118
+ should_1.default.equal(utils_1.default.isValidPrivateKey(icp_1.Accounts.errorsAccounts.account4.secretKey), false);
119
+ should_1.default.equal(utils_1.default.isValidPrivateKey(icp_1.Accounts.errorsAccounts.account5.secretKey), false);
120
+ should_1.default.equal(utils_1.default.isValidPrivateKey(icp_1.Accounts.errorsAccounts.account6.secretKey), false);
121
+ });
122
+ });
123
+ describe('getAddressFromPublicKey()', () => {
124
+ it('should return the correct address for a valid public key', () => {
125
+ const address1 = utils_1.default.getAddressFromPublicKey(icp_1.Accounts.account1.publicKey);
126
+ should_1.default.equal(address1, icp_1.Accounts.account1.address);
127
+ const address2 = utils_1.default.getAddressFromPublicKey(icp_1.Accounts.account1.publicKey);
128
+ should_1.default.equal(address2, icp_1.Accounts.account1.address);
129
+ const address3 = utils_1.default.getAddressFromPublicKey(icp_1.Accounts.account1.publicKey);
130
+ should_1.default.equal(address3, icp_1.Accounts.account1.address);
131
+ const address4 = utils_1.default.getAddressFromPublicKey(icp_1.Accounts.account1.publicKey);
132
+ should_1.default.equal(address4, icp_1.Accounts.account1.address);
133
+ const address5 = utils_1.default.getAddressFromPublicKey(icp_1.Accounts.account1.publicKey);
134
+ should_1.default.equal(address5, icp_1.Accounts.account1.address);
135
+ const address6 = utils_1.default.getAddressFromPublicKey(icp_1.Accounts.account1.publicKey);
136
+ should_1.default.equal(address6, icp_1.Accounts.account1.address);
137
+ });
138
+ it('should throw an error for an invalid public key', () => {
139
+ (() => utils_1.default.getAddressFromPublicKey(icp_1.Accounts.errorsAccounts.account1.publicKey)).should.throw('Invalid hex-encoded public key format.');
140
+ });
141
+ });
142
+ describe('generateKeyPair()', () => {
143
+ it('should generate a valid key pair without a seed', () => {
144
+ const keyPair = utils_1.default.generateKeyPair();
145
+ should_1.default.exist(keyPair);
146
+ should_1.default.exist(keyPair.pub);
147
+ should_1.default.exist(keyPair.prv);
148
+ });
149
+ it('should generate a valid key pair with a given seed', () => {
150
+ const seed = (0, crypto_1.randomBytes)(32);
151
+ const keyPair = utils_1.default.generateKeyPair(seed);
152
+ should_1.default.exist(keyPair);
153
+ should_1.default.exist(keyPair.pub);
154
+ should_1.default.exist(keyPair.prv);
155
+ });
156
+ it('should generate different key pairs for different seeds', () => {
157
+ const seed1 = (0, crypto_1.randomBytes)(32);
158
+ const seed2 = (0, crypto_1.randomBytes)(32);
159
+ const keyPair1 = utils_1.default.generateKeyPair(seed1);
160
+ const keyPair2 = utils_1.default.generateKeyPair(seed2);
161
+ should_1.default.notEqual(keyPair1.pub, keyPair2.pub);
162
+ should_1.default.notEqual(keyPair1.prv, keyPair2.prv);
163
+ });
164
+ it('should generate the same key pair for the same seed', () => {
165
+ const seed = (0, crypto_1.randomBytes)(32);
166
+ const keyPair1 = utils_1.default.generateKeyPair(seed);
167
+ const keyPair2 = utils_1.default.generateKeyPair(seed);
168
+ should_1.default.equal(keyPair1.pub, keyPair2.pub);
169
+ should_1.default.equal(keyPair1.prv, keyPair2.prv);
170
+ });
171
+ });
172
+ describe('validateRawTransaction()', () => {
173
+ const data = icp_1.IcpTransactionData;
174
+ it('should validate icpTransactionData correctly', () => {
175
+ utils_1.default.validateRawTransaction(data);
176
+ });
177
+ it('should throw an error for invalid expiryTime', () => {
178
+ (data.expiryTime = Date.now()), should_1.default.throws(() => utils_1.default.validateRawTransaction(data), 'Invalid expiry time');
179
+ });
180
+ it('should throw an error for invalid fee', () => {
181
+ data.fee = '-100';
182
+ should_1.default.throws(() => utils_1.default.validateRawTransaction(data), 'Invalid fee value');
183
+ });
184
+ it('should throw an error for invalid amount', () => {
185
+ data.amount = '0';
186
+ should_1.default.throws(() => utils_1.default.validateRawTransaction(data), 'amount cannot be less than or equal to zero');
187
+ });
188
+ });
189
+ describe('getTransactionId()', () => {
190
+ const sender = '47867f2cfb85094275c847435fa10cad54a813eba7e6a9bc3538aa2f537f1d73';
191
+ const receiver = 'a1c60efca988c411cd7bc5e481364b9c94caebb24c00e01db269e3a0541ee498';
192
+ it('should return the correct transaction hash for amount less than 2^32 (amount = 1000)', () => {
193
+ const unsignedTransaction = 'b90002677570646174657381826b5452414e53414354494f4eb900056b63616e69737465725f69644a000000000000000201016b6d6574686f645f6e616d656773656e645f70626361726758400a02080012050a0308e8071a0308904e2a220a20a1c60efca988c411cd7bc5e481364b9c94caebb24c00e01db269e3a0541ee4983a0a088084a8a988e4f4a0186673656e646572581da905b86bba9bfed194ac8c12377b5d48847128dbfff10f01adb80f7f026e696e67726573735f6578706972791b000000000000000070696e67726573735f6578706972696573811b1841d35866476200';
194
+ const transactionHash = utils_1.default.getTransactionId(unsignedTransaction, sender, receiver);
195
+ const expectedTransactionHash = 'bb502d0566f726da02a1925415f68cb6f175cdd6cba1e09823143078715b2ba4';
196
+ should_1.default.equal(transactionHash, expectedTransactionHash);
197
+ });
198
+ it('should return the correct transaction hash for amount greater than 2^32 (amount = 6948150200)', () => {
199
+ const unsignedTransaction = 'b90002677570646174657381826b5452414e53414354494f4eb900056b63616e69737465725f69644a000000000000000201016b6d6574686f645f6e616d656773656e645f70626361726758430a02080012080a0608b8b791f1191a0308904e2a220a20a1c60efca988c411cd7bc5e481364b9c94caebb24c00e01db269e3a0541ee4983a0a0880b8a789bfebf4a0186673656e646572581da905b86bba9bfed194ac8c12377b5d48847128dbfff10f01adb80f7f026e696e67726573735f6578706972791b000000000000000070696e67726573735f6578706972696573811b1841d393d2473c00';
200
+ const transactionHash = utils_1.default.getTransactionId(unsignedTransaction, sender, receiver);
201
+ const expectedTransactionHash = '016411110006d4645cbcb553a84efdec6c402847f856caa909111d81bb513565';
202
+ should_1.default.equal(transactionHash, expectedTransactionHash);
203
+ });
204
+ });
205
+ });
206
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90ZXN0L3VuaXQvdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxvREFBNEI7QUFDNUIsZ0VBQXdDO0FBQ3hDLDBDQUFnRztBQUNoRyxNQUFNLEVBQUUsTUFBTSxFQUFFLEdBQUcsT0FBTyxDQUFDLHNCQUFzQixDQUFDLENBQUM7QUFDbkQsbUNBQXFDO0FBRXJDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsR0FBRyxFQUFFO0lBQ3JCLFFBQVEsQ0FBQyxrQkFBa0IsRUFBRSxHQUFHLEVBQUU7UUFDaEMsRUFBRSxDQUFDLHFDQUFxQyxFQUFFLEdBQUcsRUFBRTtZQUM3QyxnQkFBTSxDQUFDLEtBQUssQ0FBQyxlQUFLLENBQUMsY0FBYyxDQUFDLGNBQVEsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDcEUsZ0JBQU0sQ0FBQyxLQUFLLENBQUMsZUFBSyxDQUFDLGNBQWMsQ0FBQyxjQUFRLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ3BFLGdCQUFNLENBQUMsS0FBSyxDQUFDLGVBQUssQ0FBQyxjQUFjLENBQUMsY0FBUSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztZQUNwRSxnQkFBTSxDQUFDLEtBQUssQ0FBQyxlQUFLLENBQUMsY0FBYyxDQUFDLGNBQVEsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDcEUsZ0JBQU0sQ0FBQyxLQUFLLENBQUMsZUFBSyxDQUFDLGNBQWMsQ0FBQyxjQUFRLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ3BFLGdCQUFNLENBQUMsS0FBSyxDQUFDLGVBQUssQ0FBQyxjQUFjLENBQUMsY0FBUSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMs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Q0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLDJCQUEyQixFQUFFLEdBQUcsRUFBRTtRQUN6QyxFQUFFLENBQUMsMERBQTBELEVBQUUsR0FBRyxFQUFFO1lBQ2xFLE1BQU0sUUFBUSxHQUFHLGVBQUssQ0FBQyx1QkFBdUIsQ0FBQyxjQUFRLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQzVFLGdCQUFNLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxjQUFRLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ2xELE1BQU0sUUFBUSxHQUFHLGVBQUssQ0FBQyx1QkFBdUIsQ0FBQyxjQUFRLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQzVFLGdCQUFNLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxjQUFRLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ2xELE1BQU0sUUFBUSxHQUFHLGVBQUssQ0FBQyx1QkFBdUIsQ0FBQyxjQUFRLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQzVFLGdCQUFNLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxjQUFRLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ2xELE1BQU0sUUFBUSxHQUFHLGVBQUssQ0FBQyx1QkFBdUIsQ0FBQyxjQUFRLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQzVFLGdCQUFNLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxjQUFRLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ2xELE1BQU0sUUFBUSxHQUFHLGVBQUssQ0FBQyx1QkFBdUIsQ0FBQyxjQUFRLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQzVFLGdCQUFNLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxjQUFRLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ2xELE1BQU0sUUFBUSxHQUFHLGVBQUssQ0FBQyx1QkFBdUIsQ0FBQyxjQUFRLENBQUMsUUFBUSxDQUFDLFNB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QUcsZUFBSyxDQUFDLGdCQUFnQixDQUFDLG1CQUFtQixFQUFFLE1BQU0sRUFBRSxRQUFRLENBQUMsQ0FBQztZQUN0RixNQUFNLHVCQUF1QixHQUFHLGtFQUFrRSxDQUFDO1lBQ25HLGdCQUFNLENBQUMsS0FBSyxDQUFDLGVBQWUsRUFBRSx1QkFBdUIsQ0FBQyxDQUFDO1FBQ3pELENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLCtGQUErRixFQUFFLEdBQUcsRUFBRTtZQUN2RyxNQUFNLG1CQUFtQixHQUN2QixvZEFBb2QsQ0FBQztZQUN2ZCxNQUFNLGVBQWUsR0FBRyxlQUFLLENBQUMsZ0JBQWdCLENBQUMsbUJBQW1CLEVBQUUsTUFBTSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBQ3RGLE1BQU0sdUJBQXVCLEdBQUcsa0VBQWtFLENBQUM7WUFDbkcsZ0JBQU0sQ0FBQyxLQUFLLENBQUMsZUFBZSxFQUFFLHVCQUF1QixDQUFDLENBQUM7UUFDekQsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHNob3VsZCBmcm9tICdzaG91bGQnO1xuaW1wb3J0IHV0aWxzIGZyb20gJy4uLy4uL3NyYy9saWIvdXRpbHMnO1xuaW1wb3J0IHsgQWNjb3VudHMsIEljcFRyYW5zYWN0aW9uRGF0YSwgQmxvY2tIYXNoZXMsIFRyYW5zYWN0aW9uSGFzaGVzIH0gZnJvbSAnLi4vcmVzb3VyY2VzL2ljcCc7XG5jb25zdCB7IGVuY29kZSB9ID0gcmVxdWlyZSgnY2Jvci14L2luZGV4LW5vLWV2YWwnKTtcbmltcG9ydCB7IHJhbmRvbUJ5dGVzIH0gZnJvbSAnY3J5cHRvJztcblxuZGVzY3JpYmUoJ3V0aWxzJywgKCkgPT4ge1xuICBkZXNjcmliZSgnaXNWYWxpZEFkZHJlc3MoKScsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIHZhbGlkYXRlIGFkZHJlc3NlcyBjb3JyZWN0bHknLCAoKSA9PiB7XG4gICAgICBzaG91bGQuZXF1YWwodXRpbHMuaXNWYWxpZEFkZHJlc3MoQWNjb3VudHMuYWNjb3VudDEuYWRkcmVzcyksIHRydWUpO1xuICAgICAgc2hvdWxkLmVxdWFsKHV0aWxzLmlzVmFsaWRBZGRyZXNzKEFjY291bnRzLmFjY291bnQyLmFkZHJlc3MpLCB0cnVlKTtcbiAgICAgIHNob3VsZC5lcXVhbCh1dGlscy5pc1ZhbGlkQWRkcmVzcyhBY2NvdW50cy5hY2NvdW50My5hZGRyZXNzKSwgdHJ1ZSk7XG4gICAgICBzaG91bGQuZXF1YWwodXRpbHMuaXNWYWxpZEFkZHJlc3MoQWNjb3VudHMuYWNjb3VudDQuYWRkcmVzcyksIHRydWUpO1xuICAgICAgc2hvdWxkLmVxdWFsKHV0aWxzLmlzVmFsaWRBZGRyZXNzKEFjY291bnRzLmFjY291bnQ1LmFkZHJlc3MpLCB0cnVlKTtcbiAgICAgIHNob3VsZC5lcXVhbCh1dGlscy5pc1ZhbGlkQWRkcmVzcyhBY2NvdW50cy5hY2NvdW50Ni5hZGRyZXNzKSwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGludmFsaWRhdGUgd3JvbmcgYWRkcmVzc2VzIGNvcnJlY3RseScsICgpID0+IHtcbiAgICAgIHNob3VsZC5lcXVhbCh1dGlscy5pc1ZhbGlkQWRkcmVzcyhBY2NvdW50cy5lcnJvcnNBY2NvdW50cy5hY2NvdW50MS5hZGRyZXNzKSwgZmFsc2UpO1xuICAgICAgc2hvdWxkLmVxdWFsKHV0aWxzLmlzVmFsaWRBZGRyZXNzKEFjY291bnRzLmVycm9yc0FjY291bnRzLmFjY291bnQyLmFkZHJlc3MpLCBmYWxzZSk7XG4gICAgICBzaG91bGQuZXF1YWwodXRpbHMuaXNWYWxpZEFkZHJlc3MoQWNjb3VudHMuZXJyb3JzQWNjb3VudHMuYWNjb3VudDMuYWRkcmVzcyksIGZhbHNlKTtcbiAgICAgIHNob3VsZC5lcXVhbCh1dGlscy5pc1ZhbGlkQWRkcmVzcyhBY2NvdW50cy5lcnJvcnNBY2NvdW50cy5hY2NvdW50NC5hZGRyZXNzKSwgZmFsc2UpO1xuICAgICAgc2hvdWxkLmVxdWFsKHV0aWxzLmlzVmFsaWRBZGRyZXNzKEFjY291bnRzLmVycm9yc0FjY291bnRzLmFjY291bnQ1LmFkZHJlc3MpLCBmYWxzZSk7XG4gICAgICBzaG91bGQuZXF1YWwodXRpbHMuaXNWYWxpZEFkZHJlc3MoQWNjb3VudHMuZXJyb3JzQWNjb3VudHMuYWNjb3VudDYuYWRkcmVzcyksIGZhbHNlKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2lzVmFsaWRCbG9ja0lkKCknLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCB2YWxpZGF0ZSBibG9jayBoYXNoZXMgY29ycmVjdGx5JywgKCkgPT4ge1xuICAgICAgc2hvdWxkLmVxdWFsKHV0aWxzLmlzVmFsaWRCbG9ja0lkKEJsb2NrSGFzaGVzLnZhbGlkSGFzaGVzLmJsb2NrMSksIHRydWUpO1xuICAgICAgc2hvdWxkLmVxdWFsKHV0aWxzLmlzVmFsaWRCbG9ja0lkKEJsb2NrSGFzaGVzLnZhbGlkSGFzaGVzLmJsb2NrMiksIHRydWUpO1xuICAgICAgc2hvdWxkLmVxdWFsKHV0aWxzLmlzVmFsaWRCbG9ja0lkKEJsb2NrSGFzaGVzLnZhbGlkSGFzaGVzLmJsb2NrMyksIHRydWUpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnaXNWYWxpZFRyYW5zYWN0aW9uSWQoKScsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIHZhbGlkYXRlIHRyYW5zYWN0aW9uIGhhc2hlcyBjb3JyZWN0bHknLCAoKSA9PiB7XG4gICAgICBzaG91bGQuZXF1YWwodXRpbHMuaXNWYWxpZEJsb2NrSWQoVHJhbnNhY3Rpb25IYXNoZXMudmFsaWRIYXNoZXMudHhJZDEpLCB0cnVlKTtcbiAgICAgIHNob3VsZC5lcXVhbCh1dGlscy5pc1ZhbGlkQmxvY2tJZChUcmFuc2FjdGlvbkhhc2hlcy52YWxpZEhhc2hlcy50eElkMiksIHRydWUpO1xuICAgICAgc2hvdWxkLmVxdWFsKHV0aWxzLmlzVmFsaWRCbG9ja0lkKFRyYW5zYWN0aW9uSGFzaGVzLnZhbGlkSGFzaGVzLnR4SWQzKSwgdHJ1ZSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdnYXNEYXRhKCknLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gY29ycmVjdCBnYXMgZGF0YScsICgpID0+IHtcbiAgICAgIHNob3VsZC5lcXVhbCh1dGlscy5mZWVEYXRhKCksICctMTAwMDAnKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2lzVmFsaWRQdWJsaWNLZXkoKScsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIHZhbGlkYXRlIHB1YmxpYyBrZXkgY29ycmVjdGx5JywgKCkgPT4ge1xuICAgICAgc2hvdWxkLmVxdWFsKHV0aWxzLmlzVmFsaWRQdWJsaWNLZXkoQWNjb3VudHMuYWNjb3VudDEucHVibGljS2V5KSwgdHJ1ZSk7XG4gICAgICBzaG91bGQuZXF1YWwodXRpbHMuaXNWYWxpZFB1YmxpY0tleShBY2NvdW50cy5hY2NvdW50Mi5wdWJsaWNLZXkpLCB0cnVlKTtcbiAgICAgIHNob3VsZC5lcXVhbCh1dGlscy5pc1ZhbGlkUHVibGljS2V5KEFjY291bnRzLmFjY291bnQzLnB1YmxpY0tleSksIHRydWUpO1xuICAgICAgc2hvdWxkLmVxdWFsKHV0aWxzLmlzVmFsaWRQdWJsaWNLZXkoQWNjb3VudHMuYWNjb3VudDQucHVibGljS2V5KSwgdHJ1ZSk7XG4gICAgICBzaG91bGQuZXF1YWwodXRpbHMuaXNWYWxpZFB1YmxpY0tleShBY2NvdW50cy5hY2NvdW50NS5wdWJsaWNLZXkpLCB0cnVlKTtcbiAgICAgIHNob3VsZC5lcXVhbCh1dGlscy5pc1ZhbGlkUHVibGljS2V5KEFjY291bnRzLmFjY291bnQ2LnB1YmxpY0tleSksIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBpbnZhbGlkYXRlIHB1YmxpYyBrZXkgY29ycmVjdGx5JywgKCkgPT4ge1xuICAgICAgc2hvdWxkLmVxdWFsKHV0aWxzLmlzVmFsaWRQdWJsaWNLZXkoQWNjb3VudHMuZXJyb3JzQWNjb3VudHMuYWNjb3VudDEucHVibGljS2V5KSwgZmFsc2UpO1xuICAgICAgc2hvdWxkLmVxdWFsKHV0aWxzLmlzVmFsaWRQdWJsaWNLZXkoQWNjb3VudHMuZXJyb3JzQWNjb3VudHMuYWNjb3VudDIucHVibGljS2V5KSwgZmFsc2UpO1xuICAgICAgc2hvdWxkLmVxdWFsKHV0aWxzLmlzVmFsaWRQdWJsaWNLZXkoQWNjb3VudHMuZXJyb3JzQWNjb3VudHMuYWNjb3VudDMucHVibGljS2V5KSwgZmFsc2UpO1xuICAgICAgc2hvdWxkLmVxdWFsKHV0aWxzLmlzVmFsaWRQdWJsaWNLZXkoQWNjb3VudHMuZXJyb3JzQWNjb3VudHMuYWNjb3VudDQucHVibGljS2V5KSwgZmFsc2UpO1xuICAgICAgc2hvdWxkLmVxdWFsKHV0aWxzLmlzVmFsaWRQdWJsaWNLZXkoQWNjb3VudHMuZXJyb3JzQWNjb3VudHMuYWNjb3VudDUucHVibGljS2V5KSwgZmFsc2UpO1xuICAgICAgc2hvdWxkLmVxdWFsKHV0aWxzLmlzVmFsaWRQdWJsaWNLZXkoQWNjb3VudHMuZXJyb3JzQWNjb3VudHMuYWNjb3VudDYucHVibGljS2V5KSwgZmFsc2UpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnY2JvckVuY29kZSgpJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgY29ycmVjdGx5IGVuY29kZSBhbiBvYmplY3QnLCAoKSA9PiB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHsga2V5OiAndmFsdWUnIH07XG4gICAgICBjb25zdCBleHBlY3RlZEhleCA9IEJ1ZmZlci5mcm9tKGVuY29kZSh2YWx1ZSkpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgIHNob3VsZC5lcXVhbCh1dGlscy5jYm9yRW5jb2RlKHZhbHVlKSwgZXhwZWN0ZWRIZXgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBlbmNvZGUgYW5kIGRlY29kZSBhIGJpZyBudW1iZXIgY29ycmVjdGx5JywgKCkgPT4ge1xuICAgICAgY29uc3Qgb3JpZ2luYWwgPSB7IG51bWJlcjogQmlnSW50KDE3NDA2ODA3Nzc0NTgwMDAwMDApIH07XG4gICAgICBjb25zdCBlbmNvZGVkID0gZW5jb2RlKG9yaWdpbmFsKTtcbiAgICAgIGNvbnN0IGRlY29kZWQgPSB1dGlscy5jYm9yRGVjb2RlKGVuY29kZWQpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbChkZWNvZGVkLCBvcmlnaW5hbCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdjYm9yRGVjb2RlKCknLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBjb3JyZWN0bHkgZGVjb2RlIGEgQ0JPUi1lbmNvZGVkIG9iamVjdCcsICgpID0+IHtcbiAgICAgIGNvbnN0IG9yaWdpbmFsID0geyBrZXk6ICd2YWx1ZScsIG51bWJlcjogMTAwIH07XG4gICAgICBjb25zdCBlbmNvZGVkID0gZW5jb2RlKG9yaWdpbmFsKTtcbiAgICAgIGNvbnN0IGRlY29kZWQgPSB1dGlscy5jYm9yRGVjb2RlKGVuY29kZWQpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbChkZWNvZGVkLCBvcmlnaW5hbCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdpc1ZhbGlkTGVuZ3RoKCknLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgYSB2YWxpZCBjb21wcmVzc2VkIHB1YmxpYyBrZXkgbGVuZ3RoICg2NiBjaGFyYWN0ZXJzKScsICgpID0+IHtcbiAgICAgIHNob3VsZC5lcXVhbCh1dGlscy5pc1ZhbGlkTGVuZ3RoKCdhJy5yZXBlYXQoNjYpKSwgdHJ1ZSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdpc1ZhbGlkSGV4KCknLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgYSB2YWxpZCBoZXhhZGVjaW1hbCBzdHJpbmcnLCAoKSA9PiB7XG4gICAgICBzaG91bGQuZXF1YWwodXRpbHMuaXNWYWxpZEhleCgnYWJjZGVmMTIzNDU2Nzg5MEFCQ0RFRicpLCB0cnVlKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2hleFRvQnl0ZXMoKScsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGNvcnJlY3RseSBjb252ZXJ0IGEgdmFsaWQgaGV4YWRlY2ltYWwgc3RyaW5nIHRvIGEgVWludDhBcnJheScsICgpID0+IHtcbiAgICAgIGNvbnN0IGhleCA9ICdhYmNkZWYxMjM0NTYnO1xuICAgICAgY29uc3QgZXhwZWN0ZWQgPSBuZXcgVWludDhBcnJheShbMHhhYiwgMHhjZCwgMHhlZiwgMHgxMiwgMHgzNCwgMHg1Nl0pO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh1dGlscy5oZXhUb0J5dGVzKGhleCksIGV4cGVjdGVkKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2lzVmFsaWRQcml2YXRlS2V5KCknLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCB2YWxpZGF0ZSBwcml2YXRlIGtleSBjb3JyZWN0bHknLCAoKSA9PiB7XG4gICAgICBzaG91bGQuZXF1YWwodXRpbHMuaXNWYWxpZFByaXZhdGVLZXkoQWNjb3VudHMuYWNjb3VudDEuc2VjcmV0S2V5KSwgdHJ1ZSk7XG4gICAgICBzaG91bGQuZXF1YWwodXRpbHMuaXNWYWxpZFByaXZhdGVLZXkoQWNjb3VudHMuYWNjb3VudDIuc2VjcmV0S2V5KSwgdHJ1ZSk7XG4gICAgICBzaG91bGQuZXF1YWwodXRpbHMuaXNWYWxpZFByaXZhdGVLZXkoQWNjb3VudHMuYWNjb3VudDMuc2VjcmV0S2V5KSwgdHJ1ZSk7XG4gICAgICBzaG91bGQuZXF1YWwodXRpbHMuaXNWYWxpZFByaXZhdGVLZXkoQWNjb3VudHMuYWNjb3VudDQuc2VjcmV0S2V5KSwgdHJ1ZSk7XG4gICAgICBzaG91bGQuZXF1YWwodXRpbHMuaXNWYWxpZFByaXZhdGVLZXkoQWNjb3VudHMuYWNjb3VudDUuc2VjcmV0S2V5KSwgdHJ1ZSk7XG4gICAgICBzaG91bGQuZXF1YWwodXRpbHMuaXNWYWxpZFByaXZhdGVLZXkoQWNjb3VudHMuYWNjb3VudDYuc2VjcmV0S2V5KSwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGludmFsaWRhdGUgcHJpdmF0ZSBrZXkgY29ycmVjdGx5JywgKCkgPT4ge1xuICAgICAgc2hvdWxkLmVxdWFsKHV0aWxzLmlzVmFsaWRQcml2YXRlS2V5KEFjY291bnRzLmVycm9yc0FjY291bnRzLmFjY291bnQxLnNlY3JldEtleSksIGZhbHNlKTtcbiAgICAgIHNob3VsZC5lcXVhbCh1dGlscy5pc1ZhbGlkUHJpdmF0ZUtleShBY2NvdW50cy5lcnJvcnNBY2NvdW50cy5hY2NvdW50Mi5zZWNyZXRLZXkpLCBmYWxzZSk7XG4gICAgICBzaG91bGQuZXF1YWwodXRpbHMuaXNWYWxpZFByaXZhdGVLZXkoQWNjb3VudHMuZXJyb3JzQWNjb3VudHMuYWNjb3VudDMuc2VjcmV0S2V5KSwgZmFsc2UpO1xuICAgICAgc2hvdWxkLmVxdWFsKHV0aWxzLmlzVmFsaWRQcml2YXRlS2V5KEFjY291bnRzLmVycm9yc0FjY291bnRzLmFjY291bnQ0LnNlY3JldEtleSksIGZhbHNlKTtcbiAgICAgIHNob3VsZC5lcXVhbCh1dGlscy5pc1ZhbGlkUHJpdmF0ZUtleShBY2NvdW50cy5lcnJvcnNBY2NvdW50cy5hY2NvdW50NS5zZWNyZXRLZXkpLCBmYWxzZSk7XG4gICAgICBzaG91bGQuZXF1YWwodXRpbHMuaXNWYWxpZFByaXZhdGVLZXkoQWNjb3VudHMuZXJyb3JzQWNjb3VudHMuYWNjb3VudDYuc2VjcmV0S2V5KSwgZmFsc2UpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnZ2V0QWRkcmVzc0Zyb21QdWJsaWNLZXkoKScsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIHJldHVybiB0aGUgY29ycmVjdCBhZGRyZXNzIGZvciBhIHZhbGlkIHB1YmxpYyBrZXknLCAoKSA9PiB7XG4gICAgICBjb25zdCBhZGRyZXNzMSA9IHV0aWxzLmdldEFkZHJlc3NGcm9tUHVibGljS2V5KEFjY291bnRzLmFjY291bnQxLnB1YmxpY0tleSk7XG4gICAgICBzaG91bGQuZXF1YWwoYWRkcmVzczEsIEFjY291bnRzLmFjY291bnQxLmFkZHJlc3MpO1xuICAgICAgY29uc3QgYWRkcmVzczIgPSB1dGlscy5nZXRBZGRyZXNzRnJvbVB1YmxpY0tleShBY2NvdW50cy5hY2NvdW50MS5wdWJsaWNLZXkpO1xuICAgICAgc2hvdWxkLmVxdWFsKGFkZHJlc3MyLCBBY2NvdW50cy5hY2NvdW50MS5hZGRyZXNzKTtcbiAgICAgIGNvbnN0IGFkZHJlc3MzID0gdXRpbHMuZ2V0QWRkcmVzc0Zyb21QdWJsaWNLZXkoQWNjb3VudHMuYWNjb3VudDEucHVibGljS2V5KTtcbiAgICAgIHNob3VsZC5lcXVhbChhZGRyZXNzMywgQWNjb3VudHMuYWNjb3VudDEuYWRkcmVzcyk7XG4gICAgICBjb25zdCBhZGRyZXNzNCA9IHV0aWxzLmdldEFkZHJlc3NGcm9tUHVibGljS2V5KEFjY291bnRzLmFjY291bnQxLnB1YmxpY0tleSk7XG4gICAgICBzaG91bGQuZXF1YWwoYWRkcmVzczQsIEFjY291bnRzLmFjY291bnQxLmFkZHJlc3MpO1xuICAgICAgY29uc3QgYWRkcmVzczUgPSB1dGlscy5nZXRBZGRyZXNzRnJvbVB1YmxpY0tleShBY2NvdW50cy5hY2NvdW50MS5wdWJsaWNLZXkpO1xuICAgICAgc2hvdWxkLmVxdWFsKGFkZHJlc3M1LCBBY2NvdW50cy5hY2NvdW50MS5hZGRyZXNzKTtcbiAgICAgIGNvbnN0IGFkZHJlc3M2ID0gdXRpbHMuZ2V0QWRkcmVzc0Zyb21QdWJsaWNLZXkoQWNjb3VudHMuYWNjb3VudDEucHVibGljS2V5KTtcbiAgICAgIHNob3VsZC5lcXVhbChhZGRyZXNzNiwgQWNjb3VudHMuYWNjb3VudDEuYWRkcmVzcyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGFuIGVycm9yIGZvciBhbiBpbnZhbGlkIHB1YmxpYyBrZXknLCAoKSA9PiB7XG4gICAgICAoKCkgPT4gdXRpbHMuZ2V0QWRkcmVzc0Zyb21QdWJsaWNLZXkoQWNjb3VudHMuZXJyb3JzQWNjb3VudHMuYWNjb3VudDEucHVibGljS2V5KSkuc2hvdWxkLnRocm93KFxuICAgICAgICAnSW52YWxpZCBoZXgtZW5jb2RlZCBwdWJsaWMga2V5IGZvcm1hdC4nXG4gICAgICApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnZ2VuZXJhdGVLZXlQYWlyKCknLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBhIHZhbGlkIGtleSBwYWlyIHdpdGhvdXQgYSBzZWVkJywgKCkgPT4ge1xuICAgICAgY29uc3Qga2V5UGFpciA9IHV0aWxzLmdlbmVyYXRlS2V5UGFpcigpO1xuICAgICAgc2hvdWxkLmV4aXN0KGtleVBhaXIpO1xuICAgICAgc2hvdWxkLmV4aXN0KGtleVBhaXIucHViKTtcbiAgICAgIHNob3VsZC5leGlzdChrZXlQYWlyLnBydik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIGEgdmFsaWQga2V5IHBhaXIgd2l0aCBhIGdpdmVuIHNlZWQnLCAoKSA9PiB7XG4gICAgICBjb25zdCBzZWVkID0gcmFuZG9tQnl0ZXMoMzIpO1xuICAgICAgY29uc3Qga2V5UGFpciA9IHV0aWxzLmdlbmVyYXRlS2V5UGFpcihzZWVkKTtcbiAgICAgIHNob3VsZC5leGlzdChrZXlQYWlyKTtcbiAgICAgIHNob3VsZC5leGlzdChrZXlQYWlyLnB1Yik7XG4gICAgICBzaG91bGQuZXhpc3Qoa2V5UGFpci5wcnYpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBkaWZmZXJlbnQga2V5IHBhaXJzIGZvciBkaWZmZXJlbnQgc2VlZHMnLCAoKSA9PiB7XG4gICAgICBjb25zdCBzZWVkMSA9IHJhbmRvbUJ5dGVzKDMyKTtcbiAgICAgIGNvbnN0IHNlZWQyID0gcmFuZG9tQnl0ZXMoMzIpO1xuICAgICAgY29uc3Qga2V5UGFpcjEgPSB1dGlscy5nZW5lcmF0ZUtleVBhaXIoc2VlZDEpO1xuICAgICAgY29uc3Qga2V5UGFpcjIgPSB1dGlscy5nZW5lcmF0ZUtleVBhaXIoc2VlZDIpO1xuXG4gICAgICBzaG91bGQubm90RXF1YWwoa2V5UGFpcjEucHViLCBrZXlQYWlyMi5wdWIpO1xuICAgICAgc2hvdWxkLm5vdEVxdWFsKGtleVBhaXIxLnBydiwga2V5UGFpcjIucHJ2KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgdGhlIHNhbWUga2V5IHBhaXIgZm9yIHRoZSBzYW1lIHNlZWQnLCAoKSA9PiB7XG4gICAgICBjb25zdCBzZWVkID0gcmFuZG9tQnl0ZXMoMzIpO1xuICAgICAgY29uc3Qga2V5UGFpcjEgPSB1dGlscy5nZW5lcmF0ZUtleVBhaXIoc2VlZCk7XG4gICAgICBjb25zdCBrZXlQYWlyMiA9IHV0aWxzLmdlbmVyYXRlS2V5UGFpcihzZWVkKTtcblxuICAgICAgc2hvdWxkLmVxdWFsKGtleVBhaXIxLnB1Yiwga2V5UGFpcjIucHViKTtcbiAgICAgIHNob3VsZC5lcXVhbChrZXlQYWlyMS5wcnYsIGtleVBhaXIyLnBydik7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCd2YWxpZGF0ZVJhd1RyYW5zYWN0aW9uKCknLCAoKSA9PiB7XG4gICAgY29uc3QgZGF0YSA9IEljcFRyYW5zYWN0aW9uRGF0YTtcbiAgICBpdCgnc2hvdWxkIHZhbGlkYXRlIGljcFRyYW5zYWN0aW9uRGF0YSBjb3JyZWN0bHknLCAoKSA9PiB7XG4gICAgICB1dGlscy52YWxpZGF0ZVJhd1RyYW5zYWN0aW9uKGRhdGEpO1xuICAgIH0pO1xuICAgIGl0KCdzaG91bGQgdGhyb3cgYW4gZXJyb3IgZm9yIGludmFsaWQgZXhwaXJ5VGltZScsICgpID0+IHtcbiAgICAgIChkYXRhLmV4cGlyeVRpbWUgPSBEYXRlLm5vdygpKSwgc2hvdWxkLnRocm93cygoKSA9PiB1dGlscy52YWxpZGF0ZVJhd1RyYW5zYWN0aW9uKGRhdGEpLCAnSW52YWxpZCBleHBpcnkgdGltZScpO1xuICAgIH0pO1xuICAgIGl0KCdzaG91bGQgdGhyb3cgYW4gZXJyb3IgZm9yIGludmFsaWQgZmVlJywgKCkgPT4ge1xuICAgICAgZGF0YS5mZWUgPSAnLTEwMCc7XG4gICAgICBzaG91bGQudGhyb3dzKCgpID0+IHV0aWxzLnZhbGlkYXRlUmF3VHJhbnNhY3Rpb24oZGF0YSksICdJbnZhbGlkIGZlZSB2YWx1ZScpO1xuICAgIH0pO1xuICAgIGl0KCdzaG91bGQgdGhyb3cgYW4gZXJyb3IgZm9yIGludmFsaWQgYW1vdW50JywgKCkgPT4ge1xuICAgICAgZGF0YS5hbW91bnQgPSAnMCc7XG4gICAgICBzaG91bGQudGhyb3dzKCgpID0+IHV0aWxzLnZhbGlkYXRlUmF3VHJhbnNhY3Rpb24oZGF0YSksICdhbW91bnQgY2Fubm90IGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byB6ZXJvJyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdnZXRUcmFuc2FjdGlvbklkKCknLCAoKSA9PiB7XG4gICAgY29uc3Qgc2VuZGVyID0gJzQ3ODY3ZjJjZmI4NTA5NDI3NWM4NDc0MzVmYTEwY2FkNTRhODEzZWJhN2U2YTliYzM1MzhhYTJmNTM3ZjFkNzMnO1xuICAgIGNvbnN0IHJlY2VpdmVyID0gJ2ExYzYwZWZjYTk4OGM0MTFjZDdiYzVlNDgxMzY0YjljOTRjYWViYjI0YzAwZTAxZGIyNjllM2EwNTQxZWU0OTgnO1xuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRoZSBjb3JyZWN0IHRyYW5zYWN0aW9uIGhhc2ggZm9yIGFtb3VudCBsZXNzIHRoYW4gMl4zMiAoYW1vdW50ID0gMTAwMCknLCAoKSA9PiB7XG4gICAgICBjb25zdCB1bnNpZ25lZFRyYW5zYWN0aW9uID1cbiAgICAgICAgJ2I5MDAwMjY3NzU3MDY0NjE3NDY1NzM4MTgyNmI1NDUyNDE0ZTUzNDE0MzU0NDk0ZjRlYjkwMDA1NmI2MzYxNmU2OTczNzQ2NTcyNWY2OTY0NGEwMDAwMDAwMDAwMDAwMDAyMDEwMTZiNmQ2NTc0Njg2ZjY0NWY2ZTYxNmQ2NTY3NzM2NTZlNjQ1ZjcwNjI2MzYxNzI2NzU4NDAwYTAyMDgwMDEyMDUwYTAzMDhlODA3MWEwMzA4OTA0ZTJhMjIwYTIwYTFjNjBlZmNhOTg4YzQxMWNkN2JjNWU0ODEzNjRiOWM5NGNhZWJiMjRjMDBlMDFkYjI2OWUzYTA1NDFlZTQ5ODNhMGEwODgwODRhOGE5ODhlNGY0YTAxODY2NzM2NTZlNjQ2NTcyNTgxZGE5MDViODZiYmE5YmZlZDE5NGFjOGMxMjM3N2I1ZDQ4ODQ3MTI4ZGJmZmYxMGYwMWFkYjgwZjdmMDI2ZTY5NmU2NzcyNjU3MzczNWY2NTc4NzA2OTcyNzkxYjAwMDAwMDAwMDAwMDAwMDA3MDY5NmU2NzcyNjU3MzczNWY2NTc4NzA2OTcyNjk2NTczODExYjE4NDFkMzU4NjY0NzYyMDAnO1xuICAgICAgY29uc3QgdHJhbnNhY3Rpb25IYXNoID0gdXRpbHMuZ2V0VHJhbnNhY3Rpb25JZCh1bnNpZ25lZFRyYW5zYWN0aW9uLCBzZW5kZXIsIHJlY2VpdmVyKTtcbiAgICAgIGNvbnN0IGV4cGVjdGVkVHJhbnNhY3Rpb25IYXNoID0gJ2JiNTAyZDA1NjZmNzI2ZGEwMmExOTI1NDE1ZjY4Y2I2ZjE3NWNkZDZjYmExZTA5ODIzMTQzMDc4NzE1YjJiYTQnO1xuICAgICAgc2hvdWxkLmVxdWFsKHRyYW5zYWN0aW9uSGFzaCwgZXhwZWN0ZWRUcmFuc2FjdGlvbkhhc2gpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdGhlIGNvcnJlY3QgdHJhbnNhY3Rpb24gaGFzaCBmb3IgYW1vdW50IGdyZWF0ZXIgdGhhbiAyXjMyIChhbW91bnQgPSA2OTQ4MTUwMjAwKScsICgpID0+IHtcbiAgICAgIGNvbnN0IHVuc2lnbmVkVHJhbnNhY3Rpb24gPVxuICAgICAgICAnYjkwMDAyNjc3NTcwNjQ2MTc0NjU3MzgxODI2YjU0NTI0MTRlNTM0MTQzNTQ0OTRmNGViOTAwMDU2YjYzNjE2ZTY5NzM3NDY1NzI1ZjY5NjQ0YTAwMDAwMDAwMDAwMDAwMDIwMTAxNmI2ZDY1NzQ2ODZmNjQ1ZjZlNjE2ZDY1Njc3MzY1NmU2NDVmNzA2MjYzNjE3MjY3NTg0MzBhMDIwODAwMTIwODBhMDYwOGI4Yjc5MWYxMTkxYTAzMDg5MDRlMmEyMjBhMjBhMWM2MGVmY2E5ODhjNDExY2Q3YmM1ZTQ4MTM2NGI5Yzk0Y2FlYmIyNGMwMGUwMWRiMjY5ZTNhMDU0MWVlNDk4M2EwYTA4ODBiOGE3ODliZmViZjRhMDE4NjY3MzY1NmU2NDY1NzI1ODFkYTkwNWI4NmJiYTliZmVkMTk0YWM4YzEyMzc3YjVkNDg4NDcxMjhkYmZmZjEwZjAxYWRiODBmN2YwMjZlNjk2ZTY3NzI2NTczNzM1ZjY1Nzg3MDY5NzI3OTFiMDAwMDAwMDAwMDAwMDAwMDcwNjk2ZTY3NzI2NTczNzM1ZjY1Nzg3MDY5NzI2OTY1NzM4MTFiMTg0MWQzOTNkMjQ3M2MwMCc7XG4gICAgICBjb25zdCB0cmFuc2FjdGlvbkhhc2ggPSB1dGlscy5nZXRUcmFuc2FjdGlvbklkKHVuc2lnbmVkVHJhbnNhY3Rpb24sIHNlbmRlciwgcmVjZWl2ZXIpO1xuICAgICAgY29uc3QgZXhwZWN0ZWRUcmFuc2FjdGlvbkhhc2ggPSAnMDE2NDExMTEwMDA2ZDQ2NDVjYmNiNTUzYTg0ZWZkZWM2YzQwMjg0N2Y4NTZjYWE5MDkxMTFkODFiYjUxMzU2NSc7XG4gICAgICBzaG91bGQuZXF1YWwodHJhbnNhY3Rpb25IYXNoLCBleHBlY3RlZFRyYW5zYWN0aW9uSGFzaCk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=