@ledgerhq/live-common
Version:
Common ground for the Ledger Live apps
283 lines (260 loc) • 6.57 kB
text/typescript
import { BigNumber } from "bignumber.js";
import { Transaction } from "../../generated/types";
import { TransactionCommon } from "@ledgerhq/types-live";
export type { SwapLiveError } from "@ledgerhq/wallet-api-exchange-module";
export function defaultTransaction({
family,
amount,
recipient,
customFeeConfig,
}: TransactionWithCustomFee): Partial<Transaction> {
// Type assertion needed because each Transaction family has different required properties
// This function provides base properties that are then extended by family-specific functions
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
return {
family,
amount,
recipient,
...customFeeConfig,
} as Partial<Transaction>;
}
export function cardanoTransaction({
amount,
recipient,
customFeeConfig,
}: TransactionWithCustomFee): Partial<Extract<Transaction, { family: "cardano" }>> {
return {
family: "cardano",
amount,
recipient,
mode: "send",
...customFeeConfig,
};
}
export function nearTransaction({
amount,
recipient,
customFeeConfig,
}: TransactionWithCustomFee): Extract<Transaction, { family: "near" }> {
return {
family: "near",
amount,
recipient,
mode: "send",
...customFeeConfig,
};
}
export function tezosTransaction({
amount,
recipient,
customFeeConfig,
}: TransactionWithCustomFee): Partial<Extract<Transaction, { family: "tezos" }>> {
return {
family: "tezos",
amount,
recipient,
mode: "send",
...customFeeConfig,
};
}
export function tronTransaction({
amount,
recipient,
customFeeConfig,
}: TransactionWithCustomFee): Partial<Extract<Transaction, { family: "tron" }>> {
return {
family: "tron",
amount,
recipient,
mode: "send",
...customFeeConfig,
};
}
export function stellarTransaction({
amount,
recipient,
customFeeConfig,
payinExtraId,
customErrorType,
}: TransactionWithCustomFee): Extract<Transaction, { family: "stellar" }> {
if (!payinExtraId)
throw {
error: new Error("Missing payinExtraId"),
step: "PayinExtraIdStepError",
customErrorType,
};
return {
family: "stellar",
mode: "send",
amount,
recipient,
...customFeeConfig,
memoValue: payinExtraId,
memoType: "MEMO_TEXT",
};
}
export function rippleTransaction({
amount,
recipient,
customFeeConfig,
payinExtraId,
customErrorType,
}: TransactionWithCustomFee): Partial<Extract<Transaction, { family: "xrp" }>> {
if (!payinExtraId)
throw {
error: new Error("Missing payinExtraId"),
step: "PayinExtraIdStepError",
customErrorType,
};
return {
family: "xrp",
amount,
recipient,
...customFeeConfig,
tag: new BigNumber(payinExtraId).toNumber(),
};
}
export function evmTransaction({
amount,
recipient,
customFeeConfig,
extraTransactionParameters,
}: TransactionWithCustomFee): Partial<Extract<Transaction, { family: "evm" }>> {
if (customFeeConfig?.gasLimit) {
delete customFeeConfig.gasLimit;
}
if (extraTransactionParameters) {
return {
family: "evm" as const,
amount,
recipient,
...customFeeConfig,
data: Buffer.from(extraTransactionParameters, "hex"),
};
}
return {
family: "evm" as const,
amount,
recipient,
...customFeeConfig,
};
}
export function bitcoinTransaction({
amount,
recipient,
customFeeConfig,
extraTransactionParameters,
}: TransactionWithCustomFee): Partial<Extract<Transaction, { family: "bitcoin" }>> {
const baseTransaction = {
family: "bitcoin" as const,
amount,
recipient,
...customFeeConfig,
};
if (extraTransactionParameters) {
return {
...baseTransaction,
opReturnData: Buffer.from(extraTransactionParameters, "utf-8"),
};
}
return baseTransaction;
}
export function solanaTransaction({
amount,
recipient,
customFeeConfig: _customFeeConfig,
}: TransactionWithCustomFee): Extract<Transaction, { family: "solana" }> {
return {
family: "solana",
amount,
recipient,
model: { kind: "transfer", uiState: {} },
};
}
export function elrondTransaction({
amount,
recipient,
customFeeConfig,
}: TransactionWithCustomFee): Extract<Transaction, { family: "multiversx" }> {
return {
family: "multiversx",
amount,
recipient,
mode: "send",
fees: customFeeConfig.fees || null,
gasLimit: customFeeConfig.gasLimit ? Number(customFeeConfig.gasLimit) : 0,
};
}
function tonTransaction({
amount,
recipient,
customFeeConfig: _customFeeConfig,
}: TransactionWithCustomFee): Extract<Transaction, { family: "ton" }> {
return {
family: "ton",
amount,
recipient,
comment: { isEncrypted: false, text: "" },
fees: new BigNumber(0), // Set default value as completeExchange call prepareTransaction, which set again fees.
};
}
export function cosmosTransaction({
amount,
recipient,
customFeeConfig,
payinExtraId,
}: TransactionWithCustomFee): Partial<Extract<Transaction, { family: "cosmos" }>> {
return {
family: "cosmos",
amount,
recipient,
mode: "send",
networkInfo: null,
...customFeeConfig,
memo: payinExtraId ?? undefined,
};
}
export type TransactionWithCustomFee = TransactionCommon & {
customFeeConfig: {
[key: string]: BigNumber;
};
payinExtraId?: string;
customErrorType?: "swap";
extraTransactionParameters?: string;
family: string;
};
// Define a specific type for the strategy functions, assuming they might need parameters
export type TransactionStrategyFunction = (
params: TransactionWithCustomFee,
) => Partial<Transaction>;
export const transactionStrategy: {
[K in Transaction["family"]]: TransactionStrategyFunction;
} = {
algorand: defaultTransaction,
aptos: defaultTransaction,
bitcoin: bitcoinTransaction,
canton: defaultTransaction,
cardano: cardanoTransaction,
casper: defaultTransaction,
celo: defaultTransaction,
cosmos: cosmosTransaction,
evm: evmTransaction,
filecoin: defaultTransaction,
hedera: defaultTransaction,
icon: defaultTransaction,
internet_computer: defaultTransaction,
mina: defaultTransaction,
multiversx: elrondTransaction,
near: nearTransaction,
polkadot: defaultTransaction,
solana: solanaTransaction,
stacks: defaultTransaction,
stellar: stellarTransaction,
sui: defaultTransaction,
tezos: tezosTransaction,
ton: tonTransaction,
tron: tronTransaction,
vechain: defaultTransaction,
kaspa: defaultTransaction,
xrp: rippleTransaction,
};