All pages
Powered by GitBook
1 of 6

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

UI

The UI is the official interface for Snapshot X.

GitHub

https://github.com/snapshot-labs/sx-monorepo/tree/master/apps/ui

UI

https://snapshot.box

Services

Architecture

To enhance the user experience of interacting with the protocol, we offer a number of additional off-chain services. All of these products are fully open source in the Snapshot Labs Github organization. These are all completely optional and therefore do not introduce any censorship concerns.

  • SX UI: An easy to use interface for interacting with the protocol.

  • SX API: A fast and efficient indexer for all the protocol data.

  • SX.js: A Typescript SDK that can be used to build 3rd Party Integrations with the protocol.

  • : A meta-transaction relayer that can provide a way for proposal creation and vote costs to be sponsored.

Mana

SX.js

SX.js is the official Typescript SDK to interact with Snapshot X. The SDK includes a client for Mana, the meta transaction relayer.

GitHub

https://github.com/snapshot-labs/sx-monorepo/tree/master/packages/sx.js

Quick start

Installation

Install the latest version of the beta release:

Configuration

Clients

Everything happens thanks to the clients objects. Depending on the specific Space or Proposal setup, you may need to use a Transaction or Signature Client. This quick guide demonstrates how to easily set all of them up, both for Ethereum and StarkNet:

To learn more about StarkNet's Provider object, have a look .

Usage

Make sure to use the right client for your use case. The examples below use Sepolia network and its config is imported from the sx.js package.

Cast a vote

Create a proposal

Update a proposal

Get voting power

Address' voting power depends on the strategy used. Below you can see an example of getting voting power for whitelist Voting strategy on Starknet.

More details coming soon.

here
npm install @snapshot-labs/sx@beta
yarn add @snapshot-labs/sx@beta
bun add @snapshot-labs/sx@beta
import { clients, evmSepolia } from '@snapshot-labs/sx';

const clientConfig = { networkConfig: evmSepolia }

const client = new clients.EthereumTx(clientConfig);
const ethSigClient = new clients.EthereumSig(clientConfig);
import { clients } from '@snapshot-labs/sx';
import { Provider, constants } from 'starknet';

const ethUrl = 'https://rpc.snapshot.org/1';
const manaUrl = 'https://mana.pizza';

const starkProvider = new Provider({ sequencer: { network: constants.NetworkName.SN_GOERLI } });

const clientConfig = {
  starkProvider,
  manaUrl,
  ethUrl
};

const client = new clients.StarkNetTx(clientConfig);
const starkSigClient = new clients.StarkNetSig(clientConfig);
import { clients, evmSepolia } from '@snapshot-labs/sx';
import type { Web3Provider } from '@ethersproject/providers';

const clientConfig = { networkConfig: evmSepolia }
const client = new clients.EthereumTx(clientConfig);

const web3 = new Web3Provider(window.ethereum);

const data = {
  space: '0x012b261effbf548f2b9a495d50b81a8a7c1dd941',
  authenticator: '0xba06e6ccb877c332181a6867c05c8b746a21aed1',
  strategies: [
    {
      address: '0xc1245c5dca7885c73e32294140f1e5d30688c202',
      index: 0
    }
  ],
  proposal: 7,
  choice: 1,
  metadataUri: ''
};

const receipt = await client.vote({
  signer: web3.getSigner(),
  envelope: {
    data
  }
});

console.log('Receipt', receipt);
import { clients, evmSepolia } from '@snapshot-labs/sx';
import type { Web3Provider } from '@ethersproject/providers';

const clientConfig = { networkConfig: evmSepolia }
const ethSigClient = new clients.EthereumSig(clientConfig);

const web3 = new Web3Provider(window.ethereum);

const data = {
  space: '0x012b261effbf548f2b9a495d50b81a8a7c1dd941',
  authenticator: '0xba06e6ccb877c332181a6867c05c8b746a21aed1',
  strategies: [
    {
      address: '0xc1245c5dca7885c73e32294140f1e5d30688c202',
      index: 0
    }
  ],
  proposal: 7,
  choice: 1,
  metadataUri: ''
};

const receipt = await ethSigClient.vote({
  signer: web3.getSigner(),
  data
});

console.log('Receipt', receipt);
import { clients } from '@snapshot-labs/sx';
import { Provider, constants } from 'starknet';

const web3 = window.starknet.provider;

const ethUrl = 'https://rpc.snapshot.org/1';
const manaUrl = 'https://mana.pizza';

const starkProvider = new Provider({ sequencer: { network: constants.NetworkName.SN_GOERLI } });

const clientConfig = {
  starkProvider,
  manaUrl,
  ethUrl
};

const client = new clients.StarkNetTx(clientConfig);

const data = {
  space: '0x012b261effbf548f2b9a495d50b81a8a7c1dd941',
  authenticator: '0xba06e6ccb877c332181a6867c05c8b746a21aed1',
  strategies: [
    {
      address: '0xc1245c5dca7885c73e32294140f1e5d30688c202',
      index: 0
    }
  ],
  proposal: 7,
  choice: 1,
  metadataUri: ''
};

const receipt = await client.vote(web3.provider.account, {
    data
});

console.log('Receipt', receipt);
import { clients } from '@snapshot-labs/sx';
import { Provider, constants } from 'starknet';

const web3 = window.starknet.provider;

const ethUrl = 'https://rpc.snapshot.org/1';
const manaUrl = 'https://mana.pizza';

const starkProvider = new Provider({ sequencer: { network: constants.NetworkName.SN_GOERLI } });

const clientConfig = {
  starkProvider,
  manaUrl,
  ethUrl
};

const client = new clients.StarkNetSig(clientConfig);

const data = {
  space: '0x012b261effbf548f2b9a495d50b81a8a7c1dd941',
  authenticator: '0xba06e6ccb877c332181a6867c05c8b746a21aed1',
  strategies: [
    {
      address: '0xc1245c5dca7885c73e32294140f1e5d30688c202',
      index: 0
    }
  ],
  proposal: 7,
  choice: 1,
  metadataUri: ''
};

const envelope = await client.vote({
    signer: web3.provider.account,
    data
});

const receipt = await client.send(envelope);

console.log('Receipt', receipt);
import { clients, evmSepolia } from '@snapshot-labs/sx';
import type { Web3Provider } from '@ethersproject/providers';

const clientConfig = { networkConfig: evmSepolia }
const client = new clients.EthereumTx(clientConfig);

const web3 = new Web3Provider(window.ethereum);

const data = {
  space: '0x012b261effbf548f2b9a495d50b81a8a7c1dd941',
  authenticator: '0xba06e6ccb877c332181a6867c05c8b746a21aed1',
  strategies: [
    {
      address: '0xc1245c5dca7885c73e32294140f1e5d30688c202',
      index: 0
    }
  ],
  executionStrategy: {
    addr: '0x0000000000000000000000000000000000000000',
    params: '0x'
  },
  metadataUri: ''
};

const receipt = await client.propose({
  signer: web3.getSigner(),
  envelope: {
    data
  }
});

console.log('Receipt', receipt);
import { clients, evmSepolia } from '@snapshot-labs/sx';
import type { Web3Provider } from '@ethersproject/providers';

const clientConfig = { networkConfig: evmSepolia }
const client = new clients.EthereumSig(clientConfig);

const web3 = new Web3Provider(window.ethereum);

const data = {
  space: '0x012b261effbf548f2b9a495d50b81a8a7c1dd941',
  authenticator: '0xba06e6ccb877c332181a6867c05c8b746a21aed1',
  strategies: [
    {
      address: '0xc1245c5dca7885c73e32294140f1e5d30688c202',
      index: 0
    }
  ],
  executionStrategy: {
    addr: '0x0000000000000000000000000000000000000000',
    params: '0x'
  },
  metadataUri: ''
};

const receipt = await ethSigClient.propose({
  signer: web3.getSigner(),
    data
});

console.log('Receipt', receipt);
import { clients } from '@snapshot-labs/sx';
import { Provider, constants } from 'starknet';

const web3 = window.starknet.provider;

const ethUrl = 'https://rpc.snapshot.org/1';
const manaUrl = 'https://mana.pizza';

const starkProvider = new Provider({ sequencer: { network: constants.NetworkName.SN_GOERLI } });

const clientConfig = {
  starkProvider,
  manaUrl,
  ethUrl
};

const client = new clients.StarkNetTx(clientConfig);

const data = {
  space: '0x012b261effbf548f2b9a495d50b81a8a7c1dd941',
  authenticator: '0xba06e6ccb877c332181a6867c05c8b746a21aed1',
  strategies: [
    {
      address: '0xc1245c5dca7885c73e32294140f1e5d30688c202',
      index: 0
    }
  ],
  executionStrategy: {
    addr: '0x0000000000000000000000000000000000000000',
    params: '0x'
  },
  metadataUri: ''
};

const receipt = await client.propose(web3.provider.account, {
    data
});

console.log('Receipt', receipt);
import { clients } from '@snapshot-labs/sx';
import { Provider, constants } from 'starknet';

const web3 = window.starknet.provider;

const ethUrl = 'https://rpc.snapshot.org/1';
const manaUrl = 'https://mana.pizza';

const starkProvider = new Provider({ sequencer: { network: constants.NetworkName.SN_GOERLI } });

const clientConfig = {
  starkProvider,
  manaUrl,
  ethUrl
};

const client = new clients.StarkNetSig(clientConfig);

const data = {
  space: '0x012b261effbf548f2b9a495d50b81a8a7c1dd941',
  authenticator: '0xba06e6ccb877c332181a6867c05c8b746a21aed1',
  strategies: [
    {
      address: '0xc1245c5dca7885c73e32294140f1e5d30688c202',
      index: 0
    }
  ],
  executionStrategy: {
    addr: '0x0000000000000000000000000000000000000000',
    params: '0x'
  },
  metadataUri: ''
};

const envelope = await client.propose({
    signer: web3.provider.account,
    data
});

const receipt = await client.send(envelope);

console.log('Receipt', receipt);
import { clients, evmSepolia } from '@snapshot-labs/sx';
import type { Web3Provider } from '@ethersproject/providers';

const clientConfig = { networkConfig: evmSepolia }
const client = new clients.EthereumTx(clientConfig);

const web3 = new Web3Provider(window.ethereum);

const data = {
  space: '0x012b261effbf548f2b9a495d50b81a8a7c1dd941',
  proposal: 1, // proposalId
  authenticator: '0xba06e6ccb877c332181a6867c05c8b746a21aed1',
  executionStrategy: {
    addr: '0x0000000000000000000000000000000000000000',
    params: '0x'
  },
  metadataUri: ''
};

const receipt = await client.updateProposal({
  signer: web3.getSigner(),
  envelope: {
    data
  }
});

console.log('Receipt', receipt);
import { clients, evmSepolia } from '@snapshot-labs/sx';
import type { Web3Provider } from '@ethersproject/providers';

const clientConfig = { networkConfig: evmSepolia }
const client = new clients.EthereumSig(clientConfig);

const web3 = new Web3Provider(window.ethereum);

const data = {
  space: '0x012b261effbf548f2b9a495d50b81a8a7c1dd941',
  proposal: 1, // proposalId
  authenticator: '0xba06e6ccb877c332181a6867c05c8b746a21aed1',
  executionStrategy: {
    addr: '0x0000000000000000000000000000000000000000',
    params: '0x'
  },
  metadataUri: ''
};

const receipt = await ethSigClient.updateProposal({
  signer: web3.getSigner(),
  envelope: {
    data
  }
});

console.log('Receipt', receipt);
import { clients } from '@snapshot-labs/sx';
import { Provider, constants } from 'starknet';

const web3 = window.starknet.provider;

const ethUrl = 'https://rpc.snapshot.org/1';
const manaUrl = 'https://mana.pizza';

const starkProvider = new Provider({ sequencer: { network: constants.NetworkName.SN_GOERLI } });

const clientConfig = {
  starkProvider,
  manaUrl,
  ethUrl
};

const client = new clients.StarkNetTx(clientConfig);

const data = {
  space: '0x012b261effbf548f2b9a495d50b81a8a7c1dd941',
  proposal: 1, // proposalId
  authenticator: '0xba06e6ccb877c332181a6867c05c8b746a21aed1',
  executionStrategy: {
    addr: '0x0000000000000000000000000000000000000000',
    params: '0x'
  },
  metadataUri: ''
};

const receipt = await client.updateProposal(web3.provider.account, {
    data
});

console.log('Receipt', receipt);
import { clients } from '@snapshot-labs/sx';
import { Provider, constants } from 'starknet';

const web3 = window.starknet.provider;

const ethUrl = 'https://rpc.snapshot.org/1';
const manaUrl = 'https://mana.pizza';

const starkProvider = new Provider({ sequencer: { network: constants.NetworkName.SN_GOERLI } });

const clientConfig = {
  starkProvider,
  manaUrl,
  ethUrl
};

const client = new clients.StarkNetSig(clientConfig);

const data = {
  space: '0x012b261effbf548f2b9a495d50b81a8a7c1dd941',
  proposal: 1, // proposalId
  authenticator: '0xba06e6ccb877c332181a6867c05c8b746a21aed1',
  executionStrategy: {
    addr: '0x0000000000000000000000000000000000000000',
    params: '0x'
  },
  metadataUri: ''
};

const envelope = await client.updateProposal({
    signer: web3.provider.account,
    data
});

const receipt = await client.send(envelope);

console.log('Receipt', receipt);
import {
  starknetGoerli1,
  getStarknetStrategy,
} from '@snapshot-labs/sx';

const clientConfig = {
  starkProvider,
  ethUrl,
  networkConfig: starknetGoerli1
};

const address = '0xe3ca14dcb7862116bbbe4331a9927c6693b141aa8936bb76e2bdfa4b551a52';
const voterAddress = '0x556B14CbdA79A36dC33FcD461a04A5BCb5dC2A70';
const strategyMetadata = {
    "tree": [
        {
            "type": 1,
            "address": "0x556B14CbdA79A36dC33FcD461a04A5BCb5dC2A70",
            "votingPower": "10"
        }
    ]
}
const timestamp = 1703090187
const strategyParams = [
    "0xe3ca14dcb7862116bbbe4331a9927c6693b141aa8936bb76e2bdfa4b551a52"
]

const strategy = getStarknetStrategy(address, clientConfig.networkConfig);

const vp = await strategy.getVotingPower(
  address,
  voterAddress,
  strategyMetadata,
  timestamp,
  strategyParams,
  clientConfig
);

Mana

Mana is a meta-transaction relayer that allows users to interact with Snapshot X without paying gas fee. This service works in conjunction with signature based Snapshot X . Users sign a meta transaction in the SX UI and then the relayer submits each encoded transaction along with its signature to the signature authenticator. If the signature is valid, then the transaction will be forwarded to the relevant space contract.

The system included a mechanism that allows DAOs to fund the transactions sent by the relayer, enabling the free end user experience. However importantly, users can directly interact with Snapshot X and therefore do not rely on trusting the relayer to not censor votes. Additionally, Anyone can run a relayer if they want to take over the sponsoring of transactions.

Note that currently Mana only supports proposal creation, proposal updates, and vote casting transactions. It does not currently support proposal execution or space controller actions.

GitHub

https://github.com/snapshot-labs/sx-monorepo/tree/master/apps/mana

Public API

https://mana.box

authenticators

API

The API indexes Snapshot X data. Specifically, it monitors events emitted by spaces and space factories so that votes, proposals, and the deployment of new spaces can be tracked. Anyone can run the API. It uses and support multiple chains.

GitHub

Public APIs

Mainnets: https://api.snapshot.box Testnets: https://testnet-api.snapshot.box

Checkpoint
https://github.com/snapshot-labs/sx-monorepo/tree/master/apps/api