@sky-mavis/tanto-widget
Version:
Tanto Widget
102 lines • 3.1 kB
JavaScript
import {useRef,useCallback,useEffect}from'react';import {useAccount}from'wagmi';import {analytic}from'../analytic.mjs';const SIGN_METHODS = ['personal_sign', 'eth_signTypedData_v4', 'eth_sendTransaction'];
const createRequestProxy = (request, beforeRequest, afterRequest) => {
return new Proxy(request, {
async apply(target, thisArg, args) {
try {
await beforeRequest(args[0]);
const result = await Reflect.apply(target, thisArg, args);
await afterRequest(args[0]);
return result;
} catch (e) {
await afterRequest(args[0], e);
throw e;
}
}
});
};
const createSignerProxy = (signer, beforeRequest, afterRequest) => {
return new Proxy(signer, {
get(target, prop, receiver) {
if (prop === 'request') {
return createRequestProxy(target.request, beforeRequest, afterRequest);
}
return Reflect.get(target, prop, receiver);
}
});
};
const useConnectorRequestAnalyticInterceptor = () => {
const {
connector
} = useAccount();
const isListenerActive = useRef(false);
const handleBeforeRequest = useCallback(async ({
method,
params
}) => {
if (SIGN_METHODS.includes(method)) {
await analytic.sendEvent('sign_message_open', {
method,
params
});
}
if (method === 'eth_sendTransaction') {
await analytic.sendEvent('send_transaction_open', {
method,
params
});
}
}, []);
const handleAfterRequest = useCallback(async ({
method,
params
}, error) => {
if (SIGN_METHODS.includes(method)) {
if (error) {
await analytic.sendEvent('sign_message_fail', {
method,
params,
error_reason: error.message
});
} else {
await analytic.sendEvent('sign_message_success', {
method,
params
});
}
}
if (method === 'eth_sendTransaction') {
if (error) {
await analytic.sendEvent('send_transaction_fail', {
method,
params,
error_reason: error.message
});
} else {
await analytic.sendEvent('send_transaction_success', {
method,
params
});
}
}
}, []);
useEffect(() => {
if (!connector || isListenerActive.current) return;
isListenerActive.current = true;
const setupProvider = async () => {
try {
const provider = await connector.getProvider();
if (provider.signer && typeof provider.signer.request === 'function') {
provider.signer = createSignerProxy(provider.signer, handleBeforeRequest, handleAfterRequest);
return;
}
if (provider.request && typeof provider.request === 'function') {
provider.request = createRequestProxy(provider.request, handleBeforeRequest, handleAfterRequest);
}
} catch {}
};
void setupProvider();
return () => {
isListenerActive.current = false;
};
}, [connector, handleBeforeRequest, handleAfterRequest]);
};export{useConnectorRequestAnalyticInterceptor};