useCallback for listeners

This commit is contained in:
apoorvlathey
2024-10-30 19:25:32 +04:00
parent 895f6d37b2
commit e6303ffc64
3 changed files with 187 additions and 155 deletions

View File

@@ -24,7 +24,7 @@ function BrowserExtensionTab() {
</chakra.a> </chakra.a>
</Text> </Text>
</Box> </Box>
<HStack mt="2" w="full" fontSize={"lg"}> {/* <HStack mt="2" w="full" fontSize={"lg"}>
<Text>Read more:</Text> <Text>Read more:</Text>
<Link <Link
color="cyan.200" color="cyan.200"
@@ -34,7 +34,7 @@ function BrowserExtensionTab() {
> >
Launch Tweet Launch Tweet
</Link> </Link>
</HStack> </HStack> */}
<Image mt="2" src="/extension.png" /> <Image mt="2" src="/extension.png" />
</Center> </Center>
); );

View File

@@ -1,6 +1,6 @@
"use client"; "use client";
import { useState, useEffect } from "react"; import { useState, useEffect, useCallback } from "react";
import { Container, useToast, Center, Spacer, Flex } from "@chakra-ui/react"; import { Container, useToast, Center, Spacer, Flex } from "@chakra-ui/react";
import { SingleValue } from "chakra-react-select"; import { SingleValue } from "chakra-react-select";
@@ -171,13 +171,6 @@ function Body() {
// eslint-disable-next-line // eslint-disable-next-line
}, [provider]); }, [provider]);
useEffect(() => {
if (web3wallet) {
subscribeToEvents();
}
// eslint-disable-next-line
}, [web3wallet]);
useEffect(() => { useEffect(() => {
localStorage.setItem("tenderlyForkId", tenderlyForkId); localStorage.setItem("tenderlyForkId", tenderlyForkId);
}, [tenderlyForkId]); }, [tenderlyForkId]);
@@ -236,7 +229,17 @@ function Body() {
}, },
], ],
}) })
.then((res) => console.log(res.data)); .then((res) => {
console.log(res.data);
toast({
title: "Txn Simulated on Tenderly",
description: `Hash: ${res.data.result}`,
status: "success",
position: "bottom-right",
duration: null,
isClosable: true,
});
});
} }
} }
// eslint-disable-next-line // eslint-disable-next-line
@@ -380,86 +383,109 @@ function Body() {
setAppUrl(_inputAppUrl); setAppUrl(_inputAppUrl);
}; };
const subscribeToEvents = async () => { const onSessionProposal = useCallback(
console.log("ACTION", "subscribeToEvents"); async (proposal) => {
if (loading) {
setLoading(false);
}
console.log("EVENT", "session_proposal", proposal);
if (web3wallet) { const { requiredNamespaces, optionalNamespaces } = proposal.params;
web3wallet.on("session_proposal", async (proposal) => { const namespaceKey = "eip155";
if (loading) { const requiredNamespace = requiredNamespaces[namespaceKey] as
setLoading(false); | ProposalTypes.BaseRequiredNamespace
| undefined;
const optionalNamespace = optionalNamespaces
? optionalNamespaces[namespaceKey]
: undefined;
let chains: string[] | undefined =
requiredNamespace === undefined ? undefined : requiredNamespace.chains;
if (optionalNamespace && optionalNamespace.chains) {
if (chains) {
// merge chains from requiredNamespace & optionalNamespace, while avoiding duplicates
chains = Array.from(new Set(chains.concat(optionalNamespace.chains)));
} else {
chains = optionalNamespace.chains;
} }
console.log("EVENT", "session_proposal", proposal);
const { requiredNamespaces, optionalNamespaces } = proposal.params;
const namespaceKey = "eip155";
const requiredNamespace = requiredNamespaces[namespaceKey] as
| ProposalTypes.BaseRequiredNamespace
| undefined;
const optionalNamespace = optionalNamespaces
? optionalNamespaces[namespaceKey]
: undefined;
let chains: string[] | undefined =
requiredNamespace === undefined
? undefined
: requiredNamespace.chains;
if (optionalNamespace && optionalNamespace.chains) {
if (chains) {
// merge chains from requiredNamespace & optionalNamespace, while avoiding duplicates
chains = Array.from(
new Set(chains.concat(optionalNamespace.chains))
);
} else {
chains = optionalNamespace.chains;
}
}
const accounts: string[] = [];
chains?.map((chain) => {
accounts.push(`${chain}:${address}`);
return null;
});
const namespace: SessionTypes.Namespace = {
accounts,
chains: chains,
methods:
requiredNamespace === undefined ? [] : requiredNamespace.methods,
events:
requiredNamespace === undefined ? [] : requiredNamespace.events,
};
if (requiredNamespace && requiredNamespace.chains) {
const _chainId = parseInt(requiredNamespace.chains[0].split(":")[1]);
setSelectedNetworkOption({
label: networksList[_chainId].name,
value: _chainId,
});
}
const session = await web3wallet.approveSession({
id: proposal.id,
namespaces: {
[namespaceKey]: namespace,
},
});
setWeb3WalletSession(session);
setIsConnected(true);
});
try {
await web3wallet.core.pairing.pair({ uri });
} catch (e) {
console.error(e);
} }
web3wallet.on("session_request", async (event) => { const accounts: string[] = [];
const { topic, params, id } = event; chains?.map((chain) => {
const { request } = params; accounts.push(`${chain}:${address}`);
return null;
});
const namespace: SessionTypes.Namespace = {
accounts,
chains: chains,
methods:
requiredNamespace === undefined ? [] : requiredNamespace.methods,
events: requiredNamespace === undefined ? [] : requiredNamespace.events,
};
console.log("EVENT", "session_request", event); if (requiredNamespace && requiredNamespace.chains) {
const _chainId = parseInt(requiredNamespace.chains[0].split(":")[1]);
setSelectedNetworkOption({
label: networksList[_chainId].name,
value: _chainId,
});
}
if (request.method === "eth_sendTransaction") { const session = await web3wallet?.approveSession({
await handleSendTransaction(id, request.params, topic); id: proposal.id,
namespaces: {
[namespaceKey]: namespace,
},
});
setWeb3WalletSession(session);
setIsConnected(true);
},
[web3wallet]
);
const handleSendTransaction = useCallback(
async (id: number, params: any[], topic?: string) => {
setSendTxnData((data) => {
const newTxn = {
id: id,
from: params[0].from,
to: params[0].to,
data: params[0].data,
value: params[0].value
? parseInt(params[0].value, 16).toString()
: "0",
};
if (data.some((d) => d.id === newTxn.id)) {
return data;
} else { } else {
return [newTxn, ...data];
}
});
if (tenderlyForkId.length > 0) {
const { data: res } = await axios.post(
"https://rpc.tenderly.co/fork/" + tenderlyForkId,
{
jsonrpc: "2.0",
id: id,
method: "eth_sendTransaction",
params: params,
}
);
console.log({ res });
// Approve Call Request
if (web3wallet && topic) {
// await web3wallet.respondSessionRequest({
// topic,
// response: {
// jsonrpc: "2.0",
// id: res.id,
// result: res.result,
// },
// });
await web3wallet.respondSessionRequest({ await web3wallet.respondSessionRequest({
topic, topic,
response: { response: {
@@ -472,92 +498,97 @@ function Body() {
}, },
}); });
} }
});
web3wallet.on("session_delete", () => { toast({
console.log("EVENT", "session_delete"); title: "Txn Simulated on Tenderly",
description: `Hash: ${res.result}`,
reset(); status: "success",
}); position: "bottom-right",
} duration: null,
}; isClosable: true,
});
const handleSendTransaction = async (
id: number,
params: any[],
topic?: string
) => {
setSendTxnData((data) => {
const newTxn = {
id: id,
from: params[0].from,
to: params[0].to,
data: params[0].data,
value: params[0].value ? parseInt(params[0].value, 16).toString() : "0",
};
if (data.some((d) => d.id === newTxn.id)) {
return data;
} else { } else {
return [newTxn, ...data]; if (web3wallet && topic) {
} await web3wallet.respondSessionRequest({
}); topic,
response: {
if (tenderlyForkId.length > 0) { jsonrpc: "2.0",
const { data: res } = await axios.post( id: id,
"https://rpc.tenderly.co/fork/" + tenderlyForkId, error: {
{ code: 0,
jsonrpc: "2.0", message: "Method not supported by Impersonator",
id: id, },
method: "eth_sendTransaction", },
params: params, });
} }
); }
console.log({ res }); },
[tenderlyForkId, web3wallet]
);
// Approve Call Request const onSessionRequest = useCallback(
if (web3wallet && topic) { async (event) => {
// await web3wallet.respondSessionRequest({ const { topic, params, id } = event;
// topic, const { request } = params;
// response: {
// jsonrpc: "2.0",
// id: res.id,
// result: res.result,
// },
// });
await web3wallet.respondSessionRequest({ console.log("EVENT", "session_request", event);
if (request.method === "eth_sendTransaction") {
await handleSendTransaction(id, request.params, topic);
} else {
await web3wallet?.respondSessionRequest({
topic, topic,
response: { response: {
jsonrpc: "2.0", jsonrpc: "2.0",
id: id, id: id,
error: { code: 0, message: "Method not supported by Impersonator" }, error: {
code: 0,
message: "Method not supported by Impersonator",
},
}, },
}); });
} }
},
[web3wallet, handleSendTransaction]
);
toast({ const onSessionDelete = () => {
title: "Txn Simulated on Tenderly", console.log("EVENT", "session_delete");
description: `Hash: ${res.result}`,
status: "success", reset();
position: "bottom-right",
duration: null,
isClosable: true,
});
} else {
if (web3wallet && topic) {
await web3wallet.respondSessionRequest({
topic,
response: {
jsonrpc: "2.0",
id: id,
error: { code: 0, message: "Method not supported by Impersonator" },
},
});
}
}
}; };
const subscribeToEvents = useCallback(async () => {
console.log("ACTION", "subscribeToEvents");
if (web3wallet) {
web3wallet.on("session_proposal", onSessionProposal);
try {
await web3wallet.core.pairing.pair({ uri });
} catch (e) {
console.error(e);
}
web3wallet.on("session_request", onSessionRequest);
web3wallet.on("session_delete", onSessionDelete);
}
}, [handleSendTransaction, web3wallet]);
useEffect(() => {
if (web3wallet) {
subscribeToEvents();
}
return () => {
// Clean up event listeners
if (web3wallet) {
web3wallet.removeListener("session_proposal", onSessionProposal);
web3wallet.removeListener("session_request", onSessionRequest);
web3wallet.removeListener("session_delete", onSessionDelete);
}
};
}, [web3wallet, subscribeToEvents]);
const updateSession = async ({ const updateSession = async ({
newChainId, newChainId,
newAddress, newAddress,

View File

@@ -17,6 +17,7 @@ const theme = extendTheme({
global: { global: {
body: { body: {
bg: "brand.black", bg: "brand.black",
color: "white",
}, },
}, },
}, },