Skip to main content

Crate solana_wasi

Crate solana_wasi 

Source
Expand description

Solana primitives that compile to wasm32-wasip2.

solana-sdk and solana-client do not build inside a WebAssembly component without a fight, and the parts of them a tool plugin needs are small. This crate is those parts, written against the wire formats directly: pubkeys and PDAs, a typed JSON-RPC client over a swappable transport, SPL Token and Token-2022 account parsing including the full extension set, unsigned v0 transaction construction, durable nonces, and the output-shaping helpers that keep a tool’s answer inside a model’s context budget.

§Three properties, on purpose

It cannot sign. There is no keypair type, no signer trait, and no path from an instruction to a signature. A plugin built on this crate can hold at most an RPC URL. Signing belongs to a wallet, a human, or a multisig.

It is host-testable. Everything except [transport::WakiTransport] is pure Rust with no wasm dependency. A plugin’s cargo test runs on the host against transport::MockTransport, with no wasm toolchain and no live network, which is what ZeroClaw’s plugin CI requires.

It treats the chain as hostile input. Token names, symbols and metadata URIs are written by whoever deployed the mint. sanitize exists because those strings end up in a language model’s context, and a tool that forwards them verbatim is an injection vector with an RPC bill.

§Example

use solana_wasi::prelude::*;

let transport = MockTransport::new().on(
    "getAccountInfo",
    serde_json::json!({
        "context": { "slot": 1 },
        "value": {
            "lamports": 1_000_000_000u64,
            "owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
            // 82 zero bytes: a mint with no authorities.
            "data": [base64_of_82_zero_bytes(), "base64"],
            "executable": false,
            "rentEpoch": 0
        }
    }),
);

let rpc = RpcClient::new("https://api.mainnet-beta.solana.com", transport);
let mint_address = Pubkey::from_base58("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v")?;
let account = rpc.require_account(&mint_address)?;
let state = MintState::parse(mint_address, &account)?;

assert_eq!(state.program, TokenProgram::Legacy);
assert!(state.mint.freeze_authority.is_none());

Re-exports§

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

Modules§

error
One error type for the whole crate.
metadata
Metaplex Token Metadata, decoded far enough to answer one question: can the team still change what this token claims to be?
nonce
Durable nonce accounts.
prelude
Everything a plugin’s pure core typically imports.
pubkey
32-byte public keys, base58, and program-derived addresses.
rpc
A small, typed JSON-RPC client.
sanitize
Making on-chain strings safe to put in front of a language model.
shape
Output shaping: turning chain data into the ~200 tokens a model needs.
token
SPL Token and Token-2022 account layouts.
transport
How a JSON-RPC request leaves the component.
tx
Building and serializing an unsigned v0 transaction.