Setup mainnet example with DAI

This commit is contained in:
Franck 2021-12-21 15:17:23 +11:00
parent ad16693915
commit 0e15e7e6a6
No known key found for this signature in database
GPG Key ID: A82ED75A8DFC50A4
14 changed files with 377 additions and 0 deletions

View File

@ -0,0 +1,5 @@
{
"extends": [
"../../.eslintrc.json"
]
}

View File

@ -0,0 +1,8 @@
{
"spec": "test/**/*.test.{ts,tsx}",
"require": "ts-node/register",
"watchExtensions": "ts",
"extension": "ts",
"timeout": 3000,
"file": "./test/setup.ts"
}

View File

@ -0,0 +1,72 @@
# DappConnect Poll SDK Example
This package is example usage of WakuPolling
Example uses usedapp for exposing web3 provider
For using usedapp please see usedapp docs
## creating WakuPolling object
to create waku polling object you can just use react hook
```
const wakuPolling = useWakuPolling(
appName,
tokenaddress,
library,
multicallAddress
)
```
it is a good idea for token address and multicall address to be dependent on current chainId.
useWakuPolling creates a new WakuPolling object whenever chainId changes.
## creating new poll
to create new poll you can use `createTimedPoll` function from WakuPolling class
```
wakuPolling.createTimedPoll(
question,
answers,
selectedType,
undefined,
endTime
)
```
If you want you can use already created modal component for creating polls
```
const [showPollCreation, setShowPollCreation] = useState(false)
.
.
.
{showPollCreation && (
<PollCreation wakuPolling={wakuPolling} setShowPollCreation={setShowPollCreation} theme={theme} />
)}
```
### showing polls
to show list of polls you can either use `PollList` component from polling-component
```
<PollList wakuPolling={wakuPolling} account={account} theme={theme} />
```
If you want to create your own react component please use
```
usePollList(wakuPolling: WakuPolling | undefined)
```
Which returns memoized DetailedTimedPoll[] array.
Waku polling also exposes `getDetailedTimedPolls`
```
const DetailedTimedPolls = await wakuPolling.getDetailedTimedPolls()
```

View File

@ -0,0 +1,62 @@
{
"name": "@dappconnect/mainnet-poll-sdk-example",
"version": "0.1.0",
"main": "dist/cjs/src/index.js",
"module": "dist/esm/src/index.js",
"types": "dist/esm/src/index.d.ts",
"license": "MIT",
"watch": {
"build": {
"patterns": ["src"],
"extensions": "ts,tsx",
"runOnChangeOnly": false
}
},
"scripts": {
"watch": "yarn npm-watch",
"clean:all": "yarn clean && rimraf node_modules/",
"clean": "rimraf dist/",
"copy-assets": "yarn copy-files:cjs && yarn copy-files:esm",
"copy-files:cjs": "copyfiles -u 1 src/**/*.svg src/**/*.png dist/cjs/src",
"copy-files:esm": "copyfiles -u 1 src/**/*.svg src/**/*.png dist/esm/src",
"build": "yarn build:all && yarn copy-assets",
"build:all": "yarn run build:esm && yarn run build:cjs",
"build:esm": "tsc --module es2020 --target es2017 --outDir dist/esm",
"build:cjs": "tsc --outDir dist/cjs",
"test": "mocha -r jsdom-global/register",
"lint": "yarn lint:prettier --check && yarn lint:eslint",
"lint:fix": "yarn lint:prettier --write && yarn lint:eslint --fix",
"lint:eslint": "eslint './{src,test}/**/*.{ts,tsx}'",
"lint:prettier": "yarn prettier './{src,test}/**/*.{ts,tsx}'"
},
"dependencies": {
"@dappconnect/vote-poll-sdk-core": "^0.1.0",
"@dappconnect/poll-sdk-react-components": "^0.1.0",
"@dappconnect/poll-sdk-react-hooks": "^0.1.0",
"@dappconnect/vote-poll-sdk-react-components": "^0.1.0",
"@usedapp/core": "^0.4.7",
"ethers": "^5.4.4",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-router-dom": "^5.2.0",
"styled-components": "^5.3.0"
},
"devDependencies": {
"@types/chai": "^4.2.21",
"@types/mocha": "^9.0.0",
"@types/react": "^17.0.16",
"@types/styled-components": "^5.1.12",
"@typescript-eslint/eslint-plugin": "^4.29.0",
"@typescript-eslint/parser": "^4.29.0",
"chai": "^4.3.4",
"copyfiles": "^2.4.1",
"eslint": "^7.32.0",
"jsdom": "^16.7.0",
"jsdom-global": "^3.0.2",
"mocha": "^9.0.3",
"npm-watch": "^0.11.0",
"rimraf": "^3.0.2",
"ts-node": "^10.1.0",
"typescript": "^4.3.5"
}
}

View File

@ -0,0 +1 @@
module.exports = require('../../.prettierrc.json')

View File

@ -0,0 +1 @@
/* /index.html 200

View File

@ -0,0 +1,14 @@
declare module '*.svg' {
const url: string
export default url
}
declare module '*.jpg' {
const url: string
export default url
}
declare module '*.png' {
const url: string
export default url
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@ -0,0 +1,79 @@
import React, { useState, useEffect } from 'react'
import { useConfig, useEthers } from '@usedapp/core'
import styled from 'styled-components'
import { PollList, PollCreation } from '@dappconnect/poll-sdk-react-components'
import { JsonRpcSigner } from '@ethersproject/providers'
import { useWakuPolling } from '@dappconnect/poll-sdk-react-hooks'
import { Modal, Networks, CreateButton } from '@dappconnect/vote-poll-sdk-react-components'
import { Theme } from '@dappconnect/vote-poll-sdk-react-components/dist/esm/src/style/themes'
type WakuPollingProps = {
appName: string
signer: JsonRpcSigner | undefined
theme: Theme
tokenAddress: string
}
export function WakuPolling({ appName, signer, theme, tokenAddress }: WakuPollingProps) {
const { activateBrowserWallet, account, library, chainId } = useEthers()
const config = useConfig()
const [showPollCreation, setShowPollCreation] = useState(false)
const [selectConnect, setSelectConnect] = useState(false)
const wakuPolling = useWakuPolling(
appName,
tokenAddress,
library,
config?.multicallAddresses?.[chainId ?? 1337]
)
return (
<Wrapper>
{showPollCreation && signer && (
<PollCreation wakuPolling={wakuPolling} setShowPollCreation={setShowPollCreation} theme={theme} />
)}
{account ? (
<CreateButton theme={theme} disabled={!signer} onClick={() => setShowPollCreation(true)}>
Create a poll
</CreateButton>
) : (
<CreateButton
theme={theme}
onClick={() => {
if ((window as any)?.ethereum) {
activateBrowserWallet()
} else setSelectConnect(true)
}}
>
Connect to vote
</CreateButton>
)}
{selectConnect && (
<Modal heading="Connect" theme={theme} setShowModal={setSelectConnect}>
<Networks />
</Modal>
)}
<PollList wakuPolling={wakuPolling} account={account} theme={theme} />
</Wrapper>
)
}
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;
}
`

View File

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="icon" href="/favicon.ico" />
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0,minimum-scale=1" />
<link rel="icon" type="image/svg+xml" sizes="any" href="../src/assets/images/pollingIcon.svg" />
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />
<title>Polling Dapp</title>
</head>
<body>
<div id="root"></div>
<noscript>You need to enable JavaScript to run this app.</noscript>
<script type="module" src="/index.js"></script>
</body>
</html>

View File

@ -0,0 +1,87 @@
import React, { useEffect, useState } from 'react'
import styled from 'styled-components'
import { DAppProvider, ChainId, useEthers } from '@usedapp/core'
import { DEFAULT_CONFIG } from '@usedapp/core/dist/cjs/src/model/config/default'
import { WakuPolling } from './components/WakuPolling'
import { TopBar, GlobalStyle } from '@dappconnect/vote-poll-sdk-react-components'
import pollingIcon from './assets/images/pollingIcon.png'
import { JsonRpcSigner } from '@ethersproject/providers'
import { orangeTheme } from '@dappconnect/vote-poll-sdk-react-components/dist/esm/src/style/themes'
import ReactDOM from "react-dom"
import {BrowserRouter} from "react-router-dom"
import {Route, Switch} from "react-router"
const daiTokenContract = "0x6B175474E89094C44Da98b954EedeAC495271d0F";
const config = {
readOnlyChainId: ChainId.Mainnet,
readOnlyUrls: {
[ChainId.Mainnet]: 'https://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 Polling({tokenAddress}: {tokenAddress: string}) {
const { account, library, activateBrowserWallet, deactivate } = useEthers()
const [signer, setSigner] = useState<undefined | JsonRpcSigner>(undefined)
useEffect(() => {
setSigner(library?.getSigner())
}, [account])
return (
<Wrapper>
<TopBar
logo={pollingIcon}
logoWidth={84}
title={'Polling Dapp for DAI users'}
theme={orangeTheme}
activate={activateBrowserWallet}
account={account}
deactivate={deactivate}
/>
<WakuPolling theme={orangeTheme} appName={'testApp_'} signer={signer} tokenAddress={tokenAddress} />
</Wrapper>
)
}
export function DaiPollingPage() {
return (
<Page>
<GlobalStyle />
<DAppProvider config={config}>
<Polling tokenAddress={daiTokenContract}/>
</DAppProvider>
</Page>
)
}
const Page = styled.div`
height: 100%;
width: 100%;
`
const Wrapper = styled.div`
height: 100%;
width: 100%;
`
ReactDOM.render(
<div style={{ height: '100%' }}>
<BrowserRouter>
<Switch>
<Route exact path="/dai" component={DaiPollingPage} />
</Switch>
</BrowserRouter>
</div>,
document.getElementById('root')
)

View File

@ -0,0 +1,7 @@
import { expect } from 'chai'
describe('test react-components', () => {
it('foo', async () => {
expect('Hello world').to.eq('Hello world')
})
})

View File

@ -0,0 +1,25 @@
{
"compilerOptions": {
"outDir": "dist",
"jsx":"react",
"esModuleInterop": true,
"moduleResolution": "node",
"resolveJsonModule": true,
"skipLibCheck": true,
"downlevelIteration": true,
"strict": true,
"composite": true,
"declaration": true,
"sourceMap": true,
"declarationMap": true,
"module": "commonjs",
"forceConsistentCasingInFileNames": true,
"target": "es6",
"typeRoots": [ "./types", "./node_modules/@types", "../../node_modules/@types"]
},
"include": [
"src",
"src/**/*.json",
"test"
]
}