Overview
@snapshot-labs/sx is the official TypeScript SDK for Snapshot X governance protocol. It provides unified interfaces for creating, voting on, and executing governance proposals across multiple blockchain networks and protocols.
The package is published on npm at version 0.1.10 and supports both ESM and CommonJS.
Installation
Install via npm or yarn:
npm install @snapshot-labs/sx
yarn add @snapshot-labs/sx
Main Exports
The SDK is organized into several modules:
Clients
Clients provide protocol-specific interfaces for interacting with governance contracts:
import { clients } from '@snapshot-labs/sx' ;
// Starknet protocol clients
const ethTx = new clients . EthereumTx ( config );
const ethSig = new clients . EthereumSig ( config );
const starknetTx = new clients . StarknetTx ( config );
const starknetSig = new clients . StarknetSig ( config );
const l1Executor = new clients . L1Executor ( config );
const herodotus = new clients . HerodotusController ( config );
// EVM protocol clients
const evmTx = new clients . EvmEthereumTx ( config );
const evmSig = new clients . EvmEthereumSig ( config );
// Governor Bravo (Compound) clients
const bravoTx = new clients . GovernorBravoEthereumTx ( config );
const bravoSig = new clients . GovernorBravoEthereumSig ( config );
// OpenZeppelin Governor clients
const ozTx = new clients . OpenZeppelinEthereumTx ( config );
const ozSig = new clients . OpenZeppelinEthereumSig ( config );
// Offchain (Snapshot) clients
const offchainEth = new clients . OffchainEthereumSig ( config );
const offchainStark = new clients . OffchainStarknetSig ( config );
Tx clients handle transaction submission, while Sig clients handle signature generation for gasless voting.
Strategies
Voting power calculation strategies for different governance systems:
import { getEvmStrategy , getStarknetStrategy , getOffchainStrategy } from '@snapshot-labs/sx' ;
// EVM strategies
const evmStrategy = getEvmStrategy ( 'vanilla' , {
address: '0x...'
});
// Available EVM strategies:
// - vanilla: Basic token balance
// - ozVotes: OpenZeppelin Votes
// - comp: Compound-style checkpoints
// - merkleWhitelist: Whitelist-based
// - apeGas: ApeChain gas token
// Starknet strategies
const starknetStrategy = getStarknetStrategy ( 'erc20Votes' , {
address: '0x...'
});
// Available Starknet strategies:
// - vanilla: Basic token balance
// - erc20Votes: Starknet Votes standard
// - evmSlotValue: Cross-chain EVM storage proofs
// - ozVotesStorageProof: OpenZeppelin Votes with proofs
// - merkleWhitelist: Whitelist-based
// Offchain strategies
const offchainStrategy = getOffchainStrategy ( 'remote-vp' , {
url: 'https://...'
});
Executors
Execution strategies for onchain proposal actions:
import { getExecutionData } from '@snapshot-labs/sx' ;
const executionData = getExecutionData (
'SimpleQuorumAvatar' ,
executorAddress ,
{
transactions: [
{
to: '0x...' ,
value: '0' ,
data: '0x...' ,
operation: 0
}
]
}
);
Available executor types:
SimpleQuorumVanilla - Basic execution
SimpleQuorumAvatar - Gnosis Safe Avatar
SimpleQuorumTimelock - Timelock-based
EthRelayer - Cross-chain relayer
Axiom - Axiom-based execution
Isokratia - Isokratia execution
Utilities
Helper functions for encoding, storage proofs, and more:
import { utils } from '@snapshot-labs/sx' ;
// Encoding utilities
const encoded = utils . encoding . encodeProposal ( proposal );
// Storage proof utilities
const proof = await utils . storageProofs . getStorageProof ( ... );
Example Usage
Creating a Proposal (Starknet)
packages/sx.js/src/clients/starknet/ethereum-tx/index.ts
import { Signer } from '@ethersproject/abstract-signer' ;
import { Contract } from '@ethersproject/contracts' ;
import { clients } from '@snapshot-labs/sx' ;
const signer : Signer = /* your signer */ ;
const config = {
starknetCommit: '0x...' , // L1 commit contract
starknetCore: '0x...' , // L1 Starknet core
ethereumExecutor: '0x...'
};
const client = new clients . EthereumTx ( config );
await client . propose ({
signer ,
envelope: {
space: '0x...' ,
authenticator: '0x...' ,
strategies: [
{
address: '0x...' ,
params: []
}
],
executionStrategy: {
address: '0x...' ,
params: []
},
metadataUri: 'ipfs://...'
},
author: '0x...' ,
executionStrategy: {
address: '0x...' ,
params: []
},
userProposalValidationParams: [],
metadataUri: 'ipfs://...'
});
Voting on a Proposal
await client . vote ({
signer ,
envelope: {
space: '0x...' ,
authenticator: '0x...'
},
voter: '0x...' ,
proposalId: 1 ,
choice: 1 , // 1 = For, 2 = Against, 3 = Abstain
votingStrategies: [
{
index: 0 ,
params: []
}
],
metadataUri: 'ipfs://...'
});
Network Support
EVM Networks
Ethereum Mainnet
Ethereum Sepolia
Optimism
Polygon
Arbitrum
Base
Mantle
ApeChain
Starknet
Starknet Mainnet
Starknet Sepolia
Protocol Support
The SDK supports multiple governance protocols:
Snapshot X - Hybrid onchain/offchain governance
Compound Governor (Governor Bravo) - Compound-style governance
OpenZeppelin Governor - OpenZeppelin Governance standard
Snapshot Offchain - Gasless offchain voting
Package Scripts
From the package.json:
{
"scripts" : {
"dev" : "tsc -w -p tsconfig.esnext.json" ,
"build" : "tsc -p tsconfig.esnext.json && tsc -p tsconfig.cjs.json" ,
"typecheck" : "tsc --noEmit" ,
"test" : "vitest run test/unit" ,
"test:integration" : "./test/run-integration-tests.sh" ,
"test:integration:starknet" : "vitest run test/integration/starknet" ,
"test:integration:evm" : "vitest run test/integration/evm"
}
}
Dependencies
Core dependencies include:
Ethers.js v5 - Ethereum interactions
Starknet.js 7.6.4 - Starknet interactions
micro-starknet - Starknet utilities
@openzeppelin/merkle-tree - Merkle proof generation
@shutter-network/shutter-crypto - Shutter encryption
TypeScript Support
Fully typed with TypeScript 5.8+. All types are exported from the main package:
import type { Propose , Vote , UpdateProposal , Envelope } from '@snapshot-labs/sx' ;
Repository
Source code: snapshot-labs/sx-monorepo
Package directory: packages/sx.js
License
MIT