@ledgerhq/live-wallet 0.2.0 → 0.3.0-next.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 (39) hide show
  1. package/.unimportedrc.json +1 -0
  2. package/CHANGELOG.md +12 -0
  3. package/lib/walletsync/api.d.ts +72 -0
  4. package/lib/walletsync/api.d.ts.map +1 -0
  5. package/lib/walletsync/api.js +98 -0
  6. package/lib/walletsync/api.js.map +1 -0
  7. package/lib/walletsync/datatypes/accounts.d.ts +93 -0
  8. package/lib/walletsync/datatypes/accounts.d.ts.map +1 -0
  9. package/lib/walletsync/datatypes/accounts.js +19 -0
  10. package/lib/walletsync/datatypes/accounts.js.map +1 -0
  11. package/lib/walletsync/index.d.ts +4 -0
  12. package/lib/walletsync/index.d.ts.map +1 -0
  13. package/lib/walletsync/index.js +21 -0
  14. package/lib/walletsync/index.js.map +1 -0
  15. package/lib/walletsync/sdk.d.ts +33 -0
  16. package/lib/walletsync/sdk.d.ts.map +1 -0
  17. package/lib/walletsync/sdk.js +94 -0
  18. package/lib/walletsync/sdk.js.map +1 -0
  19. package/lib-es/walletsync/api.d.ts +72 -0
  20. package/lib-es/walletsync/api.d.ts.map +1 -0
  21. package/lib-es/walletsync/api.js +93 -0
  22. package/lib-es/walletsync/api.js.map +1 -0
  23. package/lib-es/walletsync/datatypes/accounts.d.ts +93 -0
  24. package/lib-es/walletsync/datatypes/accounts.d.ts.map +1 -0
  25. package/lib-es/walletsync/datatypes/accounts.js +16 -0
  26. package/lib-es/walletsync/datatypes/accounts.js.map +1 -0
  27. package/lib-es/walletsync/index.d.ts +4 -0
  28. package/lib-es/walletsync/index.d.ts.map +1 -0
  29. package/lib-es/walletsync/index.js +3 -0
  30. package/lib-es/walletsync/index.js.map +1 -0
  31. package/lib-es/walletsync/sdk.d.ts +33 -0
  32. package/lib-es/walletsync/sdk.d.ts.map +1 -0
  33. package/lib-es/walletsync/sdk.js +87 -0
  34. package/lib-es/walletsync/sdk.js.map +1 -0
  35. package/package.json +14 -9
  36. package/src/walletsync/api.ts +99 -0
  37. package/src/walletsync/datatypes/accounts.ts +21 -0
  38. package/src/walletsync/index.ts +3 -0
  39. package/src/walletsync/sdk.ts +112 -0
@@ -1,5 +1,6 @@
1
1
  {
2
2
  "entry": [
3
+ "src/walletsync/index.ts",
3
4
  "src/liveqr/cross.ts",
4
5
  "src/liveqr/importAccounts.ts",
5
6
  "src/ordering.ts",
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @ledgerhq/live-wallet
2
2
 
3
+ ## 0.3.0-next.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#7079](https://github.com/LedgerHQ/ledger-live/pull/7079) [`9f33fc1`](https://github.com/LedgerHQ/ledger-live/commit/9f33fc14e0628a68d32957171aa879c30041f27e) Thanks [@KVNLS](https://github.com/KVNLS)! - Keep previously renamed accounts alias
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [[`9551536`](https://github.com/LedgerHQ/ledger-live/commit/955153681ebc19344ed5becfbf7b131224b2ebd0), [`cde94b9`](https://github.com/LedgerHQ/ledger-live/commit/cde94b9584d6889849fb097813a5fc11ea19d069), [`785c618`](https://github.com/LedgerHQ/ledger-live/commit/785c6180c2212ca879c2fddb8302f0bab5686761)]:
12
+ - @ledgerhq/types-live@6.48.1-next.0
13
+ - @ledgerhq/coin-framework@0.15.0-next.0
14
+
3
15
  ## 0.2.0
4
16
 
5
17
  ### Minor Changes
@@ -0,0 +1,72 @@
1
+ import z from "zod";
2
+ export type JWT = {
3
+ accessToken: string;
4
+ };
5
+ declare const schemaAtomicGetResponse: z.ZodDiscriminatedUnion<"status", [z.ZodObject<{
6
+ status: z.ZodLiteral<"no-data">;
7
+ }, "strip", z.ZodTypeAny, {
8
+ status: "no-data";
9
+ }, {
10
+ status: "no-data";
11
+ }>, z.ZodObject<{
12
+ status: z.ZodLiteral<"up-to-date">;
13
+ }, "strip", z.ZodTypeAny, {
14
+ status: "up-to-date";
15
+ }, {
16
+ status: "up-to-date";
17
+ }>, z.ZodObject<{
18
+ status: z.ZodLiteral<"out-of-sync">;
19
+ version: z.ZodNumber;
20
+ payload: z.ZodString;
21
+ date: z.ZodString;
22
+ info: z.ZodOptional<z.ZodString>;
23
+ }, "strip", z.ZodTypeAny, {
24
+ payload: string;
25
+ status: "out-of-sync";
26
+ date: string;
27
+ version: number;
28
+ info?: string | undefined;
29
+ }, {
30
+ payload: string;
31
+ status: "out-of-sync";
32
+ date: string;
33
+ version: number;
34
+ info?: string | undefined;
35
+ }>]>;
36
+ export type APISyncResponse = z.infer<typeof schemaAtomicGetResponse>;
37
+ declare const schemaAtomicPostResponse: z.ZodDiscriminatedUnion<"status", [z.ZodObject<{
38
+ status: z.ZodLiteral<"updated">;
39
+ }, "strip", z.ZodTypeAny, {
40
+ status: "updated";
41
+ }, {
42
+ status: "updated";
43
+ }>, z.ZodObject<{
44
+ status: z.ZodLiteral<"out-of-sync">;
45
+ version: z.ZodNumber;
46
+ payload: z.ZodString;
47
+ date: z.ZodString;
48
+ info: z.ZodOptional<z.ZodString>;
49
+ }, "strip", z.ZodTypeAny, {
50
+ payload: string;
51
+ status: "out-of-sync";
52
+ date: string;
53
+ version: number;
54
+ info?: string | undefined;
55
+ }, {
56
+ payload: string;
57
+ status: "out-of-sync";
58
+ date: string;
59
+ version: number;
60
+ info?: string | undefined;
61
+ }>]>;
62
+ export type APISyncUpdateResponse = z.infer<typeof schemaAtomicPostResponse>;
63
+ declare function fetchDataStatus(jwt: JWT, datatype: string, version?: number): Promise<APISyncResponse>;
64
+ declare function uploadData(jwt: JWT, datatype: string, version: number, payload: string): Promise<APISyncUpdateResponse>;
65
+ declare function deleteData(jwt: JWT, datatype: string): Promise<void>;
66
+ declare const _default: {
67
+ fetchDataStatus: typeof fetchDataStatus;
68
+ uploadData: typeof uploadData;
69
+ deleteData: typeof deleteData;
70
+ };
71
+ export default _default;
72
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/walletsync/api.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,KAAK,CAAC;AAIpB,MAAM,MAAM,GAAG,GAAG;IAChB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAeF,QAAA,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAI3B,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAYtE,QAAA,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;IAG5B,CAAC;AAEH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAG7E,iBAAe,eAAe,CAC5B,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,eAAe,CAAC,CAU1B;AAGD,iBAAe,UAAU,CACvB,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,qBAAqB,CAAC,CAahC;AAGD,iBAAe,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQnE;;;;;;AAED,wBAIE"}
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const zod_1 = __importDefault(require("zod"));
16
+ const live_network_1 = __importDefault(require("@ledgerhq/live-network"));
17
+ const live_env_1 = require("@ledgerhq/live-env");
18
+ const schemaAtomicGetNoData = zod_1.default.object({
19
+ status: zod_1.default.literal("no-data"),
20
+ });
21
+ const schemaAtomicGetUpToDate = zod_1.default.object({
22
+ status: zod_1.default.literal("up-to-date"),
23
+ });
24
+ const schemaAtomicGetOutOfSync = zod_1.default.object({
25
+ status: zod_1.default.literal("out-of-sync"),
26
+ version: zod_1.default.number(),
27
+ payload: zod_1.default.string(),
28
+ date: zod_1.default.string(),
29
+ info: zod_1.default.string().optional(),
30
+ });
31
+ const schemaAtomicGetResponse = zod_1.default.discriminatedUnion("status", [
32
+ schemaAtomicGetNoData,
33
+ schemaAtomicGetUpToDate,
34
+ schemaAtomicGetOutOfSync,
35
+ ]);
36
+ const schemaAtomicPostUpdated = zod_1.default.object({
37
+ status: zod_1.default.literal("updated"),
38
+ });
39
+ const schemaAtomicPostOutOfSync = zod_1.default.object({
40
+ status: zod_1.default.literal("out-of-sync"),
41
+ version: zod_1.default.number(),
42
+ payload: zod_1.default.string(),
43
+ date: zod_1.default.string(),
44
+ info: zod_1.default.string().optional(),
45
+ });
46
+ const schemaAtomicPostResponse = zod_1.default.discriminatedUnion("status", [
47
+ schemaAtomicPostUpdated,
48
+ schemaAtomicPostOutOfSync,
49
+ ]);
50
+ // Fetch data status from cloud
51
+ function fetchDataStatus(jwt, datatype, version) {
52
+ return __awaiter(this, void 0, void 0, function* () {
53
+ const { data } = yield (0, live_network_1.default)({
54
+ url: `${(0, live_env_1.getEnv)("WALLET_SYNC_API")}/atomic/v1/${datatype}`,
55
+ method: "GET",
56
+ headers: {
57
+ Authorization: `Bearer ${jwt.accessToken}`,
58
+ },
59
+ params: version !== undefined ? { version } : {},
60
+ });
61
+ return schemaAtomicGetResponse.parse(data);
62
+ });
63
+ }
64
+ // Upload new version of data to cloud
65
+ function uploadData(jwt, datatype, version, payload) {
66
+ return __awaiter(this, void 0, void 0, function* () {
67
+ const { data } = yield (0, live_network_1.default)({
68
+ url: `${(0, live_env_1.getEnv)("WALLET_SYNC_API")}/atomic/v1/${datatype}?version=${version}`,
69
+ method: "POST",
70
+ headers: {
71
+ Authorization: `Bearer ${jwt.accessToken}`,
72
+ "Content-Type": "application/json",
73
+ },
74
+ data: {
75
+ payload,
76
+ },
77
+ });
78
+ return schemaAtomicPostResponse.parse(data);
79
+ });
80
+ }
81
+ // Delete data from cloud
82
+ function deleteData(jwt, datatype) {
83
+ return __awaiter(this, void 0, void 0, function* () {
84
+ yield (0, live_network_1.default)({
85
+ url: `${(0, live_env_1.getEnv)("WALLET_SYNC_API")}/atomic/v1/${datatype}`,
86
+ method: "DELETE",
87
+ headers: {
88
+ Authorization: `Bearer ${jwt.accessToken}`,
89
+ },
90
+ });
91
+ });
92
+ }
93
+ exports.default = {
94
+ fetchDataStatus,
95
+ uploadData,
96
+ deleteData,
97
+ };
98
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/walletsync/api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,93 @@
1
+ import { z } from "zod";
2
+ export declare const accountDescriptorSchema: z.ZodObject<{
3
+ id: z.ZodString;
4
+ currencyId: z.ZodString;
5
+ freshAddress: z.ZodString;
6
+ seedIdentifier: z.ZodString;
7
+ derivationMode: z.ZodString;
8
+ index: z.ZodNumber;
9
+ }, "strip", z.ZodTypeAny, {
10
+ index: number;
11
+ id: string;
12
+ seedIdentifier: string;
13
+ derivationMode: string;
14
+ freshAddress: string;
15
+ currencyId: string;
16
+ }, {
17
+ index: number;
18
+ id: string;
19
+ seedIdentifier: string;
20
+ derivationMode: string;
21
+ freshAddress: string;
22
+ currencyId: string;
23
+ }>;
24
+ export type AccountDescriptor = z.infer<typeof accountDescriptorSchema>;
25
+ export declare const accountsDescriptorSchema: z.ZodArray<z.ZodObject<{
26
+ id: z.ZodString;
27
+ currencyId: z.ZodString;
28
+ freshAddress: z.ZodString;
29
+ seedIdentifier: z.ZodString;
30
+ derivationMode: z.ZodString;
31
+ index: z.ZodNumber;
32
+ }, "strip", z.ZodTypeAny, {
33
+ index: number;
34
+ id: string;
35
+ seedIdentifier: string;
36
+ derivationMode: string;
37
+ freshAddress: string;
38
+ currencyId: string;
39
+ }, {
40
+ index: number;
41
+ id: string;
42
+ seedIdentifier: string;
43
+ derivationMode: string;
44
+ freshAddress: string;
45
+ currencyId: string;
46
+ }>, "many">;
47
+ export declare const schema: z.ZodObject<{
48
+ accounts: z.ZodArray<z.ZodObject<{
49
+ id: z.ZodString;
50
+ currencyId: z.ZodString;
51
+ freshAddress: z.ZodString;
52
+ seedIdentifier: z.ZodString;
53
+ derivationMode: z.ZodString;
54
+ index: z.ZodNumber;
55
+ }, "strip", z.ZodTypeAny, {
56
+ index: number;
57
+ id: string;
58
+ seedIdentifier: string;
59
+ derivationMode: string;
60
+ freshAddress: string;
61
+ currencyId: string;
62
+ }, {
63
+ index: number;
64
+ id: string;
65
+ seedIdentifier: string;
66
+ derivationMode: string;
67
+ freshAddress: string;
68
+ currencyId: string;
69
+ }>, "many">;
70
+ names: z.ZodRecord<z.ZodString, z.ZodString>;
71
+ }, "strip", z.ZodTypeAny, {
72
+ accounts: {
73
+ index: number;
74
+ id: string;
75
+ seedIdentifier: string;
76
+ derivationMode: string;
77
+ freshAddress: string;
78
+ currencyId: string;
79
+ }[];
80
+ names: Record<string, string>;
81
+ }, {
82
+ accounts: {
83
+ index: number;
84
+ id: string;
85
+ seedIdentifier: string;
86
+ derivationMode: string;
87
+ freshAddress: string;
88
+ currencyId: string;
89
+ }[];
90
+ names: Record<string, string>;
91
+ }>;
92
+ export type Data = z.infer<typeof schema>;
93
+ //# sourceMappingURL=accounts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accounts.d.ts","sourceRoot":"","sources":["../../../src/walletsync/datatypes/accounts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;EAOlC,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;WAAmC,CAAC;AAEzE,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAIjB,CAAC;AAEH,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,CAAC"}
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.schema = exports.accountsDescriptorSchema = exports.accountDescriptorSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ exports.accountDescriptorSchema = zod_1.z.object({
6
+ id: zod_1.z.string(),
7
+ currencyId: zod_1.z.string(),
8
+ freshAddress: zod_1.z.string(),
9
+ seedIdentifier: zod_1.z.string(),
10
+ derivationMode: zod_1.z.string(),
11
+ index: zod_1.z.number(),
12
+ });
13
+ exports.accountsDescriptorSchema = zod_1.z.array(exports.accountDescriptorSchema);
14
+ exports.schema = zod_1.z.object({
15
+ accounts: exports.accountsDescriptorSchema,
16
+ names: zod_1.z.record(zod_1.z.string()),
17
+ // NB: append more fields here when we have more needs in the future, but NEVER break a type
18
+ });
19
+ //# sourceMappingURL=accounts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accounts.js","sourceRoot":"","sources":["../../../src/walletsync/datatypes/accounts.ts"],"names":[],"mappings":";;;AAAA,6BAAwB;AAEX,QAAA,uBAAuB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC9C,EAAE,EAAE,OAAC,CAAC,MAAM,EAAE;IACd,UAAU,EAAE,OAAC,CAAC,MAAM,EAAE;IACtB,YAAY,EAAE,OAAC,CAAC,MAAM,EAAE;IACxB,cAAc,EAAE,OAAC,CAAC,MAAM,EAAE;IAC1B,cAAc,EAAE,OAAC,CAAC,MAAM,EAAE;IAC1B,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE;CAClB,CAAC,CAAC;AAGU,QAAA,wBAAwB,GAAG,OAAC,CAAC,KAAK,CAAC,+BAAuB,CAAC,CAAC;AAE5D,QAAA,MAAM,GAAG,OAAC,CAAC,MAAM,CAAC;IAC7B,QAAQ,EAAE,gCAAwB;IAClC,KAAK,EAAE,OAAC,CAAC,MAAM,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC;IAC3B,4FAA4F;CAC7F,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from "./sdk";
2
+ export { schema as accountsSchema } from "./datatypes/accounts";
3
+ export type { Data as AccountsData } from "./datatypes/accounts";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/walletsync/index.ts"],"names":[],"mappings":"AAAA,cAAc,OAAO,CAAC;AACtB,OAAO,EAAE,MAAM,IAAI,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAChE,YAAY,EAAE,IAAI,IAAI,YAAY,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,21 @@
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.accountsSchema = void 0;
18
+ __exportStar(require("./sdk"), exports);
19
+ var accounts_1 = require("./datatypes/accounts");
20
+ Object.defineProperty(exports, "accountsSchema", { enumerable: true, get: function () { return accounts_1.schema; } });
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/walletsync/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,wCAAsB;AACtB,iDAAgE;AAAvD,0GAAA,MAAM,OAAkB"}
@@ -0,0 +1,33 @@
1
+ import { Trustchain, TrustchainSDK } from "@ledgerhq/trustchain/types";
2
+ import { Data } from "./datatypes/accounts";
3
+ import { JWT } from "./api";
4
+ export type UpdateEvent = {
5
+ type: "new-data";
6
+ data: Data;
7
+ version: number;
8
+ } | {
9
+ type: "pushed-data";
10
+ version: number;
11
+ } | {
12
+ type: "deleted-data";
13
+ };
14
+ export declare class WalletSyncSDK {
15
+ trustchainSdk: TrustchainSDK;
16
+ getCurrentVersion: () => number | undefined;
17
+ saveNewUpdate: (updateEvent: UpdateEvent) => Promise<void>;
18
+ constructor({ trustchainSdk, getCurrentVersion, saveNewUpdate, }: {
19
+ trustchainSdk: TrustchainSDK;
20
+ /**
21
+ * returns the current version of the data, if available.
22
+ */
23
+ getCurrentVersion: () => number | undefined;
24
+ /**
25
+ * apply the data over the accounts and we also save the version.
26
+ */
27
+ saveNewUpdate: (event: UpdateEvent) => Promise<void>;
28
+ });
29
+ push(jwt: JWT, trustchain: Trustchain, data: Data): Promise<void>;
30
+ pull(jwt: JWT, trustchain: Trustchain): Promise<void>;
31
+ destroy(jwt: JWT): Promise<void>;
32
+ }
33
+ //# sourceMappingURL=sdk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../../src/walletsync/sdk.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,EAAE,IAAI,EAAU,MAAM,sBAAsB,CAAC;AACpD,OAAY,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAIjC,MAAM,MAAM,WAAW,GACnB;IACE,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,IAAI,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;CACjB,GACD;IACE,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB,GACD;IACE,IAAI,EAAE,cAAc,CAAC;CACtB,CAAC;AAEN,qBAAa,aAAa;IACxB,aAAa,EAAE,aAAa,CAAC;IAC7B,iBAAiB,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IAC5C,aAAa,EAAE,CAAC,WAAW,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;gBAE/C,EACV,aAAa,EACb,iBAAiB,EACjB,aAAa,GACd,EAAE;QACD,aAAa,EAAE,aAAa,CAAC;QAC7B;;WAEG;QACH,iBAAiB,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;QAC5C;;WAEG;QACH,aAAa,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KACtD;IAMK,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BjE,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAkCrD,OAAO,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;CAMvC"}
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.WalletSyncSDK = void 0;
16
+ const accounts_1 = require("./datatypes/accounts");
17
+ const api_1 = __importDefault(require("./api"));
18
+ const base64_js_1 = __importDefault(require("base64-js"));
19
+ const fflate_1 = require("fflate");
20
+ class WalletSyncSDK {
21
+ constructor({ trustchainSdk, getCurrentVersion, saveNewUpdate, }) {
22
+ this.trustchainSdk = trustchainSdk;
23
+ this.getCurrentVersion = getCurrentVersion;
24
+ this.saveNewUpdate = saveNewUpdate;
25
+ }
26
+ push(jwt, trustchain, data) {
27
+ return __awaiter(this, void 0, void 0, function* () {
28
+ const validated = accounts_1.schema.parse(data);
29
+ const json = JSON.stringify(validated);
30
+ const bytes = new TextEncoder().encode(json);
31
+ const compressed = yield new Promise((resolve, reject) => (0, fflate_1.compress)(bytes, (err, result) => (err ? reject(err) : resolve(result))));
32
+ const encrypted = yield this.trustchainSdk.encryptUserData(trustchain, compressed);
33
+ const base64 = base64_js_1.default.fromByteArray(encrypted);
34
+ const version = (this.getCurrentVersion() || 0) + 1;
35
+ const response = yield api_1.default.uploadData(jwt, "accounts", version, base64);
36
+ switch (response.status) {
37
+ case "updated": {
38
+ yield this.saveNewUpdate({
39
+ type: "pushed-data",
40
+ version,
41
+ });
42
+ break;
43
+ }
44
+ case "out-of-sync": {
45
+ // WHAT TO DO? maybe we ignore because in this case we just wait for a pull?
46
+ console.warn("out-of-sync", response);
47
+ }
48
+ }
49
+ });
50
+ }
51
+ pull(jwt, trustchain) {
52
+ return __awaiter(this, void 0, void 0, function* () {
53
+ const response = yield api_1.default.fetchDataStatus(jwt, "accounts", this.getCurrentVersion());
54
+ switch (response.status) {
55
+ case "no-data": {
56
+ // no data, nothing to do
57
+ break;
58
+ }
59
+ case "up-to-date": {
60
+ // already up to date
61
+ break;
62
+ }
63
+ case "out-of-sync": {
64
+ const decrypted = yield this.trustchainSdk
65
+ .decryptUserData(trustchain, base64_js_1.default.toByteArray(response.payload))
66
+ .catch(e => {
67
+ // TODO if we fail to decrypt, it may mean we need to restore trustchain. and if it still fails and on specific error, we will have to eject. figure out how to integrate this in the pull lifecycle.
68
+ throw e;
69
+ });
70
+ const decompressed = yield new Promise((resolve, reject) => (0, fflate_1.decompress)(decrypted, (err, result) => (err ? reject(err) : resolve(result))));
71
+ const json = JSON.parse(new TextDecoder().decode(decompressed));
72
+ const validated = accounts_1.schema.parse(json);
73
+ const version = response.version;
74
+ yield this.saveNewUpdate({
75
+ type: "new-data",
76
+ data: validated,
77
+ version,
78
+ });
79
+ break;
80
+ }
81
+ }
82
+ });
83
+ }
84
+ destroy(jwt) {
85
+ return __awaiter(this, void 0, void 0, function* () {
86
+ yield api_1.default.deleteData(jwt, "accounts");
87
+ yield this.saveNewUpdate({
88
+ type: "deleted-data",
89
+ });
90
+ });
91
+ }
92
+ }
93
+ exports.WalletSyncSDK = WalletSyncSDK;
94
+ //# sourceMappingURL=sdk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdk.js","sourceRoot":"","sources":["../../src/walletsync/sdk.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,72 @@
1
+ import z from "zod";
2
+ export type JWT = {
3
+ accessToken: string;
4
+ };
5
+ declare const schemaAtomicGetResponse: z.ZodDiscriminatedUnion<"status", [z.ZodObject<{
6
+ status: z.ZodLiteral<"no-data">;
7
+ }, "strip", z.ZodTypeAny, {
8
+ status: "no-data";
9
+ }, {
10
+ status: "no-data";
11
+ }>, z.ZodObject<{
12
+ status: z.ZodLiteral<"up-to-date">;
13
+ }, "strip", z.ZodTypeAny, {
14
+ status: "up-to-date";
15
+ }, {
16
+ status: "up-to-date";
17
+ }>, z.ZodObject<{
18
+ status: z.ZodLiteral<"out-of-sync">;
19
+ version: z.ZodNumber;
20
+ payload: z.ZodString;
21
+ date: z.ZodString;
22
+ info: z.ZodOptional<z.ZodString>;
23
+ }, "strip", z.ZodTypeAny, {
24
+ payload: string;
25
+ status: "out-of-sync";
26
+ date: string;
27
+ version: number;
28
+ info?: string | undefined;
29
+ }, {
30
+ payload: string;
31
+ status: "out-of-sync";
32
+ date: string;
33
+ version: number;
34
+ info?: string | undefined;
35
+ }>]>;
36
+ export type APISyncResponse = z.infer<typeof schemaAtomicGetResponse>;
37
+ declare const schemaAtomicPostResponse: z.ZodDiscriminatedUnion<"status", [z.ZodObject<{
38
+ status: z.ZodLiteral<"updated">;
39
+ }, "strip", z.ZodTypeAny, {
40
+ status: "updated";
41
+ }, {
42
+ status: "updated";
43
+ }>, z.ZodObject<{
44
+ status: z.ZodLiteral<"out-of-sync">;
45
+ version: z.ZodNumber;
46
+ payload: z.ZodString;
47
+ date: z.ZodString;
48
+ info: z.ZodOptional<z.ZodString>;
49
+ }, "strip", z.ZodTypeAny, {
50
+ payload: string;
51
+ status: "out-of-sync";
52
+ date: string;
53
+ version: number;
54
+ info?: string | undefined;
55
+ }, {
56
+ payload: string;
57
+ status: "out-of-sync";
58
+ date: string;
59
+ version: number;
60
+ info?: string | undefined;
61
+ }>]>;
62
+ export type APISyncUpdateResponse = z.infer<typeof schemaAtomicPostResponse>;
63
+ declare function fetchDataStatus(jwt: JWT, datatype: string, version?: number): Promise<APISyncResponse>;
64
+ declare function uploadData(jwt: JWT, datatype: string, version: number, payload: string): Promise<APISyncUpdateResponse>;
65
+ declare function deleteData(jwt: JWT, datatype: string): Promise<void>;
66
+ declare const _default: {
67
+ fetchDataStatus: typeof fetchDataStatus;
68
+ uploadData: typeof uploadData;
69
+ deleteData: typeof deleteData;
70
+ };
71
+ export default _default;
72
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/walletsync/api.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,KAAK,CAAC;AAIpB,MAAM,MAAM,GAAG,GAAG;IAChB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAeF,QAAA,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAI3B,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAYtE,QAAA,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;IAG5B,CAAC;AAEH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAG7E,iBAAe,eAAe,CAC5B,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,eAAe,CAAC,CAU1B;AAGD,iBAAe,UAAU,CACvB,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,qBAAqB,CAAC,CAahC;AAGD,iBAAe,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQnE;;;;;;AAED,wBAIE"}
@@ -0,0 +1,93 @@
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 z from "zod";
11
+ import network from "@ledgerhq/live-network";
12
+ import { getEnv } from "@ledgerhq/live-env";
13
+ const schemaAtomicGetNoData = z.object({
14
+ status: z.literal("no-data"),
15
+ });
16
+ const schemaAtomicGetUpToDate = z.object({
17
+ status: z.literal("up-to-date"),
18
+ });
19
+ const schemaAtomicGetOutOfSync = z.object({
20
+ status: z.literal("out-of-sync"),
21
+ version: z.number(),
22
+ payload: z.string(),
23
+ date: z.string(),
24
+ info: z.string().optional(),
25
+ });
26
+ const schemaAtomicGetResponse = z.discriminatedUnion("status", [
27
+ schemaAtomicGetNoData,
28
+ schemaAtomicGetUpToDate,
29
+ schemaAtomicGetOutOfSync,
30
+ ]);
31
+ const schemaAtomicPostUpdated = z.object({
32
+ status: z.literal("updated"),
33
+ });
34
+ const schemaAtomicPostOutOfSync = z.object({
35
+ status: z.literal("out-of-sync"),
36
+ version: z.number(),
37
+ payload: z.string(),
38
+ date: z.string(),
39
+ info: z.string().optional(),
40
+ });
41
+ const schemaAtomicPostResponse = z.discriminatedUnion("status", [
42
+ schemaAtomicPostUpdated,
43
+ schemaAtomicPostOutOfSync,
44
+ ]);
45
+ // Fetch data status from cloud
46
+ function fetchDataStatus(jwt, datatype, version) {
47
+ return __awaiter(this, void 0, void 0, function* () {
48
+ const { data } = yield network({
49
+ url: `${getEnv("WALLET_SYNC_API")}/atomic/v1/${datatype}`,
50
+ method: "GET",
51
+ headers: {
52
+ Authorization: `Bearer ${jwt.accessToken}`,
53
+ },
54
+ params: version !== undefined ? { version } : {},
55
+ });
56
+ return schemaAtomicGetResponse.parse(data);
57
+ });
58
+ }
59
+ // Upload new version of data to cloud
60
+ function uploadData(jwt, datatype, version, payload) {
61
+ return __awaiter(this, void 0, void 0, function* () {
62
+ const { data } = yield network({
63
+ url: `${getEnv("WALLET_SYNC_API")}/atomic/v1/${datatype}?version=${version}`,
64
+ method: "POST",
65
+ headers: {
66
+ Authorization: `Bearer ${jwt.accessToken}`,
67
+ "Content-Type": "application/json",
68
+ },
69
+ data: {
70
+ payload,
71
+ },
72
+ });
73
+ return schemaAtomicPostResponse.parse(data);
74
+ });
75
+ }
76
+ // Delete data from cloud
77
+ function deleteData(jwt, datatype) {
78
+ return __awaiter(this, void 0, void 0, function* () {
79
+ yield network({
80
+ url: `${getEnv("WALLET_SYNC_API")}/atomic/v1/${datatype}`,
81
+ method: "DELETE",
82
+ headers: {
83
+ Authorization: `Bearer ${jwt.accessToken}`,
84
+ },
85
+ });
86
+ });
87
+ }
88
+ export default {
89
+ fetchDataStatus,
90
+ uploadData,
91
+ deleteData,
92
+ };
93
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/walletsync/api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,93 @@
1
+ import { z } from "zod";
2
+ export declare const accountDescriptorSchema: z.ZodObject<{
3
+ id: z.ZodString;
4
+ currencyId: z.ZodString;
5
+ freshAddress: z.ZodString;
6
+ seedIdentifier: z.ZodString;
7
+ derivationMode: z.ZodString;
8
+ index: z.ZodNumber;
9
+ }, "strip", z.ZodTypeAny, {
10
+ index: number;
11
+ id: string;
12
+ seedIdentifier: string;
13
+ derivationMode: string;
14
+ freshAddress: string;
15
+ currencyId: string;
16
+ }, {
17
+ index: number;
18
+ id: string;
19
+ seedIdentifier: string;
20
+ derivationMode: string;
21
+ freshAddress: string;
22
+ currencyId: string;
23
+ }>;
24
+ export type AccountDescriptor = z.infer<typeof accountDescriptorSchema>;
25
+ export declare const accountsDescriptorSchema: z.ZodArray<z.ZodObject<{
26
+ id: z.ZodString;
27
+ currencyId: z.ZodString;
28
+ freshAddress: z.ZodString;
29
+ seedIdentifier: z.ZodString;
30
+ derivationMode: z.ZodString;
31
+ index: z.ZodNumber;
32
+ }, "strip", z.ZodTypeAny, {
33
+ index: number;
34
+ id: string;
35
+ seedIdentifier: string;
36
+ derivationMode: string;
37
+ freshAddress: string;
38
+ currencyId: string;
39
+ }, {
40
+ index: number;
41
+ id: string;
42
+ seedIdentifier: string;
43
+ derivationMode: string;
44
+ freshAddress: string;
45
+ currencyId: string;
46
+ }>, "many">;
47
+ export declare const schema: z.ZodObject<{
48
+ accounts: z.ZodArray<z.ZodObject<{
49
+ id: z.ZodString;
50
+ currencyId: z.ZodString;
51
+ freshAddress: z.ZodString;
52
+ seedIdentifier: z.ZodString;
53
+ derivationMode: z.ZodString;
54
+ index: z.ZodNumber;
55
+ }, "strip", z.ZodTypeAny, {
56
+ index: number;
57
+ id: string;
58
+ seedIdentifier: string;
59
+ derivationMode: string;
60
+ freshAddress: string;
61
+ currencyId: string;
62
+ }, {
63
+ index: number;
64
+ id: string;
65
+ seedIdentifier: string;
66
+ derivationMode: string;
67
+ freshAddress: string;
68
+ currencyId: string;
69
+ }>, "many">;
70
+ names: z.ZodRecord<z.ZodString, z.ZodString>;
71
+ }, "strip", z.ZodTypeAny, {
72
+ accounts: {
73
+ index: number;
74
+ id: string;
75
+ seedIdentifier: string;
76
+ derivationMode: string;
77
+ freshAddress: string;
78
+ currencyId: string;
79
+ }[];
80
+ names: Record<string, string>;
81
+ }, {
82
+ accounts: {
83
+ index: number;
84
+ id: string;
85
+ seedIdentifier: string;
86
+ derivationMode: string;
87
+ freshAddress: string;
88
+ currencyId: string;
89
+ }[];
90
+ names: Record<string, string>;
91
+ }>;
92
+ export type Data = z.infer<typeof schema>;
93
+ //# sourceMappingURL=accounts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accounts.d.ts","sourceRoot":"","sources":["../../../src/walletsync/datatypes/accounts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;EAOlC,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;WAAmC,CAAC;AAEzE,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAIjB,CAAC;AAEH,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { z } from "zod";
2
+ export const accountDescriptorSchema = z.object({
3
+ id: z.string(),
4
+ currencyId: z.string(),
5
+ freshAddress: z.string(),
6
+ seedIdentifier: z.string(),
7
+ derivationMode: z.string(),
8
+ index: z.number(),
9
+ });
10
+ export const accountsDescriptorSchema = z.array(accountDescriptorSchema);
11
+ export const schema = z.object({
12
+ accounts: accountsDescriptorSchema,
13
+ names: z.record(z.string()),
14
+ // NB: append more fields here when we have more needs in the future, but NEVER break a type
15
+ });
16
+ //# sourceMappingURL=accounts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accounts.js","sourceRoot":"","sources":["../../../src/walletsync/datatypes/accounts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9C,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;IACtB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;IACxB,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE;IAC1B,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE;IAC1B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;CAClB,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;AAEzE,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7B,QAAQ,EAAE,wBAAwB;IAClC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAC3B,4FAA4F;CAC7F,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from "./sdk";
2
+ export { schema as accountsSchema } from "./datatypes/accounts";
3
+ export type { Data as AccountsData } from "./datatypes/accounts";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/walletsync/index.ts"],"names":[],"mappings":"AAAA,cAAc,OAAO,CAAC;AACtB,OAAO,EAAE,MAAM,IAAI,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAChE,YAAY,EAAE,IAAI,IAAI,YAAY,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from "./sdk";
2
+ export { schema as accountsSchema } from "./datatypes/accounts";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/walletsync/index.ts"],"names":[],"mappings":"AAAA,cAAc,OAAO,CAAC;AACtB,OAAO,EAAE,MAAM,IAAI,cAAc,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,33 @@
1
+ import { Trustchain, TrustchainSDK } from "@ledgerhq/trustchain/types";
2
+ import { Data } from "./datatypes/accounts";
3
+ import { JWT } from "./api";
4
+ export type UpdateEvent = {
5
+ type: "new-data";
6
+ data: Data;
7
+ version: number;
8
+ } | {
9
+ type: "pushed-data";
10
+ version: number;
11
+ } | {
12
+ type: "deleted-data";
13
+ };
14
+ export declare class WalletSyncSDK {
15
+ trustchainSdk: TrustchainSDK;
16
+ getCurrentVersion: () => number | undefined;
17
+ saveNewUpdate: (updateEvent: UpdateEvent) => Promise<void>;
18
+ constructor({ trustchainSdk, getCurrentVersion, saveNewUpdate, }: {
19
+ trustchainSdk: TrustchainSDK;
20
+ /**
21
+ * returns the current version of the data, if available.
22
+ */
23
+ getCurrentVersion: () => number | undefined;
24
+ /**
25
+ * apply the data over the accounts and we also save the version.
26
+ */
27
+ saveNewUpdate: (event: UpdateEvent) => Promise<void>;
28
+ });
29
+ push(jwt: JWT, trustchain: Trustchain, data: Data): Promise<void>;
30
+ pull(jwt: JWT, trustchain: Trustchain): Promise<void>;
31
+ destroy(jwt: JWT): Promise<void>;
32
+ }
33
+ //# sourceMappingURL=sdk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../../src/walletsync/sdk.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,EAAE,IAAI,EAAU,MAAM,sBAAsB,CAAC;AACpD,OAAY,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAIjC,MAAM,MAAM,WAAW,GACnB;IACE,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,IAAI,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;CACjB,GACD;IACE,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB,GACD;IACE,IAAI,EAAE,cAAc,CAAC;CACtB,CAAC;AAEN,qBAAa,aAAa;IACxB,aAAa,EAAE,aAAa,CAAC;IAC7B,iBAAiB,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IAC5C,aAAa,EAAE,CAAC,WAAW,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;gBAE/C,EACV,aAAa,EACb,iBAAiB,EACjB,aAAa,GACd,EAAE;QACD,aAAa,EAAE,aAAa,CAAC;QAC7B;;WAEG;QACH,iBAAiB,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;QAC5C;;WAEG;QACH,aAAa,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KACtD;IAMK,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BjE,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAkCrD,OAAO,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;CAMvC"}
@@ -0,0 +1,87 @@
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 { schema } from "./datatypes/accounts";
11
+ import api from "./api";
12
+ import Base64 from "base64-js";
13
+ import { compress, decompress } from "fflate";
14
+ export class WalletSyncSDK {
15
+ constructor({ trustchainSdk, getCurrentVersion, saveNewUpdate, }) {
16
+ this.trustchainSdk = trustchainSdk;
17
+ this.getCurrentVersion = getCurrentVersion;
18
+ this.saveNewUpdate = saveNewUpdate;
19
+ }
20
+ push(jwt, trustchain, data) {
21
+ return __awaiter(this, void 0, void 0, function* () {
22
+ const validated = schema.parse(data);
23
+ const json = JSON.stringify(validated);
24
+ const bytes = new TextEncoder().encode(json);
25
+ const compressed = yield new Promise((resolve, reject) => compress(bytes, (err, result) => (err ? reject(err) : resolve(result))));
26
+ const encrypted = yield this.trustchainSdk.encryptUserData(trustchain, compressed);
27
+ const base64 = Base64.fromByteArray(encrypted);
28
+ const version = (this.getCurrentVersion() || 0) + 1;
29
+ const response = yield api.uploadData(jwt, "accounts", version, base64);
30
+ switch (response.status) {
31
+ case "updated": {
32
+ yield this.saveNewUpdate({
33
+ type: "pushed-data",
34
+ version,
35
+ });
36
+ break;
37
+ }
38
+ case "out-of-sync": {
39
+ // WHAT TO DO? maybe we ignore because in this case we just wait for a pull?
40
+ console.warn("out-of-sync", response);
41
+ }
42
+ }
43
+ });
44
+ }
45
+ pull(jwt, trustchain) {
46
+ return __awaiter(this, void 0, void 0, function* () {
47
+ const response = yield api.fetchDataStatus(jwt, "accounts", this.getCurrentVersion());
48
+ switch (response.status) {
49
+ case "no-data": {
50
+ // no data, nothing to do
51
+ break;
52
+ }
53
+ case "up-to-date": {
54
+ // already up to date
55
+ break;
56
+ }
57
+ case "out-of-sync": {
58
+ const decrypted = yield this.trustchainSdk
59
+ .decryptUserData(trustchain, Base64.toByteArray(response.payload))
60
+ .catch(e => {
61
+ // TODO if we fail to decrypt, it may mean we need to restore trustchain. and if it still fails and on specific error, we will have to eject. figure out how to integrate this in the pull lifecycle.
62
+ throw e;
63
+ });
64
+ const decompressed = yield new Promise((resolve, reject) => decompress(decrypted, (err, result) => (err ? reject(err) : resolve(result))));
65
+ const json = JSON.parse(new TextDecoder().decode(decompressed));
66
+ const validated = schema.parse(json);
67
+ const version = response.version;
68
+ yield this.saveNewUpdate({
69
+ type: "new-data",
70
+ data: validated,
71
+ version,
72
+ });
73
+ break;
74
+ }
75
+ }
76
+ });
77
+ }
78
+ destroy(jwt) {
79
+ return __awaiter(this, void 0, void 0, function* () {
80
+ yield api.deleteData(jwt, "accounts");
81
+ yield this.saveNewUpdate({
82
+ type: "deleted-data",
83
+ });
84
+ });
85
+ }
86
+ }
87
+ //# sourceMappingURL=sdk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdk.js","sourceRoot":"","sources":["../../src/walletsync/sdk.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ledgerhq/live-wallet",
3
- "version": "0.2.0",
3
+ "version": "0.3.0-next.0",
4
4
  "description": "Ledger Live wallet",
5
5
  "keywords": [
6
6
  "Ledger"
@@ -22,21 +22,26 @@
22
22
  "license": "Apache-2.0",
23
23
  "dependencies": {
24
24
  "@ledgerhq/compressjs": "github:LedgerHQ/compressjs#d9e8e4d994923e0ea76a32b97289bcccfe71b82e",
25
- "rxjs": "7",
26
- "lodash": "4",
25
+ "base64-js": "1",
27
26
  "bignumber.js": "9",
28
- "@ledgerhq/types-live": "6.48.0",
29
- "@ledgerhq/types-cryptoassets": "7.13.0",
30
- "@ledgerhq/coin-framework": "0.14.0",
27
+ "fflate": "^0.8.2",
28
+ "lodash": "4",
29
+ "rxjs": "7",
30
+ "zod": "^3.22.4",
31
+ "@ledgerhq/coin-framework": "0.15.0-next.0",
32
+ "@ledgerhq/cryptoassets": "13.1.0",
33
+ "@ledgerhq/devices": "8.4.0",
31
34
  "@ledgerhq/live-env": "2.1.0",
35
+ "@ledgerhq/live-network": "1.3.0",
32
36
  "@ledgerhq/live-promise": "0.1.0",
33
37
  "@ledgerhq/logs": "6.12.0",
34
- "@ledgerhq/devices": "8.4.0",
35
- "@ledgerhq/cryptoassets": "13.1.0"
38
+ "@ledgerhq/trustchain": "0.1.1",
39
+ "@ledgerhq/types-cryptoassets": "7.13.0",
40
+ "@ledgerhq/types-live": "6.48.1-next.0"
36
41
  },
37
42
  "devDependencies": {
38
- "@types/lodash": "4",
39
43
  "@types/jest": "^29.5.10",
44
+ "@types/lodash": "4",
40
45
  "jest": "^29.7.0",
41
46
  "ts-jest": "^29.1.1"
42
47
  },
@@ -0,0 +1,99 @@
1
+ import z from "zod";
2
+ import network from "@ledgerhq/live-network";
3
+ import { getEnv } from "@ledgerhq/live-env";
4
+
5
+ export type JWT = {
6
+ accessToken: string;
7
+ };
8
+
9
+ const schemaAtomicGetNoData = z.object({
10
+ status: z.literal("no-data"),
11
+ });
12
+ const schemaAtomicGetUpToDate = z.object({
13
+ status: z.literal("up-to-date"),
14
+ });
15
+ const schemaAtomicGetOutOfSync = z.object({
16
+ status: z.literal("out-of-sync"),
17
+ version: z.number(),
18
+ payload: z.string(),
19
+ date: z.string(),
20
+ info: z.string().optional(),
21
+ });
22
+ const schemaAtomicGetResponse = z.discriminatedUnion("status", [
23
+ schemaAtomicGetNoData,
24
+ schemaAtomicGetUpToDate,
25
+ schemaAtomicGetOutOfSync,
26
+ ]);
27
+ export type APISyncResponse = z.infer<typeof schemaAtomicGetResponse>;
28
+
29
+ const schemaAtomicPostUpdated = z.object({
30
+ status: z.literal("updated"),
31
+ });
32
+ const schemaAtomicPostOutOfSync = z.object({
33
+ status: z.literal("out-of-sync"),
34
+ version: z.number(),
35
+ payload: z.string(),
36
+ date: z.string(),
37
+ info: z.string().optional(),
38
+ });
39
+ const schemaAtomicPostResponse = z.discriminatedUnion("status", [
40
+ schemaAtomicPostUpdated,
41
+ schemaAtomicPostOutOfSync,
42
+ ]);
43
+
44
+ export type APISyncUpdateResponse = z.infer<typeof schemaAtomicPostResponse>;
45
+
46
+ // Fetch data status from cloud
47
+ async function fetchDataStatus(
48
+ jwt: JWT,
49
+ datatype: string,
50
+ version?: number,
51
+ ): Promise<APISyncResponse> {
52
+ const { data } = await network<unknown>({
53
+ url: `${getEnv("WALLET_SYNC_API")}/atomic/v1/${datatype}`,
54
+ method: "GET",
55
+ headers: {
56
+ Authorization: `Bearer ${jwt.accessToken}`,
57
+ },
58
+ params: version !== undefined ? { version } : {},
59
+ });
60
+ return schemaAtomicGetResponse.parse(data);
61
+ }
62
+
63
+ // Upload new version of data to cloud
64
+ async function uploadData(
65
+ jwt: JWT,
66
+ datatype: string,
67
+ version: number,
68
+ payload: string,
69
+ ): Promise<APISyncUpdateResponse> {
70
+ const { data } = await network<unknown>({
71
+ url: `${getEnv("WALLET_SYNC_API")}/atomic/v1/${datatype}?version=${version}`,
72
+ method: "POST",
73
+ headers: {
74
+ Authorization: `Bearer ${jwt.accessToken}`,
75
+ "Content-Type": "application/json",
76
+ },
77
+ data: {
78
+ payload,
79
+ },
80
+ });
81
+ return schemaAtomicPostResponse.parse(data);
82
+ }
83
+
84
+ // Delete data from cloud
85
+ async function deleteData(jwt: JWT, datatype: string): Promise<void> {
86
+ await network<void>({
87
+ url: `${getEnv("WALLET_SYNC_API")}/atomic/v1/${datatype}`,
88
+ method: "DELETE",
89
+ headers: {
90
+ Authorization: `Bearer ${jwt.accessToken}`,
91
+ },
92
+ });
93
+ }
94
+
95
+ export default {
96
+ fetchDataStatus,
97
+ uploadData,
98
+ deleteData,
99
+ };
@@ -0,0 +1,21 @@
1
+ import { z } from "zod";
2
+
3
+ export const accountDescriptorSchema = z.object({
4
+ id: z.string(),
5
+ currencyId: z.string(),
6
+ freshAddress: z.string(),
7
+ seedIdentifier: z.string(),
8
+ derivationMode: z.string(),
9
+ index: z.number(),
10
+ });
11
+ export type AccountDescriptor = z.infer<typeof accountDescriptorSchema>;
12
+
13
+ export const accountsDescriptorSchema = z.array(accountDescriptorSchema);
14
+
15
+ export const schema = z.object({
16
+ accounts: accountsDescriptorSchema,
17
+ names: z.record(z.string()),
18
+ // NB: append more fields here when we have more needs in the future, but NEVER break a type
19
+ });
20
+
21
+ export type Data = z.infer<typeof schema>;
@@ -0,0 +1,3 @@
1
+ export * from "./sdk";
2
+ export { schema as accountsSchema } from "./datatypes/accounts";
3
+ export type { Data as AccountsData } from "./datatypes/accounts";
@@ -0,0 +1,112 @@
1
+ import { Trustchain, TrustchainSDK } from "@ledgerhq/trustchain/types";
2
+ import { Data, schema } from "./datatypes/accounts";
3
+ import api, { JWT } from "./api";
4
+ import Base64 from "base64-js";
5
+ import { compress, decompress } from "fflate";
6
+
7
+ export type UpdateEvent =
8
+ | {
9
+ type: "new-data";
10
+ data: Data;
11
+ version: number;
12
+ }
13
+ | {
14
+ type: "pushed-data";
15
+ version: number;
16
+ }
17
+ | {
18
+ type: "deleted-data";
19
+ };
20
+
21
+ export class WalletSyncSDK {
22
+ trustchainSdk: TrustchainSDK;
23
+ getCurrentVersion: () => number | undefined;
24
+ saveNewUpdate: (updateEvent: UpdateEvent) => Promise<void>;
25
+
26
+ constructor({
27
+ trustchainSdk,
28
+ getCurrentVersion,
29
+ saveNewUpdate,
30
+ }: {
31
+ trustchainSdk: TrustchainSDK;
32
+ /**
33
+ * returns the current version of the data, if available.
34
+ */
35
+ getCurrentVersion: () => number | undefined;
36
+ /**
37
+ * apply the data over the accounts and we also save the version.
38
+ */
39
+ saveNewUpdate: (event: UpdateEvent) => Promise<void>;
40
+ }) {
41
+ this.trustchainSdk = trustchainSdk;
42
+ this.getCurrentVersion = getCurrentVersion;
43
+ this.saveNewUpdate = saveNewUpdate;
44
+ }
45
+
46
+ async push(jwt: JWT, trustchain: Trustchain, data: Data): Promise<void> {
47
+ const validated = schema.parse(data);
48
+ const json = JSON.stringify(validated);
49
+ const bytes = new TextEncoder().encode(json);
50
+ const compressed = await new Promise<Uint8Array>((resolve, reject) =>
51
+ compress(bytes, (err, result) => (err ? reject(err) : resolve(result))),
52
+ );
53
+ const encrypted = await this.trustchainSdk.encryptUserData(trustchain, compressed);
54
+ const base64 = Base64.fromByteArray(encrypted);
55
+ const version = (this.getCurrentVersion() || 0) + 1;
56
+ const response = await api.uploadData(jwt, "accounts", version, base64);
57
+ switch (response.status) {
58
+ case "updated": {
59
+ await this.saveNewUpdate({
60
+ type: "pushed-data",
61
+ version,
62
+ });
63
+ break;
64
+ }
65
+ case "out-of-sync": {
66
+ // WHAT TO DO? maybe we ignore because in this case we just wait for a pull?
67
+ console.warn("out-of-sync", response);
68
+ }
69
+ }
70
+ }
71
+
72
+ async pull(jwt: JWT, trustchain: Trustchain): Promise<void> {
73
+ const response = await api.fetchDataStatus(jwt, "accounts", this.getCurrentVersion());
74
+ switch (response.status) {
75
+ case "no-data": {
76
+ // no data, nothing to do
77
+ break;
78
+ }
79
+ case "up-to-date": {
80
+ // already up to date
81
+ break;
82
+ }
83
+ case "out-of-sync": {
84
+ const decrypted = await this.trustchainSdk
85
+ .decryptUserData(trustchain, Base64.toByteArray(response.payload))
86
+ .catch(e => {
87
+ // TODO if we fail to decrypt, it may mean we need to restore trustchain. and if it still fails and on specific error, we will have to eject. figure out how to integrate this in the pull lifecycle.
88
+ throw e;
89
+ });
90
+ const decompressed = await new Promise<Uint8Array>((resolve, reject) =>
91
+ decompress(decrypted, (err, result) => (err ? reject(err) : resolve(result))),
92
+ );
93
+ const json = JSON.parse(new TextDecoder().decode(decompressed));
94
+ const validated = schema.parse(json);
95
+ const version = response.version;
96
+ await this.saveNewUpdate({
97
+ type: "new-data",
98
+ data: validated,
99
+ version,
100
+ });
101
+ break;
102
+ }
103
+ }
104
+ }
105
+
106
+ async destroy(jwt: JWT): Promise<void> {
107
+ await api.deleteData(jwt, "accounts");
108
+ await this.saveNewUpdate({
109
+ type: "deleted-data",
110
+ });
111
+ }
112
+ }