Skip to content

pina-rs/wasm_solana

Repository files navigation

solana development with a rust based wasm client

Continuous integration badge for github actions


Description

This repository contains several crates that make it easier to interact with Solana in WebAssembly environments:

Crate Version Description
memory_wallet 0.1 A memory based wallet standard implementation primarily used for testing.
test_utils_insta 0.1 Test utilities for working with insta redactions
test_utils_keypairs 0.1 Test utilities for working with pre-defined keypairs
test_utils_solana 0.5 Testing utilities for Solana programs
test_utils_anchor 0.2 Testing utilities specific to Anchor programs
wasm_client_anchor 0.9 WebAssembly client for interacting with Anchor programs
wasm_client_solana 0.9 WebAssembly client for interacting with Solana programs

Why?

The roots of Solana development have always been about "eating glass"—building against the odds with grit and determination. Lately, however, the ecosystem has matured. Development has become easier with the introduction of powerful browser libraries, SDKs, and world-class documentation.

This project asks: what if we went back to our roots? It's a return to the ethos of embracing difficulty and pain to build something truly meaningful. This library is for those who know there are easier languages than Rust, but choose to persevere regardless.

The path will not be easy. Hiring may be difficult, error messages may be cryptic, and progress can be painstaking. But you will build with Rust, you will make meaningful progress, and you will love it.

Crate Details

  • memory_wallet: A wallet-standard compliant in-memory wallet, ideal for testing and prototyping. It manages Keypairs directly in memory, allowing for seamless signing of transactions and messages without requiring user interaction.

    use solana_sdk::transaction::Transaction;
    use solana_sdk::signature::Keypair;
    use wasm_client_solana::{SolanaRpcClient, WasmRpcClient};
    use memory_wallet::MemoryWallet;
    
    // 1. Create a mock RPC client
    let client = SolanaRpcClient::new("https://api.devnet.solana.com");
    
    // 2. Create a keypair for the wallet
    let keypair = Keypair::new();
    
    // 3. Instantiate the in-memory wallet
    let mut wallet = MemoryWallet::new(client, &[keypair]);
    
    // 4. The wallet can now be used to sign transactions, etc.
    // let signed_transaction = wallet.sign_transaction(Transaction::new_with_payer(&[], Some(&wallet.pubkey()))).await?;
  • test_utils_insta: Provides helper functions for creating redactions in insta snapshot tests. This is useful for redacting dynamic data like signatures or timestamps, ensuring that snapshots remain consistent across test runs.

    use insta::assert_debug_snapshot;
    use solana_sdk::signature::Signature;
    use test_utils_insta::create_insta_redaction;
    
    let signature = Signature::new_unique();
    
    assert_debug_snapshot!("my_snapshot", &signature, {
      "signature" => create_insta_redaction(signature, "SIGNATURE"),
    });
  • test_utils_keypairs: A collection of pre-defined, constant Keypairs for use in testing. This avoids the need to generate new keypairs in every test and provides known addresses for setting up test scenarios.

    use test_utils_keypairs::{get_admin_keypair, get_wallet_keypair};
    
    let admin_keypair = get_admin_keypair();
    let wallet_pubkey = get_wallet_keypair().pubkey();
    
    println!("Admin pubkey: {}", admin_keypair.pubkey());
    println!("Wallet pubkey: {}", wallet_pubkey);
  • test_utils_solana: A suite of utilities for Solana integration testing. It simplifies the process of setting up a ProgramTest environment, managing test validators, and creating test accounts, streamlining the entire testing workflow.

    use solana_program_test::ProgramTest;
    use test_utils_solana::ProgramTestExtension;
    
    let mut program_test = ProgramTest::default();
    program_test.add_program("my_program", my_program_id, None);
    
    // Easily add an account with a specific balance
    program_test.add_account_with_lamports(
        some_pubkey,
        1_000_000_000, // 1 SOL
    );
    
    // let (mut banks_client, _, _) = program_test.start().await;
  • test_utils_anchor: Extends test_utils_solana with specific helpers for testing Anchor programs. It provides utilities for serializing and deserializing Anchor accounts, making it easier to set up and verify state in your tests.

    use anchor_lang::{Account, AnchorSerialize};
    use solana_program_test::ProgramTest;
    use test_utils_anchor::ProgramTestAnchorExtension;
    
    #[derive(Account, AnchorSerialize)]
    pub struct MyAnchorAccount {
        pub data: u64,
    }
    
    let mut program_test = ProgramTest::default();
    let my_account_data = MyAnchorAccount { data: 42 };
    
    // Add a serialzed Anchor account directly to the test environment
    program_test.add_account_with_anchor(
        my_account_pubkey,
        my_program_id,
        my_account_data,
        false,
    );
  • wasm_client_anchor: A WebAssembly-compatible client for interacting with Anchor programs from a web environment. It provides a type-safe interface for building instructions and making RPC calls to your on-chain programs.

    // This crate is primarily for building client-side applications in WASM.
    // The following is a conceptual example of how you might define a client.
    
    // In your program's client library:
    // use wasm_client_anchor::prelude::*;
    //
    // #[program]
    // pub mod my_program {
    //     use super::*;
    //     pub fn initialize(ctx: Context<Initialize>) -> Result<()> { Ok(()) }
    // }
    //
    // #[derive(Accounts)]
    // pub struct Initialize {}
    //
    // // This would generate a client to call `initialize` from your WASM app.
  • wasm_client_solana: A general-purpose WebAssembly client for the Solana RPC API. It allows you to fetch account information, send transactions, and interact with the Solana network directly from the browser or other WASM runtimes.

    use std::str::FromStr;
    
    use solana_sdk::pubkey::Pubkey;
    use wasm_client_solana::SolanaRpcClient;
    use wasm_client_solana::WasmRpcClient;
    
    async fn get_balance() {
    	let client = SolanaRpcClient::new("https://api.devnet.solana.com");
    	let pubkey = Pubkey::from_str("So11111111111111111111111111111111111111112").unwrap();
    
    	let balance = client.get_balance(&pubkey).await;
    	println!("Balance: {:?}", balance);
    }

Contributing

devenv is used to provide a reproducible development environment for this project. Follow the getting started instructions.

To automatically load the environment you should install direnv and then load the direnv.

direnv allow .

At this point you should see the nix commands available in your terminal. Any changes made to the .envrc file will require you to run the above command again.

Run the following command to install required rust binaries and solana tooling locally so you don't need to worry about polluting your global namespace or versioning.

install:all

Upgrading devenv

nix profile upgrade devenv

Editor Setup

To setup recommended configuration for your favorite editor run the following commands.

setup:vscode # Setup vscode
setup:helix

License

Unlicense, see the LICENSE file.

About

Wasm binding for solana using rust in the browser.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •  

Languages