From c44f6ad09993ebacfb31171d6168c2799ddf0180 Mon Sep 17 00:00:00 2001 From: Diana Savatina Date: Fri, 13 Dec 2024 13:36:15 +0000 Subject: [PATCH] feat: WalletConenctError is added --- ...ithWc.tsx => useSignWithWalletConnect.tsx} | 2 +- .../SendFlow/common/BatchSignPage.tsx | 2 +- .../SendFlow/common/SingleSignPage.tsx | 2 +- .../WalletConnect/WalletConnectProvider.tsx | 29 +++++++++++-------- .../WalletConnect/useHandleWcRequest.tsx | 26 ++++++----------- packages/utils/src/ErrorContext.ts | 10 +++++++ 6 files changed, 39 insertions(+), 32 deletions(-) rename apps/web/src/components/SendFlow/WalletConnect/{useSignWithWc.tsx => useSignWithWalletConnect.tsx} (95%) diff --git a/apps/web/src/components/SendFlow/WalletConnect/useSignWithWc.tsx b/apps/web/src/components/SendFlow/WalletConnect/useSignWithWalletConnect.tsx similarity index 95% rename from apps/web/src/components/SendFlow/WalletConnect/useSignWithWc.tsx rename to apps/web/src/components/SendFlow/WalletConnect/useSignWithWalletConnect.tsx index e3f688526c..0711d4c72a 100644 --- a/apps/web/src/components/SendFlow/WalletConnect/useSignWithWc.tsx +++ b/apps/web/src/components/SendFlow/WalletConnect/useSignWithWalletConnect.tsx @@ -40,7 +40,7 @@ export const useSignWithWalletConnect = ({ return openWith(); }, error => ({ - description: `Failed to confirm Beacon operation: ${error.message}`, + description: `Failed to confirm WalletConnect operation: ${error.message}`, }) ); diff --git a/apps/web/src/components/SendFlow/common/BatchSignPage.tsx b/apps/web/src/components/SendFlow/common/BatchSignPage.tsx index fd451cfe9b..eee5749c08 100644 --- a/apps/web/src/components/SendFlow/common/BatchSignPage.tsx +++ b/apps/web/src/components/SendFlow/common/BatchSignPage.tsx @@ -23,7 +23,7 @@ import { useSignWithBeacon } from "../Beacon/useSignWithBeacon"; import { SignButton } from "../SignButton"; import { SignPageFee } from "../SignPageFee"; import { type SdkSignPageProps } from "../utils"; -import { useSignWithWalletConnect } from "../WalletConnect/useSignWithWc"; +import { useSignWithWalletConnect } from "../WalletConnect/useSignWithWalletConnect"; export const BatchSignPage = ( signProps: SdkSignPageProps, diff --git a/apps/web/src/components/SendFlow/common/SingleSignPage.tsx b/apps/web/src/components/SendFlow/common/SingleSignPage.tsx index 11250ce2f5..5c35f7addf 100644 --- a/apps/web/src/components/SendFlow/common/SingleSignPage.tsx +++ b/apps/web/src/components/SendFlow/common/SingleSignPage.tsx @@ -10,7 +10,7 @@ import { TezSignPage } from "./TezSignPage"; import { UndelegationSignPage } from "./UndelegationSignPage"; import { UnstakeSignPage } from "./UnstakeSignPage"; import { useSignWithBeacon } from "../Beacon/useSignWithBeacon"; -import { useSignWithWalletConnect } from "../WalletConnect/useSignWithWc"; +import { useSignWithWalletConnect } from "../WalletConnect/useSignWithWalletConnect"; export const SingleSignPage = (signProps: SdkSignPageProps) => { const operationType = signProps.operation.operations[0].type; diff --git a/apps/web/src/components/WalletConnect/WalletConnectProvider.tsx b/apps/web/src/components/WalletConnect/WalletConnectProvider.tsx index 9627069e5b..e5c7e54fc8 100644 --- a/apps/web/src/components/WalletConnect/WalletConnectProvider.tsx +++ b/apps/web/src/components/WalletConnect/WalletConnectProvider.tsx @@ -12,10 +12,10 @@ import { walletKit, } from "@umami/state"; import { type Network } from "@umami/tezos"; -import { CustomError } from "@umami/utils"; +import { CustomError, WalletConnectError } from "@umami/utils"; import { formatJsonRpcError } from "@walletconnect/jsonrpc-utils"; import { type SessionTypes } from "@walletconnect/types"; -import { getSdkError } from "@walletconnect/utils"; +import { type SdkErrorKey, getSdkError } from "@walletconnect/utils"; import { type PropsWithChildren, useCallback, useEffect, useRef } from "react"; import { SessionProposalModal } from "./SessionProposalModal"; @@ -94,12 +94,10 @@ export const WalletConnectProvider = ({ children }: PropsWithChildren) => { handleAsyncActionUnsafe(async () => { const activeSessions: Record = walletKit.getActiveSessions(); if (!(event.topic in activeSessions)) { - console.error("WalletConnect session request failed. Session not found", event); - throw new CustomError("WalletConnect session request failed. Session not found"); + throw new WalletConnectError("Session not found", "INVALID_EVENT"); } const session = activeSessions[event.topic]; - toast({ description: `Session request from dApp ${session.peer.metadata.name}`, status: "info", @@ -108,21 +106,28 @@ export const WalletConnectProvider = ({ children }: PropsWithChildren) => { }).catch(async error => { const { id, topic } = event; const activeSessions: Record = walletKit.getActiveSessions(); - console.error("WalletConnect session request failed", event, error); - if (event.topic in activeSessions) { - const session = activeSessions[event.topic]; + const sdkErrorKey: SdkErrorKey = + error instanceof WalletConnectError ? error.sdkError : "SESSION_SETTLEMENT_FAILED"; + const sdkErrorMessage = getSdkError(sdkErrorKey).message; + if (sdkErrorKey === "USER_REJECTED") { + console.info("WC request rejected", sdkErrorKey, event, error); toast({ - description: `Session request for dApp ${session.peer.metadata.name} failed. It was rejected.`, - status: "error", + description: "Session request rejected", + status: "info", }); } else { + console.warn("WC request failed", sdkErrorKey, event, error); + const dappName = + event.topic in activeSessions + ? activeSessions[event.topic].peer.metadata.name + : "unknown dApp"; toast({ - description: `Session request for dApp ${topic} failed. It was rejected. Peer not found by topic.`, + description: `Session request for ${dappName} failed: ${error.message}`, status: "error", }); } // dApp is waiting so we need to notify it - const response = formatJsonRpcError(id, getSdkError("INVALID_METHOD").message); + const response = formatJsonRpcError(id, sdkErrorMessage); await walletKit.respondSessionRequest({ topic, response }); }), [handleAsyncActionUnsafe, handleWcRequest, toast] diff --git a/apps/web/src/components/WalletConnect/useHandleWcRequest.tsx b/apps/web/src/components/WalletConnect/useHandleWcRequest.tsx index cb1403277f..dd28548bf4 100644 --- a/apps/web/src/components/WalletConnect/useHandleWcRequest.tsx +++ b/apps/web/src/components/WalletConnect/useHandleWcRequest.tsx @@ -7,6 +7,7 @@ import { useGetOwnedAccountSafe, walletKit, } from "@umami/state"; +import { CustomError, WalletConnectError } from "@umami/utils"; import { formatJsonRpcError } from "@walletconnect/jsonrpc-utils"; import { type SessionTypes, type SignClientTypes, type Verify } from "@walletconnect/types"; import { getSdkError } from "@walletconnect/utils"; @@ -51,29 +52,20 @@ export const useHandleWcRequest = () => { switch (request.method) { case "tezos_getAccounts": { - const response = formatJsonRpcError(id, getSdkError("INVALID_METHOD").message); - await walletKit.respondSessionRequest({ topic, response }); - return; + throw new WalletConnectError("Getting accounts is not supported yet", "WC_METHOD_UNSUPPORTED"); } case "tezos_sign": { - // onClose = async () => { - // const response = formatJsonRpcError(id, getSdkError("USER_REJECTED").message); - // await walletKit.respondSessionRequest({ topic, response }); - // }; - // return openWith(, { onClose }); - const response = formatJsonRpcError(id, getSdkError("INVALID_METHOD").message); - await walletKit.respondSessionRequest({ topic, response }); - return; + throw new WalletConnectError("Sign is not supported yet", "WC_METHOD_UNSUPPORTED"); } case "tezos_send": { if (!request.params.account) { - throw new Error("Missing account in request"); + throw new WalletConnectError("Missing account in request", "INVALID_EVENT"); } const signer = getAccount(request.params.account); if (!signer) { - throw new Error(`Unknown account, no signer: ${request.params.account}`); + throw new WalletConnectError(`Unknown account, no signer: ${request.params.account}`, "UNAUTHORIZED_EVENT"); } const operation = toAccountOperations( request.params.operations, @@ -107,16 +99,16 @@ export const useHandleWcRequest = () => { const response = formatJsonRpcError(id, getSdkError("USER_REJECTED").message); await walletKit.respondSessionRequest({ topic, response }); }; + // onClose = () => { + // throw new WalletConnectError("Rejected by user", "USER_REJECTED"); + // }; return openWith(modal, { onClose }); } default: - throw new Error(`Unsupported method ${request.method}`); + throw new WalletConnectError(`Unsupported method ${request.method}`, "WC_METHOD_UNSUPPORTED"); } } - // error => ({ - // description: `Error while processing WalletConnect request: ${error.message}`, - // }) ); }; }; diff --git a/packages/utils/src/ErrorContext.ts b/packages/utils/src/ErrorContext.ts index 1766f220f7..db44ce569d 100644 --- a/packages/utils/src/ErrorContext.ts +++ b/packages/utils/src/ErrorContext.ts @@ -1,3 +1,4 @@ +import {type SdkErrorKey} from "@walletconnect/utils"; export type ErrorContext = { timestamp: string; description: string; @@ -12,6 +13,15 @@ export class CustomError extends Error { } } +export class WalletConnectError extends Error { + sdkError: SdkErrorKey; + constructor(message: string, sdkError: SdkErrorKey) { + super(message); + this.name = "WalletConnectError"; + this.sdkError = sdkError; + } +} + // Converts a known L1 error message to a more user-friendly one export const handleTezError = (err: Error): string | undefined => { if (err.message.includes("subtraction_underflow")) {