@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.
- package/.unimportedrc.json +1 -0
- package/CHANGELOG.md +12 -0
- package/lib/walletsync/api.d.ts +72 -0
- package/lib/walletsync/api.d.ts.map +1 -0
- package/lib/walletsync/api.js +98 -0
- package/lib/walletsync/api.js.map +1 -0
- package/lib/walletsync/datatypes/accounts.d.ts +93 -0
- package/lib/walletsync/datatypes/accounts.d.ts.map +1 -0
- package/lib/walletsync/datatypes/accounts.js +19 -0
- package/lib/walletsync/datatypes/accounts.js.map +1 -0
- package/lib/walletsync/index.d.ts +4 -0
- package/lib/walletsync/index.d.ts.map +1 -0
- package/lib/walletsync/index.js +21 -0
- package/lib/walletsync/index.js.map +1 -0
- package/lib/walletsync/sdk.d.ts +33 -0
- package/lib/walletsync/sdk.d.ts.map +1 -0
- package/lib/walletsync/sdk.js +94 -0
- package/lib/walletsync/sdk.js.map +1 -0
- package/lib-es/walletsync/api.d.ts +72 -0
- package/lib-es/walletsync/api.d.ts.map +1 -0
- package/lib-es/walletsync/api.js +93 -0
- package/lib-es/walletsync/api.js.map +1 -0
- package/lib-es/walletsync/datatypes/accounts.d.ts +93 -0
- package/lib-es/walletsync/datatypes/accounts.d.ts.map +1 -0
- package/lib-es/walletsync/datatypes/accounts.js +16 -0
- package/lib-es/walletsync/datatypes/accounts.js.map +1 -0
- package/lib-es/walletsync/index.d.ts +4 -0
- package/lib-es/walletsync/index.d.ts.map +1 -0
- package/lib-es/walletsync/index.js +3 -0
- package/lib-es/walletsync/index.js.map +1 -0
- package/lib-es/walletsync/sdk.d.ts +33 -0
- package/lib-es/walletsync/sdk.d.ts.map +1 -0
- package/lib-es/walletsync/sdk.js +87 -0
- package/lib-es/walletsync/sdk.js.map +1 -0
- package/package.json +14 -9
- package/src/walletsync/api.ts +99 -0
- package/src/walletsync/datatypes/accounts.ts +21 -0
- package/src/walletsync/index.ts +3 -0
- package/src/walletsync/sdk.ts +112 -0
package/.unimportedrc.json
CHANGED
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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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.
|
|
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
|
-
"
|
|
26
|
-
"lodash": "4",
|
|
25
|
+
"base64-js": "1",
|
|
27
26
|
"bignumber.js": "9",
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
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/
|
|
35
|
-
"@ledgerhq/cryptoassets": "13.
|
|
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,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
|
+
}
|