Add Poll SDK tutorial (#15)
@ -32,7 +32,7 @@ params:
|
||||
BookTheme: 'dark'
|
||||
BookToC: true
|
||||
BookSection: 'docs'
|
||||
BookDateFormat: '2006/02/01'
|
||||
BookDateFormat: 'Jan 2, 2006'
|
||||
BookSearch: true
|
||||
|
||||
# GitHub edit links
|
||||
|
83
content/docs/guides/vote_poll_sdk/_index.md
Normal file
@ -0,0 +1,83 @@
|
||||
---
|
||||
weight: 100
|
||||
---
|
||||
# WakuConnect Vote & Poll SDK
|
||||
|
||||
The WakuConnect Vote & Poll SDK enables developers to add Waku powered polling and voting features to their dApp.
|
||||
|
||||
The repository can be found on GitHub: https://github.com/status-im/wakuconnect-vote-poll-sdk.
|
||||
|
||||
The SDK can be used in two different ways:
|
||||
to vote (commitment to the blockchain) or poll (no interaction with the blockchain).
|
||||
|
||||
For both functionalities, only ERC-20 token holders can create or answer polls/votes.
|
||||
The developer using the SDK can configure which ERC-20 token contract is used.
|
||||
|
||||
## Packages
|
||||
|
||||
### Common
|
||||
|
||||
- `@waku/vote-poll-sdk-core`: Common libraries to both vote and poll functionalities.
|
||||
- `@waku/vote-poll-sdk-react-components`: Common React components to both vote and poll functionalities.
|
||||
|
||||
### Vote
|
||||
|
||||
- `@waku/vote-sdk-react-components`: React components.
|
||||
- `@waku/vote-sdk-react-hooks`: React hooks.
|
||||
- `@waku/vote-sdk-contracts`: Solidity contracts.
|
||||
|
||||
### Poll
|
||||
|
||||
- `@waku/poll-sdk-react-components`: React components.
|
||||
- `@waku/poll-sdk-react-hooks`: React hooks.
|
||||
|
||||
## WakuConnect Vote SDK
|
||||
|
||||
The WakuConnect Vote SDK allows you to leverage Waku to save gas fees for most voters.
|
||||
It uses Waku to broadcast and aggregates votes.
|
||||
Most token holders will not need to spend gas to vote.
|
||||
|
||||
Only the party that starts an election and submit the end results need to interact with the blockchain.
|
||||
|
||||
For example, it can be used by a DAO to manage proposals
|
||||
where proposal creation and vote results must be committed to the blockchain.
|
||||
|
||||
With WakuConnect Vote SDK, the DAO could be the one spending gas when creating the proposal and committing the votes,
|
||||
whereas the token holders do not spend gas when voting.
|
||||
|
||||
### Documentation
|
||||
|
||||
{{< hint info >}}
|
||||
The documentation effort is currently in progress.
|
||||
It is tracked with [status-im/wakuconnect-vote-poll-sdk#11](https://github.com/status-im/wakuconnect-vote-poll-sdk/issues/11).
|
||||
Contributions are welcome.
|
||||
{{< /hint >}}
|
||||
|
||||
You can find more information about the Vote SDK's properties in the [README](https://github.com/status-im/wakuconnect-vote-poll-sdk#wakuconnect-vote-sdk).
|
||||
|
||||
A working example dApp that includes voting feature can be found in the [repo](https://github.com/status-im/wakuconnect-vote-poll-sdk/tree/main/packages/example).
|
||||
|
||||
{{< hint warning >}}
|
||||
However, as the example is part of the yarn workspace, there may be issues with undeclared dependencies with this example.
|
||||
Tracked with [status-im/wakuconnect-vote-poll-sdk#11](https://github.com/status-im/wakuconnect-vote-poll-sdk/issues/11).
|
||||
{{< /hint >}}
|
||||
|
||||
## WakuConnect Poll SDK
|
||||
|
||||
The WakuConnect Poll SDK allows you to leverage Waku and enable token holder to create, answer and view polls.
|
||||
The polls are not committed to the blockchain and hence do not cost gas.
|
||||
|
||||
As the polls use Waku, they do maintain properties expected from dApps: decentralized and censorship-resistant.
|
||||
|
||||
The high-level functionality is as follows:
|
||||
|
||||
- To create a poll, a token holder sends a message with the poll questions, possible answers and an end time over Waku,
|
||||
- Other users receive the poll creation message and can view the poll,
|
||||
- To avoid spam, only polls created by actual token holders are displayed,
|
||||
- Any token holder can send their poll answer over Waku,
|
||||
- Each user cumulates poll responses from Waku and can view them,
|
||||
- To avoid spam, only responses sent by actual token holders are displayed.
|
||||
|
||||
### Documentation
|
||||
|
||||
See [How to Use the WakuConnect Poll SDK](./poll_sdk).
|
116
content/docs/guides/vote_poll_sdk/poll_sdk/01_create_dapp.md
Normal file
@ -0,0 +1,116 @@
|
||||
---
|
||||
title: Create the DApp and Install Dependencies
|
||||
date: 2022-01-03T11:00:00+1100
|
||||
weight: 11
|
||||
---
|
||||
|
||||
# Create the DApp and Install Dependencies
|
||||
|
||||
## Create React App
|
||||
|
||||
Create the new React app using the `typescript` template.
|
||||
Install the Waku Poll SDK packages.
|
||||
|
||||
In this guide, we use [useDApp](https://usedapp.io/) to access the blockchain.
|
||||
|
||||
|
||||
```shell
|
||||
yarn create react-app poll-dapp-ts --template typescript
|
||||
cd poll-dapp-ts
|
||||
yarn add \
|
||||
@waku/poll-sdk-react-components @waku/poll-sdk-react-hooks @waku/vote-poll-sdk-react-components \
|
||||
@usedapp/core@0.4.7
|
||||
yarn add -D @types/styled-components
|
||||
```
|
||||
|
||||
{{< hint warning >}}
|
||||
`@usedapp/core` must be frozen to version `0.4.7` due to incompatibility between minor versions of `ethers`.
|
||||
|
||||
WakuConnect Vote & Poll SDK will be upgraded to the latest version of `@usedapp/core` and `ethers` once `ethereum-waffle`
|
||||
is released with the [latest version of `ethers`](https://github.com/EthWorks/Waffle/pull/603).
|
||||
{{< /hint >}}
|
||||
|
||||
## Setup polyfills
|
||||
|
||||
A number of Web3 dependencies need polyfills.
|
||||
Said polyfills must be explicitly declared when using webpack 5.
|
||||
|
||||
The latest `react-scripts` version uses webpack 5.
|
||||
|
||||
We will describe below a method to configure polyfills when using `create-react-app`/`react-scripts` or webpack 5.
|
||||
This may not be necessary if you do not use `react-scripts` or if you use webpack 4.
|
||||
|
||||
Start by installing the polyfill libraries:
|
||||
|
||||
```shell
|
||||
yarn add assert buffer crypto-browserify stream-browserify
|
||||
```
|
||||
|
||||
### Webpack 5
|
||||
|
||||
If you directly use webpack 5,
|
||||
then you can inspire yourself from this [webpack.config.js](https://github.com/status-im/wakuconnect-vote-poll-sdk/blob/main/examples/mainnet-poll/webpack.config.js).
|
||||
|
||||
### React-App-Rewired
|
||||
|
||||
An alternative is to let `react-scripts` control the webpack 5 config and only override some elements using `react-app-rewired`.
|
||||
|
||||
Install `react-app-rewired`:
|
||||
|
||||
```shell
|
||||
yarn add -D react-app-rewired
|
||||
```
|
||||
|
||||
Create a `config-overrides.js` file at the root of your app:
|
||||
|
||||
```js
|
||||
const webpack = require('webpack');
|
||||
|
||||
module.exports = (config) => {
|
||||
|
||||
// Override webpack 5 config from react-scripts to load polyfills
|
||||
if (!config.resolve) config.resolve = {};
|
||||
if (!config.resolve.fallback) config.resolve.fallback = {};
|
||||
Object.assign(config.resolve.fallback, {
|
||||
"buffer": require.resolve("buffer"),
|
||||
"crypto": require.resolve("crypto-browserify"),
|
||||
"stream": require.resolve("stream-browserify"),
|
||||
"assert": require.resolve("assert")
|
||||
}
|
||||
)
|
||||
|
||||
if (!config.plugins) config.plugins = []
|
||||
config.plugins.push(
|
||||
new webpack.ProvidePlugin({
|
||||
Buffer: ['buffer', 'Buffer'],
|
||||
}));
|
||||
|
||||
return config;
|
||||
}
|
||||
```
|
||||
|
||||
Use `react-app-rewired` in the `package.json`, instead of `react-scripts`:
|
||||
|
||||
```
|
||||
"scripts": {
|
||||
- "start": "react-scripts start",
|
||||
- "build": "react-scripts build",
|
||||
- "test": "react-scripts test",
|
||||
- "eject": "react-scripts eject"
|
||||
+ "start": "react-app-rewired start",
|
||||
+ "build": "react-app-rewired build",
|
||||
+ "test": "react-app-rewired test",
|
||||
+ "eject": "react-app-rewired eject"
|
||||
},
|
||||
```
|
||||
|
||||
## Start development server
|
||||
|
||||
You can now start the development server to serve your dApp at http://localhost:3000/ while we code:
|
||||
|
||||
```shell
|
||||
yarn start
|
||||
```
|
||||
|
||||
{{< button relref="./" >}}Back{{< /button >}}
|
||||
{{< button relref="./02_connect_wallet" >}}Next: Connect to the Ethereum Wallet{{< /button >}}
|
201
content/docs/guides/vote_poll_sdk/poll_sdk/02_connect_wallet.md
Normal file
@ -0,0 +1,201 @@
|
||||
---
|
||||
title: Connect to the Ethereum Wallet
|
||||
date: 2022-01-03T11:00:00+1100
|
||||
weight: 12
|
||||
---
|
||||
|
||||
# Connect to the Ethereum Wallet
|
||||
|
||||
{{< hint info >}}
|
||||
This section may be skipped if you are adding the poll feature to an existing dApp
|
||||
that already connects to the user's wallet.
|
||||
{{< /hint >}}
|
||||
|
||||
Delete the template `App` component:
|
||||
|
||||
```shell
|
||||
rm -f App.tsx App.css App.test.tsx
|
||||
```
|
||||
|
||||
## Top bar
|
||||
|
||||
Use `TopBar` component to display wallet information.
|
||||
For that, create a `PollPage` component that includes the top bar and will include the poll elements.
|
||||
The component uses `ethers` to connect to the user's wallet:
|
||||
|
||||
```tsx
|
||||
export function PollPage() {
|
||||
const {account, library, activateBrowserWallet, deactivate} = useEthers()
|
||||
const [signer, setSigner] = useState<undefined | JsonRpcSigner>(undefined)
|
||||
|
||||
useEffect(() => {
|
||||
if (account) {
|
||||
setSigner(library?.getSigner())
|
||||
} else {
|
||||
// Deactivate signer if signed out
|
||||
setSigner(undefined)
|
||||
}
|
||||
}, [account])
|
||||
|
||||
return (
|
||||
<div>
|
||||
<TopBar
|
||||
logo={""}
|
||||
logoWidth={84}
|
||||
title={'Poll dApp'}
|
||||
theme={orangeTheme}
|
||||
activate={activateBrowserWallet}
|
||||
account={account}
|
||||
deactivate={deactivate}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
## Page
|
||||
|
||||
### UseDApp
|
||||
|
||||
Create a `config` variable that contains the Ethereum network parameters:
|
||||
|
||||
```tsx
|
||||
import {ChainId, DAppProvider, useEthers} from '@usedapp/core';
|
||||
import {DEFAULT_CONFIG} from "@usedapp/core/dist/cjs/src/model/config/default";
|
||||
|
||||
const config = {
|
||||
readOnlyChainId: ChainId.Mainnet,
|
||||
readOnlyUrls: {
|
||||
[ChainId.Mainnet]: 'https://mainnet.infura.io/v3/your-infura-token',
|
||||
},
|
||||
multicallAddresses: {
|
||||
1: '0xeefba1e63905ef1d7acba5a8513c70307c1ce441',
|
||||
3: '0x53c43764255c17bd724f74c4ef150724ac50a3ed',
|
||||
1337: process.env.GANACHE_MULTICALL_CONTRACT ?? '0x0000000000000000000000000000000000000000',
|
||||
},
|
||||
supportedChains: [...DEFAULT_CONFIG.supportedChains, 1337],
|
||||
notifications: {
|
||||
checkInterval: 500,
|
||||
expirationPeriod: 50000,
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Replace `your-infura-token` with your [Infura API token](https://infura.io/docs/ethereum).
|
||||
|
||||
### Styled-components
|
||||
|
||||
[`styled-components`](https://styled-components.com/) is used for easy styling.
|
||||
Create a `Wrapper` variable to use in the page component:
|
||||
|
||||
```tsx
|
||||
import styled from 'styled-components'
|
||||
|
||||
const Wrapper = styled.div`
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
`
|
||||
```
|
||||
|
||||
### Render
|
||||
|
||||
Finally, create the `App` component:
|
||||
|
||||
```tsx
|
||||
export function App() {
|
||||
return (
|
||||
<Wrapper>
|
||||
<GlobalStyle/>
|
||||
<DAppProvider config={config}>
|
||||
<PollPage/>
|
||||
</DAppProvider>
|
||||
</Wrapper>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
Your `index.tsx` should now be:
|
||||
|
||||
```tsx
|
||||
import {ChainId, DAppProvider, useEthers} from '@usedapp/core';
|
||||
import {GlobalStyle, TopBar} from '@waku/vote-poll-sdk-react-components';
|
||||
import React, {useEffect, useState} from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import './index.css';
|
||||
import {JsonRpcSigner} from "@ethersproject/providers";
|
||||
import {orangeTheme} from "@waku/vote-poll-sdk-react-components/dist/cjs/src/style/themes";
|
||||
import {DEFAULT_CONFIG} from "@usedapp/core/dist/cjs/src/model/config/default";
|
||||
import styled from 'styled-components'
|
||||
|
||||
const config = {
|
||||
readOnlyChainId: ChainId.Mainnet,
|
||||
readOnlyUrls: {
|
||||
[ChainId.Mainnet]: 'https://mainnet.infura.io/v3/b4451d780cc64a078ccf2181e872cfcf',
|
||||
},
|
||||
multicallAddresses: {
|
||||
1: '0xeefba1e63905ef1d7acba5a8513c70307c1ce441',
|
||||
3: '0x53c43764255c17bd724f74c4ef150724ac50a3ed',
|
||||
1337: process.env.GANACHE_MULTICALL_CONTRACT ?? '0x0000000000000000000000000000000000000000',
|
||||
},
|
||||
supportedChains: [...DEFAULT_CONFIG.supportedChains, 1337],
|
||||
notifications: {
|
||||
checkInterval: 500,
|
||||
expirationPeriod: 50000,
|
||||
},
|
||||
}
|
||||
|
||||
export function PollPage() {
|
||||
const {account, library, activateBrowserWallet, deactivate} = useEthers()
|
||||
const [signer, setSigner] = useState<undefined | JsonRpcSigner>(undefined)
|
||||
|
||||
useEffect(() => {
|
||||
if (account) {
|
||||
setSigner(library?.getSigner())
|
||||
} else {
|
||||
// Deactivate signer if signed out
|
||||
setSigner(undefined)
|
||||
}
|
||||
}, [account])
|
||||
|
||||
return (
|
||||
<div>
|
||||
<TopBar
|
||||
logo={""}
|
||||
logoWidth={84}
|
||||
title={'Poll dApp'}
|
||||
theme={orangeTheme}
|
||||
activate={activateBrowserWallet}
|
||||
account={account}
|
||||
deactivate={deactivate}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export function App() {
|
||||
return (
|
||||
<Wrapper>
|
||||
<GlobalStyle/>
|
||||
<DAppProvider config={config}>
|
||||
<PollPage/>
|
||||
</DAppProvider>
|
||||
</Wrapper>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
const Wrapper = styled.div`
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
`
|
||||
|
||||
ReactDOM.render(
|
||||
<React.StrictMode>
|
||||
<App/>
|
||||
</React.StrictMode>,
|
||||
document.getElementById('root')
|
||||
);
|
||||
```
|
||||
|
||||
{{< button relref="./01_create_dapp" >}}Back{{< /button >}}
|
||||
{{< button relref="./03_create-a-poll_button" >}}Next: Create-A-Poll Button{{< /button >}}
|
@ -0,0 +1,128 @@
|
||||
---
|
||||
title: Create-A-Poll Button
|
||||
date: 2022-01-03T11:00:00+1100
|
||||
weight: 13
|
||||
---
|
||||
|
||||
# Create-A-Poll Button
|
||||
|
||||
Create the `Poll` component,
|
||||
it will allow the user to create a new poll, view polls and answer them.
|
||||
We'll start by adding a button to create a poll.
|
||||
|
||||
```shell
|
||||
mkdir components
|
||||
touch components/Poll.tsx
|
||||
```
|
||||
|
||||
## Styled-components
|
||||
|
||||
Again, create a `Wrapper` for styling:
|
||||
|
||||
```tsx
|
||||
import styled from 'styled-components'
|
||||
|
||||
const Wrapper = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
max-width: 1146px;
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
padding: 150px 32px 50px;
|
||||
width: 100%;
|
||||
@media (max-width: 1146px) {
|
||||
max-width: 780px;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
padding: 132px 16px 32px;
|
||||
}
|
||||
@media (max-width: 425px) {
|
||||
padding: 96px 16px 84px;
|
||||
}
|
||||
`
|
||||
```
|
||||
|
||||
## Button
|
||||
|
||||
Create a button that will display the `PollCreation` component on click.
|
||||
To create a poll, we need access to the wallet,
|
||||
thus the button must be disabled if the wallet is not connected.
|
||||
|
||||
The button is disabled if `signer` is undefined.
|
||||
To give a visual clue to the user, also make the button grey when disabled.
|
||||
|
||||
Upon clicking the button, we set `showPollCreation` to true.
|
||||
`showPollCreation` will control when to render the poll creation modal.
|
||||
|
||||
`components/Poll.tsx`:
|
||||
```tsx
|
||||
import {useState} from 'react'
|
||||
import {JsonRpcSigner, Web3Provider} from '@ethersproject/providers'
|
||||
import {CreateButton} from '@waku/vote-poll-sdk-react-components'
|
||||
import {Theme} from '@waku/vote-poll-sdk-react-components/dist/esm/src/style/themes'
|
||||
|
||||
type PollProps = {
|
||||
signer: JsonRpcSigner | undefined
|
||||
theme: Theme
|
||||
}
|
||||
|
||||
export function Poll({signer, theme}: PollProps) {
|
||||
const [showPollCreation, setShowPollCreation] = useState(false)
|
||||
|
||||
const disabled = !signer;
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
{
|
||||
<CreateButton style={{backgroundColor: disabled ? "lightgrey" : theme.primaryColor}} theme={theme}
|
||||
disabled={disabled}
|
||||
onClick={() => setShowPollCreation(true)}>
|
||||
Create a poll
|
||||
</CreateButton>
|
||||
}
|
||||
</Wrapper>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
Now update the `PollPage` component to render the new `Poll` component:
|
||||
|
||||
`index.tsx`:
|
||||
```tsx
|
||||
export function PollPage() {
|
||||
const {account, library, activateBrowserWallet, deactivate} = useEthers()
|
||||
const [signer, setSigner] = useState<undefined | JsonRpcSigner>(undefined)
|
||||
|
||||
useEffect(() => {
|
||||
if (account) {
|
||||
setSigner(library?.getSigner())
|
||||
} else {
|
||||
// Deactivate signer if signed out
|
||||
setSigner(undefined)
|
||||
}
|
||||
}, [account])
|
||||
|
||||
return (
|
||||
<div>
|
||||
<TopBar
|
||||
logo={""}
|
||||
logoWidth={84}
|
||||
title={'Poll dApp'}
|
||||
theme={orangeTheme}
|
||||
activate={activateBrowserWallet}
|
||||
account={account}
|
||||
deactivate={deactivate}
|
||||
/>
|
||||
<Poll theme={orangeTheme} signer={signer}/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
Now, you have a button:
|
||||
|
||||

|
||||
|
||||
{{< button relref="./02_connect_wallet" >}}Back{{< /button >}}
|
||||
{{< button relref="./04_poll_creation" >}}Next: Poll Creation Component{{< /button >}}
|
112
content/docs/guides/vote_poll_sdk/poll_sdk/04_poll_creation.md
Normal file
@ -0,0 +1,112 @@
|
||||
---
|
||||
title: Poll Creation Component
|
||||
date: 2022-01-03T11:00:00+1100
|
||||
weight: 14
|
||||
---
|
||||
|
||||
# Poll Creation Component
|
||||
|
||||
The Poll SDK provide an off-the-shelf component to create a new poll: `PollCreation`.
|
||||
It takes in a `WakuPolling` hook that can created with `useWakuPolling`.
|
||||
|
||||
`useWakuPolling` takes:
|
||||
- `appName`: Your app name.
|
||||
It is used to generate a unique content topic for your polls.
|
||||
See [How to Choose a Content Topic](/docs/guides/01_choose_content_topic/) for more information.
|
||||
- `tokenAddress`: The address of your ERC-20 token.
|
||||
Only token holders can create and answer polls.
|
||||
- `provider`: The Web3 provider to access the blockchain.
|
||||
- `multicallAddress`: Address to this blockchain's multicall contract.
|
||||
|
||||
Add these parameters to `PollProps` and call `useWakuPolling`.
|
||||
|
||||
`components/Poll.tsx`
|
||||
```tsx
|
||||
import {useState} from 'react'
|
||||
import {useConfig} from '@usedapp/core'
|
||||
import {PollCreation} from '@waku/poll-sdk-react-components'
|
||||
import {JsonRpcSigner, Web3Provider} from '@ethersproject/providers'
|
||||
import {useWakuPolling} from '@waku/poll-sdk-react-hooks'
|
||||
import {CreateButton} from '@waku/vote-poll-sdk-react-components'
|
||||
import {Theme} from '@waku/vote-poll-sdk-react-components/dist/esm/src/style/themes'
|
||||
import {ChainId} from "@usedapp/core/src/constants";
|
||||
|
||||
type PollProps = {
|
||||
appName: string
|
||||
library: Web3Provider | undefined
|
||||
signer: JsonRpcSigner | undefined
|
||||
chainId: ChainId | undefined
|
||||
theme: Theme
|
||||
tokenAddress: string
|
||||
}
|
||||
|
||||
export function Poll({appName, library, signer, chainId, theme, tokenAddress}: PollProps) {
|
||||
const config = useConfig()
|
||||
const [showPollCreation, setShowPollCreation] = useState(false)
|
||||
const wakuPolling = useWakuPolling(appName, tokenAddress, library, config?.multicallAddresses?.[chainId ?? 1337])
|
||||
|
||||
const disabled = !signer;
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
{showPollCreation && signer && (
|
||||
<PollCreation wakuPolling={wakuPolling} setShowPollCreation={setShowPollCreation} theme={theme}/>
|
||||
)}
|
||||
{
|
||||
<CreateButton style={{backgroundColor: disabled ? "lightgrey" : theme.primaryColor}} theme={theme}
|
||||
disabled={disabled}
|
||||
onClick={() => setShowPollCreation(true)}>
|
||||
Create a poll
|
||||
</CreateButton>
|
||||
}
|
||||
</Wrapper>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
Then pass them in `PollPage`.
|
||||
|
||||
In this example, we use `demo-poll-dapp` for the app name and the mainnet SNT token contract for the token address.
|
||||
Replace those with your own.
|
||||
|
||||
`index.tsx`
|
||||
```tsx
|
||||
export function PollPage() {
|
||||
const {account, library, activateBrowserWallet, deactivate, chainId} = useEthers()
|
||||
const [signer, setSigner] = useState<undefined | JsonRpcSigner>(undefined)
|
||||
|
||||
useEffect(() => {
|
||||
if (account) {
|
||||
setSigner(library?.getSigner())
|
||||
} else {
|
||||
// Deactivate signer if signed out
|
||||
setSigner(undefined)
|
||||
}
|
||||
}, [account])
|
||||
|
||||
return (
|
||||
<div>
|
||||
<TopBar
|
||||
logo={""}
|
||||
logoWidth={84}
|
||||
title={'Poll dApp'}
|
||||
theme={orangeTheme}
|
||||
activate={activateBrowserWallet}
|
||||
account={account}
|
||||
deactivate={deactivate}
|
||||
/>
|
||||
<Poll theme={orangeTheme} appName={'demo-poll-dapp'} library={library} signer={signer} chainId={chainId}
|
||||
tokenAddress={'0x744d70FDBE2Ba4CF95131626614a1763DF805B9E'}/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
You can now see the poll creation modal when clicking on the button:
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
{{< button relref="./03_create-a-poll_button" >}}Back{{< /button >}}
|
||||
{{< button relref="./05_poll_list" >}}Next: Poll List Component{{< /button >}}
|
88
content/docs/guides/vote_poll_sdk/poll_sdk/05_poll_list.md
Normal file
@ -0,0 +1,88 @@
|
||||
---
|
||||
title: Poll List Component
|
||||
date: 2022-01-03T11:00:00+1100
|
||||
weight: 15
|
||||
---
|
||||
|
||||
# Poll List Component
|
||||
|
||||
To display existing polls, the `PollList` component is provided.
|
||||
|
||||
Simply add it to the `Poll` function to render it.
|
||||
It needs the `account` variable that can be passed as a property to `Poll`:
|
||||
|
||||
`components/Poll.tsx`:
|
||||
```tsx
|
||||
import {useState} from 'react'
|
||||
import {useConfig} from '@usedapp/core'
|
||||
import {PollCreation, PollList} from '@waku/poll-sdk-react-components'
|
||||
import {JsonRpcSigner, Web3Provider} from '@ethersproject/providers'
|
||||
import {useWakuPolling} from '@waku/poll-sdk-react-hooks'
|
||||
import {CreateButton} from '@waku/vote-poll-sdk-react-components'
|
||||
import {Theme} from '@waku/vote-poll-sdk-react-components/dist/esm/src/style/themes'
|
||||
import {ChainId} from "@usedapp/core/src/constants";
|
||||
|
||||
type PollProps = {
|
||||
appName: string
|
||||
library: Web3Provider | undefined
|
||||
signer: JsonRpcSigner | undefined
|
||||
chainId: ChainId | undefined
|
||||
account: string | null | undefined
|
||||
theme: Theme
|
||||
tokenAddress: string
|
||||
}
|
||||
|
||||
export function Poll({appName, library, signer, chainId, account, theme, tokenAddress}: PollProps) {
|
||||
const config = useConfig()
|
||||
const [showPollCreation, setShowPollCreation] = useState(false)
|
||||
const wakuPolling = useWakuPolling(appName, tokenAddress, library, config?.multicallAddresses?.[chainId ?? 1337])
|
||||
|
||||
const disabled = !signer;
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
{showPollCreation && signer && (
|
||||
<PollCreation wakuPolling={wakuPolling} setShowPollCreation={setShowPollCreation} theme={theme}/>
|
||||
)}
|
||||
{
|
||||
<CreateButton style={{backgroundColor: disabled ? "lightgrey" : theme.primaryColor}} theme={theme}
|
||||
disabled={disabled}
|
||||
onClick={() => setShowPollCreation(true)}>
|
||||
Create a poll
|
||||
</CreateButton>
|
||||
}
|
||||
<PollList wakuPolling={wakuPolling} account={account} theme={theme} />
|
||||
</Wrapper>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
Pass the `account` to `Poll` in `index.tsx`:
|
||||
```tsx
|
||||
<Poll theme={orangeTheme} appName={'demo-poll-dapp'} library={library} signer={signer} chainId={chainId}
|
||||
account={account}
|
||||
tokenAddress={'0x744d70FDBE2Ba4CF95131626614a1763DF805B9E'}/>
|
||||
```
|
||||
|
||||
Et voila!
|
||||
The `PollList` component handles the display of polls:
|
||||
|
||||

|
||||
|
||||
And answering them:
|
||||
|
||||

|
||||
|
||||
You can find the resulting code in the [examples folder](https://github.com/status-im/wakuconnect-vote-poll-sdk/tree/main/examples/mainnet-poll).
|
||||
|
||||
{{< hint info >}}
|
||||
The example above uses webpack 5 instead of react-app-rewired.
|
||||
It also allows passing a token contract address in the url, as described in the [README](https://github.com/status-im/wakuconnect-vote-poll-sdk/blob/main/examples/mainnet-poll/README.md).
|
||||
{{< /hint >}}
|
||||
|
||||
The final gif:
|
||||
|
||||

|
||||
|
||||
|
||||
{{< button relref="./04_poll_creation" >}}Back{{< /button >}}
|
20
content/docs/guides/vote_poll_sdk/poll_sdk/_index.md
Normal file
@ -0,0 +1,20 @@
|
||||
---
|
||||
title: Poll SDK
|
||||
date: 2022-01-03T11:00:00+1100
|
||||
weight: 1
|
||||
---
|
||||
|
||||
# How to Use the WakuConnect Poll SDK
|
||||
|
||||
To demonstrate how to use the WakuConnect Poll SDK in your dApp, we will create a TypeScript React app from scratch.
|
||||
|
||||
You can then adapt the steps depending on your dApp configuration and build setup.
|
||||
|
||||
The resulting code of this guide can be found at
|
||||
https://github.com/status-im/wakuconnect-vote-poll-sdk/tree/main/examples/mainnet-poll.
|
||||
|
||||
Here is a preview of the end result:
|
||||
|
||||

|
||||
|
||||
{{< button relref="./01_create_dapp" >}}Get Started{{< /button >}}
|
BIN
static/assets/poll_sdk/create-a-poll-component.png
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
static/assets/poll_sdk/create-poll-button.png
Normal file
After Width: | Height: | Size: 9.0 KiB |
BIN
static/assets/poll_sdk/listed-polls-with-answer.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
static/assets/poll_sdk/listed-polls.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
static/assets/poll_sdk/poll-created.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
static/assets/poll_sdk/sign-message.png
Normal file
After Width: | Height: | Size: 35 KiB |
BIN
static/assets/poll_sdk/wakuconnect-poll-demo.gif
Normal file
After Width: | Height: | Size: 568 KiB |