From f8c8b4d8ab194292826494f2fb70945e5da8d01e Mon Sep 17 00:00:00 2001 From: Onyewuchi Emmanuel Date: Tue, 3 Sep 2024 16:44:34 +0100 Subject: [PATCH] =?UTF-8?q?interact-with-wallets.md=20refactor:=20optimize?= =?UTF-8?q?=20web3=20import=20and=20add=20error=20handling=20to=20transact?= =?UTF-8?q?ion=20=E2=80=A6=20(#354)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: optimize web3 import and add error handling to transaction logic - Refactored import from 'import * as web3' to 'importing the necessary packages' for better efficiency. - Added try-catch block for robust error handling during transaction execution. - Fixed variable typo when logging transaction signature. - Improved handling for cases where connection or publicKey is unavailable. * refcator(): - Refactored `useEffect` to use `async/await` consistently instead of mixing with `.then()`/`.catch()`. - Wrapped the code in `try/catch` blocks for better error handling and to ensure any failures are properly caught. - Updated error handling to use `throw new Error()` instead of throwing strings. - Improved code readability and maintainability by centralizing the balance update logic within a single `async` function. --------- Co-authored-by: Onyewuchi Emeka --- .../intro-to-solana/interact-with-wallets.md | 146 +++++++++++------- 1 file changed, 94 insertions(+), 52 deletions(-) diff --git a/content/courses/intro-to-solana/interact-with-wallets.md b/content/courses/intro-to-solana/interact-with-wallets.md index db3c99240..924a5ea11 100644 --- a/content/courses/intro-to-solana/interact-with-wallets.md +++ b/content/courses/intro-to-solana/interact-with-wallets.md @@ -118,10 +118,10 @@ import { ConnectionProvider, WalletProvider, } from "@solana/wallet-adapter-react"; -import * as web3 from "@solana/web3.js"; +import { clusterApiUrl } from "@solana/web3.js"; export const Home: NextPage = props => { - const endpoint = web3.clusterApiUrl("devnet"); + const endpoint = clusterApiUrl("devnet"); const wallets = useMemo(() => [], []); return ( @@ -167,10 +167,15 @@ import { WalletModalProvider, WalletMultiButton, } from "@solana/wallet-adapter-react-ui"; -import * as web3 from "@solana/web3.js"; +import { + clusterApiUrl, + Transaction, + PublicKey, + SystemProgram, +} from "@solana/web3.js"; const Home: NextPage = props => { - const endpoint = web3.clusterApiUrl("devnet"); + const endpoint = clusterApiUrl("devnet"); const wallets = useMemo(() => [], []); return ( @@ -229,21 +234,33 @@ export const BalanceDisplay: FC = () => { const { publicKey } = useWallet(); useEffect(() => { - if (!connection || !publicKey) { - return; - } - - connection.onAccountChange( - publicKey, - updatedAccountInfo => { - setBalance(updatedAccountInfo.lamports / LAMPORTS_PER_SOL); - }, - "confirmed", - ); - - connection.getAccountInfo(publicKey).then(info => { - setBalance(info.lamports); - }); + const updateBalance = async () => { + if (!connection || !publicKey) { + console.error("Wallet not connected or connection unavailable"); + } + + try { + connection.onAccountChange( + publicKey, + updatedAccountInfo => { + setBalance(updatedAccountInfo.lamports / LAMPORTS_PER_SOL); + }, + "confirmed", + ); + + const accountInfo = await connection.getAccountInfo(publicKey); + + if (accountInfo) { + setBalance(accountInfo.lamports / LAMPORTS_PER_SOL); + } else { + throw new Error("Account info not found"); + } + } catch (error) { + console.error("Failed to retrieve account info:", error); + } + }; + + updateBalance(); }, [connection, publicKey]); return ( @@ -269,18 +286,28 @@ const { connection } = useConnection(); const sendSol = async event => { event.preventDefault(); - const transaction = new web3.Transaction(); - const recipientPubKey = new web3.PublicKey(event.target.recipient.value); + if (!publicKey) { + console.error("Wallet not connected"); + return; + } + + try { + const recipientPubKey = new PublicKey(event.currentTarget.recipient.value); + + const transaction = new Transaction(); + const sendSolInstruction = SystemProgram.transfer({ + fromPubkey: publicKey, + toPubkey: recipientPubKey, + lamports: 0.1 * LAMPORTS_PER_SOL, + }); - const sendSolInstruction = web3.SystemProgram.transfer({ - fromPubkey: publicKey, - toPubkey: recipientPubKey, - lamports: 0.1 * LAMPORTS_PER_SOL, - }); + transaction.add(sendSolInstruction); - transaction.add(sendSolInstruction); - const signature = sendTransaction(transaction, connection); - console.log(signature); + const signature = await sendTransaction(transaction, connection); + console.log(`Transaction signature: ${signature}`); + } catch (error) { + console.error("Transaction failed", error); + } }; ``` @@ -401,12 +428,12 @@ import { WalletProvider, } from "@solana/wallet-adapter-react"; import { WalletModalProvider } from "@solana/wallet-adapter-react-ui"; -import * as web3 from "@solana/web3.js"; +import { clusterApiUrl } from "@solana/web3.js"; import * as walletAdapterWallets from "@solana/wallet-adapter-wallets"; require("@solana/wallet-adapter-react-ui/styles.css"); const WalletContextProvider: FC<{ children: ReactNode }> = ({ children }) => { - const endpoint = web3.clusterApiUrl("devnet"); + const endpoint = clusterApiUrl("devnet"); const wallets = useMemo(() => [], []); return ( @@ -506,7 +533,12 @@ import `@solana/web3.js` since we’ll need it to create our transaction. ```tsx import { useConnection, useWallet } from "@solana/wallet-adapter-react"; -import * as web3 from "@solana/web3.js"; +import { + PublicKey, + Transaction, + TransactionInstruction, + sendTransaction, +} from "@solana/web3.js"; import { FC, useState } from "react"; import styles from "../styles/PingButton.module.css"; @@ -528,7 +560,12 @@ Now use the `useConnection` hook to create a `connection` constant and the ```tsx import { useConnection, useWallet } from "@solana/wallet-adapter-react"; -import * as web3 from "@solana/web3.js"; +import { + PublicKey, + Transaction, + TransactionInstruction, + sendTransaction, +} from "@solana/web3.js"; import { FC, useState } from "react"; import styles from "../styles/PingButton.module.css"; @@ -567,27 +604,32 @@ Finally, call `sendTransaction`. ```tsx const onClick = async () => { if (!connection || !publicKey) { - return; + console.error("Wallet not connected or connection unavailable"); } - const programId = new web3.PublicKey(PROGRAM_ID); - const programDataAccount = new web3.PublicKey(DATA_ACCOUNT_PUBKEY); - const transaction = new web3.Transaction(); - - const instruction = new web3.TransactionInstruction({ - keys: [ - { - pubkey: programDataAccount, - isSigner: false, - isWritable: true, - }, - ], - programId, - }); - - transaction.add(instruction); - const signature = await sendTransaction(transaction, connection); - console.log(sig); + try { + const programId = new PublicKey(PROGRAM_ID); + const programDataAccount = new PublicKey(DATA_ACCOUNT_PUBKEY); + const transaction = new Transaction(); + + const instruction = new TransactionInstruction({ + keys: [ + { + pubkey: programDataAccount, + isSigner: false, + isWritable: true, + }, + ], + programId, + }); + + transaction.add(instruction); + + const signature = await sendTransaction(transaction, connection); + console.log("Transaction Signature:", signature); + } catch (error) { + console.error("Transaction failed:", error); + } }; ```