Skip to main content

Crate leptos_solana

Crate leptos_solana 

Source
Expand description

Pure-Rust Wallet Standard bindings for Leptos. Discover, connect to, and sign with Phantom, Backpack, Solflare, Glow, Ledger Live, and any other Wallet Standard-compliant Solana wallet — no hand-written JavaScript shipped with the crate, no npm, no wallet-adapter wrappers.

§Quick start

Add the crate alongside Leptos:

[dependencies]
leptos-solana = "0.1"
leptos = { version = "0.8", features = ["csr"] }

Install the context once at the app root, then call use_wallet from any component:

use leptos::prelude::*;
use leptos_solana::prelude::*;
use leptos_solana::wallet::CHAIN_MAINNET;

#[component]
fn App() -> impl IntoView {
    provide_wallet_context(CHAIN_MAINNET);
    let wallet = use_wallet();

    view! {
        <ul>
            {move || wallet.wallets.get().0.into_iter().map(|w| {
                let name = w.name();
                let ctx = wallet.clone();
                view! {
                    <li><button on:click=move |_| ctx.select(w.clone())>{name}</button></li>
                }
            }).collect_view()}
        </ul>
    }
}

Signing and submitting a transaction:

use leptos_solana::prelude::*;

let ix = Instruction {
    program_id,
    accounts: vec![
        AccountMeta::new(from, true),
        AccountMeta::new(to, false),
    ],
    data,
};

let rpc = RpcClient::devnet();
let blockhash = rpc.get_latest_blockhash(CommitmentConfig::confirmed()).await?;

let msg = Message::new_with_blockhash(&[ix], Some(&from), &blockhash);
let tx: VersionedTransaction = Transaction::new_unsigned(msg).into();

let sig: Vec<u8> = wallet.sign_and_send(&tx).await?;

§Design notes

  • Wallet Standard is a JS spec. Wallets register themselves via CustomEvents on window. The crate reaches those objects with wasm_bindgen/js_sys — no .js shim is written by hand and no npm/esbuild is needed. discovery::start runs the spec-compliant app-ready + register-wallet handshake.

  • VersionedTransaction only. The wallet-signing API is VersionedTransaction-only. Legacy Transaction values can still be constructed and converted via Into — the Legacy variant of VersionedMessage serializes to the exact same wire bytes, so there is no behavior change for programs that do not need address lookup tables.

  • Tiny dep closure. No solana-sdk, no solana-client, no tokio. Pure Rust transaction construction via Anza’s split crates (solana-pubkey, solana-message, solana-transaction, solana-instruction), bincode v1 for wire format, gloo-net for JSON-RPC.

  • Reactive state. WalletContext exposes wallets/selected/account/chain as Leptos signals. The context’s connect/disconnect/sign_* methods are async and can be called from spawn_local.

  • Auto-reconnect. On successful connect, the wallet name is persisted to localStorage; on provide_wallet_context, if that wallet registers during discovery it is silently reconnected without prompting.

  • Clean teardown. discovery::start returns a DiscoveryHandle that removes the event listener in Drop. provide_wallet_context ties the handle’s lifetime to the Leptos owner.

§Comparison with the JS stack

The JS wallet ecosystem is layered: @wallet-standard/app@solana/wallet-adapter-base@solana/wallet-adapter-react@solana/wallet-adapter-react-ui. This crate provides the first three layers for Leptos (discovery, signer primitives, and a reactive context). No UI components ship with the crate.

§Modules

  • context Leptos WalletContext, signals, connect/sign_* methods.
  • discovery Wallet Standard event-based discovery.
  • features Typed wrappers over Solana feature methods.
  • rpc Minimal JSON-RPC client (gloo-net).
  • storage localStorage persistence for last-connected wallet.
  • tx VersionedTransaction bincode serialize/deserialize.
  • wallet wasm_bindgen extern types matching the Wallet Standard spec.
  • error Crate-wide error type.
  • prelude use leptos_solana::prelude::*; brings in everything callers need.

Re-exports§

pub use error::Error;
pub use error::Result;

Modules§

context
Leptos context + signals for wallet state.
discovery
Wallet Standard discovery via CustomEvents on window.
error
features
Typed wrappers over Solana Wallet Standard feature methods.
prelude
One-stop import for common callers: use leptos_solana::prelude::*;.
rpc
Minimal Solana JSON-RPC client over gloo-net.
storage
localStorage helpers for remembering the last-connected wallet so crate::context::provide_wallet_context can silent-reconnect on page load.
tx
Transaction serialization helpers.
wallet
wasm-bindgen extern types matching the Wallet Standard spec.