@ledgerhq/live-common
Version:
Common ground for the Ledger Live apps
61 lines (54 loc) • 1.56 kB
text/typescript
import { Subject } from "rxjs";
import { withDevice } from "./deviceAccess";
export type BidirectionalEvent =
| {
type: "input-frame";
apduHex: string;
}
| {
type: "device-request";
data: string;
}
| {
type: "device-response";
data: string;
}
| {
type: "error";
error: unknown;
};
export type OpenTransportAsSubjectRequest = {
deviceId: string;
};
export default function openTransportAsSubject({
deviceId,
}: OpenTransportAsSubjectRequest): Subject<BidirectionalEvent> {
const subject = new Subject<BidirectionalEvent>();
withDevice(deviceId)(transport => {
// The input part of the bidirectional communication
subject.subscribe({
next: e => {
/**
* Receiving an event from the ipc bridge allows us to pass a msg
* into an ongoing withDevice job. Allowing to exchange messages with the
* transport exposed from the job.
*/
if (e?.type === "input-frame") {
subject.next({ type: "device-request", data: e.apduHex });
// TODO important avoiding collisions, also types will be broken
transport
.exchange(Buffer.from(e.apduHex, "hex"))
.then(response =>
subject.next({
type: "device-response",
data: response.toString("hex"),
}),
)
.catch(error => subject.next({ type: "error", error }));
}
},
});
return subject;
}).subscribe();
return subject;
}