wagmi-extended 0.1.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs.js +252 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.esm.js +245 -0
- package/dist/index.esm.js.map +1 -0
- package/package.json +20 -4
- package/rollup.config.mjs +28 -0
- package/tsconfig.json +1 -1
- package/dist/hooks/useContractWriteExtended.js +0 -39
- package/dist/hooks/useHandleTransactionMutation.js +0 -77
- package/dist/hooks/useInvalidateQueries.js +0 -17
- package/dist/hooks/useSendTransactionExtended.js +0 -39
- package/dist/index.js +0 -19
- package/dist/utils/errorParser.js +0 -90
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var wagmi = require('wagmi');
|
|
4
|
+
var actions = require('wagmi/actions');
|
|
5
|
+
var reactQuery = require('@tanstack/react-query');
|
|
6
|
+
var react = require('react');
|
|
7
|
+
var viem = require('viem');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Hook to invalidate multiple queries in the React Query cache.
|
|
11
|
+
*
|
|
12
|
+
* @returns An object with the invalidateMany function.
|
|
13
|
+
*/
|
|
14
|
+
function useInvalidateQueries() {
|
|
15
|
+
const queryClient = reactQuery.useQueryClient();
|
|
16
|
+
const invalidateMany = async (queries) => {
|
|
17
|
+
const promises = queries.map((queryKey) => queryClient.invalidateQueries({ queryKey }));
|
|
18
|
+
await Promise.all(promises);
|
|
19
|
+
};
|
|
20
|
+
return { invalidateMany };
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Default error mapping that contains a set of error identifiers mapped to user-friendly error messages.
|
|
25
|
+
*/
|
|
26
|
+
const defaultErrorMapping = {
|
|
27
|
+
EnforcedPause: "Temporary pause in effect, please check Discord for updates.",
|
|
28
|
+
ErrorNotEnoughAllowance: "Not enough allowance, did you approve your tokens first?",
|
|
29
|
+
"0xc2139725": "Not enough allowance, did you approve your tokens first?",
|
|
30
|
+
SharesReceivedBelowMinimum: "Action exceeded safe slippage parameters, please try again later",
|
|
31
|
+
"0xea8d7f02": "Action exceeded safe slippage parameters, please try again later",
|
|
32
|
+
MaxSlippageExceeded: "Action exceeded safe slippage parameters, please try again later",
|
|
33
|
+
"51": "Supply cap exceeded",
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* A mutable copy of the default error mapping that can be extended or overridden by users.
|
|
37
|
+
*/
|
|
38
|
+
let currentErrorMapping = { ...defaultErrorMapping };
|
|
39
|
+
/**
|
|
40
|
+
* Merges a custom error mapping into the current error mapping.
|
|
41
|
+
* Custom values override any existing keys.
|
|
42
|
+
*
|
|
43
|
+
* @param customMapping - An object containing error keys and the corresponding custom messages.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* setErrorMapping({
|
|
47
|
+
* ErrorNotEnoughAllowance: "Custom message: Please approve tokens first!",
|
|
48
|
+
* NewCustomError: "A custom error occurred."
|
|
49
|
+
* });
|
|
50
|
+
*/
|
|
51
|
+
const setErrorMapping = (customMapping) => {
|
|
52
|
+
currentErrorMapping = { ...currentErrorMapping, ...customMapping };
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Resets the current error mapping to the default error mapping.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* resetErrorMapping();
|
|
59
|
+
*/
|
|
60
|
+
const resetErrorMapping = () => {
|
|
61
|
+
currentErrorMapping = { ...defaultErrorMapping };
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Retrieves the current error mapping.
|
|
65
|
+
*
|
|
66
|
+
* @returns The current error mapping object.
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* const mapping = getErrorMapping();
|
|
70
|
+
* console.log(mapping);
|
|
71
|
+
*/
|
|
72
|
+
const getErrorMapping = () => currentErrorMapping;
|
|
73
|
+
/**
|
|
74
|
+
* Parses an error object and returns a user-friendly error message.
|
|
75
|
+
*
|
|
76
|
+
* The function checks if the error is a ContractFunctionRevertedError by attempting to walk through
|
|
77
|
+
* the error using its `walk` method. If a matching error is found and its error key exists in the
|
|
78
|
+
* current error mapping, the corresponding custom message will be returned. Otherwise, it falls back
|
|
79
|
+
* to the error's own message properties.
|
|
80
|
+
*
|
|
81
|
+
* @param error - The error object, potentially including additional error details.
|
|
82
|
+
* @returns A user-friendly error message.
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* const message = getParsedError(someError);
|
|
86
|
+
* console.log(message); // Outputs a custom error message or a default error message.
|
|
87
|
+
*/
|
|
88
|
+
const getParsedError = (error) => {
|
|
89
|
+
var _a, _b, _c, _d;
|
|
90
|
+
const defaultMessage = "An unknown error occurred. Please contact support.";
|
|
91
|
+
let message = defaultMessage;
|
|
92
|
+
let errorKey = "";
|
|
93
|
+
const revertedError = (error === null || error === void 0 ? void 0 : error.walk)
|
|
94
|
+
? error.walk((err) => err instanceof viem.ContractFunctionRevertedError)
|
|
95
|
+
: null;
|
|
96
|
+
if (revertedError instanceof viem.ContractFunctionRevertedError) {
|
|
97
|
+
errorKey =
|
|
98
|
+
(_d = (_c = (_b = (_a = revertedError.data) === null || _a === void 0 ? void 0 : _a.errorName) !== null && _b !== void 0 ? _b : revertedError.signature) !== null && _c !== void 0 ? _c : revertedError.reason) !== null && _d !== void 0 ? _d : "";
|
|
99
|
+
if (currentErrorMapping[errorKey])
|
|
100
|
+
return currentErrorMapping[errorKey];
|
|
101
|
+
}
|
|
102
|
+
message = error.shortMessage || error.details || error.message || message;
|
|
103
|
+
return message;
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Custom hook to handle transaction mutations.
|
|
108
|
+
*
|
|
109
|
+
* @returns {Function} A shared `onSettled` callback for transaction mutations.
|
|
110
|
+
*/
|
|
111
|
+
function useHandleTransactionMutation({ settings, }) {
|
|
112
|
+
const wagmiConfig = wagmi.useConfig();
|
|
113
|
+
const { invalidateMany } = useInvalidateQueries();
|
|
114
|
+
const [isPending, setIsPending] = react.useState(false);
|
|
115
|
+
const [errorMessage, setErrorMessage] = react.useState(undefined);
|
|
116
|
+
const onMutate = () => {
|
|
117
|
+
setIsPending(true);
|
|
118
|
+
setErrorMessage(undefined);
|
|
119
|
+
};
|
|
120
|
+
const onSettled = async (txHash, error, args) => {
|
|
121
|
+
var _a, _b, _c;
|
|
122
|
+
try {
|
|
123
|
+
if (error)
|
|
124
|
+
throw error;
|
|
125
|
+
if (!(settings === null || settings === void 0 ? void 0 : settings.disableWaitingForReceipt)) {
|
|
126
|
+
// 1. wait for transaction receipt
|
|
127
|
+
const txReceipt = await actions.waitForTransactionReceipt(wagmiConfig, {
|
|
128
|
+
hash: txHash,
|
|
129
|
+
});
|
|
130
|
+
// 2. throw if receipt is not valid
|
|
131
|
+
if (txReceipt.status === "reverted")
|
|
132
|
+
throw new Error("Execution reverted.");
|
|
133
|
+
if (txReceipt.status !== "success")
|
|
134
|
+
throw new Error("Execution reverted.");
|
|
135
|
+
}
|
|
136
|
+
// 3. invalidate queries
|
|
137
|
+
if (settings === null || settings === void 0 ? void 0 : settings.queriesToInvalidate)
|
|
138
|
+
await invalidateMany(settings === null || settings === void 0 ? void 0 : settings.queriesToInvalidate);
|
|
139
|
+
// 4. call onSuccess callback
|
|
140
|
+
(_a = settings === null || settings === void 0 ? void 0 : settings.onSuccess) === null || _a === void 0 ? void 0 : _a.call(settings, txHash);
|
|
141
|
+
if (!(settings === null || settings === void 0 ? void 0 : settings.disableLogging)) {
|
|
142
|
+
// 5. log result
|
|
143
|
+
// eslint-disable-next-line no-console
|
|
144
|
+
console.info("Operation successful:", txHash); // todo: add logging service
|
|
145
|
+
}
|
|
146
|
+
// 6. return result
|
|
147
|
+
return txHash;
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
const parsedError = getParsedError(error);
|
|
151
|
+
if (!(settings === null || settings === void 0 ? void 0 : settings.disableLogging)) {
|
|
152
|
+
// 1. log error
|
|
153
|
+
console.error(`ContractWriteExtended Operation failed with error(parsed): ${parsedError}`, { error }, { args });
|
|
154
|
+
console.error({ error });
|
|
155
|
+
}
|
|
156
|
+
// 2. set error message
|
|
157
|
+
setErrorMessage(parsedError);
|
|
158
|
+
// 3. call callback
|
|
159
|
+
(_b = settings === null || settings === void 0 ? void 0 : settings.onError) === null || _b === void 0 ? void 0 : _b.call(settings, error);
|
|
160
|
+
}
|
|
161
|
+
finally {
|
|
162
|
+
setIsPending(false);
|
|
163
|
+
// 1. call callback
|
|
164
|
+
(_c = settings === null || settings === void 0 ? void 0 : settings.onSettled) === null || _c === void 0 ? void 0 : _c.call(settings);
|
|
165
|
+
}
|
|
166
|
+
return undefined;
|
|
167
|
+
};
|
|
168
|
+
return {
|
|
169
|
+
onMutate,
|
|
170
|
+
onSettled,
|
|
171
|
+
isPending,
|
|
172
|
+
errorMessage,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Custom hook for writing to a smart contract using Wagmi.
|
|
178
|
+
*
|
|
179
|
+
* This hook provides functionality for sending a transaction using Wagmi, handling the asynchronous nature of the operation, waiting for the transaction receipt, and error handling.
|
|
180
|
+
*
|
|
181
|
+
* @param {WriteExtendedAsyncParams} [settings] - Optional settings for the write operation.
|
|
182
|
+
* @param {boolean} [settings.disableWaitingForReceipt] - Disables waiting for the transaction receipt.
|
|
183
|
+
* @param {boolean} [settings.disableLogging] - Disables logging the result of the transaction.
|
|
184
|
+
* @param {Function} [settings.onSuccess] - Callback function to be called on successful transaction.
|
|
185
|
+
* @param {Function} [settings.onError] - Callback function to be called on transaction error.
|
|
186
|
+
* @param {Function} [settings.onSettled] - Callback function to be called after the transaction settles (whether success or failure).
|
|
187
|
+
* @param {QueryKey[]} [settings.queriesToInvalidate] - Array of query keys to invalidate after the transaction receives a receipt.
|
|
188
|
+
* @returns {Object} Object containing the following properties:
|
|
189
|
+
* - {boolean} isPending - Indicates whether the transaction is pending.
|
|
190
|
+
* - {string|undefined} errorMessage - The error message, if an error occurred during the transaction.
|
|
191
|
+
* - {Function} writeContractAsync - Function to trigger the write operation.
|
|
192
|
+
*/
|
|
193
|
+
function useContractWriteExtended(settings) {
|
|
194
|
+
const { isPending, errorMessage, onMutate, onSettled } = useHandleTransactionMutation({
|
|
195
|
+
settings,
|
|
196
|
+
});
|
|
197
|
+
const { writeContractAsync, ...rest } = wagmi.useWriteContract({
|
|
198
|
+
mutation: {
|
|
199
|
+
onMutate,
|
|
200
|
+
onSettled,
|
|
201
|
+
},
|
|
202
|
+
});
|
|
203
|
+
return {
|
|
204
|
+
...rest,
|
|
205
|
+
isPending,
|
|
206
|
+
errorMessage,
|
|
207
|
+
writeContractAsync,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Custom hook for sending a transaction using Wagmi.
|
|
213
|
+
*
|
|
214
|
+
* This hook provides functionality for sending a transaction using Wagmi, handling the asynchronous nature of the operation, waiting for the transaction receipt, and error handling.
|
|
215
|
+
*
|
|
216
|
+
* @param {SeamlessWriteAsyncParams} [settings] - Optional settings for the write operation.
|
|
217
|
+
* @param {boolean} [settings.disableWaitingForReceipt] - Disables waiting for the transaction receipt.
|
|
218
|
+
* @param {boolean} [settings.disableLogging] - Disables logging the result of the transaction.
|
|
219
|
+
* @param {Function} [settings.onSuccess] - Callback function to be called on successful transaction.
|
|
220
|
+
* @param {Function} [settings.onError] - Callback function to be called on transaction error.
|
|
221
|
+
* @param {Function} [settings.onSettled] - Callback function to be called after the transaction settles (whether success or failure).
|
|
222
|
+
* @param {QueryKey[]} [settings.queriesToInvalidate] - Array of query keys to invalidate after the transaction receives a receipt.
|
|
223
|
+
* @returns {Object} Object containing the following properties:
|
|
224
|
+
* - {boolean} isPending - Indicates whether the transaction is pending.
|
|
225
|
+
* - {string|undefined} errorMessage - The error message, if an error occurred during the transaction.
|
|
226
|
+
* - {Function} sendTransactionAsync - Function to trigger the send transaction mutation.
|
|
227
|
+
*/
|
|
228
|
+
function useSendTransactionExtended(settings) {
|
|
229
|
+
const { isPending, errorMessage, onMutate, onSettled } = useHandleTransactionMutation({
|
|
230
|
+
settings,
|
|
231
|
+
});
|
|
232
|
+
const { sendTransactionAsync, ...rest } = wagmi.useSendTransaction({
|
|
233
|
+
mutation: {
|
|
234
|
+
onMutate,
|
|
235
|
+
onSettled,
|
|
236
|
+
},
|
|
237
|
+
});
|
|
238
|
+
return {
|
|
239
|
+
...rest,
|
|
240
|
+
isPending,
|
|
241
|
+
errorMessage,
|
|
242
|
+
sendTransactionAsync,
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
exports.getErrorMapping = getErrorMapping;
|
|
247
|
+
exports.getParsedError = getParsedError;
|
|
248
|
+
exports.resetErrorMapping = resetErrorMapping;
|
|
249
|
+
exports.setErrorMapping = setErrorMapping;
|
|
250
|
+
exports.useContractWriteExtended = useContractWriteExtended;
|
|
251
|
+
exports.useSendTransactionExtended = useSendTransactionExtended;
|
|
252
|
+
//# sourceMappingURL=index.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../src/hooks/useInvalidateQueries.ts","../src/utils/errorParser.ts","../src/hooks/useHandleTransactionMutation.ts","../src/hooks/useContractWriteExtended.ts","../src/hooks/useSendTransactionExtended.ts"],"sourcesContent":["import { QueryKey, useQueryClient } from \"@tanstack/react-query\";\n\n/**\n * Hook to invalidate multiple queries in the React Query cache.\n *\n * @returns An object with the invalidateMany function.\n */\nexport function useInvalidateQueries() {\n const queryClient = useQueryClient();\n\n const invalidateMany = async (queries: (QueryKey | undefined)[]) => {\n const promises = queries.map((queryKey) =>\n queryClient.invalidateQueries({ queryKey })\n );\n await Promise.all(promises);\n };\n\n return { invalidateMany };\n}\n","import { BaseError, ContractFunctionRevertedError } from \"viem\";\n\n/**\n * Default error mapping that contains a set of error identifiers mapped to user-friendly error messages.\n */\nconst defaultErrorMapping: Record<string, string> = {\n EnforcedPause: \"Temporary pause in effect, please check Discord for updates.\",\n ErrorNotEnoughAllowance:\n \"Not enough allowance, did you approve your tokens first?\",\n \"0xc2139725\": \"Not enough allowance, did you approve your tokens first?\",\n SharesReceivedBelowMinimum:\n \"Action exceeded safe slippage parameters, please try again later\",\n \"0xea8d7f02\":\n \"Action exceeded safe slippage parameters, please try again later\",\n MaxSlippageExceeded:\n \"Action exceeded safe slippage parameters, please try again later\",\n \"51\": \"Supply cap exceeded\",\n};\n\n/**\n * A mutable copy of the default error mapping that can be extended or overridden by users.\n */\nlet currentErrorMapping: Record<string, string> = { ...defaultErrorMapping };\n\n/**\n * Merges a custom error mapping into the current error mapping.\n * Custom values override any existing keys.\n *\n * @param customMapping - An object containing error keys and the corresponding custom messages.\n *\n * @example\n * setErrorMapping({\n * ErrorNotEnoughAllowance: \"Custom message: Please approve tokens first!\",\n * NewCustomError: \"A custom error occurred.\"\n * });\n */\nexport const setErrorMapping = (\n customMapping: Record<string, string>\n): void => {\n currentErrorMapping = { ...currentErrorMapping, ...customMapping };\n};\n\n/**\n * Resets the current error mapping to the default error mapping.\n *\n * @example\n * resetErrorMapping();\n */\nexport const resetErrorMapping = (): void => {\n currentErrorMapping = { ...defaultErrorMapping };\n};\n\n/**\n * Retrieves the current error mapping.\n *\n * @returns The current error mapping object.\n *\n * @example\n * const mapping = getErrorMapping();\n * console.log(mapping);\n */\nexport const getErrorMapping = (): Record<string, string> =>\n currentErrorMapping;\n\n/**\n * Parses an error object and returns a user-friendly error message.\n *\n * The function checks if the error is a ContractFunctionRevertedError by attempting to walk through\n * the error using its `walk` method. If a matching error is found and its error key exists in the\n * current error mapping, the corresponding custom message will be returned. Otherwise, it falls back\n * to the error's own message properties.\n *\n * @param error - The error object, potentially including additional error details.\n * @returns A user-friendly error message.\n *\n * @example\n * const message = getParsedError(someError);\n * console.log(message); // Outputs a custom error message or a default error message.\n */\nexport const getParsedError = (error: any | BaseError): string => {\n const defaultMessage = \"An unknown error occurred. Please contact support.\";\n let message = defaultMessage;\n let errorKey = \"\";\n\n const revertedError = error?.walk\n ? error.walk((err: unknown) => err instanceof ContractFunctionRevertedError)\n : null;\n if (revertedError instanceof ContractFunctionRevertedError) {\n errorKey =\n revertedError.data?.errorName ??\n revertedError.signature ??\n revertedError.reason ??\n \"\";\n if (currentErrorMapping[errorKey]) return currentErrorMapping[errorKey];\n }\n\n message = error.shortMessage || error.details || error.message || message;\n return message;\n};\n","import { waitForTransactionReceipt } from \"wagmi/actions\";\nimport { useInvalidateQueries } from \"./useInvalidateQueries\";\nimport { useConfig } from \"wagmi\";\nimport { QueryKey } from \"@tanstack/query-core\";\nimport { Address } from \"viem\";\nimport { useState } from \"react\";\nimport { getParsedError } from \"../utils/errorParser\";\n\nexport type WriteExtendedAsyncParams = {\n onSuccess?: (txHash: Address) => void;\n onError?: (e: any) => void;\n onSettled?: () => void;\n queriesToInvalidate?: (QueryKey | undefined)[];\n disableLogging?: boolean;\n disableWaitingForReceipt?: boolean;\n};\n\n/**\n * Custom hook to handle transaction mutations.\n *\n * @returns {Function} A shared `onSettled` callback for transaction mutations.\n */\nexport function useHandleTransactionMutation({\n settings,\n}: {\n settings?: WriteExtendedAsyncParams;\n}) {\n const wagmiConfig = useConfig();\n\n const { invalidateMany } = useInvalidateQueries();\n const [isPending, setIsPending] = useState(false);\n const [errorMessage, setErrorMessage] = useState<string | undefined>(\n undefined\n );\n\n const onMutate = () => {\n setIsPending(true);\n setErrorMessage(undefined);\n };\n\n const onSettled = async (\n txHash: Address | undefined,\n error: any,\n args: any\n ) => {\n try {\n if (error) throw error;\n\n if (!settings?.disableWaitingForReceipt) {\n // 1. wait for transaction receipt\n const txReceipt = await waitForTransactionReceipt(wagmiConfig, {\n hash: txHash!,\n });\n\n // 2. throw if receipt is not valid\n if (txReceipt.status === \"reverted\")\n throw new Error(\"Execution reverted.\");\n if (txReceipt.status !== \"success\")\n throw new Error(\"Execution reverted.\");\n }\n\n // 3. invalidate queries\n if (settings?.queriesToInvalidate)\n await invalidateMany(settings?.queriesToInvalidate);\n\n // 4. call onSuccess callback\n settings?.onSuccess?.(txHash!);\n\n if (!settings?.disableLogging) {\n // 5. log result\n // eslint-disable-next-line no-console\n console.info(\"Operation successful:\", txHash); // todo: add logging service\n }\n // 6. return result\n return txHash;\n } catch (error) {\n const parsedError = getParsedError(error);\n\n if (!settings?.disableLogging) {\n // 1. log error\n console.error(\n `ContractWriteExtended Operation failed with error(parsed): ${parsedError}`,\n { error },\n { args }\n );\n console.error({ error });\n }\n // 2. set error message\n setErrorMessage(parsedError);\n\n // 3. call callback\n settings?.onError?.(error);\n } finally {\n setIsPending(false);\n // 1. call callback\n settings?.onSettled?.();\n }\n return undefined;\n };\n\n return {\n onMutate,\n onSettled,\n isPending,\n errorMessage,\n };\n}\n","import { useWriteContract } from \"wagmi\";\nimport {\n WriteExtendedAsyncParams,\n useHandleTransactionMutation,\n} from \"./useHandleTransactionMutation\";\n\n/**\n * Custom hook for writing to a smart contract using Wagmi.\n *\n * This hook provides functionality for sending a transaction using Wagmi, handling the asynchronous nature of the operation, waiting for the transaction receipt, and error handling.\n *\n * @param {WriteExtendedAsyncParams} [settings] - Optional settings for the write operation.\n * @param {boolean} [settings.disableWaitingForReceipt] - Disables waiting for the transaction receipt.\n * @param {boolean} [settings.disableLogging] - Disables logging the result of the transaction.\n * @param {Function} [settings.onSuccess] - Callback function to be called on successful transaction.\n * @param {Function} [settings.onError] - Callback function to be called on transaction error.\n * @param {Function} [settings.onSettled] - Callback function to be called after the transaction settles (whether success or failure).\n * @param {QueryKey[]} [settings.queriesToInvalidate] - Array of query keys to invalidate after the transaction receives a receipt.\n * @returns {Object} Object containing the following properties:\n * - {boolean} isPending - Indicates whether the transaction is pending.\n * - {string|undefined} errorMessage - The error message, if an error occurred during the transaction.\n * - {Function} writeContractAsync - Function to trigger the write operation.\n */\n\nexport function useContractWriteExtended(settings?: WriteExtendedAsyncParams) {\n const { isPending, errorMessage, onMutate, onSettled } =\n useHandleTransactionMutation({\n settings,\n });\n\n const { writeContractAsync, ...rest } = useWriteContract({\n mutation: {\n onMutate,\n onSettled,\n },\n });\n\n return {\n ...rest,\n isPending,\n errorMessage,\n writeContractAsync,\n };\n}\n","import { Hash } from \"viem\";\nimport { useSendTransaction } from \"wagmi\";\nimport { QueryKey } from \"@tanstack/query-core\";\nimport { useHandleTransactionMutation } from \"./useHandleTransactionMutation\";\n\nexport type SeamlessSendAsyncParams = {\n onSuccess?: (txHash: Hash) => void;\n onError?: (e: any) => void;\n onSettled?: () => void;\n queriesToInvalidate?: (QueryKey | undefined)[];\n};\n\n/**\n * Custom hook for sending a transaction using Wagmi.\n *\n * This hook provides functionality for sending a transaction using Wagmi, handling the asynchronous nature of the operation, waiting for the transaction receipt, and error handling.\n *\n * @param {SeamlessWriteAsyncParams} [settings] - Optional settings for the write operation.\n * @param {boolean} [settings.disableWaitingForReceipt] - Disables waiting for the transaction receipt.\n * @param {boolean} [settings.disableLogging] - Disables logging the result of the transaction.\n * @param {Function} [settings.onSuccess] - Callback function to be called on successful transaction.\n * @param {Function} [settings.onError] - Callback function to be called on transaction error.\n * @param {Function} [settings.onSettled] - Callback function to be called after the transaction settles (whether success or failure).\n * @param {QueryKey[]} [settings.queriesToInvalidate] - Array of query keys to invalidate after the transaction receives a receipt.\n * @returns {Object} Object containing the following properties:\n * - {boolean} isPending - Indicates whether the transaction is pending.\n * - {string|undefined} errorMessage - The error message, if an error occurred during the transaction.\n * - {Function} sendTransactionAsync - Function to trigger the send transaction mutation.\n */\n\nexport function useSendTransactionExtended(settings?: SeamlessSendAsyncParams) {\n const { isPending, errorMessage, onMutate, onSettled } =\n useHandleTransactionMutation({\n settings,\n });\n\n const { sendTransactionAsync, ...rest } = useSendTransaction({\n mutation: {\n onMutate,\n onSettled,\n },\n });\n\n return {\n ...rest,\n isPending,\n errorMessage,\n sendTransactionAsync,\n };\n}\n"],"names":["useQueryClient","ContractFunctionRevertedError","useConfig","useState","waitForTransactionReceipt","useWriteContract","useSendTransaction"],"mappings":"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"}
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import { useConfig, useWriteContract, useSendTransaction } from 'wagmi';
|
|
2
|
+
import { waitForTransactionReceipt } from 'wagmi/actions';
|
|
3
|
+
import { useQueryClient } from '@tanstack/react-query';
|
|
4
|
+
import { useState } from 'react';
|
|
5
|
+
import { ContractFunctionRevertedError } from 'viem';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Hook to invalidate multiple queries in the React Query cache.
|
|
9
|
+
*
|
|
10
|
+
* @returns An object with the invalidateMany function.
|
|
11
|
+
*/
|
|
12
|
+
function useInvalidateQueries() {
|
|
13
|
+
const queryClient = useQueryClient();
|
|
14
|
+
const invalidateMany = async (queries) => {
|
|
15
|
+
const promises = queries.map((queryKey) => queryClient.invalidateQueries({ queryKey }));
|
|
16
|
+
await Promise.all(promises);
|
|
17
|
+
};
|
|
18
|
+
return { invalidateMany };
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Default error mapping that contains a set of error identifiers mapped to user-friendly error messages.
|
|
23
|
+
*/
|
|
24
|
+
const defaultErrorMapping = {
|
|
25
|
+
EnforcedPause: "Temporary pause in effect, please check Discord for updates.",
|
|
26
|
+
ErrorNotEnoughAllowance: "Not enough allowance, did you approve your tokens first?",
|
|
27
|
+
"0xc2139725": "Not enough allowance, did you approve your tokens first?",
|
|
28
|
+
SharesReceivedBelowMinimum: "Action exceeded safe slippage parameters, please try again later",
|
|
29
|
+
"0xea8d7f02": "Action exceeded safe slippage parameters, please try again later",
|
|
30
|
+
MaxSlippageExceeded: "Action exceeded safe slippage parameters, please try again later",
|
|
31
|
+
"51": "Supply cap exceeded",
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* A mutable copy of the default error mapping that can be extended or overridden by users.
|
|
35
|
+
*/
|
|
36
|
+
let currentErrorMapping = { ...defaultErrorMapping };
|
|
37
|
+
/**
|
|
38
|
+
* Merges a custom error mapping into the current error mapping.
|
|
39
|
+
* Custom values override any existing keys.
|
|
40
|
+
*
|
|
41
|
+
* @param customMapping - An object containing error keys and the corresponding custom messages.
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* setErrorMapping({
|
|
45
|
+
* ErrorNotEnoughAllowance: "Custom message: Please approve tokens first!",
|
|
46
|
+
* NewCustomError: "A custom error occurred."
|
|
47
|
+
* });
|
|
48
|
+
*/
|
|
49
|
+
const setErrorMapping = (customMapping) => {
|
|
50
|
+
currentErrorMapping = { ...currentErrorMapping, ...customMapping };
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Resets the current error mapping to the default error mapping.
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* resetErrorMapping();
|
|
57
|
+
*/
|
|
58
|
+
const resetErrorMapping = () => {
|
|
59
|
+
currentErrorMapping = { ...defaultErrorMapping };
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Retrieves the current error mapping.
|
|
63
|
+
*
|
|
64
|
+
* @returns The current error mapping object.
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* const mapping = getErrorMapping();
|
|
68
|
+
* console.log(mapping);
|
|
69
|
+
*/
|
|
70
|
+
const getErrorMapping = () => currentErrorMapping;
|
|
71
|
+
/**
|
|
72
|
+
* Parses an error object and returns a user-friendly error message.
|
|
73
|
+
*
|
|
74
|
+
* The function checks if the error is a ContractFunctionRevertedError by attempting to walk through
|
|
75
|
+
* the error using its `walk` method. If a matching error is found and its error key exists in the
|
|
76
|
+
* current error mapping, the corresponding custom message will be returned. Otherwise, it falls back
|
|
77
|
+
* to the error's own message properties.
|
|
78
|
+
*
|
|
79
|
+
* @param error - The error object, potentially including additional error details.
|
|
80
|
+
* @returns A user-friendly error message.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* const message = getParsedError(someError);
|
|
84
|
+
* console.log(message); // Outputs a custom error message or a default error message.
|
|
85
|
+
*/
|
|
86
|
+
const getParsedError = (error) => {
|
|
87
|
+
var _a, _b, _c, _d;
|
|
88
|
+
const defaultMessage = "An unknown error occurred. Please contact support.";
|
|
89
|
+
let message = defaultMessage;
|
|
90
|
+
let errorKey = "";
|
|
91
|
+
const revertedError = (error === null || error === void 0 ? void 0 : error.walk)
|
|
92
|
+
? error.walk((err) => err instanceof ContractFunctionRevertedError)
|
|
93
|
+
: null;
|
|
94
|
+
if (revertedError instanceof ContractFunctionRevertedError) {
|
|
95
|
+
errorKey =
|
|
96
|
+
(_d = (_c = (_b = (_a = revertedError.data) === null || _a === void 0 ? void 0 : _a.errorName) !== null && _b !== void 0 ? _b : revertedError.signature) !== null && _c !== void 0 ? _c : revertedError.reason) !== null && _d !== void 0 ? _d : "";
|
|
97
|
+
if (currentErrorMapping[errorKey])
|
|
98
|
+
return currentErrorMapping[errorKey];
|
|
99
|
+
}
|
|
100
|
+
message = error.shortMessage || error.details || error.message || message;
|
|
101
|
+
return message;
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Custom hook to handle transaction mutations.
|
|
106
|
+
*
|
|
107
|
+
* @returns {Function} A shared `onSettled` callback for transaction mutations.
|
|
108
|
+
*/
|
|
109
|
+
function useHandleTransactionMutation({ settings, }) {
|
|
110
|
+
const wagmiConfig = useConfig();
|
|
111
|
+
const { invalidateMany } = useInvalidateQueries();
|
|
112
|
+
const [isPending, setIsPending] = useState(false);
|
|
113
|
+
const [errorMessage, setErrorMessage] = useState(undefined);
|
|
114
|
+
const onMutate = () => {
|
|
115
|
+
setIsPending(true);
|
|
116
|
+
setErrorMessage(undefined);
|
|
117
|
+
};
|
|
118
|
+
const onSettled = async (txHash, error, args) => {
|
|
119
|
+
var _a, _b, _c;
|
|
120
|
+
try {
|
|
121
|
+
if (error)
|
|
122
|
+
throw error;
|
|
123
|
+
if (!(settings === null || settings === void 0 ? void 0 : settings.disableWaitingForReceipt)) {
|
|
124
|
+
// 1. wait for transaction receipt
|
|
125
|
+
const txReceipt = await waitForTransactionReceipt(wagmiConfig, {
|
|
126
|
+
hash: txHash,
|
|
127
|
+
});
|
|
128
|
+
// 2. throw if receipt is not valid
|
|
129
|
+
if (txReceipt.status === "reverted")
|
|
130
|
+
throw new Error("Execution reverted.");
|
|
131
|
+
if (txReceipt.status !== "success")
|
|
132
|
+
throw new Error("Execution reverted.");
|
|
133
|
+
}
|
|
134
|
+
// 3. invalidate queries
|
|
135
|
+
if (settings === null || settings === void 0 ? void 0 : settings.queriesToInvalidate)
|
|
136
|
+
await invalidateMany(settings === null || settings === void 0 ? void 0 : settings.queriesToInvalidate);
|
|
137
|
+
// 4. call onSuccess callback
|
|
138
|
+
(_a = settings === null || settings === void 0 ? void 0 : settings.onSuccess) === null || _a === void 0 ? void 0 : _a.call(settings, txHash);
|
|
139
|
+
if (!(settings === null || settings === void 0 ? void 0 : settings.disableLogging)) {
|
|
140
|
+
// 5. log result
|
|
141
|
+
// eslint-disable-next-line no-console
|
|
142
|
+
console.info("Operation successful:", txHash); // todo: add logging service
|
|
143
|
+
}
|
|
144
|
+
// 6. return result
|
|
145
|
+
return txHash;
|
|
146
|
+
}
|
|
147
|
+
catch (error) {
|
|
148
|
+
const parsedError = getParsedError(error);
|
|
149
|
+
if (!(settings === null || settings === void 0 ? void 0 : settings.disableLogging)) {
|
|
150
|
+
// 1. log error
|
|
151
|
+
console.error(`ContractWriteExtended Operation failed with error(parsed): ${parsedError}`, { error }, { args });
|
|
152
|
+
console.error({ error });
|
|
153
|
+
}
|
|
154
|
+
// 2. set error message
|
|
155
|
+
setErrorMessage(parsedError);
|
|
156
|
+
// 3. call callback
|
|
157
|
+
(_b = settings === null || settings === void 0 ? void 0 : settings.onError) === null || _b === void 0 ? void 0 : _b.call(settings, error);
|
|
158
|
+
}
|
|
159
|
+
finally {
|
|
160
|
+
setIsPending(false);
|
|
161
|
+
// 1. call callback
|
|
162
|
+
(_c = settings === null || settings === void 0 ? void 0 : settings.onSettled) === null || _c === void 0 ? void 0 : _c.call(settings);
|
|
163
|
+
}
|
|
164
|
+
return undefined;
|
|
165
|
+
};
|
|
166
|
+
return {
|
|
167
|
+
onMutate,
|
|
168
|
+
onSettled,
|
|
169
|
+
isPending,
|
|
170
|
+
errorMessage,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Custom hook for writing to a smart contract using Wagmi.
|
|
176
|
+
*
|
|
177
|
+
* This hook provides functionality for sending a transaction using Wagmi, handling the asynchronous nature of the operation, waiting for the transaction receipt, and error handling.
|
|
178
|
+
*
|
|
179
|
+
* @param {WriteExtendedAsyncParams} [settings] - Optional settings for the write operation.
|
|
180
|
+
* @param {boolean} [settings.disableWaitingForReceipt] - Disables waiting for the transaction receipt.
|
|
181
|
+
* @param {boolean} [settings.disableLogging] - Disables logging the result of the transaction.
|
|
182
|
+
* @param {Function} [settings.onSuccess] - Callback function to be called on successful transaction.
|
|
183
|
+
* @param {Function} [settings.onError] - Callback function to be called on transaction error.
|
|
184
|
+
* @param {Function} [settings.onSettled] - Callback function to be called after the transaction settles (whether success or failure).
|
|
185
|
+
* @param {QueryKey[]} [settings.queriesToInvalidate] - Array of query keys to invalidate after the transaction receives a receipt.
|
|
186
|
+
* @returns {Object} Object containing the following properties:
|
|
187
|
+
* - {boolean} isPending - Indicates whether the transaction is pending.
|
|
188
|
+
* - {string|undefined} errorMessage - The error message, if an error occurred during the transaction.
|
|
189
|
+
* - {Function} writeContractAsync - Function to trigger the write operation.
|
|
190
|
+
*/
|
|
191
|
+
function useContractWriteExtended(settings) {
|
|
192
|
+
const { isPending, errorMessage, onMutate, onSettled } = useHandleTransactionMutation({
|
|
193
|
+
settings,
|
|
194
|
+
});
|
|
195
|
+
const { writeContractAsync, ...rest } = useWriteContract({
|
|
196
|
+
mutation: {
|
|
197
|
+
onMutate,
|
|
198
|
+
onSettled,
|
|
199
|
+
},
|
|
200
|
+
});
|
|
201
|
+
return {
|
|
202
|
+
...rest,
|
|
203
|
+
isPending,
|
|
204
|
+
errorMessage,
|
|
205
|
+
writeContractAsync,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Custom hook for sending a transaction using Wagmi.
|
|
211
|
+
*
|
|
212
|
+
* This hook provides functionality for sending a transaction using Wagmi, handling the asynchronous nature of the operation, waiting for the transaction receipt, and error handling.
|
|
213
|
+
*
|
|
214
|
+
* @param {SeamlessWriteAsyncParams} [settings] - Optional settings for the write operation.
|
|
215
|
+
* @param {boolean} [settings.disableWaitingForReceipt] - Disables waiting for the transaction receipt.
|
|
216
|
+
* @param {boolean} [settings.disableLogging] - Disables logging the result of the transaction.
|
|
217
|
+
* @param {Function} [settings.onSuccess] - Callback function to be called on successful transaction.
|
|
218
|
+
* @param {Function} [settings.onError] - Callback function to be called on transaction error.
|
|
219
|
+
* @param {Function} [settings.onSettled] - Callback function to be called after the transaction settles (whether success or failure).
|
|
220
|
+
* @param {QueryKey[]} [settings.queriesToInvalidate] - Array of query keys to invalidate after the transaction receives a receipt.
|
|
221
|
+
* @returns {Object} Object containing the following properties:
|
|
222
|
+
* - {boolean} isPending - Indicates whether the transaction is pending.
|
|
223
|
+
* - {string|undefined} errorMessage - The error message, if an error occurred during the transaction.
|
|
224
|
+
* - {Function} sendTransactionAsync - Function to trigger the send transaction mutation.
|
|
225
|
+
*/
|
|
226
|
+
function useSendTransactionExtended(settings) {
|
|
227
|
+
const { isPending, errorMessage, onMutate, onSettled } = useHandleTransactionMutation({
|
|
228
|
+
settings,
|
|
229
|
+
});
|
|
230
|
+
const { sendTransactionAsync, ...rest } = useSendTransaction({
|
|
231
|
+
mutation: {
|
|
232
|
+
onMutate,
|
|
233
|
+
onSettled,
|
|
234
|
+
},
|
|
235
|
+
});
|
|
236
|
+
return {
|
|
237
|
+
...rest,
|
|
238
|
+
isPending,
|
|
239
|
+
errorMessage,
|
|
240
|
+
sendTransactionAsync,
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
export { getErrorMapping, getParsedError, resetErrorMapping, setErrorMapping, useContractWriteExtended, useSendTransactionExtended };
|
|
245
|
+
//# sourceMappingURL=index.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":["../src/hooks/useInvalidateQueries.ts","../src/utils/errorParser.ts","../src/hooks/useHandleTransactionMutation.ts","../src/hooks/useContractWriteExtended.ts","../src/hooks/useSendTransactionExtended.ts"],"sourcesContent":["import { QueryKey, useQueryClient } from \"@tanstack/react-query\";\n\n/**\n * Hook to invalidate multiple queries in the React Query cache.\n *\n * @returns An object with the invalidateMany function.\n */\nexport function useInvalidateQueries() {\n const queryClient = useQueryClient();\n\n const invalidateMany = async (queries: (QueryKey | undefined)[]) => {\n const promises = queries.map((queryKey) =>\n queryClient.invalidateQueries({ queryKey })\n );\n await Promise.all(promises);\n };\n\n return { invalidateMany };\n}\n","import { BaseError, ContractFunctionRevertedError } from \"viem\";\n\n/**\n * Default error mapping that contains a set of error identifiers mapped to user-friendly error messages.\n */\nconst defaultErrorMapping: Record<string, string> = {\n EnforcedPause: \"Temporary pause in effect, please check Discord for updates.\",\n ErrorNotEnoughAllowance:\n \"Not enough allowance, did you approve your tokens first?\",\n \"0xc2139725\": \"Not enough allowance, did you approve your tokens first?\",\n SharesReceivedBelowMinimum:\n \"Action exceeded safe slippage parameters, please try again later\",\n \"0xea8d7f02\":\n \"Action exceeded safe slippage parameters, please try again later\",\n MaxSlippageExceeded:\n \"Action exceeded safe slippage parameters, please try again later\",\n \"51\": \"Supply cap exceeded\",\n};\n\n/**\n * A mutable copy of the default error mapping that can be extended or overridden by users.\n */\nlet currentErrorMapping: Record<string, string> = { ...defaultErrorMapping };\n\n/**\n * Merges a custom error mapping into the current error mapping.\n * Custom values override any existing keys.\n *\n * @param customMapping - An object containing error keys and the corresponding custom messages.\n *\n * @example\n * setErrorMapping({\n * ErrorNotEnoughAllowance: \"Custom message: Please approve tokens first!\",\n * NewCustomError: \"A custom error occurred.\"\n * });\n */\nexport const setErrorMapping = (\n customMapping: Record<string, string>\n): void => {\n currentErrorMapping = { ...currentErrorMapping, ...customMapping };\n};\n\n/**\n * Resets the current error mapping to the default error mapping.\n *\n * @example\n * resetErrorMapping();\n */\nexport const resetErrorMapping = (): void => {\n currentErrorMapping = { ...defaultErrorMapping };\n};\n\n/**\n * Retrieves the current error mapping.\n *\n * @returns The current error mapping object.\n *\n * @example\n * const mapping = getErrorMapping();\n * console.log(mapping);\n */\nexport const getErrorMapping = (): Record<string, string> =>\n currentErrorMapping;\n\n/**\n * Parses an error object and returns a user-friendly error message.\n *\n * The function checks if the error is a ContractFunctionRevertedError by attempting to walk through\n * the error using its `walk` method. If a matching error is found and its error key exists in the\n * current error mapping, the corresponding custom message will be returned. Otherwise, it falls back\n * to the error's own message properties.\n *\n * @param error - The error object, potentially including additional error details.\n * @returns A user-friendly error message.\n *\n * @example\n * const message = getParsedError(someError);\n * console.log(message); // Outputs a custom error message or a default error message.\n */\nexport const getParsedError = (error: any | BaseError): string => {\n const defaultMessage = \"An unknown error occurred. Please contact support.\";\n let message = defaultMessage;\n let errorKey = \"\";\n\n const revertedError = error?.walk\n ? error.walk((err: unknown) => err instanceof ContractFunctionRevertedError)\n : null;\n if (revertedError instanceof ContractFunctionRevertedError) {\n errorKey =\n revertedError.data?.errorName ??\n revertedError.signature ??\n revertedError.reason ??\n \"\";\n if (currentErrorMapping[errorKey]) return currentErrorMapping[errorKey];\n }\n\n message = error.shortMessage || error.details || error.message || message;\n return message;\n};\n","import { waitForTransactionReceipt } from \"wagmi/actions\";\nimport { useInvalidateQueries } from \"./useInvalidateQueries\";\nimport { useConfig } from \"wagmi\";\nimport { QueryKey } from \"@tanstack/query-core\";\nimport { Address } from \"viem\";\nimport { useState } from \"react\";\nimport { getParsedError } from \"../utils/errorParser\";\n\nexport type WriteExtendedAsyncParams = {\n onSuccess?: (txHash: Address) => void;\n onError?: (e: any) => void;\n onSettled?: () => void;\n queriesToInvalidate?: (QueryKey | undefined)[];\n disableLogging?: boolean;\n disableWaitingForReceipt?: boolean;\n};\n\n/**\n * Custom hook to handle transaction mutations.\n *\n * @returns {Function} A shared `onSettled` callback for transaction mutations.\n */\nexport function useHandleTransactionMutation({\n settings,\n}: {\n settings?: WriteExtendedAsyncParams;\n}) {\n const wagmiConfig = useConfig();\n\n const { invalidateMany } = useInvalidateQueries();\n const [isPending, setIsPending] = useState(false);\n const [errorMessage, setErrorMessage] = useState<string | undefined>(\n undefined\n );\n\n const onMutate = () => {\n setIsPending(true);\n setErrorMessage(undefined);\n };\n\n const onSettled = async (\n txHash: Address | undefined,\n error: any,\n args: any\n ) => {\n try {\n if (error) throw error;\n\n if (!settings?.disableWaitingForReceipt) {\n // 1. wait for transaction receipt\n const txReceipt = await waitForTransactionReceipt(wagmiConfig, {\n hash: txHash!,\n });\n\n // 2. throw if receipt is not valid\n if (txReceipt.status === \"reverted\")\n throw new Error(\"Execution reverted.\");\n if (txReceipt.status !== \"success\")\n throw new Error(\"Execution reverted.\");\n }\n\n // 3. invalidate queries\n if (settings?.queriesToInvalidate)\n await invalidateMany(settings?.queriesToInvalidate);\n\n // 4. call onSuccess callback\n settings?.onSuccess?.(txHash!);\n\n if (!settings?.disableLogging) {\n // 5. log result\n // eslint-disable-next-line no-console\n console.info(\"Operation successful:\", txHash); // todo: add logging service\n }\n // 6. return result\n return txHash;\n } catch (error) {\n const parsedError = getParsedError(error);\n\n if (!settings?.disableLogging) {\n // 1. log error\n console.error(\n `ContractWriteExtended Operation failed with error(parsed): ${parsedError}`,\n { error },\n { args }\n );\n console.error({ error });\n }\n // 2. set error message\n setErrorMessage(parsedError);\n\n // 3. call callback\n settings?.onError?.(error);\n } finally {\n setIsPending(false);\n // 1. call callback\n settings?.onSettled?.();\n }\n return undefined;\n };\n\n return {\n onMutate,\n onSettled,\n isPending,\n errorMessage,\n };\n}\n","import { useWriteContract } from \"wagmi\";\nimport {\n WriteExtendedAsyncParams,\n useHandleTransactionMutation,\n} from \"./useHandleTransactionMutation\";\n\n/**\n * Custom hook for writing to a smart contract using Wagmi.\n *\n * This hook provides functionality for sending a transaction using Wagmi, handling the asynchronous nature of the operation, waiting for the transaction receipt, and error handling.\n *\n * @param {WriteExtendedAsyncParams} [settings] - Optional settings for the write operation.\n * @param {boolean} [settings.disableWaitingForReceipt] - Disables waiting for the transaction receipt.\n * @param {boolean} [settings.disableLogging] - Disables logging the result of the transaction.\n * @param {Function} [settings.onSuccess] - Callback function to be called on successful transaction.\n * @param {Function} [settings.onError] - Callback function to be called on transaction error.\n * @param {Function} [settings.onSettled] - Callback function to be called after the transaction settles (whether success or failure).\n * @param {QueryKey[]} [settings.queriesToInvalidate] - Array of query keys to invalidate after the transaction receives a receipt.\n * @returns {Object} Object containing the following properties:\n * - {boolean} isPending - Indicates whether the transaction is pending.\n * - {string|undefined} errorMessage - The error message, if an error occurred during the transaction.\n * - {Function} writeContractAsync - Function to trigger the write operation.\n */\n\nexport function useContractWriteExtended(settings?: WriteExtendedAsyncParams) {\n const { isPending, errorMessage, onMutate, onSettled } =\n useHandleTransactionMutation({\n settings,\n });\n\n const { writeContractAsync, ...rest } = useWriteContract({\n mutation: {\n onMutate,\n onSettled,\n },\n });\n\n return {\n ...rest,\n isPending,\n errorMessage,\n writeContractAsync,\n };\n}\n","import { Hash } from \"viem\";\nimport { useSendTransaction } from \"wagmi\";\nimport { QueryKey } from \"@tanstack/query-core\";\nimport { useHandleTransactionMutation } from \"./useHandleTransactionMutation\";\n\nexport type SeamlessSendAsyncParams = {\n onSuccess?: (txHash: Hash) => void;\n onError?: (e: any) => void;\n onSettled?: () => void;\n queriesToInvalidate?: (QueryKey | undefined)[];\n};\n\n/**\n * Custom hook for sending a transaction using Wagmi.\n *\n * This hook provides functionality for sending a transaction using Wagmi, handling the asynchronous nature of the operation, waiting for the transaction receipt, and error handling.\n *\n * @param {SeamlessWriteAsyncParams} [settings] - Optional settings for the write operation.\n * @param {boolean} [settings.disableWaitingForReceipt] - Disables waiting for the transaction receipt.\n * @param {boolean} [settings.disableLogging] - Disables logging the result of the transaction.\n * @param {Function} [settings.onSuccess] - Callback function to be called on successful transaction.\n * @param {Function} [settings.onError] - Callback function to be called on transaction error.\n * @param {Function} [settings.onSettled] - Callback function to be called after the transaction settles (whether success or failure).\n * @param {QueryKey[]} [settings.queriesToInvalidate] - Array of query keys to invalidate after the transaction receives a receipt.\n * @returns {Object} Object containing the following properties:\n * - {boolean} isPending - Indicates whether the transaction is pending.\n * - {string|undefined} errorMessage - The error message, if an error occurred during the transaction.\n * - {Function} sendTransactionAsync - Function to trigger the send transaction mutation.\n */\n\nexport function useSendTransactionExtended(settings?: SeamlessSendAsyncParams) {\n const { isPending, errorMessage, onMutate, onSettled } =\n useHandleTransactionMutation({\n settings,\n });\n\n const { sendTransactionAsync, ...rest } = useSendTransaction({\n mutation: {\n onMutate,\n onSettled,\n },\n });\n\n return {\n ...rest,\n isPending,\n errorMessage,\n sendTransactionAsync,\n };\n}\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wagmi-extended",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"type": "module",
|
|
4
5
|
"description": "A library providing extended hooks on top of Wagmi with additional features.",
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
+
"main": "dist/index.cjs.js",
|
|
7
|
+
"module": "dist/index.esm.js",
|
|
6
8
|
"types": "dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dist/index.esm.js",
|
|
12
|
+
"require": "./dist/index.cjs.js",
|
|
13
|
+
"types": "./dist/index.d.ts"
|
|
14
|
+
},
|
|
15
|
+
"./hooks/*": "./dist/hooks/*.js",
|
|
16
|
+
"./utils/*": "./dist/utils/*.js"
|
|
17
|
+
},
|
|
7
18
|
"repository": {
|
|
8
19
|
"type": "git",
|
|
9
20
|
"url": "https://github.com/WingsDevelopment/wagmi-extended.git"
|
|
@@ -15,10 +26,10 @@
|
|
|
15
26
|
"react",
|
|
16
27
|
"blockchain"
|
|
17
28
|
],
|
|
18
|
-
"author": "
|
|
29
|
+
"author": "Srdjan Rakic <bans.cowboy@gmail.com>",
|
|
19
30
|
"license": "MIT",
|
|
20
31
|
"scripts": {
|
|
21
|
-
"build": "
|
|
32
|
+
"build": "rollup -c --bundleConfigAsCjs",
|
|
22
33
|
"prepublishOnly": "npm run build"
|
|
23
34
|
},
|
|
24
35
|
"peerDependencies": {
|
|
@@ -28,8 +39,13 @@
|
|
|
28
39
|
"wagmi": "^2.0.0"
|
|
29
40
|
},
|
|
30
41
|
"devDependencies": {
|
|
42
|
+
"@rollup/plugin-commonjs": "^28.0.3",
|
|
43
|
+
"@rollup/plugin-node-resolve": "^16.0.1",
|
|
44
|
+
"@rollup/plugin-typescript": "^12.1.2",
|
|
31
45
|
"@types/node": "^22.14.0",
|
|
32
46
|
"@types/react": "^19.1.0",
|
|
47
|
+
"rollup": "^4.39.0",
|
|
48
|
+
"rollup-plugin-peer-deps-external": "^2.2.4",
|
|
33
49
|
"typescript": "^5.0.0"
|
|
34
50
|
}
|
|
35
51
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// rollup.config.mjs
|
|
2
|
+
import typescript from "@rollup/plugin-typescript";
|
|
3
|
+
import peerDepsExternal from "rollup-plugin-peer-deps-external";
|
|
4
|
+
import resolve from "@rollup/plugin-node-resolve";
|
|
5
|
+
import commonjs from "@rollup/plugin-commonjs";
|
|
6
|
+
|
|
7
|
+
export default {
|
|
8
|
+
input: "src/index.ts",
|
|
9
|
+
output: [
|
|
10
|
+
{
|
|
11
|
+
file: "dist/index.cjs.js",
|
|
12
|
+
format: "cjs",
|
|
13
|
+
sourcemap: true,
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
file: "dist/index.esm.js",
|
|
17
|
+
format: "esm",
|
|
18
|
+
sourcemap: true,
|
|
19
|
+
},
|
|
20
|
+
],
|
|
21
|
+
plugins: [
|
|
22
|
+
peerDepsExternal(),
|
|
23
|
+
resolve(),
|
|
24
|
+
commonjs(),
|
|
25
|
+
typescript({ tsconfig: "./tsconfig.json" }),
|
|
26
|
+
],
|
|
27
|
+
external: ["react", "@tanstack/react-query", "wagmi", "viem"],
|
|
28
|
+
};
|
package/tsconfig.json
CHANGED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.useContractWriteExtended = useContractWriteExtended;
|
|
4
|
-
const wagmi_1 = require("wagmi");
|
|
5
|
-
const useHandleTransactionMutation_1 = require("./useHandleTransactionMutation");
|
|
6
|
-
/**
|
|
7
|
-
* Custom hook for writing to a smart contract using Wagmi.
|
|
8
|
-
*
|
|
9
|
-
* This hook provides functionality for sending a transaction using Wagmi, handling the asynchronous nature of the operation, waiting for the transaction receipt, and error handling.
|
|
10
|
-
*
|
|
11
|
-
* @param {WriteExtendedAsyncParams} [settings] - Optional settings for the write operation.
|
|
12
|
-
* @param {boolean} [settings.disableWaitingForReceipt] - Disables waiting for the transaction receipt.
|
|
13
|
-
* @param {boolean} [settings.disableLogging] - Disables logging the result of the transaction.
|
|
14
|
-
* @param {Function} [settings.onSuccess] - Callback function to be called on successful transaction.
|
|
15
|
-
* @param {Function} [settings.onError] - Callback function to be called on transaction error.
|
|
16
|
-
* @param {Function} [settings.onSettled] - Callback function to be called after the transaction settles (whether success or failure).
|
|
17
|
-
* @param {QueryKey[]} [settings.queriesToInvalidate] - Array of query keys to invalidate after the transaction receives a receipt.
|
|
18
|
-
* @returns {Object} Object containing the following properties:
|
|
19
|
-
* - {boolean} isPending - Indicates whether the transaction is pending.
|
|
20
|
-
* - {string|undefined} errorMessage - The error message, if an error occurred during the transaction.
|
|
21
|
-
* - {Function} writeContractAsync - Function to trigger the write operation.
|
|
22
|
-
*/
|
|
23
|
-
function useContractWriteExtended(settings) {
|
|
24
|
-
const { isPending, errorMessage, onMutate, onSettled } = (0, useHandleTransactionMutation_1.useHandleTransactionMutation)({
|
|
25
|
-
settings,
|
|
26
|
-
});
|
|
27
|
-
const { writeContractAsync, ...rest } = (0, wagmi_1.useWriteContract)({
|
|
28
|
-
mutation: {
|
|
29
|
-
onMutate,
|
|
30
|
-
onSettled,
|
|
31
|
-
},
|
|
32
|
-
});
|
|
33
|
-
return {
|
|
34
|
-
...rest,
|
|
35
|
-
isPending,
|
|
36
|
-
errorMessage,
|
|
37
|
-
writeContractAsync,
|
|
38
|
-
};
|
|
39
|
-
}
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.useHandleTransactionMutation = useHandleTransactionMutation;
|
|
4
|
-
const actions_1 = require("wagmi/actions");
|
|
5
|
-
const useInvalidateQueries_1 = require("./useInvalidateQueries");
|
|
6
|
-
const wagmi_1 = require("wagmi");
|
|
7
|
-
const react_1 = require("react");
|
|
8
|
-
const errorParser_1 = require("../utils/errorParser");
|
|
9
|
-
/**
|
|
10
|
-
* Custom hook to handle transaction mutations.
|
|
11
|
-
*
|
|
12
|
-
* @returns {Function} A shared `onSettled` callback for transaction mutations.
|
|
13
|
-
*/
|
|
14
|
-
function useHandleTransactionMutation({ settings, }) {
|
|
15
|
-
const wagmiConfig = (0, wagmi_1.useConfig)();
|
|
16
|
-
const { invalidateMany } = (0, useInvalidateQueries_1.useInvalidateQueries)();
|
|
17
|
-
const [isPending, setIsPending] = (0, react_1.useState)(false);
|
|
18
|
-
const [errorMessage, setErrorMessage] = (0, react_1.useState)(undefined);
|
|
19
|
-
const onMutate = () => {
|
|
20
|
-
setIsPending(true);
|
|
21
|
-
setErrorMessage(undefined);
|
|
22
|
-
};
|
|
23
|
-
const onSettled = async (txHash, error, args) => {
|
|
24
|
-
var _a, _b, _c;
|
|
25
|
-
try {
|
|
26
|
-
if (error)
|
|
27
|
-
throw error;
|
|
28
|
-
if (!(settings === null || settings === void 0 ? void 0 : settings.disableWaitingForReceipt)) {
|
|
29
|
-
// 1. wait for transaction receipt
|
|
30
|
-
const txReceipt = await (0, actions_1.waitForTransactionReceipt)(wagmiConfig, {
|
|
31
|
-
hash: txHash,
|
|
32
|
-
});
|
|
33
|
-
// 2. throw if receipt is not valid
|
|
34
|
-
if (txReceipt.status === "reverted")
|
|
35
|
-
throw new Error("Execution reverted.");
|
|
36
|
-
if (txReceipt.status !== "success")
|
|
37
|
-
throw new Error("Execution reverted.");
|
|
38
|
-
}
|
|
39
|
-
// 3. invalidate queries
|
|
40
|
-
if (settings === null || settings === void 0 ? void 0 : settings.queriesToInvalidate)
|
|
41
|
-
await invalidateMany(settings === null || settings === void 0 ? void 0 : settings.queriesToInvalidate);
|
|
42
|
-
// 4. call onSuccess callback
|
|
43
|
-
(_a = settings === null || settings === void 0 ? void 0 : settings.onSuccess) === null || _a === void 0 ? void 0 : _a.call(settings, txHash);
|
|
44
|
-
if (!(settings === null || settings === void 0 ? void 0 : settings.disableLogging)) {
|
|
45
|
-
// 5. log result
|
|
46
|
-
// eslint-disable-next-line no-console
|
|
47
|
-
console.info("Operation successful:", txHash); // todo: add logging service
|
|
48
|
-
}
|
|
49
|
-
// 6. return result
|
|
50
|
-
return txHash;
|
|
51
|
-
}
|
|
52
|
-
catch (error) {
|
|
53
|
-
const parsedError = (0, errorParser_1.getParsedError)(error);
|
|
54
|
-
if (!(settings === null || settings === void 0 ? void 0 : settings.disableLogging)) {
|
|
55
|
-
// 1. log error
|
|
56
|
-
console.error(`ContractWriteExtended Operation failed with error(parsed): ${parsedError}`, { error }, { args });
|
|
57
|
-
console.error({ error });
|
|
58
|
-
}
|
|
59
|
-
// 2. set error message
|
|
60
|
-
setErrorMessage(parsedError);
|
|
61
|
-
// 3. call callback
|
|
62
|
-
(_b = settings === null || settings === void 0 ? void 0 : settings.onError) === null || _b === void 0 ? void 0 : _b.call(settings, error);
|
|
63
|
-
}
|
|
64
|
-
finally {
|
|
65
|
-
setIsPending(false);
|
|
66
|
-
// 1. call callback
|
|
67
|
-
(_c = settings === null || settings === void 0 ? void 0 : settings.onSettled) === null || _c === void 0 ? void 0 : _c.call(settings);
|
|
68
|
-
}
|
|
69
|
-
return undefined;
|
|
70
|
-
};
|
|
71
|
-
return {
|
|
72
|
-
onMutate,
|
|
73
|
-
onSettled,
|
|
74
|
-
isPending,
|
|
75
|
-
errorMessage,
|
|
76
|
-
};
|
|
77
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.useInvalidateQueries = useInvalidateQueries;
|
|
4
|
-
const react_query_1 = require("@tanstack/react-query");
|
|
5
|
-
/**
|
|
6
|
-
* Hook to invalidate multiple queries in the React Query cache.
|
|
7
|
-
*
|
|
8
|
-
* @returns An object with the invalidateMany function.
|
|
9
|
-
*/
|
|
10
|
-
function useInvalidateQueries() {
|
|
11
|
-
const queryClient = (0, react_query_1.useQueryClient)();
|
|
12
|
-
const invalidateMany = async (queries) => {
|
|
13
|
-
const promises = queries.map((queryKey) => queryClient.invalidateQueries({ queryKey }));
|
|
14
|
-
await Promise.all(promises);
|
|
15
|
-
};
|
|
16
|
-
return { invalidateMany };
|
|
17
|
-
}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.useSendTransactionExtended = useSendTransactionExtended;
|
|
4
|
-
const wagmi_1 = require("wagmi");
|
|
5
|
-
const useHandleTransactionMutation_1 = require("./useHandleTransactionMutation");
|
|
6
|
-
/**
|
|
7
|
-
* Custom hook for sending a transaction using Wagmi.
|
|
8
|
-
*
|
|
9
|
-
* This hook provides functionality for sending a transaction using Wagmi, handling the asynchronous nature of the operation, waiting for the transaction receipt, and error handling.
|
|
10
|
-
*
|
|
11
|
-
* @param {SeamlessWriteAsyncParams} [settings] - Optional settings for the write operation.
|
|
12
|
-
* @param {boolean} [settings.disableWaitingForReceipt] - Disables waiting for the transaction receipt.
|
|
13
|
-
* @param {boolean} [settings.disableLogging] - Disables logging the result of the transaction.
|
|
14
|
-
* @param {Function} [settings.onSuccess] - Callback function to be called on successful transaction.
|
|
15
|
-
* @param {Function} [settings.onError] - Callback function to be called on transaction error.
|
|
16
|
-
* @param {Function} [settings.onSettled] - Callback function to be called after the transaction settles (whether success or failure).
|
|
17
|
-
* @param {QueryKey[]} [settings.queriesToInvalidate] - Array of query keys to invalidate after the transaction receives a receipt.
|
|
18
|
-
* @returns {Object} Object containing the following properties:
|
|
19
|
-
* - {boolean} isPending - Indicates whether the transaction is pending.
|
|
20
|
-
* - {string|undefined} errorMessage - The error message, if an error occurred during the transaction.
|
|
21
|
-
* - {Function} sendTransactionAsync - Function to trigger the send transaction mutation.
|
|
22
|
-
*/
|
|
23
|
-
function useSendTransactionExtended(settings) {
|
|
24
|
-
const { isPending, errorMessage, onMutate, onSettled } = (0, useHandleTransactionMutation_1.useHandleTransactionMutation)({
|
|
25
|
-
settings,
|
|
26
|
-
});
|
|
27
|
-
const { sendTransactionAsync, ...rest } = (0, wagmi_1.useSendTransaction)({
|
|
28
|
-
mutation: {
|
|
29
|
-
onMutate,
|
|
30
|
-
onSettled,
|
|
31
|
-
},
|
|
32
|
-
});
|
|
33
|
-
return {
|
|
34
|
-
...rest,
|
|
35
|
-
isPending,
|
|
36
|
-
errorMessage,
|
|
37
|
-
sendTransactionAsync,
|
|
38
|
-
};
|
|
39
|
-
}
|
package/dist/index.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./hooks/useContractWriteExtended"), exports);
|
|
18
|
-
__exportStar(require("./hooks/useSendTransactionExtended"), exports);
|
|
19
|
-
__exportStar(require("./utils/errorParser"), exports);
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getParsedError = exports.getErrorMapping = exports.resetErrorMapping = exports.setErrorMapping = void 0;
|
|
4
|
-
const viem_1 = require("viem");
|
|
5
|
-
/**
|
|
6
|
-
* Default error mapping that contains a set of error identifiers mapped to user-friendly error messages.
|
|
7
|
-
*/
|
|
8
|
-
const defaultErrorMapping = {
|
|
9
|
-
EnforcedPause: "Temporary pause in effect, please check Discord for updates.",
|
|
10
|
-
ErrorNotEnoughAllowance: "Not enough allowance, did you approve your tokens first?",
|
|
11
|
-
"0xc2139725": "Not enough allowance, did you approve your tokens first?",
|
|
12
|
-
SharesReceivedBelowMinimum: "Action exceeded safe slippage parameters, please try again later",
|
|
13
|
-
"0xea8d7f02": "Action exceeded safe slippage parameters, please try again later",
|
|
14
|
-
MaxSlippageExceeded: "Action exceeded safe slippage parameters, please try again later",
|
|
15
|
-
"51": "Supply cap exceeded",
|
|
16
|
-
};
|
|
17
|
-
/**
|
|
18
|
-
* A mutable copy of the default error mapping that can be extended or overridden by users.
|
|
19
|
-
*/
|
|
20
|
-
let currentErrorMapping = { ...defaultErrorMapping };
|
|
21
|
-
/**
|
|
22
|
-
* Merges a custom error mapping into the current error mapping.
|
|
23
|
-
* Custom values override any existing keys.
|
|
24
|
-
*
|
|
25
|
-
* @param customMapping - An object containing error keys and the corresponding custom messages.
|
|
26
|
-
*
|
|
27
|
-
* @example
|
|
28
|
-
* setErrorMapping({
|
|
29
|
-
* ErrorNotEnoughAllowance: "Custom message: Please approve tokens first!",
|
|
30
|
-
* NewCustomError: "A custom error occurred."
|
|
31
|
-
* });
|
|
32
|
-
*/
|
|
33
|
-
const setErrorMapping = (customMapping) => {
|
|
34
|
-
currentErrorMapping = { ...currentErrorMapping, ...customMapping };
|
|
35
|
-
};
|
|
36
|
-
exports.setErrorMapping = setErrorMapping;
|
|
37
|
-
/**
|
|
38
|
-
* Resets the current error mapping to the default error mapping.
|
|
39
|
-
*
|
|
40
|
-
* @example
|
|
41
|
-
* resetErrorMapping();
|
|
42
|
-
*/
|
|
43
|
-
const resetErrorMapping = () => {
|
|
44
|
-
currentErrorMapping = { ...defaultErrorMapping };
|
|
45
|
-
};
|
|
46
|
-
exports.resetErrorMapping = resetErrorMapping;
|
|
47
|
-
/**
|
|
48
|
-
* Retrieves the current error mapping.
|
|
49
|
-
*
|
|
50
|
-
* @returns The current error mapping object.
|
|
51
|
-
*
|
|
52
|
-
* @example
|
|
53
|
-
* const mapping = getErrorMapping();
|
|
54
|
-
* console.log(mapping);
|
|
55
|
-
*/
|
|
56
|
-
const getErrorMapping = () => currentErrorMapping;
|
|
57
|
-
exports.getErrorMapping = getErrorMapping;
|
|
58
|
-
/**
|
|
59
|
-
* Parses an error object and returns a user-friendly error message.
|
|
60
|
-
*
|
|
61
|
-
* The function checks if the error is a ContractFunctionRevertedError by attempting to walk through
|
|
62
|
-
* the error using its `walk` method. If a matching error is found and its error key exists in the
|
|
63
|
-
* current error mapping, the corresponding custom message will be returned. Otherwise, it falls back
|
|
64
|
-
* to the error's own message properties.
|
|
65
|
-
*
|
|
66
|
-
* @param error - The error object, potentially including additional error details.
|
|
67
|
-
* @returns A user-friendly error message.
|
|
68
|
-
*
|
|
69
|
-
* @example
|
|
70
|
-
* const message = getParsedError(someError);
|
|
71
|
-
* console.log(message); // Outputs a custom error message or a default error message.
|
|
72
|
-
*/
|
|
73
|
-
const getParsedError = (error) => {
|
|
74
|
-
var _a, _b, _c, _d;
|
|
75
|
-
const defaultMessage = "An unknown error occurred. Please contact support.";
|
|
76
|
-
let message = defaultMessage;
|
|
77
|
-
let errorKey = "";
|
|
78
|
-
const revertedError = (error === null || error === void 0 ? void 0 : error.walk)
|
|
79
|
-
? error.walk((err) => err instanceof viem_1.ContractFunctionRevertedError)
|
|
80
|
-
: null;
|
|
81
|
-
if (revertedError instanceof viem_1.ContractFunctionRevertedError) {
|
|
82
|
-
errorKey =
|
|
83
|
-
(_d = (_c = (_b = (_a = revertedError.data) === null || _a === void 0 ? void 0 : _a.errorName) !== null && _b !== void 0 ? _b : revertedError.signature) !== null && _c !== void 0 ? _c : revertedError.reason) !== null && _d !== void 0 ? _d : "";
|
|
84
|
-
if (currentErrorMapping[errorKey])
|
|
85
|
-
return currentErrorMapping[errorKey];
|
|
86
|
-
}
|
|
87
|
-
message = error.shortMessage || error.details || error.message || message;
|
|
88
|
-
return message;
|
|
89
|
-
};
|
|
90
|
-
exports.getParsedError = getParsedError;
|