# Working with Polls

{% hint style="warning" %}
Make sure to implement the [prerequisite code](https://connect.socios.com/interact-with-chiliz-chain/prerequisites), or else the examples in this page will not work!
{% endhint %}

## Prerequisite: Survey3ABI JSON file

{% hint style="success" %}
When working with polls, and for some use-cases (the ones that import `survey3ABI`), you will need the below **survey3ABI.json** file saved in your project folder.&#x20;

Make sure that you import that file in your code in order to achieve the wanted step (the samples already have the necessary `import` code).
{% endhint %}

{% file src="<https://31329255-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FMDcaoJLMj5Y3jzFMTONF%2Fuploads%2FQtuJhi06OOetyXOrvudX%2Fsurvey3ABI.json?alt=media&token=5644de83-6a46-4e72-81ee-52639e99d570>" %}

## Retrieve poll question

You can retrieve any poll question from Chiliz Chain, provided that you have the poll's contract address.

{% hint style="success" %}
Before you run this blockchain call, you need to know the poll's ID.&#x20;

You can use the `GET /polls/` endpoint to retrieve it. [See this documentation](https://connect.socios.com/partner-api/api-reference/polls-api/polls-api-endpoints#get-polls).
{% endhint %}

{% code lineNumbers="true" fullWidth="true" %}

```javascript
import { createPublicClient, http } from 'viem';
import survey3ABI from './survey3ABI.json';

const client = createPublicClient({
  transport: http('YOUR-RPC.com'),
});

const pollAddress = '0xPollAddress'; // Replace with the actual poll contract address

// Returns question text
async function getQuestion() {
  const question = await client.readContract({
    address: pollAddress, // Poll contract address
    abi: survey3ABI, // Poll conttract ABI
    functionName: 'question', // Function to retrieve the question
    args: [],
  });
  return question;
}

// Example usage
getQuestion().then(console.log);
```

{% endcode %}

## Retrieve poll answers

You can retrieve all poll answers from Chiliz Chain, provided that you have the poll's contract address.

{% hint style="warning" %}
As of May 2025, you cannot retrieve poll answers media (such as pictures and videos) via this blockchain call.&#x20;

To do that, you must use the Socios.com API `GET /polls/` endpoint, [documented here](https://connect.socios.com/partner-api/api-reference/polls-api/polls-api-endpoints#get-polls).

We are working on this for the next version of our survey smart contract. This is planned for end of 2025.
{% endhint %}

{% code lineNumbers="true" fullWidth="true" %}

```javascript
import { createPublicClient, http } from 'viem';
import survey3ABI from './survey3ABI.json';

const client = createPublicClient({
  transport: http('YOUR-RPC.com'),
});

const pollAddress = '0xPollAddress'; // Replace with the actual poll contract address

// Returns a list of answers with id, total votes and total amount of tokens used in votes
async function getAnswers() {
  const answers = await client.readContract({
    address: pollAddress, // Poll contract address
    abi: survey3ABI, // Poll conttract ABI
    functionName: 'getAnswers', // Function to retrieve the answers
    args: [],
  });
  return answers;
}

// Example usage
getAnswers().then(console.log);
```

{% endcode %}

## Allow a user to vote on a poll

You can allow a logged-in user to vote a specific Socios.com poll.&#x20;

We recommend to implement [Reown's Wallet Kit](https://connect.socios.com/interact-with-chiliz-chain/prerequisites) (previously called WalletConnect) in order to have your users logged in via their web3 wallet. \
Once they are logged in, if they have a Fan Token of the team the poll belongs to, they will be able to vote on that poll.&#x20;

We also recommend to check whether the user has a token or not before allowing them to vote, because if they don't, their vote will be rejected at the smart contract level.

### Approve token staking

#### Prerequisite: erc20ABI JSON file

{% hint style="success" %}
When approving token staking, you will need the below **erc20ABI.json** file saved in your project folder.&#x20;

Make sure that you import that file in your code in order to achieve the wanted step (the samples already have the necessary `import` code).
{% endhint %}

{% file src="<https://31329255-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FMDcaoJLMj5Y3jzFMTONF%2Fuploads%2F4TYSk9KJGsbbvnEWLF1w%2FFanTokenABI.json?alt=media&token=84a15b49-8e5f-4a5c-9052-9ef9ed717b06>" %}

{% code overflow="wrap" lineNumbers="true" fullWidth="true" %}

```javascript
import { createWalletClient, privateKeyToAccount } from 'viem';
import erc20ABI from './erc20ABI.json';

const privateKey = '0xSenderPrivateKey'; // Replace with the sender's private key
const account = privateKeyToAccount(privateKey);
const walletClient = createWalletClient({
  account,
  transport: http('YOUR-RPC.com'),
});

async function approveTokens(stakingContractAddress) {
  const txHash = await walletClient.writeContract({
    address: '0xYourTokenAddress', // Replace with the ERC-20 token contract address
    abi: erc20ABI,
    functionName: 'approve', // Standard ERC-20 function to approve tokens
    args: [stakingContractAddress, BigInt(1e18)], // For 0 decimal tokens, use BigInt(1) for 1 token
  });
  return txHash;
}

// Example usage. Replace 0xStakingContractAddress with the actual staking smart contract address.
approveTokens('0xStakingContractAddress').then(console.log);
```

{% endcode %}

{% hint style="danger" %}
**Your private key must only be used in server-side code.** \
DO NOT release code on production with your private key shared on front-end side code.
{% endhint %}

### Vote on poll

{% hint style="success" %}
This is a code-based alternative to the `POST /poll/{pollId}/vote` endpoint, which was deprecated from the Socios.com API in Q1 2025.
{% endhint %}

{% code lineNumbers="true" fullWidth="true" %}

```javascript
import { createWalletClient, privateKeyToAccount } from 'viem';

const privateKey = '0xSenderPrivateKey'; // Replace with the sender's private key
const account = privateKeyToAccount(privateKey);
const walletClient = createWalletClient({
  account,
  transport: http('YOUR-RPC.com'),
});

async function vote(id, weight) {
  const txHash = await walletClient.writeContract({
    address: '0xPollAddress', // Replace with the poll contract address
    abi: survey3ABI, // Poll contract ABI
    functionName: 'vote', // Function to cast the vote
    args: [id, BigInt(weight)], // Replace 'id' with answer id and 'weight' with the amount of tokens that should be used to cast the vote
  });
  return txHash;
}

// Example usage
vote('dab3d446-959f-47e7-8789-f618d969de1e', 1).then(console.log);
```

{% endcode %}

{% hint style="danger" %}
**Your private key must only be used in server-side code.** \
DO NOT release code on production with your private key shared on front-end side code.
{% endhint %}

## Retrieve user vote on a poll

You can know whether a user has already voted on a specific poll or not, and if they have then you can retrieve which answer they have selected.

{% hint style="success" %}
This is a code-based alternative to the `GET /poll/{pollId}` endpoint, which was deprecated from the Socios.com API in Q1 2025.
{% endhint %}

{% code lineNumbers="true" fullWidth="true" %}

```javascript
import { createPublicClient, http, keccak256 } from 'viem';
import survey3ABI from './survey3ABI.json';

const client = createPublicClient({
  transport: http('YOUR-RPC.com'),
});
const pollAddress = '0xPollAddress'; // Replace with the actual poll contract address
const userAddress = '0xUserAddress'; // Replace with the user's wallet address

// Returns hashes of answerIds that the user voted on
async function getUserVoteHashes() {
  const votes = await client.readContract({
    address: pollAddress, // Poll contract address
    abi: survey3ABI, // Poll contract ABI
    functionName: 'getUserAnswers', // Function to retrieve the answers that the user voted on
    args: [userAddress], // User's address whose votes you want to fetch
  });
  return votes;
}

// Returns votes in plain text
async function getUserVotesPlainText() {
  // fetch all answers
  const answers = await client.readContract({
    address: pollAddress, // Poll contract address
    abi: survey3ABI, // Poll contract ABI
    functionName: 'getAnswers', // Function to retrieve the answers
    args: [], // User's address whose votes you want to fetch
  });

  // fetch user's votes
  const votes = await client.readContract({
    address: pollAddress, // Poll contract address
    abi: survey3ABI, // Poll conttract ABI
    functionName: 'getUserAnswers', // Function to retrieve the answers that the user voted on
    args: [userAddress], // User's address whose votes you want to fetch
  });

  // filter answers, return the ones that the user voted on
  const plainTextVotes = answers.filter(a => votes.includes(keccak256(a.id)));

  return plainTextVotes;
}

// Example usage
getUserVotesPlainText().then(console.log);
getUserVoteHashes().then(console.log);
```

{% endcode %}
