@ledgerhq/hw-transport-http
Version:
Ledger Hardware Wallet communication layer over http
76 lines (65 loc) • 1.92 kB
text/typescript
import Transport from "@ledgerhq/hw-transport";
import { TransportError } from "@ledgerhq/errors";
import axios from "axios";
import { log } from "@ledgerhq/logs";
/**
* HTTP transport implementation
*/
export default class HttpTransport extends Transport {
static isSupported = (): Promise<boolean> => Promise.resolve(typeof fetch === "function");
// this transport is not discoverable
static list = (): any => Promise.resolve([]);
static listen = (_observer: any) => ({
unsubscribe: () => {},
});
static check = async (url: string, timeout = 5000) => {
const response = await axios({
url,
timeout,
});
if (response.status !== 200) {
throw new TransportError(
"failed to access HttpTransport(" + url + "): status " + response.status,
"HttpTransportNotAccessible",
);
}
};
static async open(url: string, timeout?: number): Promise<Transport> {
await HttpTransport.check(url, timeout);
return new HttpTransport(url);
}
url: string;
constructor(url: string) {
super();
this.url = url;
}
async exchange(apdu: Buffer): Promise<Buffer> {
const apduHex = apdu.toString("hex");
log("apdu", "=> " + apduHex);
const response = await axios({
method: "POST",
url: this.url,
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
data: JSON.stringify({
apduHex,
}),
});
if (response.status !== 200) {
throw new TransportError(
"failed to communicate to server. code=" + response.status,
"HttpTransportStatus" + response.status,
);
}
const body: any = await response.data;
if (body.error) throw body.error;
log("apdu", "<= " + body.data);
return Buffer.from(body.data, "hex");
}
setScrambleKey() {}
close(): Promise<void> {
return Promise.resolve();
}
}