UNPKG

@ledgerhq/coin-tron

Version:
121 lines (102 loc) 3.87 kB
import { SignerContext } from "@ledgerhq/ledger-wallet-framework/signer"; import { SignOperationEvent, SignOperationFnSignature, TokenAccount } from "@ledgerhq/types-live"; import BigNumber from "bignumber.js"; import { Observable } from "rxjs"; import { claimRewardTronTransaction, createTronTransaction, freezeTronTransaction, legacyUnfreezeTronTransaction, unDelegateResourceTransaction, unfreezeTronTransaction, voteTronSuperRepresentatives, withdrawExpireUnfreezeTronTransaction, } from "../network"; import { Transaction, TronAccount, TronSigner } from "../types"; import { buildOptimisticOperation } from "./buildOptimisticOperation"; import getEstimatedFees from "./getEstimateFees"; export const buildSignOperation = (signerContext: SignerContext<TronSigner>): SignOperationFnSignature<Transaction, TronAccount> => ({ account, transaction, deviceId }): Observable<SignOperationEvent> => new Observable(o => { async function main() { const subAccount = transaction.subAccountId && account.subAccounts ? account.subAccounts.find(sa => sa.id === transaction.subAccountId) : undefined; const fee = await getEstimatedFees(account, transaction, subAccount); const balance = subAccount ? subAccount.balance : BigNumber.max(0, account.spendableBalance.minus(fee)); if (transaction.useAllAmount) { transaction = { ...transaction }; // transaction object must not be mutated transaction.amount = balance; // force the amount to be the max } const { raw_data_hex: rawDataHex, raw_data: rawData, txID: hash, } = await prepareTransactionForSignature(account, subAccount, transaction); o.next({ type: "device-signature-requested", }); const txArg = { rawDataHex, // only for trc10, we need to put the token ledger signature tokenSignature: subAccount && subAccount.type === "TokenAccount" && subAccount.token.id.includes("trc10") ? subAccount.token.ledgerSignature : undefined, }; // Sign by device const signature = await signerContext(deviceId, signer => signer.sign( account.freshAddressPath, txArg.rawDataHex ?? "", //FIXME: why rawDataHex could be undefined? This shouldn't be the case. txArg.tokenSignature ? [txArg.tokenSignature] : [], ), ); o.next({ type: "device-signature-granted", }); const operation = buildOptimisticOperation(account, subAccount, transaction, fee, hash); o.next({ type: "signed", signedOperation: { operation, signature, rawData, }, }); } main().then( () => o.complete(), e => o.error(e), ); }); const prepareTransactionForSignature = ( account: TronAccount, subAccount: TokenAccount | undefined, transaction: Transaction, ) => { switch (transaction.mode) { case "freeze": return freezeTronTransaction(account, transaction); case "unfreeze": return unfreezeTronTransaction(account, transaction); case "vote": return voteTronSuperRepresentatives(account, transaction); case "claimReward": return claimRewardTronTransaction(account); case "withdrawExpireUnfreeze": return withdrawExpireUnfreezeTronTransaction(account, transaction); case "unDelegateResource": return unDelegateResourceTransaction(account, transaction); case "legacyUnfreeze": return legacyUnfreezeTronTransaction(account, transaction); default: return createTronTransaction(account, transaction, subAccount); } };