UNPKG

@sky-mavis/tanto-widget

Version:
133 lines 3.84 kB
import {useRef,useCallback,useEffect}from'react';import {useAccount}from'wagmi';import {analytic}from'../analytic.mjs';const SIGNATURE_METHODS = ['personal_sign', 'eth_signTypedData_v4', 'eth_sign', 'eth_signTypedData']; const TRANSACTION_METHODS = ['eth_sendTransaction']; const REQUIRED_SIGNING_METHODS = [...SIGNATURE_METHODS, ...TRANSACTION_METHODS]; function isSignatureMethod(method) { return SIGNATURE_METHODS.includes(method); } function isTransactionMethod(method) { return TRANSACTION_METHODS.includes(method); } function isRequiredSigningMethod(method) { return REQUIRED_SIGNING_METHODS.includes(method); } function createRequestProxy({ request, beforeRequest, afterRequest }) { return new Proxy(request, { async apply(target, thisArg, args) { beforeRequest?.(args[0]); try { const result = await Reflect.apply(target, thisArg, args); afterRequest?.(args[0]); return result; } catch (e) { afterRequest?.(args[0], e); throw e; } } }); } function createSignerProxy({ signer, beforeRequest, afterRequest }) { return new Proxy(signer, { get(target, prop, receiver) { if (prop === 'request') { return createRequestProxy({ request: target.request, beforeRequest, afterRequest }); } return Reflect.get(target, prop, receiver); } }); } function useConnectorRequestInterceptor({ beforeRequest, afterRequest } = {}) { const { connector } = useAccount(); const isListenerActive = useRef(false); const handleBeforeRequest = useCallback(({ method, params }) => { if (!isRequiredSigningMethod(method)) return; beforeRequest?.({ method, params }); if (isSignatureMethod(method)) analytic.sendEvent('sign_message_open', { method, params }); if (isTransactionMethod(method)) analytic.sendEvent('send_transaction_open', { method, params }); }, [beforeRequest]); const handleAfterRequest = useCallback(({ method, params }, error) => { if (!isRequiredSigningMethod(method)) return; afterRequest?.({ method, params }, error); if (isSignatureMethod(method)) { if (error) analytic.sendEvent('sign_message_fail', { method, params, error_reason: error.message });else analytic.sendEvent('sign_message_success', { method, params }); } if (isTransactionMethod(method)) { if (error) analytic.sendEvent('send_transaction_fail', { method, params, error_reason: error.message });else analytic.sendEvent('send_transaction_success', { method, params }); } }, [afterRequest]); useEffect(() => { if (!connector || isListenerActive.current) return; isListenerActive.current = true; async function setupProvider() { try { const provider = await connector.getProvider(); if (provider?.signer && typeof provider.signer.request === 'function') { provider.signer = createSignerProxy({ signer: provider.signer, beforeRequest: handleBeforeRequest, afterRequest: handleAfterRequest }); return; } if (provider?.request && typeof provider.request === 'function') { provider.request = createRequestProxy({ request: provider.request, beforeRequest: handleBeforeRequest, afterRequest: handleAfterRequest }); } } catch (error) { console.debug('Failed to setup provider in useConnectorRequestInterceptor:', error); } } void setupProvider(); }, [connector, handleBeforeRequest, handleAfterRequest]); }export{useConnectorRequestInterceptor};