From 464a61d41c516cc2d7c45905a0e68dc0c9969ee4 Mon Sep 17 00:00:00 2001 From: chrisduma-ledger Date: Wed, 28 Aug 2024 16:14:25 +0300 Subject: [PATCH 01/13] feat: confirmation message lld --- .../components/DeviceAction/index.tsx | 2 + .../src/renderer/components/LiveAppDrawer.tsx | 12 ++- .../Exchange/CompleteExchange/Body.tsx | 39 +++++--- .../Exchange/CompleteExchange/BodyContent.tsx | 13 ++- .../TransactionBroadcastedContent.tsx | 51 ++++++---- .../src/renderer/reducers/UI.ts | 1 + .../Form/ExchangeDrawer/SellCompleted.tsx | 98 +++++++++++++++++++ .../static/i18n/en/app.json | 10 +- 8 files changed, 188 insertions(+), 38 deletions(-) create mode 100644 apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/ExchangeDrawer/SellCompleted.tsx diff --git a/apps/ledger-live-desktop/src/renderer/components/DeviceAction/index.tsx b/apps/ledger-live-desktop/src/renderer/components/DeviceAction/index.tsx index cd9fd8e9f119..97a50f81a13f 100644 --- a/apps/ledger-live-desktop/src/renderer/components/DeviceAction/index.tsx +++ b/apps/ledger-live-desktop/src/renderer/components/DeviceAction/index.tsx @@ -376,6 +376,7 @@ export const DeviceActionDefaultRendering = ({ case 0x01: // sell case 0x02: // fund + console.log("inside switch!"); return renderSecureTransferDeviceConfirmation({ exchangeType: exchangeType === 0x01 ? "sell" : "fund", modelId, @@ -388,6 +389,7 @@ export const DeviceActionDefaultRendering = ({ } if (initSwapRequested && !initSwapResult && !initSwapError) { + console.log("Init swap requested"); const { transaction, exchange, exchangeRate } = request as { transaction: Transaction; exchange: ExchangeSwap; diff --git a/apps/ledger-live-desktop/src/renderer/components/LiveAppDrawer.tsx b/apps/ledger-live-desktop/src/renderer/components/LiveAppDrawer.tsx index 49940f252f77..c6305f7eb0e3 100644 --- a/apps/ledger-live-desktop/src/renderer/components/LiveAppDrawer.tsx +++ b/apps/ledger-live-desktop/src/renderer/components/LiveAppDrawer.tsx @@ -62,6 +62,9 @@ export function isStartExchangeData(data: unknown): data is StartExchangeData { export const LiveAppDrawer = () => { const [dismissDisclaimerChecked, setDismissDisclaimerChecked] = useState(false); + const { t } = useTranslation(); + const dispatch = useDispatch(); + // @ts-expect-error how to type payload? const { isOpen, @@ -78,8 +81,6 @@ export const LiveAppDrawer = () => { }; } = useSelector(platformAppDrawerStateSelector); - const { t } = useTranslation(); - const dispatch = useDispatch(); const onContinue = useCallback(() => { if (payload && payload.type === "DAPP_DISCLAIMER") { const { manifest, disclaimerId, next } = payload; @@ -90,11 +91,15 @@ export const LiveAppDrawer = () => { next(manifest, dismissDisclaimerChecked); } }, [dismissDisclaimerChecked, dispatch, payload]); + const drawerContent = useMemo(() => { if (!payload) { return null; } const { type, manifest, data } = payload; + console.log("In drawer1", type); + console.log("In drawer2", manifest); + console.log("In drawer3", data); const action = createAction(connectApp, startExchange); switch (type) { case "DAPP_INFO": @@ -153,12 +158,14 @@ export const LiveAppDrawer = () => { ); case "EXCHANGE_START": + console.log("exchange started", data?.onResult.toString()); return data && isStartExchangeData(data) ? ( renderLoading()} onResult={result => { + console.log("Result in exchange started", result); if ("startExchangeResult" in result) { data.onResult(result.startExchangeResult); } @@ -170,6 +177,7 @@ export const LiveAppDrawer = () => { /> ) : null; case "EXCHANGE_COMPLETE": + console.log("I am here", data, isCompleteExchangeData(data)); return data && isCompleteExchangeData(data) ? ( void | undefined }) => { const dispatch = useDispatch(); const { onResult, onCancel, swapId, magnitudeAwareRate, ...exchangeParams } = data; + console.log("DATA", data); + console.log("EXCHANGE", exchangeParams); const { exchange, provider, transaction: transactionParams } = exchangeParams; const { fromAccount: account, fromParentAccount: parentAccount } = exchange; @@ -102,7 +113,7 @@ const Body = ({ data, onClose }: { data: Data; onClose?: () => void | undefined const [transaction, setTransaction] = useState(); const [signedOperation, setSignedOperation] = useState(); const [error, setError] = useState(); - const [result, setResult] = useState(); + const [result, setResult] = useState(); const signRequest = useMemo( () => @@ -163,24 +174,30 @@ const Body = ({ data, onClose }: { data: Data; onClose?: () => void | undefined return onCancel(new DisabledTransactionBroadcastError()); } onResult(operation); - // else not swap i.e card and sell we close the drawer + } else if ( + (data.exchangeType === ExchangeType.SELL || data.exchangeType === ExchangeType.SELL_NG) && + sourceCurrency + ) { + onResult(operation); + setResult({ provider, isSell: true, sourceCurrency }); } else { + // else not swap i.e card we close the drawer onResult(operation); onClose?.(); } }, [ - setResult, - onResult, - onCancel, - onClose, - updateAccount, + swapId, + toAccount, magnitudeAwareRate, - provider, sourceCurrency, targetCurrency, - swapId, - toAccount, + data.exchangeType, + updateAccount, + provider, + onResult, + onCancel, + onClose, ], ); diff --git a/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/BodyContent.tsx b/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/BodyContent.tsx index 1816f6878494..37ea3169bba1 100644 --- a/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/BodyContent.tsx +++ b/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/BodyContent.tsx @@ -37,10 +37,12 @@ export type BodyContentProps = { amountExpectedTo?: number; }; result?: { - swapId: string; + swapId?: string; + // The isSell will probably be replaced with a sellId similar with swapId. + isSell?: boolean; provider: string; sourceCurrency: SwapSelectorStateType["currency"]; - targetCurrency: SwapSelectorStateType["currency"]; + targetCurrency?: SwapSelectorStateType["currency"]; }; onOperationSigned: (value: SignedOperation) => void; onTransactionComplete: (value: Transaction) => void; @@ -50,14 +52,17 @@ export type BodyContentProps = { }; export const BodyContent = (props: BodyContentProps) => { + console.log("BodyContent", props); if (props.error) { return ; } if (props.result) { + console.log("BodyContentResult", props.result); return ( { } if (props.signedOperation) { + console.log("BodyContentSignedOp", props.signedOperation); return ; } if (props.signRequest) { + console.log("BodyContentSignReq", props.signRequest); return ( { /> ); } - + console.log("Past everything"); return ( @@ -30,24 +33,32 @@ export function TransactionBroadcastedContent(props: TransactionBroadcastedConte provider={provider} {...swapDefaultTrack} /> - {targetCurrency && ( - - - + {swapId && targetCurrency && ( + <> + + + + + + + + + + + )} + {isSell && sourceCurrency && ( + <> + + + + )} - - - - - - ); } diff --git a/apps/ledger-live-desktop/src/renderer/reducers/UI.ts b/apps/ledger-live-desktop/src/renderer/reducers/UI.ts index 515f5bceee5f..71b6615bdcb3 100644 --- a/apps/ledger-live-desktop/src/renderer/reducers/UI.ts +++ b/apps/ledger-live-desktop/src/renderer/reducers/UI.ts @@ -105,6 +105,7 @@ const handlers: UIHandlers = { }; }, PLATFORM_APP_DRAWER_OPEN: (state, { payload }) => { + console.log("Platform app drawer opened", payload); return { ...state, platformAppDrawer: { diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/ExchangeDrawer/SellCompleted.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/ExchangeDrawer/SellCompleted.tsx new file mode 100644 index 000000000000..675021a1778a --- /dev/null +++ b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/ExchangeDrawer/SellCompleted.tsx @@ -0,0 +1,98 @@ +import { getProviderName } from "@ledgerhq/live-common/exchange/swap/utils/index"; +import { Icon, Link } from "@ledgerhq/react-ui"; +import React, { useCallback, useEffect, useState } from "react"; +import { Trans } from "react-i18next"; +import styled from "styled-components"; +import Alert from "~/renderer/components/Alert"; +import Box from "~/renderer/components/Box"; +import CopyWithFeedback from "~/renderer/components/CopyWithFeedback"; +import FakeLink from "~/renderer/components/FakeLink"; +import Text from "~/renderer/components/Text"; +import { GradientHover } from "~/renderer/drawers/OperationDetails/styledComponents"; +import IconCheck from "~/renderer/icons/Check"; +import IconClock from "~/renderer/icons/Clock"; +import { openURL } from "~/renderer/linking"; +import { colors } from "~/renderer/styles/theme"; +import { track } from "~/renderer/analytics/segment"; +import { + getSwapProvider, + AdditionalProviderConfig, +} from "@ledgerhq/live-common/exchange/providers/swap"; + +const IconWrapper = styled(Box)` + background: ${colors.lightGreen}; + color: ${colors.positiveGreen}; + width: 50px; + height: 50px; + border-radius: 25px; + align-items: center; + justify-content: center; + position: relative; +`; +const Pill = styled(Text)` + user-select: text; + border-radius: 4px; + background: ${p => p.theme.colors.palette.text.shade10}; + padding: 3px 6px; +`; +const SwapIdWrapper = styled(Box).attrs(p => ({ + ff: "Inter", + color: p.color || "palette.text.shade80", + fontSize: 4, + relative: true, +}))` + padding-top: 24px; + + ${GradientHover} { + display: none; + } + + &:hover ${GradientHover} { + display: flex; + & > * { + cursor: pointer; + } + } + + &:hover ${Pill} { + color: ${p => p.theme.colors.palette.text.shade100}; + } +} +`; +const WrapperClock = styled(Box).attrs(() => ({ + bg: "palette.background.paper", + color: "palette.text.shade60", +}))` + border-radius: 50%; + position: absolute; + bottom: -2px; + right: -2px; + padding: 2px; +`; + +const SellCompleted = ({ + provider, + sourceCurrency, +}: { + provider: string; + sourceCurrency: string; +}) => { + return ( + + + + + + + + + + + + + + + ); +}; + +export default SellCompleted; diff --git a/apps/ledger-live-desktop/static/i18n/en/app.json b/apps/ledger-live-desktop/static/i18n/en/app.json index a7c0880492eb..280745f81824 100644 --- a/apps/ledger-live-desktop/static/i18n/en/app.json +++ b/apps/ledger-live-desktop/static/i18n/en/app.json @@ -2190,7 +2190,13 @@ }, "sell": { "title": "Sell", - "titleCrypto": "Sell {{currency}}" + "titleCrypto": "Sell {{currency}}", + "exchangeDrawer": { + "completed": { + "title": "Transaction broadcast successfully", + "description": "Your Sell operation has been sent to the network for confirmation. Please wait for your transaction to be confirmed and for the provider to process it." + } + } }, "receive": { "title": "Receive", @@ -6550,4 +6556,4 @@ "description": "Follow the instruction which appear on your Ledger’s Trusted Display." } } -} +} \ No newline at end of file From dd4daf1a1b5e38d46c2985bf99838c587bbc7ced Mon Sep 17 00:00:00 2001 From: chrisduma-ledger Date: Wed, 28 Aug 2024 16:15:26 +0300 Subject: [PATCH 02/13] chore: changeset --- .changeset/modern-otters-own.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/modern-otters-own.md diff --git a/.changeset/modern-otters-own.md b/.changeset/modern-otters-own.md new file mode 100644 index 000000000000..9097703318d2 --- /dev/null +++ b/.changeset/modern-otters-own.md @@ -0,0 +1,5 @@ +--- +"ledger-live-desktop": minor +--- + +Adds confirmation message for Sell in LLD From 7fc43c6b59b659c72ddbcbf699ca244539415fb9 Mon Sep 17 00:00:00 2001 From: chrisduma-ledger Date: Wed, 28 Aug 2024 16:21:30 +0300 Subject: [PATCH 03/13] chore: tidy pr up --- .../components/DeviceAction/index.tsx | 2 - .../src/renderer/components/LiveAppDrawer.tsx | 8 +-- .../Exchange/CompleteExchange/BodyContent.tsx | 6 +-- .../ExchangeDrawer => Sell}/SellCompleted.tsx | 51 +------------------ 4 files changed, 5 insertions(+), 62 deletions(-) rename apps/ledger-live-desktop/src/renderer/screens/exchange/{Swap2/Form/ExchangeDrawer => Sell}/SellCompleted.tsx (50%) diff --git a/apps/ledger-live-desktop/src/renderer/components/DeviceAction/index.tsx b/apps/ledger-live-desktop/src/renderer/components/DeviceAction/index.tsx index 97a50f81a13f..cd9fd8e9f119 100644 --- a/apps/ledger-live-desktop/src/renderer/components/DeviceAction/index.tsx +++ b/apps/ledger-live-desktop/src/renderer/components/DeviceAction/index.tsx @@ -376,7 +376,6 @@ export const DeviceActionDefaultRendering = ({ case 0x01: // sell case 0x02: // fund - console.log("inside switch!"); return renderSecureTransferDeviceConfirmation({ exchangeType: exchangeType === 0x01 ? "sell" : "fund", modelId, @@ -389,7 +388,6 @@ export const DeviceActionDefaultRendering = ({ } if (initSwapRequested && !initSwapResult && !initSwapError) { - console.log("Init swap requested"); const { transaction, exchange, exchangeRate } = request as { transaction: Transaction; exchange: ExchangeSwap; diff --git a/apps/ledger-live-desktop/src/renderer/components/LiveAppDrawer.tsx b/apps/ledger-live-desktop/src/renderer/components/LiveAppDrawer.tsx index c6305f7eb0e3..bb20bc94266d 100644 --- a/apps/ledger-live-desktop/src/renderer/components/LiveAppDrawer.tsx +++ b/apps/ledger-live-desktop/src/renderer/components/LiveAppDrawer.tsx @@ -96,10 +96,9 @@ export const LiveAppDrawer = () => { if (!payload) { return null; } + const { type, manifest, data } = payload; - console.log("In drawer1", type); - console.log("In drawer2", manifest); - console.log("In drawer3", data); + const action = createAction(connectApp, startExchange); switch (type) { case "DAPP_INFO": @@ -158,14 +157,12 @@ export const LiveAppDrawer = () => { ); case "EXCHANGE_START": - console.log("exchange started", data?.onResult.toString()); return data && isStartExchangeData(data) ? ( renderLoading()} onResult={result => { - console.log("Result in exchange started", result); if ("startExchangeResult" in result) { data.onResult(result.startExchangeResult); } @@ -177,7 +174,6 @@ export const LiveAppDrawer = () => { /> ) : null; case "EXCHANGE_COMPLETE": - console.log("I am here", data, isCompleteExchangeData(data)); return data && isCompleteExchangeData(data) ? ( { - console.log("BodyContent", props); if (props.error) { return ; } if (props.result) { - console.log("BodyContentResult", props.result); return ( { } if (props.signedOperation) { - console.log("BodyContentSignedOp", props.signedOperation); return ; } if (props.signRequest) { - console.log("BodyContentSignReq", props.signRequest); return ( { /> ); } - console.log("Past everything"); + return ( p.theme.colors.palette.text.shade10}; - padding: 3px 6px; -`; -const SwapIdWrapper = styled(Box).attrs(p => ({ - ff: "Inter", - color: p.color || "palette.text.shade80", - fontSize: 4, - relative: true, -}))` - padding-top: 24px; - - ${GradientHover} { - display: none; - } - &:hover ${GradientHover} { - display: flex; - & > * { - cursor: pointer; - } - } - - &:hover ${Pill} { - color: ${p => p.theme.colors.palette.text.shade100}; - } -} -`; const WrapperClock = styled(Box).attrs(() => ({ bg: "palette.background.paper", color: "palette.text.shade60", @@ -70,13 +29,7 @@ const WrapperClock = styled(Box).attrs(() => ({ padding: 2px; `; -const SellCompleted = ({ - provider, - sourceCurrency, -}: { - provider: string; - sourceCurrency: string; -}) => { +const SellCompleted = () => { return ( From a1da8696c083cc07ecc02a2a47a66eb97f887928 Mon Sep 17 00:00:00 2001 From: chrisduma-ledger Date: Wed, 28 Aug 2024 16:24:48 +0300 Subject: [PATCH 04/13] chore: tidy up --- .../screens/exchange/Sell/SellCompleted.tsx | 25 +----------------- .../Form/ExchangeDrawer/SwapCompleted.tsx | 22 +--------------- .../screens/exchange/shared/shared-styles.tsx | 26 +++++++++++++++++++ 3 files changed, 28 insertions(+), 45 deletions(-) create mode 100644 apps/ledger-live-desktop/src/renderer/screens/exchange/shared/shared-styles.tsx diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Sell/SellCompleted.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Sell/SellCompleted.tsx index ba15cc4d2cd0..752d674ee603 100644 --- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Sell/SellCompleted.tsx +++ b/apps/ledger-live-desktop/src/renderer/screens/exchange/Sell/SellCompleted.tsx @@ -1,33 +1,10 @@ import React from "react"; import { Trans } from "react-i18next"; -import styled from "styled-components"; import Box from "~/renderer/components/Box"; import Text from "~/renderer/components/Text"; import IconCheck from "~/renderer/icons/Check"; import IconClock from "~/renderer/icons/Clock"; -import { colors } from "~/renderer/styles/theme"; - -const IconWrapper = styled(Box)` - background: ${colors.lightGreen}; - color: ${colors.positiveGreen}; - width: 50px; - height: 50px; - border-radius: 25px; - align-items: center; - justify-content: center; - position: relative; -`; - -const WrapperClock = styled(Box).attrs(() => ({ - bg: "palette.background.paper", - color: "palette.text.shade60", -}))` - border-radius: 50%; - position: absolute; - bottom: -2px; - right: -2px; - padding: 2px; -`; +import { IconWrapper, WrapperClock } from "../shared/shared-styles"; const SellCompleted = () => { return ( diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/ExchangeDrawer/SwapCompleted.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/ExchangeDrawer/SwapCompleted.tsx index f884f3ec07a1..9ca129c4de46 100644 --- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/ExchangeDrawer/SwapCompleted.tsx +++ b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/ExchangeDrawer/SwapCompleted.tsx @@ -12,23 +12,13 @@ import { GradientHover } from "~/renderer/drawers/OperationDetails/styledCompone import IconCheck from "~/renderer/icons/Check"; import IconClock from "~/renderer/icons/Clock"; import { openURL } from "~/renderer/linking"; -import { colors } from "~/renderer/styles/theme"; import { track } from "~/renderer/analytics/segment"; import { getSwapProvider, AdditionalProviderConfig, } from "@ledgerhq/live-common/exchange/providers/swap"; +import { IconWrapper, WrapperClock } from "../../../shared/shared-styles"; -const IconWrapper = styled(Box)` - background: ${colors.lightGreen}; - color: ${colors.positiveGreen}; - width: 50px; - height: 50px; - border-radius: 25px; - align-items: center; - justify-content: center; - position: relative; -`; const Pill = styled(Text)` user-select: text; border-radius: 4px; @@ -59,16 +49,6 @@ const SwapIdWrapper = styled(Box).attrs(p => ({ } } `; -const WrapperClock = styled(Box).attrs(() => ({ - bg: "palette.background.paper", - color: "palette.text.shade60", -}))` - border-radius: 50%; - position: absolute; - bottom: -2px; - right: -2px; - padding: 2px; -`; const SwapCompleted = ({ swapId, diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/shared/shared-styles.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/shared/shared-styles.tsx new file mode 100644 index 000000000000..d62b386efc98 --- /dev/null +++ b/apps/ledger-live-desktop/src/renderer/screens/exchange/shared/shared-styles.tsx @@ -0,0 +1,26 @@ +import styled from "styled-components"; +import Box from "~/renderer/components/Box"; + +import { colors } from "~/renderer/styles/theme"; + +export const IconWrapper = styled(Box)` + background: ${colors.lightGreen}; + color: ${colors.positiveGreen}; + width: 50px; + height: 50px; + border-radius: 25px; + align-items: center; + justify-content: center; + position: relative; +`; + +export const WrapperClock = styled(Box).attrs(() => ({ + bg: "palette.background.paper", + color: "palette.text.shade60", +}))` + border-radius: 50%; + position: absolute; + bottom: -2px; + right: -2px; + padding: 2px; +`; From 7fe3c7559e8e41b8c14087631fef757bbaf90531 Mon Sep 17 00:00:00 2001 From: chrisduma-ledger Date: Wed, 28 Aug 2024 16:29:31 +0300 Subject: [PATCH 05/13] chore: use currency --- .../Platform/Exchange/CompleteExchange/Body.tsx | 10 +++++----- .../Exchange/CompleteExchange/BodyContent.tsx | 7 +++---- .../TransactionBroadcastedContent.tsx | 13 ++++++------- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/Body.tsx b/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/Body.tsx index ced698e933a9..af119f629e89 100644 --- a/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/Body.tsx +++ b/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/Body.tsx @@ -2,13 +2,13 @@ import React, { useCallback, useEffect, useMemo, useRef, useState } from "react" import { useDispatch } from "react-redux"; import { Operation, SignedOperation } from "@ledgerhq/types-live"; import { Exchange } from "@ledgerhq/live-common/exchange/types"; -import { ExchangeSwap, SwapSelectorStateType } from "@ledgerhq/live-common/exchange/swap/types"; +import { ExchangeSwap } from "@ledgerhq/live-common/exchange/swap/types"; import { getUpdateAccountWithUpdaterParams } from "@ledgerhq/live-common/exchange/swap/getUpdateAccountWithUpdaterParams"; import { useBroadcast } from "@ledgerhq/live-common/hooks/useBroadcast"; import { Transaction } from "@ledgerhq/live-common/generated/types"; -import { TokenCurrency } from "@ledgerhq/types-cryptoassets"; +import { Currency, TokenCurrency } from "@ledgerhq/types-cryptoassets"; import { updateAccountWithUpdater } from "~/renderer/actions/accounts"; -import { BodyContent, BodyContentProps } from "./BodyContent"; +import { BodyContent } from "./BodyContent"; import { BigNumber } from "bignumber.js"; import { AccountLike } from "@ledgerhq/types-live"; import { DisabledTransactionBroadcastError } from "@ledgerhq/errors"; @@ -36,8 +36,8 @@ type ResultsState = { isSell?: boolean; swapId?: string; provider: string; - sourceCurrency: SwapSelectorStateType["currency"]; - targetCurrency?: SwapSelectorStateType["currency"]; + sourceCurrency: Currency; + targetCurrency?: Currency; }; export function isCompleteExchangeData(data: unknown): data is Data { diff --git a/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/BodyContent.tsx b/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/BodyContent.tsx index e922c3c0c82d..7e1527b0b0c7 100644 --- a/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/BodyContent.tsx +++ b/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/BodyContent.tsx @@ -6,12 +6,11 @@ import connectApp from "@ledgerhq/live-common/hw/connectApp"; import { createAction } from "@ledgerhq/live-common/hw/actions/completeExchange"; import { createAction as txCreateAction } from "@ledgerhq/live-common/hw/actions/transaction"; import completeExchange from "@ledgerhq/live-common/exchange/platform/completeExchange"; -import { TokenCurrency } from "@ledgerhq/types-cryptoassets"; +import { Currency, TokenCurrency } from "@ledgerhq/types-cryptoassets"; import DeviceAction from "~/renderer/components/DeviceAction"; import BigSpinner from "~/renderer/components/BigSpinner"; import ErrorDisplay from "~/renderer/components/ErrorDisplay"; import { TransactionBroadcastedContent } from "./TransactionBroadcastedContent"; -import { SwapSelectorStateType } from "@ledgerhq/live-common/exchange/swap/types"; const exchangeAction = createAction(completeExchange); const sendAction = txCreateAction(connectApp); @@ -41,8 +40,8 @@ export type BodyContentProps = { // The isSell will probably be replaced with a sellId similar with swapId. isSell?: boolean; provider: string; - sourceCurrency: SwapSelectorStateType["currency"]; - targetCurrency?: SwapSelectorStateType["currency"]; + sourceCurrency: Currency; + targetCurrency?: Currency; }; onOperationSigned: (value: SignedOperation) => void; onTransactionComplete: (value: Transaction) => void; diff --git a/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/TransactionBroadcastedContent.tsx b/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/TransactionBroadcastedContent.tsx index d948a92157d9..375a6fd61efa 100644 --- a/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/TransactionBroadcastedContent.tsx +++ b/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/TransactionBroadcastedContent.tsx @@ -1,28 +1,27 @@ import React from "react"; import { Trans } from "react-i18next"; -import { SwapSelectorStateType } from "@ledgerhq/live-common/exchange/swap/types"; import Box from "~/renderer/components/Box"; import { Separator } from "~/renderer/screens/exchange/Swap2/Form/Separator"; import Button from "~/renderer/components/Button"; import SwapCompleted from "~/renderer/screens/exchange/Swap2/Form/ExchangeDrawer/SwapCompleted"; -import SellCompleted from "~/renderer/screens/exchange/Swap2/Form/ExchangeDrawer/SellCompleted"; import { useGetSwapTrackingProperties } from "~/renderer/screens/exchange/Swap2/utils"; import TrackPage from "~/renderer/analytics/TrackPage"; +import { Currency } from "@ledgerhq/types-cryptoassets"; +import SellCompleted from "~/renderer/screens/exchange/Sell/SellCompleted"; type TransactionBroadcastedContentProps = { swapId?: string; isSell?: boolean; provider: string; - sourceCurrency: SwapSelectorStateType["currency"]; - targetCurrency: SwapSelectorStateType["currency"]; + sourceCurrency: Currency; + targetCurrency?: Currency; onViewDetails: (id: string) => void; }; export function TransactionBroadcastedContent(props: TransactionBroadcastedContentProps) { const { swapId, provider, sourceCurrency, targetCurrency, onViewDetails, isSell } = props; - console.log("Got in3", targetCurrency); - console.log("Is sell?!?!", isSell); const swapDefaultTrack = useGetSwapTrackingProperties(); + return ( - + )} From 9268680dc23cd87cd1b53a755236c2fbc0323dd7 Mon Sep 17 00:00:00 2001 From: chrisduma-ledger Date: Wed, 28 Aug 2024 16:37:49 +0300 Subject: [PATCH 06/13] chore: remove logs --- .../modals/Platform/Exchange/CompleteExchange/Body.tsx | 4 ---- apps/ledger-live-desktop/src/renderer/reducers/UI.ts | 1 - 2 files changed, 5 deletions(-) diff --git a/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/Body.tsx b/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/Body.tsx index af119f629e89..4282ee2060e5 100644 --- a/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/Body.tsx +++ b/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/Body.tsx @@ -60,12 +60,8 @@ const Root = styled.div` const Body = ({ data, onClose }: { data: Data; onClose?: () => void | undefined }) => { const dispatch = useDispatch(); const { onResult, onCancel, swapId, magnitudeAwareRate, ...exchangeParams } = data; - console.log("DATA", data); - console.log("EXCHANGE", exchangeParams); const { exchange, provider, transaction: transactionParams } = exchangeParams; - const { fromAccount: account, fromParentAccount: parentAccount } = exchange; - // toAccount exists only in swap mode const toAccount = "toAccount" in exchange ? exchange.toAccount : undefined; diff --git a/apps/ledger-live-desktop/src/renderer/reducers/UI.ts b/apps/ledger-live-desktop/src/renderer/reducers/UI.ts index 71b6615bdcb3..515f5bceee5f 100644 --- a/apps/ledger-live-desktop/src/renderer/reducers/UI.ts +++ b/apps/ledger-live-desktop/src/renderer/reducers/UI.ts @@ -105,7 +105,6 @@ const handlers: UIHandlers = { }; }, PLATFORM_APP_DRAWER_OPEN: (state, { payload }) => { - console.log("Platform app drawer opened", payload); return { ...state, platformAppDrawer: { From 35eb952018b83862a7751868d14f61ea1d6f7fec Mon Sep 17 00:00:00 2001 From: chrisduma-ledger Date: Thu, 29 Aug 2024 11:43:28 +0300 Subject: [PATCH 07/13] chore: review --- .../modals/Platform/Exchange/CompleteExchange/Body.tsx | 3 +++ .../CompleteExchange/TransactionBroadcastedContent.tsx | 4 +++- .../src/renderer/screens/exchange/Sell/utils/index.ts | 10 ++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 apps/ledger-live-desktop/src/renderer/screens/exchange/Sell/utils/index.ts diff --git a/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/Body.tsx b/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/Body.tsx index 4282ee2060e5..508971652f94 100644 --- a/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/Body.tsx +++ b/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/Body.tsx @@ -174,6 +174,9 @@ const Body = ({ data, onClose }: { data: Data; onClose?: () => void | undefined (data.exchangeType === ExchangeType.SELL || data.exchangeType === ExchangeType.SELL_NG) && sourceCurrency ) { + if (getEnv("DISABLE_TRANSACTION_BROADCAST")) { + return onCancel(new DisabledTransactionBroadcastError()); + } onResult(operation); setResult({ provider, isSell: true, sourceCurrency }); } else { diff --git a/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/TransactionBroadcastedContent.tsx b/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/TransactionBroadcastedContent.tsx index 375a6fd61efa..076c19d0b3b1 100644 --- a/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/TransactionBroadcastedContent.tsx +++ b/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/TransactionBroadcastedContent.tsx @@ -5,6 +5,7 @@ import { Separator } from "~/renderer/screens/exchange/Swap2/Form/Separator"; import Button from "~/renderer/components/Button"; import SwapCompleted from "~/renderer/screens/exchange/Swap2/Form/ExchangeDrawer/SwapCompleted"; import { useGetSwapTrackingProperties } from "~/renderer/screens/exchange/Swap2/utils"; +import { useGetSellTrackingProperties } from "~/renderer/screens/exchange/Sell/utils"; import TrackPage from "~/renderer/analytics/TrackPage"; import { Currency } from "@ledgerhq/types-cryptoassets"; import SellCompleted from "~/renderer/screens/exchange/Sell/SellCompleted"; @@ -21,6 +22,7 @@ type TransactionBroadcastedContentProps = { export function TransactionBroadcastedContent(props: TransactionBroadcastedContentProps) { const { swapId, provider, sourceCurrency, targetCurrency, onViewDetails, isSell } = props; const swapDefaultTrack = useGetSwapTrackingProperties(); + const sellDefaultTrack = useGetSellTrackingProperties(); return ( @@ -30,7 +32,7 @@ export function TransactionBroadcastedContent(props: TransactionBroadcastedConte sourceCurrency={sourceCurrency?.name} targetCurrency={targetCurrency?.name} provider={provider} - {...swapDefaultTrack} + {...(swapId ? swapDefaultTrack : sellDefaultTrack)} /> {swapId && targetCurrency && ( <> diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Sell/utils/index.ts b/apps/ledger-live-desktop/src/renderer/screens/exchange/Sell/utils/index.ts new file mode 100644 index 000000000000..d1f002008f5b --- /dev/null +++ b/apps/ledger-live-desktop/src/renderer/screens/exchange/Sell/utils/index.ts @@ -0,0 +1,10 @@ +export const SELL_VERSION = "1.00"; + +const SELL_TRACKING_PROPERTIES = { + swapVersion: SELL_VERSION, + flow: "sell", +}; + +export const useGetSellTrackingProperties = () => { + return SELL_TRACKING_PROPERTIES; +}; From 3a2bb2f294aa9820f007f077b4f3c28931a3cf45 Mon Sep 17 00:00:00 2001 From: chrisduma-ledger Date: Fri, 30 Aug 2024 11:56:17 +0300 Subject: [PATCH 08/13] chore: refactor --- .../Exchange/CompleteExchange/Body.tsx | 65 ++++++++++++------- .../Exchange/CompleteExchange/BodyContent.tsx | 6 +- .../TransactionBroadcastedContent.tsx | 9 +-- apps/ledger-live-mobile/Gemfile.lock | 24 ++++--- libs/exchange-module/src/index.ts | 3 + libs/exchange-module/src/types.ts | 3 + .../src/wallet-api/Exchange/server.ts | 12 +++- 7 files changed, 79 insertions(+), 43 deletions(-) diff --git a/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/Body.tsx b/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/Body.tsx index 508971652f94..75344530e36a 100644 --- a/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/Body.tsx +++ b/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/Body.tsx @@ -32,8 +32,15 @@ export type Data = { magnitudeAwareRate?: BigNumber; }; +export enum ExchangeModeEnum { + Sell = "sell", + Swap = "swap", +} + +export type ExchangeMode = "sell" | "swap"; + type ResultsState = { - isSell?: boolean; + mode: ExchangeMode; swapId?: string; provider: string; sourceCurrency: Currency; @@ -149,36 +156,44 @@ const Body = ({ data, onClose }: { data: Data; onClose?: () => void | undefined const onBroadcastSuccess = useCallback( (operation: Operation) => { - // If swap we save to swap history and keep open the drawer - if (swapId && toAccount && magnitudeAwareRate && sourceCurrency && targetCurrency) { - const newResult = { - operation, - swapId, - }; - updateAccount({ - result: newResult, - magnitudeAwareRate, - }); - setResult({ - swapId, - provider, - sourceCurrency, - targetCurrency, - }); + // TODO: swapId && sellId will become quoteId - if (getEnv("DISABLE_TRANSACTION_BROADCAST")) { - return onCancel(new DisabledTransactionBroadcastError()); - } - onResult(operation); - } else if ( + const isValidExchangeSDKSwapTx = + (ExchangeType.SWAP || ExchangeType.SWAP_NG) && + swapId && + toAccount && + magnitudeAwareRate && + sourceCurrency && + targetCurrency; + + const isValidExchangeSDKSellTx = (data.exchangeType === ExchangeType.SELL || data.exchangeType === ExchangeType.SELL_NG) && - sourceCurrency - ) { + sourceCurrency; + + if (isValidExchangeSDKSellTx || isValidExchangeSDKSwapTx) { + if (isValidExchangeSDKSwapTx) { + const newResult = { + operation, + swapId, + }; + + updateAccount({ + result: newResult, + magnitudeAwareRate, + }); + } + + const result = isValidExchangeSDKSwapTx + ? { swapId, provider, sourceCurrency, targetCurrency, mode: ExchangeModeEnum.Swap } + : { provider, mode: ExchangeModeEnum.Sell, sourceCurrency }; + + setResult(result); + if (getEnv("DISABLE_TRANSACTION_BROADCAST")) { return onCancel(new DisabledTransactionBroadcastError()); } + onResult(operation); - setResult({ provider, isSell: true, sourceCurrency }); } else { // else not swap i.e card we close the drawer onResult(operation); diff --git a/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/BodyContent.tsx b/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/BodyContent.tsx index 7e1527b0b0c7..6b62f9069d07 100644 --- a/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/BodyContent.tsx +++ b/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/BodyContent.tsx @@ -11,6 +11,7 @@ import DeviceAction from "~/renderer/components/DeviceAction"; import BigSpinner from "~/renderer/components/BigSpinner"; import ErrorDisplay from "~/renderer/components/ErrorDisplay"; import { TransactionBroadcastedContent } from "./TransactionBroadcastedContent"; +import { ExchangeMode } from "./Body"; const exchangeAction = createAction(completeExchange); const sendAction = txCreateAction(connectApp); @@ -37,8 +38,7 @@ export type BodyContentProps = { }; result?: { swapId?: string; - // The isSell will probably be replaced with a sellId similar with swapId. - isSell?: boolean; + mode: ExchangeMode; provider: string; sourceCurrency: Currency; targetCurrency?: Currency; @@ -59,7 +59,7 @@ export const BodyContent = (props: BodyContentProps) => { return ( - {swapId && targetCurrency && ( + {mode === ExchangeModeEnum.Swap && swapId && targetCurrency && ( <> )} - {isSell && sourceCurrency && ( + {mode === ExchangeModeEnum.Sell && sourceCurrency && ( <> diff --git a/apps/ledger-live-mobile/Gemfile.lock b/apps/ledger-live-mobile/Gemfile.lock index ccfd7e88b0db..153b3c9586ee 100644 --- a/apps/ledger-live-mobile/Gemfile.lock +++ b/apps/ledger-live-mobile/Gemfile.lock @@ -5,11 +5,12 @@ GEM base64 nkf rexml - activesupport (7.0.8.4) + activesupport (6.1.7.8) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) tzinfo (~> 2.0) + zeitwerk (~> 2.3) addressable (2.8.7) public_suffix (>= 2.0.2, < 7.0) algoliasearch (1.27.5) @@ -81,13 +82,14 @@ GEM declarative (0.0.20) digest-crc (0.6.5) rake (>= 12.0.0, < 14.0.0) - domain_name (0.6.20240107) + domain_name (0.5.20190701) + unf (>= 0.0.5, < 1.0.0) dotenv (2.8.1) emoji_regex (3.2.3) escape (0.0.4) ethon (0.16.0) ffi (>= 1.15.0) - excon (0.111.0) + excon (0.109.0) faraday (1.10.3) faraday-em_http (~> 1.0) faraday-em_synchrony (~> 1.0) @@ -178,19 +180,19 @@ GEM google-apis-core (>= 0.11.0, < 2.a) google-apis-playcustomapp_v1 (0.13.0) google-apis-core (>= 0.11.0, < 2.a) - google-apis-storage_v1 (0.31.0) + google-apis-storage_v1 (0.29.0) google-apis-core (>= 0.11.0, < 2.a) - google-cloud-core (1.7.1) + google-cloud-core (1.6.1) google-cloud-env (>= 1.0, < 3.a) google-cloud-errors (~> 1.0) google-cloud-env (1.6.0) faraday (>= 0.17.3, < 3.0) - google-cloud-errors (1.4.0) - google-cloud-storage (1.47.0) + google-cloud-errors (1.3.1) + google-cloud-storage (1.45.0) addressable (~> 2.8) digest-crc (~> 0.4) google-apis-iamcredentials_v1 (~> 0.1) - google-apis-storage_v1 (~> 0.31.0) + google-apis-storage_v1 (~> 0.29.0) google-cloud-core (~> 1.6) googleauth (>= 0.16.2, < 2.a) mini_mime (~> 1.0) @@ -239,7 +241,7 @@ GEM rubyzip (2.3.2) security (0.1.3) semver2 (3.4.2) - signet (0.19.0) + signet (0.18.0) addressable (~> 2.8) faraday (>= 0.17.5, < 3.a) jwt (>= 1.5, < 3.0) @@ -261,6 +263,7 @@ GEM tzinfo (2.0.6) concurrent-ruby (~> 1.0) uber (0.1.0) + unf (0.2.0) unicode-display_width (2.5.0) word_wrap (1.0.0) xcodeproj (1.25.0) @@ -274,6 +277,7 @@ GEM rouge (~> 2.0.7) xcpretty-travis-formatter (1.0.1) xcpretty (~> 0.2, >= 0.0.7) + zeitwerk (2.6.17) PLATFORMS ruby @@ -288,4 +292,4 @@ DEPENDENCIES semver2 (~> 3.4, >= 3.4.2) BUNDLED WITH - 2.5.7 + 2.4.22 diff --git a/libs/exchange-module/src/index.ts b/libs/exchange-module/src/index.ts index e13aadfeeed2..b905f74c84fc 100644 --- a/libs/exchange-module/src/index.ts +++ b/libs/exchange-module/src/index.ts @@ -154,6 +154,7 @@ export class ExchangeModule extends CustomModule { binaryPayload, signature, feeStrategy, + quoteId, }: { provider: string; fromAccountId: string; @@ -161,6 +162,7 @@ export class ExchangeModule extends CustomModule { binaryPayload: Buffer; signature: Buffer; feeStrategy: ExchangeCompleteParams["feeStrategy"]; + quoteId: string; }): Promise { const result = await this.request( "custom.exchange.complete", @@ -172,6 +174,7 @@ export class ExchangeModule extends CustomModule { hexBinaryPayload: binaryPayload.toString("hex"), hexSignature: signature.toString("hex"), feeStrategy, + quoteId, }, ); diff --git a/libs/exchange-module/src/types.ts b/libs/exchange-module/src/types.ts index c7d47fcd1eb5..583b4e6aadc7 100644 --- a/libs/exchange-module/src/types.ts +++ b/libs/exchange-module/src/types.ts @@ -45,10 +45,13 @@ export type ExchangeCompleteBaseParams = { export type ExchangeCompleteFundParams = ExchangeCompleteBaseParams & { exchangeType: "FUND"; + // Optional until we actually implement it + quoteId?: string; }; export type ExchangeCompleteSellParams = ExchangeCompleteBaseParams & { exchangeType: "SELL"; + quoteId: string; }; export type ExchangeCompleteSwapParams = ExchangeCompleteBaseParams & { diff --git a/libs/ledger-live-common/src/wallet-api/Exchange/server.ts b/libs/ledger-live-common/src/wallet-api/Exchange/server.ts index dbd1d9a476ff..133c609386d6 100644 --- a/libs/ledger-live-common/src/wallet-api/Exchange/server.ts +++ b/libs/ledger-live-common/src/wallet-api/Exchange/server.ts @@ -61,6 +61,7 @@ export type CompleteExchangeUiRequest = { feesStrategy: string; exchangeType: number; swapId?: string; + quoteId?: string; amountExpectedTo?: number; magnitudeAwareRate?: BigNumber; }; @@ -270,6 +271,15 @@ export const handlers = ({ magnitudeAwareRate = tx.amount && amountExpectedTo.dividedBy(tx.amount); } + // Typeguard, so typescript does not complain, + // This check is necessary because TypeScript sometimes fails to correctly infer the union type properties. + const quoteOrSwapId = + params.exchangeType === "SWAP" + ? params.swapId + : "quoteId" in params + ? params.quoteId + : undefined; + return new Promise((resolve, reject) => uiExchangeComplete({ exchangeParams: { @@ -280,7 +290,7 @@ export const handlers = ({ binaryPayload: params.hexBinaryPayload, exchange, feesStrategy: params.feeStrategy, - swapId: params.exchangeType === "SWAP" ? params.swapId : undefined, + quoteId: quoteOrSwapId, amountExpectedTo, magnitudeAwareRate, }, From d62cf063a52102597fc99ce6b7c9cd26d78f901b Mon Sep 17 00:00:00 2001 From: chrisduma-ledger Date: Mon, 2 Sep 2024 11:36:01 +0300 Subject: [PATCH 09/13] feat: wording --- apps/ledger-live-desktop/static/i18n/en/app.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/ledger-live-desktop/static/i18n/en/app.json b/apps/ledger-live-desktop/static/i18n/en/app.json index 280745f81824..fd8ed6989f37 100644 --- a/apps/ledger-live-desktop/static/i18n/en/app.json +++ b/apps/ledger-live-desktop/static/i18n/en/app.json @@ -1869,8 +1869,8 @@ "targetAccount": "Target Account" }, "sell": { - "notice": "Verify the Sell details on your device before sending it. The addresses are exchanged securely so you don’t have to verify them.", - "confirm": "Confirm Sell transaction" + "notice": "Verify the details on your device before sending it. The addresses are exchanged securely so you don’t have to verify them.", + "confirm": "Confirm transaction" }, "fund": { "notice": "Verify the Fund details on your device before sending it. The addresses are exchanged securely so you don't have to verify them.", @@ -2194,7 +2194,7 @@ "exchangeDrawer": { "completed": { "title": "Transaction broadcast successfully", - "description": "Your Sell operation has been sent to the network for confirmation. Please wait for your transaction to be confirmed and for the provider to process it." + "description": "Your operation has been sent to the network for confirmation. Please wait for your transaction to be confirmed and for the provider to process it." } } }, From 232df5e6a0922d36effdc6bb35da15d8763b1f9d Mon Sep 17 00:00:00 2001 From: chrisduma-ledger Date: Mon, 2 Sep 2024 14:07:02 +0300 Subject: [PATCH 10/13] feat: backwards compatibility --- libs/ledger-live-common/src/wallet-api/Exchange/server.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libs/ledger-live-common/src/wallet-api/Exchange/server.ts b/libs/ledger-live-common/src/wallet-api/Exchange/server.ts index 133c609386d6..39d82793ec0b 100644 --- a/libs/ledger-live-common/src/wallet-api/Exchange/server.ts +++ b/libs/ledger-live-common/src/wallet-api/Exchange/server.ts @@ -22,6 +22,7 @@ import { ExchangeType, ExchangeStartSellParams, SwapLiveError, + ExchangeCompleteSwapParams, } from "@ledgerhq/wallet-api-exchange-module"; import { decodePayloadProtobuf } from "@ledgerhq/hw-app-exchange"; import { TrackingAPI } from "./tracking"; @@ -290,6 +291,11 @@ export const handlers = ({ binaryPayload: params.hexBinaryPayload, exchange, feesStrategy: params.feeStrategy, + // swapId still here for backwards compatibility, we are planning to rename this field to quoteId to align with sell and card + swapId: + params.exchangeType === "SWAP" + ? (params as ExchangeCompleteSwapParams).swapId + : undefined, quoteId: quoteOrSwapId, amountExpectedTo, magnitudeAwareRate, From 10f99fd0f5a83f36667f7d90c22dc506f34372fa Mon Sep 17 00:00:00 2001 From: chrisduma-ledger Date: Tue, 3 Sep 2024 14:44:02 +0300 Subject: [PATCH 11/13] chore: revert --- .../Exchange/CompleteExchange/Body.tsx | 65 +++++++------------ .../Exchange/CompleteExchange/BodyContent.tsx | 6 +- .../TransactionBroadcastedContent.tsx | 9 ++- apps/ledger-live-mobile/Gemfile.lock | 24 +++---- libs/exchange-module/src/index.ts | 3 - libs/exchange-module/src/types.ts | 3 - .../src/wallet-api/Exchange/server.ts | 17 +---- 7 files changed, 43 insertions(+), 84 deletions(-) diff --git a/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/Body.tsx b/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/Body.tsx index 75344530e36a..508971652f94 100644 --- a/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/Body.tsx +++ b/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/Body.tsx @@ -32,15 +32,8 @@ export type Data = { magnitudeAwareRate?: BigNumber; }; -export enum ExchangeModeEnum { - Sell = "sell", - Swap = "swap", -} - -export type ExchangeMode = "sell" | "swap"; - type ResultsState = { - mode: ExchangeMode; + isSell?: boolean; swapId?: string; provider: string; sourceCurrency: Currency; @@ -156,44 +149,36 @@ const Body = ({ data, onClose }: { data: Data; onClose?: () => void | undefined const onBroadcastSuccess = useCallback( (operation: Operation) => { - // TODO: swapId && sellId will become quoteId - - const isValidExchangeSDKSwapTx = - (ExchangeType.SWAP || ExchangeType.SWAP_NG) && - swapId && - toAccount && - magnitudeAwareRate && - sourceCurrency && - targetCurrency; + // If swap we save to swap history and keep open the drawer + if (swapId && toAccount && magnitudeAwareRate && sourceCurrency && targetCurrency) { + const newResult = { + operation, + swapId, + }; + updateAccount({ + result: newResult, + magnitudeAwareRate, + }); + setResult({ + swapId, + provider, + sourceCurrency, + targetCurrency, + }); - const isValidExchangeSDKSellTx = - (data.exchangeType === ExchangeType.SELL || data.exchangeType === ExchangeType.SELL_NG) && - sourceCurrency; - - if (isValidExchangeSDKSellTx || isValidExchangeSDKSwapTx) { - if (isValidExchangeSDKSwapTx) { - const newResult = { - operation, - swapId, - }; - - updateAccount({ - result: newResult, - magnitudeAwareRate, - }); + if (getEnv("DISABLE_TRANSACTION_BROADCAST")) { + return onCancel(new DisabledTransactionBroadcastError()); } - - const result = isValidExchangeSDKSwapTx - ? { swapId, provider, sourceCurrency, targetCurrency, mode: ExchangeModeEnum.Swap } - : { provider, mode: ExchangeModeEnum.Sell, sourceCurrency }; - - setResult(result); - + onResult(operation); + } else if ( + (data.exchangeType === ExchangeType.SELL || data.exchangeType === ExchangeType.SELL_NG) && + sourceCurrency + ) { if (getEnv("DISABLE_TRANSACTION_BROADCAST")) { return onCancel(new DisabledTransactionBroadcastError()); } - onResult(operation); + setResult({ provider, isSell: true, sourceCurrency }); } else { // else not swap i.e card we close the drawer onResult(operation); diff --git a/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/BodyContent.tsx b/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/BodyContent.tsx index 6b62f9069d07..7e1527b0b0c7 100644 --- a/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/BodyContent.tsx +++ b/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/BodyContent.tsx @@ -11,7 +11,6 @@ import DeviceAction from "~/renderer/components/DeviceAction"; import BigSpinner from "~/renderer/components/BigSpinner"; import ErrorDisplay from "~/renderer/components/ErrorDisplay"; import { TransactionBroadcastedContent } from "./TransactionBroadcastedContent"; -import { ExchangeMode } from "./Body"; const exchangeAction = createAction(completeExchange); const sendAction = txCreateAction(connectApp); @@ -38,7 +37,8 @@ export type BodyContentProps = { }; result?: { swapId?: string; - mode: ExchangeMode; + // The isSell will probably be replaced with a sellId similar with swapId. + isSell?: boolean; provider: string; sourceCurrency: Currency; targetCurrency?: Currency; @@ -59,7 +59,7 @@ export const BodyContent = (props: BodyContentProps) => { return ( - {mode === ExchangeModeEnum.Swap && swapId && targetCurrency && ( + {swapId && targetCurrency && ( <> )} - {mode === ExchangeModeEnum.Sell && sourceCurrency && ( + {isSell && sourceCurrency && ( <> diff --git a/apps/ledger-live-mobile/Gemfile.lock b/apps/ledger-live-mobile/Gemfile.lock index 153b3c9586ee..ccfd7e88b0db 100644 --- a/apps/ledger-live-mobile/Gemfile.lock +++ b/apps/ledger-live-mobile/Gemfile.lock @@ -5,12 +5,11 @@ GEM base64 nkf rexml - activesupport (6.1.7.8) + activesupport (7.0.8.4) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) tzinfo (~> 2.0) - zeitwerk (~> 2.3) addressable (2.8.7) public_suffix (>= 2.0.2, < 7.0) algoliasearch (1.27.5) @@ -82,14 +81,13 @@ GEM declarative (0.0.20) digest-crc (0.6.5) rake (>= 12.0.0, < 14.0.0) - domain_name (0.5.20190701) - unf (>= 0.0.5, < 1.0.0) + domain_name (0.6.20240107) dotenv (2.8.1) emoji_regex (3.2.3) escape (0.0.4) ethon (0.16.0) ffi (>= 1.15.0) - excon (0.109.0) + excon (0.111.0) faraday (1.10.3) faraday-em_http (~> 1.0) faraday-em_synchrony (~> 1.0) @@ -180,19 +178,19 @@ GEM google-apis-core (>= 0.11.0, < 2.a) google-apis-playcustomapp_v1 (0.13.0) google-apis-core (>= 0.11.0, < 2.a) - google-apis-storage_v1 (0.29.0) + google-apis-storage_v1 (0.31.0) google-apis-core (>= 0.11.0, < 2.a) - google-cloud-core (1.6.1) + google-cloud-core (1.7.1) google-cloud-env (>= 1.0, < 3.a) google-cloud-errors (~> 1.0) google-cloud-env (1.6.0) faraday (>= 0.17.3, < 3.0) - google-cloud-errors (1.3.1) - google-cloud-storage (1.45.0) + google-cloud-errors (1.4.0) + google-cloud-storage (1.47.0) addressable (~> 2.8) digest-crc (~> 0.4) google-apis-iamcredentials_v1 (~> 0.1) - google-apis-storage_v1 (~> 0.29.0) + google-apis-storage_v1 (~> 0.31.0) google-cloud-core (~> 1.6) googleauth (>= 0.16.2, < 2.a) mini_mime (~> 1.0) @@ -241,7 +239,7 @@ GEM rubyzip (2.3.2) security (0.1.3) semver2 (3.4.2) - signet (0.18.0) + signet (0.19.0) addressable (~> 2.8) faraday (>= 0.17.5, < 3.a) jwt (>= 1.5, < 3.0) @@ -263,7 +261,6 @@ GEM tzinfo (2.0.6) concurrent-ruby (~> 1.0) uber (0.1.0) - unf (0.2.0) unicode-display_width (2.5.0) word_wrap (1.0.0) xcodeproj (1.25.0) @@ -277,7 +274,6 @@ GEM rouge (~> 2.0.7) xcpretty-travis-formatter (1.0.1) xcpretty (~> 0.2, >= 0.0.7) - zeitwerk (2.6.17) PLATFORMS ruby @@ -292,4 +288,4 @@ DEPENDENCIES semver2 (~> 3.4, >= 3.4.2) BUNDLED WITH - 2.4.22 + 2.5.7 diff --git a/libs/exchange-module/src/index.ts b/libs/exchange-module/src/index.ts index b905f74c84fc..e13aadfeeed2 100644 --- a/libs/exchange-module/src/index.ts +++ b/libs/exchange-module/src/index.ts @@ -154,7 +154,6 @@ export class ExchangeModule extends CustomModule { binaryPayload, signature, feeStrategy, - quoteId, }: { provider: string; fromAccountId: string; @@ -162,7 +161,6 @@ export class ExchangeModule extends CustomModule { binaryPayload: Buffer; signature: Buffer; feeStrategy: ExchangeCompleteParams["feeStrategy"]; - quoteId: string; }): Promise { const result = await this.request( "custom.exchange.complete", @@ -174,7 +172,6 @@ export class ExchangeModule extends CustomModule { hexBinaryPayload: binaryPayload.toString("hex"), hexSignature: signature.toString("hex"), feeStrategy, - quoteId, }, ); diff --git a/libs/exchange-module/src/types.ts b/libs/exchange-module/src/types.ts index 583b4e6aadc7..c7d47fcd1eb5 100644 --- a/libs/exchange-module/src/types.ts +++ b/libs/exchange-module/src/types.ts @@ -45,13 +45,10 @@ export type ExchangeCompleteBaseParams = { export type ExchangeCompleteFundParams = ExchangeCompleteBaseParams & { exchangeType: "FUND"; - // Optional until we actually implement it - quoteId?: string; }; export type ExchangeCompleteSellParams = ExchangeCompleteBaseParams & { exchangeType: "SELL"; - quoteId: string; }; export type ExchangeCompleteSwapParams = ExchangeCompleteBaseParams & { diff --git a/libs/ledger-live-common/src/wallet-api/Exchange/server.ts b/libs/ledger-live-common/src/wallet-api/Exchange/server.ts index 39d82793ec0b..1f6e2b28f4cd 100644 --- a/libs/ledger-live-common/src/wallet-api/Exchange/server.ts +++ b/libs/ledger-live-common/src/wallet-api/Exchange/server.ts @@ -62,7 +62,6 @@ export type CompleteExchangeUiRequest = { feesStrategy: string; exchangeType: number; swapId?: string; - quoteId?: string; amountExpectedTo?: number; magnitudeAwareRate?: BigNumber; }; @@ -272,15 +271,6 @@ export const handlers = ({ magnitudeAwareRate = tx.amount && amountExpectedTo.dividedBy(tx.amount); } - // Typeguard, so typescript does not complain, - // This check is necessary because TypeScript sometimes fails to correctly infer the union type properties. - const quoteOrSwapId = - params.exchangeType === "SWAP" - ? params.swapId - : "quoteId" in params - ? params.quoteId - : undefined; - return new Promise((resolve, reject) => uiExchangeComplete({ exchangeParams: { @@ -291,12 +281,7 @@ export const handlers = ({ binaryPayload: params.hexBinaryPayload, exchange, feesStrategy: params.feeStrategy, - // swapId still here for backwards compatibility, we are planning to rename this field to quoteId to align with sell and card - swapId: - params.exchangeType === "SWAP" - ? (params as ExchangeCompleteSwapParams).swapId - : undefined, - quoteId: quoteOrSwapId, + swapId: params.exchangeType === "SWAP" ? params.swapId : undefined, amountExpectedTo, magnitudeAwareRate, }, From 817f7e255580b97c9cd9b1f0e108fc9753144290 Mon Sep 17 00:00:00 2001 From: chrisduma-ledger Date: Tue, 3 Sep 2024 16:07:14 +0300 Subject: [PATCH 12/13] feat: refactor --- .../Exchange/CompleteExchange/Body.tsx | 98 +++++++++++++------ .../Exchange/CompleteExchange/BodyContent.tsx | 6 +- .../TransactionBroadcastedContent.tsx | 13 ++- .../screens/exchange/Sell/utils/index.ts | 10 -- .../src/wallet-api/Exchange/server.ts | 1 - 5 files changed, 76 insertions(+), 52 deletions(-) delete mode 100644 apps/ledger-live-desktop/src/renderer/screens/exchange/Sell/utils/index.ts diff --git a/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/Body.tsx b/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/Body.tsx index 508971652f94..e35455d04325 100644 --- a/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/Body.tsx +++ b/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/Body.tsx @@ -6,7 +6,7 @@ import { ExchangeSwap } from "@ledgerhq/live-common/exchange/swap/types"; import { getUpdateAccountWithUpdaterParams } from "@ledgerhq/live-common/exchange/swap/getUpdateAccountWithUpdaterParams"; import { useBroadcast } from "@ledgerhq/live-common/hooks/useBroadcast"; import { Transaction } from "@ledgerhq/live-common/generated/types"; -import { Currency, TokenCurrency } from "@ledgerhq/types-cryptoassets"; +import { CryptoCurrency, Currency, TokenCurrency } from "@ledgerhq/types-cryptoassets"; import { updateAccountWithUpdater } from "~/renderer/actions/accounts"; import { BodyContent } from "./BodyContent"; import { BigNumber } from "bignumber.js"; @@ -32,8 +32,15 @@ export type Data = { magnitudeAwareRate?: BigNumber; }; +export enum ExchangeModeEnum { + Sell = "sell", + Swap = "swap", +} + +export type ExchangeMode = "sell" | "swap"; + type ResultsState = { - isSell?: boolean; + mode: ExchangeMode; swapId?: string; provider: string; sourceCurrency: Currency; @@ -147,44 +154,73 @@ const Body = ({ data, onClose }: { data: Data; onClose?: () => void | undefined [dispatch, exchange, transactionParams, provider], ); - const onBroadcastSuccess = useCallback( - (operation: Operation) => { - // If swap we save to swap history and keep open the drawer - if (swapId && toAccount && magnitudeAwareRate && sourceCurrency && targetCurrency) { - const newResult = { - operation, - swapId, - }; - updateAccount({ - result: newResult, - magnitudeAwareRate, - }); - setResult({ + const getResultByTransactionType = ( + isSwapTransaction: "" | CryptoCurrency | TokenCurrency | null | undefined, + ) => { + return isSwapTransaction + ? { swapId, + mode: ExchangeModeEnum.Swap, provider, - sourceCurrency, - targetCurrency, - }); - - if (getEnv("DISABLE_TRANSACTION_BROADCAST")) { - return onCancel(new DisabledTransactionBroadcastError()); + sourceCurrency: sourceCurrency as Currency, + targetCurrency: targetCurrency as Currency, } - onResult(operation); - } else if ( + : { + provider, + mode: ExchangeModeEnum.Sell, + sourceCurrency: sourceCurrency as Currency, + }; + }; + + const handleSwapTransaction = (operation: Operation, result: ResultsState) => { + const newResult = { + operation, + swapId: swapId as string, + }; + + updateAccount({ + result: newResult, + magnitudeAwareRate: magnitudeAwareRate as BigNumber, + }); + + setResult(result); + + onResult(operation); + }; + + const handleSellTransaction = (operation: Operation, result: ResultsState) => { + setResult(result); + + onResult(operation); + }; + + const onBroadcastSuccess = useCallback( + (operation: Operation) => { + if (getEnv("DISABLE_TRANSACTION_BROADCAST")) { + return onCancel(new DisabledTransactionBroadcastError()); + } + + const isSwapTransaction = + swapId && toAccount && magnitudeAwareRate && sourceCurrency && targetCurrency; + + const isSellTransaction = (data.exchangeType === ExchangeType.SELL || data.exchangeType === ExchangeType.SELL_NG) && - sourceCurrency - ) { - if (getEnv("DISABLE_TRANSACTION_BROADCAST")) { - return onCancel(new DisabledTransactionBroadcastError()); - } - onResult(operation); - setResult({ provider, isSell: true, sourceCurrency }); + sourceCurrency; + + const result = getResultByTransactionType(isSwapTransaction); + + if (isSwapTransaction) { + handleSwapTransaction(operation, result); + } else if (isSellTransaction) { + handleSellTransaction(operation, result); } else { - // else not swap i.e card we close the drawer + // old platform exchange flow onResult(operation); onClose?.(); } }, + // Disabling exhaustive-deps because adding handleSellTransaction and handleSwapTransaction would make it change on every render + // eslint-disable-next-line react-hooks/exhaustive-deps [ swapId, toAccount, diff --git a/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/BodyContent.tsx b/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/BodyContent.tsx index 7e1527b0b0c7..6b62f9069d07 100644 --- a/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/BodyContent.tsx +++ b/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/BodyContent.tsx @@ -11,6 +11,7 @@ import DeviceAction from "~/renderer/components/DeviceAction"; import BigSpinner from "~/renderer/components/BigSpinner"; import ErrorDisplay from "~/renderer/components/ErrorDisplay"; import { TransactionBroadcastedContent } from "./TransactionBroadcastedContent"; +import { ExchangeMode } from "./Body"; const exchangeAction = createAction(completeExchange); const sendAction = txCreateAction(connectApp); @@ -37,8 +38,7 @@ export type BodyContentProps = { }; result?: { swapId?: string; - // The isSell will probably be replaced with a sellId similar with swapId. - isSell?: boolean; + mode: ExchangeMode; provider: string; sourceCurrency: Currency; targetCurrency?: Currency; @@ -59,7 +59,7 @@ export const BodyContent = (props: BodyContentProps) => { return ( @@ -32,9 +31,9 @@ export function TransactionBroadcastedContent(props: TransactionBroadcastedConte sourceCurrency={sourceCurrency?.name} targetCurrency={targetCurrency?.name} provider={provider} - {...(swapId ? swapDefaultTrack : sellDefaultTrack)} + {...(mode === ExchangeModeEnum.Swap && swapId && swapDefaultTrack)} /> - {swapId && targetCurrency && ( + {mode === ExchangeModeEnum.Swap && swapId && targetCurrency && ( <> )} - {isSell && sourceCurrency && ( + {mode === ExchangeModeEnum.Sell && sourceCurrency && ( <> diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Sell/utils/index.ts b/apps/ledger-live-desktop/src/renderer/screens/exchange/Sell/utils/index.ts deleted file mode 100644 index d1f002008f5b..000000000000 --- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Sell/utils/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -export const SELL_VERSION = "1.00"; - -const SELL_TRACKING_PROPERTIES = { - swapVersion: SELL_VERSION, - flow: "sell", -}; - -export const useGetSellTrackingProperties = () => { - return SELL_TRACKING_PROPERTIES; -}; diff --git a/libs/ledger-live-common/src/wallet-api/Exchange/server.ts b/libs/ledger-live-common/src/wallet-api/Exchange/server.ts index 1f6e2b28f4cd..dbd1d9a476ff 100644 --- a/libs/ledger-live-common/src/wallet-api/Exchange/server.ts +++ b/libs/ledger-live-common/src/wallet-api/Exchange/server.ts @@ -22,7 +22,6 @@ import { ExchangeType, ExchangeStartSellParams, SwapLiveError, - ExchangeCompleteSwapParams, } from "@ledgerhq/wallet-api-exchange-module"; import { decodePayloadProtobuf } from "@ledgerhq/hw-app-exchange"; import { TrackingAPI } from "./tracking"; From 5e53bdc7dd45ad2d2a319a3ae24c872c5fb932d8 Mon Sep 17 00:00:00 2001 From: chrisduma-ledger Date: Tue, 3 Sep 2024 16:18:20 +0300 Subject: [PATCH 13/13] chore: refactor --- .../Platform/Exchange/CompleteExchange/Body.tsx | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/Body.tsx b/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/Body.tsx index e35455d04325..1bd8e0495e0f 100644 --- a/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/Body.tsx +++ b/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/Body.tsx @@ -172,6 +172,12 @@ const Body = ({ data, onClose }: { data: Data; onClose?: () => void | undefined }; }; + const handleTransactionResult = (result: ResultsState, operation: Operation) => { + setResult(result); + + onResult(operation); + }; + const handleSwapTransaction = (operation: Operation, result: ResultsState) => { const newResult = { operation, @@ -183,15 +189,11 @@ const Body = ({ data, onClose }: { data: Data; onClose?: () => void | undefined magnitudeAwareRate: magnitudeAwareRate as BigNumber, }); - setResult(result); - - onResult(operation); + handleTransactionResult(result, operation); }; const handleSellTransaction = (operation: Operation, result: ResultsState) => { - setResult(result); - - onResult(operation); + handleTransactionResult(result, operation); }; const onBroadcastSuccess = useCallback(