diff --git a/.changeset/tidy-insects-remember.md b/.changeset/tidy-insects-remember.md new file mode 100644 index 000000000000..7987cd82be0c --- /dev/null +++ b/.changeset/tidy-insects-remember.md @@ -0,0 +1,5 @@ +--- +"@ledgerhq/live-common": minor +--- + +updated cal fetch to use API calls instead of loading the cal inside LL diff --git a/libs/ledger-live-common/src/exchange/index.ts b/libs/ledger-live-common/src/exchange/index.ts index 5d4dcf62fb31..2db546b796c3 100644 --- a/libs/ledger-live-common/src/exchange/index.ts +++ b/libs/ledger-live-common/src/exchange/index.ts @@ -1,8 +1,9 @@ import { valid, gte } from "semver"; import type { CryptoCurrency, TokenCurrency } from "@ledgerhq/types-cryptoassets"; -import { findExchangeCurrencyConfig as findProdExchangeCurrencyConfig } from "@ledgerhq/cryptoassets"; import { getEnv } from "@ledgerhq/live-env"; import { findTestExchangeCurrencyConfig } from "./testCurrencyConfig"; +import { findExchangeCurrencyData } from "./providers/swap"; +import { findExchangeCurrencyConfig as findProdExchangeCurrencyConfig } from "@ledgerhq/cryptoassets"; // Minimum version of a currency app which has exchange capabilities, meaning it can be used // for sell/swap, and do silent signing. const exchangeSupportAppVersions = { @@ -26,21 +27,6 @@ const exchangeSupportAppVersions = { zencash: "1.5.0", }; -const findExchangeCurrencyConfig = ( - id: string, -): - | { - config: string; - - signature: string; - } - | null - | undefined => { - return getEnv("MOCK_EXCHANGE_TEST_CONFIG") - ? findTestExchangeCurrencyConfig(id) - : findProdExchangeCurrencyConfig(id); -}; - type ExchangeCurrencyNameAndSignature = { config: Buffer; signature: Buffer; @@ -51,13 +37,25 @@ export const isExchangeSupportedByApp = (appName: string, appVersion: string): b return !!(valid(minVersion) && valid(appVersion) && gte(appVersion, minVersion)); }; -export const getCurrencyExchangeConfig = ( +export const getCurrencyExchangeConfig = async ( currency: CryptoCurrency | TokenCurrency, -): ExchangeCurrencyNameAndSignature => { - const res = findExchangeCurrencyConfig(currency.id); +): Promise => { + let res; + try { + res = getEnv("MOCK_EXCHANGE_TEST_CONFIG") + ? await findTestExchangeCurrencyConfig(currency.id) + : await findExchangeCurrencyData(currency.id); - if (!res) { - throw new Error(`Exchange, missing configuration for ${currency.id}`); + if (!res) { + throw new Error("Missing primary config"); + } + } catch (error) { + // Fallback to old production config if the primary fetch fails, should be removed when we have a HA CAL + res = await findProdExchangeCurrencyConfig(currency.id); + + if (!res) { + throw new Error(`Exchange, missing configuration for ${currency.id}`); + } } return { @@ -65,7 +63,3 @@ export const getCurrencyExchangeConfig = ( signature: Buffer.from(res.signature, "hex"), }; }; - -export const isCurrencyExchangeSupported = (currency: CryptoCurrency | TokenCurrency): boolean => { - return !!findExchangeCurrencyConfig(currency.id); -}; diff --git a/libs/ledger-live-common/src/exchange/platform/transfer/completeExchange.ts b/libs/ledger-live-common/src/exchange/platform/transfer/completeExchange.ts index f18ebfde3586..6cb2b08c15be 100644 --- a/libs/ledger-live-common/src/exchange/platform/transfer/completeExchange.ts +++ b/libs/ledger-live-common/src/exchange/platform/transfer/completeExchange.ts @@ -102,7 +102,7 @@ const completeExchange = ( if (unsubscribed) return; const { config: payoutAddressConfig, signature: payoutAddressConfigSignature } = - getCurrencyExchangeConfig(payoutCurrency); + await getCurrencyExchangeConfig(payoutCurrency); try { o.next({ diff --git a/libs/ledger-live-common/src/exchange/providers/swap.ts b/libs/ledger-live-common/src/exchange/providers/swap.ts index 36f68ed6db40..9338a69f9c1d 100644 --- a/libs/ledger-live-common/src/exchange/providers/swap.ts +++ b/libs/ledger-live-common/src/exchange/providers/swap.ts @@ -173,6 +173,34 @@ const DEFAULT_SWAP_PROVIDERS: Record | null = null; export const getSwapProvider = async ( @@ -187,7 +215,7 @@ export const getSwapProvider = async ( return res[providerName.toLowerCase()]; }; -function transformData(providersData) { +function transformData(providersData: ProvidersDataResponse): Record { const transformed = {}; providersData.forEach(provider => { const key = provider.name.toLowerCase(); @@ -203,14 +231,44 @@ function transformData(providersData) { return transformed; } -export const getProvidersData = async () => { - const providersData = await network({ - url: - "https://crypto-assets-service.api.ledger.com/v1/partners" + - "?output=name,signature,public_key,public_key_curve" + - "&service_name=swap", +export const getProvidersData = async (): Promise> => { + const { data: providersData } = await network({ + method: "GET", + url: "https://crypto-assets-service.api.ledger.com/v1/partners", + params: { + output: "name,signature,public_key,public_key_curve", + service_name: "swap", + }, }); - return transformData(providersData.data); + + return transformData(providersData); +}; + +/** + * Retrieves the currency data for a given ID + * @param currencyId The unique identifier for the currency. + * @returns A promise that resolves to the currency data including ID, serialized config, and signature. + */ +export const findExchangeCurrencyData = async (currencyId: string): Promise => { + const { data: currencyData } = await network({ + method: "GET", + url: "https://crypto-assets-service.api.ledger.com/v1/currencies", + params: { + output: "id,exchange_app_config_serialized,exchange_app_signature", + id: currencyId, + }, + }); + if (!currencyData.length) { + throw new Error(`Exchange, missing configuration for ${currencyId}`); + } + if (currencyData.length !== 1) { + throw new Error(`Exchange, multiple configurations found for ${currencyId}`); + } + return { + id: currencyData[0].id, + config: currencyData[0].exchange_app_config_serialized, + signature: currencyData[0].exchange_app_signature, + } as CurrencyData; }; export const getProvidersCDNData = async () => { diff --git a/libs/ledger-live-common/src/exchange/swap/completeExchange.ts b/libs/ledger-live-common/src/exchange/swap/completeExchange.ts index 797748bea014..bb382c795fef 100644 --- a/libs/ledger-live-common/src/exchange/swap/completeExchange.ts +++ b/libs/ledger-live-common/src/exchange/swap/completeExchange.ts @@ -111,7 +111,7 @@ const completeExchange = ( if (unsubscribed) return; const { config: payoutAddressConfig, signature: payoutAddressConfigSignature } = - getCurrencyExchangeConfig(payoutCurrency); + await getCurrencyExchangeConfig(payoutCurrency); try { currentStep = "CHECK_PAYOUT_ADDRESS"; @@ -150,7 +150,7 @@ const completeExchange = ( if (unsubscribed) return; const { config: refundAddressConfig, signature: refundAddressConfigSignature } = - getCurrencyExchangeConfig(refundCurrency); + await getCurrencyExchangeConfig(refundCurrency); if (unsubscribed) return; try { diff --git a/libs/ledger-live-common/src/exchange/swap/initSwap.ts b/libs/ledger-live-common/src/exchange/swap/initSwap.ts index 6aa2d26cf6b7..041daffa6c9d 100644 --- a/libs/ledger-live-common/src/exchange/swap/initSwap.ts +++ b/libs/ledger-live-common/src/exchange/swap/initSwap.ts @@ -200,7 +200,7 @@ const initSwap = (input: InitSwapInput): Observable => { ); if (unsubscribed) return; const { config: payoutAddressConfig, signature: payoutAddressConfigSignature } = - getCurrencyExchangeConfig(payoutCurrency); + await getCurrencyExchangeConfig(payoutCurrency); try { await swap.checkPayoutAddress( @@ -234,7 +234,7 @@ const initSwap = (input: InitSwapInput): Observable => { ); if (unsubscribed) return; const { config: refundAddressConfig, signature: refundAddressConfigSignature } = - getCurrencyExchangeConfig(refundCurrency); + await getCurrencyExchangeConfig(refundCurrency); if (unsubscribed) return; // NB Floating rates may change the original amountTo so we can pass an override // to properly render the amount on the device confirmation steps. Although changelly