@ledgerhq/ledger-key-ring-protocol 0.5.1-nightly.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 (180) hide show
  1. package/.eslintrc.js +33 -0
  2. package/.turbo/turbo-build.log +4 -0
  3. package/.unimportedrc.json +16 -0
  4. package/CHANGELOG.md +299 -0
  5. package/LICENSE.txt +21 -0
  6. package/README.md +3 -0
  7. package/jest.config.js +13 -0
  8. package/lib/HWDeviceProvider.d.ts +25 -0
  9. package/lib/HWDeviceProvider.d.ts.map +1 -0
  10. package/lib/HWDeviceProvider.js +88 -0
  11. package/lib/HWDeviceProvider.js.map +1 -0
  12. package/lib/api.d.ts +77 -0
  13. package/lib/api.d.ts.map +1 -0
  14. package/lib/api.js +150 -0
  15. package/lib/api.js.map +1 -0
  16. package/lib/auth.d.ts +3 -0
  17. package/lib/auth.d.ts.map +1 -0
  18. package/lib/auth.js +79 -0
  19. package/lib/auth.js.map +1 -0
  20. package/lib/errors.d.ts +40 -0
  21. package/lib/errors.d.ts.map +1 -0
  22. package/lib/errors.js +18 -0
  23. package/lib/errors.js.map +1 -0
  24. package/lib/index.d.ts +6 -0
  25. package/lib/index.d.ts.map +1 -0
  26. package/lib/index.js +17 -0
  27. package/lib/index.js.map +1 -0
  28. package/lib/mockSdk.d.ts +22 -0
  29. package/lib/mockSdk.d.ts.map +1 -0
  30. package/lib/mockSdk.js +208 -0
  31. package/lib/mockSdk.js.map +1 -0
  32. package/lib/qrcode/cipher.d.ts +12 -0
  33. package/lib/qrcode/cipher.d.ts.map +1 -0
  34. package/lib/qrcode/cipher.js +69 -0
  35. package/lib/qrcode/cipher.js.map +1 -0
  36. package/lib/qrcode/cipher.test.d.ts +2 -0
  37. package/lib/qrcode/cipher.test.d.ts.map +1 -0
  38. package/lib/qrcode/cipher.test.js +40 -0
  39. package/lib/qrcode/cipher.test.js.map +1 -0
  40. package/lib/qrcode/index.d.ts +70 -0
  41. package/lib/qrcode/index.d.ts.map +1 -0
  42. package/lib/qrcode/index.js +312 -0
  43. package/lib/qrcode/index.js.map +1 -0
  44. package/lib/qrcode/index.test.d.ts +2 -0
  45. package/lib/qrcode/index.test.d.ts.map +1 -0
  46. package/lib/qrcode/index.test.js +131 -0
  47. package/lib/qrcode/index.test.js.map +1 -0
  48. package/lib/qrcode/types.d.ts +69 -0
  49. package/lib/qrcode/types.d.ts.map +1 -0
  50. package/lib/qrcode/types.js +3 -0
  51. package/lib/qrcode/types.js.map +1 -0
  52. package/lib/sdk.d.ts +31 -0
  53. package/lib/sdk.d.ts.map +1 -0
  54. package/lib/sdk.js +380 -0
  55. package/lib/sdk.js.map +1 -0
  56. package/lib/store.d.ts +71 -0
  57. package/lib/store.d.ts.map +1 -0
  58. package/lib/store.js +62 -0
  59. package/lib/store.js.map +1 -0
  60. package/lib/types.d.ts +181 -0
  61. package/lib/types.d.ts.map +1 -0
  62. package/lib/types.js +10 -0
  63. package/lib/types.js.map +1 -0
  64. package/lib-es/HWDeviceProvider.d.ts +25 -0
  65. package/lib-es/HWDeviceProvider.d.ts.map +1 -0
  66. package/lib-es/HWDeviceProvider.js +81 -0
  67. package/lib-es/HWDeviceProvider.js.map +1 -0
  68. package/lib-es/api.d.ts +77 -0
  69. package/lib-es/api.d.ts.map +1 -0
  70. package/lib-es/api.js +145 -0
  71. package/lib-es/api.js.map +1 -0
  72. package/lib-es/auth.d.ts +3 -0
  73. package/lib-es/auth.d.ts.map +1 -0
  74. package/lib-es/auth.js +75 -0
  75. package/lib-es/auth.js.map +1 -0
  76. package/lib-es/errors.d.ts +40 -0
  77. package/lib-es/errors.d.ts.map +1 -0
  78. package/lib-es/errors.js +15 -0
  79. package/lib-es/errors.js.map +1 -0
  80. package/lib-es/index.d.ts +6 -0
  81. package/lib-es/index.d.ts.map +1 -0
  82. package/lib-es/index.js +13 -0
  83. package/lib-es/index.js.map +1 -0
  84. package/lib-es/mockSdk.d.ts +22 -0
  85. package/lib-es/mockSdk.d.ts.map +1 -0
  86. package/lib-es/mockSdk.js +201 -0
  87. package/lib-es/mockSdk.js.map +1 -0
  88. package/lib-es/qrcode/cipher.d.ts +12 -0
  89. package/lib-es/qrcode/cipher.d.ts.map +1 -0
  90. package/lib-es/qrcode/cipher.js +61 -0
  91. package/lib-es/qrcode/cipher.js.map +1 -0
  92. package/lib-es/qrcode/cipher.test.d.ts +2 -0
  93. package/lib-es/qrcode/cipher.test.d.ts.map +1 -0
  94. package/lib-es/qrcode/cipher.test.js +38 -0
  95. package/lib-es/qrcode/cipher.test.js.map +1 -0
  96. package/lib-es/qrcode/index.d.ts +70 -0
  97. package/lib-es/qrcode/index.d.ts.map +1 -0
  98. package/lib-es/qrcode/index.js +304 -0
  99. package/lib-es/qrcode/index.js.map +1 -0
  100. package/lib-es/qrcode/index.test.d.ts +2 -0
  101. package/lib-es/qrcode/index.test.d.ts.map +1 -0
  102. package/lib-es/qrcode/index.test.js +126 -0
  103. package/lib-es/qrcode/index.test.js.map +1 -0
  104. package/lib-es/qrcode/types.d.ts +69 -0
  105. package/lib-es/qrcode/types.d.ts.map +1 -0
  106. package/lib-es/qrcode/types.js +2 -0
  107. package/lib-es/qrcode/types.js.map +1 -0
  108. package/lib-es/sdk.d.ts +31 -0
  109. package/lib-es/sdk.d.ts.map +1 -0
  110. package/lib-es/sdk.js +371 -0
  111. package/lib-es/sdk.js.map +1 -0
  112. package/lib-es/store.d.ts +71 -0
  113. package/lib-es/store.d.ts.map +1 -0
  114. package/lib-es/store.js +51 -0
  115. package/lib-es/store.js.map +1 -0
  116. package/lib-es/types.d.ts +181 -0
  117. package/lib-es/types.d.ts.map +1 -0
  118. package/lib-es/types.js +7 -0
  119. package/lib-es/types.js.map +1 -0
  120. package/mocks/scenarios/addSameMemberMultipleTimes.json +426 -0
  121. package/mocks/scenarios/create2trustchainInARow.json +616 -0
  122. package/mocks/scenarios/getOrCreateTransactionCases.json +591 -0
  123. package/mocks/scenarios/member3implicitlyAdded.json +648 -0
  124. package/mocks/scenarios/membersManySelfAdd.json +1427 -0
  125. package/mocks/scenarios/randomMemberTryToDestroy.json +371 -0
  126. package/mocks/scenarios/removeMemberWithTheWrongSeed.json +510 -0
  127. package/mocks/scenarios/removedMemberEjectedOnDeletedTrustchain.json +481 -0
  128. package/mocks/scenarios/removedMemberEjectedOnGetMembers.json +648 -0
  129. package/mocks/scenarios/removedMemberEjectedOnRestore.json +648 -0
  130. package/mocks/scenarios/removingAMemberCreatesAnInteraction.json +593 -0
  131. package/mocks/scenarios/removingYourselfIsForbidden.json +397 -0
  132. package/mocks/scenarios/success.json +978 -0
  133. package/mocks/scenarios/tokenExpires.json +371 -0
  134. package/mocks/scenarios/twoAddMembersFollowedByDeviceAdd.json +705 -0
  135. package/mocks/scenarios/userRefusesAuth.json +40 -0
  136. package/mocks/scenarios/userRefusesRemoveMember.json +542 -0
  137. package/package.json +91 -0
  138. package/scripts/README.md +15 -0
  139. package/scripts/e2e.ts +57 -0
  140. package/src/HWDeviceProvider.ts +105 -0
  141. package/src/__tests__/integration/mock.sdk.test.ts +47 -0
  142. package/src/__tests__/integration/sdk.test.ts +20 -0
  143. package/src/__tests__/tsconfig.json +8 -0
  144. package/src/__tests__/unit/sdk.test.ts +236 -0
  145. package/src/api.ts +202 -0
  146. package/src/auth.ts +81 -0
  147. package/src/errors.ts +18 -0
  148. package/src/index.ts +20 -0
  149. package/src/mockSdk.ts +253 -0
  150. package/src/qrcode/cipher.test.ts +30 -0
  151. package/src/qrcode/cipher.ts +63 -0
  152. package/src/qrcode/index.test.ts +138 -0
  153. package/src/qrcode/index.ts +395 -0
  154. package/src/qrcode/types.ts +70 -0
  155. package/src/sdk.ts +542 -0
  156. package/src/store.ts +99 -0
  157. package/src/types.ts +242 -0
  158. package/tests/scenarios/_template.ts +18 -0
  159. package/tests/scenarios/addSameMemberMultipleTimes.ts +20 -0
  160. package/tests/scenarios/create2trustchainInARow.ts +14 -0
  161. package/tests/scenarios/getOrCreateTransactionCases.ts +74 -0
  162. package/tests/scenarios/member3implicitlyAdded.ts +51 -0
  163. package/tests/scenarios/membersManySelfAdd.ts +18 -0
  164. package/tests/scenarios/randomMemberTryToDestroy.ts +23 -0
  165. package/tests/scenarios/removeMemberWithTheWrongSeed.ts +28 -0
  166. package/tests/scenarios/removedMemberEjectedOnDeletedTrustchain.ts +31 -0
  167. package/tests/scenarios/removedMemberEjectedOnGetMembers.ts +29 -0
  168. package/tests/scenarios/removedMemberEjectedOnRestore.ts +31 -0
  169. package/tests/scenarios/removingAMemberCreatesAnInteraction.ts +42 -0
  170. package/tests/scenarios/removingYourselfIsForbidden.ts +11 -0
  171. package/tests/scenarios/success.ts +94 -0
  172. package/tests/scenarios/tokenExpires.ts +20 -0
  173. package/tests/scenarios/twoAddMembersFollowedByDeviceAdd.ts +49 -0
  174. package/tests/scenarios/userRefusesAuth.ts +28 -0
  175. package/tests/scenarios/userRefusesRemoveMember.ts +66 -0
  176. package/tests/test-helpers/recordTrustchainSdkTests.ts +178 -0
  177. package/tests/test-helpers/replayTrustchainSdkTests.ts +141 -0
  178. package/tests/test-helpers/types.ts +45 -0
  179. package/tests/tsconfig.json +8 -0
  180. package/tsconfig.json +15 -0
@@ -0,0 +1,61 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import Base64 from "base64-js";
11
+ import { crypto } from "@ledgerhq/hw-ledger-key-ring-protocol";
12
+ import { InvalidEncryptionKeyError } from "../errors";
13
+ export function makeCipher(sessionEncryptionKey) {
14
+ function encrypt(obj) {
15
+ return __awaiter(this, void 0, void 0, function* () {
16
+ const plaintext = JSON.stringify(obj);
17
+ const data = new TextEncoder().encode(plaintext);
18
+ const nonce = yield crypto.randomBytes(16);
19
+ const ciphertext = yield crypto.encrypt(sessionEncryptionKey, nonce, data);
20
+ const blob = new Uint8Array(nonce.length + ciphertext.length);
21
+ blob.set(nonce);
22
+ blob.set(ciphertext, nonce.length);
23
+ return Base64.fromByteArray(blob);
24
+ });
25
+ }
26
+ function decrypt(data) {
27
+ return __awaiter(this, void 0, void 0, function* () {
28
+ const blob = Base64.toByteArray(data);
29
+ const nonce = blob.slice(0, 16);
30
+ const ciphertext = blob.slice(16);
31
+ try {
32
+ const plaintext = yield crypto.decrypt(sessionEncryptionKey, nonce, ciphertext);
33
+ const text = new TextDecoder().decode(plaintext);
34
+ return JSON.parse(text);
35
+ }
36
+ catch (e) {
37
+ throw new InvalidEncryptionKeyError("data can't be decrypted");
38
+ }
39
+ });
40
+ }
41
+ return { encrypt, decrypt };
42
+ }
43
+ export function makeMessageCipher(cipher) {
44
+ function encryptMessagePayload(payload) {
45
+ return __awaiter(this, void 0, void 0, function* () {
46
+ const encrypted = yield cipher.encrypt(payload);
47
+ return { encrypted };
48
+ });
49
+ }
50
+ function decryptMessage(message) {
51
+ return __awaiter(this, void 0, void 0, function* () {
52
+ if (message.message === "InitiateHandshake" || message.message === "Failure") {
53
+ throw new Error(message.message + " is not encrypted");
54
+ }
55
+ const decrypted = (yield cipher.decrypt(message.payload.encrypted));
56
+ return decrypted;
57
+ });
58
+ }
59
+ return { encryptMessagePayload, decryptMessage };
60
+ }
61
+ //# sourceMappingURL=cipher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cipher.js","sourceRoot":"","sources":["../../src/qrcode/cipher.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,MAAM,MAAM,WAAW,CAAC;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,uCAAuC,CAAC;AAE/D,OAAO,EAAE,yBAAyB,EAAE,MAAM,WAAW,CAAC;AActD,MAAM,UAAU,UAAU,CAAC,oBAAgC;IACzD,SAAe,OAAO,CAAC,GAAW;;YAChC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YACtC,MAAM,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YACjD,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;YAC3C,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,oBAAoB,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;YAC3E,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;YAC9D,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAChB,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;YACnC,OAAO,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QACpC,CAAC;KAAA;IAED,SAAe,OAAO,CAAC,IAAY;;YACjC,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;YACtC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAChC,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAClC,IAAI,CAAC;gBACH,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,oBAAoB,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;gBAChF,MAAM,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;gBACjD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC1B,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,MAAM,IAAI,yBAAyB,CAAC,yBAAyB,CAAC,CAAC;YACjE,CAAC;QACH,CAAC;KAAA;IAED,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAAc;IAC9C,SAAe,qBAAqB,CAClC,OAAU;;YAEV,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAChD,OAAO,EAAE,SAAS,EAAE,CAAC;QACvB,CAAC;KAAA;IAED,SAAe,cAAc,CAAoB,OAAU;;YACzD,IAAI,OAAO,CAAC,OAAO,KAAK,mBAAmB,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;gBAC7E,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,GAAG,mBAAmB,CAAC,CAAC;YACzD,CAAC;YACD,MAAM,SAAS,GAAG,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAwB,CAAC;YAC3F,OAAO,SAAS,CAAC;QACnB,CAAC;KAAA;IAED,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,CAAC;AACnD,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cipher.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cipher.test.d.ts","sourceRoot":"","sources":["../../src/qrcode/cipher.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,38 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { crypto } from "@ledgerhq/hw-ledger-key-ring-protocol";
11
+ import { makeCipher } from "./cipher";
12
+ import { InvalidEncryptionKeyError } from "../errors";
13
+ describe("makeCipher", () => {
14
+ it("should encrypt and decrypt correctly", () => __awaiter(void 0, void 0, void 0, function* () {
15
+ const ephemeralKey = yield crypto.randomKeypair();
16
+ const candidate = yield crypto.randomKeypair();
17
+ const sessionEncryptionKey = yield crypto.ecdh(ephemeralKey, candidate.publicKey);
18
+ const cipher = makeCipher(sessionEncryptionKey);
19
+ const plaintext = { message: "Hello, World!" };
20
+ const encrypted = yield cipher.encrypt(plaintext);
21
+ expect(typeof encrypted).toBe("string");
22
+ const decrypted = yield cipher.decrypt(encrypted);
23
+ expect(decrypted).toEqual(plaintext);
24
+ }));
25
+ it("should throw InvalidEncryptionKeyError if key changes", () => __awaiter(void 0, void 0, void 0, function* () {
26
+ const ephemeralKey = yield crypto.randomKeypair();
27
+ const candidate = yield crypto.randomKeypair();
28
+ const sessionEncryptionKey = yield crypto.ecdh(ephemeralKey, candidate.publicKey);
29
+ const cipher = makeCipher(sessionEncryptionKey);
30
+ const plaintext = { message: "Hello, World!" };
31
+ const encrypted = yield cipher.encrypt(plaintext);
32
+ const ephemeralKey2 = yield crypto.randomKeypair();
33
+ const otherSessionEncryptionKey = yield crypto.ecdh(ephemeralKey2, candidate.publicKey);
34
+ const cipher2 = makeCipher(otherSessionEncryptionKey);
35
+ expect(cipher2.decrypt(encrypted)).rejects.toThrow(InvalidEncryptionKeyError);
36
+ }));
37
+ });
38
+ //# sourceMappingURL=cipher.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cipher.test.js","sourceRoot":"","sources":["../../src/qrcode/cipher.test.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,uCAAuC,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,yBAAyB,EAAE,MAAM,WAAW,CAAC;AAEtD,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IAC1B,EAAE,CAAC,sCAAsC,EAAE,GAAS,EAAE;QACpD,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,aAAa,EAAE,CAAC;QAClD,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,aAAa,EAAE,CAAC;QAC/C,MAAM,oBAAoB,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;QAClF,MAAM,MAAM,GAAG,UAAU,CAAC,oBAAoB,CAAC,CAAC;QAChD,MAAM,SAAS,GAAG,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC;QAC/C,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAClD,MAAM,CAAC,OAAO,SAAS,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxC,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAClD,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACvC,CAAC,CAAA,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAS,EAAE;QACrE,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,aAAa,EAAE,CAAC;QAClD,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,aAAa,EAAE,CAAC;QAC/C,MAAM,oBAAoB,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;QAClF,MAAM,MAAM,GAAG,UAAU,CAAC,oBAAoB,CAAC,CAAC;QAChD,MAAM,SAAS,GAAG,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC;QAC/C,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAClD,MAAM,aAAa,GAAG,MAAM,MAAM,CAAC,aAAa,EAAE,CAAC;QACnD,MAAM,yBAAyB,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;QACxF,MAAM,OAAO,GAAG,UAAU,CAAC,yBAAyB,CAAC,CAAC;QACtD,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAChF,CAAC,CAAA,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,70 @@
1
+ import { MemberCredentials, Trustchain, TrustchainMember } from "../types";
2
+ /**
3
+ * establish a channel to be able to add a member to the trustchain after displaying the QR Code
4
+ * @returns a promise that resolves when this is done
5
+ */
6
+ export declare function createQRCodeHostInstance({ trustchainApiBaseUrl, onDisplayQRCode, onDisplayDigits, addMember, memberCredentials, memberName, initialTrustchainId, }: {
7
+ /**
8
+ * the base URL of the trustchain API
9
+ */
10
+ trustchainApiBaseUrl: string;
11
+ /**
12
+ * this function will need to display a UI to show the QR Code
13
+ */
14
+ onDisplayQRCode: (url: string) => void;
15
+ /**
16
+ * this function will need to display a UI to show the digits
17
+ */
18
+ onDisplayDigits: (digits: string) => void;
19
+ /**
20
+ * this function will need to using the TrustchainSDK (and use sdk.addMember)
21
+ */
22
+ addMember: (member: TrustchainMember) => Promise<Trustchain>;
23
+ /**
24
+ * the client credentials of the instance (given by TrustchainSDK)
25
+ */
26
+ memberCredentials: MemberCredentials;
27
+ /**
28
+ * the name of the member
29
+ */
30
+ memberName: string;
31
+ /**
32
+ * if the member already has a trustchain, this will be defined
33
+ */
34
+ initialTrustchainId?: string;
35
+ }): Promise<Trustchain | void>;
36
+ /**
37
+ * establish a channel to be able to add myself to the trustchain after scanning the QR Code
38
+ * @returns a promise that resolves a Trustchain when this is done
39
+ */
40
+ export declare function createQRCodeCandidateInstance({ memberCredentials, memberName, addMember, initialTrustchainId, scannedUrl, onRequestQRCodeInput, }: {
41
+ /**
42
+ * the client credentials of the instance (given by TrustchainSDK)
43
+ */
44
+ memberCredentials: MemberCredentials;
45
+ /**
46
+ * the name of the member
47
+ */
48
+ memberName: string;
49
+ /**
50
+ * if the member already has a trustchain, this will be defined
51
+ */
52
+ initialTrustchainId?: string;
53
+ /**
54
+ * this function will need to using the TrustchainSDK (and use sdk.addMember)
55
+ */
56
+ addMember: (member: TrustchainMember) => Promise<Trustchain>;
57
+ /**
58
+ * the scanned URL that contains the host public key
59
+ */
60
+ scannedUrl: string;
61
+ /**
62
+ * this function will need to display a UI to ask the user to input the digits
63
+ * and then call the callback with the digits
64
+ */
65
+ onRequestQRCodeInput: (config: {
66
+ digits: number;
67
+ connected: boolean;
68
+ }, callback: (digits: string) => void) => void;
69
+ }): Promise<Trustchain | void>;
70
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/qrcode/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AA8F3E;;;GAGG;AACH,wBAAsB,wBAAwB,CAAC,EAC7C,oBAAoB,EACpB,eAAe,EACf,eAAe,EACf,SAAS,EACT,iBAAiB,EACjB,UAAU,EACV,mBAAmB,GACpB,EAAE;IACD;;OAEG;IACH,oBAAoB,EAAE,MAAM,CAAC;IAC7B;;OAEG;IACH,eAAe,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC;;OAEG;IACH,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C;;OAEG;IACH,SAAS,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IAC7D;;OAEG;IACH,iBAAiB,EAAE,iBAAiB,CAAC;IACrC;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAsF7B;AAED;;;GAGG;AACH,wBAAsB,6BAA6B,CAAC,EAClD,iBAAiB,EACjB,UAAU,EACV,SAAS,EACT,mBAAmB,EACnB,UAAU,EACV,oBAAoB,GACrB,EAAE;IACD;;OAEG;IACH,iBAAiB,EAAE,iBAAiB,CAAC;IACrC;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;OAEG;IACH,SAAS,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IAC7D;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,oBAAoB,EAAE,CACpB,MAAM,EAAE;QACN,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,OAAO,CAAC;KACpB,EACD,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,KAC/B,IAAI,CAAC;CACX,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CA8E7B"}
@@ -0,0 +1,304 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { Permissions, crypto } from "@ledgerhq/hw-ledger-key-ring-protocol";
11
+ import WebSocket from "isomorphic-ws";
12
+ import { makeCipher, makeMessageCipher } from "./cipher";
13
+ import { InvalidDigitsError, NoTrustchainInitialized, QRCodeWSClosed, ScannedInvalidQrCode, ScannedOldImportQrCode, TrustchainAlreadyInitialized, } from "../errors";
14
+ import { log } from "@ledgerhq/logs";
15
+ const version = 1;
16
+ const CLOSE_TIMEOUT = 100; // just enough time for the onerror to appear before onclose
17
+ const commonSwitch = (_a) => __awaiter(void 0, [_a], void 0, function* ({ data, cipher, addMember, send, publisher, resolve, memberCredentials, memberName, reject, ws, setFinished, initialTrustchainId, }) {
18
+ switch (data.message) {
19
+ case "TrustchainShareCredential": {
20
+ if (!initialTrustchainId) {
21
+ const payload = {
22
+ type: "UNEXPECTED_SHARE_CREDENTIAL",
23
+ message: "unexpected share credential",
24
+ };
25
+ send({ version, publisher, message: "Failure", payload });
26
+ throw new NoTrustchainInitialized("unexpected share credential");
27
+ }
28
+ setFinished(true);
29
+ if (!cipher) {
30
+ throw new Error("sessionEncryptionKey not set");
31
+ }
32
+ const { id, name } = yield cipher.decryptMessage(data);
33
+ const trustchain = yield addMember({ id, name, permissions: Permissions.OWNER });
34
+ const payload = yield cipher.encryptMessagePayload({ trustchain });
35
+ send({ version, publisher, message: "TrustchainAddedMember", payload });
36
+ resolve();
37
+ break;
38
+ }
39
+ case "TrustchainRequestCredential": {
40
+ if (initialTrustchainId) {
41
+ const payload = {
42
+ type: "UNEXPECTED_REQUEST_CREDENTIAL",
43
+ message: initialTrustchainId,
44
+ };
45
+ send({ version, publisher, message: "Failure", payload });
46
+ throw new TrustchainAlreadyInitialized(initialTrustchainId);
47
+ }
48
+ const payload = yield cipher.encryptMessagePayload({
49
+ id: memberCredentials.pubkey,
50
+ name: memberName,
51
+ });
52
+ send({ version, publisher, message: "TrustchainShareCredential", payload });
53
+ break;
54
+ }
55
+ case "TrustchainAddedMember": {
56
+ setFinished(true);
57
+ const { trustchain } = yield cipher.decryptMessage(data);
58
+ resolve(trustchain);
59
+ ws.close();
60
+ break;
61
+ }
62
+ case "Failure": {
63
+ setFinished(true);
64
+ log("trustchain/qrcode", "Failure", { data });
65
+ const error = fromErrorMessage(data.payload);
66
+ reject(error);
67
+ ws.close();
68
+ break;
69
+ }
70
+ case "HandshakeChallenge":
71
+ case "HandshakeCompletionSucceeded":
72
+ case "InitiateHandshake":
73
+ case "CompleteHandshakeChallenge":
74
+ break;
75
+ default:
76
+ throw new Error("unexpected message");
77
+ }
78
+ });
79
+ /**
80
+ * establish a channel to be able to add a member to the trustchain after displaying the QR Code
81
+ * @returns a promise that resolves when this is done
82
+ */
83
+ export function createQRCodeHostInstance(_a) {
84
+ return __awaiter(this, arguments, void 0, function* ({ trustchainApiBaseUrl, onDisplayQRCode, onDisplayDigits, addMember, memberCredentials, memberName, initialTrustchainId, }) {
85
+ const ephemeralKey = yield crypto.randomKeypair();
86
+ const publisher = crypto.to_hex(ephemeralKey.publicKey);
87
+ const url = `${trustchainApiBaseUrl.replace("http", "ws")}/v1/qr?host=${publisher}`;
88
+ const ws = new WebSocket(url);
89
+ function send(message) {
90
+ ws.send(JSON.stringify(message));
91
+ }
92
+ let sessionEncryptionKey;
93
+ let cipher;
94
+ let expectedDigits;
95
+ let finished = false;
96
+ const setFinished = newValue => (finished = newValue);
97
+ onDisplayQRCode(url);
98
+ return new Promise((resolve, reject) => {
99
+ const startedAt = Date.now();
100
+ ws.addEventListener("error", reject);
101
+ ws.addEventListener("close", () => {
102
+ if (finished)
103
+ return;
104
+ // this error would reflect a protocol error. because otherwise, we would get the "error" event.
105
+ const time = Date.now() - startedAt;
106
+ reject(new QRCodeWSClosed("qrcode websocket prematurely closed", { time }));
107
+ });
108
+ ws.addEventListener("message", (e) => __awaiter(this, void 0, void 0, function* () {
109
+ try {
110
+ const data = parseMessage(e.data);
111
+ switch (data.message) {
112
+ case "InitiateHandshake": {
113
+ const candidatePublicKey = crypto.from_hex(data.payload.ephemeral_public_key);
114
+ sessionEncryptionKey = yield crypto.ecdh(ephemeralKey, candidatePublicKey);
115
+ cipher = makeMessageCipher(makeCipher(sessionEncryptionKey));
116
+ // --- end of handshake first phase ---
117
+ const digitsCount = 3;
118
+ const digits = yield randomDigits(digitsCount);
119
+ expectedDigits = digits;
120
+ onDisplayDigits(digits);
121
+ const payload = yield cipher.encryptMessagePayload({
122
+ digits: digitsCount,
123
+ connected: false,
124
+ });
125
+ send({ version, publisher, message: "HandshakeChallenge", payload });
126
+ break;
127
+ }
128
+ case "CompleteHandshakeChallenge": {
129
+ if (!cipher) {
130
+ throw new Error("sessionEncryptionKey not set");
131
+ }
132
+ const { digits } = yield cipher.decryptMessage(data);
133
+ if (digits !== expectedDigits) {
134
+ console.warn("User invalid digits", { digits, expectedDigits });
135
+ const payload = {
136
+ type: "HANDSHAKE_COMPLETION_FAILED",
137
+ message: "invalid digits",
138
+ };
139
+ send({ version, publisher, message: "Failure", payload });
140
+ throw new InvalidDigitsError("invalid digits");
141
+ }
142
+ const payload = yield cipher.encryptMessagePayload({});
143
+ send({ version, publisher, message: "HandshakeCompletionSucceeded", payload });
144
+ break;
145
+ }
146
+ }
147
+ yield commonSwitch({
148
+ data,
149
+ cipher,
150
+ addMember,
151
+ send,
152
+ publisher,
153
+ resolve,
154
+ memberCredentials,
155
+ memberName,
156
+ reject,
157
+ ws,
158
+ setFinished,
159
+ initialTrustchainId,
160
+ });
161
+ }
162
+ catch (e) {
163
+ console.error("socket error", e);
164
+ ws.close();
165
+ reject(e);
166
+ }
167
+ }));
168
+ });
169
+ });
170
+ }
171
+ /**
172
+ * establish a channel to be able to add myself to the trustchain after scanning the QR Code
173
+ * @returns a promise that resolves a Trustchain when this is done
174
+ */
175
+ export function createQRCodeCandidateInstance(_a) {
176
+ return __awaiter(this, arguments, void 0, function* ({ memberCredentials, memberName, addMember, initialTrustchainId, scannedUrl, onRequestQRCodeInput, }) {
177
+ const m = scannedUrl.match(/host=([0-9A-Fa-f]+)/);
178
+ if (!m) {
179
+ if (isFromOldAccountsImport(scannedUrl))
180
+ throw new ScannedOldImportQrCode();
181
+ throw new ScannedInvalidQrCode();
182
+ }
183
+ const hostPublicKey = crypto.from_hex(m[1]);
184
+ const ephemeralKey = yield crypto.randomKeypair();
185
+ const publisher = crypto.to_hex(ephemeralKey.publicKey);
186
+ const sessionEncryptionKey = yield crypto.ecdh(ephemeralKey, hostPublicKey);
187
+ const cipher = makeMessageCipher(makeCipher(sessionEncryptionKey));
188
+ const ws = new WebSocket(scannedUrl);
189
+ function send(message) {
190
+ ws.send(JSON.stringify(message));
191
+ }
192
+ let finished = false;
193
+ const setFinished = newValue => (finished = newValue);
194
+ return new Promise((resolve, reject) => {
195
+ ws.addEventListener("close", () => {
196
+ if (finished)
197
+ return;
198
+ // this error would reflect a protocol error. because otherwise, we would get the "error" event. it shouldn't be visible to user, but we use it to ensure the promise ends.
199
+ setTimeout(() => reject(new Error("qrcode websocket prematurely closed")), CLOSE_TIMEOUT);
200
+ });
201
+ ws.addEventListener("message", (e) => __awaiter(this, void 0, void 0, function* () {
202
+ try {
203
+ const data = parseMessage(e.data);
204
+ switch (data.message) {
205
+ case "HandshakeChallenge": {
206
+ const config = yield cipher.decryptMessage(data);
207
+ onRequestQRCodeInput(config, digits => {
208
+ cipher.encryptMessagePayload({ digits }).then(payload => {
209
+ send({ version, publisher, message: "CompleteHandshakeChallenge", payload });
210
+ });
211
+ });
212
+ break;
213
+ }
214
+ case "HandshakeCompletionSucceeded": {
215
+ if (initialTrustchainId) {
216
+ const payload = yield cipher.encryptMessagePayload({});
217
+ send({ version, publisher, message: "TrustchainRequestCredential", payload });
218
+ }
219
+ else {
220
+ const payload = yield cipher.encryptMessagePayload({
221
+ id: memberCredentials.pubkey,
222
+ name: memberName,
223
+ });
224
+ send({ version, publisher, message: "TrustchainShareCredential", payload });
225
+ }
226
+ break;
227
+ }
228
+ }
229
+ yield commonSwitch({
230
+ data,
231
+ cipher,
232
+ addMember,
233
+ send,
234
+ publisher,
235
+ resolve,
236
+ memberCredentials,
237
+ memberName,
238
+ reject,
239
+ ws,
240
+ setFinished,
241
+ initialTrustchainId,
242
+ });
243
+ }
244
+ catch (e) {
245
+ console.error("socket error", e);
246
+ ws.close();
247
+ reject(e);
248
+ }
249
+ }));
250
+ ws.addEventListener("error", reject);
251
+ ws.addEventListener("open", () => {
252
+ const payload = { ephemeral_public_key: crypto.to_hex(ephemeralKey.publicKey) };
253
+ send({ version, publisher, message: "InitiateHandshake", payload });
254
+ });
255
+ });
256
+ });
257
+ }
258
+ function randomDigits(count) {
259
+ return __awaiter(this, void 0, void 0, function* () {
260
+ const bytes = yield crypto.randomBytes(count);
261
+ let digits = "";
262
+ for (let i = 0; i < count; i++) {
263
+ digits += (bytes[i] % 10).toString();
264
+ }
265
+ return digits;
266
+ });
267
+ }
268
+ function parseMessage(e) {
269
+ const message = JSON.parse(e.toString());
270
+ if (!message || typeof message !== "object") {
271
+ throw new Error("invalid message");
272
+ }
273
+ if (message.version !== 1) {
274
+ throw new Error("invalid version");
275
+ }
276
+ if (typeof message.publisher !== "string") {
277
+ throw new Error("invalid publisher");
278
+ }
279
+ if (typeof message.message !== "string") {
280
+ throw new Error("invalid message");
281
+ }
282
+ if (typeof message.payload !== "object") {
283
+ throw new Error("invalid payload");
284
+ }
285
+ return message;
286
+ }
287
+ function fromErrorMessage(payload) {
288
+ if (payload.type === "HANDSHAKE_COMPLETION_FAILED") {
289
+ throw new InvalidDigitsError(payload.message);
290
+ }
291
+ if (payload.type === "UNEXPECTED_SHARE_CREDENTIAL") {
292
+ throw new NoTrustchainInitialized(payload.message);
293
+ }
294
+ if (payload.type === "UNEXPECTED_REQUEST_CREDENTIAL") {
295
+ throw new TrustchainAlreadyInitialized(payload.message);
296
+ }
297
+ const error = new Error(payload.message);
298
+ error.name = "TrustchainQRCode-" + payload.type;
299
+ return error;
300
+ }
301
+ function isFromOldAccountsImport(scannedUrl) {
302
+ return !!scannedUrl.match(/^[A-Za-z0-9+/=]*$/);
303
+ }
304
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/qrcode/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../../src/qrcode/index.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,126 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { createQRCodeHostInstance, createQRCodeCandidateInstance } from ".";
11
+ import WebSocket from "ws";
12
+ import { convertKeyPairToLiveCredentials } from "../sdk";
13
+ import { crypto } from "@ledgerhq/hw-ledger-key-ring-protocol";
14
+ import { ScannedInvalidQrCode, ScannedOldImportQrCode } from "../errors";
15
+ describe("Trustchain QR Code", () => {
16
+ let server;
17
+ let a;
18
+ let b;
19
+ beforeAll(() => {
20
+ server = new WebSocket.Server({ port: 1234 });
21
+ server.on("connection", ws => {
22
+ if (!a) {
23
+ a = ws;
24
+ }
25
+ else if (!b) {
26
+ b = ws;
27
+ }
28
+ ws.on("message", message => {
29
+ if (ws === a && b) {
30
+ b.send(message);
31
+ }
32
+ else if (ws === b && a) {
33
+ a.send(message);
34
+ }
35
+ });
36
+ });
37
+ });
38
+ afterAll(() => {
39
+ server.close();
40
+ });
41
+ test("digits matching scenario", () => __awaiter(void 0, void 0, void 0, function* () {
42
+ const onDisplayDigits = jest.fn();
43
+ const trustchain = {
44
+ rootId: "test-root-id",
45
+ walletSyncEncryptionKey: "test-wallet-sync-encryption-key",
46
+ applicationPath: "m/0'/16'/0'",
47
+ };
48
+ const addMember = jest.fn(() => Promise.resolve(trustchain));
49
+ const memberCredentials = convertKeyPairToLiveCredentials(yield crypto.randomKeypair());
50
+ const memberName = "foo";
51
+ let scannedUrlResolve;
52
+ const scannedUrlPromise = new Promise(resolve => {
53
+ scannedUrlResolve = resolve;
54
+ });
55
+ const onDisplayQRCode = (url) => {
56
+ scannedUrlResolve(url);
57
+ };
58
+ const onRequestQRCodeInput = jest.fn((config, callback) => callback(onDisplayDigits.mock.calls[0][0]));
59
+ const hostP = createQRCodeHostInstance({
60
+ trustchainApiBaseUrl: "ws://localhost:1234",
61
+ onDisplayQRCode,
62
+ onDisplayDigits,
63
+ addMember,
64
+ memberCredentials,
65
+ memberName,
66
+ initialTrustchainId: trustchain.rootId,
67
+ });
68
+ const scannedUrl = yield scannedUrlPromise;
69
+ const candidateP = createQRCodeCandidateInstance({
70
+ memberCredentials,
71
+ memberName,
72
+ initialTrustchainId: undefined,
73
+ addMember,
74
+ scannedUrl,
75
+ onRequestQRCodeInput,
76
+ });
77
+ const [_, res] = yield Promise.all([hostP, candidateP]);
78
+ expect(onDisplayDigits).toHaveBeenCalledWith(expect.any(String));
79
+ expect(addMember).toHaveBeenCalled();
80
+ expect(onRequestQRCodeInput).toHaveBeenCalledWith({ digits: 3, connected: false }, expect.any(Function));
81
+ expect(res).toEqual(trustchain);
82
+ }));
83
+ test("invalid qr code scanned", () => __awaiter(void 0, void 0, void 0, function* () {
84
+ const trustchain = {
85
+ rootId: "test-root-id",
86
+ walletSyncEncryptionKey: "test-wallet-sync-encryption-key",
87
+ applicationPath: "m/0'/16'/0'",
88
+ };
89
+ const addMember = jest.fn(() => Promise.resolve(trustchain));
90
+ const memberCredentials = convertKeyPairToLiveCredentials(yield crypto.randomKeypair());
91
+ const memberName = "foo";
92
+ const onRequestQRCodeInput = jest.fn();
93
+ const scannedUrl = "https://example.com";
94
+ const candidateP = createQRCodeCandidateInstance({
95
+ memberCredentials,
96
+ memberName,
97
+ initialTrustchainId: undefined,
98
+ addMember,
99
+ scannedUrl,
100
+ onRequestQRCodeInput,
101
+ });
102
+ yield expect(candidateP).rejects.toThrow(new ScannedInvalidQrCode());
103
+ }));
104
+ test("old accounts export qr code scanned", () => __awaiter(void 0, void 0, void 0, function* () {
105
+ const trustchain = {
106
+ rootId: "test-root-id",
107
+ walletSyncEncryptionKey: "test-wallet-sync-encryption-key",
108
+ applicationPath: "m/0'/16'/0'",
109
+ };
110
+ const addMember = jest.fn(() => Promise.resolve(trustchain));
111
+ const memberCredentials = convertKeyPairToLiveCredentials(yield crypto.randomKeypair());
112
+ const memberName = "foo";
113
+ const onRequestQRCodeInput = jest.fn();
114
+ const scannedUrl = "ZAADAAIAAAAEd2JXMpuoYdzvkNzFTlmQLPcGf2LSjDOgqaB3nQoZqlimcCX6HNkescWKyT1DCGuwO7IesD7oYg+fdZPkiIfFL3V9swfZRePkaNN09IjXsWLsim9hK/qi/RC1/ofX3hYNKUxUAgYVVG82WKXIk47siWfUlRZsCYSAARQ6ASpUgidPjMHaOMK6w53wTZplwo7Zjv1HrIyKwr3Ci8OmrFye5g==";
115
+ const candidateP = createQRCodeCandidateInstance({
116
+ memberCredentials,
117
+ memberName,
118
+ initialTrustchainId: undefined,
119
+ addMember,
120
+ scannedUrl,
121
+ onRequestQRCodeInput,
122
+ });
123
+ yield expect(candidateP).rejects.toThrow(new ScannedOldImportQrCode());
124
+ }));
125
+ });
126
+ //# sourceMappingURL=index.test.js.map