diff --git a/.changeset/rude-zebras-thank.md b/.changeset/rude-zebras-thank.md
new file mode 100644
index 000000000000..4deeafeee763
--- /dev/null
+++ b/.changeset/rude-zebras-thank.md
@@ -0,0 +1,5 @@
+---
+"ledger-live-desktop": minor
+---
+
+use common MemoTagField for sol/xrp and extract memo related value from transaction coin/by/coin
diff --git a/apps/ledger-live-desktop/src/newArch/features/MemoTag/__tests__/utils.test.ts b/apps/ledger-live-desktop/src/newArch/features/MemoTag/__tests__/utils.test.ts
new file mode 100644
index 000000000000..4b72db74ab52
--- /dev/null
+++ b/apps/ledger-live-desktop/src/newArch/features/MemoTag/__tests__/utils.test.ts
@@ -0,0 +1,47 @@
+import { getMemoTagValueByTransactionFamily } from "../utils";
+import { Transaction } from "@ledgerhq/live-common/generated/types";
+import { Transaction as StellarTransaction } from "@ledgerhq/live-common/families/stellar/types";
+import { Transaction as SolanaTransaction } from "@ledgerhq/live-common/families/solana/types";
+
+describe("getMemoTagValueByTransactionFamily", () => {
+ it("should return empty string if transaction family is not recognized", () => {
+ const transaction: Transaction = { family: "unknown" } as Transaction;
+ expect(getMemoTagValueByTransactionFamily(transaction)).toBeUndefined();
+ });
+
+ it("should return tag for xrp family", () => {
+ const transaction: Transaction = { family: "xrp", tag: 12345 } as Transaction;
+ expect(getMemoTagValueByTransactionFamily(transaction)).toBe(12345);
+ });
+
+ it("should return comment text for ton family", () => {
+ const transaction: Transaction = {
+ family: "ton",
+ comment: { text: "Test comment" },
+ } as Transaction;
+ expect(getMemoTagValueByTransactionFamily(transaction)).toBe("Test comment");
+ });
+
+ it("should return memoValue for stellar family", () => {
+ const transaction: StellarTransaction = {
+ family: "stellar",
+ memoValue: "Stellar memo",
+ } as StellarTransaction;
+ expect(getMemoTagValueByTransactionFamily(transaction)).toBe("Stellar memo");
+ });
+
+ it("should return memo for solana family", () => {
+ const transaction: SolanaTransaction = {
+ family: "solana",
+ model: { uiState: { memo: "Solana memo" } },
+ } as SolanaTransaction;
+ expect(getMemoTagValueByTransactionFamily(transaction)).toBe("Solana memo");
+ });
+
+ it("should return memo for default case", () => {
+ const transaction: Transaction = { family: "cosmos", memo: "Default memo" } as Transaction & {
+ memo: string;
+ };
+ expect(getMemoTagValueByTransactionFamily(transaction)).toBe("Default memo");
+ });
+});
diff --git a/apps/ledger-live-desktop/src/newArch/features/MemoTag/constants.ts b/apps/ledger-live-desktop/src/newArch/features/MemoTag/constants.ts
index 77ccc2914a04..acd8e01332a9 100644
--- a/apps/ledger-live-desktop/src/newArch/features/MemoTag/constants.ts
+++ b/apps/ledger-live-desktop/src/newArch/features/MemoTag/constants.ts
@@ -1,15 +1,14 @@
export const MEMO_TAG_COINS: string[] = [
- "ripple",
- "stellar",
+ "algorand",
+ "cardano",
+ "casper",
"cosmos",
- "hedera",
- "injective",
"crypto_org",
- "crypto_org_croeseid",
+ "hedera",
+ "internet_computer",
+ "solana",
"stacks",
+ "stellar",
"ton",
- "eos",
- "bsc",
- "casper",
- "cardano",
+ "xrp",
];
diff --git a/apps/ledger-live-desktop/src/newArch/features/MemoTag/utils.ts b/apps/ledger-live-desktop/src/newArch/features/MemoTag/utils.ts
new file mode 100644
index 000000000000..fe175df6b2e2
--- /dev/null
+++ b/apps/ledger-live-desktop/src/newArch/features/MemoTag/utils.ts
@@ -0,0 +1,33 @@
+import { Transaction } from "@ledgerhq/live-common/generated/types";
+import { Transaction as StellarTransaction } from "@ledgerhq/live-common/families/stellar/types";
+import { Transaction as SolanaTransaction } from "@ledgerhq/live-common/families/solana/types";
+import { MEMO_TAG_COINS } from "./constants";
+
+/**
+ * Retrieves the memo tag value from a transaction based on its family type.
+ *
+ * @param {Transaction} transaction - The transaction object from which to extract the memo tag value.
+ * @returns {string | undefined} The memo tag value if the transaction family is supported, otherwise undefined.
+ */
+export const getMemoTagValueByTransactionFamily = (transaction: Transaction) => {
+ if (!MEMO_TAG_COINS.includes(transaction?.family as string)) return undefined;
+ const { family } = transaction;
+ switch (family) {
+ case "xrp":
+ return transaction?.tag;
+ case "ton":
+ return transaction?.comment?.text;
+ case "stellar":
+ return (transaction as StellarTransaction)?.memoValue;
+ case "solana":
+ return (
+ transaction as SolanaTransaction & {
+ model: {
+ uiState: { memo: string };
+ };
+ }
+ )?.model.uiState.memo;
+ default:
+ return (transaction as Transaction & { memo: string })?.memo;
+ }
+};
diff --git a/apps/ledger-live-desktop/src/renderer/families/solana/MemoValueField.tsx b/apps/ledger-live-desktop/src/renderer/families/solana/MemoValueField.tsx
index 6f0b076a773d..a841bed5a8c7 100644
--- a/apps/ledger-live-desktop/src/renderer/families/solana/MemoValueField.tsx
+++ b/apps/ledger-live-desktop/src/renderer/families/solana/MemoValueField.tsx
@@ -8,16 +8,21 @@ import {
Transaction,
SolanaAccount,
} from "@ledgerhq/live-common/families/solana/types";
+import { useFeature } from "@ledgerhq/live-common/featureFlags/index";
+import MemoTagField from "~/newArch/features/MemoTag/components/MemoTagField";
type Props = {
onChange: (t: Transaction) => void;
transaction: Transaction;
status: TransactionStatus;
account: SolanaAccount;
+ autoFocus?: boolean;
};
-const MemoValueField = ({ onChange, account, transaction, status }: Props) => {
+const MemoValueField = ({ onChange, account, transaction, status, autoFocus }: Props) => {
const { t } = useTranslation();
+ const lldMemoTag = useFeature("lldMemoTag");
+
invariant(transaction.family === "solana", "Memo: solana family expected");
const bridge = getAccountBridge(account);
const onMemoValueChange = useCallback(
@@ -36,13 +41,17 @@ const MemoValueField = ({ onChange, account, transaction, status }: Props) => {
},
[onChange, transaction, bridge],
);
+
+ const InputField = lldMemoTag?.enabled ? MemoTagField : Input;
+
return transaction.model.kind === "transfer" || transaction.model.kind === "token.transfer" ? (
-
) : null;
};
diff --git a/apps/ledger-live-desktop/src/renderer/families/solana/SendRecipientFields.tsx b/apps/ledger-live-desktop/src/renderer/families/solana/SendRecipientFields.tsx
index 23bd4a699d1a..d15c25e9402d 100644
--- a/apps/ledger-live-desktop/src/renderer/families/solana/SendRecipientFields.tsx
+++ b/apps/ledger-live-desktop/src/renderer/families/solana/SendRecipientFields.tsx
@@ -8,6 +8,7 @@ import {
Transaction,
SolanaAccount,
} from "@ledgerhq/live-common/families/solana/types";
+import { useFeature } from "@ledgerhq/live-common/featureFlags/index";
type Props = {
onChange: (t: Transaction) => void;
@@ -17,15 +18,19 @@ type Props = {
};
const Root = (props: Props) => {
+ const lldMemoTag = useFeature("lldMemoTag");
+
return (
-
-
-
+ {!lldMemoTag?.enabled && (
+
+
+
+ )}
diff --git a/apps/ledger-live-desktop/src/renderer/families/stellar/MemoTypeField.tsx b/apps/ledger-live-desktop/src/renderer/families/stellar/MemoTypeField.tsx
index f5579ba0df51..7e628d028de3 100644
--- a/apps/ledger-live-desktop/src/renderer/families/stellar/MemoTypeField.tsx
+++ b/apps/ledger-live-desktop/src/renderer/families/stellar/MemoTypeField.tsx
@@ -28,6 +28,7 @@ const MemoTypeField = ({
onChange(
bridge.updateTransaction(transaction, {
memoType: memoType.value,
+ memoValue: memoType.value === "NO_MEMO" ? "" : transaction.memoValue,
}),
);
},
diff --git a/apps/ledger-live-desktop/src/renderer/families/ton/CommentField.tsx b/apps/ledger-live-desktop/src/renderer/families/ton/CommentField.tsx
index 09a302497386..03f952c18301 100644
--- a/apps/ledger-live-desktop/src/renderer/families/ton/CommentField.tsx
+++ b/apps/ledger-live-desktop/src/renderer/families/ton/CommentField.tsx
@@ -1,9 +1,11 @@
import { getAccountBridge } from "@ledgerhq/live-common/bridge/index";
import { Transaction, TransactionStatus } from "@ledgerhq/live-common/families/ton/types";
+import { useFeature } from "@ledgerhq/live-common/featureFlags/index";
import { Account } from "@ledgerhq/types-live";
import invariant from "invariant";
import React, { useCallback } from "react";
import { useTranslation } from "react-i18next";
+import MemoTagField from "~/newArch/features/MemoTag/components/MemoTagField";
import Input from "~/renderer/components/Input";
const CommentField = ({
@@ -11,17 +13,20 @@ const CommentField = ({
account,
transaction,
status,
+ autoFocus,
}: {
onChange: (a: Transaction) => void;
account: Account;
transaction: Transaction;
status: TransactionStatus;
+ autoFocus?: boolean;
}) => {
invariant(transaction.family === "ton", "Comment: TON family expected");
const { t } = useTranslation();
const bridge = getAccountBridge(account);
+ const lldMemoTag = useFeature("lldMemoTag");
const onCommentFieldChange = useCallback(
(value: string) => {
@@ -34,16 +39,19 @@ const CommentField = ({
[onChange, transaction, bridge],
);
+ const InputField = lldMemoTag?.enabled ? MemoTagField : Input;
+
// We use transaction as an error here.
// on the ledger-live mobile
return (
-
);
};
diff --git a/apps/ledger-live-desktop/src/renderer/families/ton/SendRecipientFields.tsx b/apps/ledger-live-desktop/src/renderer/families/ton/SendRecipientFields.tsx
index 530bb70fe01d..5387a1d41d49 100644
--- a/apps/ledger-live-desktop/src/renderer/families/ton/SendRecipientFields.tsx
+++ b/apps/ledger-live-desktop/src/renderer/families/ton/SendRecipientFields.tsx
@@ -6,6 +6,7 @@ import Box from "~/renderer/components/Box";
import Label from "~/renderer/components/Label";
import LabelInfoTooltip from "~/renderer/components/LabelInfoTooltip";
import CommentField from "./CommentField";
+import { useFeature } from "@ledgerhq/live-common/featureFlags/index";
const Root = (props: {
account: Account;
@@ -13,18 +14,22 @@ const Root = (props: {
status: TransactionStatus;
onChange: (a: Transaction) => void;
trackProperties?: object;
+ autoFocus?: boolean;
}) => {
+ const lldMemoTag = useFeature("lldMemoTag");
return (
-
-
-
+ {!lldMemoTag?.enabled && (
+
+
+
+ )}
void;
transaction: Transaction;
account: Account;
+ autoFocus?: boolean;
};
const uint32maxPlus1 = BigNumber(2).pow(32);
-const TagField = ({ onChange, account, transaction }: Props) => {
+const TagField = ({ onChange, account, transaction, autoFocus }: Props) => {
const onChangeTag = useCallback(
(str: string) => {
const bridge = getAccountBridge(account);
@@ -31,7 +32,13 @@ const TagField = ({ onChange, account, transaction }: Props) => {
},
[onChange, account, transaction],
);
- return ;
+ return (
+
+ );
};
export default {
component: TagField,
diff --git a/apps/ledger-live-desktop/src/renderer/modals/Send/steps/StepRecipient.tsx b/apps/ledger-live-desktop/src/renderer/modals/Send/steps/StepRecipient.tsx
index ae00356cea58..e6bbd99a18d2 100644
--- a/apps/ledger-live-desktop/src/renderer/modals/Send/steps/StepRecipient.tsx
+++ b/apps/ledger-live-desktop/src/renderer/modals/Send/steps/StepRecipient.tsx
@@ -28,6 +28,7 @@ import CheckBox from "~/renderer/components/CheckBox";
import { alwaysShowMemoTagInfoSelector } from "~/renderer/reducers/application";
import { toggleShouldDisplayMemoTagInfo } from "~/renderer/actions/application";
import { useFeature } from "@ledgerhq/live-common/featureFlags/index";
+import { getMemoTagValueByTransactionFamily } from "~/newArch/features/MemoTag/utils";
const StepRecipient = ({
t,
@@ -153,9 +154,10 @@ export const StepRecipientFooter = ({
const alwaysShowMemoTagInfo = useSelector(alwaysShowMemoTagInfoSelector);
const handleOnNext = async () => {
+ const memoTagValue = getMemoTagValueByTransactionFamily(transaction as Transaction);
if (
lldMemoTag?.enabled &&
- !transaction?.memo &&
+ !memoTagValue &&
MEMO_TAG_COINS.includes(transaction?.family as string) &&
alwaysShowMemoTagInfo
) {
diff --git a/apps/ledger-live-desktop/src/renderer/modals/Send/steps/StepSummary.tsx b/apps/ledger-live-desktop/src/renderer/modals/Send/steps/StepSummary.tsx
index 69aed778c0d4..dfb2006cb507 100644
--- a/apps/ledger-live-desktop/src/renderer/modals/Send/steps/StepSummary.tsx
+++ b/apps/ledger-live-desktop/src/renderer/modals/Send/steps/StepSummary.tsx
@@ -30,6 +30,7 @@ import { useMaybeAccountName } from "~/renderer/reducers/wallet";
import MemoIcon from "~/renderer/icons/MemoIcon";
import { Flex } from "@ledgerhq/react-ui";
import { useFeature } from "@ledgerhq/live-common/featureFlags/index";
+import { getMemoTagValueByTransactionFamily } from "~/newArch/features/MemoTag/utils";
const FromToWrapper = styled.div``;
const Circle = styled.div`
@@ -84,8 +85,13 @@ const StepSummary = (props: StepProps) => {
const specific = currency ? getLLDCoinFamily(mainAccount.currency.family) : null;
const SpecificSummaryNetworkFeesRow = specific?.StepSummaryNetworkFeesRow;
- const memo = "memo" in transaction ? transaction.memo : undefined;
-
+ const memo = lldMemoTag?.enabled
+ ? getMemoTagValueByTransactionFamily(transaction)
+ : (
+ transaction as Transaction & {
+ memo: string;
+ }
+ )?.memo;
const handleOnEditMemo = () => {
transitionTo("recipient");
};
diff --git a/apps/ledger-live-desktop/src/renderer/modals/Send/types.ts b/apps/ledger-live-desktop/src/renderer/modals/Send/types.ts
index 5c1ed0aee44b..8d96f1b3bfbf 100644
--- a/apps/ledger-live-desktop/src/renderer/modals/Send/types.ts
+++ b/apps/ledger-live-desktop/src/renderer/modals/Send/types.ts
@@ -12,7 +12,7 @@ export type StepProps = {
device: Device | undefined | null;
account: AccountLike | undefined | null;
parentAccount: Account | undefined | null;
- transaction: (Transaction & { memo?: string }) | undefined | null;
+ transaction: Transaction | undefined | null;
status: TransactionStatus;
bridgePending: boolean;
error: Error | undefined | null;