Fix: Fetch token data fetch when wallet connect and not connect#70
Fix: Fetch token data fetch when wallet connect and not connect#70kumawatkaran523 merged 3 commits intoStabilityNexus:mainfrom
Conversation
📝 WalkthroughWalkthroughThe PR refactors token verification in CreateInvoice by adding chain-specific verification support. The Changes
Sequence DiagramsequenceDiagram
actor User
participant CreateInvoice as CreateInvoice Component
participant VerifyToken as verifyToken Function
participant ChainLogic as Chain Determination
participant ProviderLogic as Provider Selection
participant Provider as Web3 Provider
participant TokenContract as Token Contract
User->>CreateInvoice: Verify token (address, optional chainId)
CreateInvoice->>VerifyToken: Call with targetChainId
VerifyToken->>ChainLogic: Determine chainIdToUse
ChainLogic-->>ChainLogic: Prioritize: targetChainId → URL param → account.chainId
ChainLogic-->>VerifyToken: Return resolved chainId
VerifyToken->>ProviderLogic: Select provider for chainId
alt Wallet Connected
ProviderLogic->>Provider: Use wallet provider
else Unsupported Chain
ProviderLogic-->>VerifyToken: Error - unsupported chain
VerifyToken-->>CreateInvoice: Early return / error
else Public RPC Available
ProviderLogic->>Provider: Initialize JsonRpcProvider with RPC URL
end
Provider->>TokenContract: Fetch symbol, name, decimals
TokenContract-->>Provider: Return token metadata
Provider-->>VerifyToken: Token data
VerifyToken-->>VerifyToken: Parse decimals as Number
VerifyToken->>CreateInvoice: Return {symbol, name, decimals, chainId}
CreateInvoice-->>User: Token verified with chain info
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@frontend/src/page/CreateInvoice.jsx`:
- Around line 259-276: The code can call new ethers.Contract(address, ERC20_ABI,
provider) with provider undefined if neither isConnected/walletClient nor
chainIdToUse/rpcUrl are available (and walletClient can be undefined even when
isConnected). Fix by validating/initializing provider before constructing the
contract: when isConnected check that walletClient is defined before using new
BrowserProvider(walletClient) (otherwise fall back to a public JsonRpcProvider
or setTokenVerificationState("error") and return), and if !isConnected ensure
chainIdToUse exists and rpcUrls[chainIdToUse] exists; only call
ethers.Contract(address, ERC20_ABI, provider) after provider is guaranteed
non-null.
🧹 Nitpick comments (2)
frontend/src/page/CreateInvoice.jsx (2)
284-284: Remove debug console.log statement.This debug logging should be removed or converted to conditional debug logging before merging to production.
♻️ Suggested fix
- console.log([symbol, name, decimals]);
251-258: Consider making RPC URLs configurable.The hardcoded RPC URLs work but could become stale or rate-limited. For better maintainability, consider moving these to environment variables or a configuration file.
// Example: Use environment variables const rpcUrls = { // ... };
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
frontend/src/page/CreateInvoice.jsx
🔇 Additional comments (1)
frontend/src/page/CreateInvoice.jsx (1)
160-160: Good addition ofwalletClientto the dependency array.This correctly ensures the effect re-runs when the wallet client becomes available, which addresses the page refresh bug where token metadata wasn't fetched because
walletClientwas still loading.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
| if (typeof window !== "undefined" && isConnected) { | ||
| // Fallback to wallet provider if no chainId specified | ||
| provider = new BrowserProvider(walletClient); | ||
| // If chainId is available, always use public RPC (works without wallet) | ||
| } else if (chainIdToUse) { | ||
| const rpcUrl = rpcUrls[chainIdToUse]; | ||
|
|
||
| if (!rpcUrl) { | ||
| console.error(`Unsupported chain ${chainIdToUse}. Supported chains: Ethereum (1), Ethereum Classic (61), Polygon (137), BNB Smart Chain (56), Base (8453), Sepolia (11155111)`); | ||
| setTokenVerificationState("error"); | ||
| return; | ||
| } | ||
| } catch (error) { | ||
| console.error("Verification failed:", error); | ||
| setTokenVerificationState("error"); | ||
| // Use JsonRpcProvider with timeout for faster response | ||
| provider = new ethers.JsonRpcProvider(rpcUrl, Number(chainIdToUse)); | ||
| } | ||
| }; | ||
|
|
||
| const contract = new ethers.Contract(address, ERC20_ABI, provider); |
There was a problem hiding this comment.
Potential runtime error when provider is not initialized.
If the user is not connected (isConnected is false) and no chainIdToUse is available (no URL chain param and no account.chainId), then provider is never assigned. Line 276 will throw when attempting to create the contract.
Additionally, walletClient can be undefined even when isConnected is true due to async loading from useWalletClient().
🐛 Proposed fix to handle edge cases
if (typeof window !== "undefined" && isConnected) {
- // Fallback to wallet provider if no chainId specified
- provider = new BrowserProvider(walletClient);
+ if (!walletClient) {
+ console.error("Wallet client not ready yet");
+ setTokenVerificationState("error");
+ return;
+ }
+ provider = new BrowserProvider(walletClient);
// If chainId is available, always use public RPC (works without wallet)
} else if (chainIdToUse) {
const rpcUrl = rpcUrls[chainIdToUse];
if (!rpcUrl) {
console.error(`Unsupported chain ${chainIdToUse}. Supported chains: Ethereum (1), Ethereum Classic (61), Polygon (137), BNB Smart Chain (56), Base (8453), Sepolia (11155111)`);
setTokenVerificationState("error");
return;
}
// Use JsonRpcProvider with timeout for faster response
provider = new ethers.JsonRpcProvider(rpcUrl, Number(chainIdToUse));
+ } else {
+ console.error("Cannot verify token: no wallet connected and no chain specified");
+ setTokenVerificationState("error");
+ return;
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if (typeof window !== "undefined" && isConnected) { | |
| // Fallback to wallet provider if no chainId specified | |
| provider = new BrowserProvider(walletClient); | |
| // If chainId is available, always use public RPC (works without wallet) | |
| } else if (chainIdToUse) { | |
| const rpcUrl = rpcUrls[chainIdToUse]; | |
| if (!rpcUrl) { | |
| console.error(`Unsupported chain ${chainIdToUse}. Supported chains: Ethereum (1), Ethereum Classic (61), Polygon (137), BNB Smart Chain (56), Base (8453), Sepolia (11155111)`); | |
| setTokenVerificationState("error"); | |
| return; | |
| } | |
| } catch (error) { | |
| console.error("Verification failed:", error); | |
| setTokenVerificationState("error"); | |
| // Use JsonRpcProvider with timeout for faster response | |
| provider = new ethers.JsonRpcProvider(rpcUrl, Number(chainIdToUse)); | |
| } | |
| }; | |
| const contract = new ethers.Contract(address, ERC20_ABI, provider); | |
| if (typeof window !== "undefined" && isConnected) { | |
| if (!walletClient) { | |
| console.error("Wallet client not ready yet"); | |
| setTokenVerificationState("error"); | |
| return; | |
| } | |
| // Fallback to wallet provider if no chainId specified | |
| provider = new BrowserProvider(walletClient); | |
| // If chainId is available, always use public RPC (works without wallet) | |
| } else if (chainIdToUse) { | |
| const rpcUrl = rpcUrls[chainIdToUse]; | |
| if (!rpcUrl) { | |
| console.error(`Unsupported chain ${chainIdToUse}. Supported chains: Ethereum (1), Ethereum Classic (61), Polygon (137), BNB Smart Chain (56), Base (8453), Sepolia (11155111)`); | |
| setTokenVerificationState("error"); | |
| return; | |
| } | |
| // Use JsonRpcProvider with timeout for faster response | |
| provider = new ethers.JsonRpcProvider(rpcUrl, Number(chainIdToUse)); | |
| } else { | |
| console.error("Cannot verify token: no wallet connected and no chain specified"); | |
| setTokenVerificationState("error"); | |
| return; | |
| } | |
| const contract = new ethers.Contract(address, ERC20_ABI, provider); |
🤖 Prompt for AI Agents
In `@frontend/src/page/CreateInvoice.jsx` around lines 259 - 276, The code can
call new ethers.Contract(address, ERC20_ABI, provider) with provider undefined
if neither isConnected/walletClient nor chainIdToUse/rpcUrl are available (and
walletClient can be undefined even when isConnected). Fix by
validating/initializing provider before constructing the contract: when
isConnected check that walletClient is defined before using new
BrowserProvider(walletClient) (otherwise fall back to a public JsonRpcProvider
or setTokenVerificationState("error") and return), and if !isConnected ensure
chainIdToUse exists and rpcUrls[chainIdToUse] exists; only call
ethers.Contract(address, ERC20_ABI, provider) after provider is guaranteed
non-null.
|
Can you explain bit more what exactly the issue is? |
issue - #63
when user connect -
error when refresh the page -

solve -
when user not connect -
example with using alchemy rpc for sepolia -
@Zahnentferner @kumawatkaran523
Summary by CodeRabbit
Release Notes
✏️ Tip: You can customize this high-level summary in your review settings.