@ledgerhq/hw-transport-vault 1.1.0-nightly.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +4 -0
- package/CHANGELOG.md +12 -0
- package/README.md +40 -0
- package/jest.config.ts +6 -0
- package/lib/index.d.ts +15 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +107 -0
- package/lib/index.js.map +1 -0
- package/lib-es/index.d.ts +15 -0
- package/lib-es/index.d.ts.map +1 -0
- package/lib-es/index.js +101 -0
- package/lib-es/index.js.map +1 -0
- package/package.json +56 -0
- package/src/index.ts +105 -0
- package/tsconfig.json +8 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# @ledgerhq/hw-transport-vault
|
|
2
|
+
|
|
3
|
+
## 1.1.0-nightly.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-nightly.1
|
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
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
|
package/lib/index.js.map
ADDED
|
@@ -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"}
|
package/lib-es/index.js
ADDED
|
@@ -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-nightly.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-nightly.0",
|
|
33
|
+
"@ledgerhq/hw-transport": "^6.28.5-nightly.0",
|
|
34
|
+
"@ledgerhq/hw-transport-http": "^6.28.0-nightly.1",
|
|
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
|
+
}
|