@ledgerhq/hw-transport-node-speculos
Advanced tools
Comparing version 5.51.1 to 6.0.0-alpha.5
@@ -0,11 +1,58 @@ | ||
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) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
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 }; | ||
} | ||
}; | ||
import { Subject } from "rxjs"; | ||
import net from "net"; | ||
import Transport from "@ledgerhq/hw-transport"; | ||
import { DisconnectedDevice, DisconnectedDeviceDuringOperation, TransportError } from "@ledgerhq/errors"; | ||
import { DisconnectedDevice, DisconnectedDeviceDuringOperation, TransportError, } from "@ledgerhq/errors"; | ||
import { log } from "@ledgerhq/logs"; | ||
/** | ||
* | ||
*/ | ||
/** | ||
* Speculos TCP transport implementation | ||
@@ -18,154 +65,152 @@ * | ||
*/ | ||
export default class SpeculosTransport extends Transport { | ||
// this transport is not discoverable | ||
/** | ||
* | ||
*/ | ||
constructor(apduSocket, opts) { | ||
super(); | ||
this.apduSocket = void 0; | ||
this.opts = void 0; | ||
this.rejectExchange = _e => {}; | ||
this.resolveExchange = _b => {}; | ||
this.automationSocket = void 0; | ||
this.automationEvents = new Subject(); | ||
this.button = command => new Promise((resolve, reject) => { | ||
log("speculos-button", command); | ||
const { | ||
buttonPort, | ||
host | ||
} = this.opts; | ||
if (!buttonPort) throw new Error("buttonPort is missing"); | ||
const socket = new net.Socket(); | ||
socket.on("error", e => { | ||
socket.destroy(); | ||
reject(e); | ||
}); | ||
socket.connect(buttonPort, host || "127.0.0.1", () => { | ||
socket.write(Buffer.from(command, "ascii")); | ||
socket.destroy(); | ||
resolve(); | ||
}); | ||
}); | ||
this.opts = opts; | ||
this.apduSocket = apduSocket; | ||
apduSocket.on("error", e => { | ||
this.emit("disconnect", new DisconnectedDevice(e.message)); | ||
this.rejectExchange(e); | ||
this.apduSocket.destroy(); | ||
}); | ||
apduSocket.on("end", () => { | ||
this.emit("disconnect", new DisconnectedDevice()); | ||
this.rejectExchange(new DisconnectedDeviceDuringOperation()); | ||
}); | ||
apduSocket.on("data", data => { | ||
try { | ||
this.resolveExchange(decodeAPDUPayload(data)); | ||
} catch (e) { | ||
this.rejectExchange(e); | ||
} | ||
}); | ||
const { | ||
automationPort | ||
} = opts; | ||
if (automationPort) { | ||
const socket = new net.Socket(); | ||
this.automationSocket = socket; | ||
socket.on("error", e => { | ||
log("speculos-automation-error", String(e)); | ||
socket.destroy(); | ||
}); | ||
socket.on("data", data => { | ||
log("speculos-automation-data", data); | ||
const split = data.toString("ascii").split("\n"); | ||
split.filter(ascii => !!ascii).forEach(ascii => { | ||
const json = JSON.parse(ascii); | ||
this.automationEvents.next(json); | ||
var SpeculosTransport = /** @class */ (function (_super) { | ||
__extends(SpeculosTransport, _super); | ||
function SpeculosTransport(apduSocket, opts) { | ||
var _this = _super.call(this) || this; | ||
_this.rejectExchange = function (_e) { }; | ||
_this.resolveExchange = function (_b) { }; | ||
_this.automationEvents = new Subject(); | ||
/** | ||
* Send a speculos button command | ||
* typically "Ll" would press and release the left button | ||
* typically "Rr" would press and release the right button | ||
* @param {*} command | ||
*/ | ||
_this.button = function (command) { | ||
return new Promise(function (resolve, reject) { | ||
log("speculos-button", command); | ||
var _a = _this.opts, buttonPort = _a.buttonPort, host = _a.host; | ||
if (!buttonPort) | ||
throw new Error("buttonPort is missing"); | ||
var socket = new net.Socket(); | ||
socket.on("error", function (e) { | ||
socket.destroy(); | ||
reject(e); | ||
}); | ||
socket.connect(buttonPort, host || "127.0.0.1", function () { | ||
socket.write(Buffer.from(command, "ascii")); | ||
socket.destroy(); | ||
resolve(); | ||
}); | ||
}); | ||
}; | ||
_this.opts = opts; | ||
_this.apduSocket = apduSocket; | ||
apduSocket.on("error", function (e) { | ||
_this.emit("disconnect", new DisconnectedDevice(e.message)); | ||
_this.rejectExchange(e); | ||
_this.apduSocket.destroy(); | ||
}); | ||
}); | ||
socket.connect(automationPort, opts.host || "127.0.0.1"); | ||
apduSocket.on("end", function () { | ||
_this.emit("disconnect", new DisconnectedDevice()); | ||
_this.rejectExchange(new DisconnectedDeviceDuringOperation()); | ||
}); | ||
apduSocket.on("data", function (data) { | ||
try { | ||
_this.resolveExchange(decodeAPDUPayload(data)); | ||
} | ||
catch (e) { | ||
_this.rejectExchange(e); | ||
} | ||
}); | ||
var automationPort = opts.automationPort; | ||
if (automationPort) { | ||
var socket_1 = new net.Socket(); | ||
_this.automationSocket = socket_1; | ||
socket_1.on("error", function (e) { | ||
log("speculos-automation-error", String(e)); | ||
socket_1.destroy(); | ||
}); | ||
socket_1.on("data", function (data) { | ||
log("speculos-automation-data", data.toString("ascii")); | ||
var split = data.toString("ascii").split("\n"); | ||
split | ||
.filter(function (ascii) { return !!ascii; }) | ||
.forEach(function (ascii) { | ||
var json = JSON.parse(ascii); | ||
_this.automationEvents.next(json); | ||
}); | ||
}); | ||
socket_1.connect(automationPort, opts.host || "127.0.0.1"); | ||
} | ||
return _this; | ||
} | ||
} | ||
/** | ||
* Send a speculos button command | ||
* typically "Ll" would press and release the left button | ||
* typically "Rr" would press and release the right button | ||
* @param {*} command | ||
*/ | ||
async exchange(apdu) { | ||
const hex = apdu.toString("hex"); | ||
log("apdu", "=> " + hex); | ||
const encoded = encodeAPDU(apdu); | ||
const res = await new Promise((resolve, reject) => { | ||
this.rejectExchange = reject; | ||
this.resolveExchange = resolve; | ||
this.apduSocket.write(encoded); | ||
}); | ||
log("apdu", "<= " + res.toString("hex")); | ||
return res; | ||
} | ||
setScrambleKey() {} | ||
async close() { | ||
if (this.automationSocket) this.automationSocket.destroy(); | ||
this.apduSocket.destroy(); | ||
return Promise.resolve(); | ||
} | ||
} | ||
SpeculosTransport.isSupported = () => Promise.resolve(true); | ||
SpeculosTransport.list = () => Promise.resolve([]); | ||
SpeculosTransport.listen = _observer => ({ | ||
unsubscribe: () => {} | ||
}); | ||
SpeculosTransport.open = opts => new Promise((resolve, reject) => { | ||
const socket = new net.Socket(); | ||
socket.on("error", e => { | ||
socket.destroy(); | ||
reject(e); | ||
}); | ||
socket.on("end", () => { | ||
reject(new DisconnectedDevice("tcp closed")); | ||
}); | ||
socket.connect(opts.apduPort, opts.host || "127.0.0.1", () => { | ||
// we delay a bit the transport creation to make sure the tcp does not hang up | ||
setTimeout(() => { | ||
resolve(new SpeculosTransport(socket, opts)); | ||
}, 100); | ||
}); | ||
}); | ||
SpeculosTransport.prototype.exchange = function (apdu) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var hex, encoded, res; | ||
var _this = this; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
hex = apdu.toString("hex"); | ||
log("apdu", "=> " + hex); | ||
encoded = encodeAPDU(apdu); | ||
return [4 /*yield*/, new Promise(function (resolve, reject) { | ||
_this.rejectExchange = reject; | ||
_this.resolveExchange = resolve; | ||
_this.apduSocket.write(encoded); | ||
})]; | ||
case 1: | ||
res = _a.sent(); | ||
log("apdu", "<= " + res.toString("hex")); | ||
return [2 /*return*/, res]; | ||
} | ||
}); | ||
}); | ||
}; | ||
SpeculosTransport.prototype.setScrambleKey = function () { }; | ||
SpeculosTransport.prototype.close = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
if (this.automationSocket) | ||
this.automationSocket.destroy(); | ||
this.apduSocket.destroy(); | ||
return [2 /*return*/, Promise.resolve()]; | ||
}); | ||
}); | ||
}; | ||
SpeculosTransport.isSupported = function () { return Promise.resolve(true); }; | ||
// this transport is not discoverable | ||
SpeculosTransport.list = function () { return Promise.resolve([]); }; | ||
SpeculosTransport.listen = function (_observer) { return ({ | ||
unsubscribe: function () { } | ||
}); }; | ||
/** | ||
* | ||
*/ | ||
SpeculosTransport.open = function (opts) { | ||
return new Promise(function (resolve, reject) { | ||
var socket = new net.Socket(); | ||
socket.on("error", function (e) { | ||
socket.destroy(); | ||
reject(e); | ||
}); | ||
socket.on("end", function () { | ||
reject(new DisconnectedDevice("tcp closed")); | ||
}); | ||
socket.connect(opts.apduPort, opts.host || "127.0.0.1", function () { | ||
// we delay a bit the transport creation to make sure the tcp does not hang up | ||
setTimeout(function () { | ||
resolve(new SpeculosTransport(socket, opts)); | ||
}, 100); | ||
}); | ||
}); | ||
}; | ||
return SpeculosTransport; | ||
}(Transport)); | ||
export default SpeculosTransport; | ||
function encodeAPDU(apdu) { | ||
const size = Buffer.allocUnsafe(4); | ||
size.writeUIntBE(apdu.length, 0, 4); | ||
return Buffer.concat([size, apdu]); | ||
var size = Buffer.allocUnsafe(4); | ||
size.writeUIntBE(apdu.length, 0, 4); | ||
return Buffer.concat([size, apdu]); | ||
} | ||
function decodeAPDUPayload(data) { | ||
const dataLength = data.readUIntBE(0, 4); // 4 bytes tells the data length | ||
const size = dataLength + 2; // size does not include the status code so we add 2 | ||
const payload = data.slice(4); | ||
if (payload.length !== size) { | ||
throw new TransportError(`Expected payload of length ${size} but got ${payload.length}`); | ||
} | ||
return payload; | ||
var dataLength = data.readUIntBE(0, 4); // 4 bytes tells the data length | ||
var size = dataLength + 2; // size does not include the status code so we add 2 | ||
var payload = data.slice(4); | ||
if (payload.length !== size) { | ||
throw new TransportError("Expected payload of length " + size + " but got " + payload.length, ""); | ||
} | ||
return payload; | ||
} | ||
//# sourceMappingURL=SpeculosTransport.js.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports.default = void 0; | ||
var _rxjs = require("rxjs"); | ||
var _net = _interopRequireDefault(require("net")); | ||
var _hwTransport = _interopRequireDefault(require("@ledgerhq/hw-transport")); | ||
var _errors = require("@ledgerhq/errors"); | ||
var _logs = require("@ledgerhq/logs"); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
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) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
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 __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
exports.__esModule = true; | ||
var rxjs_1 = require("rxjs"); | ||
var net_1 = __importDefault(require("net")); | ||
var hw_transport_1 = __importDefault(require("@ledgerhq/hw-transport")); | ||
var errors_1 = require("@ledgerhq/errors"); | ||
var logs_1 = require("@ledgerhq/logs"); | ||
/** | ||
@@ -28,156 +70,152 @@ * Speculos TCP transport implementation | ||
*/ | ||
class SpeculosTransport extends _hwTransport.default { | ||
// this transport is not discoverable | ||
/** | ||
* | ||
*/ | ||
constructor(apduSocket, opts) { | ||
super(); | ||
this.apduSocket = void 0; | ||
this.opts = void 0; | ||
this.rejectExchange = _e => {}; | ||
this.resolveExchange = _b => {}; | ||
this.automationSocket = void 0; | ||
this.automationEvents = new _rxjs.Subject(); | ||
this.button = command => new Promise((resolve, reject) => { | ||
(0, _logs.log)("speculos-button", command); | ||
const { | ||
buttonPort, | ||
host | ||
} = this.opts; | ||
if (!buttonPort) throw new Error("buttonPort is missing"); | ||
const socket = new _net.default.Socket(); | ||
socket.on("error", e => { | ||
socket.destroy(); | ||
reject(e); | ||
}); | ||
socket.connect(buttonPort, host || "127.0.0.1", () => { | ||
socket.write(Buffer.from(command, "ascii")); | ||
socket.destroy(); | ||
resolve(); | ||
}); | ||
}); | ||
this.opts = opts; | ||
this.apduSocket = apduSocket; | ||
apduSocket.on("error", e => { | ||
this.emit("disconnect", new _errors.DisconnectedDevice(e.message)); | ||
this.rejectExchange(e); | ||
this.apduSocket.destroy(); | ||
}); | ||
apduSocket.on("end", () => { | ||
this.emit("disconnect", new _errors.DisconnectedDevice()); | ||
this.rejectExchange(new _errors.DisconnectedDeviceDuringOperation()); | ||
}); | ||
apduSocket.on("data", data => { | ||
try { | ||
this.resolveExchange(decodeAPDUPayload(data)); | ||
} catch (e) { | ||
this.rejectExchange(e); | ||
} | ||
}); | ||
const { | ||
automationPort | ||
} = opts; | ||
if (automationPort) { | ||
const socket = new _net.default.Socket(); | ||
this.automationSocket = socket; | ||
socket.on("error", e => { | ||
(0, _logs.log)("speculos-automation-error", String(e)); | ||
socket.destroy(); | ||
}); | ||
socket.on("data", data => { | ||
(0, _logs.log)("speculos-automation-data", data); | ||
const split = data.toString("ascii").split("\n"); | ||
split.filter(ascii => !!ascii).forEach(ascii => { | ||
const json = JSON.parse(ascii); | ||
this.automationEvents.next(json); | ||
var SpeculosTransport = /** @class */ (function (_super) { | ||
__extends(SpeculosTransport, _super); | ||
function SpeculosTransport(apduSocket, opts) { | ||
var _this = _super.call(this) || this; | ||
_this.rejectExchange = function (_e) { }; | ||
_this.resolveExchange = function (_b) { }; | ||
_this.automationEvents = new rxjs_1.Subject(); | ||
/** | ||
* Send a speculos button command | ||
* typically "Ll" would press and release the left button | ||
* typically "Rr" would press and release the right button | ||
* @param {*} command | ||
*/ | ||
_this.button = function (command) { | ||
return new Promise(function (resolve, reject) { | ||
logs_1.log("speculos-button", command); | ||
var _a = _this.opts, buttonPort = _a.buttonPort, host = _a.host; | ||
if (!buttonPort) | ||
throw new Error("buttonPort is missing"); | ||
var socket = new net_1["default"].Socket(); | ||
socket.on("error", function (e) { | ||
socket.destroy(); | ||
reject(e); | ||
}); | ||
socket.connect(buttonPort, host || "127.0.0.1", function () { | ||
socket.write(Buffer.from(command, "ascii")); | ||
socket.destroy(); | ||
resolve(); | ||
}); | ||
}); | ||
}; | ||
_this.opts = opts; | ||
_this.apduSocket = apduSocket; | ||
apduSocket.on("error", function (e) { | ||
_this.emit("disconnect", new errors_1.DisconnectedDevice(e.message)); | ||
_this.rejectExchange(e); | ||
_this.apduSocket.destroy(); | ||
}); | ||
}); | ||
socket.connect(automationPort, opts.host || "127.0.0.1"); | ||
apduSocket.on("end", function () { | ||
_this.emit("disconnect", new errors_1.DisconnectedDevice()); | ||
_this.rejectExchange(new errors_1.DisconnectedDeviceDuringOperation()); | ||
}); | ||
apduSocket.on("data", function (data) { | ||
try { | ||
_this.resolveExchange(decodeAPDUPayload(data)); | ||
} | ||
catch (e) { | ||
_this.rejectExchange(e); | ||
} | ||
}); | ||
var automationPort = opts.automationPort; | ||
if (automationPort) { | ||
var socket_1 = new net_1["default"].Socket(); | ||
_this.automationSocket = socket_1; | ||
socket_1.on("error", function (e) { | ||
logs_1.log("speculos-automation-error", String(e)); | ||
socket_1.destroy(); | ||
}); | ||
socket_1.on("data", function (data) { | ||
logs_1.log("speculos-automation-data", data.toString("ascii")); | ||
var split = data.toString("ascii").split("\n"); | ||
split | ||
.filter(function (ascii) { return !!ascii; }) | ||
.forEach(function (ascii) { | ||
var json = JSON.parse(ascii); | ||
_this.automationEvents.next(json); | ||
}); | ||
}); | ||
socket_1.connect(automationPort, opts.host || "127.0.0.1"); | ||
} | ||
return _this; | ||
} | ||
} | ||
/** | ||
* Send a speculos button command | ||
* typically "Ll" would press and release the left button | ||
* typically "Rr" would press and release the right button | ||
* @param {*} command | ||
*/ | ||
async exchange(apdu) { | ||
const hex = apdu.toString("hex"); | ||
(0, _logs.log)("apdu", "=> " + hex); | ||
const encoded = encodeAPDU(apdu); | ||
const res = await new Promise((resolve, reject) => { | ||
this.rejectExchange = reject; | ||
this.resolveExchange = resolve; | ||
this.apduSocket.write(encoded); | ||
}); | ||
(0, _logs.log)("apdu", "<= " + res.toString("hex")); | ||
return res; | ||
} | ||
setScrambleKey() {} | ||
async close() { | ||
if (this.automationSocket) this.automationSocket.destroy(); | ||
this.apduSocket.destroy(); | ||
return Promise.resolve(); | ||
} | ||
} | ||
exports.default = SpeculosTransport; | ||
SpeculosTransport.isSupported = () => Promise.resolve(true); | ||
SpeculosTransport.list = () => Promise.resolve([]); | ||
SpeculosTransport.listen = _observer => ({ | ||
unsubscribe: () => {} | ||
}); | ||
SpeculosTransport.open = opts => new Promise((resolve, reject) => { | ||
const socket = new _net.default.Socket(); | ||
socket.on("error", e => { | ||
socket.destroy(); | ||
reject(e); | ||
}); | ||
socket.on("end", () => { | ||
reject(new _errors.DisconnectedDevice("tcp closed")); | ||
}); | ||
socket.connect(opts.apduPort, opts.host || "127.0.0.1", () => { | ||
// we delay a bit the transport creation to make sure the tcp does not hang up | ||
setTimeout(() => { | ||
resolve(new SpeculosTransport(socket, opts)); | ||
}, 100); | ||
}); | ||
}); | ||
SpeculosTransport.prototype.exchange = function (apdu) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var hex, encoded, res; | ||
var _this = this; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
hex = apdu.toString("hex"); | ||
logs_1.log("apdu", "=> " + hex); | ||
encoded = encodeAPDU(apdu); | ||
return [4 /*yield*/, new Promise(function (resolve, reject) { | ||
_this.rejectExchange = reject; | ||
_this.resolveExchange = resolve; | ||
_this.apduSocket.write(encoded); | ||
})]; | ||
case 1: | ||
res = _a.sent(); | ||
logs_1.log("apdu", "<= " + res.toString("hex")); | ||
return [2 /*return*/, res]; | ||
} | ||
}); | ||
}); | ||
}; | ||
SpeculosTransport.prototype.setScrambleKey = function () { }; | ||
SpeculosTransport.prototype.close = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
if (this.automationSocket) | ||
this.automationSocket.destroy(); | ||
this.apduSocket.destroy(); | ||
return [2 /*return*/, Promise.resolve()]; | ||
}); | ||
}); | ||
}; | ||
SpeculosTransport.isSupported = function () { return Promise.resolve(true); }; | ||
// this transport is not discoverable | ||
SpeculosTransport.list = function () { return Promise.resolve([]); }; | ||
SpeculosTransport.listen = function (_observer) { return ({ | ||
unsubscribe: function () { } | ||
}); }; | ||
/** | ||
* | ||
*/ | ||
SpeculosTransport.open = function (opts) { | ||
return new Promise(function (resolve, reject) { | ||
var socket = new net_1["default"].Socket(); | ||
socket.on("error", function (e) { | ||
socket.destroy(); | ||
reject(e); | ||
}); | ||
socket.on("end", function () { | ||
reject(new errors_1.DisconnectedDevice("tcp closed")); | ||
}); | ||
socket.connect(opts.apduPort, opts.host || "127.0.0.1", function () { | ||
// we delay a bit the transport creation to make sure the tcp does not hang up | ||
setTimeout(function () { | ||
resolve(new SpeculosTransport(socket, opts)); | ||
}, 100); | ||
}); | ||
}); | ||
}; | ||
return SpeculosTransport; | ||
}(hw_transport_1["default"])); | ||
exports["default"] = SpeculosTransport; | ||
function encodeAPDU(apdu) { | ||
const size = Buffer.allocUnsafe(4); | ||
size.writeUIntBE(apdu.length, 0, 4); | ||
return Buffer.concat([size, apdu]); | ||
var size = Buffer.allocUnsafe(4); | ||
size.writeUIntBE(apdu.length, 0, 4); | ||
return Buffer.concat([size, apdu]); | ||
} | ||
function decodeAPDUPayload(data) { | ||
const dataLength = data.readUIntBE(0, 4); // 4 bytes tells the data length | ||
const size = dataLength + 2; // size does not include the status code so we add 2 | ||
const payload = data.slice(4); | ||
if (payload.length !== size) { | ||
throw new _errors.TransportError(`Expected payload of length ${size} but got ${payload.length}`); | ||
} | ||
return payload; | ||
var dataLength = data.readUIntBE(0, 4); // 4 bytes tells the data length | ||
var size = dataLength + 2; // size does not include the status code so we add 2 | ||
var payload = data.slice(4); | ||
if (payload.length !== size) { | ||
throw new errors_1.TransportError("Expected payload of length " + size + " but got " + payload.length, ""); | ||
} | ||
return payload; | ||
} | ||
//# sourceMappingURL=SpeculosTransport.js.map |
{ | ||
"name": "@ledgerhq/hw-transport-node-speculos", | ||
"version": "5.51.1", | ||
"version": "6.0.0-alpha.5", | ||
"description": "Ledger Hardware Wallet communication layer with speculos Nano simulator", | ||
@@ -28,20 +28,17 @@ "keywords": [ | ||
"module": "lib-es/SpeculosTransport.js", | ||
"types": "lib/SpeculosTransport.d.ts", | ||
"license": "Apache-2.0", | ||
"dependencies": { | ||
"@ledgerhq/errors": "^5.50.0", | ||
"@ledgerhq/hw-transport": "^5.51.1", | ||
"@ledgerhq/logs": "^5.50.0", | ||
"@ledgerhq/errors": "^6.0.0-alpha.5", | ||
"@ledgerhq/hw-transport": "^6.0.0-alpha.5", | ||
"@ledgerhq/logs": "^6.0.0-alpha.5", | ||
"rxjs": "6" | ||
}, | ||
"devDependencies": { | ||
"flow-bin": "^0.149.0" | ||
}, | ||
"scripts": { | ||
"flow": "flow", | ||
"clean": "bash ../../script/clean.sh", | ||
"build": "bash ../../script/build.sh", | ||
"watch": "bash ../../script/watch.sh", | ||
"doc": "bash ../../script/doc.sh" | ||
"doc": "bash ../../script/doc-ts.sh" | ||
}, | ||
"gitHead": "991888009774c7cdd2b0e0711bdbf870c260e7a5" | ||
"gitHead": "dd0dea64b58e5a9125c8a422dcffd29e5ef6abec" | ||
} |
@@ -74,2 +74,4 @@ <img src="https://user-images.githubusercontent.com/211411/34776833-6f1ef4da-f618-11e7-8b13-f0697901d6a8.png" height="100" /> | ||
Type: {apduPort: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number), buttonPort: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?, automationPort: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?, host: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?} | ||
#### Properties | ||
@@ -76,0 +78,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
67701
0
15
696
121
1
+ Added@ledgerhq/devices@8.4.4(transitive)
+ Added@ledgerhq/errors@6.19.1(transitive)
+ Added@ledgerhq/hw-transport@6.31.4(transitive)
+ Added@ledgerhq/logs@6.12.0(transitive)
+ Addedrxjs@7.8.1(transitive)
+ Addedtslib@2.8.1(transitive)
- Removed@ledgerhq/devices@5.51.1(transitive)
- Removed@ledgerhq/errors@5.50.0(transitive)
- Removed@ledgerhq/hw-transport@5.51.1(transitive)
- Removed@ledgerhq/logs@5.50.0(transitive)