@ledgerhq/coin-tezos
Version:
83 lines • 3.26 kB
JavaScript
import { Observable } from "rxjs";
import { FeeNotLoaded } from "@ledgerhq/errors";
import { buildOptimisticOperation } from "./buildOptimisticOperation";
import { craftTransaction, rawEncode } from "../logic";
import { getTezosToolkit } from "../logic/tezosToolkit";
// Exported for test purpose only
export async function getOperationContents({ account, transaction, counter, public_key, public_key_hash, }) {
let publicKey = undefined;
if (!account.tezosResources.revealed) {
publicKey = {
publicKey: public_key,
publicKeyHash: public_key_hash,
};
}
return craftTransaction({
address: account.freshAddress,
counter,
}, {
type: transaction.mode,
recipient: transaction.recipient,
amount: BigInt(transaction.amount.toString()),
fee: {
fees: (transaction.fees || 0).toString(),
gasLimit: (transaction.gasLimit || 0).toString(),
storageLimit: (transaction.storageLimit || 0).toString(),
},
}, publicKey);
}
export const buildSignOperation = (signerContext) => ({ account, deviceId, transaction }) => new Observable(o => {
let cancelled = false;
async function main() {
const { fees } = transaction;
if (!fees)
throw new FeeNotLoaded();
const { freshAddressPath, freshAddress } = account;
const signedInfo = await signerContext(deviceId, async (signer) => {
const ledgerSigner = signer.createLedgerSigner(freshAddressPath, false, 0);
const tezosToolkit = getTezosToolkit();
tezosToolkit.setProvider({ signer: ledgerSigner });
const publicKey = await ledgerSigner.publicKey();
const publicKeyHash = await ledgerSigner.publicKeyHash();
const sourceData = await tezosToolkit.rpc.getContract(freshAddress);
o.next({ type: "device-signature-requested" });
if (cancelled) {
return;
}
const { type, contents } = await getOperationContents({
account,
transaction,
counter: Number(sourceData.counter),
public_key: publicKey,
public_key_hash: publicKeyHash,
});
const forgedBytes = await rawEncode(contents);
const signature = await ledgerSigner.sign(forgedBytes);
return {
type,
signature,
};
});
if (!signedInfo) {
return;
}
o.next({ type: "device-signature-granted" });
const { type, signature } = signedInfo;
const operation = buildOptimisticOperation(account, transaction, type);
o.next({
type: "signed",
signedOperation: {
operation,
// we slice the signature to remove the `03` prefix
// which souldn't be included in the signature
signature: signature.sbytes.slice(2),
},
});
}
main().then(() => o.complete(), e => o.error(e));
return () => {
cancelled = true;
};
});
export default buildSignOperation;
//# sourceMappingURL=signOperation.js.map