@bitgo-beta/key-card 0.0.1-beta.8 → 0.1.1

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.
package/CHANGELOG.md ADDED
@@ -0,0 +1,32 @@
1
+ # Change Log
2
+
3
+ All notable changes to this project will be documented in this file.
4
+ See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
+
6
+ ## [0.1.1](https://github.com/BitGo/BitGoJS/compare/@bitgo/key-card@0.1.0...@bitgo/key-card@0.1.1) (2023-02-17)
7
+
8
+ **Note:** Version bump only for package @bitgo/key-card
9
+
10
+
11
+
12
+
13
+
14
+ # 0.1.0 (2023-02-16)
15
+
16
+
17
+ ### Bug Fixes
18
+
19
+ * **key-card:** fix errors in key-card drawing code ([092bc0a](https://github.com/BitGo/BitGoJS/commit/092bc0a4b851d6cf9d396e8eb5af476b4c52954d))
20
+ * **key-card:** reduce size of QR codes ([c8e08b8](https://github.com/BitGo/BitGoJS/commit/c8e08b8ca007bd45cb0628c5a06a80b81f5a308e))
21
+ * **root:** manually fix up incorrect versions ([3b1d28a](https://github.com/BitGo/BitGoJS/commit/3b1d28a8a4925e6dc1d89bb7482ea3b2f52b7b95))
22
+
23
+
24
+ ### Features
25
+
26
+ * **key-card:** add basic code to generate key cards ([83b01fc](https://github.com/BitGo/BitGoJS/commit/83b01fc5c31801e4f8db1166b06f2b8e7de3183f))
27
+ * **key-card:** add code to select qrData ([8b0e814](https://github.com/BitGo/BitGoJS/commit/8b0e814e54d9e33c41e5459d4fc69dac7b7d7737))
28
+ * **key-card:** add function to generate key card faqs ([749798d](https://github.com/BitGo/BitGoJS/commit/749798d184153e8257a7926f62e6c72420c31bc8))
29
+ * **key-card:** add support for qrcodes ([d79b9f7](https://github.com/BitGo/BitGoJS/commit/d79b9f7192dcabe9a7a1d5c261b799b5cbedb6f7))
30
+ * **key-card:** add utils function to split keys ([3547b19](https://github.com/BitGo/BitGoJS/commit/3547b194b49a50da8901b8d76c5f9a96c2f9c994))
31
+ * **key-card:** change contents of Boxes B & C for SMHA wallets ([2c27cd0](https://github.com/BitGo/BitGoJS/commit/2c27cd055bcdeb1a1a444d204298a8adb1d7a1c8))
32
+ * **key-card:** support BitGo Trust holding TSS backup key ([6cb8f94](https://github.com/BitGo/BitGoJS/commit/6cb8f94a4916a211f73c774ee9d94f6fdf6e6650))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bitgo-beta/key-card",
3
- "version": "0.0.1-beta.8",
3
+ "version": "0.1.1",
4
4
  "description": "key card generator for BitGo wallets",
5
5
  "main": "./dist/src/index.js",
6
6
  "types": "./dist/src/index.d.ts",
@@ -33,9 +33,14 @@
33
33
  ]
34
34
  },
35
35
  "dependencies": {
36
- "@bitgo-beta/sdk-api": "1.1.1-beta.133",
37
- "@bitgo-beta/sdk-core": "1.1.1-beta.133",
38
- "@bitgo-beta/statics": "7.0.1-beta.133"
36
+ "@bitgo-beta/sdk-api": "1.6.1-alpha.20",
37
+ "@bitgo-beta/sdk-core": "2.4.1-alpha.20",
38
+ "@bitgo-beta/statics": "10.0.1-alpha.20",
39
+ "jspdf": "^2.5.1",
40
+ "qrcode": "^1.5.1"
39
41
  },
40
- "gitHead": "6bef6baebbe61a28b8bd67a626e00f22efc7bfda"
42
+ "devDependencies": {
43
+ "@types/qrcode": "1.5.0"
44
+ },
45
+ "gitHead": "d8649762f34588bb46b97089be3365e3a3e77650"
41
46
  }
@@ -0,0 +1,240 @@
1
+ import { jsPDF } from 'jspdf';
2
+ import * as QRCode from 'qrcode';
3
+ import { FAQ } from './faq';
4
+ import { QrData } from './generateQrData';
5
+ import { splitKeys } from './utils';
6
+
7
+ // Max for Binary/Byte Data https://github.com/soldair/node-qrcode#qr-code-capacity
8
+ // the largest theoretically possible value is actually 2953 but the QR codes get so dense that scanning them with a
9
+ // phone (off of a printed page) doesn't work anymore
10
+ // this limitation was chosen by trial and error
11
+ export const QRBinaryMaxLength = 1500;
12
+
13
+ const font = {
14
+ header: 24,
15
+ subheader: 15,
16
+ body: 12,
17
+ };
18
+
19
+ const color = {
20
+ black: '#000000',
21
+ darkgray: '#4c4c4c',
22
+ gray: '#9b9b9b',
23
+ red: '#e21e1e',
24
+ };
25
+
26
+ const margin = 30;
27
+
28
+ // Helpers for data formatting / positioning on the paper
29
+ function left(x: number): number {
30
+ return margin + x;
31
+ }
32
+ function moveDown(y: number, ydelta: number): number {
33
+ return y + ydelta;
34
+ }
35
+
36
+ function drawOnePageOfQrCodes(qrImages: HTMLCanvasElement[], doc: jsPDF, y: number, qrSize: number, startIndex): number {
37
+ doc.setFont('helvetica');
38
+ let qrIndex: number = startIndex;
39
+ for (; qrIndex < qrImages.length; qrIndex++) {
40
+ const image = qrImages[qrIndex];
41
+ const textBuffer = 15;
42
+ if (y + qrSize + textBuffer >= doc.internal.pageSize.getHeight()) {
43
+ return qrIndex;
44
+ }
45
+
46
+ doc.addImage(image, left(0), y, qrSize, qrSize);
47
+
48
+ if (qrImages.length === 1) {
49
+ return qrIndex + 1;
50
+ }
51
+
52
+ y = moveDown(y, qrSize + textBuffer);
53
+ doc.setFontSize(font.body).setTextColor(color.black);
54
+ doc.text('Part ' + (qrIndex + 1).toString(), left(0), y);
55
+ y = moveDown(y, 20);
56
+ }
57
+ return qrIndex + 1;
58
+ }
59
+
60
+ export async function drawKeycard({ activationCode, questions, keyCardImage, qrData, walletLabel }: {
61
+ activationCode?: string;
62
+ keyCardImage?: HTMLImageElement;
63
+ qrData: QrData;
64
+ questions: FAQ[];
65
+ walletLabel: string;
66
+ }): Promise<jsPDF> {
67
+ // document details
68
+ const width = 8.5 * 72;
69
+ let y = 0;
70
+
71
+ // Create the PDF instance
72
+ const doc = new jsPDF('portrait', 'pt', 'letter'); // jshint ignore:line
73
+ doc.setFont('helvetica');
74
+
75
+ // PDF Header Area - includes the logo and company name
76
+ // This is data for the BitGo logo in the top left of the PDF
77
+ y = moveDown(y, 30);
78
+
79
+ if (keyCardImage) {
80
+ doc.addImage(keyCardImage, left(0), y, 303, 40);
81
+ }
82
+
83
+ // Activation Code
84
+ if (activationCode) {
85
+ y = moveDown(y, 8);
86
+ doc.setFontSize(font.body).setTextColor(color.gray);
87
+ doc.text('Activation Code', left(460), y);
88
+ }
89
+ doc.setFontSize(font.header).setTextColor(color.black);
90
+ y = moveDown(y, 25);
91
+ doc.text('KeyCard', left(325), y - 1);
92
+ if (activationCode) {
93
+ doc.setFontSize(font.header).setTextColor(color.gray);
94
+ doc.text(activationCode, left(460), y);
95
+ }
96
+
97
+ // Subheader
98
+ // titles
99
+ const date = new Date().toDateString();
100
+ y = moveDown(y, margin);
101
+ doc.setFontSize(font.body).setTextColor(color.gray);
102
+ doc.text('Created on ' + date + ' for wallet named:', left(0), y);
103
+ // copy
104
+ y = moveDown(y, 25);
105
+ doc.setFontSize(font.subheader).setTextColor(color.black);
106
+ doc.text(walletLabel, left(0), y);
107
+ // Red Bar
108
+ y = moveDown(y, 20);
109
+ doc.setFillColor(255, 230, 230);
110
+ doc.rect(left(0), y, width - 2 * margin, 32, 'F');
111
+
112
+ // warning message
113
+ y = moveDown(y, 20);
114
+ doc.setFontSize(font.body).setTextColor(color.red);
115
+ doc.text('Print this document, or keep it securely offline. See below for FAQ.', left(75), y);
116
+
117
+ // Generate the first page's data for the backup PDF
118
+ y = moveDown(y, 35);
119
+ const qrSize = 130;
120
+
121
+ const qrKeys = ['user', 'passcode', 'backup', 'bitgo'];
122
+ for (let index = 0; index < qrKeys.length; index++) {
123
+ const name = qrKeys[index];
124
+ if (index === 2) {
125
+ // Add 2nd Page
126
+ doc.addPage();
127
+
128
+ // 2nd page title
129
+ y = 30;
130
+ }
131
+
132
+ const qr = qrData[name];
133
+ let topY = y;
134
+ const textLeft = left(qrSize + 15);
135
+ let textHeight = 0;
136
+
137
+ const qrImages: HTMLCanvasElement[] = [];
138
+ const keys = splitKeys(qr.data, QRBinaryMaxLength);
139
+ for (const key of keys) {
140
+ qrImages.push(await QRCode.toCanvas(key, { errorCorrectionLevel: 'L' }));
141
+ }
142
+
143
+ let nextQrIndex = drawOnePageOfQrCodes(qrImages, doc, y, qrSize, 0);
144
+
145
+ doc.setFontSize(font.subheader).setTextColor(color.black);
146
+ y = moveDown(y, 10);
147
+ textHeight += 10;
148
+ doc.text(qr.title, textLeft, y);
149
+ textHeight += doc.getLineHeight();
150
+ y = moveDown(y, 15);
151
+ textHeight += 15;
152
+ doc.setFontSize(font.body).setTextColor(color.darkgray);
153
+ doc.text(qr.description, textLeft, y);
154
+ textHeight += doc.getLineHeight();
155
+ doc.setFontSize(font.body - 2);
156
+ if (qr?.data?.length > QRBinaryMaxLength) {
157
+ y = moveDown(y, 30);
158
+ textHeight += 30;
159
+ doc.text('Note: you will need to put all Parts together for the full key', textLeft, y);
160
+ }
161
+ y = moveDown(y, 30);
162
+ textHeight += 30;
163
+ doc.text('Data:', textLeft, y);
164
+ textHeight += doc.getLineHeight();
165
+ y = moveDown(y, 15);
166
+ textHeight += 15;
167
+ const width = 72 * 8.5 - textLeft - 30;
168
+ doc.setFont('courier').setFontSize(9).setTextColor(color.black);
169
+ const lines = doc.splitTextToSize(qr.data, width);
170
+ const buffer = 10;
171
+ for (let line = 0; line < lines.length; line++) {
172
+ // add new page if data does not fit on one page
173
+ if (y + buffer >= doc.internal.pageSize.getHeight()) {
174
+ doc.addPage();
175
+ textHeight = 0;
176
+ y = 30;
177
+ topY = y;
178
+ nextQrIndex = drawOnePageOfQrCodes(qrImages, doc, y, qrSize, nextQrIndex);
179
+ doc.setFont('courier').setFontSize(9).setTextColor(color.black);
180
+ }
181
+ doc.text(lines[line], textLeft, y);
182
+ if (line !== lines.length - 1) {
183
+ y = moveDown(y, buffer);
184
+ textHeight += buffer;
185
+ }
186
+ }
187
+
188
+ // Add public key if exists
189
+ if (qr.publicMasterKey) {
190
+ const text = 'Key Id: ' + qr.publicMasterKey;
191
+
192
+ // Gray bar
193
+ y = moveDown(y, 20);
194
+ textHeight += 20;
195
+ doc.setFillColor(247, 249, 249); // Gray background
196
+ doc.setDrawColor(0, 0, 0); // Border
197
+
198
+ // Leave a bit of space for the side of the rectangle.
199
+ const splitKeyId = doc.splitTextToSize(text, width - 10);
200
+
201
+ // The height of the box must be at least 15 px (for single line case), or
202
+ // a multiple of 13 for each line. This allows for proper padding.
203
+ doc.rect(textLeft, y, width, Math.max(12 * splitKeyId.length, 15), 'FD');
204
+ textHeight += splitKeyId.length * doc.getLineHeight();
205
+ doc.text(splitKeyId, textLeft + 5, y + 10);
206
+ }
207
+
208
+ doc.setFont('helvetica');
209
+ // Move down the size of the QR code minus accumulated height on the right side, plus margin
210
+ // if we have a key that spans multiple pages, then exclude QR code size
211
+ const rowHeight = Math.max(qr.data.length > QRBinaryMaxLength ? qrSize + 20 : qrSize, textHeight);
212
+ const marginBottom = 15;
213
+ y = moveDown(y, rowHeight - (y - topY) + marginBottom);
214
+ }
215
+
216
+ // Add next Page
217
+ doc.addPage();
218
+
219
+ // next pages title
220
+ y = 0;
221
+ y = moveDown(y, 55);
222
+ doc.setFontSize(font.header).setTextColor(color.black);
223
+ doc.text('BitGo KeyCard FAQ', left(0), y);
224
+
225
+ // Generate the second page's data for the backup PDF
226
+ y = moveDown(y, 30);
227
+ questions.forEach(function (q) {
228
+ doc.setFontSize(font.subheader).setTextColor(color.black);
229
+ doc.text(q.question, left(0), y);
230
+ y = moveDown(y, 20);
231
+ doc.setFontSize(font.body).setTextColor(color.darkgray);
232
+ q.answer.forEach(function (line) {
233
+ doc.text(line, left(0), y);
234
+ y = moveDown(y, font.body + 3);
235
+ });
236
+ y = moveDown(y, 22);
237
+ });
238
+
239
+ return doc;
240
+ }
@@ -6,7 +6,7 @@ import * as assert from 'assert';
6
6
  export interface GenerateQrDataParams {
7
7
  // The backup keychain as it is returned from the BitGo API upon creation
8
8
  backupKeychain: Keychain,
9
- // The 3rd party provider of the backup key if neither the user nor BitGo stores it
9
+ // The name of the 3rd party provider of the backup key if neither the user nor BitGo stores it
10
10
  backupKeyProvider?: string;
11
11
  // The key id of the backup key, only used for cold keys
12
12
  backupMasterKey?: string;
@@ -31,7 +31,6 @@ export interface GenerateQrDataParams {
31
31
  interface QrDataEntry {
32
32
  data: string;
33
33
  description: string;
34
- image: string;
35
34
  title: string;
36
35
  publicMasterKey?: string;
37
36
  }
@@ -58,7 +57,6 @@ function generateUserQrData(userKeychain: Keychain, userMasterKey?: string): QrD
58
57
  if (userKeychain.encryptedPrv) {
59
58
  return {
60
59
  title: 'A: User Key',
61
- image: '.qrEncryptedUserKey',
62
60
  description: 'This is your private key, encrypted with your wallet password.',
63
61
  data: userKeychain.encryptedPrv,
64
62
  };
@@ -69,7 +67,6 @@ function generateUserQrData(userKeychain: Keychain, userMasterKey?: string): QrD
69
67
 
70
68
  return {
71
69
  title: 'A: Provided User Key',
72
- image: '.qrPublicUserKey',
73
70
  description: 'This is the public key you provided for your wallet.',
74
71
  data: pub,
75
72
  publicMasterKey: userMasterKey,
@@ -87,21 +84,19 @@ function generateBackupQrData(coin: Readonly<BaseCoin>, backupKeychain: Keychain
87
84
  if (backupKeychain.encryptedPrv) {
88
85
  return {
89
86
  title,
90
- image: '.qrEncryptedBackupKey',
91
87
  description: 'This is your backup private key, encrypted with your wallet password.',
92
88
  data: backupKeychain.encryptedPrv,
93
89
  };
94
90
  }
95
91
 
96
92
  if (backupKeyProvider === 'BitGo Trust' && backupKeychain.type === 'tss') {
97
- const userToBackupShare = backupKeychain.keyShares?.find((keyShare) => keyShare.from === 'user' && keyShare.to === 'backup');
98
- assert(userToBackupShare);
93
+ const keyShares = backupKeychain.keyShares?.filter((keyShare) => keyShare.to === 'backup');
94
+ assert(keyShares?.length === 2);
99
95
  return {
100
- title: 'B: User To Backup Key Share',
101
- image: '.qrUserToBackupKeyShare',
102
- description: `This is the key share from you for ${backupKeyProvider}. If BitGo Inc goes out of business,` +
103
- `\r\ncontact ${backupKeyProvider} and they will help you recover your funds.`,
104
- data: JSON.stringify(userToBackupShare),
96
+ title: 'B: Backup Key Shares',
97
+ description: `These are the key shares for ${backupKeyProvider}. If BitGo Inc. goes out of business,\r\n` +
98
+ `contact ${backupKeyProvider} and they will help you recover your funds.`,
99
+ data: JSON.stringify(keyShares),
105
100
  };
106
101
  }
107
102
 
@@ -111,7 +106,6 @@ function generateBackupQrData(coin: Readonly<BaseCoin>, backupKeychain: Keychain
111
106
  if (backupKeyProvider) {
112
107
  return {
113
108
  title: 'B: Backup Key',
114
- image: '.qrPublicBackupKey',
115
109
  description: `This is the public key held at ${backupKeyProvider}, an ${coin.name} recovery service. ` +
116
110
  `If you lose\r\nyour key, ${backupKeyProvider} will be able to sign transactions to recover funds.`,
117
111
  data: pub,
@@ -120,38 +114,18 @@ function generateBackupQrData(coin: Readonly<BaseCoin>, backupKeychain: Keychain
120
114
 
121
115
  return {
122
116
  title: 'B: Provided Backup Key',
123
- image: '.qrEncryptedUserProvidedXpub',
124
117
  description: 'This is the public key you provided for your wallet.',
125
118
  data: pub,
126
119
  publicMasterKey: backupMasterKey,
127
120
  };
128
121
  }
129
122
 
130
- function generateBitGoQrData(bitgoKeychain: Keychain, {
131
- backupKeychain,
132
- backupKeyProvider,
133
- }: {
134
- backupKeychain?: Keychain,
135
- backupKeyProvider?: string;
136
- }): QrDataEntry {
137
- if (backupKeyProvider === 'BitGo Trust' && backupKeychain?.type === 'tss') {
138
- const bitgoToBackupShare = backupKeychain.keyShares?.find((keyShare) => keyShare.from === 'bitgo' && keyShare.to === 'backup');
139
- assert(bitgoToBackupShare);
140
- return {
141
- title: 'C: BitGo To Backup Key Share',
142
- image: '.qrBitGoToBackupKeyShare',
143
- description: `This is the key share from BitGo Inc for ${backupKeyProvider}. If BitGo Inc goes out of business,` +
144
- `\r\ncontact ${backupKeyProvider} and they will help you recover your funds.`,
145
- data: JSON.stringify(bitgoToBackupShare),
146
- };
147
- }
148
-
123
+ function generateBitGoQrData(bitgoKeychain: Keychain): QrDataEntry {
149
124
  const bitgoData = getPubFromKey(bitgoKeychain);
150
125
  assert(bitgoData);
151
126
 
152
127
  return {
153
128
  title: 'C: BitGo Public Key',
154
- image: '.qrBitgoKey',
155
129
  description:
156
130
  'This is the public part of the key that BitGo will use to ' +
157
131
  'co-sign transactions\r\nwith you on your wallet.',
@@ -176,10 +150,7 @@ export function generateQrData({
176
150
  backupKeyProvider,
177
151
  backupMasterKey,
178
152
  }),
179
- bitgo: generateBitGoQrData(bitgoKeychain, {
180
- backupKeychain,
181
- backupKeyProvider,
182
- }),
153
+ bitgo: generateBitGoQrData(bitgoKeychain),
183
154
  };
184
155
 
185
156
  if (passphrase && passcodeEncryptionCode) {
@@ -187,8 +158,7 @@ export function generateQrData({
187
158
 
188
159
  qrData.passcode = {
189
160
  title: 'D: Encrypted wallet Password',
190
- image: '.qrEncryptedWalletPasscode',
191
- description: 'This is the wallet password, encrypted client-side with a key held by\r\nBitGo.',
161
+ description: 'This is the wallet password, encrypted client-side with a key held by BitGo.',
192
162
  data: encryptedWalletPasscode,
193
163
  };
194
164
  }
package/src/index.ts CHANGED
@@ -1 +1,22 @@
1
+ import { generateQrData, GenerateQrDataParams } from './generateQrData';
2
+ import { generateFaq } from './faq';
3
+ import { drawKeycard } from './drawKeycard';
4
+
5
+ export * from './drawKeycard';
6
+ export * from './faq';
7
+ export * from './generateQrData';
1
8
  export * from './utils';
9
+
10
+ export interface GenerateKeycardParams extends GenerateQrDataParams {
11
+ activationCode?: string;
12
+ keyCardImage?: HTMLImageElement;
13
+ walletLabel: string;
14
+ }
15
+
16
+ export async function generateKeycard(params: GenerateKeycardParams): Promise<void> {
17
+ const questions = generateFaq(params.coin.fullName);
18
+ const qrData = generateQrData(params);
19
+ const keycard = await drawKeycard({ ...params, questions, qrData });
20
+ // Save the PDF on the user's browser
21
+ keycard.save(`BitGo Keycard for ${params.walletLabel}.pdf`);
22
+ }
@@ -57,27 +57,23 @@ describe('generateQrData', function () {
57
57
  });
58
58
 
59
59
  qrData.user.title.should.equal('A: User Key');
60
- qrData.user.image.should.equal('.qrEncryptedUserKey');
61
60
  qrData.user.description.should.equal('This is your private key, encrypted with your wallet password.');
62
61
  qrData.user.data.should.equal(userEncryptedPrv);
63
62
 
64
63
  assert(qrData.backup);
65
64
  qrData.backup.title.should.equal('B: Backup Key');
66
- qrData.backup.image.should.equal('.qrEncryptedBackupKey');
67
65
  qrData.backup.description.should.equal('This is your backup private key, encrypted with your wallet password.');
68
66
  qrData.backup.data.should.equal(backupEncryptedPrv);
69
67
 
70
68
  assert(qrData.bitgo);
71
69
  qrData.bitgo.title.should.equal('C: BitGo Public Key');
72
- qrData.bitgo.image.should.equal('.qrBitgoKey');
73
70
  qrData.bitgo.description.should.equal('This is the public part of the key that BitGo will use to ' +
74
71
  'co-sign transactions\r\nwith you on your wallet.');
75
72
  qrData.bitgo.data.should.equal(bitgoPub);
76
73
 
77
74
  assert(qrData.passcode);
78
75
  qrData.passcode.title.should.equal('D: Encrypted wallet Password');
79
- qrData.passcode.image.should.equal('.qrEncryptedWalletPasscode');
80
- qrData.passcode.description.should.equal('This is the wallet password, encrypted client-side with a key held by\r\nBitGo.');
76
+ qrData.passcode.description.should.equal('This is the wallet password, encrypted client-side with a key held by BitGo.');
81
77
  const decryptedData = decrypt(passcodeEncryptionCode, qrData.passcode.data);
82
78
  decryptedData.should.equal(passphrase);
83
79
  });
@@ -120,14 +116,12 @@ describe('generateQrData', function () {
120
116
  });
121
117
 
122
118
  qrData.user.title.should.equal('A: Provided User Key');
123
- qrData.user.image.should.equal('.qrPublicUserKey');
124
119
  qrData.user.description.should.equal('This is the public key you provided for your wallet.');
125
120
  qrData.user.data.should.equal(userPub);
126
121
  should.equal(qrData.user.publicMasterKey, userMasterKey);
127
122
 
128
123
  assert(qrData.backup);
129
124
  qrData.backup.title.should.equal('B: Provided Backup Key');
130
- qrData.backup.image.should.equal('.qrEncryptedUserProvidedXpub');
131
125
  qrData.backup.description.should.equal('This is the public key you provided for your wallet.');
132
126
  qrData.backup.data.should.equal(backupPub);
133
127
  should.equal(qrData.backup?.publicMasterKey, backupMasterKey);
@@ -165,7 +159,6 @@ describe('generateQrData', function () {
165
159
 
166
160
  assert(qrData.backup);
167
161
  qrData.backup.title.should.equal('B: Backup Key');
168
- qrData.backup.image.should.equal('.qrPublicBackupKey');
169
162
  qrData.backup.description.should.equal('This is the public key held at ' +
170
163
  provider +
171
164
  ', an ' +
@@ -186,6 +179,7 @@ describe('generateQrData', function () {
186
179
  const backupKeyProvider = 'BitGo Trust';
187
180
  const userToBackupKeyShare: ApiKeyShare = { from: 'user', to: 'backup', publicShare: 'userToBackupPublic', privateShare: 'userToBackupPrivate' };
188
181
  const bitgoToBackupKeyShare: ApiKeyShare = { from: 'bitgo', to: 'backup', publicShare: 'bitgoToBackupPublic', privateShare: 'bitgoToBackupPrivate' };
182
+ const bitgoCommonKeychain = 'commonCommonBitGo';
189
183
  const qrData = generateQrData({
190
184
  backupKeychain: createKeychain({
191
185
  provider,
@@ -195,6 +189,7 @@ describe('generateQrData', function () {
195
189
  backupKeyProvider,
196
190
  bitgoKeychain: createKeychain({
197
191
  type: 'tss',
192
+ commonKeychain: bitgoCommonKeychain,
198
193
  }),
199
194
  coin,
200
195
  userKeychain: createKeychain({
@@ -206,15 +201,13 @@ describe('generateQrData', function () {
206
201
  qrData.user.data.should.equal(userEncryptedPrv);
207
202
 
208
203
  assert(qrData.backup);
209
- qrData.backup.title.should.equal('B: User To Backup Key Share');
210
- qrData.backup.image.should.equal('.qrUserToBackupKeyShare');
211
- qrData.backup.description.should.equal(`This is the key share from you for ${backupKeyProvider}. If BitGo Inc goes out of business,\r\ncontact ${backupKeyProvider} and they will help you recover your funds.`);
212
- qrData.backup.data.should.equal(JSON.stringify(userToBackupKeyShare));
204
+ qrData.backup.title.should.equal('B: Backup Key Shares');
205
+ qrData.backup.description.should.equal(`These are the key shares for ${backupKeyProvider}. If BitGo Inc. goes out of business,\r\ncontact ${backupKeyProvider} and they will help you recover your funds.`);
206
+ qrData.backup.data.should.equal(JSON.stringify([userToBackupKeyShare, bitgoToBackupKeyShare]));
213
207
 
214
208
  assert(qrData.bitgo);
215
- qrData.bitgo.title.should.equal('C: BitGo To Backup Key Share');
216
- qrData.bitgo.image.should.equal('.qrBitGoToBackupKeyShare');
217
- qrData.bitgo.description.should.equal(`This is the key share from BitGo Inc for ${backupKeyProvider}. If BitGo Inc goes out of business,\r\ncontact ${backupKeyProvider} and they will help you recover your funds.`);
218
- qrData.bitgo.data.should.equal(JSON.stringify(bitgoToBackupKeyShare));
209
+ qrData.bitgo.title.should.equal('C: BitGo Public Key');
210
+ qrData.bitgo.description.should.equal('This is the public part of the key that BitGo will use to co-sign transactions\r\nwith you on your wallet.');
211
+ qrData.bitgo.data.should.equal(bitgoCommonKeychain);
219
212
  });
220
213
  });