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