Documentation Index
Fetch the complete documentation index at: https://mintlify.com/snapshot-labs/sx-monorepo/llms.txt
Use this file to discover all available pages before exploring further.
SDK Overview
@snapshot-labs/sx is the official TypeScript SDK for interacting with Snapshot X governance infrastructure. It provides a unified interface for creating and managing governance actions across multiple blockchain networks and offchain environments.
What is @snapshot-labs/sx?
The SDK is a comprehensive toolkit that enables developers to:
- Create and manage governance spaces
- Submit and vote on proposals
- Execute approved proposals onchain
- Implement custom voting strategies
- Support multiple blockchain networks (Ethereum, Starknet, Polygon, Arbitrum, Optimism, Base, Mantle, and more)
- Work with offchain Snapshot spaces
- Handle cross-chain governance scenarios
Key Features
Multi-Network Support
The SDK supports three execution environments:
- EVM Networks: Ethereum mainnet, Sepolia, Optimism, Polygon, Arbitrum, Base, Mantle, and ApeChain
- Starknet: Native Starknet transactions and cross-chain messaging
- Offchain: Traditional Snapshot spaces with gasless voting
Flexible Client Architecture
The SDK provides specialized clients for different signing and transaction patterns:
- Signature-based clients (
EthereumSig, StarknetSig) for gasless meta-transactions
- Transaction clients (
EthereumTx, StarknetTx) for direct onchain interactions
- Protocol-specific clients for Compound Governor Bravo and OpenZeppelin Governor
Type-Safe TypeScript
Fully typed interfaces with comprehensive TypeScript definitions for all methods and data structures.
Package Structure
The SDK is organized into four main modules:
Clients
Clients handle the creation and submission of governance actions. Available clients include:
import { clients } from '@snapshot-labs/sx';
// EVM clients for Snapshot X spaces
const evmEthereumSig = new clients.EvmEthereumSig(config);
const evmEthereumTx = new clients.EvmEthereumTx(config);
// Starknet clients
const starknetSig = new clients.StarknetSig(config);
const starknetTx = new clients.StarknetTx(config);
// Offchain clients for traditional Snapshot
const offchainEthereumSig = new clients.OffchainEthereumSig();
const offchainStarknetSig = new clients.OffchainStarknetSig();
// Protocol-specific clients
const governorBravo = new clients.GovernorBravoEthereumSig(config);
const openZeppelin = new clients.OpenZeppelinEthereumSig(config);
Strategies
Strategies define how voting power is calculated. The SDK includes built-in strategies for:
- Vanilla: Simple token balance voting
- Comp: Compound-style checkpoint voting
- OZVotes: OpenZeppelin Votes standard
- Whitelist: Merkle tree-based whitelisting
- Cross-chain: Storage proof-based voting from other chains
import { getEvmStrategy, getStarknetStrategy, getOffchainStrategy } from '@snapshot-labs/sx';
// Get strategy implementations
const evmStrategy = getEvmStrategy('vanilla');
const starknetStrategy = getStarknetStrategy('erc20Votes');
const offchainStrategy = getOffchainStrategy('remoteVp');
Executors
Executors determine how approved proposals are executed onchain:
- SimpleQuorumAvatar: Execute through a Gnosis Safe
- SimpleQuorumTimelock: Execute with a time delay
- Axiom: ZK-proof based execution
- Isokratia: Custom execution logic
- EthRelayer: Cross-chain execution via relayer
import { getExecutionData } from '@snapshot-labs/sx';
const executionData = getExecutionData(
'SimpleQuorumAvatar',
executorAddress,
{ transactions: [...] }
);
Utils
Utility functions for common operations:
import { utils } from '@snapshot-labs/sx';
// Encoding utilities
const encoded = utils.encoding.executionHash(...);
// Merkle tree utilities
const tree = utils.merkle.createTree(leaves);
// Storage proof utilities
const proof = utils.storageProofs.getProof(...);
// Byte manipulation
const hex = utils.bytes.bytesToHex(buffer);
Use Cases
Creating a Governance Space
import { clients, evmSepolia } from '@snapshot-labs/sx';
import { Wallet, providers } from 'ethers';
const provider = new providers.JsonRpcProvider('https://rpc.snapshot.org/11155111');
const wallet = new Wallet(privateKey, provider);
const client = new clients.EvmEthereumTx({
networkConfig: evmSepolia
});
const { txId, address } = await client.deploySpace({
signer: wallet,
params: {
controller: wallet.address,
votingDelay: 0,
minVotingDuration: 300,
maxVotingDuration: 86400,
proposalValidationStrategy: {
addr: evmSepolia.strategies['0xC1245C5DCa7885C73E32294140F1e5d30688c202'].type,
params: '0x'
},
proposalValidationStrategyMetadataUri: '',
daoUri: 'https://example.com',
metadataUri: 'ipfs://...',
authenticators: [evmSepolia.authenticators['0x5f9B7D78c9a37a439D78f801E0E339C6E711e260']],
votingStrategies: [{
addr: '0xC1245C5DCa7885C73E32294140F1e5d30688c202',
params: '0x'
}],
votingStrategiesMetadata: ['']
}
});
Submitting a Proposal (EVM)
import { clients, evmMainnet } from '@snapshot-labs/sx';
import { Wallet, providers } from 'ethers';
const provider = new providers.JsonRpcProvider('https://rpc.snapshot.org/1');
const wallet = new Wallet(privateKey, provider);
const client = new clients.EvmEthereumSig({
networkConfig: evmMainnet,
manaUrl: 'https://mana.pizza'
});
const envelope = await client.propose({
signer: wallet,
data: {
space: '0x...',
authenticator: '0x...',
strategies: [{
index: 0,
address: '0x...',
params: '0x'
}],
executionStrategy: {
addr: '0x...',
params: '0x'
},
metadataUri: 'ipfs://...'
}
});
const receipt = await client.send(envelope);
Voting on a Proposal (Starknet)
import { clients, starknetSepolia } from '@snapshot-labs/sx';
import { Account, RpcProvider } from 'starknet';
const provider = new RpcProvider({
nodeUrl: 'https://starknet-sepolia.public.blastapi.io'
});
const account = new Account(provider, address, privateKey);
const client = new clients.StarknetSig({
networkConfig: starknetSepolia,
manaUrl: 'https://mana.pizza'
});
const envelope = await client.vote({
signer: account,
data: {
space: '0x...',
authenticator: '0x...',
strategies: [{
index: 0,
address: '0x...',
params: []
}],
proposal: 1,
choice: 1,
metadataUri: ''
}
});
const receipt = await client.send(envelope);
Offchain Voting
import { clients } from '@snapshot-labs/sx';
import { Wallet } from 'ethers';
const wallet = new Wallet(privateKey);
const client = new clients.OffchainEthereumSig({
networkConfig: { eip712ChainId: 1 }
});
const envelope = await client.vote({
signer: wallet,
data: {
space: 'example.eth',
proposal: '0x...', // IPFS hash
type: 'single-choice',
choice: 1,
reason: 'I support this proposal',
app: 'my-app',
from: wallet.address
}
});
const receipt = await client.send(envelope);
Network Configurations
The SDK provides pre-configured network settings for all supported chains:
import {
// EVM networks
evmMainnet,
evmSepolia,
evmOptimism,
evmPolygon,
evmArbitrum,
evmBase,
evmMantle,
evmApe,
evmCurtis,
// Starknet networks
starknetMainnet,
starknetSepolia,
// Offchain networks
offchainMainnet,
offchainGoerli
} from '@snapshot-labs/sx';
Each network configuration includes:
- Chain ID and block time
- Deployed contract addresses (authenticators, strategies, executors)
- Network-specific parameters (gas settings, etc.)
Next Steps