Crate fireblocks_solana_signer

Crate fireblocks_solana_signer 

Source
Expand description

fireblocks-solana-signer

docs build deps codecov crate

§Overview

Implementation of a Solana Signer using Fireblocks as backend signer

§Prerequisites

A fireblocks account with API key. See developer portal and sign up for a sandbox account

§Installation

Add this to your Cargo.toml:

[dependencies]
fireblocks-solana-signer = "1"

Or install via cargo:

cargo add fireblocks-solana-signer@1

§TLDR

use {
    fireblocks_solana_sdk::signature::FireblocksSigner,
    solana_sdk::message::Message,
    solana_client::rpc_client::{RpcClient, SerializableTransaction},
    solana_sdk::instruction::Instruction,
    solana_sdk::transaction::Transaction,
};

fn memo(message: &str) -> Instruction {
    Instruction {
        program_id: spl_memo_interface::v3::id(),
        accounts: vec![],
        data: message.as_bytes().to_vec(),
    }
}

fn main() -> anyhow::Result<()> {
    let signer: FireblocksSigner = FireblocksSigner::try_from_env(None)?;
    let rpc = RpcClient::new(
        std::env::var("RPC_URL")
            .ok()
            .unwrap_or("https://rpc.ankr.com/solana_devnet".to_string()),
    );
    let hash = rpc.get_latest_blockhash()?;
    let message = Message::new(&[memo("fireblocks signer")], Some(&signer.pk));
    let mut tx = Transaction::new_unsigned(message);

    tx.try_sign(&[&signer], hash)?;
    rpc.send_transaction(&tx)?;

    Ok(())
}

See example

§Transaction Broadcasting

By default, this signer only signs transactions and does not broadcast them. You control when transactions are sent to the network by calling rpc.send_transaction() yourself.

To enable automatic broadcasting (where Fireblocks signs and broadcasts in one step), set:

  • Environment variable: FIREBLOCKS_BROADCAST=true
  • Config file: broadcast = true in the [signer] section

When auto-broadcasting is enabled, transactions are sent to the network immediately after signing, and you should not call send_transaction() yourself.

§Environment Variables

VarExample
FIREBLOCKS_SECRETRSA private key of your API user
FIREBLOCKS_API_KEYuuid of api user
FIREBLOCKS_ENDPOINThttps://sandbox-api.fireblocks.io
FIREBLOCKS_PUBKEYoptional pubkey, or lookup based on FIREBLOCKS_VAULT
FIREBLOCKS_DEVNETset to any value if you are on devnet
FIREBLOCKS_VAULTyour vault id
FIREBLOCKS_POLL_TIMEOUTin seconds, total time to check status of transaction
FIREBLOCKS_POLL_INTERVALin seconds
FIREBLOCKS_BROADCASTset to “true” to auto-broadcast transactions (default: false)

§Configuration Files (Optional)

As an alternative to environment variables, you can use configuration files with the config feature. This provides a more structured approach to managing multiple Fireblocks environments and credentials.

§Enabling the Config Feature

Add the config feature to your Cargo.toml:

[dependencies]
fireblocks-solana-signer = { version = "1", features = ["config"] }

§Configuration File Setup

The config feature uses the fireblocks-config crate for configuration management. Configuration files are stored in the ~/.config/fireblocks/ directory using the microxdg crate.

File Structure:

  • Default configuration: ~/.config/fireblocks/default.toml (always loaded)
  • Profile configurations: ~/.config/fireblocks/{profile}.toml (override default settings)

Example ~/.config/fireblocks/default.toml:

api_key = "your-sandbox-api-key-uuid"
secret_path = "/path/to/your/sandbox-private-key.pem"
url = "https://sandbox-api.fireblocks.io"
mainnet = false

[signer]
vault = "your-sandbox-vault-id"
poll_timeout = 30
poll_interval = 2
broadcast = false # default is false

Example ~/.config/fireblocks/production.toml:

api_key = "your-production-api-key"
secret_path = "/path/to/production-key.pem"
url = "https://api.fireblocks.io"
mainnet = true

[signer]
vault = "your-production-vault-id"
poll_timeout = 60
poll_interval = 3
broadcast = true

§Using Configuration Files

use fireblocks_solana_sdk::signature::FireblocksSigner;

fn main() -> anyhow::Result<()> {
    // Use default configuration profile
    let signer = FireblocksSigner::try_from_config::<String>(
        &[],
        |tx_response| println!("Transaction status: {}", tx_response)
    )?;

    // Use specific configuration profiles
    let signer = FireblocksSigner::try_from_config(
        &["mainnet"],
        |tx_response| eprintln!("Mainnet TX: {}", tx_response)
    )?;

    // Use multiple profiles (later profiles override earlier ones)
    let signer = FireblocksSigner::try_from_config(
        &["default", "production"],
        |tx_response| println!("TX Update: {}", tx_response)
    )?;

    // Your transaction code here...
    Ok(())
}

How Profile Loading Works:

  • Empty slice &[]: Loads only ~/.config/fireblocks/default.toml
  • Single profile &["production"]: Loads default.toml first, then production.toml overrides any matching settings
  • Multiple profiles &["staging", "production"]: Loads default.toml, then staging.toml, then production.toml (each overriding previous values)

§Benefits of Configuration Files

  • Multiple Environments: Easily switch between sandbox, testnet, and mainnet
  • Profile Management: Organize different configurations by environment or use case
  • Version Control: Configuration files can be committed (without secrets) for team sharing
  • Validation: Built-in validation and error handling for configuration values
  • Flexibility: Override specific settings per profile while inheriting defaults

§Configuration vs Environment Variables

MethodBest ForProsCons
Environment VariablesSimple setups, CI/CDEasy to set, widely supportedHard to manage multiple environments
Configuration FilesComplex setups, multiple environmentsOrganized, version-controllable, flexibleRequires additional feature, more setup

For detailed configuration options and file locations, see the fireblocks-config documentation.

§Development

§Prerequisites

  • Rust Nightly: Required for code formatting with advanced features

    rustup install nightly
  • Environment Setup: Create a .env file with your Fireblocks credentials

    cp env-sample .env
    # Edit .env with your actual Fireblocks API credentials

§Getting Started

  1. Clone the repository

    git clone https://github.com/CarteraMesh/fireblocks-solana-signer.git
    cd fireblocks-solana-signer
  2. Set up environment

    # Copy and configure environment variables
    cp env-sample .env
    
    # Install Rust nightly for formatting
    rustup install nightly
  3. Build and test

    # Build the project
    cargo build
    
    # Run tests (requires valid Fireblocks credentials in .env)
    cargo test
    
    # Format code (requires nightly)
    cargo +nightly fmt --all

§Code Formatting

This project uses advanced Rust formatting features that require nightly:

# Format all code
cargo +nightly fmt --all

# Check formatting
cargo +nightly fmt --all -- --check

§Running Examples

# Make sure your .env file is configured first
cargo run --example memo

Structs§

Client
A client for interacting with the Fireblocks API.
ClientBuilder
Builder for configuring and creating Fireblocks API clients.
FireblocksSigner
A Solana signer implementation using Fireblocks as the backend signing service.
FireblocksSignerBuilder
Use builder syntax to set the inputs and finish with build().
PollConfig
Configuration for polling Fireblocks transaction status.
PollConfigBuilder
Use builder syntax to set the inputs and finish with build().
TransactionResponse

Enums§

Asset
EnvVar
Environment variables used by the FireblocksSigner.
Error
TransactionStatus
TransactionStatus : The primary status of the transaction. For details, see Primary transaction statuses The primary status of the transaction. For details, see Primary transaction statuses

Constants§

DEFAULT_CLIENT_TIMEOUT
FIREBLOCKS_API
The production Fireblocks API endpoint.
FIREBLOCKS_SANDBOX_API
The sandbox Fireblocks API endpoint for testing.
SOL
SOL_TEST

Traits§

FromStr
Parse a value from a string
VersionedTransactionExtension
Extension trait for VersionedTransaction that adds support for partial signing and address lookup table operations.

Functions§

build_client_and_address_blocking_safe
Builds a Fireblocks client and retrieves the associated Solana address in a tokio-safe manner.
build_client_safe
See build_client_and_address_blocking_safe
keypair_from_seed
Constructs a FireblocksSigner from caller-provided seed entropy.

Type Aliases§

Result
A type alias for std::result::Result with this crate’s Error type.