Skip to content

Commit f032971

Browse files
committed
refactor(leptos-rainbowkit): improve error handling with Eip1193Error
- Update wallet connection error handling to use typed errors - Add format_transport_error() for user-friendly error display - Improve error logging in connection state management - Update modal components to handle typed errors
1 parent a029ad0 commit f032971

File tree

3 files changed

+55
-8
lines changed

3 files changed

+55
-8
lines changed

crates/leptos-rainbowkit/src/components/modals/connect.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,16 @@ pub fn ConnectModal() -> impl IntoView {
1919
let discovered_wallets = RwSignal::new(Vec::<EIP6963ProviderInfo>::new());
2020

2121
// Setup EIP-6963 discovery when component mounts
22+
// Use a StoredValue to track if we've already set up discovery
23+
let discovery_setup = StoredValue::new(false);
24+
2225
Effect::new(move |_| {
26+
// Only run once
27+
if discovery_setup.get_value() {
28+
return;
29+
}
30+
discovery_setup.set_value(true);
31+
2332
log::info!("Setting up EIP-6963 wallet discovery");
2433

2534
setup_eip6963_discovery(move |provider| {

crates/leptos-rainbowkit/src/hooks/use_wallet.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use alloy::primitives::Address;
99
/// - EIP-1193 signer for wallet signing operations
1010
///
1111
/// This matches the wagmi v2 architecture.
12+
#[derive(Clone, Copy)]
1213
pub struct WalletInfo {
1314
pub address: Signal<Option<Address>>,
1415
pub chain_id: Signal<Option<u64>>,
@@ -27,6 +28,41 @@ pub struct WalletInfo {
2728
pub provider: Signal<Option<WalletProvider>>,
2829
}
2930

31+
impl WalletInfo {
32+
/// Get the address without reactive tracking
33+
///
34+
/// Use this in event handlers or async contexts where you don't want
35+
/// to create reactive dependencies.
36+
pub fn address_untracked(&self) -> Option<Address> {
37+
self.address.get_untracked()
38+
}
39+
40+
/// Get the chain ID without reactive tracking
41+
pub fn chain_id_untracked(&self) -> Option<u64> {
42+
self.chain_id.get_untracked()
43+
}
44+
45+
/// Get the provider without reactive tracking
46+
pub fn provider_untracked(&self) -> Option<WalletProvider> {
47+
self.provider.get_untracked()
48+
}
49+
50+
/// Check if connected without reactive tracking
51+
pub fn is_connected_untracked(&self) -> bool {
52+
self.is_connected.get_untracked()
53+
}
54+
55+
/// Check if connecting without reactive tracking
56+
pub fn is_connecting_untracked(&self) -> bool {
57+
self.is_connecting.get_untracked()
58+
}
59+
60+
/// Get the connector ID without reactive tracking
61+
pub fn connector_id_untracked(&self) -> Option<String> {
62+
self.connector_id.get_untracked()
63+
}
64+
}
65+
3066
/// Hook to access wallet connection information and Alloy provider
3167
///
3268
/// # Example

crates/leptos-rainbowkit/src/state/connection.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use leptos::prelude::*;
22
use alloy::primitives::Address;
33
use alloy::providers::ProviderBuilder;
44
use crate::wallets::wallet::WalletConnector;
5-
use crate::provider::{Eip1193Signer, Eip1193Transport};
5+
use crate::provider::Eip1193Transport;
66
use wasm_bindgen::prelude::*;
77
use wasm_bindgen::JsCast;
88
use web_sys::js_sys;
@@ -297,9 +297,6 @@ impl ConnectionState {
297297
let ethereum_js = connector.get_provider()
298298
.ok_or_else(|| JsValue::from_str("Connector did not provide ethereum provider"))?;
299299

300-
// Create EIP-1193 signer from wallet
301-
let signer = Eip1193Signer::new(ethereum_js.clone(), address);
302-
303300
// Get current chain ID from wallet
304301
let transport = Eip1193Transport::new(ethereum_js.clone());
305302
let chain_id = self.get_current_chain_id(&transport).await?;
@@ -311,11 +308,16 @@ impl ConnectionState {
311308

312309
log::info!("Using RPC URL: {} for chain {}", rpc_url, chain_id);
313310

314-
// Create HTTP provider with consumer's RPC + wallet signer
311+
// Create WalletLayer to route wallet operations through EIP-1193
312+
let wallet_layer = alloy_eip1193::WalletLayer::new(ethereum_js.clone());
313+
314+
// Create provider with WalletLayer + HTTP transport
315+
// This routes wallet operations (eth_sendTransaction) to browser wallet
316+
// while RPC reads go to the HTTP provider
315317
let url: reqwest::Url = rpc_url.parse().map_err(|e| JsValue::from_str(&format!("Invalid RPC URL: {}", e)))?;
316318
let provider = ProviderBuilder::new()
317-
.wallet(signer)
318-
.connect_http(url);
319+
.layer(wallet_layer)
320+
.on_http(url);
319321

320322
// Wrap in Arc to make it cloneable for Leptos signals
321323
let provider: WalletProvider = Arc::new(provider);
@@ -330,7 +332,7 @@ impl ConnectionState {
330332
self.provider.set(Some(provider));
331333
self.status.set(ConnectionStatus::Connected);
332334

333-
log::info!("Connection successful, provider created with HTTP transport + EIP-1193 signer");
335+
log::info!("Connection successful, provider created with WalletLayer + HTTP transport");
334336
Ok(())
335337
}
336338
Err(e) => {

0 commit comments

Comments
 (0)