@ledgerhq/coin-stellar
Version:
Ledger Stellar Coin integration
59 lines (51 loc) • 1.84 kB
text/typescript
import { Observable } from "rxjs";
import { FeeNotLoaded } from "@ledgerhq/errors";
import type { Account, AccountBridge } from "@ledgerhq/types-live";
import { SignerContext } from "@ledgerhq/coin-framework/signer";
import type { Transaction } from "../types";
import { buildTransaction } from "./buildTransaction";
import { buildOptimisticOperation } from "./buildOptimisticOperation";
import { StellarSigner } from "../types/signer";
export function buildSignOperation(
signerContext: SignerContext<StellarSigner>,
): AccountBridge<Transaction, Account>["signOperation"] {
return function signOperation({ account, deviceId, transaction }) {
return new Observable(obs => {
let cancelled = false;
async function main() {
obs.next({ type: "device-signature-requested" });
if (cancelled) {
return;
}
if (!transaction.fees) {
throw new FeeNotLoaded();
}
const unsigned = await buildTransaction(account, transaction);
const unsignedPayload: Buffer = Buffer.from(unsigned.signatureBase());
// Sign by device
const { signature } = await signerContext(deviceId, signer =>
signer.signTransaction(account.freshAddressPath, unsignedPayload),
);
unsigned.addSignature(account.freshAddress, signature.toString("base64"));
obs.next({
type: "device-signature-granted",
});
const operation = await buildOptimisticOperation(account, transaction);
obs.next({
type: "signed",
signedOperation: {
operation,
signature: unsigned.toXDR(),
},
});
}
main().then(
() => obs.complete(),
err => obs.error(err),
);
return () => {
cancelled = true;
};
});
};
}