@ledgerhq/coin-aptos
Version:
Ledger Aptos Coin integration
107 lines • 4.95 kB
JavaScript
import BigNumber from "bignumber.js";
import { encodeTokenAccountId, findSubAccountById, isTokenAccount, } from "@ledgerhq/coin-framework/account/index";
import { encodeOperationId } from "@ledgerhq/coin-framework/operation";
import { getCryptoAssetsStore } from "@ledgerhq/cryptoassets/state";
import { APTOS_ASSET_ID, OP_TYPE, DEFAULT_GAS, DEFAULT_GAS_PRICE, APTOS_ASSET_FUNGIBLE_ID, } from "../constants";
import { convertFunctionPayloadResponseToInputEntryFunctionData } from "../logic/transactionsToOperations";
import { compareAddress, getCoinAndAmounts } from "../logic/getCoinAndAmounts";
import { calculateAmount } from "../logic/calculateAmount";
import { processRecipients } from "../logic/processRecipients";
import { getFunctionAddress } from "../logic/getFunctionAddress";
export const getMaxSendBalance = (account, parentAccount, gas, gasPrice) => {
gas = gas ?? BigNumber(DEFAULT_GAS);
gasPrice = gasPrice ?? BigNumber(DEFAULT_GAS_PRICE);
const totalGas = gas.multipliedBy(gasPrice);
return parentAccount
? account.spendableBalance
: getMaxSendBalanceFromAccount(account, totalGas);
};
const getMaxSendBalanceFromAccount = (account, totalGas) => account.spendableBalance.gt(totalGas)
? account.spendableBalance.minus(totalGas)
: new BigNumber(0);
export const getBlankOperation = (tx, id) => ({
id: "",
hash: tx.hash,
type: "",
value: new BigNumber(0),
fee: new BigNumber(0),
blockHash: tx.block?.hash,
blockHeight: tx.block?.height,
senders: [],
recipients: [],
accountId: id,
date: new Date(parseInt(tx.timestamp) / 1000),
extra: { version: tx.version },
transactionSequenceNumber: new BigNumber(parseInt(tx.sequence_number)),
hasFailed: false,
});
export const txsToOps = async (info, id, txs) => {
const { address } = info;
const ops = [];
const opsTokens = [];
const opsStaking = [];
for (const tx of txs) {
if (tx !== null) {
const op = getBlankOperation(tx, id);
op.fee = new BigNumber(tx.gas_used).multipliedBy(new BigNumber(tx.gas_unit_price));
const payload = convertFunctionPayloadResponseToInputEntryFunctionData(tx.payload);
const function_address = getFunctionAddress(payload);
if (!function_address) {
continue; // skip transaction without functions in payload
}
const { coin_id, amount_in, amount_out, type } = getCoinAndAmounts(tx, address);
op.value = calculateAmount(tx.sender, address, amount_in, amount_out);
op.type =
type !== OP_TYPE.UNKNOWN
? type
: compareAddress(tx.sender, address)
? OP_TYPE.OUT
: OP_TYPE.IN;
op.senders.push(tx.sender);
op.hasFailed = !tx.success;
op.id = encodeOperationId(op.accountId, tx.hash, op.type);
processRecipients(payload, address, op, function_address);
if (op.value.isZero()) {
// skip transaction that result no Aptos change
op.type = OP_TYPE.UNKNOWN;
}
if (op.type === OP_TYPE.STAKE ||
op.type === OP_TYPE.UNSTAKE ||
op.type === OP_TYPE.WITHDRAW) {
ops.push(op);
opsStaking.push(op);
}
else if (op.type !== OP_TYPE.UNKNOWN && coin_id !== null) {
if (coin_id === APTOS_ASSET_ID || coin_id === APTOS_ASSET_FUNGIBLE_ID) {
ops.push(op);
}
else {
const token = await getCryptoAssetsStore().findTokenByAddressInCurrency(coin_id.toLowerCase(), "aptos");
if (token !== undefined) {
const tokenAccountId = encodeTokenAccountId(id, token);
op.accountId = tokenAccountId;
opsTokens.push(op);
if (op.type === OP_TYPE.OUT) {
const accountId = tokenAccountId.split("+")[0];
// Create FEES operation with decoded main account ID
const feesOp = {
...op,
accountId,
value: op.fee,
type: "FEES",
};
ops.push(feesOp);
}
}
}
}
}
}
return [ops, opsTokens, opsStaking];
};
export function getTokenAccount(account, transaction) {
const tokenAccount = findSubAccountById(account, transaction.subAccountId ?? "");
const fromTokenAccount = tokenAccount && isTokenAccount(tokenAccount);
return fromTokenAccount ? tokenAccount : undefined;
}
//# sourceMappingURL=logic.js.map