@hazae41/ledger
Version:
Private and supply-chain hardened Ledger controller for TypeScript
1 lines • 7.67 kB
Source Map (JSON)
{"version":3,"file":"index.mjs","sources":["../../../../src/mods/usb/index.ts"],"sourcesContent":["import { ApduRequest, ApduRequestInit, ApduResponse } from \"@hazae41/apdu\"\nimport { Opaque, Readable, Writable } from \"@hazae41/binary\"\nimport { Bytes } from \"@hazae41/bytes\"\nimport { HidContainer, HidFrame } from \"../hid/index.js\"\n\nexport const VENDOR_ID = 0x2c97\nexport const PACKET_SIZE = 64\n\nexport class DeviceInterfaceNotFoundError extends Error {\n readonly #class = DeviceInterfaceNotFoundError\n readonly name = this.#class.name\n\n constructor(options?: ErrorOptions) {\n super(`Could not find device interface`, options)\n }\n\n static from(cause: unknown) {\n return new DeviceInterfaceNotFoundError({ cause })\n }\n}\n\nexport class DeviceTransferOutError extends Error {\n readonly #class = DeviceTransferOutError\n readonly name = this.#class.name\n\n constructor(options?: ErrorOptions) {\n super(`Could not transfer data to device`, options)\n }\n\n static from(cause: unknown) {\n return new DeviceTransferOutError({ cause })\n }\n}\n\nexport class DeviceTransferInError extends Error {\n readonly #class = DeviceTransferInError\n readonly name = this.#class.name\n\n constructor(options?: ErrorOptions) {\n super(`Could not transfer data from device`, options)\n }\n\n static from(cause: unknown) {\n return new DeviceTransferInError({ cause })\n }\n}\n\nexport async function getDevicesOrThrow() {\n const devices = await navigator.usb.getDevices()\n return devices.filter(x => x.vendorId === VENDOR_ID)\n}\n\nexport async function getOrRequestDeviceOrThrow() {\n const devices = await getDevicesOrThrow()\n const device = devices[0]\n\n if (device != null)\n return device\n\n return await navigator.usb.requestDevice({ filters: [{ vendorId: VENDOR_ID }] })\n}\n\nexport async function connectOrThrow(device: USBDevice) {\n await device.open()\n\n if (device.configuration == null)\n await device.selectConfiguration(1)\n\n await device.reset()\n\n const iface = device.configurations[0].interfaces.find(({ alternates }) => alternates.some(x => x.interfaceClass === 255))\n\n if (iface == null)\n throw new DeviceInterfaceNotFoundError()\n\n await device.claimInterface(iface.interfaceNumber)\n\n return new Connector(device, iface)\n}\n\nexport class Connector {\n readonly #channel = Math.floor(Math.random() * 0xffff)\n\n constructor(\n readonly device: USBDevice,\n readonly iface: USBInterface\n ) { }\n\n async #transferOutOrThrow(frame: HidFrame<Opaque>): Promise<void> {\n await this.device.transferOut(3, Writable.writeToBytesOrThrow(frame))\n }\n\n async #transferInOrThrow(length: number): Promise<HidFrame<Opaque>> {\n const result = await this.device.transferIn(3, length)\n\n if (result.data == null)\n throw new DeviceTransferInError()\n\n const bytes = Bytes.fromView(result.data)\n const frame = Readable.readFromBytesOrThrow(HidFrame, bytes)\n\n return frame\n }\n\n async #sendOrThrow<T extends Writable>(fragment: T): Promise<void> {\n const container = HidContainer.newOrThrow(fragment)\n const bytes = Writable.writeToBytesOrThrow(container)\n\n const frames = HidFrame.splitOrThrow(this.#channel, bytes)\n\n let frame = frames.next()\n\n for (; !frame.done; frame = frames.next())\n await this.#transferOutOrThrow(frame.value)\n\n return frame.value\n }\n\n async *#receiveOrThrow(): AsyncGenerator<HidFrame<Opaque>, never, unknown> {\n while (true)\n yield await this.#transferInOrThrow(64)\n }\n\n async requestOrThrow<T extends Writable>(init: ApduRequestInit<T>): Promise<ApduResponse<Opaque>> {\n const request = ApduRequest.fromOrThrow(init)\n await this.#sendOrThrow(request)\n\n const bytes = await HidFrame.unsplitOrThrow(this.#channel, this.#receiveOrThrow())\n const response = Readable.readFromBytesOrThrow(ApduResponse, bytes)\n\n return response\n }\n\n}"],"names":[],"mappings":"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"}