在使用 web_sys
库与 Rust 语言来与 Web APIs 进行交互时,要获取 window.ethereum
需要使用 web_sys
提供的 Window
对象以及处理 JavaScript 对象的方法。window.ethereum
是由以太坊的浏览器扩展如 MetaMask 提供的,用于使网页应用能够请求用户的以太坊账号访问权限、发送交易等。
步骤 1: 添加依赖
首先,确保在 Cargo.toml
中包含了 web-sys
的依赖,并启用相应的特性:
toml[dependencies] web-sys = { version = "0.3", features = ["Window", "console"] }
步骤 2: 使用 Web-sys 访问 Window 对象
在 Rust 代码中,你首先需要获取当前的 window
对象:
rustuse web_sys::window; fn main() { let window = window().expect("should have a Window"); // 接下来的步骤将在这里继续 }
步骤 3: 获取 window.ethereum
因为 window.ethereum
对象是 JavaScript 中的一个全局对象,它可能不存在(比如用户没有安装 MetaMask)。Rust 和 WebAssembly 预设并不直接支持这种动态属性,因此我们需要使用 JsValue
和 Reflect
:
rustuse wasm_bindgen::JsCast; use wasm_bindgen::JsValue; use web_sys::{Reflect, Window}; fn get_ethereum(window: &Window) -> Option<JsValue> { if let Ok(ethereum) = Reflect::get(&JsValue::from(window), &JsValue::from_str("ethereum")) { if ethereum.is_undefined() { None } else { Some(ethereum) } } else { None } } fn main() { let window = window().expect("should have a Window"); if let Some(ethereum) = get_ethereum(&window) { // 现在你可以使用这个 ethereum 对象 console::log_1(&"Ethereum object found!".into()); } else { console::log_1(&"Ethereum object not found.".into()); } }
例子
假设你想要检查用户是否已经安装了 MetaMask 并连接到你的网页应用,你可以在获取到 ethereum
对象后调用其 API 方法。比如,请求账户访问:
rustuse wasm_bindgen::prelude::*; use wasm_bindgen::JsCast; #[wasm_bindgen] extern "C" { #[wasm_bindgen(js_namespace = console)] fn log(s: &str); #[wasm_bindgen(method, js_name = requestAccounts)] pub async fn request_accounts(this: &JsValue) -> Result<JsValue, JsValue>; } async fn request_user_accounts(ethereum: JsValue) -> Result<JsValue, JsValue> { ethereum.unchecked_into::<JsValue>().request_accounts().await } #[wasm_bindgen(start)] pub async fn run() -> Result<(), JsValue> { let window = web_sys::window().expect("should have a window"); let ethereum = get_ethereum(&window).expect("Ethereum object should be available"); match request_user_accounts(ethereum).await { Ok(accounts) => log(&format!("Accounts: {:?}", accounts)), Err(_) => log("Failed to get accounts."), } Ok(()) }
这段代码首先使用 get_ethereum
来获取 ethereum
对象,然后通过 request_user_accounts
函数请求用户的以太坊账户,这是与用户进行交互的一种方式。这里用到了异步处理,因为请求账户访问是一种异步操作。
2024年7月26日 22:16 回复