Skip to content

Commit

Permalink
feat: exchangeModule triggers error drawer (#6654)
Browse files Browse the repository at this point in the history
* feat: exchangeModule triggers error drawer

* chore: changesets

* fixme: error screen llm

* chore: lint

* chore:removing duplicate types declaration

* Revert "chore:removing duplicate types declaration"

This reverts commit 1479137.

* remove duplicate types
  • Loading branch information
CremaFR committed Apr 17, 2024
1 parent 66a4172 commit d9d8902
Show file tree
Hide file tree
Showing 11 changed files with 72 additions and 29 deletions.
5 changes: 5 additions & 0 deletions .changeset/mean-jobs-help.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"ledger-live-desktop": patch
---

support new error management
5 changes: 5 additions & 0 deletions .changeset/twenty-moose-peel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@ledgerhq/wallet-api-exchange-module": minor
---

added error management
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useMemo } from "react";
import React, { useMemo } from "react";
import { useDispatch, useSelector } from "react-redux";
import { WalletAPICustomHandlers } from "@ledgerhq/live-common/wallet-api/types";
import {
Expand All @@ -12,10 +12,13 @@ import { flattenAccountsSelector } from "~/renderer/reducers/accounts";
import { currentRouteNameRef } from "~/renderer/analytics/screenRefs";
import { openExchangeDrawer } from "~/renderer/actions/UI";
import { WebviewProps } from "../Web3AppWebview/types";
import { context } from "~/renderer/drawers/Provider";
import WebviewErrorDrawer from "~/renderer/screens/exchange/Swap2/Form/WebviewErrorDrawer";

export function usePTXCustomHandlers(manifest: WebviewProps["manifest"]) {
const dispatch = useDispatch();
const accounts = useSelector(flattenAccountsSelector);
const { setDrawer } = React.useContext(context);

const tracking = useMemo(
() =>
Expand Down Expand Up @@ -77,8 +80,12 @@ export function usePTXCustomHandlers(manifest: WebviewProps["manifest"]) {
}),
);
},
"custom.exchange.error": ({ error }) => {
setDrawer(WebviewErrorDrawer, error);
return Promise.resolve();
},
},
}),
};
}, [accounts, dispatch, manifest, tracking]);
}, [accounts, dispatch, manifest, tracking, setDrawer]);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useEffect, useMemo, useRef, useState } from "react";
import { useSelector, useDispatch } from "react-redux";
import styled from "styled-components";
import { context } from "~/renderer/drawers/Provider";
import WebviewErrorDrawer, { SwapLiveError } from "./WebviewErrorDrawer/index";
import WebviewErrorDrawer from "./WebviewErrorDrawer/index";

import { counterValueCurrencySelector, languageSelector } from "~/renderer/reducers/settings";
import useTheme from "~/renderer/hooks/useTheme";
Expand All @@ -23,6 +23,7 @@ import { captureException } from "~/sentry/internal";
import { usePTXCustomHandlers } from "~/renderer/components/WebPTXPlayer/CustomHandlers";
import { LiveAppManifest } from "@ledgerhq/live-common/platform/types";
import { useFeature } from "@ledgerhq/live-common/featureFlags/index";
import { SwapLiveError } from "@ledgerhq/live-common/exchange/swap/types";

const isDevelopment = process.env.NODE_ENV === "development";

Expand All @@ -35,10 +36,6 @@ export class UnableToLoadSwapLiveError extends Error {
}
}

type CustomHandlersParams<Params> = {
params: Params;
};

export type SwapProps = {
provider: string;
fromAccountId: string;
Expand Down Expand Up @@ -114,12 +111,6 @@ const SwapWebView = ({ manifest, swapState, liveAppUnavailable }: SwapWebProps)
// "custom.swapStateSet": (params: CustomHandlersParams<unknown>) => {
// return Promise.resolve();
// },
"custom.throwExchangeErrorToLedgerLive": ({
params,
}: CustomHandlersParams<SwapLiveError>) => {
onSwapWebviewError(params);
return Promise.resolve();
},
"custom.saveSwapToHistory": ({
params,
}: {
Expand Down Expand Up @@ -166,10 +157,6 @@ const SwapWebView = ({ manifest, swapState, liveAppUnavailable }: SwapWebProps)
);
return Promise.resolve();
},
"custom.throwGenericErrorToLedgerLive": () => {
onSwapWebviewError();
return Promise.resolve();
},
"custom.swapRedirectToHistory": () => {
redirectToHistory();
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import Box from "~/renderer/components/Box";
import { useGetSwapTrackingProperties } from "../../utils/index";
import { Text } from "@ledgerhq/react-ui";
import ErrorNoBorder from "~/renderer/icons/ErrorNoBorder";
import { SwapLiveError } from "@ledgerhq/live-common/exchange/swap/types";

const ContentBox = styled(Box)`
display: flex;
Expand Down Expand Up @@ -43,14 +44,6 @@ const ErrorDescription = styled(Text).attrs({
user-select: text;
`;

export type SwapLiveError = {
type?: string;
cause: {
message?: string;
swapCode?: string;
};
};

export default function WebviewErrorDrawer(error?: SwapLiveError) {
const swapDefaultTrack = useGetSwapTrackingProperties();
let titleKey = "swap2.webviewErrorDrawer.title";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ export function usePTXCustomHandlers(manifest: WebviewProps["manifest"]) {
},
});
},
"custom.exchange.error": () => {
// todo add screen for LLM
},
},
}),
};
Expand Down
19 changes: 15 additions & 4 deletions libs/exchange-module/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
ExchangeStartResult,
ExchangeStartSellParams,
ExchangeStartSwapParams,
SwapLiveError,
} from "./types";

export * from "./types";
Expand Down Expand Up @@ -82,8 +83,6 @@ export class ExchangeModule extends CustomModule {
* @param fromAccountId - Identifier of the account used as a source for the tx or parent account (for "new token")
* @param toAccountId - Identifier of the account or parent account (for "new token") used as a destination
* @param swapId - Identifier of the swap used by backend
* @param amountExpectedTo - Amount expected to receive by the user in the transaction
* @param magnitudeAwareRate - rate expected to receive by the user in the swap transaction
* @param tokenCurrency - "new token" used in the transaction, not listed yet in wallet-api list
* @param transaction - Transaction containing the recipient and amount
* @param binaryPayload - Blueprint of the data that we'll allow signing
Expand All @@ -107,8 +106,6 @@ export class ExchangeModule extends CustomModule {
fromAccountId: string;
toAccountId: string;
swapId: string;
amountExpectedTo: bigint;
magnitudeAwareRate: bigint;
transaction: Transaction;
binaryPayload: string;
signature: string;
Expand Down Expand Up @@ -178,6 +175,20 @@ export class ExchangeModule extends CustomModule {
return result.transactionHash;
}

/**
* open a drawer to display errors that Ledger live can't display itself
* @param error, the error to display
* @returns nothing
*/
async throwExchangeErrorToLedgerLive({
error,
}: {
error: SwapLiveError | undefined;
}): Promise<void> {
await this.request<SwapLiveError | undefined, void>("custom.exchange.error", error);
return;
}

/**
* Complete an exchange fund process by passing by the exchange content and its signature.
* User will be prompted on its device to approve the fund exchange operation.
Expand Down
8 changes: 8 additions & 0 deletions libs/exchange-module/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,11 @@ export type ExchangeCompleteParams =
export type ExchangeCompleteResult = {
transactionHash: string;
};

export type SwapLiveError = {
type?: string;
cause: {
message?: string;
swapCode?: string;
};
};
1 change: 1 addition & 0 deletions libs/ledger-live-common/src/exchange/swap/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Account, AccountLike, AccountRaw, AccountRawLike, Operation } from "@le
import { Transaction, TransactionRaw } from "../../generated/types";
import { Result as UseBridgeTransactionResult } from "../../bridge/useBridgeTransaction";
import { DeviceModelId } from "@ledgerhq/devices";
export type { SwapLiveError } from "@ledgerhq/wallet-api-exchange-module";

export type ExchangeSwap = {
fromParentAccount: Account | null | undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,12 @@ const testAppManifest = {

const mockUiStartExchange = jest.fn();
const mockUiCompleteExchange = jest.fn();
const mockUiError = jest.fn();

const mockUiHooks = {
"custom.exchange.start": mockUiStartExchange,
"custom.exchange.complete": mockUiCompleteExchange,
"custom.exchange.error": mockUiError,
};

// Mock converter id to send back the id received in params.
Expand Down
21 changes: 21 additions & 0 deletions libs/ledger-live-common/src/wallet-api/Exchange/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
ExchangeStartResult,
ExchangeType,
ExchangeStartSellParams,
SwapLiveError,
} from "@ledgerhq/wallet-api-exchange-module";
import { decodePayloadProtobuf } from "@ledgerhq/hw-app-exchange";
import { TrackingAPI } from "./tracking";
Expand Down Expand Up @@ -48,6 +49,7 @@ type Handlers = {
ExchangeStartParams | ExchangeStartSwapParams | ExchangeStartSellParams
>;
"custom.exchange.complete": RPCHandler<ExchangeCompleteResult, ExchangeCompleteParams>;
"custom.exchange.error": RPCHandler<void, SwapLiveError>;
};

export type CompleteExchangeUiRequest = {
Expand Down Expand Up @@ -88,6 +90,11 @@ type ExchangeUiHooks = {
onSuccess: (hash: string) => void;
onCancel: (error: Error) => void;
}) => void;
"custom.exchange.error": (params: {
error: SwapLiveError | undefined;
onSuccess: () => void;
onCancel: () => void;
}) => void;
};

export const handlers = ({
Expand All @@ -97,6 +104,7 @@ export const handlers = ({
uiHooks: {
"custom.exchange.start": uiExchangeStart,
"custom.exchange.complete": uiExchangeComplete,
"custom.exchange.error": uiError,
},
}: {
accounts: AccountLike[];
Expand Down Expand Up @@ -288,6 +296,19 @@ export const handlers = ({
);
},
),
"custom.exchange.error": customWrapper<SwapLiveError, void>(async params => {
return new Promise((resolve, reject) =>
uiError({
error: params,
onSuccess: () => {
resolve();
},
onCancel: () => {
reject();
},
}),
);
}),
}) as const satisfies Handlers;

function extractSwapStartParam(
Expand Down

0 comments on commit d9d8902

Please sign in to comment.