Socket
Socket
Sign inDemoInstall

@ledgerhq/hw-transport-web-ble

Package Overview
Dependencies
5
Maintainers
20
Versions
273
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 6.27.12 to 6.27.15

62

CHANGELOG.md
# @ledgerhq/hw-transport-web-ble
## 6.27.15
### Patch Changes
- Updated dependencies [[`77f990e207`](https://github.com/LedgerHQ/ledger-live/commit/77f990e2075c7c9a4be69b364e3754b449c7a546)]:
- @ledgerhq/errors@6.12.6
- @ledgerhq/devices@8.0.3
- @ledgerhq/hw-transport@6.28.4
## 6.27.15-next.0
### Patch Changes
- Updated dependencies [[`77f990e207`](https://github.com/LedgerHQ/ledger-live/commit/77f990e2075c7c9a4be69b364e3754b449c7a546)]:
- @ledgerhq/errors@6.12.6-next.0
- @ledgerhq/devices@8.0.3-next.0
- @ledgerhq/hw-transport@6.28.4-next.0
## 6.27.14
### Patch Changes
- Updated dependencies [[`87d2349fd8`](https://github.com/LedgerHQ/ledger-live/commit/87d2349fd835e5deb39d1ee8dfcf3539f4195472)]:
- @ledgerhq/errors@6.12.5
- @ledgerhq/devices@8.0.2
- @ledgerhq/hw-transport@6.28.3
## 6.27.14-next.0
### Patch Changes
- Updated dependencies [[`87d2349fd8`](https://github.com/LedgerHQ/ledger-live/commit/87d2349fd835e5deb39d1ee8dfcf3539f4195472)]:
- @ledgerhq/errors@6.12.5-next.0
- @ledgerhq/devices@8.0.2-next.0
- @ledgerhq/hw-transport@6.28.3-next.0
## 6.27.13
### Patch Changes
- Updated dependencies [[`1d0b2d19eb`](https://github.com/LedgerHQ/ledger-live/commit/1d0b2d19ebc5acd058930b842c6d37f8daf2a5a3), [`ef945b05c0`](https://github.com/LedgerHQ/ledger-live/commit/ef945b05c01a791281687abb28e639e1bcc4e472), [`5fa68510b4`](https://github.com/LedgerHQ/ledger-live/commit/5fa68510b49334cfd80c30793dfe68900f1b9b3b)]:
- @ledgerhq/errors@6.12.4
- @ledgerhq/devices@8.0.1
- @ledgerhq/hw-transport@6.28.2
## 6.27.13-next.0
### Patch Changes
- Updated dependencies [[`1d0b2d19eb`](https://github.com/LedgerHQ/ledger-live/commit/1d0b2d19ebc5acd058930b842c6d37f8daf2a5a3), [`ef945b05c0`](https://github.com/LedgerHQ/ledger-live/commit/ef945b05c01a791281687abb28e639e1bcc4e472), [`5fa68510b4`](https://github.com/LedgerHQ/ledger-live/commit/5fa68510b49334cfd80c30793dfe68900f1b9b3b)]:
- @ledgerhq/errors@6.12.4-next.0
- @ledgerhq/devices@8.0.1-next.0
- @ledgerhq/hw-transport@6.28.2-next.0
## 6.27.12

@@ -11,2 +65,10 @@

## 6.27.12-next.0
### Patch Changes
- Updated dependencies [[`62af25493e`](https://github.com/LedgerHQ/ledger-live/commit/62af25493e2becf897d517af42542db208b971c7)]:
- @ledgerhq/devices@8.0.0-next.0
- @ledgerhq/hw-transport@6.28.1-next.0
## 6.27.11

@@ -13,0 +75,0 @@

30

lib-es/monitorCharacteristic.js
import { Observable } from "rxjs";
import { log } from "@ledgerhq/logs";
export var monitorCharacteristic = function (characteristic) {
return Observable.create(function (o) {
log("ble-verbose", "start monitor " + characteristic.uuid);
function onCharacteristicValueChanged(event) {
var characteristic = event.target;
if (characteristic.value) {
o.next(Buffer.from(characteristic.value.buffer));
}
export const monitorCharacteristic = (characteristic) => Observable.create((o) => {
log("ble-verbose", "start monitor " + characteristic.uuid);
function onCharacteristicValueChanged(event) {
const characteristic = event.target;
if (characteristic.value) {
o.next(Buffer.from(characteristic.value.buffer));
}
characteristic.startNotifications().then(function () {
characteristic.addEventListener("characteristicvaluechanged", onCharacteristicValueChanged);
});
return function () {
log("ble-verbose", "end monitor " + characteristic.uuid);
characteristic.stopNotifications();
};
}
characteristic.startNotifications().then(() => {
characteristic.addEventListener("characteristicvaluechanged", onCharacteristicValueChanged);
});
};
return () => {
log("ble-verbose", "end monitor " + characteristic.uuid);
characteristic.stopNotifications();
};
});
//# sourceMappingURL=monitorCharacteristic.js.map

@@ -1,16 +0,1 @@

var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

@@ -25,45 +10,3 @@ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }

};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var _a;
/* eslint-disable prefer-template */

@@ -79,5 +22,5 @@ import Transport from "@ledgerhq/hw-transport";

import { monitorCharacteristic } from "./monitorCharacteristic";
var requiresBluetooth = function () {
const requiresBluetooth = () => {
// $FlowFixMe
var bluetooth = navigator.bluetooth;
const { bluetooth } = navigator;
if (typeof bluetooth === "undefined") {

@@ -88,137 +31,103 @@ throw new Error("web bluetooth not supported");

};
var availability = function () {
return Observable.create(function (observer) {
var bluetooth = requiresBluetooth();
var onAvailabilityChanged = function (e) {
observer.next(e.value);
};
bluetooth.addEventListener("availabilitychanged", onAvailabilityChanged);
var unsubscribed = false;
bluetooth.getAvailability().then(function (available) {
if (!unsubscribed) {
observer.next(available);
}
});
return function () {
unsubscribed = true;
bluetooth.removeEventListener("availabilitychanged", onAvailabilityChanged);
};
});
};
var transportsCache = {};
var requestDeviceParam = function () { return ({
filters: getBluetoothServiceUuids().map(function (uuid) { return ({
services: [uuid]
}); })
}); };
var retrieveService = function (device) { return __awaiter(void 0, void 0, void 0, function () {
var _a, service, infos;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
if (!device.gatt)
throw new Error("bluetooth gatt not found");
return [4 /*yield*/, device.gatt.getPrimaryServices()];
case 1:
_a = __read.apply(void 0, [_b.sent(), 1]), service = _a[0];
if (!service)
throw new Error("bluetooth service not found");
infos = getInfosForServiceUuid(service.uuid);
if (!infos)
throw new Error("bluetooth service infos not found");
return [2 /*return*/, [service, infos]];
const availability = () => Observable.create((observer) => {
const bluetooth = requiresBluetooth();
const onAvailabilityChanged = (e) => {
observer.next(e.value);
};
bluetooth.addEventListener("availabilitychanged", onAvailabilityChanged);
let unsubscribed = false;
bluetooth.getAvailability().then((available) => {
if (!unsubscribed) {
observer.next(available);
}
});
}); };
return () => {
unsubscribed = true;
bluetooth.removeEventListener("availabilitychanged", onAvailabilityChanged);
};
});
const transportsCache = {};
const requestDeviceParam = () => ({
filters: getBluetoothServiceUuids().map((uuid) => ({
services: [uuid],
})),
});
const retrieveService = (device) => __awaiter(void 0, void 0, void 0, function* () {
if (!device.gatt)
throw new Error("bluetooth gatt not found");
const [service] = yield device.gatt.getPrimaryServices();
if (!service)
throw new Error("bluetooth service not found");
const infos = getInfosForServiceUuid(service.uuid);
if (!infos)
throw new Error("bluetooth service infos not found");
return [service, infos];
});
function open(deviceOrId, needsReconnect) {
return __awaiter(this, void 0, void 0, function () {
var device, bluetooth, _a, service, infos, deviceModel, writeUuid, notifyUuid, _b, writeC, notifyC, notifyObservable, notif, transport, onDisconnect, beforeMTUTime, afterMTUTime;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
if (!(typeof deviceOrId === "string")) return [3 /*break*/, 2];
if (transportsCache[deviceOrId]) {
log("ble-verbose", "Transport in cache, using that.");
return [2 /*return*/, transportsCache[deviceOrId]];
}
bluetooth = requiresBluetooth();
return [4 /*yield*/, bluetooth.requestDevice(requestDeviceParam())];
case 1:
// TODO instead we should "query" the device by its ID
device = _c.sent();
return [3 /*break*/, 3];
case 2:
device = deviceOrId;
_c.label = 3;
case 3:
if (!!device.gatt.connected) return [3 /*break*/, 5];
log("ble-verbose", "not connected. connecting...");
return [4 /*yield*/, device.gatt.connect()];
case 4:
_c.sent();
_c.label = 5;
case 5: return [4 /*yield*/, retrieveService(device)];
case 6:
_a = __read.apply(void 0, [_c.sent(), 2]), service = _a[0], infos = _a[1];
deviceModel = infos.deviceModel, writeUuid = infos.writeUuid, notifyUuid = infos.notifyUuid;
return [4 /*yield*/, Promise.all([
service.getCharacteristic(writeUuid),
service.getCharacteristic(notifyUuid),
])];
case 7:
_b = __read.apply(void 0, [_c.sent(), 2]), writeC = _b[0], notifyC = _b[1];
notifyObservable = monitorCharacteristic(notifyC).pipe(tap(function (value) {
log("ble-frame", "<= " + value.toString("hex"));
}), share());
notif = notifyObservable.subscribe();
transport = new BluetoothTransport(device, writeC, notifyObservable, deviceModel);
if (!device.gatt.connected) {
throw new DisconnectedDevice();
}
// eslint-disable-next-line require-atomic-updates
transportsCache[transport.id] = transport;
onDisconnect = function (e) {
console.log("onDisconnect!", e);
delete transportsCache[transport.id];
transport.notYetDisconnected = false;
notif.unsubscribe();
device.removeEventListener("gattserverdisconnected", onDisconnect);
log("ble-verbose", "BleTransport(".concat(transport.id, ") disconnected"));
transport.emit("disconnect", e);
};
device.addEventListener("gattserverdisconnected", onDisconnect);
beforeMTUTime = Date.now();
_c.label = 8;
case 8:
_c.trys.push([8, , 10, 14]);
return [4 /*yield*/, transport.inferMTU()];
case 9:
_c.sent();
return [3 /*break*/, 14];
case 10:
afterMTUTime = Date.now();
// workaround for #279: we need to open() again if we come the first time here,
// to make sure we do a disconnect() after the first pairing time
// because of a firmware bug
if (afterMTUTime - beforeMTUTime < 1000) {
needsReconnect = false; // (optim) there is likely no new pairing done because mtu answer was fast.
}
if (!needsReconnect) return [3 /*break*/, 13];
return [4 /*yield*/, device.gatt.disconnect()];
case 11:
_c.sent();
// necessary time for the bonding workaround
return [4 /*yield*/, new Promise(function (s) { return setTimeout(s, 4000); })];
case 12:
// necessary time for the bonding workaround
_c.sent();
_c.label = 13;
case 13: return [7 /*endfinally*/];
case 14:
if (needsReconnect) {
return [2 /*return*/, open(device, false)];
}
return [2 /*return*/, transport];
return __awaiter(this, void 0, void 0, function* () {
let device;
if (typeof deviceOrId === "string") {
if (transportsCache[deviceOrId]) {
log("ble-verbose", "Transport in cache, using that.");
return transportsCache[deviceOrId];
}
});
const bluetooth = requiresBluetooth();
// TODO instead we should "query" the device by its ID
device = yield bluetooth.requestDevice(requestDeviceParam());
}
else {
device = deviceOrId;
}
if (!device.gatt.connected) {
log("ble-verbose", "not connected. connecting...");
yield device.gatt.connect();
}
const [service, infos] = yield retrieveService(device);
const { deviceModel, writeUuid, notifyUuid } = infos;
const [writeC, notifyC] = yield Promise.all([
service.getCharacteristic(writeUuid),
service.getCharacteristic(notifyUuid),
]);
const notifyObservable = monitorCharacteristic(notifyC).pipe(tap((value) => {
log("ble-frame", "<= " + value.toString("hex"));
}), share());
const notif = notifyObservable.subscribe();
const transport = new BluetoothTransport(device, writeC, notifyObservable, deviceModel);
if (!device.gatt.connected) {
throw new DisconnectedDevice();
}
// eslint-disable-next-line require-atomic-updates
transportsCache[transport.id] = transport;
const onDisconnect = (e) => {
console.log("onDisconnect!", e);
delete transportsCache[transport.id];
transport.notYetDisconnected = false;
notif.unsubscribe();
device.removeEventListener("gattserverdisconnected", onDisconnect);
log("ble-verbose", `BleTransport(${transport.id}) disconnected`);
transport.emit("disconnect", e);
};
device.addEventListener("gattserverdisconnected", onDisconnect);
const beforeMTUTime = Date.now();
try {
yield transport.inferMTU();
}
finally {
const afterMTUTime = Date.now();
// workaround for #279: we need to open() again if we come the first time here,
// to make sure we do a disconnect() after the first pairing time
// because of a firmware bug
if (afterMTUTime - beforeMTUTime < 1000) {
needsReconnect = false; // (optim) there is likely no new pairing done because mtu answer was fast.
}
if (needsReconnect) {
yield device.gatt.disconnect();
// necessary time for the bonding workaround
yield new Promise((s) => setTimeout(s, 4000));
}
}
if (needsReconnect) {
return open(device, false);
}
return transport;
});

@@ -231,28 +140,3 @@ }

*/
var BluetoothTransport = /** @class */ (function (_super) {
__extends(BluetoothTransport, _super);
function BluetoothTransport(device, writeCharacteristic, notifyObservable, deviceModel) {
var _this = _super.call(this) || this;
_this.mtuSize = 20;
_this.notYetDisconnected = true;
_this.write = function (buffer) { return __awaiter(_this, void 0, void 0, function () {
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
log("ble-frame", "=> " + buffer.toString("hex"));
return [4 /*yield*/, this.writeCharacteristic.writeValue(buffer)];
case 1:
_b.sent();
return [2 /*return*/];
}
});
}); };
_this.id = device.id;
_this.device = device;
_this.writeCharacteristic = writeCharacteristic;
_this.notifyObservable = notifyObservable;
_this.deviceModel = deviceModel;
log("ble-verbose", "BleTransport(".concat(String(_this.id), ") new instance"));
return _this;
}
export default class BluetoothTransport extends Transport {
/**

@@ -262,15 +146,15 @@ * Scan for Ledger Bluetooth devices.

*/
BluetoothTransport.listen = function (observer) {
static listen(observer) {
log("ble-verbose", "listen...");
var unsubscribed;
var bluetooth = requiresBluetooth();
bluetooth.requestDevice(requestDeviceParam()).then(function (device) {
let unsubscribed;
const bluetooth = requiresBluetooth();
bluetooth.requestDevice(requestDeviceParam()).then((device) => {
if (!unsubscribed) {
observer.next({
type: "add",
descriptor: device
descriptor: device,
});
observer.complete();
}
}, function (error) {
}, (error) => {
observer.error(new TransportOpenUserCancelled(error.message));

@@ -282,56 +166,50 @@ });

return {
unsubscribe: unsubscribe
unsubscribe,
};
};
}
/**
* open a bluetooth device.
*/
BluetoothTransport.open = function (deviceOrId) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_b) {
return [2 /*return*/, open(deviceOrId, true)];
});
static open(deviceOrId) {
return __awaiter(this, void 0, void 0, function* () {
return open(deviceOrId, true);
});
};
BluetoothTransport.prototype.inferMTU = function () {
return __awaiter(this, void 0, void 0, function () {
var mtu, mtuSize;
var _this = this;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
mtu = 23;
return [4 /*yield*/, this.exchangeAtomicImpl(function () { return __awaiter(_this, void 0, void 0, function () {
var e_1;
var _this = this;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
_b.trys.push([0, 2, , 3]);
return [4 /*yield*/, merge(this.notifyObservable.pipe(first(function (buffer) { return buffer.readUInt8(0) === 0x08; }), map(function (buffer) { return buffer.readUInt8(5); })), defer(function () { return from(_this.write(Buffer.from([0x08, 0, 0, 0, 0]))); }).pipe(ignoreElements())).toPromise()];
case 1:
mtu =
(_b.sent()) + 3;
return [3 /*break*/, 3];
case 2:
e_1 = _b.sent();
log("ble-error", "inferMTU got " + String(e_1));
this.device.gatt.disconnect();
throw e_1;
case 3: return [2 /*return*/];
}
});
}); })];
case 1:
_b.sent();
if (mtu > 23) {
mtuSize = mtu - 3;
log("ble-verbose", "BleTransport(".concat(String(this.id), ") mtu set to ").concat(String(mtuSize)));
this.mtuSize = mtuSize;
}
return [2 /*return*/, this.mtuSize];
}
constructor(device, writeCharacteristic, notifyObservable, deviceModel) {
super();
this.mtuSize = 20;
this.notYetDisconnected = true;
this.write = (buffer) => __awaiter(this, void 0, void 0, function* () {
log("ble-frame", "=> " + buffer.toString("hex"));
yield this.writeCharacteristic.writeValue(buffer);
});
this.id = device.id;
this.device = device;
this.writeCharacteristic = writeCharacteristic;
this.notifyObservable = notifyObservable;
this.deviceModel = deviceModel;
log("ble-verbose", `BleTransport(${String(this.id)}) new instance`);
}
inferMTU() {
return __awaiter(this, void 0, void 0, function* () {
let mtu = 23;
yield this.exchangeAtomicImpl(() => __awaiter(this, void 0, void 0, function* () {
try {
mtu =
(yield merge(this.notifyObservable.pipe(first((buffer) => buffer.readUInt8(0) === 0x08), map((buffer) => buffer.readUInt8(5))), defer(() => from(this.write(Buffer.from([0x08, 0, 0, 0, 0])))).pipe(ignoreElements())).toPromise()) + 3;
}
});
catch (e) {
log("ble-error", "inferMTU got " + String(e));
this.device.gatt.disconnect();
throw e;
}
}));
if (mtu > 23) {
const mtuSize = mtu - 3;
log("ble-verbose", `BleTransport(${String(this.id)}) mtu set to ${String(mtuSize)}`);
this.mtuSize = mtuSize;
}
return this.mtuSize;
});
};
}
/**

@@ -342,90 +220,55 @@ * Exchange with the device using APDU protocol.

*/
BluetoothTransport.prototype.exchange = function (apdu) {
return __awaiter(this, void 0, void 0, function () {
var b;
var _this = this;
return __generator(this, function (_b) {
switch (_b.label) {
case 0: return [4 /*yield*/, this.exchangeAtomicImpl(function () { return __awaiter(_this, void 0, void 0, function () {
var msgIn, data, msgOut, e_2;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
_b.trys.push([0, 2, , 3]);
msgIn = apdu.toString("hex");
log("apdu", "=> ".concat(msgIn));
return [4 /*yield*/, merge(this.notifyObservable.pipe(receiveAPDU), sendAPDU(this.write, apdu, this.mtuSize)).toPromise()];
case 1:
data = _b.sent();
msgOut = data.toString("hex");
log("apdu", "<= ".concat(msgOut));
return [2 /*return*/, data];
case 2:
e_2 = _b.sent();
log("ble-error", "exchange got " + String(e_2));
if (this.notYetDisconnected) {
// in such case we will always disconnect because something is bad.
this.device.gatt.disconnect();
}
throw e_2;
case 3: return [2 /*return*/];
}
});
}); })];
case 1:
b = _b.sent();
return [2 /*return*/, b];
exchange(apdu) {
return __awaiter(this, void 0, void 0, function* () {
const b = yield this.exchangeAtomicImpl(() => __awaiter(this, void 0, void 0, function* () {
try {
const msgIn = apdu.toString("hex");
log("apdu", `=> ${msgIn}`);
const data = yield merge(this.notifyObservable.pipe(receiveAPDU), sendAPDU(this.write, apdu, this.mtuSize)).toPromise();
const msgOut = data.toString("hex");
log("apdu", `<= ${msgOut}`);
return data;
}
});
});
};
BluetoothTransport.prototype.setScrambleKey = function () { };
BluetoothTransport.prototype.close = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
if (!this.exchangeBusyPromise) return [3 /*break*/, 2];
return [4 /*yield*/, this.exchangeBusyPromise];
case 1:
_b.sent();
_b.label = 2;
case 2: return [2 /*return*/];
catch (e) {
log("ble-error", "exchange got " + String(e));
if (this.notYetDisconnected) {
// in such case we will always disconnect because something is bad.
this.device.gatt.disconnect();
}
throw e;
}
});
}));
return b;
});
};
var _a;
_a = BluetoothTransport;
BluetoothTransport.isSupported = function () {
return Promise.resolve()
.then(requiresBluetooth)
.then(function () { return true; }, function () { return false; });
};
/**
* observe event with { available: bool, type: string }
* (available is generic, type is specific)
* an event is emit once and then each time it changes
*/
BluetoothTransport.observeAvailability = function (observer) {
return availability().subscribe(observer);
};
BluetoothTransport.list = function () { return Promise.resolve([]); };
/**
* globally disconnect a bluetooth device by its id.
*/
BluetoothTransport.disconnect = function (id) { return __awaiter(void 0, void 0, void 0, function () {
var transport;
return __generator(_a, function (_b) {
log("ble-verbose", "user disconnect(".concat(id, ")"));
transport = transportsCache[id];
if (transport) {
transport.device.gatt.disconnect();
}
setScrambleKey() { }
close() {
return __awaiter(this, void 0, void 0, function* () {
if (this.exchangeBusyPromise) {
yield this.exchangeBusyPromise;
}
return [2 /*return*/];
});
}); };
return BluetoothTransport;
}(Transport));
export default BluetoothTransport;
}
}
_a = BluetoothTransport;
BluetoothTransport.isSupported = () => Promise.resolve()
.then(requiresBluetooth)
.then(() => true, () => false);
/**
* observe event with { available: bool, type: string }
* (available is generic, type is specific)
* an event is emit once and then each time it changes
*/
BluetoothTransport.observeAvailability = (observer) => availability().subscribe(observer);
BluetoothTransport.list = () => Promise.resolve([]);
/**
* globally disconnect a bluetooth device by its id.
*/
BluetoothTransport.disconnect = (id) => __awaiter(void 0, void 0, void 0, function* () {
log("ble-verbose", `user disconnect(${id})`);
const transport = transportsCache[id];
if (transport) {
transport.device.gatt.disconnect();
}
});
//# sourceMappingURL=TransportWebBLE.js.map

@@ -1,3 +0,3 @@

export declare type Device = Record<string, any>;
export declare type Characteristic = Record<string, any>;
export type Device = Record<string, any>;
export type Characteristic = Record<string, any>;
//# sourceMappingURL=types.d.ts.map
"use strict";
exports.__esModule = true;
Object.defineProperty(exports, "__esModule", { value: true });
exports.monitorCharacteristic = void 0;
var rxjs_1 = require("rxjs");
var logs_1 = require("@ledgerhq/logs");
var monitorCharacteristic = function (characteristic) {
return rxjs_1.Observable.create(function (o) {
(0, logs_1.log)("ble-verbose", "start monitor " + characteristic.uuid);
function onCharacteristicValueChanged(event) {
var characteristic = event.target;
if (characteristic.value) {
o.next(Buffer.from(characteristic.value.buffer));
}
const rxjs_1 = require("rxjs");
const logs_1 = require("@ledgerhq/logs");
const monitorCharacteristic = (characteristic) => rxjs_1.Observable.create((o) => {
(0, logs_1.log)("ble-verbose", "start monitor " + characteristic.uuid);
function onCharacteristicValueChanged(event) {
const characteristic = event.target;
if (characteristic.value) {
o.next(Buffer.from(characteristic.value.buffer));
}
characteristic.startNotifications().then(function () {
characteristic.addEventListener("characteristicvaluechanged", onCharacteristicValueChanged);
});
return function () {
(0, logs_1.log)("ble-verbose", "end monitor " + characteristic.uuid);
characteristic.stopNotifications();
};
}
characteristic.startNotifications().then(() => {
characteristic.addEventListener("characteristicvaluechanged", onCharacteristicValueChanged);
});
};
return () => {
(0, logs_1.log)("ble-verbose", "end monitor " + characteristic.uuid);
characteristic.stopNotifications();
};
});
exports.monitorCharacteristic = monitorCharacteristic;
//# sourceMappingURL=monitorCharacteristic.js.map
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

@@ -26,62 +11,20 @@ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }

};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
exports.__esModule = true;
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
/* eslint-disable prefer-template */
var hw_transport_1 = __importDefault(require("@ledgerhq/hw-transport"));
var errors_1 = require("@ledgerhq/errors");
var devices_1 = require("@ledgerhq/devices");
var sendAPDU_1 = require("@ledgerhq/devices/ble/sendAPDU");
var receiveAPDU_1 = require("@ledgerhq/devices/ble/receiveAPDU");
var logs_1 = require("@ledgerhq/logs");
var rxjs_1 = require("rxjs");
var operators_1 = require("rxjs/operators");
var monitorCharacteristic_1 = require("./monitorCharacteristic");
var requiresBluetooth = function () {
const hw_transport_1 = __importDefault(require("@ledgerhq/hw-transport"));
const errors_1 = require("@ledgerhq/errors");
const devices_1 = require("@ledgerhq/devices");
const sendAPDU_1 = require("@ledgerhq/devices/ble/sendAPDU");
const receiveAPDU_1 = require("@ledgerhq/devices/ble/receiveAPDU");
const logs_1 = require("@ledgerhq/logs");
const rxjs_1 = require("rxjs");
const operators_1 = require("rxjs/operators");
const monitorCharacteristic_1 = require("./monitorCharacteristic");
const requiresBluetooth = () => {
// $FlowFixMe
var bluetooth = navigator.bluetooth;
const { bluetooth } = navigator;
if (typeof bluetooth === "undefined") {

@@ -92,137 +35,103 @@ throw new Error("web bluetooth not supported");

};
var availability = function () {
return rxjs_1.Observable.create(function (observer) {
var bluetooth = requiresBluetooth();
var onAvailabilityChanged = function (e) {
observer.next(e.value);
};
bluetooth.addEventListener("availabilitychanged", onAvailabilityChanged);
var unsubscribed = false;
bluetooth.getAvailability().then(function (available) {
if (!unsubscribed) {
observer.next(available);
}
});
return function () {
unsubscribed = true;
bluetooth.removeEventListener("availabilitychanged", onAvailabilityChanged);
};
});
};
var transportsCache = {};
var requestDeviceParam = function () { return ({
filters: (0, devices_1.getBluetoothServiceUuids)().map(function (uuid) { return ({
services: [uuid]
}); })
}); };
var retrieveService = function (device) { return __awaiter(void 0, void 0, void 0, function () {
var _a, service, infos;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
if (!device.gatt)
throw new Error("bluetooth gatt not found");
return [4 /*yield*/, device.gatt.getPrimaryServices()];
case 1:
_a = __read.apply(void 0, [_b.sent(), 1]), service = _a[0];
if (!service)
throw new Error("bluetooth service not found");
infos = (0, devices_1.getInfosForServiceUuid)(service.uuid);
if (!infos)
throw new Error("bluetooth service infos not found");
return [2 /*return*/, [service, infos]];
const availability = () => rxjs_1.Observable.create((observer) => {
const bluetooth = requiresBluetooth();
const onAvailabilityChanged = (e) => {
observer.next(e.value);
};
bluetooth.addEventListener("availabilitychanged", onAvailabilityChanged);
let unsubscribed = false;
bluetooth.getAvailability().then((available) => {
if (!unsubscribed) {
observer.next(available);
}
});
}); };
return () => {
unsubscribed = true;
bluetooth.removeEventListener("availabilitychanged", onAvailabilityChanged);
};
});
const transportsCache = {};
const requestDeviceParam = () => ({
filters: (0, devices_1.getBluetoothServiceUuids)().map((uuid) => ({
services: [uuid],
})),
});
const retrieveService = (device) => __awaiter(void 0, void 0, void 0, function* () {
if (!device.gatt)
throw new Error("bluetooth gatt not found");
const [service] = yield device.gatt.getPrimaryServices();
if (!service)
throw new Error("bluetooth service not found");
const infos = (0, devices_1.getInfosForServiceUuid)(service.uuid);
if (!infos)
throw new Error("bluetooth service infos not found");
return [service, infos];
});
function open(deviceOrId, needsReconnect) {
return __awaiter(this, void 0, void 0, function () {
var device, bluetooth, _a, service, infos, deviceModel, writeUuid, notifyUuid, _b, writeC, notifyC, notifyObservable, notif, transport, onDisconnect, beforeMTUTime, afterMTUTime;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
if (!(typeof deviceOrId === "string")) return [3 /*break*/, 2];
if (transportsCache[deviceOrId]) {
(0, logs_1.log)("ble-verbose", "Transport in cache, using that.");
return [2 /*return*/, transportsCache[deviceOrId]];
}
bluetooth = requiresBluetooth();
return [4 /*yield*/, bluetooth.requestDevice(requestDeviceParam())];
case 1:
// TODO instead we should "query" the device by its ID
device = _c.sent();
return [3 /*break*/, 3];
case 2:
device = deviceOrId;
_c.label = 3;
case 3:
if (!!device.gatt.connected) return [3 /*break*/, 5];
(0, logs_1.log)("ble-verbose", "not connected. connecting...");
return [4 /*yield*/, device.gatt.connect()];
case 4:
_c.sent();
_c.label = 5;
case 5: return [4 /*yield*/, retrieveService(device)];
case 6:
_a = __read.apply(void 0, [_c.sent(), 2]), service = _a[0], infos = _a[1];
deviceModel = infos.deviceModel, writeUuid = infos.writeUuid, notifyUuid = infos.notifyUuid;
return [4 /*yield*/, Promise.all([
service.getCharacteristic(writeUuid),
service.getCharacteristic(notifyUuid),
])];
case 7:
_b = __read.apply(void 0, [_c.sent(), 2]), writeC = _b[0], notifyC = _b[1];
notifyObservable = (0, monitorCharacteristic_1.monitorCharacteristic)(notifyC).pipe((0, operators_1.tap)(function (value) {
(0, logs_1.log)("ble-frame", "<= " + value.toString("hex"));
}), (0, operators_1.share)());
notif = notifyObservable.subscribe();
transport = new BluetoothTransport(device, writeC, notifyObservable, deviceModel);
if (!device.gatt.connected) {
throw new errors_1.DisconnectedDevice();
}
// eslint-disable-next-line require-atomic-updates
transportsCache[transport.id] = transport;
onDisconnect = function (e) {
console.log("onDisconnect!", e);
delete transportsCache[transport.id];
transport.notYetDisconnected = false;
notif.unsubscribe();
device.removeEventListener("gattserverdisconnected", onDisconnect);
(0, logs_1.log)("ble-verbose", "BleTransport(".concat(transport.id, ") disconnected"));
transport.emit("disconnect", e);
};
device.addEventListener("gattserverdisconnected", onDisconnect);
beforeMTUTime = Date.now();
_c.label = 8;
case 8:
_c.trys.push([8, , 10, 14]);
return [4 /*yield*/, transport.inferMTU()];
case 9:
_c.sent();
return [3 /*break*/, 14];
case 10:
afterMTUTime = Date.now();
// workaround for #279: we need to open() again if we come the first time here,
// to make sure we do a disconnect() after the first pairing time
// because of a firmware bug
if (afterMTUTime - beforeMTUTime < 1000) {
needsReconnect = false; // (optim) there is likely no new pairing done because mtu answer was fast.
}
if (!needsReconnect) return [3 /*break*/, 13];
return [4 /*yield*/, device.gatt.disconnect()];
case 11:
_c.sent();
// necessary time for the bonding workaround
return [4 /*yield*/, new Promise(function (s) { return setTimeout(s, 4000); })];
case 12:
// necessary time for the bonding workaround
_c.sent();
_c.label = 13;
case 13: return [7 /*endfinally*/];
case 14:
if (needsReconnect) {
return [2 /*return*/, open(device, false)];
}
return [2 /*return*/, transport];
return __awaiter(this, void 0, void 0, function* () {
let device;
if (typeof deviceOrId === "string") {
if (transportsCache[deviceOrId]) {
(0, logs_1.log)("ble-verbose", "Transport in cache, using that.");
return transportsCache[deviceOrId];
}
});
const bluetooth = requiresBluetooth();
// TODO instead we should "query" the device by its ID
device = yield bluetooth.requestDevice(requestDeviceParam());
}
else {
device = deviceOrId;
}
if (!device.gatt.connected) {
(0, logs_1.log)("ble-verbose", "not connected. connecting...");
yield device.gatt.connect();
}
const [service, infos] = yield retrieveService(device);
const { deviceModel, writeUuid, notifyUuid } = infos;
const [writeC, notifyC] = yield Promise.all([
service.getCharacteristic(writeUuid),
service.getCharacteristic(notifyUuid),
]);
const notifyObservable = (0, monitorCharacteristic_1.monitorCharacteristic)(notifyC).pipe((0, operators_1.tap)((value) => {
(0, logs_1.log)("ble-frame", "<= " + value.toString("hex"));
}), (0, operators_1.share)());
const notif = notifyObservable.subscribe();
const transport = new BluetoothTransport(device, writeC, notifyObservable, deviceModel);
if (!device.gatt.connected) {
throw new errors_1.DisconnectedDevice();
}
// eslint-disable-next-line require-atomic-updates
transportsCache[transport.id] = transport;
const onDisconnect = (e) => {
console.log("onDisconnect!", e);
delete transportsCache[transport.id];
transport.notYetDisconnected = false;
notif.unsubscribe();
device.removeEventListener("gattserverdisconnected", onDisconnect);
(0, logs_1.log)("ble-verbose", `BleTransport(${transport.id}) disconnected`);
transport.emit("disconnect", e);
};
device.addEventListener("gattserverdisconnected", onDisconnect);
const beforeMTUTime = Date.now();
try {
yield transport.inferMTU();
}
finally {
const afterMTUTime = Date.now();
// workaround for #279: we need to open() again if we come the first time here,
// to make sure we do a disconnect() after the first pairing time
// because of a firmware bug
if (afterMTUTime - beforeMTUTime < 1000) {
needsReconnect = false; // (optim) there is likely no new pairing done because mtu answer was fast.
}
if (needsReconnect) {
yield device.gatt.disconnect();
// necessary time for the bonding workaround
yield new Promise((s) => setTimeout(s, 4000));
}
}
if (needsReconnect) {
return open(device, false);
}
return transport;
});

@@ -235,28 +144,3 @@ }

*/
var BluetoothTransport = /** @class */ (function (_super) {
__extends(BluetoothTransport, _super);
function BluetoothTransport(device, writeCharacteristic, notifyObservable, deviceModel) {
var _this = _super.call(this) || this;
_this.mtuSize = 20;
_this.notYetDisconnected = true;
_this.write = function (buffer) { return __awaiter(_this, void 0, void 0, function () {
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
(0, logs_1.log)("ble-frame", "=> " + buffer.toString("hex"));
return [4 /*yield*/, this.writeCharacteristic.writeValue(buffer)];
case 1:
_b.sent();
return [2 /*return*/];
}
});
}); };
_this.id = device.id;
_this.device = device;
_this.writeCharacteristic = writeCharacteristic;
_this.notifyObservable = notifyObservable;
_this.deviceModel = deviceModel;
(0, logs_1.log)("ble-verbose", "BleTransport(".concat(String(_this.id), ") new instance"));
return _this;
}
class BluetoothTransport extends hw_transport_1.default {
/**

@@ -266,15 +150,15 @@ * Scan for Ledger Bluetooth devices.

*/
BluetoothTransport.listen = function (observer) {
static listen(observer) {
(0, logs_1.log)("ble-verbose", "listen...");
var unsubscribed;
var bluetooth = requiresBluetooth();
bluetooth.requestDevice(requestDeviceParam()).then(function (device) {
let unsubscribed;
const bluetooth = requiresBluetooth();
bluetooth.requestDevice(requestDeviceParam()).then((device) => {
if (!unsubscribed) {
observer.next({
type: "add",
descriptor: device
descriptor: device,
});
observer.complete();
}
}, function (error) {
}, (error) => {
observer.error(new errors_1.TransportOpenUserCancelled(error.message));

@@ -286,56 +170,50 @@ });

return {
unsubscribe: unsubscribe
unsubscribe,
};
};
}
/**
* open a bluetooth device.
*/
BluetoothTransport.open = function (deviceOrId) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_b) {
return [2 /*return*/, open(deviceOrId, true)];
});
static open(deviceOrId) {
return __awaiter(this, void 0, void 0, function* () {
return open(deviceOrId, true);
});
};
BluetoothTransport.prototype.inferMTU = function () {
return __awaiter(this, void 0, void 0, function () {
var mtu, mtuSize;
var _this = this;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
mtu = 23;
return [4 /*yield*/, this.exchangeAtomicImpl(function () { return __awaiter(_this, void 0, void 0, function () {
var e_1;
var _this = this;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
_b.trys.push([0, 2, , 3]);
return [4 /*yield*/, (0, rxjs_1.merge)(this.notifyObservable.pipe((0, operators_1.first)(function (buffer) { return buffer.readUInt8(0) === 0x08; }), (0, operators_1.map)(function (buffer) { return buffer.readUInt8(5); })), (0, rxjs_1.defer)(function () { return (0, rxjs_1.from)(_this.write(Buffer.from([0x08, 0, 0, 0, 0]))); }).pipe((0, operators_1.ignoreElements)())).toPromise()];
case 1:
mtu =
(_b.sent()) + 3;
return [3 /*break*/, 3];
case 2:
e_1 = _b.sent();
(0, logs_1.log)("ble-error", "inferMTU got " + String(e_1));
this.device.gatt.disconnect();
throw e_1;
case 3: return [2 /*return*/];
}
});
}); })];
case 1:
_b.sent();
if (mtu > 23) {
mtuSize = mtu - 3;
(0, logs_1.log)("ble-verbose", "BleTransport(".concat(String(this.id), ") mtu set to ").concat(String(mtuSize)));
this.mtuSize = mtuSize;
}
return [2 /*return*/, this.mtuSize];
}
constructor(device, writeCharacteristic, notifyObservable, deviceModel) {
super();
this.mtuSize = 20;
this.notYetDisconnected = true;
this.write = (buffer) => __awaiter(this, void 0, void 0, function* () {
(0, logs_1.log)("ble-frame", "=> " + buffer.toString("hex"));
yield this.writeCharacteristic.writeValue(buffer);
});
this.id = device.id;
this.device = device;
this.writeCharacteristic = writeCharacteristic;
this.notifyObservable = notifyObservable;
this.deviceModel = deviceModel;
(0, logs_1.log)("ble-verbose", `BleTransport(${String(this.id)}) new instance`);
}
inferMTU() {
return __awaiter(this, void 0, void 0, function* () {
let mtu = 23;
yield this.exchangeAtomicImpl(() => __awaiter(this, void 0, void 0, function* () {
try {
mtu =
(yield (0, rxjs_1.merge)(this.notifyObservable.pipe((0, operators_1.first)((buffer) => buffer.readUInt8(0) === 0x08), (0, operators_1.map)((buffer) => buffer.readUInt8(5))), (0, rxjs_1.defer)(() => (0, rxjs_1.from)(this.write(Buffer.from([0x08, 0, 0, 0, 0])))).pipe((0, operators_1.ignoreElements)())).toPromise()) + 3;
}
});
catch (e) {
(0, logs_1.log)("ble-error", "inferMTU got " + String(e));
this.device.gatt.disconnect();
throw e;
}
}));
if (mtu > 23) {
const mtuSize = mtu - 3;
(0, logs_1.log)("ble-verbose", `BleTransport(${String(this.id)}) mtu set to ${String(mtuSize)}`);
this.mtuSize = mtuSize;
}
return this.mtuSize;
});
};
}
/**

@@ -346,90 +224,56 @@ * Exchange with the device using APDU protocol.

*/
BluetoothTransport.prototype.exchange = function (apdu) {
return __awaiter(this, void 0, void 0, function () {
var b;
var _this = this;
return __generator(this, function (_b) {
switch (_b.label) {
case 0: return [4 /*yield*/, this.exchangeAtomicImpl(function () { return __awaiter(_this, void 0, void 0, function () {
var msgIn, data, msgOut, e_2;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
_b.trys.push([0, 2, , 3]);
msgIn = apdu.toString("hex");
(0, logs_1.log)("apdu", "=> ".concat(msgIn));
return [4 /*yield*/, (0, rxjs_1.merge)(this.notifyObservable.pipe(receiveAPDU_1.receiveAPDU), (0, sendAPDU_1.sendAPDU)(this.write, apdu, this.mtuSize)).toPromise()];
case 1:
data = _b.sent();
msgOut = data.toString("hex");
(0, logs_1.log)("apdu", "<= ".concat(msgOut));
return [2 /*return*/, data];
case 2:
e_2 = _b.sent();
(0, logs_1.log)("ble-error", "exchange got " + String(e_2));
if (this.notYetDisconnected) {
// in such case we will always disconnect because something is bad.
this.device.gatt.disconnect();
}
throw e_2;
case 3: return [2 /*return*/];
}
});
}); })];
case 1:
b = _b.sent();
return [2 /*return*/, b];
exchange(apdu) {
return __awaiter(this, void 0, void 0, function* () {
const b = yield this.exchangeAtomicImpl(() => __awaiter(this, void 0, void 0, function* () {
try {
const msgIn = apdu.toString("hex");
(0, logs_1.log)("apdu", `=> ${msgIn}`);
const data = yield (0, rxjs_1.merge)(this.notifyObservable.pipe(receiveAPDU_1.receiveAPDU), (0, sendAPDU_1.sendAPDU)(this.write, apdu, this.mtuSize)).toPromise();
const msgOut = data.toString("hex");
(0, logs_1.log)("apdu", `<= ${msgOut}`);
return data;
}
});
});
};
BluetoothTransport.prototype.setScrambleKey = function () { };
BluetoothTransport.prototype.close = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
if (!this.exchangeBusyPromise) return [3 /*break*/, 2];
return [4 /*yield*/, this.exchangeBusyPromise];
case 1:
_b.sent();
_b.label = 2;
case 2: return [2 /*return*/];
catch (e) {
(0, logs_1.log)("ble-error", "exchange got " + String(e));
if (this.notYetDisconnected) {
// in such case we will always disconnect because something is bad.
this.device.gatt.disconnect();
}
throw e;
}
});
}));
return b;
});
};
var _a;
_a = BluetoothTransport;
BluetoothTransport.isSupported = function () {
return Promise.resolve()
.then(requiresBluetooth)
.then(function () { return true; }, function () { return false; });
};
/**
* observe event with { available: bool, type: string }
* (available is generic, type is specific)
* an event is emit once and then each time it changes
*/
BluetoothTransport.observeAvailability = function (observer) {
return availability().subscribe(observer);
};
BluetoothTransport.list = function () { return Promise.resolve([]); };
/**
* globally disconnect a bluetooth device by its id.
*/
BluetoothTransport.disconnect = function (id) { return __awaiter(void 0, void 0, void 0, function () {
var transport;
return __generator(_a, function (_b) {
(0, logs_1.log)("ble-verbose", "user disconnect(".concat(id, ")"));
transport = transportsCache[id];
if (transport) {
transport.device.gatt.disconnect();
}
setScrambleKey() { }
close() {
return __awaiter(this, void 0, void 0, function* () {
if (this.exchangeBusyPromise) {
yield this.exchangeBusyPromise;
}
return [2 /*return*/];
});
}); };
return BluetoothTransport;
}(hw_transport_1["default"]));
exports["default"] = BluetoothTransport;
}
}
exports.default = BluetoothTransport;
_a = BluetoothTransport;
BluetoothTransport.isSupported = () => Promise.resolve()
.then(requiresBluetooth)
.then(() => true, () => false);
/**
* observe event with { available: bool, type: string }
* (available is generic, type is specific)
* an event is emit once and then each time it changes
*/
BluetoothTransport.observeAvailability = (observer) => availability().subscribe(observer);
BluetoothTransport.list = () => Promise.resolve([]);
/**
* globally disconnect a bluetooth device by its id.
*/
BluetoothTransport.disconnect = (id) => __awaiter(void 0, void 0, void 0, function* () {
(0, logs_1.log)("ble-verbose", `user disconnect(${id})`);
const transport = transportsCache[id];
if (transport) {
transport.device.gatt.disconnect();
}
});
//# sourceMappingURL=TransportWebBLE.js.map

@@ -1,3 +0,3 @@

export declare type Device = Record<string, any>;
export declare type Characteristic = Record<string, any>;
export type Device = Record<string, any>;
export type Characteristic = Record<string, any>;
//# sourceMappingURL=types.d.ts.map
"use strict";
exports.__esModule = true;
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=types.js.map
{
"name": "@ledgerhq/hw-transport-web-ble",
"version": "6.27.12",
"version": "6.27.15",
"description": "Ledger Hardware Wallet Web Bluetooth implementation of the communication layer",

@@ -31,9 +31,17 @@ "keywords": [

"rxjs": "6",
"@ledgerhq/devices": "^8.0.0",
"@ledgerhq/errors": "^6.12.3",
"@ledgerhq/hw-transport": "^6.28.1",
"@ledgerhq/devices": "^8.0.3",
"@ledgerhq/errors": "^6.12.6",
"@ledgerhq/hw-transport": "^6.28.4",
"@ledgerhq/logs": "^6.10.1"
},
"devDependencies": {
"@types/web-bluetooth": "^0.0.12"
"@types/jest": "^29.5.0",
"@types/node": "^18.15.3",
"@types/web-bluetooth": "^0.0.12",
"documentation": "13.2.4",
"jest": "^28.1.1",
"rimraf": "^4.4.1",
"source-map-support": "^0.5.21",
"ts-jest": "^28.0.5",
"ts-node": "^10.4.0"
},

@@ -40,0 +48,0 @@ "gitHead": "dd0dea64b58e5a9125c8a422dcffd29e5ef6abec",

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc