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, },