> ## Documentation Index
> Fetch the complete documentation index at: https://docs.snapshot.box/llms.txt
> Use this file to discover all available pages before exploring further.

# 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](https://github.com/snapshot-labs/sx-monorepo/tree/master/packages/sx.js)

## Quick start

### Installation

Install the latest version of the beta release:

<Tabs>
  <Tab title="NPM">
    ```bash theme={null}
    npm install @snapshot-labs/sx@beta
    ```
  </Tab>

  <Tab title="Yarn">
    ```bash theme={null}
    yarn add @snapshot-labs/sx@beta
    ```
  </Tab>

  <Tab title="Bun">
    ```bash theme={null}
    bun add @snapshot-labs/sx@beta
    ```
  </Tab>
</Tabs>

### 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:

<Tabs>
  <Tab title="EVM clients">
    ```typescript theme={null}
    import { clients, evmSepolia } from '@snapshot-labs/sx';

    const clientConfig = { networkConfig: evmSepolia }

    const client = new clients.EthereumTx(clientConfig);
    const ethSigClient = new clients.EthereumSig(clientConfig);
    ```
  </Tab>

  <Tab title="Starknet clients">
    ```typescript theme={null}
    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_SEPOLIA } });

    const clientConfig = {
      starkProvider,
      manaUrl,
      ethUrl
    };

    const client = new clients.StarkNetTx(clientConfig);
    const starkSigClient = new clients.StarkNetSig(clientConfig);
    ```
  </Tab>
</Tabs>

To learn more about StarkNet's `Provider` object, have a look [here](https://www.starknetjs.com/docs/guides/connect_network).

## Usage

<Info>
  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.
</Info>

### Cast a vote

<Tabs>
  <Tab title="Ethereum transaction (EVM)">
    ```typescript theme={null}
    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);
    ```
  </Tab>

  <Tab title="Ethereum signature (EVM)">
    ```typescript theme={null}
    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);
    ```
  </Tab>

  <Tab title="Starknet transaction">
    ```typescript theme={null}
    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_SEPOLIA } });

    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);
    ```
  </Tab>

  <Tab title="Starknet signature">
    ```typescript theme={null}
    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_SEPOLIA } });

    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);
    ```
  </Tab>
</Tabs>

### Create a proposal

<Tabs>
  <Tab title="Ethereum transaction (EVM)">
    ```typescript theme={null}
    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);
    ```
  </Tab>

  <Tab title="Ethereum signature (EVM)">
    ```typescript theme={null}
    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);
    ```
  </Tab>

  <Tab title="Starknet transaction">
    ```typescript theme={null}
    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_SEPOLIA } });

    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);
    ```
  </Tab>

  <Tab title="Starknet signature">
    ```typescript theme={null}
    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_SEPOLIA } });

    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);
    ```
  </Tab>
</Tabs>

### Update a proposal

<Tabs>
  <Tab title="Ethereum transaction (EVM)">
    ```typescript theme={null}
    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);
    ```
  </Tab>

  <Tab title="Ethereum signature (EVM)">
    ```typescript theme={null}
    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);
    ```
  </Tab>

  <Tab title="Starknet transaction">
    ```typescript theme={null}
    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_SEPOLIA } });

    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);
    ```
  </Tab>

  <Tab title="Starknet signature">
    ```typescript theme={null}
    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_SEPOLIA } });

    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);
    ```
  </Tab>
</Tabs>

### 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.

<Tabs>
  <Tab title="Starknet Whitelist">
    ```typescript theme={null}
    import {
      starknetSepolia1,
      getStarknetStrategy,
    } from '@snapshot-labs/sx';

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

    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
    );
    ```
  </Tab>
</Tabs>

<Info>
  More details coming soon.
</Info>
