UNPKG

@ledgerhq/coin-cardano

Version:
127 lines 6.21 kB
import BigNumber from "bignumber.js"; import { HashType } from "@stricahq/typhonjs/dist/types"; import { encodeOperationId } from "@ledgerhq/coin-framework/operation"; import { formatCurrencyUnit } from "@ledgerhq/coin-framework/currencies"; import ShelleyTypeAddress from "@stricahq/typhonjs/dist/address/ShelleyTypeAddress"; import { types as TyphonTypes } from "@stricahq/typhonjs"; import { getAccountStakeCredential, getOperationType } from "./logic"; import { MEMO_LABEL } from "./constants"; export const buildOptimisticOperation = (account, unsignedTransaction, transaction) => { const cardanoResources = account.cardanoResources; const accountCreds = new Set([...cardanoResources.externalCredentials, ...cardanoResources.internalCredentials].map(cred => cred.key)); const stakeCredential = getAccountStakeCredential(account.xpub, account.index); const protocolParams = account.cardanoResources.protocolParams; const accountInput = unsignedTransaction .getInputs() .reduce((total, i) => accountCreds.has(i.address.paymentCredential.hash.toString("hex")) ? total.plus(i.amount) : total.plus(0), new BigNumber(0)); const accountOutput = unsignedTransaction .getOutputs() .reduce((total, o) => o.address instanceof ShelleyTypeAddress && accountCreds.has(o.address.paymentCredential.hash.toString("hex")) ? total.plus(o.amount) : total.plus(0), new BigNumber(0)); const txCertificates = unsignedTransaction.getCertificates(); const stakeRegistrationCertificates = []; const stakeDeRegistrationCertificates = []; txCertificates.forEach(c => { if (c.type === TyphonTypes.CertificateType.STAKE_REGISTRATION) { stakeRegistrationCertificates.push(c); } else if (c.type === TyphonTypes.CertificateType.STAKE_DE_REGISTRATION) { stakeDeRegistrationCertificates.push(c); } }); const txWithdrawals = unsignedTransaction.getWithdrawals(); const transactionHash = unsignedTransaction.getTransactionHash().toString("hex"); const auxiliaryData = unsignedTransaction.getAuxiliaryData(); const extra = {}; if (auxiliaryData) { const memoMetadata = auxiliaryData.metadata.find(m => m.label === MEMO_LABEL); if (memoMetadata && memoMetadata.data instanceof Map) { const msg = memoMetadata.data.get("msg"); if (Array.isArray(msg) && msg.length) { extra.memo = msg.join(", "); } } } let operationValue = accountOutput.minus(accountInput); if (stakeRegistrationCertificates.length) { const walletRegistration = stakeRegistrationCertificates.find(c => c.cert.stakeCredential.type === HashType.ADDRESS && c.cert.stakeCredential.hash.toString("hex") === stakeCredential.key); if (walletRegistration) { extra.deposit = formatCurrencyUnit(account.currency.units[0], new BigNumber(protocolParams.stakeKeyDeposit), { showCode: true, disableRounding: true, }); } } if (stakeDeRegistrationCertificates.length) { const walletDeRegistration = stakeDeRegistrationCertificates.find(c => c.cert.stakeCredential.type === HashType.ADDRESS && c.cert.stakeCredential.hash.toString("hex") === stakeCredential.key); if (walletDeRegistration) { operationValue = operationValue.minus(protocolParams.stakeKeyDeposit); extra.refund = formatCurrencyUnit(account.currency.units[0], new BigNumber(protocolParams.stakeKeyDeposit), { showCode: true, disableRounding: true, }); } } if (txWithdrawals && txWithdrawals.length) { const walletWithdraw = txWithdrawals.find(w => w.rewardAccount.stakeCredential.type === HashType.ADDRESS && w.rewardAccount.stakeCredential.hash.toString("hex") === stakeCredential.key); if (walletWithdraw) { operationValue = operationValue.minus(walletWithdraw.amount); extra.rewards = formatCurrencyUnit(account.currency.units[0], new BigNumber(walletWithdraw.amount), { showCode: true, disableRounding: true, }); } } const opType = txCertificates.find(c => c.type === TyphonTypes.CertificateType.STAKE_DELEGATION) ? "DELEGATE" : txCertificates.find(c => c.type === TyphonTypes.CertificateType.STAKE_KEY_DE_REGISTRATION) ? "UNDELEGATE" : getOperationType({ valueChange: operationValue, fees: unsignedTransaction.getFee(), }); const op = { id: encodeOperationId(account.id, transactionHash, opType), hash: transactionHash, type: opType, value: operationValue.absoluteValue(), fee: unsignedTransaction.getFee(), blockHash: undefined, blockHeight: null, senders: unsignedTransaction.getInputs().map(i => i.address.getBech32()), recipients: unsignedTransaction.getOutputs().map(o => o.address.getBech32()), accountId: account.id, date: new Date(), extra, }; const tokenAccount = transaction.subAccountId ? account.subAccounts?.find(ta => ta.id === transaction.subAccountId) : null; if (tokenAccount && opType === "OUT") { op.subOperations = [ { id: encodeOperationId(tokenAccount.id, transactionHash, opType), hash: transactionHash, type: opType, value: transaction.useAllAmount ? tokenAccount.balance : transaction.amount, fee: transaction.fees, blockHash: undefined, blockHeight: null, senders: unsignedTransaction.getInputs().map(i => i.address.getBech32()), recipients: unsignedTransaction.getOutputs().map(o => o.address.getBech32()), accountId: tokenAccount.id, date: new Date(), extra: {}, }, ]; } return op; }; //# sourceMappingURL=buildOptimisticOperation.js.map