From 1a949f0ad3b59cadfe8d185ed27a33b868869e06 Mon Sep 17 00:00:00 2001 From: Mikhail Date: Tue, 20 Aug 2024 14:51:45 +0300 Subject: [PATCH] fix(LLD, LLM): token summary and device screens --- apps/ledger-live-desktop/src/config/urls.ts | 2 + .../solana/TransactionConfirmFields.tsx | 67 +++++++++++++++++++ .../src/renderer/families/solana/index.ts | 2 + .../static/i18n/en/app.json | 3 +- .../solana/TransactionConfirmFields.tsx | 46 +++++++++++++ .../src/locales/en/common.json | 3 +- apps/ledger-live-mobile/src/utils/urls.tsx | 1 + .../src/deviceTransactionConfig.ts | 44 ++---------- 8 files changed, 128 insertions(+), 40 deletions(-) create mode 100644 apps/ledger-live-desktop/src/renderer/families/solana/TransactionConfirmFields.tsx create mode 100644 apps/ledger-live-mobile/src/families/solana/TransactionConfirmFields.tsx diff --git a/apps/ledger-live-desktop/src/config/urls.ts b/apps/ledger-live-desktop/src/config/urls.ts index 6203ebbcfcbe..45b7fb04cf5d 100644 --- a/apps/ledger-live-desktop/src/config/urls.ts +++ b/apps/ledger-live-desktop/src/config/urls.ts @@ -4,6 +4,7 @@ export const supportLinkByTokenType = { trc20: "https://support.ledger.com/article/360013062159-zd", asa: "https://support.ledger.com/article/360015896040-zd", nfts: "https://support.ledger.com/article/4404389453841-zd", + // spl: "Solana spl tokens. TODO: to be defined", }; const errors: Record = { @@ -153,6 +154,7 @@ export const urls = { }, solana: { staking: "https://support.ledger.com/article/4731749170461-zd", + splTokenInfo: "Solana spl tokens link TODO: to be defined", recipient_info: "https://support.ledger.com", ledgerByFigmentTC: "https://cdn.figment.io/legal/Current%20Ledger_Online%20Staking%20Delgation%20Services%20Agreement.pdf", diff --git a/apps/ledger-live-desktop/src/renderer/families/solana/TransactionConfirmFields.tsx b/apps/ledger-live-desktop/src/renderer/families/solana/TransactionConfirmFields.tsx new file mode 100644 index 000000000000..877c580773c9 --- /dev/null +++ b/apps/ledger-live-desktop/src/renderer/families/solana/TransactionConfirmFields.tsx @@ -0,0 +1,67 @@ +import React, { useMemo } from "react"; +import { getDeviceTransactionConfig } from "@ledgerhq/live-common/transaction/index"; +import { SolanaFamily } from "./types"; +import Alert from "~/renderer/components/Alert"; +import { Trans } from "react-i18next"; +import ConfirmTitle from "~/renderer/components/TransactionConfirm/ConfirmTitle"; +import LinkWithExternalIcon from "~/renderer/components/LinkWithExternalIcon"; +import Box from "~/renderer/components/Box"; +import { openURL } from "~/renderer/linking"; +import { useLocalizedUrl } from "~/renderer/hooks/useLocalizedUrls"; +import { urls } from "~/config/urls"; + +const Title: TitleComponent = props => { + const { transaction, account, parentAccount, status } = props; + const transferTokenHelpUrl = useLocalizedUrl(urls.solana.splTokenInfo); + + const fields = getDeviceTransactionConfig({ + account, + parentAccount, + transaction, + status, + }); + + const typeTransaction: string | undefined = useMemo(() => { + const typeField = fields.find(field => field.label && field.label === "Type"); + + if (typeField && typeField.type === "text" && typeField.value) { + return typeField.value; + } + }, [fields]); + + if (transaction.model.commandDescriptor?.command.kind === "token.transfer") { + return ( + + + + + openURL(transferTokenHelpUrl)} + /> + + + + ); + } + + return ; +}; + +type TransactionConfirmFields = SolanaFamily["transactionConfirmFields"]; +type TitleComponent = NonNullable["title"]>; + +const transactionConfirmFields: TransactionConfirmFields = { + // footer: Footer, // is not shown without manifestId + // fieldComponents, + title: Title, +}; + +export default transactionConfirmFields; diff --git a/apps/ledger-live-desktop/src/renderer/families/solana/index.ts b/apps/ledger-live-desktop/src/renderer/families/solana/index.ts index da1314ef035f..3396136c9ec2 100644 --- a/apps/ledger-live-desktop/src/renderer/families/solana/index.ts +++ b/apps/ledger-live-desktop/src/renderer/families/solana/index.ts @@ -6,6 +6,7 @@ import AccountBalanceSummaryFooter from "./AccountBalanceSummaryFooter"; import StakeBanner from "./StakeBanner"; import { SolanaFamily } from "./types"; import operationDetails from "./operationDetails"; +import transactionConfirmFields from "./TransactionConfirmFields"; const family: SolanaFamily = { accountHeaderManageActions, @@ -15,6 +16,7 @@ const family: SolanaFamily = { AccountBalanceSummaryFooter, StakeBanner, operationDetails, + transactionConfirmFields, }; export default family; diff --git a/apps/ledger-live-desktop/static/i18n/en/app.json b/apps/ledger-live-desktop/static/i18n/en/app.json index 05cbfa2ae70e..30b0b7d7487a 100644 --- a/apps/ledger-live-desktop/static/i18n/en/app.json +++ b/apps/ledger-live-desktop/static/i18n/en/app.json @@ -3719,7 +3719,8 @@ } }, "token": { - "frozenStateWarning": "Account assets are frozen!" + "frozenStateWarning": "Account assets are frozen!", + "transferWarning": "Solana SPL tokens transactions have unique characteristics. To learn more, visit: <0>ledger.com/spl" } }, "ethereum": { diff --git a/apps/ledger-live-mobile/src/families/solana/TransactionConfirmFields.tsx b/apps/ledger-live-mobile/src/families/solana/TransactionConfirmFields.tsx new file mode 100644 index 000000000000..4bf31f76ebfd --- /dev/null +++ b/apps/ledger-live-mobile/src/families/solana/TransactionConfirmFields.tsx @@ -0,0 +1,46 @@ +import invariant from "invariant"; +import React from "react"; +import { Linking, View } from "react-native"; +import { Trans } from "react-i18next"; +import { Link } from "@ledgerhq/native-ui"; +import { DeviceTransactionField } from "@ledgerhq/live-common/transaction/index"; +import { + SolanaAccount, + SolanaTokenAccount, + Transaction, + TransactionStatus, +} from "@ledgerhq/live-common/families/solana/types"; +import Alert from "~/components/Alert"; +import { urls } from "~/utils/urls"; +import LText from "~/components/LText"; + +type SolanaFieldComponentProps = { + account: SolanaAccount | SolanaTokenAccount; + parentAccount: SolanaAccount | undefined | null; + transaction: Transaction; + status: TransactionStatus; + field: DeviceTransactionField; +}; + +const Warning = ({ transaction }: SolanaFieldComponentProps) => { + invariant(transaction.family === "solana", "solana transaction"); + if (transaction.model.commandDescriptor?.command.kind === "token.transfer") { + return ( + + + + + Linking.openURL(urls.solana.splTokenInfo)} type="color" /> + + + + + ); + } + return null; +}; + +export default { + warning: Warning, + fieldComponents: {}, +}; diff --git a/apps/ledger-live-mobile/src/locales/en/common.json b/apps/ledger-live-mobile/src/locales/en/common.json index bd1d45a9cfc6..c9c7329989e8 100644 --- a/apps/ledger-live-mobile/src/locales/en/common.json +++ b/apps/ledger-live-mobile/src/locales/en/common.json @@ -5914,7 +5914,8 @@ "reserveWarning": "Please ensure you reserve at least {{amount}} SOL in your wallet to cover future network fees to deactivate and withdraw your stake" }, "token": { - "frozenStateWarning": "Account assets are frozen!" + "frozenStateWarning": "Account assets are frozen!", + "transferWarning": "Double-check the transaction details on your Ledger device before signing. Solana SPL tokens transactions have unique characteristics. To learn more, visit: <0>ledger.com/spl" } }, "near": { diff --git a/apps/ledger-live-mobile/src/utils/urls.tsx b/apps/ledger-live-mobile/src/utils/urls.tsx index 0fd754e885e0..dbc53be52d66 100644 --- a/apps/ledger-live-mobile/src/utils/urls.tsx +++ b/apps/ledger-live-mobile/src/utils/urls.tsx @@ -166,6 +166,7 @@ export const urls = { solana: { supportPage: "https://support.ledger.com", stakingPage: "https://support.ledger.com/article/4731749170461-zd", + splTokenInfo: "Solana spl tokens link TODO: to be defined", }, resources: { gettingStarted: diff --git a/libs/coin-modules/coin-solana/src/deviceTransactionConfig.ts b/libs/coin-modules/coin-solana/src/deviceTransactionConfig.ts index 965a1997afe0..93500d8d4987 100644 --- a/libs/coin-modules/coin-solana/src/deviceTransactionConfig.ts +++ b/libs/coin-modules/coin-solana/src/deviceTransactionConfig.ts @@ -70,55 +70,23 @@ function fieldsForTransfer(_command: TransferCommand): DeviceTransactionField[] return fields; } -function fieldsForTokenTransfer(command: TokenTransferCommand): DeviceTransactionField[] { +function fieldsForTokenTransfer(_command: TokenTransferCommand): DeviceTransactionField[] { const fields: Array = []; - if (command.recipientDescriptor.shouldCreateAsAssociatedTokenAccount) { - fields.push({ - type: "address", - label: "Create token acct", - address: command.recipientDescriptor.tokenAccAddress, - }); - - fields.push({ - type: "address", - label: "From mint", - address: command.mintAddress, - }); - fields.push({ - type: "address", - label: "Funded by", - address: command.ownerAddress, - }); - } - fields.push({ type: "amount", label: "Transfer tokens", }); fields.push({ - type: "address", - address: command.mintAddress, - label: "Mint", - }); - - fields.push({ - type: "address", - address: command.ownerAssociatedTokenAccountAddress, - label: "From", - }); - - fields.push({ - type: "address", - address: command.ownerAddress, - label: "Owner", + type: "text", + value: "Solana", + label: "Network", }); fields.push({ - type: "address", - address: command.ownerAddress, - label: "Fee payer", + type: "fees", + label: "Max network fees", }); return fields;