diff --git a/packages/nextjs/app/page.tsx b/packages/nextjs/app/page.tsx index 59fa9b7..f7eb3a5 100644 --- a/packages/nextjs/app/page.tsx +++ b/packages/nextjs/app/page.tsx @@ -31,7 +31,7 @@ const Home: NextPage = () => { try { const isTestnet = await primaryWallet?.connector?.isTestnet(); if (!isTestnet) { - alert("You might want to switch to testnet to send transactions"); + alert("You're not on a testnet, proceed with caution."); } const hash = await sendTransaction(connectedAddress, "0.0001", primaryWallet, networkConfigurations); setTransactionSignature(hash); diff --git a/packages/nextjs/app/safe/page.tsx b/packages/nextjs/app/safe/page.tsx index a8ad2ef..9f904d4 100644 --- a/packages/nextjs/app/safe/page.tsx +++ b/packages/nextjs/app/safe/page.tsx @@ -22,6 +22,7 @@ import { getPimlicoSmartAccountClient, transferERC20, } from "~~/lib/permissionless"; +import { notification } from "~~/utils/scaffold-eth"; const SafePage = () => { const { address, chain, isConnected } = useAccount(); @@ -61,6 +62,12 @@ const SafePage = () => { setNetwork(network); }; + useEffect(() => { + if (!process.env.NEXT_PUBLIC_PIMLICO_API_KEY) { + notification.error("Please set NEXT_PUBLIC_PIMLICO_API_KEY in .env file."); + } + }, []); + useEffect(() => { fetchNetwork(); }, [primaryWallet]); @@ -72,6 +79,11 @@ const SafePage = () => { const userAddress = address as `0x${string}`; if (!primaryWallet || !chain) return; + if (!process.env.NEXT_PUBLIC_PIMLICO_API_KEY) { + notification.error("Please set NEXT_PUBLIC_PIMLICO_API_KEY in .env file and restart"); + return; + } + const walletClient = await createWalletClientFromWallet(primaryWallet); const { account } = await getPimlicoSmartAccountClient(userAddress, chain, walletClient); setSafeAddress(account.address); @@ -150,8 +162,13 @@ const SafePage = () => { const transactionDetail = await getTransactionOnBaseSepoliaByHash(txHash); setTransactionDetails([...transactionDetails, transactionDetail]); } catch (err) { - setError("Failed to transfer tokens."); - console.error(err); + if (err instanceof Error) { + notification.error(err.message); + console.error(err.message); + } else { + setError("Failed to transfer tokens."); + console.error(err); + } } finally { setLoading(false); } diff --git a/packages/nextjs/components/ScaffoldEthAppWithProviders.tsx b/packages/nextjs/components/ScaffoldEthAppWithProviders.tsx index bb35c7c..8d8d04e 100644 --- a/packages/nextjs/components/ScaffoldEthAppWithProviders.tsx +++ b/packages/nextjs/components/ScaffoldEthAppWithProviders.tsx @@ -38,6 +38,25 @@ export const queryClient = new QueryClient({ }, }); +const evmNetworks = [ + ...scaffoldConfig.targetNetworks.map(chain => ({ + blockExplorerUrls: chain.blockExplorers + ? Object.values(chain.blockExplorers as any).map(({ url }: any) => url) + : [], + chainId: chain.id, + name: chain.name, + rpcUrls: Object.values(chain.rpcUrls).map(({ http }) => http[0]), + iconUrls: [ + chain.name === "Hardhat" + ? "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRz4i1wWF516fnkizp1WSDG5rnG8GfkQAVoVQ&s" + : "", + ], + nativeCurrency: chain.nativeCurrency, + networkId: chain.id, + })), + ...customEvmNetworks, +]; + export const ScaffoldEthAppWithProviders = ({ children }: { children: React.ReactNode }) => { const { resolvedTheme } = useTheme(); @@ -48,7 +67,7 @@ export const ScaffoldEthAppWithProviders = ({ children }: { children: React.Reac environmentId: scaffoldConfig.dynamicEnvId, walletConnectors: [EthereumWalletConnectors], overrides: { - evmNetworks: networks => mergeNetworks(customEvmNetworks, networks), + evmNetworks: networks => mergeNetworks(evmNetworks, networks), }, }} > diff --git a/packages/nextjs/lib/dynamic.ts b/packages/nextjs/lib/dynamic.ts index 2d1d966..e1b8bda 100644 --- a/packages/nextjs/lib/dynamic.ts +++ b/packages/nextjs/lib/dynamic.ts @@ -2,6 +2,7 @@ import { Wallet } from "@dynamic-labs/sdk-react-core"; import { NetworkConfigurationMap } from "@dynamic-labs/types"; import { getOrMapViemChain } from "@dynamic-labs/viem-utils"; import { Account, Chain, Hex, Transport, WalletClient, parseEther } from "viem"; +import { notification } from "~~/utils/scaffold-eth"; export const signMessage = async (message: string, wallet: any): Promise => { const connector = wallet?.connector; @@ -15,24 +16,32 @@ export const sendTransaction = async ( wallet: Wallet, networkConfigurations: NetworkConfigurationMap, ): Promise => { - const walletClient = wallet.connector.getWalletClient>(); - - const chainID = await wallet.connector.getNetwork(); - const currentNetwork = networkConfigurations.evm?.find(network => network.chainId === chainID); - - if (!currentNetwork) { - throw new Error("Network not found"); + try { + const walletClient = wallet.connector.getWalletClient>(); + + const chainID = await wallet.connector.getNetwork(); + const currentNetwork = networkConfigurations.evm?.find(network => network.chainId === chainID); + + if (!currentNetwork) { + throw new Error("Network not found"); + } + + const chain = getOrMapViemChain(currentNetwork); + + const transaction = { + account: wallet.address as Hex, + to: address as Hex, + chain, + value: amount ? parseEther(amount) : undefined, + }; + + const transactionHash = await walletClient.sendTransaction(transaction); + return transactionHash; + } catch (e) { + if (e instanceof Error) { + notification.error(`Error sending transaction: ${e.message}`); + } else { + notification.error("Error sending transaction"); + } } - - const chain = getOrMapViemChain(currentNetwork); - - const transaction = { - account: wallet.address as Hex, - to: address as Hex, - chain, - value: amount ? parseEther(amount) : undefined, - }; - - const transactionHash = await walletClient.sendTransaction(transaction); - return transactionHash; }; diff --git a/packages/nextjs/scaffold.config.ts b/packages/nextjs/scaffold.config.ts index 3191284..49ed1c8 100644 --- a/packages/nextjs/scaffold.config.ts +++ b/packages/nextjs/scaffold.config.ts @@ -10,7 +10,7 @@ export type ScaffoldConfig = { const scaffoldConfig = { // The networks on which your DApp is live - targetNetworks: [chains.baseSepolia], + targetNetworks: [chains.hardhat], // The interval at which your front-end polls the RPC servers for new data // it has no effect if you only target the local network (default is 4000) diff --git a/packages/nextjs/services/web3/wagmiConfig.tsx b/packages/nextjs/services/web3/wagmiConfig.tsx index 883b0f9..62fbd90 100644 --- a/packages/nextjs/services/web3/wagmiConfig.tsx +++ b/packages/nextjs/services/web3/wagmiConfig.tsx @@ -30,6 +30,7 @@ export const wagmiConfig = createConfig({ scroll, scrollSepolia, sepolia, + hardhat, ...customEvmNetworks.map(getOrMapViemChain), ], ssr: true,