UNPKG

@ledgerhq/live-common

Version:
126 lines 4.83 kB
import { of, concat } from "rxjs"; import { scan, tap } from "rxjs/operators"; import { useEffect, useState, useMemo } from "react"; import { log } from "@ledgerhq/logs"; import { createAction as createAppAction } from "./app"; import { getMainAccount } from "../../account"; import { isExchangeSwap } from "../../exchange/types"; import { isSwapDisableAppsInstall } from "../../exchange/swap/utils/isIntegrationTestEnv"; const mapResult = ({ startExchangeResult, startExchangeError, }) => startExchangeResult ? { startExchangeResult, } : startExchangeError ? { startExchangeError, } : null; const initialState = { startExchangeResult: null, startExchangeError: null, freezeReduxDevice: false, isLoading: false, }; const reducer = (state, e) => { switch (e.type) { case "start-exchange": return { ...state, freezeReduxDevice: true }; case "start-exchange-error": return { ...state, startExchangeError: e.startExchangeError, isLoading: false }; case "start-exchange-result": return { ...state, startExchangeResult: { nonce: e.startExchangeResult.nonce, device: e.startExchangeResult.device, }, isLoading: false, }; } }; function useFrozenValue(value, frozen) { const [state, setState] = useState(value); useEffect(() => { if (!frozen) { setState(value); } }, [value, frozen]); return state; } export const createAction = (connectAppExec, startExchangeExec) => { const useHook = (reduxDevice, startExchangeRequest) => { const [state, setState] = useState(initialState); const reduxDeviceFrozen = useFrozenValue(reduxDevice, state.freezeReduxDevice); const { exchangeType, provider, exchange } = startExchangeRequest; const requireLatestFirmware = true; const mainFromAccount = exchange ? getMainAccount(exchange.fromAccount, exchange.fromParentAccount) : null; const mainToAccount = exchange && isExchangeSwap(exchange) ? getMainAccount(exchange.toAccount, exchange.toParentAccount) : null; const request = useMemo(() => { if (isSwapDisableAppsInstall()) { return { appName: "Exchange", }; } const dependencies = []; if (mainFromAccount) { dependencies.push({ appName: mainFromAccount?.currency?.managerAppName }); } if (mainToAccount) { dependencies.push({ appName: mainToAccount?.currency?.managerAppName }); } const shouldAddEthApp = (mainFromAccount?.currency?.family === "evm" || mainToAccount?.currency?.family === "evm") && mainFromAccount?.currency?.managerAppName !== "Ethereum" && mainToAccount?.currency?.managerAppName !== "Ethereum"; // Check if we should add ETH app, for cases like when we want AVAX to use the ETH app. if (shouldAddEthApp) { dependencies.push({ appName: "Ethereum", }); } return { appName: "Exchange", dependencies, requireLatestFirmware, }; }, [mainFromAccount, mainToAccount, requireLatestFirmware]); const appState = createAppAction(connectAppExec).useHook(reduxDeviceFrozen, request); const { device, opened, error, appAndVersion } = appState; const hasError = error || state.error; useEffect(() => { if (!opened || !device) { // isLoading should be false until we have a device to show the correct animation setState({ ...initialState, isLoading: device ? !hasError : false }); return; } const sub = concat(of({ type: "start-exchange", }), startExchangeExec({ device, exchangeType, provider, appVersion: appAndVersion?.version, })) .pipe(tap(e => { log("actions-startExchange-event", JSON.stringify(e)); }), scan(reducer, initialState)) .subscribe(setState); return () => { sub.unsubscribe(); }; }, [exchange, device, opened, exchangeType, hasError, appAndVersion, provider]); return { ...appState, ...state, }; }; return { useHook, mapResult, }; }; //# sourceMappingURL=startExchange.js.map