@bitgo-beta/key-card 0.0.1-beta.20 → 0.0.1-beta.2000

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 (39) hide show
  1. package/dist/src/drawKeycard.d.ts +5 -0
  2. package/dist/src/drawKeycard.d.ts.map +1 -0
  3. package/dist/src/drawKeycard.js +285 -0
  4. package/dist/src/extractKeycardFromPDF.d.ts +16 -0
  5. package/dist/src/extractKeycardFromPDF.d.ts.map +1 -0
  6. package/dist/src/extractKeycardFromPDF.js +77 -0
  7. package/dist/src/faq.d.ts +4 -0
  8. package/dist/src/faq.d.ts.map +1 -0
  9. package/dist/src/faq.js +89 -0
  10. package/dist/src/generateParamsForKeyCreation.d.ts +3 -0
  11. package/dist/src/generateParamsForKeyCreation.d.ts.map +1 -0
  12. package/dist/src/generateParamsForKeyCreation.js +72 -0
  13. package/dist/src/generateQrData.d.ts +4 -0
  14. package/dist/src/generateQrData.d.ts.map +1 -0
  15. package/dist/src/generateQrData.js +186 -0
  16. package/dist/src/index.d.ts +11 -0
  17. package/dist/src/index.d.ts.map +1 -0
  18. package/dist/src/index.js +62 -0
  19. package/dist/src/parseKeycard.d.ts +23 -0
  20. package/dist/src/parseKeycard.d.ts.map +1 -0
  21. package/dist/src/parseKeycard.js +159 -0
  22. package/dist/src/types.d.ts +66 -0
  23. package/dist/src/types.d.ts.map +1 -0
  24. package/dist/src/types.js +3 -0
  25. package/dist/src/utils.d.ts +2 -0
  26. package/dist/src/utils.d.ts.map +1 -0
  27. package/dist/src/utils.js +16 -0
  28. package/dist/tsconfig.tsbuildinfo +1 -0
  29. package/package.json +10 -6
  30. package/.mocharc.js +0 -9
  31. package/src/drawKeycard.ts +0 -240
  32. package/src/faq.ts +0 -82
  33. package/src/generateQrData.ts +0 -167
  34. package/src/index.ts +0 -22
  35. package/src/utils.ts +0 -15
  36. package/test/unit/faq.ts +0 -14
  37. package/test/unit/generateQrData.ts +0 -213
  38. package/test/unit/utils.ts +0 -30
  39. package/tsconfig.json +0 -20
@@ -0,0 +1,72 @@
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
+ exports.generateParamsForKeyCreation = generateParamsForKeyCreation;
37
+ const assert = __importStar(require("assert"));
38
+ function generateParamsForKeyCreation({ curve, bitgoKeychain, walletLabel, keyCardImage, }) {
39
+ assert.ok(bitgoKeychain.commonKeychain, 'bitgoKeychain.commonKeychain is required');
40
+ return {
41
+ walletLabel,
42
+ keyCardImage,
43
+ curve,
44
+ qrData: {
45
+ user: {
46
+ title: 'A: Common Keychain',
47
+ data: bitgoKeychain.commonKeychain,
48
+ description: 'This is the common pub which is the equivalent of xpub (public key)\r\nof the key generated',
49
+ },
50
+ bitgo: {
51
+ title: 'B: BitGo Key ID',
52
+ data: bitgoKeychain.id,
53
+ description: 'This is the identifier assigned to the key generated using which BitGo\r\ncan lookup BitGo key share.',
54
+ },
55
+ },
56
+ questions: [
57
+ {
58
+ question: 'What is the KeyCard?',
59
+ answer: [
60
+ 'This key card contains information about the key id for the generated key.\r\nThis id can later be used to derive wallets.',
61
+ ],
62
+ },
63
+ {
64
+ question: 'What should I do with it?',
65
+ answer: [
66
+ 'Store this keycard for later use. The key ID is important to communicate with BitGo\r\nto derive wallets from the key.',
67
+ ],
68
+ },
69
+ ],
70
+ };
71
+ }
72
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJhdGVQYXJhbXNGb3JLZXlDcmVhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9nZW5lcmF0ZVBhcmFtc0ZvcktleUNyZWF0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBR0Esb0VBdUNDO0FBMUNELCtDQUFpQztBQUdqQyxTQUFnQiw0QkFBNEIsQ0FBQyxFQUMzQyxLQUFLLEVBQ0wsYUFBYSxFQUNiLFdBQVcsRUFDWCxZQUFZLEdBQytDO0lBQzNELE1BQU0sQ0FBQyxFQUFFLENBQUMsYUFBYSxDQUFDLGNBQWMsRUFBRSwwQ0FBMEMsQ0FBQyxDQUFDO0lBQ3BGLE9BQU87UUFDTCxXQUFXO1FBQ1gsWUFBWTtRQUNaLEtBQUs7UUFDTCxNQUFNLEVBQUU7WUFDTixJQUFJLEVBQUU7Z0JBQ0osS0FBSyxFQUFFLG9CQUFvQjtnQkFDM0IsSUFBSSxFQUFFLGFBQWEsQ0FBQyxjQUFjO2dCQUNsQyxXQUFXLEVBQUUsNkZBQTZGO2FBQzNHO1lBQ0QsS0FBSyxFQUFFO2dCQUNMLEtBQUssRUFBRSxpQkFBaUI7Z0JBQ3hCLElBQUksRUFBRSxhQUFhLENBQUMsRUFBRTtnQkFDdEIsV0FBVyxFQUNULHVHQUF1RzthQUMxRztTQUNGO1FBQ0QsU0FBUyxFQUFFO1lBQ1Q7Z0JBQ0UsUUFBUSxFQUFFLHNCQUFzQjtnQkFDaEMsTUFBTSxFQUFFO29CQUNOLDRIQUE0SDtpQkFDN0g7YUFDRjtZQUNEO2dCQUNFLFFBQVEsRUFBRSwyQkFBMkI7Z0JBQ3JDLE1BQU0sRUFBRTtvQkFDTix3SEFBd0g7aUJBQ3pIO2FBQ0Y7U0FDRjtLQUNGLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5pbXBvcnQgeyBHZW5lcmF0ZVFyRGF0YUJhc2VQYXJhbXMsIEdlbmVyYXRlUXJEYXRhRm9yS2V5Y2hhaW5QYXJhbXMsIElEcmF3S2V5Q2FyZCB9IGZyb20gJy4vdHlwZXMnO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVQYXJhbXNGb3JLZXlDcmVhdGlvbih7XG4gIGN1cnZlLFxuICBiaXRnb0tleWNoYWluLFxuICB3YWxsZXRMYWJlbCxcbiAga2V5Q2FyZEltYWdlLFxufTogR2VuZXJhdGVRckRhdGFGb3JLZXljaGFpblBhcmFtcyAmIEdlbmVyYXRlUXJEYXRhQmFzZVBhcmFtcyk6IElEcmF3S2V5Q2FyZCB7XG4gIGFzc2VydC5vayhiaXRnb0tleWNoYWluLmNvbW1vbktleWNoYWluLCAnYml0Z29LZXljaGFpbi5jb21tb25LZXljaGFpbiBpcyByZXF1aXJlZCcpO1xuICByZXR1cm4ge1xuICAgIHdhbGxldExhYmVsLFxuICAgIGtleUNhcmRJbWFnZSxcbiAgICBjdXJ2ZSxcbiAgICBxckRhdGE6IHtcbiAgICAgIHVzZXI6IHtcbiAgICAgICAgdGl0bGU6ICdBOiBDb21tb24gS2V5Y2hhaW4nLFxuICAgICAgICBkYXRhOiBiaXRnb0tleWNoYWluLmNvbW1vbktleWNoYWluLFxuICAgICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIGNvbW1vbiBwdWIgd2hpY2ggaXMgdGhlIGVxdWl2YWxlbnQgb2YgeHB1YiAocHVibGljIGtleSlcXHJcXG5vZiB0aGUga2V5IGdlbmVyYXRlZCcsXG4gICAgICB9LFxuICAgICAgYml0Z286IHtcbiAgICAgICAgdGl0bGU6ICdCOiBCaXRHbyBLZXkgSUQnLFxuICAgICAgICBkYXRhOiBiaXRnb0tleWNoYWluLmlkLFxuICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAnVGhpcyBpcyB0aGUgaWRlbnRpZmllciBhc3NpZ25lZCB0byB0aGUga2V5IGdlbmVyYXRlZCB1c2luZyB3aGljaCBCaXRHb1xcclxcbmNhbiBsb29rdXAgQml0R28ga2V5IHNoYXJlLicsXG4gICAgICB9LFxuICAgIH0sXG4gICAgcXVlc3Rpb25zOiBbXG4gICAgICB7XG4gICAgICAgIHF1ZXN0aW9uOiAnV2hhdCBpcyB0aGUgS2V5Q2FyZD8nLFxuICAgICAgICBhbnN3ZXI6IFtcbiAgICAgICAgICAnVGhpcyBrZXkgY2FyZCBjb250YWlucyBpbmZvcm1hdGlvbiBhYm91dCB0aGUga2V5IGlkIGZvciB0aGUgZ2VuZXJhdGVkIGtleS5cXHJcXG5UaGlzIGlkIGNhbiBsYXRlciBiZSB1c2VkIHRvIGRlcml2ZSB3YWxsZXRzLicsXG4gICAgICAgIF0sXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBxdWVzdGlvbjogJ1doYXQgc2hvdWxkIEkgZG8gd2l0aCBpdD8nLFxuICAgICAgICBhbnN3ZXI6IFtcbiAgICAgICAgICAnU3RvcmUgdGhpcyBrZXljYXJkIGZvciBsYXRlciB1c2UuIFRoZSBrZXkgSUQgaXMgaW1wb3J0YW50IHRvIGNvbW11bmljYXRlIHdpdGggQml0R29cXHJcXG50byBkZXJpdmUgd2FsbGV0cyBmcm9tIHRoZSBrZXkuJyxcbiAgICAgICAgXSxcbiAgICAgIH0sXG4gICAgXSxcbiAgfTtcbn1cbiJdfQ==
@@ -0,0 +1,4 @@
1
+ import { GenerateLightningQrDataParams, GenerateQrDataParams, QrData } from './types';
2
+ export declare function generateQrData(params: GenerateQrDataParams): Promise<QrData>;
3
+ export declare function generateLightningQrData(params: GenerateLightningQrDataParams): Promise<QrData>;
4
+ //# sourceMappingURL=generateQrData.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateQrData.d.ts","sourceRoot":"","sources":["../../src/generateQrData.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,6BAA6B,EAC7B,oBAAoB,EAEpB,MAAM,EAEP,MAAM,SAAS,CAAC;AAoLjB,wBAAsB,cAAc,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,CAYlF;AAED,wBAAsB,uBAAuB,CAAC,MAAM,EAAE,6BAA6B,GAAG,OAAO,CAAC,MAAM,CAAC,CAYpG"}
@@ -0,0 +1,186 @@
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
+ exports.generateQrData = generateQrData;
37
+ exports.generateLightningQrData = generateLightningQrData;
38
+ const sdk_api_1 = require("@bitgo-beta/sdk-api");
39
+ const assert = __importStar(require("assert"));
40
+ function getPubFromKey(key) {
41
+ switch (key.type) {
42
+ case 'blsdkg':
43
+ return key.commonPub;
44
+ case 'tss':
45
+ return key.commonKeychain;
46
+ case 'independent':
47
+ return key.pub;
48
+ }
49
+ }
50
+ function generateUserQrData(userKeychain, userMasterKey) {
51
+ if (userKeychain.reducedEncryptedPrv) {
52
+ return {
53
+ title: 'A: User Key',
54
+ description: 'This is your private key, encrypted with your wallet password.',
55
+ data: userKeychain.reducedEncryptedPrv,
56
+ };
57
+ }
58
+ if (userKeychain.encryptedPrv) {
59
+ return {
60
+ title: 'A: User Key',
61
+ description: 'This is your private key, encrypted with your wallet password.',
62
+ data: userKeychain.encryptedPrv,
63
+ };
64
+ }
65
+ const pub = getPubFromKey(userKeychain);
66
+ assert.ok(pub);
67
+ return {
68
+ title: 'A: Provided User Key',
69
+ description: 'This is the public key you provided for your wallet.',
70
+ data: pub,
71
+ publicMasterKey: userMasterKey,
72
+ };
73
+ }
74
+ function generateBackupQrData(coin, backupKeychain, { backupKeyProvider, backupMasterKey, } = {}) {
75
+ const title = 'B: Backup Key';
76
+ if (backupKeychain.reducedEncryptedPrv) {
77
+ return {
78
+ title,
79
+ description: 'This is your backup private key, encrypted with your wallet password.',
80
+ data: backupKeychain.reducedEncryptedPrv,
81
+ };
82
+ }
83
+ if (backupKeychain.encryptedPrv) {
84
+ return {
85
+ title,
86
+ description: 'This is your backup private key, encrypted with your wallet password.',
87
+ data: backupKeychain.encryptedPrv,
88
+ };
89
+ }
90
+ if (backupKeyProvider === 'BitGo Trust' && backupKeychain.type === 'tss') {
91
+ const keyShares = backupKeychain.keyShares?.filter((keyShare) => keyShare.to === 'backup');
92
+ assert.ok(keyShares?.length === 2);
93
+ return {
94
+ title: 'B: Backup Key Shares',
95
+ description: `These are the key shares for ${backupKeyProvider}. If BitGo Inc. goes out of business,\r\n` +
96
+ `contact ${backupKeyProvider} and they will help you recover your funds.`,
97
+ data: JSON.stringify(keyShares),
98
+ };
99
+ }
100
+ const pub = getPubFromKey(backupKeychain);
101
+ assert.ok(pub);
102
+ if (backupKeyProvider) {
103
+ return {
104
+ title: 'B: Backup Key',
105
+ description: `This is the public key held at ${backupKeyProvider}, an ${coin.name} recovery service. ` +
106
+ `If you lose\r\nyour key, ${backupKeyProvider} will be able to sign transactions to recover funds.`,
107
+ data: pub,
108
+ };
109
+ }
110
+ return {
111
+ title: 'B: Provided Backup Key',
112
+ description: 'This is the public key you provided for your wallet.',
113
+ data: pub,
114
+ publicMasterKey: backupMasterKey,
115
+ };
116
+ }
117
+ function generateBitGoQrData(bitgoKeychain) {
118
+ const bitgoData = getPubFromKey(bitgoKeychain);
119
+ assert.ok(bitgoData);
120
+ return {
121
+ title: 'C: BitGo Key',
122
+ description: 'This is the public part of the key held by BitGo.',
123
+ data: bitgoData,
124
+ };
125
+ }
126
+ function generateUserMasterPublicKeyQRData(publicKey) {
127
+ return {
128
+ title: 'E: Master User Public Key',
129
+ description: 'This is the public key used to derive the user key for the wallet. This is not stored by BitGo, and may be required for use in recovery scenarios.',
130
+ data: publicKey,
131
+ };
132
+ }
133
+ async function generatePasscodeQrData(passphrase, passcodeEncryptionCode, encryptionVersion) {
134
+ const encryptedWalletPasscode = await (0, sdk_api_1.encrypt)(passcodeEncryptionCode, passphrase, { encryptionVersion });
135
+ return {
136
+ title: 'D: Encrypted Wallet Password',
137
+ description: 'This is the wallet password, encrypted client-side with a key held by BitGo.',
138
+ data: encryptedWalletPasscode,
139
+ };
140
+ }
141
+ function generateBackupMasterPublicKeyQRData(publicKey) {
142
+ return {
143
+ title: 'F: Master Backup Public Key',
144
+ description: 'This is the public key used to derive the backup key for the wallet. This is not stored by BitGo, and may be required for use in recovery scenarios.',
145
+ data: publicKey,
146
+ };
147
+ }
148
+ function buildWalletQrData({ backupKeychain, backupKeyProvider, backupMasterKey, bitgoKeychain, coin, userKeychain, userMasterKey, userMasterPublicKey, backupMasterPublicKey, }) {
149
+ return {
150
+ user: generateUserQrData(userKeychain, userMasterKey),
151
+ userMasterPublicKey: userMasterPublicKey ? generateUserMasterPublicKeyQRData(userMasterPublicKey) : undefined,
152
+ backup: generateBackupQrData(coin, backupKeychain, {
153
+ backupKeyProvider,
154
+ backupMasterKey,
155
+ }),
156
+ backupMasterPublicKey: backupMasterPublicKey
157
+ ? generateBackupMasterPublicKeyQRData(backupMasterPublicKey)
158
+ : undefined,
159
+ bitgo: generateBitGoQrData(bitgoKeychain),
160
+ };
161
+ }
162
+ function buildLightningQrData({ userAuthKeychain }) {
163
+ assert.ok(userAuthKeychain.encryptedPrv, 'userAuthKeychain must have an encryptedPrv');
164
+ return {
165
+ user: {
166
+ title: 'A: User Auth Key',
167
+ description: 'This is your user authentication private key, encrypted with your wallet password.\r\nIt is used to authenticate payment and wallet operations.',
168
+ data: userAuthKeychain.encryptedPrv,
169
+ },
170
+ };
171
+ }
172
+ async function generateQrData(params) {
173
+ const qrData = buildWalletQrData(params);
174
+ if (params.passphrase && params.passcodeEncryptionCode) {
175
+ qrData.passcode = await generatePasscodeQrData(params.passphrase, params.passcodeEncryptionCode, params.encryptionVersion);
176
+ }
177
+ return qrData;
178
+ }
179
+ async function generateLightningQrData(params) {
180
+ const qrData = buildLightningQrData(params);
181
+ if (params.passphrase && params.passcodeEncryptionCode) {
182
+ qrData.passcode = await generatePasscodeQrData(params.passphrase, params.passcodeEncryptionCode, params.encryptionVersion);
183
+ }
184
+ return qrData;
185
+ }
186
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJhdGVRckRhdGEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZ2VuZXJhdGVRckRhdGEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUE4TEEsd0NBWUM7QUFFRCwwREFZQztBQXRORCxpREFBOEM7QUFDOUMsK0NBQWlDO0FBU2pDLFNBQVMsYUFBYSxDQUFDLEdBQWE7SUFDbEMsUUFBUSxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDakIsS0FBSyxRQUFRO1lBQ1gsT0FBTyxHQUFHLENBQUMsU0FBUyxDQUFDO1FBQ3ZCLEtBQUssS0FBSztZQUNSLE9BQU8sR0FBRyxDQUFDLGNBQWMsQ0FBQztRQUM1QixLQUFLLGFBQWE7WUFDaEIsT0FBTyxHQUFHLENBQUMsR0FBRyxDQUFDO0lBQ25CLENBQUM7QUFDSCxDQUFDO0FBRUQsU0FBUyxrQkFBa0IsQ0FBQyxZQUFzQixFQUFFLGFBQXNCO0lBQ3hFLElBQUksWUFBWSxDQUFDLG1CQUFtQixFQUFFLENBQUM7UUFDckMsT0FBTztZQUNMLEtBQUssRUFBRSxhQUFhO1lBQ3BCLFdBQVcsRUFBRSxnRUFBZ0U7WUFDN0UsSUFBSSxFQUFFLFlBQVksQ0FBQyxtQkFBbUI7U0FDdkMsQ0FBQztJQUNKLENBQUM7SUFDRCxJQUFJLFlBQVksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUM5QixPQUFPO1lBQ0wsS0FBSyxFQUFFLGFBQWE7WUFDcEIsV0FBVyxFQUFFLGdFQUFnRTtZQUM3RSxJQUFJLEVBQUUsWUFBWSxDQUFDLFlBQVk7U0FDaEMsQ0FBQztJQUNKLENBQUM7SUFFRCxNQUFNLEdBQUcsR0FBRyxhQUFhLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDeEMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUVmLE9BQU87UUFDTCxLQUFLLEVBQUUsc0JBQXNCO1FBQzdCLFdBQVcsRUFBRSxzREFBc0Q7UUFDbkUs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RCxNQUFNLE1BQU0sR0FBRyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUV6QyxJQUFJLE1BQU0sQ0FBQyxVQUFVLElBQUksTUFBTSxDQUFDLHNCQUFzQixFQUFFLENBQUM7UUFDdkQsTUFBTSxDQUFDLFFBQVEsR0FBRyxNQUFNLHNCQUFzQixDQUM1QyxNQUFNLENBQUMsVUFBVSxFQUNqQixNQUFNLENBQUMsc0JBQXNCLEVBQzdCLE1BQU0sQ0FBQyxpQkFBaUIsQ0FDekIsQ0FBQztJQUNKLENBQUM7SUFFRCxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDO0FBRU0sS0FBSyxVQUFVLHVCQUF1QixDQUFDLE1BQXFDO0lBQ2pGLE1BQU0sTUFBTSxHQUFHLG9CQUFvQixDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBRTVDLElBQUksTUFBTSxDQUFDLFVBQVUsSUFBSSxNQUFNLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztRQUN2RCxNQUFNLENBQUMsUUFBUSxHQUFHLE1BQU0sc0JBQXNCLENBQzVDLE1BQU0sQ0FBQyxVQUFVLEVBQ2pCLE1BQU0sQ0FBQyxzQkFBc0IsRUFDN0IsTUFBTSxDQUFDLGlCQUFpQixDQUN6QixDQUFDO0lBQ0osQ0FBQztJQUVELE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBCYXNlQ29pbiB9IGZyb20gJ0BiaXRnby1iZXRhL3N0YXRpY3MnO1xuaW1wb3J0IHsgS2V5Y2hhaW4gfSBmcm9tICdAYml0Z28tYmV0YS9zZGstY29yZSc7XG5pbXBvcnQgeyBlbmNyeXB0IH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWFwaSc7XG5pbXBvcnQgKiBhcyBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCB7XG4gIEdlbmVyYXRlTGlnaHRuaW5nUXJEYXRhUGFyYW1zLFxuICBHZW5lcmF0ZVFyRGF0YVBhcmFtcyxcbiAgTWFzdGVyUHVibGljS2V5UXJEYXRhRW50cnksXG4gIFFyRGF0YSxcbiAgUXJEYXRhRW50cnksXG59IGZyb20gJy4vdHlwZXMnO1xuXG5mdW5jdGlvbiBnZXRQdWJGcm9tS2V5KGtleTogS2V5Y2hhaW4pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBzd2l0Y2ggKGtleS50eXBlKSB7XG4gICAgY2FzZSAnYmxzZGtnJzpcbiAgICAgIHJldHVybiBrZXkuY29tbW9uUHViO1xuICAgIGNhc2UgJ3Rzcyc6XG4gICAgICByZXR1cm4ga2V5LmNvbW1vbktleWNoYWluO1xuICAgIGNhc2UgJ2luZGVwZW5kZW50JzpcbiAgICAgIHJldHVybiBrZXkucHViO1xuICB9XG59XG5cbmZ1bmN0aW9uIGdlbmVyYXRlVXNlclFyRGF0YSh1c2VyS2V5Y2hhaW46IEtleWNoYWluLCB1c2VyTWFzdGVyS2V5Pzogc3RyaW5nKTogUXJEYXRhRW50cnkge1xuICBpZiAodXNlcktleWNoYWluLnJlZHVjZWRFbmNyeXB0ZWRQcnYpIHtcbiAgICByZXR1cm4ge1xuICAgICAgdGl0bGU6ICdBOiBVc2VyIEtleScsXG4gICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgeW91ciBwcml2YXRlIGtleSwgZW5jcnlwdGVkIHdpdGggeW91ciB3YWxsZXQgcGFzc3dvcmQuJyxcbiAgICAgIGRhdGE6IHVzZXJLZXljaGFpbi5yZWR1Y2VkRW5jcnlwdGVkUHJ2LFxuICAgIH07XG4gIH1cbiAgaWYgKHVzZXJLZXljaGFpbi5lbmNyeXB0ZWRQcnYpIHtcbiAgICByZXR1cm4ge1xuICAgICAgdGl0bGU6ICdBOiBVc2VyIEtleScsXG4gICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgeW91ciBwcml2YXRlIGtleSwgZW5jcnlwdGVkIHdpdGggeW91ciB3YWxsZXQgcGFzc3dvcmQuJyxcbiAgICAgIGRhdGE6IHVzZXJLZXljaGFpbi5lbmNyeXB0ZWRQcnYsXG4gICAgfTtcbiAgfVxuXG4gIGNvbnN0IHB1YiA9IGdldFB1YkZyb21LZXkodXNlcktleWNoYWluKTtcbiAgYXNzZXJ0Lm9rKHB1Yik7XG5cbiAgcmV0dXJuIHtcbiAgICB0aXRsZTogJ0E6IFByb3ZpZGVkIFVzZXIgS2V5JyxcbiAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIHB1YmxpYyBrZXkgeW91IHByb3ZpZGVkIGZvciB5b3VyIHdhbGxldC4nLFxuICAgIGRhdGE6IHB1YixcbiAgICBwdWJsaWNNYXN0ZXJLZXk6IHVzZXJNYXN0ZXJLZXksXG4gIH07XG59XG5cbmZ1bmN0aW9uIGdlbmVyYXRlQmFja3VwUXJEYXRhKFxuICBjb2luOiBSZWFkb25seTxCYXNlQ29pbj4sXG4gIGJhY2t1cEtleWNoYWluOiBLZXljaGFpbixcbiAge1xuICAgIGJhY2t1cEtleVByb3ZpZGVyLFxuICAgIGJhY2t1cE1hc3RlcktleSxcbiAgfToge1xuICAgIGJhY2t1cEtleVByb3ZpZGVyPzogc3RyaW5nO1xuICAgIGJhY2t1cE1hc3RlcktleT86IHN0cmluZztcbiAgfSA9IHt9XG4pOiBRckRhdGFFbnRyeSB7XG4gIGNvbnN0IHRpdGxlID0gJ0I6IEJhY2t1cCBLZXknO1xuICBpZiAoYmFja3VwS2V5Y2hhaW4ucmVkdWNlZEVuY3J5cHRlZFBydikge1xuICAgIHJldHVybiB7XG4gICAgICB0aXRsZSxcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB5b3VyIGJhY2t1cCBwcml2YXRlIGtleSwgZW5jcnlwdGVkIHdpdGggeW91ciB3YWxsZXQgcGFzc3dvcmQuJyxcbiAgICAgIGRhdGE6IGJhY2t1cEtleWNoYWluLnJlZHVjZWRFbmNyeXB0ZWRQcnYsXG4gICAgfTtcbiAgfVxuICBpZiAoYmFja3VwS2V5Y2hhaW4uZW5jcnlwdGVkUHJ2KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHRpdGxlLFxuICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHlvdXIgYmFja3VwIHByaXZhdGUga2V5LCBlbmNyeXB0ZWQgd2l0aCB5b3VyIHdhbGxldCBwYXNzd29yZC4nLFxuICAgICAgZGF0YTogYmFja3VwS2V5Y2hhaW4uZW5jcnlwdGVkUHJ2LFxuICAgIH07XG4gIH1cblxuICBpZiAoYmFja3VwS2V5UHJvdmlkZXIgPT09ICdCaXRHbyBUcnVzdCcgJiYgYmFja3VwS2V5Y2hhaW4udHlwZSA9PT0gJ3RzcycpIHtcbiAgICBjb25zdCBrZXlTaGFyZXMgPSBiYWNrdXBLZXljaGFpbi5rZXlTaGFyZXM/LmZpbHRlcigoa2V5U2hhcmUpID0+IGtleVNoYXJlLnRvID09PSAnYmFja3VwJyk7XG4gICAgYXNzZXJ0Lm9rKGtleVNoYXJlcz8ubGVuZ3RoID09PSAyKTtcbiAgICByZXR1cm4ge1xuICAgICAgdGl0bGU6ICdCOiBCYWNrdXAgS2V5IFNoYXJlcycsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgYFRoZXNlIGFyZSB0aGUga2V5IHNoYXJlcyBmb3IgJHtiYWNrdXBLZXlQcm92aWRlcn0uIElmIEJpdEdvIEluYy4gZ29lcyBvdXQgb2YgYnVzaW5lc3MsXFxyXFxuYCArXG4gICAgICAgIGBjb250YWN0ICR7YmFja3VwS2V5UHJvdmlkZXJ9IGFuZCB0aGV5IHdpbGwgaGVscCB5b3UgcmVjb3ZlciB5b3VyIGZ1bmRzLmAsXG4gICAgICBkYXRhOiBKU09OLnN0cmluZ2lmeShrZXlTaGFyZXMpLFxuICAgIH07XG4gIH1cblxuICBjb25zdCBwdWIgPSBnZXRQdWJGcm9tS2V5KGJhY2t1cEtleWNoYWluKTtcbiAgYXNzZXJ0Lm9rKHB1Yik7XG5cbiAgaWYgKGJhY2t1cEtleVByb3ZpZGVyKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHRpdGxlOiAnQjogQmFja3VwIEtleScsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgYFRoaXMgaXMgdGhlIHB1YmxpYyBrZXkgaGVsZCBhdCAke2JhY2t1cEtleVByb3ZpZGVyfSwgYW4gJHtjb2luLm5hbWV9IHJlY292ZXJ5IHNlcnZpY2UuIGAgK1xuICAgICAgICBgSWYgeW91IGxvc2VcXHJcXG55b3VyIGtleSwgJHtiYWNrdXBLZXlQcm92aWRlcn0gd2lsbCBiZSBhYmxlIHRvIHNpZ24gdHJhbnNhY3Rpb25zIHRvIHJlY292ZXIgZnVuZHMuYCxcbiAgICAgIGRhdGE6IHB1YixcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB0aXRsZTogJ0I6IFByb3ZpZGVkIEJhY2t1cCBLZXknLFxuICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgcHVibGljIGtleSB5b3UgcHJvdmlkZWQgZm9yIHlvdXIgd2FsbGV0LicsXG4gICAgZGF0YTogcHViLFxuICAgIHB1YmxpY01hc3RlcktleTogYmFja3VwTWFzdGVyS2V5LFxuICB9O1xufVxuXG5mdW5jdGlvbiBnZW5lcmF0ZUJpdEdvUXJEYXRhKGJpdGdvS2V5Y2hhaW46IEtleWNoYWluKTogUXJEYXRhRW50cnkge1xuICBjb25zdCBiaXRnb0RhdGEgPSBnZXRQdWJGcm9tS2V5KGJpdGdvS2V5Y2hhaW4pO1xuICBhc3NlcnQub2soYml0Z29EYXRhKTtcblxuICByZXR1cm4ge1xuICAgIHRpdGxlOiAnQzogQml0R28gS2V5JyxcbiAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIHB1YmxpYyBwYXJ0IG9mIHRoZSBrZXkgaGVsZCBieSBCaXRHby4nLFxuICAgIGRhdGE6IGJpdGdvRGF0YSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gZ2VuZXJhdGVVc2VyTWFzdGVyUHVibGljS2V5UVJEYXRhKHB1YmxpY0tleTogc3RyaW5nKTogTWFzdGVyUHVibGljS2V5UXJEYXRhRW50cnkge1xuICByZXR1cm4ge1xuICAgIHRpdGxlOiAnRTogTWFzdGVyIFVzZXIgUHVibGljIEtleScsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICAnVGhpcyBpcyB0aGUgcHVibGljIGtleSB1c2VkIHRvIGRlcml2ZSB0aGUgdXNlciBrZXkgZm9yIHRoZSB3YWxsZXQuIFRoaXMgaXMgbm90IHN0b3JlZCBieSBCaXRHbywgYW5kIG1heSBiZSByZXF1aXJlZCBmb3IgdXNlIGluIHJlY292ZXJ5IHNjZW5hcmlvcy4nLFxuICAgIGRhdGE6IHB1YmxpY0tleSxcbiAgfTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZ2VuZXJhdGVQYXNzY29kZVFyRGF0YShcbiAgcGFzc3BocmFzZTogc3RyaW5nLFxuICBwYXNzY29kZUVuY3J5cHRpb25Db2RlOiBzdHJpbmcsXG4gIGVuY3J5cHRpb25WZXJzaW9uPzogMSB8IDJcbik6IFByb21pc2U8UXJEYXRhRW50cnk+IHtcbiAgY29uc3QgZW5jcnlwdGVkV2FsbGV0UGFzc2NvZGUgPSBhd2FpdCBlbmNyeXB0KHBhc3Njb2RlRW5jcnlwdGlvbkNvZGUsIHBhc3NwaHJhc2UsIHsgZW5jcnlwdGlvblZlcnNpb24gfSk7XG4gIHJldHVybiB7XG4gICAgdGl0bGU6ICdEOiBFbmNyeXB0ZWQgV2FsbGV0IFBhc3N3b3JkJyxcbiAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIHdhbGxldCBwYXNzd29yZCwgZW5jcnlwdGVkIGNsaWVudC1zaWRlIHdpdGggYSBrZXkgaGVsZCBieSBCaXRHby4nLFxuICAgIGRhdGE6IGVuY3J5cHRlZFdhbGxldFBhc3Njb2RlLFxuICB9O1xufVxuXG5mdW5jdGlvbiBnZW5lcmF0ZUJhY2t1cE1hc3RlclB1YmxpY0tleVFSRGF0YShwdWJsaWNLZXk6IHN0cmluZyk6IE1hc3RlclB1YmxpY0tleVFyRGF0YUVudHJ5IHtcbiAgcmV0dXJuIHtcbiAgICB0aXRsZTogJ0Y6IE1hc3RlciBCYWNrdXAgUHVibGljIEtleScsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICAnVGhpcyBpcyB0aGUgcHVibGljIGtleSB1c2VkIHRvIGRlcml2ZSB0aGUgYmFja3VwIGtleSBmb3IgdGhlIHdhbGxldC4gVGhpcyBpcyBub3Qgc3RvcmVkIGJ5IEJpdEdvLCBhbmQgbWF5IGJlIHJlcXVpcmVkIGZvciB1c2UgaW4gcmVjb3Zlcnkgc2NlbmFyaW9zLicsXG4gICAgZGF0YTogcHVibGljS2V5LFxuICB9O1xufVxuXG5mdW5jdGlvbiBidWlsZFdhbGxldFFyRGF0YSh7XG4gIGJhY2t1cEtleWNoYWluLFxuICBiYWNrdXBLZXlQcm92aWRlcixcbiAgYmFja3VwTWFzdGVyS2V5LFxuICBiaXRnb0tleWNoYWluLFxuICBjb2luLFxuICB1c2VyS2V5Y2hhaW4sXG4gIHVzZXJNYXN0ZXJLZXksXG4gIHVzZXJNYXN0ZXJQdWJsaWNLZXksXG4gIGJhY2t1cE1hc3RlclB1YmxpY0tleSxcbn06IEdlbmVyYXRlUXJEYXRhUGFyYW1zKTogUXJEYXRhIHtcbiAgcmV0dXJuIHtcbiAgICB1c2VyOiBnZW5lcmF0ZVVzZXJRckRhdGEodXNlcktleWNoYWluLCB1c2VyTWFzdGVyS2V5KSxcbiAgICB1c2VyTWFzdGVyUHVibGljS2V5OiB1c2VyTWFzdGVyUHVibGljS2V5ID8gZ2VuZXJhdGVVc2VyTWFzdGVyUHVibGljS2V5UVJEYXRhKHVzZXJNYXN0ZXJQdWJsaWNLZXkpIDogdW5kZWZpbmVkLFxuICAgIGJhY2t1cDogZ2VuZXJhdGVCYWNrdXBRckRhdGEoY29pbiwgYmFja3VwS2V5Y2hhaW4sIHtcbiAgICAgIGJhY2t1cEtleVByb3ZpZGVyLFxuICAgICAgYmFja3VwTWFzdGVyS2V5LFxuICAgIH0pLFxuICAgIGJhY2t1cE1hc3RlclB1YmxpY0tleTogYmFja3VwTWFzdGVyUHVibGljS2V5XG4gICAgICA/IGdlbmVyYXRlQmFja3VwTWFzdGVyUHVibGljS2V5UVJEYXRhKGJhY2t1cE1hc3RlclB1YmxpY0tleSlcbiAgICAgIDogdW5kZWZpbmVkLFxuICAgIGJpdGdvOiBnZW5lcmF0ZUJpdEdvUXJEYXRhKGJpdGdvS2V5Y2hhaW4pLFxuICB9O1xufVxuXG5mdW5jdGlvbiBidWlsZExpZ2h0bmluZ1FyRGF0YSh7IHVzZXJBdXRoS2V5Y2hhaW4gfTogR2VuZXJhdGVMaWdodG5pbmdRckRhdGFQYXJhbXMpOiBRckRhdGEge1xuICBhc3NlcnQub2sodXNlckF1dGhLZXljaGFpbi5lbmNyeXB0ZWRQcnYsICd1c2VyQXV0aEtleWNoYWluIG11c3QgaGF2ZSBhbiBlbmNyeXB0ZWRQcnYnKTtcblxuICByZXR1cm4ge1xuICAgIHVzZXI6IHtcbiAgICAgIHRpdGxlOiAnQTogVXNlciBBdXRoIEtleScsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoaXMgaXMgeW91ciB1c2VyIGF1dGhlbnRpY2F0aW9uIHByaXZhdGUga2V5LCBlbmNyeXB0ZWQgd2l0aCB5b3VyIHdhbGxldCBwYXNzd29yZC5cXHJcXG5JdCBpcyB1c2VkIHRvIGF1dGhlbnRpY2F0ZSBwYXltZW50IGFuZCB3YWxsZXQgb3BlcmF0aW9ucy4nLFxuICAgICAgZGF0YTogdXNlckF1dGhLZXljaGFpbi5lbmNyeXB0ZWRQcnYsXG4gICAgfSxcbiAgfTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdlbmVyYXRlUXJEYXRhKHBhcmFtczogR2VuZXJhdGVRckRhdGFQYXJhbXMpOiBQcm9taXNlPFFyRGF0YT4ge1xuICBjb25zdCBxckRhdGEgPSBidWlsZFdhbGxldFFyRGF0YShwYXJhbXMpO1xuXG4gIGlmIChwYXJhbXMucGFzc3BocmFzZSAmJiBwYXJhbXMucGFzc2NvZGVFbmNyeXB0aW9uQ29kZSkge1xuICAgIHFyRGF0YS5wYXNzY29kZSA9IGF3YWl0IGdlbmVyYXRlUGFzc2NvZGVRckRhdGEoXG4gICAgICBwYXJhbXMucGFzc3BocmFzZSxcbiAgICAgIHBhcmFtcy5wYXNzY29kZUVuY3J5cHRpb25Db2RlLFxuICAgICAgcGFyYW1zLmVuY3J5cHRpb25WZXJzaW9uXG4gICAgKTtcbiAgfVxuXG4gIHJldHVybiBxckRhdGE7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZW5lcmF0ZUxpZ2h0bmluZ1FyRGF0YShwYXJhbXM6IEdlbmVyYXRlTGlnaHRuaW5nUXJEYXRhUGFyYW1zKTogUHJvbWlzZTxRckRhdGE+IHtcbiAgY29uc3QgcXJEYXRhID0gYnVpbGRMaWdodG5pbmdRckRhdGEocGFyYW1zKTtcblxuICBpZiAocGFyYW1zLnBhc3NwaHJhc2UgJiYgcGFyYW1zLnBhc3Njb2RlRW5jcnlwdGlvbkNvZGUpIHtcbiAgICBxckRhdGEucGFzc2NvZGUgPSBhd2FpdCBnZW5lcmF0ZVBhc3Njb2RlUXJEYXRhKFxuICAgICAgcGFyYW1zLnBhc3NwaHJhc2UsXG4gICAgICBwYXJhbXMucGFzc2NvZGVFbmNyeXB0aW9uQ29kZSxcbiAgICAgIHBhcmFtcy5lbmNyeXB0aW9uVmVyc2lvblxuICAgICk7XG4gIH1cblxuICByZXR1cm4gcXJEYXRhO1xufVxuIl19
@@ -0,0 +1,11 @@
1
+ import { GenerateKeycardParams, GenerateLightningQrDataParams, GenerateQrDataBaseParams } from './types';
2
+ export * from './drawKeycard';
3
+ export * from './extractKeycardFromPDF';
4
+ export * from './faq';
5
+ export * from './generateQrData';
6
+ export * from './parseKeycard';
7
+ export * from './utils';
8
+ export * from './types';
9
+ export declare function generateKeycard(params: GenerateKeycardParams): Promise<void>;
10
+ export declare function generateLightningKeycard(params: GenerateQrDataBaseParams & GenerateLightningQrDataParams): Promise<void>;
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,qBAAqB,EAAE,6BAA6B,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;AAEzG,cAAc,eAAe,CAAC;AAC9B,cAAc,yBAAyB,CAAC;AACxC,cAAc,OAAO,CAAC;AACtB,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AAExB,wBAAsB,eAAe,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAqBlF;AAED,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,wBAAwB,GAAG,6BAA6B,GAC/D,OAAO,CAAC,IAAI,CAAC,CAMf"}
@@ -0,0 +1,62 @@
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.generateKeycard = generateKeycard;
18
+ exports.generateLightningKeycard = generateLightningKeycard;
19
+ const generateQrData_1 = require("./generateQrData");
20
+ const faq_1 = require("./faq");
21
+ const drawKeycard_1 = require("./drawKeycard");
22
+ const generateParamsForKeyCreation_1 = require("./generateParamsForKeyCreation");
23
+ __exportStar(require("./drawKeycard"), exports);
24
+ __exportStar(require("./extractKeycardFromPDF"), exports);
25
+ __exportStar(require("./faq"), exports);
26
+ __exportStar(require("./generateQrData"), exports);
27
+ __exportStar(require("./parseKeycard"), exports);
28
+ __exportStar(require("./utils"), exports);
29
+ __exportStar(require("./types"), exports);
30
+ async function generateKeycard(params) {
31
+ if ('userAuthKeychain' in params) {
32
+ const questions = (0, faq_1.generateLightningFaq)(params.coin.fullName);
33
+ const qrData = await (0, generateQrData_1.generateLightningQrData)(params);
34
+ const keycard = await (0, drawKeycard_1.drawKeycard)({ ...params, questions, qrData });
35
+ const label = params.walletLabel || params.coin.fullName;
36
+ keycard.save(`BitGo Keycard for ${label}.pdf`);
37
+ }
38
+ else if ('coin' in params) {
39
+ const questions = (0, faq_1.generateFaq)(params.coin.fullName);
40
+ const qrData = await (0, generateQrData_1.generateQrData)(params);
41
+ const keycard = await (0, drawKeycard_1.drawKeycard)({ ...params, questions, qrData });
42
+ const label = params.walletLabel || params.coin.fullName;
43
+ keycard.save(`BitGo Keycard for ${label}.pdf`);
44
+ }
45
+ else if ('curve' in params) {
46
+ const data = (0, generateParamsForKeyCreation_1.generateParamsForKeyCreation)(params);
47
+ const keycard = await (0, drawKeycard_1.drawKeycard)(data);
48
+ const label = params.walletLabel || params.curve;
49
+ keycard.save(`BitGo Keycard for ${label}.pdf`);
50
+ }
51
+ else {
52
+ throw new Error('Either curve or coin must be provided');
53
+ }
54
+ }
55
+ async function generateLightningKeycard(params) {
56
+ const questions = (0, faq_1.generateLightningFaq)(params.coin.fullName);
57
+ const qrData = await (0, generateQrData_1.generateLightningQrData)(params);
58
+ const keycard = await (0, drawKeycard_1.drawKeycard)({ ...params, questions, qrData });
59
+ const label = params.walletLabel || params.coin.fullName;
60
+ keycard.save(`BitGo Keycard for ${label}.pdf`);
61
+ }
62
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQWNBLDBDQXFCQztBQUVELDREQVFDO0FBN0NELHFEQUEyRTtBQUMzRSwrQkFBMEQ7QUFDMUQsK0NBQTRDO0FBQzVDLGlGQUE4RTtBQUc5RSxnREFBOEI7QUFDOUIsMERBQXdDO0FBQ3hDLHdDQUFzQjtBQUN0QixtREFBaUM7QUFDakMsaURBQStCO0FBQy9CLDBDQUF3QjtBQUN4QiwwQ0FBd0I7QUFFakIsS0FBSyxVQUFVLGVBQWUsQ0FBQyxNQUE2QjtJQUNqRSxJQUFJLGtCQUFrQixJQUFJLE1BQU0sRUFBRSxDQUFDO1FBQ2pDLE1BQU0sU0FBUyxHQUFHLElBQUEsMEJBQW9CLEVBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUM3RCxNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUEsd0NBQXVCLEVBQUMsTUFBTSxDQUFDLENBQUM7UUFDckQsTUFBTSxPQUFPLEdBQUcsTUFBTSxJQUFBLHlCQUFXLEVBQUMsRUFBRSxHQUFHLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUNwRSxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsV0FBVyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDO1FBQ3pELE9BQU8sQ0FBQyxJQUFJLENBQUMscUJBQXFCLEtBQUssTUFBTSxDQUFDLENBQUM7SUFDakQsQ0FBQztTQUFNLElBQUksTUFBTSxJQUFJLE1BQU0sRUFBRSxDQUFDO1FBQzVCLE1BQU0sU0FBUyxHQUFHLElBQUEsaUJBQVcsRUFBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3BELE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBQSwrQkFBYyxFQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzVDLE1BQU0sT0FBTyxHQUFHLE1BQU0sSUFBQSx5QkFBVyxFQUFDLEVBQUUsR0FBRyxNQUFNLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDcEUsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLFdBQVcsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQztRQUN6RCxPQUFPLENBQUMsSUFBSSxDQUFDLHFCQUFxQixLQUFLLE1BQU0sQ0FBQyxDQUFDO0lBQ2pELENBQUM7U0FBTSxJQUFJLE9BQU8sSUFBSSxNQUFNLEVBQUUsQ0FBQztRQUM3QixNQUFNLElBQUksR0FBRyxJQUFBLDJEQUE0QixFQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2xELE1BQU0sT0FBTyxHQUFHLE1BQU0sSUFBQSx5QkFBVyxFQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3hDLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxXQUFXLElBQUksTUFBTSxDQUFDLEtBQUssQ0FBQztRQUNqRCxPQUFPLENBQUMsSUFBSSxDQUFDLHFCQUFxQixLQUFLLE1BQU0sQ0FBQyxDQUFDO0lBQ2pELENBQUM7U0FBTSxDQUFDO1FBQ04sTUFBTSxJQUFJLEtBQUssQ0FBQyx1Q0FBdUMsQ0FBQyxDQUFDO0lBQzNELENBQUM7QUFDSCxDQUFDO0FBRU0sS0FBSyxVQUFVLHdCQUF3QixDQUM1QyxNQUFnRTtJQUVoRSxNQUFNLFNBQVMsR0FBRyxJQUFBLDBCQUFvQixFQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDN0QsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFBLHdDQUF1QixFQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3JELE1BQU0sT0FBTyxHQUFHLE1BQU0sSUFBQSx5QkFBVyxFQUFDLEVBQUUsR0FBRyxNQUFNLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7SUFDcEUsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLFdBQVcsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQztJQUN6RCxPQUFPLENBQUMsSUFBSSxDQUFDLHFCQUFxQixLQUFLLE1BQU0sQ0FBQyxDQUFDO0FBQ2pELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBnZW5lcmF0ZUxpZ2h0bmluZ1FyRGF0YSwgZ2VuZXJhdGVRckRhdGEgfSBmcm9tICcuL2dlbmVyYXRlUXJEYXRhJztcbmltcG9ydCB7IGdlbmVyYXRlRmFxLCBnZW5lcmF0ZUxpZ2h0bmluZ0ZhcSB9IGZyb20gJy4vZmFxJztcbmltcG9ydCB7IGRyYXdLZXljYXJkIH0gZnJvbSAnLi9kcmF3S2V5Y2FyZCc7XG5pbXBvcnQgeyBnZW5lcmF0ZVBhcmFtc0ZvcktleUNyZWF0aW9uIH0gZnJvbSAnLi9nZW5lcmF0ZVBhcmFtc0ZvcktleUNyZWF0aW9uJztcbmltcG9ydCB7IEdlbmVyYXRlS2V5Y2FyZFBhcmFtcywgR2VuZXJhdGVMaWdodG5pbmdRckRhdGFQYXJhbXMsIEdlbmVyYXRlUXJEYXRhQmFzZVBhcmFtcyB9IGZyb20gJy4vdHlwZXMnO1xuXG5leHBvcnQgKiBmcm9tICcuL2RyYXdLZXljYXJkJztcbmV4cG9ydCAqIGZyb20gJy4vZXh0cmFjdEtleWNhcmRGcm9tUERGJztcbmV4cG9ydCAqIGZyb20gJy4vZmFxJztcbmV4cG9ydCAqIGZyb20gJy4vZ2VuZXJhdGVRckRhdGEnO1xuZXhwb3J0ICogZnJvbSAnLi9wYXJzZUtleWNhcmQnO1xuZXhwb3J0ICogZnJvbSAnLi91dGlscyc7XG5leHBvcnQgKiBmcm9tICcuL3R5cGVzJztcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdlbmVyYXRlS2V5Y2FyZChwYXJhbXM6IEdlbmVyYXRlS2V5Y2FyZFBhcmFtcyk6IFByb21pc2U8dm9pZD4ge1xuICBpZiAoJ3VzZXJBdXRoS2V5Y2hhaW4nIGluIHBhcmFtcykge1xuICAgIGNvbnN0IHF1ZXN0aW9ucyA9IGdlbmVyYXRlTGlnaHRuaW5nRmFxKHBhcmFtcy5jb2luLmZ1bGxOYW1lKTtcbiAgICBjb25zdCBxckRhdGEgPSBhd2FpdCBnZW5lcmF0ZUxpZ2h0bmluZ1FyRGF0YShwYXJhbXMpO1xuICAgIGNvbnN0IGtleWNhcmQgPSBhd2FpdCBkcmF3S2V5Y2FyZCh7IC4uLnBhcmFtcywgcXVlc3Rpb25zLCBxckRhdGEgfSk7XG4gICAgY29uc3QgbGFiZWwgPSBwYXJhbXMud2FsbGV0TGFiZWwgfHwgcGFyYW1zLmNvaW4uZnVsbE5hbWU7XG4gICAga2V5Y2FyZC5zYXZlKGBCaXRHbyBLZXljYXJkIGZvciAke2xhYmVsfS5wZGZgKTtcbiAgfSBlbHNlIGlmICgnY29pbicgaW4gcGFyYW1zKSB7XG4gICAgY29uc3QgcXVlc3Rpb25zID0gZ2VuZXJhdGVGYXEocGFyYW1zLmNvaW4uZnVsbE5hbWUpO1xuICAgIGNvbnN0IHFyRGF0YSA9IGF3YWl0IGdlbmVyYXRlUXJEYXRhKHBhcmFtcyk7XG4gICAgY29uc3Qga2V5Y2FyZCA9IGF3YWl0IGRyYXdLZXljYXJkKHsgLi4ucGFyYW1zLCBxdWVzdGlvbnMsIHFyRGF0YSB9KTtcbiAgICBjb25zdCBsYWJlbCA9IHBhcmFtcy53YWxsZXRMYWJlbCB8fCBwYXJhbXMuY29pbi5mdWxsTmFtZTtcbiAgICBrZXljYXJkLnNhdmUoYEJpdEdvIEtleWNhcmQgZm9yICR7bGFiZWx9LnBkZmApO1xuICB9IGVsc2UgaWYgKCdjdXJ2ZScgaW4gcGFyYW1zKSB7XG4gICAgY29uc3QgZGF0YSA9IGdlbmVyYXRlUGFyYW1zRm9yS2V5Q3JlYXRpb24ocGFyYW1zKTtcbiAgICBjb25zdCBrZXljYXJkID0gYXdhaXQgZHJhd0tleWNhcmQoZGF0YSk7XG4gICAgY29uc3QgbGFiZWwgPSBwYXJhbXMud2FsbGV0TGFiZWwgfHwgcGFyYW1zLmN1cnZlO1xuICAgIGtleWNhcmQuc2F2ZShgQml0R28gS2V5Y2FyZCBmb3IgJHtsYWJlbH0ucGRmYCk7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdFaXRoZXIgY3VydmUgb3IgY29pbiBtdXN0IGJlIHByb3ZpZGVkJyk7XG4gIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdlbmVyYXRlTGlnaHRuaW5nS2V5Y2FyZChcbiAgcGFyYW1zOiBHZW5lcmF0ZVFyRGF0YUJhc2VQYXJhbXMgJiBHZW5lcmF0ZUxpZ2h0bmluZ1FyRGF0YVBhcmFtc1xuKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHF1ZXN0aW9ucyA9IGdlbmVyYXRlTGlnaHRuaW5nRmFxKHBhcmFtcy5jb2luLmZ1bGxOYW1lKTtcbiAgY29uc3QgcXJEYXRhID0gYXdhaXQgZ2VuZXJhdGVMaWdodG5pbmdRckRhdGEocGFyYW1zKTtcbiAgY29uc3Qga2V5Y2FyZCA9IGF3YWl0IGRyYXdLZXljYXJkKHsgLi4ucGFyYW1zLCBxdWVzdGlvbnMsIHFyRGF0YSB9KTtcbiAgY29uc3QgbGFiZWwgPSBwYXJhbXMud2FsbGV0TGFiZWwgfHwgcGFyYW1zLmNvaW4uZnVsbE5hbWU7XG4gIGtleWNhcmQuc2F2ZShgQml0R28gS2V5Y2FyZCBmb3IgJHtsYWJlbH0ucGRmYCk7XG59XG4iXX0=
@@ -0,0 +1,23 @@
1
+ export type PDFTextNode = {
2
+ text: string;
3
+ x: number;
4
+ y: number;
5
+ page: number;
6
+ width: number;
7
+ };
8
+ export type KeycardEntry = {
9
+ label: string;
10
+ value: string;
11
+ };
12
+ /**
13
+ * Reconstructs logical text lines from an unordered set of PDF text nodes.
14
+ *
15
+ * PDF text extraction returns individual positioned fragments. This function
16
+ * sorts them by page then Y-coordinate (top-to-bottom), groups fragments
17
+ * within PDF_LINE_Y_TOLERANCE points of each other onto the same line, and
18
+ * inserts a space between fragments that are separated by more than
19
+ * PDF_NODE_GAP_THRESHOLD points horizontally.
20
+ */
21
+ export declare function buildLinesFromPDFNodes(nodes: PDFTextNode[]): string[];
22
+ export declare function parseKeycardFromLines(lines: string[]): KeycardEntry[];
23
+ //# sourceMappingURL=parseKeycard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parseKeycard.d.ts","sourceRoot":"","sources":["../../src/parseKeycard.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAwCF;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,MAAM,EAAE,CA4DrE;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,YAAY,EAAE,CAyErE"}
@@ -0,0 +1,159 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildLinesFromPDFNodes = buildLinesFromPDFNodes;
4
+ exports.parseKeycardFromLines = parseKeycardFromLines;
5
+ const sectionHeaderRegex = /^([A-D])\s*[:.)-]\s*(.+?)\s*$/i;
6
+ const dataLineRegex = /^data\s*:\s*(.*)$/i;
7
+ const faqHeaderRegex = /^BitGo\s+KeyCard\s+FAQ$/i;
8
+ // PDF coordinate tolerance in points. Nodes within this distance on the Y-axis
9
+ // are treated as belonging to the same line; nodes further apart are separate lines.
10
+ const PDF_LINE_Y_TOLERANCE = 2;
11
+ // Horizontal gap in points above which a space is inserted between adjacent nodes.
12
+ const PDF_NODE_GAP_THRESHOLD = 2;
13
+ function sanitizeText(input) {
14
+ return input.replace(/\s+/g, ' ').trim();
15
+ }
16
+ function normalizeSectionValue(rawValue) {
17
+ // Two-pass removal of "Part N" page-continuation labels:
18
+ // 1. Line filter: removes labels that appear as standalone lines.
19
+ // 2. Regex replace: removes labels embedded mid-line when
20
+ // buildLinesFromPDFNodes merges them with adjacent content at the same
21
+ // y-coordinate (e.g. "...X88bPart 2 lFPMd...").
22
+ // join('') intentionally uses no separator — section values are continuous
23
+ // strings (base64 / xpub) that wrap across PDF lines without spaces.
24
+ return rawValue
25
+ .split('\n')
26
+ .filter((line) => !/^Part\s+\d+$/i.test(line.trim()))
27
+ .join('')
28
+ .replace(/\s*Part\s+\d+\s*/gi, '')
29
+ .trim();
30
+ }
31
+ function countChar(input, char) {
32
+ return input.split(char).length - 1;
33
+ }
34
+ function isEncryptedWalletPasswordSectionTitle(title) {
35
+ return title.toLowerCase().includes('encrypted wallet password');
36
+ }
37
+ /**
38
+ * Reconstructs logical text lines from an unordered set of PDF text nodes.
39
+ *
40
+ * PDF text extraction returns individual positioned fragments. This function
41
+ * sorts them by page then Y-coordinate (top-to-bottom), groups fragments
42
+ * within PDF_LINE_Y_TOLERANCE points of each other onto the same line, and
43
+ * inserts a space between fragments that are separated by more than
44
+ * PDF_NODE_GAP_THRESHOLD points horizontally.
45
+ */
46
+ function buildLinesFromPDFNodes(nodes) {
47
+ const sortedNodes = [...nodes].sort((a, b) => {
48
+ if (a.page !== b.page) {
49
+ return a.page - b.page;
50
+ }
51
+ const yDiff = Math.abs(a.y - b.y);
52
+ if (yDiff > PDF_LINE_Y_TOLERANCE) {
53
+ return b.y - a.y;
54
+ }
55
+ return a.x - b.x;
56
+ });
57
+ const lines = [];
58
+ let currentLineNodes = [];
59
+ let currentPage = -1;
60
+ let currentY = Number.NaN;
61
+ function flushLine() {
62
+ if (currentLineNodes.length === 0) {
63
+ return;
64
+ }
65
+ const sortedLineNodes = [...currentLineNodes].sort((a, b) => a.x - b.x);
66
+ let line = '';
67
+ let previousRightEdge = null;
68
+ for (const node of sortedLineNodes) {
69
+ const piece = sanitizeText(node.text);
70
+ if (!piece) {
71
+ continue;
72
+ }
73
+ if (previousRightEdge !== null && node.x - previousRightEdge > PDF_NODE_GAP_THRESHOLD) {
74
+ line += ' ';
75
+ }
76
+ line += piece;
77
+ previousRightEdge = node.x + node.width;
78
+ }
79
+ const normalizedLine = line.trim();
80
+ if (normalizedLine) {
81
+ lines.push(normalizedLine);
82
+ }
83
+ }
84
+ for (const node of sortedNodes) {
85
+ const pageChanged = node.page !== currentPage;
86
+ const lineChanged = Number.isNaN(currentY) || Math.abs(node.y - currentY) > PDF_LINE_Y_TOLERANCE;
87
+ if (pageChanged || lineChanged) {
88
+ flushLine();
89
+ currentLineNodes = [node];
90
+ currentPage = node.page;
91
+ currentY = node.y;
92
+ continue;
93
+ }
94
+ currentLineNodes.push(node);
95
+ }
96
+ flushLine();
97
+ return lines;
98
+ }
99
+ function parseKeycardFromLines(lines) {
100
+ const sections = [];
101
+ let currentSectionIndex = -1;
102
+ for (const line of lines) {
103
+ const labelMatch = line.match(sectionHeaderRegex);
104
+ if (labelMatch) {
105
+ const section = labelMatch[1]?.toUpperCase();
106
+ const title = sanitizeText(labelMatch[2] ?? '');
107
+ if (section && title) {
108
+ sections.push({
109
+ section,
110
+ title,
111
+ values: [],
112
+ isCapturingData: false,
113
+ openCurlyCount: 0,
114
+ });
115
+ currentSectionIndex = sections.length - 1;
116
+ continue;
117
+ }
118
+ }
119
+ if (currentSectionIndex < 0) {
120
+ continue;
121
+ }
122
+ const currentSection = sections[currentSectionIndex];
123
+ if (!currentSection) {
124
+ continue;
125
+ }
126
+ const dataLineMatch = line.match(dataLineRegex);
127
+ if (dataLineMatch) {
128
+ currentSection.isCapturingData = true;
129
+ const inlineValue = sanitizeText(dataLineMatch[1] ?? '');
130
+ if (inlineValue) {
131
+ currentSection.values.push(inlineValue);
132
+ currentSection.openCurlyCount += countChar(inlineValue, '{') - countChar(inlineValue, '}');
133
+ }
134
+ continue;
135
+ }
136
+ if (currentSection.isCapturingData) {
137
+ if (faqHeaderRegex.test(line)) {
138
+ currentSection.isCapturingData = false;
139
+ continue;
140
+ }
141
+ currentSection.values.push(line);
142
+ // For encrypted wallet password, data is a single JSON object. Stop as
143
+ // soon as the object closes so footer/FAQ content is not appended.
144
+ if (isEncryptedWalletPasswordSectionTitle(currentSection.title)) {
145
+ currentSection.openCurlyCount += countChar(line, '{') - countChar(line, '}');
146
+ if (currentSection.values.length > 0 && currentSection.openCurlyCount <= 0) {
147
+ currentSection.isCapturingData = false;
148
+ }
149
+ }
150
+ }
151
+ }
152
+ return sections
153
+ .filter(({ section, values }) => ['A', 'B', 'C', 'D'].includes(section) && values.length > 0)
154
+ .map(({ section, title, values }) => ({
155
+ label: `${section}: ${title}`,
156
+ value: normalizeSectionValue(values.join('\n')),
157
+ }));
158
+ }
159
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2VLZXljYXJkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3BhcnNlS2V5Y2FyZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQTREQSx3REE0REM7QUFFRCxzREF5RUM7QUF0TEQsTUFBTSxrQkFBa0IsR0FBRyxnQ0FBZ0MsQ0FBQztBQUM1RCxNQUFNLGFBQWEsR0FBRyxvQkFBb0IsQ0FBQztBQUMzQyxNQUFNLGNBQWMsR0FBRywwQkFBMEIsQ0FBQztBQUVsRCwrRUFBK0U7QUFDL0UscUZBQXFGO0FBQ3JGLE1BQU0sb0JBQW9CLEdBQUcsQ0FBQyxDQUFDO0FBQy9CLG1GQUFtRjtBQUNuRixNQUFNLHNCQUFzQixHQUFHLENBQUMsQ0FBQztBQUVqQyxTQUFTLFlBQVksQ0FBQyxLQUFhO0lBQ2pDLE9BQU8sS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7QUFDM0MsQ0FBQztBQUVELFNBQVMscUJBQXFCLENBQUMsUUFBZ0I7SUFDN0MseURBQXlEO0lBQ3pELGtFQUFrRTtJQUNsRSwwREFBMEQ7SUFDMUQsMEVBQTBFO0lBQzFFLG1EQUFtRDtJQUNuRCwyRUFBMkU7SUFDM0UscUVBQXFFO0lBQ3JFLE9BQU8sUUFBUTtTQUNaLEtBQUssQ0FBQyxJQUFJLENBQUM7U0FDWCxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztTQUNwRCxJQUFJLENBQUMsRUFBRSxDQUFDO1NBQ1IsT0FBTyxDQUFDLG9CQUFvQixFQUFFLEVBQUUsQ0FBQztTQUNqQyxJQUFJLEVBQUUsQ0FBQztBQUNaLENBQUM7QUFFRCxTQUFTLFNBQVMsQ0FBQyxLQUFhLEVBQUUsSUFBWTtJQUM1QyxPQUFPLEtBQUssQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxHQUFHLENB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QyxNQUFNLEdBQUcsQ0FBQyxJQUFJLGNBQWMsQ0FBQyxjQUFjLElBQUksQ0FBQyxFQUFFLENBQUM7b0JBQzNFLGNBQWMsQ0FBQyxlQUFlLEdBQUcsS0FBSyxDQUFDO2dCQUN6QyxDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQsT0FBTyxRQUFRO1NBQ1osTUFBTSxDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxJQUFJLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1NBQzVGLEdBQUcsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNwQyxLQUFLLEVBQUUsR0FBRyxPQUFPLEtBQUssS0FBSyxFQUFFO1FBQzdCLEtBQUssRUFBRSxxQkFBcUIsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0tBQ2hELENBQUMsQ0FBQyxDQUFDO0FBQ1IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCB0eXBlIFBERlRleHROb2RlID0ge1xuICB0ZXh0OiBzdHJpbmc7XG4gIHg6IG51bWJlcjtcbiAgeTogbnVtYmVyO1xuICBwYWdlOiBudW1iZXI7XG4gIHdpZHRoOiBudW1iZXI7XG59O1xuXG5leHBvcnQgdHlwZSBLZXljYXJkRW50cnkgPSB7XG4gIGxhYmVsOiBzdHJpbmc7XG4gIHZhbHVlOiBzdHJpbmc7XG59O1xuXG5jb25zdCBzZWN0aW9uSGVhZGVyUmVnZXggPSAvXihbQS1EXSlcXHMqWzouKS1dXFxzKiguKz8pXFxzKiQvaTtcbmNvbnN0IGRhdGFMaW5lUmVnZXggPSAvXmRhdGFcXHMqOlxccyooLiopJC9pO1xuY29uc3QgZmFxSGVhZGVyUmVnZXggPSAvXkJpdEdvXFxzK0tleUNhcmRcXHMrRkFRJC9pO1xuXG4vLyBQREYgY29vcmRpbmF0ZSB0b2xlcmFuY2UgaW4gcG9pbnRzLiBOb2RlcyB3aXRoaW4gdGhpcyBkaXN0YW5jZSBvbiB0aGUgWS1heGlzXG4vLyBhcmUgdHJlYXRlZCBhcyBiZWxvbmdpbmcgdG8gdGhlIHNhbWUgbGluZTsgbm9kZXMgZnVydGhlciBhcGFydCBhcmUgc2VwYXJhdGUgbGluZXMuXG5jb25zdCBQREZfTElORV9ZX1RPTEVSQU5DRSA9IDI7XG4vLyBIb3Jpem9udGFsIGdhcCBpbiBwb2ludHMgYWJvdmUgd2hpY2ggYSBzcGFjZSBpcyBpbnNlcnRlZCBiZXR3ZWVuIGFkamFjZW50IG5vZGVzLlxuY29uc3QgUERGX05PREVfR0FQX1RIUkVTSE9MRCA9IDI7XG5cbmZ1bmN0aW9uIHNhbml0aXplVGV4dChpbnB1dDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGlucHV0LnJlcGxhY2UoL1xccysvZywgJyAnKS50cmltKCk7XG59XG5cbmZ1bmN0aW9uIG5vcm1hbGl6ZVNlY3Rpb25WYWx1ZShyYXdWYWx1ZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgLy8gVHdvLXBhc3MgcmVtb3ZhbCBvZiBcIlBhcnQgTlwiIHBhZ2UtY29udGludWF0aW9uIGxhYmVsczpcbiAgLy8gMS4gTGluZSBmaWx0ZXI6IHJlbW92ZXMgbGFiZWxzIHRoYXQgYXBwZWFyIGFzIHN0YW5kYWxvbmUgbGluZXMuXG4gIC8vIDIuIFJlZ2V4IHJlcGxhY2U6IHJlbW92ZXMgbGFiZWxzIGVtYmVkZGVkIG1pZC1saW5lIHdoZW5cbiAgLy8gICAgYnVpbGRMaW5lc0Zyb21QREZOb2RlcyBtZXJnZXMgdGhlbSB3aXRoIGFkamFjZW50IGNvbnRlbnQgYXQgdGhlIHNhbWVcbiAgLy8gICAgeS1jb29yZGluYXRlIChlLmcuIFwiLi4uWDg4YlBhcnQgMiBsRlBNZC4uLlwiKS5cbiAgLy8gam9pbignJykgaW50ZW50aW9uYWxseSB1c2VzIG5vIHNlcGFyYXRvciDigJQgc2VjdGlvbiB2YWx1ZXMgYXJlIGNvbnRpbnVvdXNcbiAgLy8gc3RyaW5ncyAoYmFzZTY0IC8geHB1YikgdGhhdCB3cmFwIGFjcm9zcyBQREYgbGluZXMgd2l0aG91dCBzcGFjZXMuXG4gIHJldHVybiByYXdWYWx1ZVxuICAgIC5zcGxpdCgnXFxuJylcbiAgICAuZmlsdGVyKChsaW5lKSA9PiAhL15QYXJ0XFxzK1xcZCskL2kudGVzdChsaW5lLnRyaW0oKSkpXG4gICAgLmpvaW4oJycpXG4gICAgLnJlcGxhY2UoL1xccypQYXJ0XFxzK1xcZCtcXHMqL2dpLCAnJylcbiAgICAudHJpbSgpO1xufVxuXG5mdW5jdGlvbiBjb3VudENoYXIoaW5wdXQ6IHN0cmluZywgY2hhcjogc3RyaW5nKTogbnVtYmVyIHtcbiAgcmV0dXJuIGlucHV0LnNwbGl0KGNoYXIpLmxlbmd0aCAtIDE7XG59XG5cbmZ1bmN0aW9uIGlzRW5jcnlwdGVkV2FsbGV0UGFzc3dvcmRTZWN0aW9uVGl0bGUodGl0bGU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gdGl0bGUudG9Mb3dlckNhc2UoKS5pbmNsdWRlcygnZW5jcnlwdGVkIHdhbGxldCBwYXNzd29yZCcpO1xufVxuXG4vKipcbiAqIFJlY29uc3RydWN0cyBsb2dpY2FsIHRleHQgbGluZXMgZnJvbSBhbiB1bm9yZGVyZWQgc2V0IG9mIFBERiB0ZXh0IG5vZGVzLlxuICpcbiAqIFBERiB0ZXh0IGV4dHJhY3Rpb24gcmV0dXJucyBpbmRpdmlkdWFsIHBvc2l0aW9uZWQgZnJhZ21lbnRzLiBUaGlzIGZ1bmN0aW9uXG4gKiBzb3J0cyB0aGVtIGJ5IHBhZ2UgdGhlbiBZLWNvb3JkaW5hdGUgKHRvcC10by1ib3R0b20pLCBncm91cHMgZnJhZ21lbnRzXG4gKiB3aXRoaW4gUERGX0xJTkVfWV9UT0xFUkFOQ0UgcG9pbnRzIG9mIGVhY2ggb3RoZXIgb250byB0aGUgc2FtZSBsaW5lLCBhbmRcbiAqIGluc2VydHMgYSBzcGFjZSBiZXR3ZWVuIGZyYWdtZW50cyB0aGF0IGFyZSBzZXBhcmF0ZWQgYnkgbW9yZSB0aGFuXG4gKiBQREZfTk9ERV9HQVBfVEhSRVNIT0xEIHBvaW50cyBob3Jpem9udGFsbHkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZExpbmVzRnJvbVBERk5vZGVzKG5vZGVzOiBQREZUZXh0Tm9kZVtdKTogc3RyaW5nW10ge1xuICBjb25zdCBzb3J0ZWROb2RlcyA9IFsuLi5ub2Rlc10uc29ydCgoYSwgYikgPT4ge1xuICAgIGlmIChhLnBhZ2UgIT09IGIucGFnZSkge1xuICAgICAgcmV0dXJuIGEucGFnZSAtIGIucGFnZTtcbiAgICB9XG4gICAgY29uc3QgeURpZmYgPSBNYXRoLmFicyhhLnkgLSBiLnkpO1xuICAgIGlmICh5RGlmZiA+IFBERl9MSU5FX1lfVE9MRVJBTkNFKSB7XG4gICAgICByZXR1cm4gYi55IC0gYS55O1xuICAgIH1cbiAgICByZXR1cm4gYS54IC0gYi54O1xuICB9KTtcblxuICBjb25zdCBsaW5lczogc3RyaW5nW10gPSBbXTtcbiAgbGV0IGN1cnJlbnRMaW5lTm9kZXM6IFBERlRleHROb2RlW10gPSBbXTtcbiAgbGV0IGN1cnJlbnRQYWdlID0gLTE7XG4gIGxldCBjdXJyZW50WSA9IE51bWJlci5OYU47XG5cbiAgZnVuY3Rpb24gZmx1c2hMaW5lKCkge1xuICAgIGlmIChjdXJyZW50TGluZU5vZGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHNvcnRlZExpbmVOb2RlcyA9IFsuLi5jdXJyZW50TGluZU5vZGVzXS5zb3J0KChhLCBiKSA9PiBhLnggLSBiLngpO1xuICAgIGxldCBsaW5lID0gJyc7XG4gICAgbGV0IHByZXZpb3VzUmlnaHRFZGdlOiBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgICBmb3IgKGNvbnN0IG5vZGUgb2Ygc29ydGVkTGluZU5vZGVzKSB7XG4gICAgICBjb25zdCBwaWVjZSA9IHNhbml0aXplVGV4dChub2RlLnRleHQpO1xuICAgICAgaWYgKCFwaWVjZSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKHByZXZpb3VzUmlnaHRFZGdlICE9PSBudWxsICYmIG5vZGUueCAtIHByZXZpb3VzUmlnaHRFZGdlID4gUERGX05PREVfR0FQX1RIUkVTSE9MRCkge1xuICAgICAgICBsaW5lICs9ICcgJztcbiAgICAgIH1cbiAgICAgIGxpbmUgKz0gcGllY2U7XG4gICAgICBwcmV2aW91c1JpZ2h0RWRnZSA9IG5vZGUueCArIG5vZGUud2lkdGg7XG4gICAgfVxuXG4gICAgY29uc3Qgbm9ybWFsaXplZExpbmUgPSBsaW5lLnRyaW0oKTtcbiAgICBpZiAobm9ybWFsaXplZExpbmUpIHtcbiAgICAgIGxpbmVzLnB1c2gobm9ybWFsaXplZExpbmUpO1xuICAgIH1cbiAgfVxuXG4gIGZvciAoY29uc3Qgbm9kZSBvZiBzb3J0ZWROb2Rlcykge1xuICAgIGNvbnN0IHBhZ2VDaGFuZ2VkID0gbm9kZS5wYWdlICE9PSBjdXJyZW50UGFnZTtcbiAgICBjb25zdCBsaW5lQ2hhbmdlZCA9IE51bWJlci5pc05hTihjdXJyZW50WSkgfHwgTWF0aC5hYnMobm9kZS55IC0gY3VycmVudFkpID4gUERGX0xJTkVfWV9UT0xFUkFOQ0U7XG4gICAgaWYgKHBhZ2VDaGFuZ2VkIHx8IGxpbmVDaGFuZ2VkKSB7XG4gICAgICBmbHVzaExpbmUoKTtcbiAgICAgIGN1cnJlbnRMaW5lTm9kZXMgPSBbbm9kZV07XG4gICAgICBjdXJyZW50UGFnZSA9IG5vZGUucGFnZTtcbiAgICAgIGN1cnJlbnRZID0gbm9kZS55O1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgY3VycmVudExpbmVOb2Rlcy5wdXNoKG5vZGUpO1xuICB9XG5cbiAgZmx1c2hMaW5lKCk7XG4gIHJldHVybiBsaW5lcztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlS2V5Y2FyZEZyb21MaW5lcyhsaW5lczogc3RyaW5nW10pOiBLZXljYXJkRW50cnlbXSB7XG4gIGNvbnN0IHNlY3Rpb25zOiBBcnJheTx7XG4gICAgc2VjdGlvbjogc3RyaW5nO1xuICAgIHRpdGxlOiBzdHJpbmc7XG4gICAgdmFsdWVzOiBzdHJpbmdbXTtcbiAgICBpc0NhcHR1cmluZ0RhdGE6IGJvb2xlYW47XG4gICAgb3BlbkN1cmx5Q291bnQ6IG51bWJlcjtcbiAgfT4gPSBbXTtcbiAgbGV0IGN1cnJlbnRTZWN0aW9uSW5kZXggPSAtMTtcblxuICBmb3IgKGNvbnN0IGxpbmUgb2YgbGluZXMpIHtcbiAgICBjb25zdCBsYWJlbE1hdGNoID0gbGluZS5tYXRjaChzZWN0aW9uSGVhZGVyUmVnZXgpO1xuICAgIGlmIChsYWJlbE1hdGNoKSB7XG4gICAgICBjb25zdCBzZWN0aW9uID0gbGFiZWxNYXRjaFsxXT8udG9VcHBlckNhc2UoKTtcbiAgICAgIGNvbnN0IHRpdGxlID0gc2FuaXRpemVUZXh0KGxhYmVsTWF0Y2hbMl0gPz8gJycpO1xuICAgICAgaWYgKHNlY3Rpb24gJiYgdGl0bGUpIHtcbiAgICAgICAgc2VjdGlvbnMucHVzaCh7XG4gICAgICAgICAgc2VjdGlvbixcbiAgICAgICAgICB0aXRsZSxcbiAgICAgICAgICB2YWx1ZXM6IFtdLFxuICAgICAgICAgIGlzQ2FwdHVyaW5nRGF0YTogZmFsc2UsXG4gICAgICAgICAgb3BlbkN1cmx5Q291bnQ6IDAsXG4gICAgICAgIH0pO1xuICAgICAgICBjdXJyZW50U2VjdGlvbkluZGV4ID0gc2VjdGlvbnMubGVuZ3RoIC0gMTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGN1cnJlbnRTZWN0aW9uSW5kZXggPCAwKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBjb25zdCBjdXJyZW50U2VjdGlvbiA9IHNlY3Rpb25zW2N1cnJlbnRTZWN0aW9uSW5kZXhdO1xuICAgIGlmICghY3VycmVudFNlY3Rpb24pIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGNvbnN0IGRhdGFMaW5lTWF0Y2ggPSBsaW5lLm1hdGNoKGRhdGFMaW5lUmVnZXgpO1xuICAgIGlmIChkYXRhTGluZU1hdGNoKSB7XG4gICAgICBjdXJyZW50U2VjdGlvbi5pc0NhcHR1cmluZ0RhdGEgPSB0cnVlO1xuICAgICAgY29uc3QgaW5saW5lVmFsdWUgPSBzYW5pdGl6ZVRleHQoZGF0YUxpbmVNYXRjaFsxXSA/PyAnJyk7XG4gICAgICBpZiAoaW5saW5lVmFsdWUpIHtcbiAgICAgICAgY3VycmVudFNlY3Rpb24udmFsdWVzLnB1c2goaW5saW5lVmFsdWUpO1xuICAgICAgICBjdXJyZW50U2VjdGlvbi5vcGVuQ3VybHlDb3VudCArPSBjb3VudENoYXIoaW5saW5lVmFsdWUsICd7JykgLSBjb3VudENoYXIoaW5saW5lVmFsdWUsICd9Jyk7XG4gICAgICB9XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAoY3VycmVudFNlY3Rpb24uaXNDYXB0dXJpbmdEYXRhKSB7XG4gICAgICBpZiAoZmFxSGVhZGVyUmVnZXgudGVzdChsaW5lKSkge1xuICAgICAgICBjdXJyZW50U2VjdGlvbi5pc0NhcHR1cmluZ0RhdGEgPSBmYWxzZTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGN1cnJlbnRTZWN0aW9uLnZhbHVlcy5wdXNoKGxpbmUpO1xuXG4gICAgICAvLyBGb3IgZW5jcnlwdGVkIHdhbGxldCBwYXNzd29yZCwgZGF0YSBpcyBhIHNpbmdsZSBKU09OIG9iamVjdC4gU3RvcCBhc1xuICAgICAgLy8gc29vbiBhcyB0aGUgb2JqZWN0IGNsb3NlcyBzbyBmb290ZXIvRkFRIGNvbnRlbnQgaXMgbm90IGFwcGVuZGVkLlxuICAgICAgaWYgKGlzRW5jcnlwdGVkV2FsbGV0UGFzc3dvcmRTZWN0aW9uVGl0bGUoY3VycmVudFNlY3Rpb24udGl0bGUpKSB7XG4gICAgICAgIGN1cnJlbnRTZWN0aW9uLm9wZW5DdXJseUNvdW50ICs9IGNvdW50Q2hhcihsaW5lLCAneycpIC0gY291bnRDaGFyKGxpbmUsICd9Jyk7XG4gICAgICAgIGlmIChjdXJyZW50U2VjdGlvbi52YWx1ZXMubGVuZ3RoID4gMCAmJiBjdXJyZW50U2VjdGlvbi5vcGVuQ3VybHlDb3VudCA8PSAwKSB7XG4gICAgICAgICAgY3VycmVudFNlY3Rpb24uaXNDYXB0dXJpbmdEYXRhID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gc2VjdGlvbnNcbiAgICAuZmlsdGVyKCh7IHNlY3Rpb24sIHZhbHVlcyB9KSA9PiBbJ0EnLCAnQicsICdDJywgJ0QnXS5pbmNsdWRlcyhzZWN0aW9uKSAmJiB2YWx1ZXMubGVuZ3RoID4gMClcbiAgICAubWFwKCh7IHNlY3Rpb24sIHRpdGxlLCB2YWx1ZXMgfSkgPT4gKHtcbiAgICAgIGxhYmVsOiBgJHtzZWN0aW9ufTogJHt0aXRsZX1gLFxuICAgICAgdmFsdWU6IG5vcm1hbGl6ZVNlY3Rpb25WYWx1ZSh2YWx1ZXMuam9pbignXFxuJykpLFxuICAgIH0pKTtcbn1cbiJdfQ==