@bitgo/sdk-coin-starknet 0.0.1 → 1.2.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 (60) hide show
  1. package/LICENSE +191 -0
  2. package/dist/src/index.d.ts +4 -0
  3. package/dist/src/index.d.ts.map +1 -0
  4. package/dist/src/index.js +20 -0
  5. package/dist/src/lib/constants.d.ts +13 -0
  6. package/dist/src/lib/constants.d.ts.map +1 -0
  7. package/dist/src/lib/constants.js +25 -0
  8. package/dist/src/lib/iface.d.ts +78 -0
  9. package/dist/src/lib/iface.d.ts.map +1 -0
  10. package/dist/src/lib/iface.js +9 -0
  11. package/dist/src/lib/index.d.ts +9 -0
  12. package/dist/src/lib/index.d.ts.map +1 -0
  13. package/dist/src/lib/index.js +53 -0
  14. package/dist/src/lib/keyPair.d.ts +9 -0
  15. package/dist/src/lib/keyPair.d.ts.map +1 -0
  16. package/dist/src/lib/keyPair.js +48 -0
  17. package/dist/src/lib/transaction.d.ts +23 -0
  18. package/dist/src/lib/transaction.d.ts.map +1 -0
  19. package/dist/src/lib/transaction.js +145 -0
  20. package/dist/src/lib/transactionBuilder.d.ts +43 -0
  21. package/dist/src/lib/transactionBuilder.d.ts.map +1 -0
  22. package/dist/src/lib/transactionBuilder.js +158 -0
  23. package/dist/src/lib/transactionBuilderFactory.d.ts +16 -0
  24. package/dist/src/lib/transactionBuilderFactory.d.ts.map +1 -0
  25. package/dist/src/lib/transactionBuilderFactory.js +44 -0
  26. package/dist/src/lib/transferBuilder.d.ts +21 -0
  27. package/dist/src/lib/transferBuilder.d.ts.map +1 -0
  28. package/dist/src/lib/transferBuilder.js +88 -0
  29. package/dist/src/lib/utils.d.ts +104 -0
  30. package/dist/src/lib/utils.d.ts.map +1 -0
  31. package/dist/src/lib/utils.js +290 -0
  32. package/dist/src/register.d.ts +3 -0
  33. package/dist/src/register.d.ts.map +1 -0
  34. package/dist/src/register.js +10 -0
  35. package/dist/src/starknet.d.ts +35 -0
  36. package/dist/src/starknet.d.ts.map +1 -0
  37. package/dist/src/starknet.js +127 -0
  38. package/dist/test/resources/starknet.d.ts +98 -0
  39. package/dist/test/resources/starknet.d.ts.map +1 -0
  40. package/dist/test/resources/starknet.js +104 -0
  41. package/dist/test/unit/keyPair.d.ts +2 -0
  42. package/dist/test/unit/keyPair.d.ts.map +1 -0
  43. package/dist/test/unit/keyPair.js +56 -0
  44. package/dist/test/unit/starknet.d.ts +2 -0
  45. package/dist/test/unit/starknet.d.ts.map +1 -0
  46. package/dist/test/unit/starknet.js +126 -0
  47. package/dist/test/unit/transaction.d.ts +2 -0
  48. package/dist/test/unit/transaction.d.ts.map +1 -0
  49. package/dist/test/unit/transaction.js +53 -0
  50. package/dist/test/unit/transactionBuilder/transactionBuilderFactory.d.ts +2 -0
  51. package/dist/test/unit/transactionBuilder/transactionBuilderFactory.d.ts.map +1 -0
  52. package/dist/test/unit/transactionBuilder/transactionBuilderFactory.js +74 -0
  53. package/dist/test/unit/transferBuilder.d.ts +2 -0
  54. package/dist/test/unit/transferBuilder.d.ts.map +1 -0
  55. package/dist/test/unit/transferBuilder.js +208 -0
  56. package/dist/test/unit/utils.d.ts +2 -0
  57. package/dist/test/unit/utils.d.ts.map +1 -0
  58. package/dist/test/unit/utils.js +260 -0
  59. package/dist/tsconfig.tsbuildinfo +1 -0
  60. package/package.json +52 -10
@@ -0,0 +1,260 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const utils_1 = __importStar(require("../../src/lib/utils"));
37
+ const starknet_1 = require("../resources/starknet");
38
+ const constants_1 = require("../../src/lib/constants");
39
+ require("should");
40
+ describe('Starknet Utils', () => {
41
+ describe('isValidAddress', () => {
42
+ it('should accept a valid Starknet address', () => {
43
+ utils_1.default.isValidAddress(starknet_1.Accounts.account1.address).should.equal(true);
44
+ });
45
+ it('should accept a second valid address', () => {
46
+ utils_1.default.isValidAddress(starknet_1.Accounts.account2.address).should.equal(true);
47
+ });
48
+ it('should reject an invalid address', () => {
49
+ utils_1.default.isValidAddress('not_an_address').should.equal(false);
50
+ });
51
+ it('should reject an empty string', () => {
52
+ utils_1.default.isValidAddress('').should.equal(false);
53
+ });
54
+ it('should reject address without 0x prefix', () => {
55
+ utils_1.default.isValidAddress('04a1f29b8b8e3d3c9f6c9b7a8d2e1f0c5b4a3d2e1f0c5b4a3d2e1f0c5b4a3d2e').should.equal(false);
56
+ });
57
+ });
58
+ describe('isValidPublicKey', () => {
59
+ it('should accept a valid uncompressed public key', () => {
60
+ utils_1.default.isValidPublicKey(starknet_1.Accounts.account1.publicKey).should.equal(true);
61
+ });
62
+ it('should reject an invalid public key', () => {
63
+ utils_1.default.isValidPublicKey('not_a_key').should.equal(false);
64
+ });
65
+ it('should reject an empty string', () => {
66
+ utils_1.default.isValidPublicKey('').should.equal(false);
67
+ });
68
+ });
69
+ describe('isValidPrivateKey', () => {
70
+ it('should accept a valid private key', () => {
71
+ utils_1.default.isValidPrivateKey(starknet_1.Accounts.account1.secretKey).should.equal(true);
72
+ });
73
+ it('should reject an invalid private key', () => {
74
+ utils_1.default.isValidPrivateKey('not_a_key').should.equal(false);
75
+ });
76
+ it('should reject an empty string', () => {
77
+ utils_1.default.isValidPrivateKey('').should.equal(false);
78
+ });
79
+ });
80
+ describe('getUncompressedPublicKey', () => {
81
+ it('should return 128 hex chars from uncompressed key', () => {
82
+ const result = utils_1.default.getUncompressedPublicKey(starknet_1.Accounts.account1.publicKey);
83
+ result.length.should.equal(128);
84
+ });
85
+ });
86
+ describe('formatEthAccountSignature', () => {
87
+ it('should format signature as 5 felt252 values', () => {
88
+ const r = 'abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890';
89
+ const s = '1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef';
90
+ const result = utils_1.default.formatEthAccountSignature(r, s, 0);
91
+ result.length.should.equal(5);
92
+ result.forEach((val) => val.should.startWith('0x'));
93
+ });
94
+ it('should handle recid 0 and 1', () => {
95
+ const r = 'aaaa';
96
+ const s = 'bbbb';
97
+ const sig0 = utils_1.default.formatEthAccountSignature(r, s, 0);
98
+ const sig1 = utils_1.default.formatEthAccountSignature(r, s, 1);
99
+ sig0[4].should.equal('0x0');
100
+ sig1[4].should.equal('0x1');
101
+ });
102
+ });
103
+ describe('encodeShortString', () => {
104
+ it('should encode "invoke" correctly', () => {
105
+ (0, utils_1.encodeShortString)('invoke').should.equal(0x696e766f6b65n);
106
+ });
107
+ it('should encode "L1_GAS" correctly', () => {
108
+ (0, utils_1.encodeShortString)('L1_GAS').should.equal(0x4c315f474153n);
109
+ });
110
+ it('should encode "L2_GAS" correctly', () => {
111
+ (0, utils_1.encodeShortString)('L2_GAS').should.equal(0x4c325f474153n);
112
+ });
113
+ it('should encode "L1_DATA" correctly', () => {
114
+ (0, utils_1.encodeShortString)('L1_DATA').should.equal(0x4c315f44415441n);
115
+ });
116
+ it('should reject strings longer than 31 chars', () => {
117
+ (() => (0, utils_1.encodeShortString)('a'.repeat(32))).should.throw(/too long/);
118
+ });
119
+ });
120
+ describe('getSelectorFromName', () => {
121
+ it('should compute selector for "transfer"', () => {
122
+ const selector = (0, utils_1.getSelectorFromName)('transfer');
123
+ (typeof selector).should.equal('bigint');
124
+ (selector > 0n).should.equal(true);
125
+ (selector < 1n << 250n).should.equal(true);
126
+ });
127
+ it('should be deterministic', () => {
128
+ (0, utils_1.getSelectorFromName)('transfer').should.equal((0, utils_1.getSelectorFromName)('transfer'));
129
+ });
130
+ });
131
+ describe('compileExecuteCalldata', () => {
132
+ it('should compile a single transfer call', () => {
133
+ const calls = [
134
+ {
135
+ contractAddress: starknet_1.SandboxTransferData.tokenContract,
136
+ entrypoint: 'transfer',
137
+ calldata: [
138
+ starknet_1.SandboxTransferData.receiverAddress,
139
+ '0x' + (BigInt(starknet_1.SandboxTransferData.amount) & constants_1.MASK_128).toString(16),
140
+ '0x' + (BigInt(starknet_1.SandboxTransferData.amount) >> 128n).toString(16),
141
+ ],
142
+ },
143
+ ];
144
+ const compiled = (0, utils_1.compileExecuteCalldata)(calls);
145
+ compiled[0].should.equal('0x1'); // num_calls = 1
146
+ compiled[1].should.equal(starknet_1.SandboxTransferData.tokenContract); // to
147
+ compiled.length.should.equal(1 + 1 + 1 + 1 + 3); // num_calls + to + selector + data_len + 3 calldata
148
+ });
149
+ });
150
+ describe('calculateInvokeTransactionHash', () => {
151
+ it('should produce a deterministic hash', () => {
152
+ const calls = [
153
+ {
154
+ contractAddress: starknet_1.SandboxTransferData.tokenContract,
155
+ entrypoint: 'transfer',
156
+ calldata: [
157
+ starknet_1.SandboxTransferData.receiverAddress,
158
+ '0x' + (BigInt(starknet_1.SandboxTransferData.amount) & constants_1.MASK_128).toString(16),
159
+ '0x' + (BigInt(starknet_1.SandboxTransferData.amount) >> 128n).toString(16),
160
+ ],
161
+ },
162
+ ];
163
+ const compiledCalldata = (0, utils_1.compileExecuteCalldata)(calls);
164
+ const hash1 = (0, utils_1.calculateInvokeTransactionHash)({
165
+ senderAddress: starknet_1.SandboxTransferData.senderAddress,
166
+ compiledCalldata,
167
+ chainId: starknet_1.SandboxTransferData.chainId,
168
+ nonce: '0x0',
169
+ resourceBounds: starknet_1.SandboxTransferData.resourceBounds,
170
+ });
171
+ const hash2 = (0, utils_1.calculateInvokeTransactionHash)({
172
+ senderAddress: starknet_1.SandboxTransferData.senderAddress,
173
+ compiledCalldata,
174
+ chainId: starknet_1.SandboxTransferData.chainId,
175
+ nonce: '0x0',
176
+ resourceBounds: starknet_1.SandboxTransferData.resourceBounds,
177
+ });
178
+ hash1.should.equal(hash2);
179
+ hash1.should.startWith('0x');
180
+ });
181
+ it('should produce different hashes for different nonces', () => {
182
+ const calls = [
183
+ {
184
+ contractAddress: starknet_1.SandboxTransferData.tokenContract,
185
+ entrypoint: 'transfer',
186
+ calldata: [starknet_1.SandboxTransferData.receiverAddress, '0xde0b6b3a7640000', '0x0'],
187
+ },
188
+ ];
189
+ const compiledCalldata = (0, utils_1.compileExecuteCalldata)(calls);
190
+ const hash1 = (0, utils_1.calculateInvokeTransactionHash)({
191
+ senderAddress: starknet_1.SandboxTransferData.senderAddress,
192
+ compiledCalldata,
193
+ chainId: starknet_1.SandboxTransferData.chainId,
194
+ nonce: '0x0',
195
+ resourceBounds: starknet_1.SandboxTransferData.resourceBounds,
196
+ });
197
+ const hash2 = (0, utils_1.calculateInvokeTransactionHash)({
198
+ senderAddress: starknet_1.SandboxTransferData.senderAddress,
199
+ compiledCalldata,
200
+ chainId: starknet_1.SandboxTransferData.chainId,
201
+ nonce: '0x1',
202
+ resourceBounds: starknet_1.SandboxTransferData.resourceBounds,
203
+ });
204
+ hash1.should.not.equal(hash2);
205
+ });
206
+ it('should not include proof_facts when absent', () => {
207
+ const calls = [
208
+ {
209
+ contractAddress: starknet_1.SandboxTransferData.tokenContract,
210
+ entrypoint: 'transfer',
211
+ calldata: [starknet_1.SandboxTransferData.receiverAddress, '0xde0b6b3a7640000', '0x0'],
212
+ },
213
+ ];
214
+ const compiledCalldata = (0, utils_1.compileExecuteCalldata)(calls);
215
+ const hashWithout = (0, utils_1.calculateInvokeTransactionHash)({
216
+ senderAddress: starknet_1.SandboxTransferData.senderAddress,
217
+ compiledCalldata,
218
+ chainId: starknet_1.SandboxTransferData.chainId,
219
+ nonce: '0x0',
220
+ resourceBounds: starknet_1.SandboxTransferData.resourceBounds,
221
+ });
222
+ const hashWithEmpty = (0, utils_1.calculateInvokeTransactionHash)({
223
+ senderAddress: starknet_1.SandboxTransferData.senderAddress,
224
+ compiledCalldata,
225
+ chainId: starknet_1.SandboxTransferData.chainId,
226
+ nonce: '0x0',
227
+ resourceBounds: starknet_1.SandboxTransferData.resourceBounds,
228
+ proofFacts: [],
229
+ });
230
+ // Empty proofFacts should be omitted, producing same hash as absent
231
+ hashWithout.should.equal(hashWithEmpty);
232
+ });
233
+ it('should match known-good sandbox tx hash (0x739a728...)', () => {
234
+ const tv = starknet_1.KnownGoodInvokeTx;
235
+ const amountBig = BigInt(tv.amount);
236
+ const calls = [
237
+ {
238
+ contractAddress: tv.tokenContract,
239
+ entrypoint: 'transfer',
240
+ calldata: [
241
+ tv.receiverAddress,
242
+ '0x' + (amountBig & constants_1.MASK_128).toString(16),
243
+ '0x' + (amountBig >> 128n).toString(16),
244
+ ],
245
+ },
246
+ ];
247
+ const compiledCalldata = (0, utils_1.compileExecuteCalldata)(calls);
248
+ const hash = (0, utils_1.calculateInvokeTransactionHash)({
249
+ senderAddress: tv.senderAddress,
250
+ compiledCalldata,
251
+ chainId: tv.chainId,
252
+ nonce: tv.nonce,
253
+ resourceBounds: tv.resourceBounds,
254
+ tip: tv.tip,
255
+ });
256
+ hash.should.equal(tv.expectedTxHash);
257
+ });
258
+ });
259
+ });
260
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90ZXN0L3VuaXQvdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSw2REFLNkI7QUFDN0Isb0RBQXlGO0FBQ3pGLHVEQUFtRDtBQUNuRCxrQkFBZ0I7QUFFaEIsUUFBUSxDQUFDLGdCQUFnQixFQUFFLEdBQUcsRUFBRTtJQUM5QixRQUFRLENBQUMsZ0JBQWdCLEVBQUUsR0FBRyxFQUFFO1FBQzlCLEVBQUUsQ0FBQyx3Q0FBd0MsRUFBRSxHQUFHLEVBQUU7WUFDaEQsZUFBSyxDQUFDLGNBQWMsQ0FBQyxtQkFBUSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3JFLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHNDQUFzQyxFQUFFLEdBQUcsRUFBRTtZQUM5QyxlQUFLLENBQUMsY0FBYyxDQUFDLG1CQUFRLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDckUsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsa0NBQWtDLEVBQUUsR0FBRyxFQUFFO1lBQzFDLGVBQUssQ0FBQyxjQUFjLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzdELENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLCtCQUErQixFQUFFLEdBQUcsRUFBRTtZQUN2QyxlQUFLLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDL0MsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMseUNBQXlDLEVBQUUsR0FBRyxFQUFFO1lBQ2pELGVB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QUFDLGFBQWE7Z0JBQy9CLGdCQUFnQjtnQkFDaEIsT0FBTyxFQUFFLEVBQUUsQ0FBQyxPQUFPO2dCQUNuQixLQUFLLEVBQUUsRUFBRSxDQUFDLEtBQUs7Z0JBQ2YsY0FBYyxFQUFFLEVBQUUsQ0FBQyxjQUFjO2dCQUNqQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUc7YUFDWixDQUFDLENBQUM7WUFFSCxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDdkMsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHV0aWxzLCB7XG4gIGVuY29kZVNob3J0U3RyaW5nLFxuICBnZXRTZWxlY3RvckZyb21OYW1lLFxuICBjb21waWxlRXhlY3V0ZUNhbGxkYXRhLFxuICBjYWxjdWxhdGVJbnZva2VUcmFuc2FjdGlvbkhhc2gsXG59IGZyb20gJy4uLy4uL3NyYy9saWIvdXRpbHMnO1xuaW1wb3J0IHsgQWNjb3VudHMsIFNhbmRib3hUcmFuc2ZlckRhdGEsIEtub3duR29vZEludm9rZVR4IH0gZnJvbSAnLi4vcmVzb3VyY2VzL3N0YXJrbmV0JztcbmltcG9ydCB7IE1BU0tfMTI4IH0gZnJvbSAnLi4vLi4vc3JjL2xpYi9jb25zdGFudHMnO1xuaW1wb3J0ICdzaG91bGQnO1xuXG5kZXNjcmliZSgnU3RhcmtuZXQgVXRpbHMnLCAoKSA9PiB7XG4gIGRlc2NyaWJlKCdpc1ZhbGlkQWRkcmVzcycsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGFjY2VwdCBhIHZhbGlkIFN0YXJrbmV0IGFkZHJlc3MnLCAoKSA9PiB7XG4gICAgICB1dGlscy5pc1ZhbGlkQWRkcmVzcyhBY2NvdW50cy5hY2NvdW50MS5hZGRyZXNzKS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGFjY2VwdCBhIHNlY29uZCB2YWxpZCBhZGRyZXNzJywgKCkgPT4ge1xuICAgICAgdXRpbHMuaXNWYWxpZEFkZHJlc3MoQWNjb3VudHMuYWNjb3VudDIuYWRkcmVzcykuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgYW4gaW52YWxpZCBhZGRyZXNzJywgKCkgPT4ge1xuICAgICAgdXRpbHMuaXNWYWxpZEFkZHJlc3MoJ25vdF9hbl9hZGRyZXNzJykuc2hvdWxkLmVxdWFsKGZhbHNlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVqZWN0IGFuIGVtcHR5IHN0cmluZycsICgpID0+IHtcbiAgICAgIHV0aWxzLmlzVmFsaWRBZGRyZXNzKCcnKS5zaG91bGQuZXF1YWwoZmFsc2UpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgYWRkcmVzcyB3aXRob3V0IDB4IHByZWZpeCcsICgpID0+IHtcbiAgICAgIHV0aWxzLmlzVmFsaWRBZGRyZXNzKCcwNGExZjI5YjhiOGUzZDNjOWY2YzliN2E4ZDJlMWYwYzViNGEzZDJlMWYwYzViNGEzZDJlMWYwYzViNGEzZDJlJykuc2hvdWxkLmVxdWFsKGZhbHNlKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2lzVmFsaWRQdWJsaWNLZXknLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBhY2NlcHQgYSB2YWxpZCB1bmNvbXByZXNzZWQgcHVibGljIGtleScsICgpID0+IHtcbiAgICAgIHV0aWxzLmlzVmFsaWRQdWJsaWNLZXkoQWNjb3VudHMuYWNjb3VudDEucHVibGljS2V5KS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlamVjdCBhbiBpbnZhbGlkIHB1YmxpYyBrZXknLCAoKSA9PiB7XG4gICAgICB1dGlscy5pc1ZhbGlkUHVibGljS2V5KCdub3RfYV9rZXknKS5zaG91bGQuZXF1YWwoZmFsc2UpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgYW4gZW1wdHkgc3RyaW5nJywgKCkgPT4ge1xuICAgICAgdXRpbHMuaXNWYWxpZFB1YmxpY0tleSgnJykuc2hvdWxkLmVxdWFsKGZhbHNlKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2lzVmFsaWRQcml2YXRlS2V5JywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgYWNjZXB0IGEgdmFsaWQgcHJpdmF0ZSBrZXknLCAoKSA9PiB7XG4gICAgICB1dGlscy5pc1ZhbGlkUHJpdmF0ZUtleShBY2NvdW50cy5hY2NvdW50MS5zZWNyZXRLZXkpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVqZWN0IGFuIGludmFsaWQgcHJpdmF0ZSBrZXknLCAoKSA9PiB7XG4gICAgICB1dGlscy5pc1ZhbGlkUHJpdmF0ZUtleSgnbm90X2Ffa2V5Jykuc2hvdWxkLmVxdWFsKGZhbHNlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVqZWN0IGFuIGVtcHR5IHN0cmluZycsICgpID0+IHtcbiAgICAgIHV0aWxzLmlzVmFsaWRQcml2YXRlS2V5KCcnKS5zaG91bGQuZXF1YWwoZmFsc2UpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnZ2V0VW5jb21wcmVzc2VkUHVibGljS2V5JywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgcmV0dXJuIDEyOCBoZXggY2hhcnMgZnJvbSB1bmNvbXByZXNzZWQga2V5JywgKCkgPT4ge1xuICAgICAgY29uc3QgcmVzdWx0ID0gdXRpbHMuZ2V0VW5jb21wcmVzc2VkUHVibGljS2V5KEFjY291bnRzLmFjY291bnQxLnB1YmxpY0tleSk7XG4gICAgICByZXN1bHQubGVuZ3RoLnNob3VsZC5lcXVhbCgxMjgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnZm9ybWF0RXRoQWNjb3VudFNpZ25hdHVyZScsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGZvcm1hdCBzaWduYXR1cmUgYXMgNSBmZWx0MjUyIHZhbHVlcycsICgpID0+IHtcbiAgICAgIGNvbnN0IHIgPSAnYWJjZGVmMTIzNDU2Nzg5MGFiY2RlZjEyMzQ1Njc4OTBhYmNkZWYxMjM0NTY3ODkwYWJjZGVmMTIzNDU2Nzg5MCc7XG4gICAgICBjb25zdCBzID0gJzEyMzQ1Njc4OTBhYmNkZWYxMjM0NTY3ODkwYWJjZGVmMTIzNDU2Nzg5MGFiY2RlZjEyMzQ1Njc4OTBhYmNkZWYnO1xuICAgICAgY29uc3QgcmVzdWx0ID0gdXRpbHMuZm9ybWF0RXRoQWNjb3VudFNpZ25hdHVyZShyLCBzLCAwKTtcbiAgICAgIHJlc3VsdC5sZW5ndGguc2hvdWxkLmVxdWFsKDUpO1xuICAgICAgcmVzdWx0LmZvckVhY2goKHZhbCkgPT4gdmFsLnNob3VsZC5zdGFydFdpdGgoJzB4JykpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYW5kbGUgcmVjaWQgMCBhbmQgMScsICgpID0+IHtcbiAgICAgIGNvbnN0IHIgPSAnYWFhYSc7XG4gICAgICBjb25zdCBzID0gJ2JiYmInO1xuICAgICAgY29uc3Qgc2lnMCA9IHV0aWxzLmZvcm1hdEV0aEFjY291bnRTaWduYXR1cmUociwgcywgMCk7XG4gICAgICBjb25zdCBzaWcxID0gdXRpbHMuZm9ybWF0RXRoQWNjb3VudFNpZ25hdHVyZShyLCBzLCAxKTtcbiAgICAgIHNpZzBbNF0uc2hvdWxkLmVxdWFsKCcweDAnKTtcbiAgICAgIHNpZzFbNF0uc2hvdWxkLmVxdWFsKCcweDEnKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2VuY29kZVNob3J0U3RyaW5nJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgZW5jb2RlIFwiaW52b2tlXCIgY29ycmVjdGx5JywgKCkgPT4ge1xuICAgICAgZW5jb2RlU2hvcnRTdHJpbmcoJ2ludm9rZScpLnNob3VsZC5lcXVhbCgweDY5NmU3NjZmNmI2NW4pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBlbmNvZGUgXCJMMV9HQVNcIiBjb3JyZWN0bHknLCAoKSA9PiB7XG4gICAgICBlbmNvZGVTaG9ydFN0cmluZygnTDFfR0FTJykuc2hvdWxkLmVxdWFsKDB4NGMzMTVmNDc0MTUzbik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGVuY29kZSBcIkwyX0dBU1wiIGNvcnJlY3RseScsICgpID0+IHtcbiAgICAgIGVuY29kZVNob3J0U3RyaW5nKCdMMl9HQVMnKS5zaG91bGQuZXF1YWwoMHg0YzMyNWY0NzQxNTNuKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZW5jb2RlIFwiTDFfREFUQVwiIGNvcnJlY3RseScsICgpID0+IHtcbiAgICAgIGVuY29kZVNob3J0U3RyaW5nKCdMMV9EQVRBJykuc2hvdWxkLmVxdWFsKDB4NGMzMTVmNDQ0MTU0NDFuKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVqZWN0IHN0cmluZ3MgbG9uZ2VyIHRoYW4gMzEgY2hhcnMnLCAoKSA9PiB7XG4gICAgICAoKCkgPT4gZW5jb2RlU2hvcnRTdHJpbmcoJ2EnLnJlcGVhdCgzMikpKS5zaG91bGQudGhyb3coL3RvbyBsb25nLyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdnZXRTZWxlY3RvckZyb21OYW1lJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgY29tcHV0ZSBzZWxlY3RvciBmb3IgXCJ0cmFuc2ZlclwiJywgKCkgPT4ge1xuICAgICAgY29uc3Qgc2VsZWN0b3IgPSBnZXRTZWxlY3RvckZyb21OYW1lKCd0cmFuc2ZlcicpO1xuICAgICAgKHR5cGVvZiBzZWxlY3Rvcikuc2hvdWxkLmVxdWFsKCdiaWdpbnQnKTtcbiAgICAgIChzZWxlY3RvciA+IDBuKS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICAoc2VsZWN0b3IgPCAxbiA8PCAyNTBuKS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGJlIGRldGVybWluaXN0aWMnLCAoKSA9PiB7XG4gICAgICBnZXRTZWxlY3RvckZyb21OYW1lKCd0cmFuc2ZlcicpLnNob3VsZC5lcXVhbChnZXRTZWxlY3RvckZyb21OYW1lKCd0cmFuc2ZlcicpKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2NvbXBpbGVFeGVjdXRlQ2FsbGRhdGEnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBjb21waWxlIGEgc2luZ2xlIHRyYW5zZmVyIGNhbGwnLCAoKSA9PiB7XG4gICAgICBjb25zdCBjYWxscyA9IFtcbiAgICAgICAge1xuICAgICAgICAgIGNvbnRyYWN0QWRkcmVzczogU2FuZGJveFRyYW5zZmVyRGF0YS50b2tlbkNvbnRyYWN0LFxuICAgICAgICAgIGVudHJ5cG9pbnQ6ICd0cmFuc2ZlcicsXG4gICAgICAgICAgY2FsbGRhdGE6IFtcbiAgICAgICAgICAgIFNhbmRib3hUcmFuc2ZlckRhdGEucmVjZWl2ZXJBZGRyZXNzLFxuICAgICAgICAgICAgJzB4JyArIChCaWdJbnQoU2FuZGJveFRyYW5zZmVyRGF0YS5hbW91bnQpICYgTUFTS18xMjgpLnRvU3RyaW5nKDE2KSxcbiAgICAgICAgICAgICcweCcgKyAoQmlnSW50KFNhbmRib3hUcmFuc2ZlckRhdGEuYW1vdW50KSA+PiAxMjhuKS50b1N0cmluZygxNiksXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgIF07XG4gICAgICBjb25zdCBjb21waWxlZCA9IGNvbXBpbGVFeGVjdXRlQ2FsbGRhdGEoY2FsbHMpO1xuICAgICAgY29tcGlsZWRbMF0uc2hvdWxkLmVxdWFsKCcweDEnKTsgLy8gbnVtX2NhbGxzID0gMVxuICAgICAgY29tcGlsZWRbMV0uc2hvdWxkLmVxdWFsKFNhbmRib3hUcmFuc2ZlckRhdGEudG9rZW5Db250cmFjdCk7IC8vIHRvXG4gICAgICBjb21waWxlZC5sZW5ndGguc2hvdWxkLmVxdWFsKDEgKyAxICsgMSArIDEgKyAzKTsgLy8gbnVtX2NhbGxzICsgdG8gKyBzZWxlY3RvciArIGRhdGFfbGVuICsgMyBjYWxsZGF0YVxuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnY2FsY3VsYXRlSW52b2tlVHJhbnNhY3Rpb25IYXNoJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgcHJvZHVjZSBhIGRldGVybWluaXN0aWMgaGFzaCcsICgpID0+IHtcbiAgICAgIGNvbnN0IGNhbGxzID0gW1xuICAgICAgICB7XG4gICAgICAgICAgY29udHJhY3RBZGRyZXNzOiBTYW5kYm94VHJhbnNmZXJEYXRhLnRva2VuQ29udHJhY3QsXG4gICAgICAgICAgZW50cnlwb2ludDogJ3RyYW5zZmVyJyxcbiAgICAgICAgICBjYWxsZGF0YTogW1xuICAgICAgICAgICAgU2FuZGJveFRyYW5zZmVyRGF0YS5yZWNlaXZlckFkZHJlc3MsXG4gICAgICAgICAgICAnMHgnICsgKEJpZ0ludChTYW5kYm94VHJhbnNmZXJEYXRhLmFtb3VudCkgJiBNQVNLXzEyOCkudG9TdHJpbmcoMTYpLFxuICAgICAgICAgICAgJzB4JyArIChCaWdJbnQoU2FuZGJveFRyYW5zZmVyRGF0YS5hbW91bnQpID4+IDEyOG4pLnRvU3RyaW5nKDE2KSxcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgXTtcbiAgICAgIGNvbnN0IGNvbXBpbGVkQ2FsbGRhdGEgPSBjb21waWxlRXhlY3V0ZUNhbGxkYXRhKGNhbGxzKTtcblxuICAgICAgY29uc3QgaGFzaDEgPSBjYWxjdWxhdGVJbnZva2VUcmFuc2FjdGlvbkhhc2goe1xuICAgICAgICBzZW5kZXJBZGRyZXNzOiBTYW5kYm94VHJhbnNmZXJEYXRhLnNlbmRlckFkZHJlc3MsXG4gICAgICAgIGNvbXBpbGVkQ2FsbGRhdGEsXG4gICAgICAgIGNoYWluSWQ6IFNhbmRib3hUcmFuc2ZlckRhdGEuY2hhaW5JZCxcbiAgICAgICAgbm9uY2U6ICcweDAnLFxuICAgICAgICByZXNvdXJjZUJvdW5kczogU2FuZGJveFRyYW5zZmVyRGF0YS5yZXNvdXJjZUJvdW5kcyxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBoYXNoMiA9IGNhbGN1bGF0ZUludm9rZVRyYW5zYWN0aW9uSGFzaCh7XG4gICAgICAgIHNlbmRlckFkZHJlc3M6IFNhbmRib3hUcmFuc2ZlckRhdGEuc2VuZGVyQWRkcmVzcyxcbiAgICAgICAgY29tcGlsZWRDYWxsZGF0YSxcbiAgICAgICAgY2hhaW5JZDogU2FuZGJveFRyYW5zZmVyRGF0YS5jaGFpbklkLFxuICAgICAgICBub25jZTogJzB4MCcsXG4gICAgICAgIHJlc291cmNlQm91bmRzOiBTYW5kYm94VHJhbnNmZXJEYXRhLnJlc291cmNlQm91bmRzLFxuICAgICAgfSk7XG5cbiAgICAgIGhhc2gxLnNob3VsZC5lcXVhbChoYXNoMik7XG4gICAgICBoYXNoMS5zaG91bGQuc3RhcnRXaXRoKCcweCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwcm9kdWNlIGRpZmZlcmVudCBoYXNoZXMgZm9yIGRpZmZlcmVudCBub25jZXMnLCAoKSA9PiB7XG4gICAgICBjb25zdCBjYWxscyA9IFtcbiAgICAgICAge1xuICAgICAgICAgIGNvbnRyYWN0QWRkcmVzczogU2FuZGJveFRyYW5zZmVyRGF0YS50b2tlbkNvbnRyYWN0LFxuICAgICAgICAgIGVudHJ5cG9pbnQ6ICd0cmFuc2ZlcicsXG4gICAgICAgICAgY2FsbGRhdGE6IFtTYW5kYm94VHJhbnNmZXJEYXRhLnJlY2VpdmVyQWRkcmVzcywgJzB4ZGUwYjZiM2E3NjQwMDAwJywgJzB4MCddLFxuICAgICAgICB9LFxuICAgICAgXTtcbiAgICAgIGNvbnN0IGNvbXBpbGVkQ2FsbGRhdGEgPSBjb21waWxlRXhlY3V0ZUNhbGxkYXRhKGNhbGxzKTtcblxuICAgICAgY29uc3QgaGFzaDEgPSBjYWxjdWxhdGVJbnZva2VUcmFuc2FjdGlvbkhhc2goe1xuICAgICAgICBzZW5kZXJBZGRyZXNzOiBTYW5kYm94VHJhbnNmZXJEYXRhLnNlbmRlckFkZHJlc3MsXG4gICAgICAgIGNvbXBpbGVkQ2FsbGRhdGEsXG4gICAgICAgIGNoYWluSWQ6IFNhbmRib3hUcmFuc2ZlckRhdGEuY2hhaW5JZCxcbiAgICAgICAgbm9uY2U6ICcweDAnLFxuICAgICAgICByZXNvdXJjZUJvdW5kczogU2FuZGJveFRyYW5zZmVyRGF0YS5yZXNvdXJjZUJvdW5kcyxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBoYXNoMiA9IGNhbGN1bGF0ZUludm9rZVRyYW5zYWN0aW9uSGFzaCh7XG4gICAgICAgIHNlbmRlckFkZHJlc3M6IFNhbmRib3hUcmFuc2ZlckRhdGEuc2VuZGVyQWRkcmVzcyxcbiAgICAgICAgY29tcGlsZWRDYWxsZGF0YSxcbiAgICAgICAgY2hhaW5JZDogU2FuZGJveFRyYW5zZmVyRGF0YS5jaGFpbklkLFxuICAgICAgICBub25jZTogJzB4MScsXG4gICAgICAgIHJlc291cmNlQm91bmRzOiBTYW5kYm94VHJhbnNmZXJEYXRhLnJlc291cmNlQm91bmRzLFxuICAgICAgfSk7XG5cbiAgICAgIGhhc2gxLnNob3VsZC5ub3QuZXF1YWwoaGFzaDIpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBub3QgaW5jbHVkZSBwcm9vZl9mYWN0cyB3aGVuIGFic2VudCcsICgpID0+IHtcbiAgICAgIGNvbnN0IGNhbGxzID0gW1xuICAgICAgICB7XG4gICAgICAgICAgY29udHJhY3RBZGRyZXNzOiBTYW5kYm94VHJhbnNmZXJEYXRhLnRva2VuQ29udHJhY3QsXG4gICAgICAgICAgZW50cnlwb2ludDogJ3RyYW5zZmVyJyxcbiAgICAgICAgICBjYWxsZGF0YTogW1NhbmRib3hUcmFuc2ZlckRhdGEucmVjZWl2ZXJBZGRyZXNzLCAnMHhkZTBiNmIzYTc2NDAwMDAnLCAnMHgwJ10sXG4gICAgICAgIH0sXG4gICAgICBdO1xuICAgICAgY29uc3QgY29tcGlsZWRDYWxsZGF0YSA9IGNvbXBpbGVFeGVjdXRlQ2FsbGRhdGEoY2FsbHMpO1xuXG4gICAgICBjb25zdCBoYXNoV2l0aG91dCA9IGNhbGN1bGF0ZUludm9rZVRyYW5zYWN0aW9uSGFzaCh7XG4gICAgICAgIHNlbmRlckFkZHJlc3M6IFNhbmRib3hUcmFuc2ZlckRhdGEuc2VuZGVyQWRkcmVzcyxcbiAgICAgICAgY29tcGlsZWRDYWxsZGF0YSxcbiAgICAgICAgY2hhaW5JZDogU2FuZGJveFRyYW5zZmVyRGF0YS5jaGFpbklkLFxuICAgICAgICBub25jZTogJzB4MCcsXG4gICAgICAgIHJlc291cmNlQm91bmRzOiBTYW5kYm94VHJhbnNmZXJEYXRhLnJlc291cmNlQm91bmRzLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGhhc2hXaXRoRW1wdHkgPSBjYWxjdWxhdGVJbnZva2VUcmFuc2FjdGlvbkhhc2goe1xuICAgICAgICBzZW5kZXJBZGRyZXNzOiBTYW5kYm94VHJhbnNmZXJEYXRhLnNlbmRlckFkZHJlc3MsXG4gICAgICAgIGNvbXBpbGVkQ2FsbGRhdGEsXG4gICAgICAgIGNoYWluSWQ6IFNhbmRib3hUcmFuc2ZlckRhdGEuY2hhaW5JZCxcbiAgICAgICAgbm9uY2U6ICcweDAnLFxuICAgICAgICByZXNvdXJjZUJvdW5kczogU2FuZGJveFRyYW5zZmVyRGF0YS5yZXNvdXJjZUJvdW5kcyxcbiAgICAgICAgcHJvb2ZGYWN0czogW10sXG4gICAgICB9KTtcblxuICAgICAgLy8gRW1wdHkgcHJvb2ZGYWN0cyBzaG91bGQgYmUgb21pdHRlZCwgcHJvZHVjaW5nIHNhbWUgaGFzaCBhcyBhYnNlbnRcbiAgICAgIGhhc2hXaXRob3V0LnNob3VsZC5lcXVhbChoYXNoV2l0aEVtcHR5KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgbWF0Y2gga25vd24tZ29vZCBzYW5kYm94IHR4IGhhc2ggKDB4NzM5YTcyOC4uLiknLCAoKSA9PiB7XG4gICAgICBjb25zdCB0diA9IEtub3duR29vZEludm9rZVR4O1xuICAgICAgY29uc3QgYW1vdW50QmlnID0gQmlnSW50KHR2LmFtb3VudCk7XG4gICAgICBjb25zdCBjYWxscyA9IFtcbiAgICAgICAge1xuICAgICAgICAgIGNvbnRyYWN0QWRkcmVzczogdHYudG9rZW5Db250cmFjdCxcbiAgICAgICAgICBlbnRyeXBvaW50OiAndHJhbnNmZXInLFxuICAgICAgICAgIGNhbGxkYXRhOiBbXG4gICAgICAgICAgICB0di5yZWNlaXZlckFkZHJlc3MsXG4gICAgICAgICAgICAnMHgnICsgKGFtb3VudEJpZyAmIE1BU0tfMTI4KS50b1N0cmluZygxNiksXG4gICAgICAgICAgICAnMHgnICsgKGFtb3VudEJpZyA+PiAxMjhuKS50b1N0cmluZygxNiksXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgIF07XG4gICAgICBjb25zdCBjb21waWxlZENhbGxkYXRhID0gY29tcGlsZUV4ZWN1dGVDYWxsZGF0YShjYWxscyk7XG5cbiAgICAgIGNvbnN0IGhhc2ggPSBjYWxjdWxhdGVJbnZva2VUcmFuc2FjdGlvbkhhc2goe1xuICAgICAgICBzZW5kZXJBZGRyZXNzOiB0di5zZW5kZXJBZGRyZXNzLFxuICAgICAgICBjb21waWxlZENhbGxkYXRhLFxuICAgICAgICBjaGFpbklkOiB0di5jaGFpbklkLFxuICAgICAgICBub25jZTogdHYubm9uY2UsXG4gICAgICAgIHJlc291cmNlQm91bmRzOiB0di5yZXNvdXJjZUJvdW5kcyxcbiAgICAgICAgdGlwOiB0di50aXAsXG4gICAgICB9KTtcblxuICAgICAgaGFzaC5zaG91bGQuZXF1YWwodHYuZXhwZWN0ZWRUeEhhc2gpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19