@ledgerhq/hw-transport-webhid 6.30.0 → 6.30.1-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/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +9 -0
- package/lib/TransportWebHID.d.ts +1 -0
- package/lib/TransportWebHID.d.ts.map +1 -1
- package/lib/TransportWebHID.js +154 -174
- package/lib/TransportWebHID.js.map +1 -1
- package/lib-es/TransportWebHID.d.ts +1 -0
- package/lib-es/TransportWebHID.d.ts.map +1 -1
- package/lib-es/TransportWebHID.js +155 -176
- package/lib-es/TransportWebHID.js.map +1 -1
- package/package.json +8 -8
package/.turbo/turbo-build.log
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# @ledgerhq/hw-transport-webhid
|
|
2
2
|
|
|
3
|
+
## 6.30.1-next.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [[`107f35a`](https://github.com/LedgerHQ/ledger-live/commit/107f35a0650412716b088a3503b86435e6d9cf47), [`9081c26`](https://github.com/LedgerHQ/ledger-live/commit/9081c2648490f977469a33762a3c67bb2c2a0be5)]:
|
|
8
|
+
- @ledgerhq/errors@6.21.0-next.0
|
|
9
|
+
- @ledgerhq/devices@8.4.5-next.0
|
|
10
|
+
- @ledgerhq/hw-transport@6.31.5-next.0
|
|
11
|
+
|
|
3
12
|
## 6.30.0
|
|
4
13
|
|
|
5
14
|
### Minor Changes
|
package/lib/TransportWebHID.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/// <reference types="w3c-web-hid" />
|
|
2
2
|
/// <reference types="node" />
|
|
3
|
+
/// <reference types="node" />
|
|
3
4
|
import Transport from "@ledgerhq/hw-transport";
|
|
4
5
|
import type { Observer, DescriptorEvent, Subscription } from "@ledgerhq/hw-transport";
|
|
5
6
|
import type { DeviceModel } from "@ledgerhq/devices";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TransportWebHID.d.ts","sourceRoot":"","sources":["../src/TransportWebHID.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TransportWebHID.d.ts","sourceRoot":"","sources":["../src/TransportWebHID.ts"],"names":[],"mappings":";;;AAAA,OAAO,SAAS,MAAM,wBAAwB,CAAC;AAC/C,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAGtF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAgCrD,iBAAe,gBAAgB,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC,CAGtD;AAQD;;;;;;GAMG;AAEH,MAAM,CAAC,OAAO,OAAO,eAAgB,SAAQ,SAAS;IACpD,MAAM,EAAE,SAAS,CAAC;IAClB,WAAW,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,CAAC;IAC5C,OAAO,SAAsC;IAC7C,UAAU,SAAM;gBAEJ,MAAM,EAAE,SAAS;IAQ7B,MAAM,EAAE,MAAM,EAAE,CAAM;IACtB,aAAa,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;IAC3D,IAAI,QAAO,QAAQ,MAAM,CAAC,CAQxB;IACF,aAAa,MAAO,mBAAmB,UASrC;IAEF;;OAEG;IACH,MAAM,CAAC,WAAW,yBAAe;IAEjC;;OAEG;IACH,MAAM,CAAC,IAAI,0BAAoB;IAE/B;;;;;OAKG;IACH,MAAM,CAAC,MAAM,aAAc,SAAS,gBAAgB,SAAS,CAAC,CAAC,KAAG,YAAY,CA+B5E;IAEF;;OAEG;WACU,OAAO;IAKpB;;OAEG;WACU,aAAa;IAM1B;;OAEG;WACU,IAAI,CAAC,MAAM,EAAE,SAAS;IAgBnC,kBAAkB,UAAS;IAC3B,eAAe,MAAO,KAAK,UAIzB;IAEF;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAM5B;;;;OAIG;IACH,QAAQ,SAAgB,MAAM,KAAG,QAAQ,MAAM,CAAC,CA4C9C;IAEF,cAAc;CACf"}
|
package/lib/TransportWebHID.js
CHANGED
|
@@ -1,13 +1,4 @@
|
|
|
1
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
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
4
|
};
|
|
@@ -30,30 +21,24 @@ const getHID = () => {
|
|
|
30
21
|
throw new errors_1.TransportError("navigator.hid is not supported", "HIDNotSupported");
|
|
31
22
|
return hid;
|
|
32
23
|
};
|
|
33
|
-
function requestLedgerDevices() {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
filters: ledgerDevices,
|
|
37
|
-
});
|
|
38
|
-
if (Array.isArray(device))
|
|
39
|
-
return device;
|
|
40
|
-
return [device];
|
|
24
|
+
async function requestLedgerDevices() {
|
|
25
|
+
const device = await getHID().requestDevice({
|
|
26
|
+
filters: ledgerDevices,
|
|
41
27
|
});
|
|
28
|
+
if (Array.isArray(device))
|
|
29
|
+
return device;
|
|
30
|
+
return [device];
|
|
42
31
|
}
|
|
43
|
-
function getLedgerDevices() {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
return devices.filter(d => d.vendorId === devices_1.ledgerUSBVendorId);
|
|
47
|
-
});
|
|
32
|
+
async function getLedgerDevices() {
|
|
33
|
+
const devices = await getHID().getDevices();
|
|
34
|
+
return devices.filter(d => d.vendorId === devices_1.ledgerUSBVendorId);
|
|
48
35
|
}
|
|
49
|
-
function getFirstLedgerDevice() {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
return devices[0];
|
|
56
|
-
});
|
|
36
|
+
async function getFirstLedgerDevice() {
|
|
37
|
+
const existingDevices = await getLedgerDevices();
|
|
38
|
+
if (existingDevices.length > 0)
|
|
39
|
+
return existingDevices[0];
|
|
40
|
+
const devices = await requestLedgerDevices();
|
|
41
|
+
return devices[0];
|
|
57
42
|
}
|
|
58
43
|
/**
|
|
59
44
|
* WebHID Transport implementation
|
|
@@ -63,174 +48,169 @@ function getFirstLedgerDevice() {
|
|
|
63
48
|
* TransportWebHID.create().then(transport => ...)
|
|
64
49
|
*/
|
|
65
50
|
class TransportWebHID extends hw_transport_1.default {
|
|
51
|
+
device;
|
|
52
|
+
deviceModel;
|
|
53
|
+
channel = Math.floor(Math.random() * 0xffff);
|
|
54
|
+
packetSize = 64;
|
|
66
55
|
constructor(device) {
|
|
67
56
|
super();
|
|
68
|
-
this.channel = Math.floor(Math.random() * 0xffff);
|
|
69
|
-
this.packetSize = 64;
|
|
70
|
-
this.inputs = [];
|
|
71
|
-
this.read = () => {
|
|
72
|
-
if (this.inputs.length) {
|
|
73
|
-
return Promise.resolve(this.inputs.shift());
|
|
74
|
-
}
|
|
75
|
-
return new Promise(success => {
|
|
76
|
-
this.inputCallback = success;
|
|
77
|
-
});
|
|
78
|
-
};
|
|
79
|
-
this.onInputReport = (e) => {
|
|
80
|
-
const buffer = Buffer.from(e.data.buffer);
|
|
81
|
-
if (this.inputCallback) {
|
|
82
|
-
this.inputCallback(buffer);
|
|
83
|
-
this.inputCallback = null;
|
|
84
|
-
}
|
|
85
|
-
else {
|
|
86
|
-
this.inputs.push(buffer);
|
|
87
|
-
}
|
|
88
|
-
};
|
|
89
|
-
this._disconnectEmitted = false;
|
|
90
|
-
this._emitDisconnect = (e) => {
|
|
91
|
-
if (this._disconnectEmitted)
|
|
92
|
-
return;
|
|
93
|
-
this._disconnectEmitted = true;
|
|
94
|
-
this.emit("disconnect", e);
|
|
95
|
-
};
|
|
96
|
-
/**
|
|
97
|
-
* Exchange with the device using APDU protocol.
|
|
98
|
-
* @param apdu
|
|
99
|
-
* @returns a promise of apdu response
|
|
100
|
-
*/
|
|
101
|
-
this.exchange = (apdu) => __awaiter(this, void 0, void 0, function* () {
|
|
102
|
-
const b = yield this.exchangeAtomicImpl(() => __awaiter(this, void 0, void 0, function* () {
|
|
103
|
-
const { channel, packetSize } = this;
|
|
104
|
-
(0, logs_1.log)("apdu", "=> " + apdu.toString("hex"));
|
|
105
|
-
const framing = (0, hid_framing_1.default)(channel, packetSize);
|
|
106
|
-
// Write...
|
|
107
|
-
const blocks = framing.makeBlocks(apdu);
|
|
108
|
-
for (let i = 0; i < blocks.length; i++) {
|
|
109
|
-
yield this.device.sendReport(0, blocks[i]);
|
|
110
|
-
}
|
|
111
|
-
// Read...
|
|
112
|
-
let result;
|
|
113
|
-
let acc;
|
|
114
|
-
while (!(result = framing.getReducedResult(acc))) {
|
|
115
|
-
try {
|
|
116
|
-
const buffer = yield this.read();
|
|
117
|
-
acc = framing.reduceResponse(acc, buffer);
|
|
118
|
-
}
|
|
119
|
-
catch (e) {
|
|
120
|
-
if (e instanceof errors_1.TransportError && e.id === "InvalidChannel") {
|
|
121
|
-
// this can happen if the device is connected
|
|
122
|
-
// on a different channel (like another app)
|
|
123
|
-
// in this case we just filter out the event
|
|
124
|
-
continue;
|
|
125
|
-
}
|
|
126
|
-
throw e;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
(0, logs_1.log)("apdu", "<= " + result.toString("hex"));
|
|
130
|
-
return result;
|
|
131
|
-
})).catch(e => {
|
|
132
|
-
if (e && e.message && e.message.includes("write")) {
|
|
133
|
-
this._emitDisconnect(e);
|
|
134
|
-
throw new errors_1.DisconnectedDeviceDuringOperation(e.message);
|
|
135
|
-
}
|
|
136
|
-
throw e;
|
|
137
|
-
});
|
|
138
|
-
return b;
|
|
139
|
-
});
|
|
140
57
|
this.device = device;
|
|
141
58
|
this.deviceModel =
|
|
142
59
|
typeof device.productId === "number" ? (0, devices_1.identifyUSBProductId)(device.productId) : undefined;
|
|
143
60
|
device.addEventListener("inputreport", this.onInputReport);
|
|
144
61
|
}
|
|
62
|
+
inputs = [];
|
|
63
|
+
inputCallback;
|
|
64
|
+
read = () => {
|
|
65
|
+
if (this.inputs.length) {
|
|
66
|
+
return Promise.resolve(this.inputs.shift());
|
|
67
|
+
}
|
|
68
|
+
return new Promise(success => {
|
|
69
|
+
this.inputCallback = success;
|
|
70
|
+
});
|
|
71
|
+
};
|
|
72
|
+
onInputReport = (e) => {
|
|
73
|
+
const buffer = Buffer.from(e.data.buffer);
|
|
74
|
+
if (this.inputCallback) {
|
|
75
|
+
this.inputCallback(buffer);
|
|
76
|
+
this.inputCallback = null;
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
this.inputs.push(buffer);
|
|
80
|
+
}
|
|
81
|
+
};
|
|
145
82
|
/**
|
|
146
|
-
*
|
|
83
|
+
* Check if WebUSB transport is supported.
|
|
84
|
+
*/
|
|
85
|
+
static isSupported = isSupported;
|
|
86
|
+
/**
|
|
87
|
+
* List the WebUSB devices that was previously authorized by the user.
|
|
88
|
+
*/
|
|
89
|
+
static list = getLedgerDevices;
|
|
90
|
+
/**
|
|
91
|
+
* Actively listen to WebUSB devices and emit ONE device
|
|
92
|
+
* that was either accepted before, if not it will trigger the native permission UI.
|
|
93
|
+
*
|
|
94
|
+
* Important: it must be called in the context of a UI click!
|
|
147
95
|
*/
|
|
148
|
-
static
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
96
|
+
static listen = (observer) => {
|
|
97
|
+
let unsubscribed = false;
|
|
98
|
+
getFirstLedgerDevice().then(device => {
|
|
99
|
+
if (!device) {
|
|
100
|
+
observer.error(new errors_1.TransportOpenUserCancelled("Access denied to use Ledger device"));
|
|
101
|
+
}
|
|
102
|
+
else if (!unsubscribed) {
|
|
103
|
+
const deviceModel = typeof device.productId === "number"
|
|
104
|
+
? (0, devices_1.identifyUSBProductId)(device.productId)
|
|
105
|
+
: undefined;
|
|
106
|
+
observer.next({
|
|
107
|
+
type: "add",
|
|
108
|
+
descriptor: device,
|
|
109
|
+
deviceModel,
|
|
110
|
+
});
|
|
111
|
+
observer.complete();
|
|
112
|
+
}
|
|
113
|
+
}, error => {
|
|
114
|
+
observer.error(new errors_1.TransportOpenUserCancelled(error.message));
|
|
152
115
|
});
|
|
116
|
+
function unsubscribe() {
|
|
117
|
+
unsubscribed = true;
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
unsubscribe,
|
|
121
|
+
};
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* Similar to create() except it will always display the device permission (even if some devices are already accepted).
|
|
125
|
+
*/
|
|
126
|
+
static async request() {
|
|
127
|
+
const [device] = await requestLedgerDevices();
|
|
128
|
+
return TransportWebHID.open(device);
|
|
153
129
|
}
|
|
154
130
|
/**
|
|
155
131
|
* Similar to create() except it will never display the device permission (it returns a Promise<?Transport>, null if it fails to find a device).
|
|
156
132
|
*/
|
|
157
|
-
static openConnected() {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
return TransportWebHID.open(devices[0]);
|
|
163
|
-
});
|
|
133
|
+
static async openConnected() {
|
|
134
|
+
const devices = await getLedgerDevices();
|
|
135
|
+
if (devices.length === 0)
|
|
136
|
+
return null;
|
|
137
|
+
return TransportWebHID.open(devices[0]);
|
|
164
138
|
}
|
|
165
139
|
/**
|
|
166
140
|
* Create a Ledger transport with a HIDDevice
|
|
167
141
|
*/
|
|
168
|
-
static open(device) {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
return transport;
|
|
180
|
-
});
|
|
142
|
+
static async open(device) {
|
|
143
|
+
await device.open();
|
|
144
|
+
const transport = new TransportWebHID(device);
|
|
145
|
+
const onDisconnect = e => {
|
|
146
|
+
if (device === e.device) {
|
|
147
|
+
getHID().removeEventListener("disconnect", onDisconnect);
|
|
148
|
+
transport._emitDisconnect(new errors_1.DisconnectedDevice());
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
getHID().addEventListener("disconnect", onDisconnect);
|
|
152
|
+
return transport;
|
|
181
153
|
}
|
|
154
|
+
_disconnectEmitted = false;
|
|
155
|
+
_emitDisconnect = (e) => {
|
|
156
|
+
if (this._disconnectEmitted)
|
|
157
|
+
return;
|
|
158
|
+
this._disconnectEmitted = true;
|
|
159
|
+
this.emit("disconnect", e);
|
|
160
|
+
};
|
|
182
161
|
/**
|
|
183
162
|
* Release the transport device
|
|
184
163
|
*/
|
|
185
|
-
close() {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
yield this.device.close();
|
|
190
|
-
});
|
|
164
|
+
async close() {
|
|
165
|
+
await this.exchangeBusyPromise;
|
|
166
|
+
this.device.removeEventListener("inputreport", this.onInputReport);
|
|
167
|
+
await this.device.close();
|
|
191
168
|
}
|
|
169
|
+
/**
|
|
170
|
+
* Exchange with the device using APDU protocol.
|
|
171
|
+
* @param apdu
|
|
172
|
+
* @returns a promise of apdu response
|
|
173
|
+
*/
|
|
174
|
+
exchange = async (apdu) => {
|
|
175
|
+
const b = await this.exchangeAtomicImpl(async () => {
|
|
176
|
+
const { channel, packetSize } = this;
|
|
177
|
+
(0, logs_1.log)("apdu", "=> " + apdu.toString("hex"));
|
|
178
|
+
const framing = (0, hid_framing_1.default)(channel, packetSize);
|
|
179
|
+
// Write...
|
|
180
|
+
const blocks = framing.makeBlocks(apdu);
|
|
181
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
182
|
+
await this.device.sendReport(0, blocks[i]);
|
|
183
|
+
}
|
|
184
|
+
// Read...
|
|
185
|
+
let result;
|
|
186
|
+
let acc;
|
|
187
|
+
while (!(result = framing.getReducedResult(acc))) {
|
|
188
|
+
try {
|
|
189
|
+
const buffer = await this.read();
|
|
190
|
+
acc = framing.reduceResponse(acc, buffer);
|
|
191
|
+
}
|
|
192
|
+
catch (e) {
|
|
193
|
+
if (e instanceof errors_1.TransportError && e.id === "InvalidChannel") {
|
|
194
|
+
// this can happen if the device is connected
|
|
195
|
+
// on a different channel (like another app)
|
|
196
|
+
// in this case we just filter out the event
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
throw e;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
(0, logs_1.log)("apdu", "<= " + result.toString("hex"));
|
|
203
|
+
return result;
|
|
204
|
+
}).catch(e => {
|
|
205
|
+
if (e && e.message && e.message.includes("write")) {
|
|
206
|
+
this._emitDisconnect(e);
|
|
207
|
+
throw new errors_1.DisconnectedDeviceDuringOperation(e.message);
|
|
208
|
+
}
|
|
209
|
+
throw e;
|
|
210
|
+
});
|
|
211
|
+
return b;
|
|
212
|
+
};
|
|
192
213
|
setScrambleKey() { }
|
|
193
214
|
}
|
|
194
|
-
/**
|
|
195
|
-
* Check if WebUSB transport is supported.
|
|
196
|
-
*/
|
|
197
|
-
TransportWebHID.isSupported = isSupported;
|
|
198
|
-
/**
|
|
199
|
-
* List the WebUSB devices that was previously authorized by the user.
|
|
200
|
-
*/
|
|
201
|
-
TransportWebHID.list = getLedgerDevices;
|
|
202
|
-
/**
|
|
203
|
-
* Actively listen to WebUSB devices and emit ONE device
|
|
204
|
-
* that was either accepted before, if not it will trigger the native permission UI.
|
|
205
|
-
*
|
|
206
|
-
* Important: it must be called in the context of a UI click!
|
|
207
|
-
*/
|
|
208
|
-
TransportWebHID.listen = (observer) => {
|
|
209
|
-
let unsubscribed = false;
|
|
210
|
-
getFirstLedgerDevice().then(device => {
|
|
211
|
-
if (!device) {
|
|
212
|
-
observer.error(new errors_1.TransportOpenUserCancelled("Access denied to use Ledger device"));
|
|
213
|
-
}
|
|
214
|
-
else if (!unsubscribed) {
|
|
215
|
-
const deviceModel = typeof device.productId === "number"
|
|
216
|
-
? (0, devices_1.identifyUSBProductId)(device.productId)
|
|
217
|
-
: undefined;
|
|
218
|
-
observer.next({
|
|
219
|
-
type: "add",
|
|
220
|
-
descriptor: device,
|
|
221
|
-
deviceModel,
|
|
222
|
-
});
|
|
223
|
-
observer.complete();
|
|
224
|
-
}
|
|
225
|
-
}, error => {
|
|
226
|
-
observer.error(new errors_1.TransportOpenUserCancelled(error.message));
|
|
227
|
-
});
|
|
228
|
-
function unsubscribe() {
|
|
229
|
-
unsubscribed = true;
|
|
230
|
-
}
|
|
231
|
-
return {
|
|
232
|
-
unsubscribe,
|
|
233
|
-
};
|
|
234
|
-
};
|
|
235
215
|
exports.default = TransportWebHID;
|
|
236
216
|
//# sourceMappingURL=TransportWebHID.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TransportWebHID.js","sourceRoot":"","sources":["../src/TransportWebHID.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TransportWebHID.js","sourceRoot":"","sources":["../src/TransportWebHID.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/// <reference types="w3c-web-hid" />
|
|
2
2
|
/// <reference types="node" />
|
|
3
|
+
/// <reference types="node" />
|
|
3
4
|
import Transport from "@ledgerhq/hw-transport";
|
|
4
5
|
import type { Observer, DescriptorEvent, Subscription } from "@ledgerhq/hw-transport";
|
|
5
6
|
import type { DeviceModel } from "@ledgerhq/devices";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TransportWebHID.d.ts","sourceRoot":"","sources":["../src/TransportWebHID.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TransportWebHID.d.ts","sourceRoot":"","sources":["../src/TransportWebHID.ts"],"names":[],"mappings":";;;AAAA,OAAO,SAAS,MAAM,wBAAwB,CAAC;AAC/C,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAGtF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAgCrD,iBAAe,gBAAgB,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC,CAGtD;AAQD;;;;;;GAMG;AAEH,MAAM,CAAC,OAAO,OAAO,eAAgB,SAAQ,SAAS;IACpD,MAAM,EAAE,SAAS,CAAC;IAClB,WAAW,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,CAAC;IAC5C,OAAO,SAAsC;IAC7C,UAAU,SAAM;gBAEJ,MAAM,EAAE,SAAS;IAQ7B,MAAM,EAAE,MAAM,EAAE,CAAM;IACtB,aAAa,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;IAC3D,IAAI,QAAO,QAAQ,MAAM,CAAC,CAQxB;IACF,aAAa,MAAO,mBAAmB,UASrC;IAEF;;OAEG;IACH,MAAM,CAAC,WAAW,yBAAe;IAEjC;;OAEG;IACH,MAAM,CAAC,IAAI,0BAAoB;IAE/B;;;;;OAKG;IACH,MAAM,CAAC,MAAM,aAAc,SAAS,gBAAgB,SAAS,CAAC,CAAC,KAAG,YAAY,CA+B5E;IAEF;;OAEG;WACU,OAAO;IAKpB;;OAEG;WACU,aAAa;IAM1B;;OAEG;WACU,IAAI,CAAC,MAAM,EAAE,SAAS;IAgBnC,kBAAkB,UAAS;IAC3B,eAAe,MAAO,KAAK,UAIzB;IAEF;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAM5B;;;;OAIG;IACH,QAAQ,SAAgB,MAAM,KAAG,QAAQ,MAAM,CAAC,CA4C9C;IAEF,cAAc;CACf"}
|
|
@@ -1,12 +1,3 @@
|
|
|
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
1
|
import Transport from "@ledgerhq/hw-transport";
|
|
11
2
|
import hidFraming from "@ledgerhq/devices/hid-framing";
|
|
12
3
|
import { identifyUSBProductId, ledgerUSBVendorId } from "@ledgerhq/devices";
|
|
@@ -25,30 +16,24 @@ const getHID = () => {
|
|
|
25
16
|
throw new TransportError("navigator.hid is not supported", "HIDNotSupported");
|
|
26
17
|
return hid;
|
|
27
18
|
};
|
|
28
|
-
function requestLedgerDevices() {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
filters: ledgerDevices,
|
|
32
|
-
});
|
|
33
|
-
if (Array.isArray(device))
|
|
34
|
-
return device;
|
|
35
|
-
return [device];
|
|
19
|
+
async function requestLedgerDevices() {
|
|
20
|
+
const device = await getHID().requestDevice({
|
|
21
|
+
filters: ledgerDevices,
|
|
36
22
|
});
|
|
23
|
+
if (Array.isArray(device))
|
|
24
|
+
return device;
|
|
25
|
+
return [device];
|
|
37
26
|
}
|
|
38
|
-
function getLedgerDevices() {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
return devices.filter(d => d.vendorId === ledgerUSBVendorId);
|
|
42
|
-
});
|
|
27
|
+
async function getLedgerDevices() {
|
|
28
|
+
const devices = await getHID().getDevices();
|
|
29
|
+
return devices.filter(d => d.vendorId === ledgerUSBVendorId);
|
|
43
30
|
}
|
|
44
|
-
function getFirstLedgerDevice() {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
return devices[0];
|
|
51
|
-
});
|
|
31
|
+
async function getFirstLedgerDevice() {
|
|
32
|
+
const existingDevices = await getLedgerDevices();
|
|
33
|
+
if (existingDevices.length > 0)
|
|
34
|
+
return existingDevices[0];
|
|
35
|
+
const devices = await requestLedgerDevices();
|
|
36
|
+
return devices[0];
|
|
52
37
|
}
|
|
53
38
|
/**
|
|
54
39
|
* WebHID Transport implementation
|
|
@@ -57,175 +42,169 @@ function getFirstLedgerDevice() {
|
|
|
57
42
|
* ...
|
|
58
43
|
* TransportWebHID.create().then(transport => ...)
|
|
59
44
|
*/
|
|
60
|
-
class TransportWebHID extends Transport {
|
|
45
|
+
export default class TransportWebHID extends Transport {
|
|
46
|
+
device;
|
|
47
|
+
deviceModel;
|
|
48
|
+
channel = Math.floor(Math.random() * 0xffff);
|
|
49
|
+
packetSize = 64;
|
|
61
50
|
constructor(device) {
|
|
62
51
|
super();
|
|
63
|
-
this.channel = Math.floor(Math.random() * 0xffff);
|
|
64
|
-
this.packetSize = 64;
|
|
65
|
-
this.inputs = [];
|
|
66
|
-
this.read = () => {
|
|
67
|
-
if (this.inputs.length) {
|
|
68
|
-
return Promise.resolve(this.inputs.shift());
|
|
69
|
-
}
|
|
70
|
-
return new Promise(success => {
|
|
71
|
-
this.inputCallback = success;
|
|
72
|
-
});
|
|
73
|
-
};
|
|
74
|
-
this.onInputReport = (e) => {
|
|
75
|
-
const buffer = Buffer.from(e.data.buffer);
|
|
76
|
-
if (this.inputCallback) {
|
|
77
|
-
this.inputCallback(buffer);
|
|
78
|
-
this.inputCallback = null;
|
|
79
|
-
}
|
|
80
|
-
else {
|
|
81
|
-
this.inputs.push(buffer);
|
|
82
|
-
}
|
|
83
|
-
};
|
|
84
|
-
this._disconnectEmitted = false;
|
|
85
|
-
this._emitDisconnect = (e) => {
|
|
86
|
-
if (this._disconnectEmitted)
|
|
87
|
-
return;
|
|
88
|
-
this._disconnectEmitted = true;
|
|
89
|
-
this.emit("disconnect", e);
|
|
90
|
-
};
|
|
91
|
-
/**
|
|
92
|
-
* Exchange with the device using APDU protocol.
|
|
93
|
-
* @param apdu
|
|
94
|
-
* @returns a promise of apdu response
|
|
95
|
-
*/
|
|
96
|
-
this.exchange = (apdu) => __awaiter(this, void 0, void 0, function* () {
|
|
97
|
-
const b = yield this.exchangeAtomicImpl(() => __awaiter(this, void 0, void 0, function* () {
|
|
98
|
-
const { channel, packetSize } = this;
|
|
99
|
-
log("apdu", "=> " + apdu.toString("hex"));
|
|
100
|
-
const framing = hidFraming(channel, packetSize);
|
|
101
|
-
// Write...
|
|
102
|
-
const blocks = framing.makeBlocks(apdu);
|
|
103
|
-
for (let i = 0; i < blocks.length; i++) {
|
|
104
|
-
yield this.device.sendReport(0, blocks[i]);
|
|
105
|
-
}
|
|
106
|
-
// Read...
|
|
107
|
-
let result;
|
|
108
|
-
let acc;
|
|
109
|
-
while (!(result = framing.getReducedResult(acc))) {
|
|
110
|
-
try {
|
|
111
|
-
const buffer = yield this.read();
|
|
112
|
-
acc = framing.reduceResponse(acc, buffer);
|
|
113
|
-
}
|
|
114
|
-
catch (e) {
|
|
115
|
-
if (e instanceof TransportError && e.id === "InvalidChannel") {
|
|
116
|
-
// this can happen if the device is connected
|
|
117
|
-
// on a different channel (like another app)
|
|
118
|
-
// in this case we just filter out the event
|
|
119
|
-
continue;
|
|
120
|
-
}
|
|
121
|
-
throw e;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
log("apdu", "<= " + result.toString("hex"));
|
|
125
|
-
return result;
|
|
126
|
-
})).catch(e => {
|
|
127
|
-
if (e && e.message && e.message.includes("write")) {
|
|
128
|
-
this._emitDisconnect(e);
|
|
129
|
-
throw new DisconnectedDeviceDuringOperation(e.message);
|
|
130
|
-
}
|
|
131
|
-
throw e;
|
|
132
|
-
});
|
|
133
|
-
return b;
|
|
134
|
-
});
|
|
135
52
|
this.device = device;
|
|
136
53
|
this.deviceModel =
|
|
137
54
|
typeof device.productId === "number" ? identifyUSBProductId(device.productId) : undefined;
|
|
138
55
|
device.addEventListener("inputreport", this.onInputReport);
|
|
139
56
|
}
|
|
57
|
+
inputs = [];
|
|
58
|
+
inputCallback;
|
|
59
|
+
read = () => {
|
|
60
|
+
if (this.inputs.length) {
|
|
61
|
+
return Promise.resolve(this.inputs.shift());
|
|
62
|
+
}
|
|
63
|
+
return new Promise(success => {
|
|
64
|
+
this.inputCallback = success;
|
|
65
|
+
});
|
|
66
|
+
};
|
|
67
|
+
onInputReport = (e) => {
|
|
68
|
+
const buffer = Buffer.from(e.data.buffer);
|
|
69
|
+
if (this.inputCallback) {
|
|
70
|
+
this.inputCallback(buffer);
|
|
71
|
+
this.inputCallback = null;
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
this.inputs.push(buffer);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
140
77
|
/**
|
|
141
|
-
*
|
|
78
|
+
* Check if WebUSB transport is supported.
|
|
79
|
+
*/
|
|
80
|
+
static isSupported = isSupported;
|
|
81
|
+
/**
|
|
82
|
+
* List the WebUSB devices that was previously authorized by the user.
|
|
83
|
+
*/
|
|
84
|
+
static list = getLedgerDevices;
|
|
85
|
+
/**
|
|
86
|
+
* Actively listen to WebUSB devices and emit ONE device
|
|
87
|
+
* that was either accepted before, if not it will trigger the native permission UI.
|
|
88
|
+
*
|
|
89
|
+
* Important: it must be called in the context of a UI click!
|
|
142
90
|
*/
|
|
143
|
-
static
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
91
|
+
static listen = (observer) => {
|
|
92
|
+
let unsubscribed = false;
|
|
93
|
+
getFirstLedgerDevice().then(device => {
|
|
94
|
+
if (!device) {
|
|
95
|
+
observer.error(new TransportOpenUserCancelled("Access denied to use Ledger device"));
|
|
96
|
+
}
|
|
97
|
+
else if (!unsubscribed) {
|
|
98
|
+
const deviceModel = typeof device.productId === "number"
|
|
99
|
+
? identifyUSBProductId(device.productId)
|
|
100
|
+
: undefined;
|
|
101
|
+
observer.next({
|
|
102
|
+
type: "add",
|
|
103
|
+
descriptor: device,
|
|
104
|
+
deviceModel,
|
|
105
|
+
});
|
|
106
|
+
observer.complete();
|
|
107
|
+
}
|
|
108
|
+
}, error => {
|
|
109
|
+
observer.error(new TransportOpenUserCancelled(error.message));
|
|
147
110
|
});
|
|
111
|
+
function unsubscribe() {
|
|
112
|
+
unsubscribed = true;
|
|
113
|
+
}
|
|
114
|
+
return {
|
|
115
|
+
unsubscribe,
|
|
116
|
+
};
|
|
117
|
+
};
|
|
118
|
+
/**
|
|
119
|
+
* Similar to create() except it will always display the device permission (even if some devices are already accepted).
|
|
120
|
+
*/
|
|
121
|
+
static async request() {
|
|
122
|
+
const [device] = await requestLedgerDevices();
|
|
123
|
+
return TransportWebHID.open(device);
|
|
148
124
|
}
|
|
149
125
|
/**
|
|
150
126
|
* Similar to create() except it will never display the device permission (it returns a Promise<?Transport>, null if it fails to find a device).
|
|
151
127
|
*/
|
|
152
|
-
static openConnected() {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
return TransportWebHID.open(devices[0]);
|
|
158
|
-
});
|
|
128
|
+
static async openConnected() {
|
|
129
|
+
const devices = await getLedgerDevices();
|
|
130
|
+
if (devices.length === 0)
|
|
131
|
+
return null;
|
|
132
|
+
return TransportWebHID.open(devices[0]);
|
|
159
133
|
}
|
|
160
134
|
/**
|
|
161
135
|
* Create a Ledger transport with a HIDDevice
|
|
162
136
|
*/
|
|
163
|
-
static open(device) {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
return transport;
|
|
175
|
-
});
|
|
137
|
+
static async open(device) {
|
|
138
|
+
await device.open();
|
|
139
|
+
const transport = new TransportWebHID(device);
|
|
140
|
+
const onDisconnect = e => {
|
|
141
|
+
if (device === e.device) {
|
|
142
|
+
getHID().removeEventListener("disconnect", onDisconnect);
|
|
143
|
+
transport._emitDisconnect(new DisconnectedDevice());
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
getHID().addEventListener("disconnect", onDisconnect);
|
|
147
|
+
return transport;
|
|
176
148
|
}
|
|
149
|
+
_disconnectEmitted = false;
|
|
150
|
+
_emitDisconnect = (e) => {
|
|
151
|
+
if (this._disconnectEmitted)
|
|
152
|
+
return;
|
|
153
|
+
this._disconnectEmitted = true;
|
|
154
|
+
this.emit("disconnect", e);
|
|
155
|
+
};
|
|
177
156
|
/**
|
|
178
157
|
* Release the transport device
|
|
179
158
|
*/
|
|
180
|
-
close() {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
yield this.device.close();
|
|
185
|
-
});
|
|
159
|
+
async close() {
|
|
160
|
+
await this.exchangeBusyPromise;
|
|
161
|
+
this.device.removeEventListener("inputreport", this.onInputReport);
|
|
162
|
+
await this.device.close();
|
|
186
163
|
}
|
|
164
|
+
/**
|
|
165
|
+
* Exchange with the device using APDU protocol.
|
|
166
|
+
* @param apdu
|
|
167
|
+
* @returns a promise of apdu response
|
|
168
|
+
*/
|
|
169
|
+
exchange = async (apdu) => {
|
|
170
|
+
const b = await this.exchangeAtomicImpl(async () => {
|
|
171
|
+
const { channel, packetSize } = this;
|
|
172
|
+
log("apdu", "=> " + apdu.toString("hex"));
|
|
173
|
+
const framing = hidFraming(channel, packetSize);
|
|
174
|
+
// Write...
|
|
175
|
+
const blocks = framing.makeBlocks(apdu);
|
|
176
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
177
|
+
await this.device.sendReport(0, blocks[i]);
|
|
178
|
+
}
|
|
179
|
+
// Read...
|
|
180
|
+
let result;
|
|
181
|
+
let acc;
|
|
182
|
+
while (!(result = framing.getReducedResult(acc))) {
|
|
183
|
+
try {
|
|
184
|
+
const buffer = await this.read();
|
|
185
|
+
acc = framing.reduceResponse(acc, buffer);
|
|
186
|
+
}
|
|
187
|
+
catch (e) {
|
|
188
|
+
if (e instanceof TransportError && e.id === "InvalidChannel") {
|
|
189
|
+
// this can happen if the device is connected
|
|
190
|
+
// on a different channel (like another app)
|
|
191
|
+
// in this case we just filter out the event
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
throw e;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
log("apdu", "<= " + result.toString("hex"));
|
|
198
|
+
return result;
|
|
199
|
+
}).catch(e => {
|
|
200
|
+
if (e && e.message && e.message.includes("write")) {
|
|
201
|
+
this._emitDisconnect(e);
|
|
202
|
+
throw new DisconnectedDeviceDuringOperation(e.message);
|
|
203
|
+
}
|
|
204
|
+
throw e;
|
|
205
|
+
});
|
|
206
|
+
return b;
|
|
207
|
+
};
|
|
187
208
|
setScrambleKey() { }
|
|
188
209
|
}
|
|
189
|
-
/**
|
|
190
|
-
* Check if WebUSB transport is supported.
|
|
191
|
-
*/
|
|
192
|
-
TransportWebHID.isSupported = isSupported;
|
|
193
|
-
/**
|
|
194
|
-
* List the WebUSB devices that was previously authorized by the user.
|
|
195
|
-
*/
|
|
196
|
-
TransportWebHID.list = getLedgerDevices;
|
|
197
|
-
/**
|
|
198
|
-
* Actively listen to WebUSB devices and emit ONE device
|
|
199
|
-
* that was either accepted before, if not it will trigger the native permission UI.
|
|
200
|
-
*
|
|
201
|
-
* Important: it must be called in the context of a UI click!
|
|
202
|
-
*/
|
|
203
|
-
TransportWebHID.listen = (observer) => {
|
|
204
|
-
let unsubscribed = false;
|
|
205
|
-
getFirstLedgerDevice().then(device => {
|
|
206
|
-
if (!device) {
|
|
207
|
-
observer.error(new TransportOpenUserCancelled("Access denied to use Ledger device"));
|
|
208
|
-
}
|
|
209
|
-
else if (!unsubscribed) {
|
|
210
|
-
const deviceModel = typeof device.productId === "number"
|
|
211
|
-
? identifyUSBProductId(device.productId)
|
|
212
|
-
: undefined;
|
|
213
|
-
observer.next({
|
|
214
|
-
type: "add",
|
|
215
|
-
descriptor: device,
|
|
216
|
-
deviceModel,
|
|
217
|
-
});
|
|
218
|
-
observer.complete();
|
|
219
|
-
}
|
|
220
|
-
}, error => {
|
|
221
|
-
observer.error(new TransportOpenUserCancelled(error.message));
|
|
222
|
-
});
|
|
223
|
-
function unsubscribe() {
|
|
224
|
-
unsubscribed = true;
|
|
225
|
-
}
|
|
226
|
-
return {
|
|
227
|
-
unsubscribe,
|
|
228
|
-
};
|
|
229
|
-
};
|
|
230
|
-
export default TransportWebHID;
|
|
231
210
|
//# sourceMappingURL=TransportWebHID.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TransportWebHID.js","sourceRoot":"","sources":["../src/TransportWebHID.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TransportWebHID.js","sourceRoot":"","sources":["../src/TransportWebHID.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ledgerhq/hw-transport-webhid",
|
|
3
|
-
"version": "6.30.0",
|
|
3
|
+
"version": "6.30.1-next.0",
|
|
4
4
|
"description": "Ledger Hardware Wallet WebHID implementation of the communication layer",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Ledger",
|
|
@@ -26,14 +26,14 @@
|
|
|
26
26
|
"types": "lib/TransportWebHID.d.ts",
|
|
27
27
|
"license": "Apache-2.0",
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@ledgerhq/devices": "8.4.
|
|
30
|
-
"@ledgerhq/
|
|
31
|
-
"@ledgerhq/
|
|
32
|
-
"@ledgerhq/
|
|
29
|
+
"@ledgerhq/devices": "8.4.5-next.0",
|
|
30
|
+
"@ledgerhq/logs": "^6.12.0",
|
|
31
|
+
"@ledgerhq/errors": "^6.21.0-next.0",
|
|
32
|
+
"@ledgerhq/hw-transport": "^6.31.5-next.0"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@types/jest": "^29.5.10",
|
|
36
|
-
"@types/node": "^
|
|
36
|
+
"@types/node": "^22.10.10",
|
|
37
37
|
"@types/w3c-web-hid": "^1.0.2",
|
|
38
38
|
"documentation": "14.0.2",
|
|
39
39
|
"jest": "^29.7.0",
|
|
@@ -46,10 +46,10 @@
|
|
|
46
46
|
"scripts": {
|
|
47
47
|
"flow": "flow",
|
|
48
48
|
"clean": "rimraf lib lib-es",
|
|
49
|
-
"build": "tsc && tsc -m
|
|
49
|
+
"build": "tsc && tsc -m esnext --moduleResolution bundler --outDir lib-es",
|
|
50
50
|
"prewatch": "pnpm build",
|
|
51
51
|
"watch": "tsc --watch",
|
|
52
|
-
"watch:es": "tsc --watch -m
|
|
52
|
+
"watch:es": "tsc --watch -m esnext --moduleResolution bundler --outDir lib-es",
|
|
53
53
|
"doc": "documentation readme src/** --section=API --pe ts --re ts --re d.ts",
|
|
54
54
|
"lint": "eslint ./src --no-error-on-unmatched-pattern --ext .ts,.tsx --cache",
|
|
55
55
|
"lint:fix": "pnpm lint --fix",
|