From ece63320cfd2e7b79ebeccdfe51a5fd3a6620c72 Mon Sep 17 00:00:00 2001
From: BenRey
Date: Fri, 12 Jul 2024 05:13:53 +0200
Subject: [PATCH] improve error catching
---
.../hooks/useWriteSmartContract.tsx | 115 ++++++------------
src/lib/massa-react/{utils.ts => utils.tsx} | 30 ++++-
2 files changed, 64 insertions(+), 81 deletions(-)
rename src/lib/massa-react/{utils.ts => utils.tsx} (70%)
diff --git a/src/lib/massa-react/hooks/useWriteSmartContract.tsx b/src/lib/massa-react/hooks/useWriteSmartContract.tsx
index edf4c563..55417c6d 100644
--- a/src/lib/massa-react/hooks/useWriteSmartContract.tsx
+++ b/src/lib/massa-react/hooks/useWriteSmartContract.tsx
@@ -1,7 +1,6 @@
import { useState } from 'react';
-import { toast, ToastContent } from '../../../components';
-import { OperationToast } from '../../ConnectMassaWallets/components/OperationToast';
-import { logSmartContractEvents } from '../utils';
+import { toast } from '../../../components';
+import { logSmartContractEvents, showToast } from '../utils';
import Intl from '../i18n';
import {
IAccount,
@@ -14,7 +13,6 @@ import {
Operation,
OperationStatus,
} from '@massalabs/massa-web3';
-import { Toast } from 'react-hot-toast';
interface ToasterMessage {
pending: string;
@@ -30,13 +28,14 @@ function minBigInt(a: bigint, b: bigint) {
export function useWriteSmartContract(
account: IAccount,
provider: IProvider,
- isMainnet?: boolean,
+ isMainnet = false,
) {
const [isPending, setIsPending] = useState(false);
const [isOpPending, setIsOpPending] = useState(false);
const [isSuccess, setIsSuccess] = useState(false);
const [isError, setIsError] = useState(false);
const [opId, setOpId] = useState(undefined);
+ const success = OperationStatus.SpeculativeSuccess || OperationStatus.Success;
function resetState() {
setIsPending(false);
@@ -50,7 +49,6 @@ export function useWriteSmartContract(
targetFunction: string,
targetAddress: string,
parameter: Uint8Array,
- messages: ToasterMessage,
coins = BigInt(0),
): Promise {
try {
@@ -71,31 +69,6 @@ export function useWriteSmartContract(
}
}
- function showToast(
- type: 'loading' | 'error' | 'success',
- message: string,
- operationId?: string,
- duration = 5000,
- ) {
- const content = (t: Toast) => (
-
-
-
- );
-
- if (type === 'loading') {
- return toast.loading(content, { duration: Infinity });
- } else if (type === 'error') {
- toast.error(content, { duration });
- } else {
- toast.success(content, { duration });
- }
- }
-
async function callSmartContract(
targetFunction: string,
targetAddress: string,
@@ -112,71 +85,53 @@ export function useWriteSmartContract(
try {
const publicClient = new JsonRPCClient(await provider.getNetwork());
- let maxGas: bigint;
- try {
- maxGas = await gasEstimation(
- targetFunction,
- targetAddress,
- parameter,
- coins,
- );
- } catch (error) {
- console.error('Gas estimation failed:', error);
- showToast('error', messages.error);
- return;
- }
+ let maxGas = await gasEstimation(
+ targetFunction,
+ targetAddress,
+ parameter,
+ coins,
+ );
- let operationId: string;
- try {
- const { operationId: opId } = (await account.callSC(
- targetAddress,
- targetFunction,
- new Uint8Array(parameter),
- coins,
- 0n,
- maxGas,
- )) as ITransactionDetails;
- operationId = opId;
- setOpId(operationId);
- setIsOpPending(true);
- } catch (error) {
- console.error('Smart contract call failed:', error);
- showToast('error', 'Smart contract call failed.');
- return;
- }
+ const { operationId } = (await account.callSC(
+ targetAddress,
+ targetFunction,
+ new Uint8Array(parameter),
+ coins,
+ 0n,
+ maxGas,
+ )) as ITransactionDetails;
+
+ setOpId(operationId);
+ setIsOpPending(true);
- loadingToastId = showToast('loading', messages.pending, operationId);
-
- try {
- const op = new Operation(publicClient, operationId);
- const finalStatus = await op.waitFinalExecution();
- if (finalStatus !== OperationStatus.Success) {
- const errorMessage = `Operation failed with status: ${finalStatus}`;
- console.error(errorMessage);
- showToast('error', messages.error, operationId);
- logSmartContractEvents(publicClient, operationId);
- throw new Error(errorMessage);
- }
- } catch (error) {
- console.error('Operation execution failed:', error);
- showToast('error', messages.error, operationId);
+ loadingToastId = showToast(
+ 'loading',
+ messages.pending,
+ operationId,
+ isMainnet,
+ );
+
+ const op = new Operation(publicClient, operationId);
+ const finalStatus = await op.waitSpeculativeExecution();
+
+ if (!success) {
+ const errorMessage = `Operation failed with status: ${finalStatus}`;
logSmartContractEvents(publicClient, operationId);
- return;
+ throw new Error(errorMessage);
}
setIsSuccess(true);
- toast.dismiss(loadingToastId);
showToast('success', messages.success, operationId);
} catch (error) {
console.error('Error during smart contract call:', error);
setIsError(true);
- toast.dismiss(loadingToastId);
showToast(
'error',
messages.timeout || Intl.t('steps.failed-timeout'),
opId,
);
} finally {
+ toast.dismiss(loadingToastId);
resetState();
}
}
diff --git a/src/lib/massa-react/utils.ts b/src/lib/massa-react/utils.tsx
similarity index 70%
rename from src/lib/massa-react/utils.ts
rename to src/lib/massa-react/utils.tsx
index 8d673c43..da748c7d 100644
--- a/src/lib/massa-react/utils.ts
+++ b/src/lib/massa-react/utils.tsx
@@ -6,9 +6,11 @@ import {
MASSA_EXPLORER_URL,
} from './const';
import Intl from './i18n';
-import { toast } from '../../components';
+import { toast, ToastContent } from '../../components';
import { Operation, PublicAPI } from '@massalabs/massa-web3';
+import { Toast } from 'react-hot-toast';
+import { OperationToast } from '../ConnectMassaWallets/components/OperationToast';
export async function logSmartContractEvents(
client: PublicAPI,
@@ -62,3 +64,29 @@ export async function fetchMASBalance(
return { finalBalance: '0', candidateBalance: '0' };
}
}
+
+export function showToast(
+ type: 'loading' | 'error' | 'success',
+ message: string,
+ operationId?: string,
+ isMainnet?: boolean,
+ duration = 5000,
+) {
+ const content = (t: Toast) => (
+
+
+
+ );
+
+ if (type === 'loading') {
+ return toast.loading(content, { duration: Infinity });
+ } else if (type === 'error') {
+ toast.error(content, { duration });
+ } else {
+ toast.success(content, { duration });
+ }
+}