@ledgerhq/live-common
Version:
Common ground for the Ledger Live apps
149 lines • 6.84 kB
JavaScript
import { getCurrencyForAccount, } from "@ledgerhq/types-live";
import { accountToPlatformAccount, getPlatformTransactionSignFlowInfos } from "./converters";
import { deserializePlatformTransaction, deserializePlatformSignedTransaction, } from "./serializers";
import { isTokenAccount, getMainAccount, isAccount } from "../account/index";
import { getAccountBridge } from "../bridge/index";
import { prepareMessageToSign } from "../hw/signMessage/index";
export function translateContent(content, locale = "en") {
if (!content || typeof content === "string")
return content;
return content[locale] || content.en;
}
function getParentAccount(account, fromAccounts) {
return isTokenAccount(account)
? fromAccounts.find(a => a.id === account.parentId)
: undefined;
}
export function receiveOnAccountLogic(walletState, { manifest, accounts, tracking }, accountId, uiNavigation) {
tracking.platformReceiveRequested(manifest);
const account = accounts.find(account => account.id === accountId);
if (!account) {
tracking.platformReceiveFail(manifest);
return Promise.reject(new Error("Account required"));
}
const parentAccount = getParentAccount(account, accounts);
const accountAddress = accountToPlatformAccount(walletState, account, parentAccount).address;
return uiNavigation(account, parentAccount, accountAddress);
}
export function signTransactionLogic({ manifest, accounts, tracking }, accountId, transaction, uiNavigation) {
tracking.platformSignTransactionRequested(manifest);
if (!transaction) {
tracking.platformSignTransactionFail(manifest);
return Promise.reject(new Error("Transaction required"));
}
const platformTransaction = deserializePlatformTransaction(transaction);
const account = accounts.find(account => account.id === accountId);
if (!account) {
tracking.platformSignTransactionFail(manifest);
return Promise.reject(new Error("Account required"));
}
const parentAccount = getParentAccount(account, accounts);
const accountFamily = isTokenAccount(account)
? parentAccount?.currency.family
: account.currency.family;
const { canEditFees, liveTx, hasFeesProvided } = getPlatformTransactionSignFlowInfos(platformTransaction);
if (accountFamily !== liveTx.family) {
return Promise.reject(new Error(`Account and transaction must be from the same family. Account family: ${accountFamily}, Transaction family: ${liveTx.family}`));
}
return uiNavigation(account, parentAccount, {
canEditFees,
liveTx,
hasFeesProvided,
});
}
export function broadcastTransactionLogic({ manifest, accounts, tracking }, accountId, signedTransaction, uiNavigation) {
if (!signedTransaction) {
tracking.platformBroadcastFail(manifest);
return Promise.reject(new Error("Transaction required"));
}
const account = accounts.find(account => account.id === accountId);
if (!account) {
tracking.platformBroadcastFail(manifest);
return Promise.reject(new Error("Account required"));
}
const parentAccount = getParentAccount(account, accounts);
const signedOperation = deserializePlatformSignedTransaction(signedTransaction, accountId);
return uiNavigation(account, parentAccount, signedOperation);
}
export function completeExchangeLogic({ manifest, accounts, tracking }, { provider, fromAccountId, toAccountId, transaction, binaryPayload, signature, feesStrategy, exchangeType, }, uiNavigation) {
tracking.platformCompleteExchangeRequested(manifest);
// Nb get a hold of the actual accounts, and parent accounts
const fromAccount = accounts.find(a => a.id === fromAccountId);
const toAccount = accounts.find(a => a.id === toAccountId);
if (!fromAccount) {
return Promise.reject();
}
if (exchangeType === 0x00 && !toAccount) {
// if we do a swap, a destination account must be provided
return Promise.reject();
}
const fromParentAccount = getParentAccount(fromAccount, accounts);
const toParentAccount = toAccount ? getParentAccount(toAccount, accounts) : undefined;
const exchange = {
fromAccount,
fromParentAccount,
toAccount,
toParentAccount,
fromCurrency: getCurrencyForAccount(fromAccount),
toCurrency: toAccount ? getCurrencyForAccount(toAccount) : undefined,
};
const accountBridge = getAccountBridge(fromAccount, fromParentAccount);
const mainFromAccount = getMainAccount(fromAccount, fromParentAccount);
const mainFromAccountFamily = mainFromAccount.currency.family;
const platformTransaction = deserializePlatformTransaction(transaction);
const { liveTx: liveTransaction } = getPlatformTransactionSignFlowInfos(platformTransaction);
if (liveTransaction.family !== mainFromAccountFamily) {
return Promise.reject(new Error(`Account and transaction must be from the same family. Account family: ${mainFromAccountFamily}, Transaction family: ${liveTransaction.family}`));
}
/**
* 'subAccountId' is used for ETH and it's ERC-20 tokens.
* This field is ignored for BTC
*/
const subAccountId = fromParentAccount ? fromAccount.id : undefined;
const bridgeTx = accountBridge.createTransaction(mainFromAccount);
/**
* We append the `recipient` to the tx created from `createTransaction`
* to avoid having userGasLimit reset to null for ETH txs
* cf. libs/ledger-live-common/src/families/ethereum/updateTransaction.ts
*/
const tx = accountBridge.updateTransaction({
...bridgeTx,
recipient: liveTransaction.recipient,
}, {
...liveTransaction,
feesStrategy,
subAccountId,
});
return uiNavigation({
provider,
exchange,
transaction: tx,
binaryPayload,
signature,
feesStrategy,
exchangeType,
});
}
export function signMessageLogic({ manifest, accounts, tracking }, accountId, message, uiNavigation) {
tracking.platformSignMessageRequested(manifest);
const account = accounts.find(account => account.id === accountId);
if (account === undefined) {
tracking.platformSignMessageFail(manifest);
return Promise.reject(new Error(`account with id "${accountId}" not found`));
}
let formattedMessage;
try {
if (isAccount(account)) {
formattedMessage = prepareMessageToSign(account, message);
}
else {
throw new Error("account provided should be the main one");
}
}
catch (error) {
tracking.platformSignMessageFail(manifest);
return Promise.reject(error);
}
return uiNavigation(account, formattedMessage);
}
//# sourceMappingURL=logic.js.map