@ledgerhq/live-common
Version:
Common ground for the Ledger Live apps
98 lines (82 loc) • 2.98 kB
text/typescript
import type { CustomFeeInputDescriptor, FeeDescriptor } from "../../../bridge/descriptor/types";
import { BigNumber } from "bignumber.js";
const GWEI_DIVISOR = new BigNumber(10).pow(9);
function isBigNumber(value: unknown): value is BigNumber {
return BigNumber.isBigNumber(value);
}
function isRecord(value: unknown): value is Record<string, unknown> {
return typeof value === "object" && value !== null;
}
function weiToGwei(wei: BigNumber): string {
return wei.dividedBy(GWEI_DIVISOR).decimalPlaces(6, BigNumber.ROUND_DOWN).toFixed();
}
function gweiToWei(gwei: string): BigNumber {
const val = new BigNumber(gwei);
if (val.isNaN() || val.isNegative()) return new BigNumber(0);
return val.times(GWEI_DIVISOR).integerValue(BigNumber.ROUND_DOWN);
}
function getSuggestedFeesRange(
transaction: Record<string, unknown>,
): { min: string; max: string } | null {
const networkInfo = transaction.networkInfo;
const rawGasPrice = isRecord(networkInfo) ? networkInfo.gasPrice : transaction.gasPrice;
if (isBigNumber(rawGasPrice) && rawGasPrice.gt(0)) {
return {
min: weiToGwei(rawGasPrice.times(0.8).integerValue(BigNumber.ROUND_DOWN)),
max: weiToGwei(rawGasPrice.times(1.2).integerValue(BigNumber.ROUND_UP)),
};
}
const fees = transaction.fees;
if (isBigNumber(fees) && fees.gt(0)) {
return {
min: weiToGwei(fees.times(0.8).integerValue(BigNumber.ROUND_DOWN)),
max: weiToGwei(fees.times(1.2).integerValue(BigNumber.ROUND_UP)),
};
}
return null;
}
const celoCustomInputs: readonly CustomFeeInputDescriptor[] = [
{
key: "fees",
type: "number",
unitLabel: "Gwei",
suggestedRange: {
getRange: transaction => {
if (!isRecord(transaction)) return null;
return getSuggestedFeesRange(transaction);
},
},
},
];
export const fees: FeeDescriptor = {
hasPresets: false,
hasCustom: true,
hasCustomAssets: true,
custom: {
inputs: celoCustomInputs,
getInitialValues: (transaction): Record<string, string> => {
if (!isRecord(transaction)) return { fees: "" };
const feesVal = transaction.fees;
if (!isBigNumber(feesVal) || feesVal.lte(0)) return { fees: "" };
return { fees: weiToGwei(feesVal) };
},
buildTransactionPatch: values => {
const patch: Record<string, unknown> = { feesStrategy: "custom" };
const feesWei = gweiToWei(values.fees ?? "0");
if (!feesWei.isNaN() && feesWei.gt(0)) {
patch.fees = feesWei;
}
return patch;
},
},
customAssets: {
options: [
{ id: "eth", ticker: "ETH", label: "Ethereum", unitLabel: "Gwei" },
{ id: "btc", ticker: "BTC", label: "Bitcoin", unitLabel: "sat" },
{ id: "usdc", ticker: "USDC", label: "USD Coin", unitLabel: "USDC" },
{ id: "usdt", ticker: "USDT", label: "Tether", unitLabel: "USDT" },
{ id: "celo", ticker: "Celo", label: "Celo", unitLabel: "Gwei" },
],
defaultId: "eth",
},
};