@ledgerhq/hw-transport-vault 1.1.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.
@@ -0,0 +1,4 @@
1
+
2
+ > @ledgerhq/hw-transport-vault@1.0.0 build /home/runner/work/ledger-live/ledger-live/libs/ledgerjs/packages/hw-transport-vault
3
+ > tsc && tsc -m ES6 --outDir lib-es
4
+
package/CHANGELOG.md ADDED
@@ -0,0 +1,12 @@
1
+ # @ledgerhq/hw-transport-vault
2
+
3
+ ## 1.1.0-next.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#3523](https://github.com/LedgerHQ/ledger-live/pull/3523) [`500e36a789`](https://github.com/LedgerHQ/ledger-live/commit/500e36a789b34125164433fbd03c00305669ee4d) Thanks [@drakoFukayu](https://github.com/drakoFukayu)! - feat: LLD allow user to use vault as a signer
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [[`500e36a789`](https://github.com/LedgerHQ/ledger-live/commit/500e36a789b34125164433fbd03c00305669ee4d)]:
12
+ - @ledgerhq/hw-transport-http@6.28.0-next.0
package/README.md ADDED
@@ -0,0 +1,40 @@
1
+ <img src="https://user-images.githubusercontent.com/4631227/191834116-59cf590e-25cc-4956-ae5c-812ea464f324.png" height="100" />
2
+
3
+ ## @ledgerhq/hw-transport-http
4
+
5
+ Library for Ledger Hardware Wallets.
6
+
7
+ [GitHub](https://github.com/LedgerHQ/ledger-live/),
8
+ [Ledger Devs Discord](https://developers.ledger.com/discord-pro),
9
+ [Developer Portal](https://developers.ledger.com/)
10
+
11
+ ## API
12
+
13
+ <!-- Generated by documentation.js. Update this documentation by updating the source code. -->
14
+
15
+ #### Table of Contents
16
+
17
+ - [HttpTransport](#httptransport)
18
+ - [Parameters](#parameters)
19
+ - [WebSocketTransport](#websockettransport)
20
+ - [Parameters](#parameters-1)
21
+
22
+ ### HttpTransport
23
+
24
+ **Extends Transport**
25
+
26
+ HTTP transport implementation
27
+
28
+ #### Parameters
29
+
30
+ - `url` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)**
31
+
32
+ ### WebSocketTransport
33
+
34
+ **Extends Transport**
35
+
36
+ WebSocket transport implementation
37
+
38
+ #### Parameters
39
+
40
+ - `hook` **any**
package/jest.config.ts ADDED
@@ -0,0 +1,6 @@
1
+ import baseConfig from "../../jest.config";
2
+
3
+ export default {
4
+ ...baseConfig,
5
+ rootDir: __dirname,
6
+ };
package/lib/index.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ /// <reference types="node" />
2
+ import WebSocketTransport from "@ledgerhq/hw-transport-http/lib-es/WebSocketTransport";
3
+ type VaultData = {
4
+ token: string;
5
+ workspace: string;
6
+ };
7
+ export default class VaultTransport extends WebSocketTransport {
8
+ protected data: VaultData | null;
9
+ constructor(hook: any);
10
+ setData(data: VaultData): void;
11
+ static open(url: string): Promise<VaultTransport>;
12
+ exchange(apdu: Buffer): Promise<Buffer>;
13
+ }
14
+ export {};
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,kBAAkB,MAAM,uDAAuD,CAAC;AAEvF,KAAK,SAAS,GAAG;IACf,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAIF,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,kBAAkB;IAC5D,SAAS,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAAC;gBAErB,IAAI,EAAE,GAAG;IAKrB,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI;WAIjB,IAAI,CAAC,GAAG,EAAE,MAAM;IAiDvB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAgC9C"}
package/lib/index.js ADDED
@@ -0,0 +1,107 @@
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 logs_1 = require("@ledgerhq/logs");
16
+ const errors_1 = require("@ledgerhq/errors");
17
+ const WebSocketTransport_1 = __importDefault(require("@ledgerhq/hw-transport-http/lib-es/WebSocketTransport"));
18
+ let sessionId = null;
19
+ class VaultTransport extends WebSocketTransport_1.default {
20
+ constructor(hook) {
21
+ super(hook);
22
+ this.data = null;
23
+ }
24
+ setData(data) {
25
+ this.data = data;
26
+ }
27
+ static open(url) {
28
+ return __awaiter(this, void 0, void 0, function* () {
29
+ const exchangeMethods = yield new Promise((resolve, reject) => {
30
+ try {
31
+ const socket = new WebSocket(url);
32
+ const exchangeMethods = {
33
+ resolveExchange: (_b, _sessionId) => { },
34
+ rejectExchange: (_e) => { },
35
+ onDisconnect: () => { },
36
+ close: () => socket.close(),
37
+ send: msg => socket.send(msg),
38
+ };
39
+ socket.onopen = () => {
40
+ socket.send("open");
41
+ };
42
+ socket.onerror = e => {
43
+ exchangeMethods.onDisconnect();
44
+ reject(e);
45
+ };
46
+ socket.onclose = () => {
47
+ exchangeMethods.onDisconnect();
48
+ reject(new errors_1.TransportError("OpenFailed", "OpenFailed"));
49
+ };
50
+ socket.onmessage = e => {
51
+ if (typeof e.data !== "string")
52
+ return;
53
+ const data = JSON.parse(e.data);
54
+ switch (data.type) {
55
+ case "opened":
56
+ return resolve(exchangeMethods);
57
+ case "error":
58
+ reject(new Error(data.error));
59
+ return exchangeMethods.rejectExchange(new errors_1.TransportError(data.error, "WSError"));
60
+ case "response":
61
+ return exchangeMethods.resolveExchange(Buffer.from(data.data, "hex"), data.sessionId);
62
+ }
63
+ };
64
+ }
65
+ catch (e) {
66
+ reject(e);
67
+ }
68
+ });
69
+ return new VaultTransport(exchangeMethods);
70
+ });
71
+ }
72
+ exchange(apdu) {
73
+ return __awaiter(this, void 0, void 0, function* () {
74
+ const hex = apdu.toString("hex");
75
+ (0, logs_1.log)("apdu", "=> " + hex);
76
+ const iv = setInterval(() => {
77
+ this.hook.send("ping");
78
+ }, 30e3);
79
+ try {
80
+ const res = yield new Promise((resolve, reject) => {
81
+ var _a, _c;
82
+ this.hook.rejectExchange = (e) => reject(e);
83
+ this.hook.resolveExchange = (b, _sessionId) => {
84
+ if (_sessionId) {
85
+ sessionId = _sessionId;
86
+ }
87
+ return resolve(b);
88
+ };
89
+ const data = {
90
+ sessionId,
91
+ workspace: (_a = this.data) === null || _a === void 0 ? void 0 : _a.workspace,
92
+ token: (_c = this.data) === null || _c === void 0 ? void 0 : _c.token,
93
+ apdu: hex,
94
+ };
95
+ this.hook.send(JSON.stringify(data));
96
+ });
97
+ (0, logs_1.log)("apdu", "<= " + res.toString("hex"));
98
+ return res;
99
+ }
100
+ finally {
101
+ clearInterval(iv);
102
+ }
103
+ });
104
+ }
105
+ }
106
+ exports.default = VaultTransport;
107
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /// <reference types="node" />
2
+ import WebSocketTransport from "@ledgerhq/hw-transport-http/lib-es/WebSocketTransport";
3
+ type VaultData = {
4
+ token: string;
5
+ workspace: string;
6
+ };
7
+ export default class VaultTransport extends WebSocketTransport {
8
+ protected data: VaultData | null;
9
+ constructor(hook: any);
10
+ setData(data: VaultData): void;
11
+ static open(url: string): Promise<VaultTransport>;
12
+ exchange(apdu: Buffer): Promise<Buffer>;
13
+ }
14
+ export {};
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,kBAAkB,MAAM,uDAAuD,CAAC;AAEvF,KAAK,SAAS,GAAG;IACf,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAIF,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,kBAAkB;IAC5D,SAAS,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAAC;gBAErB,IAAI,EAAE,GAAG;IAKrB,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI;WAIjB,IAAI,CAAC,GAAG,EAAE,MAAM;IAiDvB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAgC9C"}
@@ -0,0 +1,101 @@
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 { log } from "@ledgerhq/logs";
11
+ import { TransportError } from "@ledgerhq/errors";
12
+ import WebSocketTransport from "@ledgerhq/hw-transport-http/lib-es/WebSocketTransport";
13
+ let sessionId = null;
14
+ export default class VaultTransport extends WebSocketTransport {
15
+ constructor(hook) {
16
+ super(hook);
17
+ this.data = null;
18
+ }
19
+ setData(data) {
20
+ this.data = data;
21
+ }
22
+ static open(url) {
23
+ return __awaiter(this, void 0, void 0, function* () {
24
+ const exchangeMethods = yield new Promise((resolve, reject) => {
25
+ try {
26
+ const socket = new WebSocket(url);
27
+ const exchangeMethods = {
28
+ resolveExchange: (_b, _sessionId) => { },
29
+ rejectExchange: (_e) => { },
30
+ onDisconnect: () => { },
31
+ close: () => socket.close(),
32
+ send: msg => socket.send(msg),
33
+ };
34
+ socket.onopen = () => {
35
+ socket.send("open");
36
+ };
37
+ socket.onerror = e => {
38
+ exchangeMethods.onDisconnect();
39
+ reject(e);
40
+ };
41
+ socket.onclose = () => {
42
+ exchangeMethods.onDisconnect();
43
+ reject(new TransportError("OpenFailed", "OpenFailed"));
44
+ };
45
+ socket.onmessage = e => {
46
+ if (typeof e.data !== "string")
47
+ return;
48
+ const data = JSON.parse(e.data);
49
+ switch (data.type) {
50
+ case "opened":
51
+ return resolve(exchangeMethods);
52
+ case "error":
53
+ reject(new Error(data.error));
54
+ return exchangeMethods.rejectExchange(new TransportError(data.error, "WSError"));
55
+ case "response":
56
+ return exchangeMethods.resolveExchange(Buffer.from(data.data, "hex"), data.sessionId);
57
+ }
58
+ };
59
+ }
60
+ catch (e) {
61
+ reject(e);
62
+ }
63
+ });
64
+ return new VaultTransport(exchangeMethods);
65
+ });
66
+ }
67
+ exchange(apdu) {
68
+ return __awaiter(this, void 0, void 0, function* () {
69
+ const hex = apdu.toString("hex");
70
+ log("apdu", "=> " + hex);
71
+ const iv = setInterval(() => {
72
+ this.hook.send("ping");
73
+ }, 30e3);
74
+ try {
75
+ const res = yield new Promise((resolve, reject) => {
76
+ var _a, _c;
77
+ this.hook.rejectExchange = (e) => reject(e);
78
+ this.hook.resolveExchange = (b, _sessionId) => {
79
+ if (_sessionId) {
80
+ sessionId = _sessionId;
81
+ }
82
+ return resolve(b);
83
+ };
84
+ const data = {
85
+ sessionId,
86
+ workspace: (_a = this.data) === null || _a === void 0 ? void 0 : _a.workspace,
87
+ token: (_c = this.data) === null || _c === void 0 ? void 0 : _c.token,
88
+ apdu: hex,
89
+ };
90
+ this.hook.send(JSON.stringify(data));
91
+ });
92
+ log("apdu", "<= " + res.toString("hex"));
93
+ return res;
94
+ }
95
+ finally {
96
+ clearInterval(iv);
97
+ }
98
+ });
99
+ }
100
+ }
101
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "@ledgerhq/hw-transport-vault",
3
+ "version": "1.1.0-next.0",
4
+ "description": "Ledger Vault transport",
5
+ "keywords": [
6
+ "Ledger",
7
+ "Vault",
8
+ "LedgerWallet",
9
+ "proxy",
10
+ "http",
11
+ "wss",
12
+ "sockets"
13
+ ],
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "https://github.com/LedgerHQ/ledger-live.git"
17
+ },
18
+ "bugs": {
19
+ "url": "https://github.com/LedgerHQ/ledger-live/issues"
20
+ },
21
+ "homepage": "https://github.com/LedgerHQ/ledger-live/tree/develop/libs/ledgerjs/packages/hw-transport-vault",
22
+ "publishConfig": {
23
+ "access": "public"
24
+ },
25
+ "main": "lib/index.js",
26
+ "module": "lib-es/index.js",
27
+ "types": "lib/index.d.ts",
28
+ "license": "Apache-2.0",
29
+ "dependencies": {
30
+ "axios": "^0.26.1",
31
+ "ws": "^7.5.2",
32
+ "@ledgerhq/errors": "^6.12.7",
33
+ "@ledgerhq/hw-transport": "^6.28.5",
34
+ "@ledgerhq/hw-transport-http": "^6.28.0-next.0",
35
+ "@ledgerhq/logs": "^6.10.1"
36
+ },
37
+ "devDependencies": {
38
+ "@types/jest": "^29.5.0",
39
+ "@types/node": "^18.15.3",
40
+ "documentation": "13.2.4",
41
+ "jest": "^28.1.1",
42
+ "rimraf": "^4.4.1",
43
+ "source-map-support": "^0.5.21",
44
+ "ts-jest": "^28.0.5",
45
+ "ts-node": "^10.4.0"
46
+ },
47
+ "scripts": {
48
+ "clean": "rimraf lib lib-es",
49
+ "build": "tsc && tsc -m ES6 --outDir lib-es",
50
+ "prewatch": "pnpm build",
51
+ "watch": "tsc --watch",
52
+ "lint": "eslint ./src --no-error-on-unmatched-pattern --ext .ts,.tsx",
53
+ "lint:fix": "pnpm lint --fix",
54
+ "test": "jest"
55
+ }
56
+ }
package/src/index.ts ADDED
@@ -0,0 +1,105 @@
1
+ import { log } from "@ledgerhq/logs";
2
+ import { TransportError } from "@ledgerhq/errors";
3
+ import WebSocketTransport from "@ledgerhq/hw-transport-http/lib-es/WebSocketTransport";
4
+
5
+ type VaultData = {
6
+ token: string;
7
+ workspace: string;
8
+ };
9
+
10
+ let sessionId: string | null = null;
11
+
12
+ export default class VaultTransport extends WebSocketTransport {
13
+ protected data: VaultData | null;
14
+
15
+ constructor(hook: any) {
16
+ super(hook);
17
+ this.data = null;
18
+ }
19
+
20
+ setData(data: VaultData): void {
21
+ this.data = data;
22
+ }
23
+
24
+ static async open(url: string) {
25
+ const exchangeMethods = await new Promise((resolve, reject) => {
26
+ try {
27
+ const socket = new WebSocket(url);
28
+ const exchangeMethods = {
29
+ resolveExchange: (_b: Buffer, _sessionId?: string | null) => {},
30
+ rejectExchange: (_e: any) => {},
31
+ onDisconnect: () => {},
32
+ close: () => socket.close(),
33
+ send: msg => socket.send(msg),
34
+ };
35
+
36
+ socket.onopen = () => {
37
+ socket.send("open");
38
+ };
39
+
40
+ socket.onerror = e => {
41
+ exchangeMethods.onDisconnect();
42
+ reject(e);
43
+ };
44
+
45
+ socket.onclose = () => {
46
+ exchangeMethods.onDisconnect();
47
+ reject(new TransportError("OpenFailed", "OpenFailed"));
48
+ };
49
+
50
+ socket.onmessage = e => {
51
+ if (typeof e.data !== "string") return;
52
+ const data = JSON.parse(e.data);
53
+
54
+ switch (data.type) {
55
+ case "opened":
56
+ return resolve(exchangeMethods);
57
+
58
+ case "error":
59
+ reject(new Error(data.error));
60
+ return exchangeMethods.rejectExchange(new TransportError(data.error, "WSError"));
61
+
62
+ case "response":
63
+ return exchangeMethods.resolveExchange(Buffer.from(data.data, "hex"), data.sessionId);
64
+ }
65
+ };
66
+ } catch (e) {
67
+ reject(e);
68
+ }
69
+ });
70
+ return new VaultTransport(exchangeMethods);
71
+ }
72
+
73
+ async exchange(apdu: Buffer): Promise<Buffer> {
74
+ const hex = apdu.toString("hex");
75
+ log("apdu", "=> " + hex);
76
+
77
+ const iv = setInterval(() => {
78
+ this.hook.send("ping");
79
+ }, 30e3);
80
+
81
+ try {
82
+ const res: Buffer = await new Promise((resolve, reject) => {
83
+ this.hook.rejectExchange = (e: any) => reject(e);
84
+
85
+ this.hook.resolveExchange = (b: Buffer, _sessionId?: string | null) => {
86
+ if (_sessionId) {
87
+ sessionId = _sessionId;
88
+ }
89
+ return resolve(b);
90
+ };
91
+ const data = {
92
+ sessionId,
93
+ workspace: this.data?.workspace,
94
+ token: this.data?.token,
95
+ apdu: hex,
96
+ };
97
+ this.hook.send(JSON.stringify(data));
98
+ });
99
+ log("apdu", "<= " + res.toString("hex"));
100
+ return res;
101
+ } finally {
102
+ clearInterval(iv);
103
+ }
104
+ }
105
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "lib",
5
+ "lib": ["DOM", "ES2017"]
6
+ },
7
+ "include": ["src/**/*"]
8
+ }