Merge pull request #5 from status-im/deploy-example-to-gh
This commit is contained in:
commit
8f9322593c
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"extends": [
|
||||
"../../.eslintrc.json"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"spec": "test/**/*.test.{ts,tsx}",
|
||||
"require": "ts-node/register",
|
||||
"watchExtensions": "ts",
|
||||
"extension": "ts",
|
||||
"timeout": 3000,
|
||||
"file": "./test/setup.ts"
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
# Mainnet DappConnect Poll SDK Example
|
|
@ -0,0 +1,47 @@
|
|||
{
|
||||
"name": "@dappconnect/mainnet-poll-sdk-example",
|
||||
"version": "0.1.0",
|
||||
"main": "index.js",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"clean:all": "yarn clean && rimraf node_modules/",
|
||||
"clean": "rimraf dist/",
|
||||
"build": "rm -rf dist && webpack --mode=production --env ENV=production",
|
||||
"start": "webpack serve --mode=development --env ENV=development --https --port 8181",
|
||||
"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"
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
module.exports = require('../../.prettierrc.json')
|
|
@ -0,0 +1 @@
|
|||
/* /index.html 200
|
|
@ -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 |
|
@ -0,0 +1,74 @@
|
|||
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;
|
||||
}
|
||||
`
|
|
@ -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>
|
|
@ -0,0 +1,91 @@
|
|||
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'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
|
||||
const sntTokenAddress = '0x744d70FDBE2Ba4CF95131626614a1763DF805B9E'
|
||||
|
||||
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 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={'WakuConnect Poll Demo'}
|
||||
theme={orangeTheme}
|
||||
activate={activateBrowserWallet}
|
||||
account={account}
|
||||
deactivate={deactivate}
|
||||
/>
|
||||
<WakuPolling theme={orangeTheme} appName={'testApp_'} signer={signer} tokenAddress={tokenAddress} />
|
||||
</Wrapper>
|
||||
)
|
||||
}
|
||||
|
||||
export function PollingPage() {
|
||||
const location = useLocation()
|
||||
const tokenAddress = new URLSearchParams(location.search).get('token')
|
||||
|
||||
return (
|
||||
<Page>
|
||||
<GlobalStyle />
|
||||
<DAppProvider config={config}>
|
||||
<Polling tokenAddress={tokenAddress ?? sntTokenAddress} />
|
||||
</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="/" component={PollingPage} />
|
||||
</Switch>
|
||||
</BrowserRouter>
|
||||
</div>,
|
||||
document.getElementById('root')
|
||||
)
|
|
@ -0,0 +1,7 @@
|
|||
import { expect } from 'chai'
|
||||
|
||||
describe('test react-components', () => {
|
||||
it('foo', async () => {
|
||||
expect('Hello world').to.eq('Hello world')
|
||||
})
|
||||
})
|
|
@ -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"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
const path = require('path')
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin')
|
||||
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin')
|
||||
const webpack = require('webpack')
|
||||
const { ESBuildMinifyPlugin } = require('esbuild-loader')
|
||||
|
||||
module.exports = (env) => {
|
||||
let environment = 'development'
|
||||
if (env.ENV) {
|
||||
environment = env.ENV
|
||||
}
|
||||
|
||||
return {
|
||||
entry: './src/index.tsx',
|
||||
output: {
|
||||
filename: 'index.[fullhash].js',
|
||||
path: path.join(__dirname, 'dist'),
|
||||
publicPath: "/",
|
||||
},
|
||||
devtool: 'source-map',
|
||||
resolve: {
|
||||
extensions: ['.ts', '.tsx', '.js', '.json'],
|
||||
fallback: {
|
||||
"buffer": require.resolve("buffer/"),
|
||||
"crypto": require.resolve("crypto-browserify"),
|
||||
"stream": require.resolve("stream-browserify"),
|
||||
"assert": require.resolve("assert")
|
||||
}
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
loader: 'esbuild-loader',
|
||||
exclude: /node_modules/,
|
||||
options: {
|
||||
loader: 'tsx',
|
||||
target: 'es2018',
|
||||
},
|
||||
},
|
||||
{
|
||||
enforce: 'pre',
|
||||
test: /\.js$/,
|
||||
exclude: /node_modules/,
|
||||
loader: 'source-map-loader'
|
||||
},
|
||||
{
|
||||
test: /\.(png|svg|jpg|gif|woff|woff2|eot|ttf|otf|ico)$/,
|
||||
use: ['file-loader'],
|
||||
},
|
||||
],
|
||||
},
|
||||
optimization: {
|
||||
minimizer: [
|
||||
new ESBuildMinifyPlugin({
|
||||
target: 'es2018',
|
||||
}),
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
new ForkTsCheckerWebpackPlugin(),
|
||||
new HtmlWebpackPlugin({
|
||||
template: 'src/index.html',
|
||||
}),
|
||||
new webpack.DefinePlugin({
|
||||
'process.env.ENV': JSON.stringify(environment),
|
||||
}),
|
||||
new webpack.ProvidePlugin({
|
||||
process: 'process/browser.js',
|
||||
Buffer: ['buffer', 'Buffer'],
|
||||
}),
|
||||
],
|
||||
devServer: {
|
||||
historyApiFallback: true,
|
||||
host: '0.0.0.0',
|
||||
stats: 'errors-only',
|
||||
overlay: true,
|
||||
hot: true,
|
||||
},
|
||||
stats: 'minimal'
|
||||
}
|
||||
}
|
|
@ -55,12 +55,12 @@ export function Poll({ poll, wakuPolling, theme, account }: PollProps) {
|
|||
</PollAnswersWrapper>
|
||||
{userInVoters < 0 && (
|
||||
<SmallButton
|
||||
disabled={!account}
|
||||
disabled={!account || selectedAnswer === undefined}
|
||||
onClick={async () => {
|
||||
if (wakuPolling && account) {
|
||||
if (wakuPolling && account && selectedAnswer !== undefined) {
|
||||
const result = await wakuPolling.sendTimedPollVote(
|
||||
poll.poll.id,
|
||||
selectedAnswer ?? 0,
|
||||
selectedAnswer,
|
||||
poll.poll.pollType === PollType.WEIGHTED ? BigNumber.from(tokenAmount) : undefined
|
||||
)
|
||||
if (result === 1) {
|
||||
|
|
|
@ -5,6 +5,8 @@ import { WakuPolling } from '@dappconnect/vote-poll-sdk-core'
|
|||
import { Input, addIcon, SmallButton, Modal, Theme } from '@dappconnect/vote-poll-sdk-react-components'
|
||||
import { MESSAGE_SENDING_RESULT } from '@dappconnect/vote-poll-sdk-core/dist/esm/src/classes/WakuPolling'
|
||||
|
||||
const defaultPollDuration = 7 * 24 * 60 * 60 * 1000 // One week in ms.
|
||||
|
||||
function getLocaleIsoTime(dateTime: Date) {
|
||||
const MS_PER_MINUTE = 60000
|
||||
const milliseconds = dateTime.getTime() - dateTime.getTimezoneOffset() * MS_PER_MINUTE
|
||||
|
@ -45,7 +47,7 @@ export function PollCreation({ wakuPolling, theme, setShowPollCreation }: PollCr
|
|||
const [showCreateConfirmation, setShowCreateConfirmation] = useState(false)
|
||||
const [showNotEnoughTokens, setShowNotEnoughTokens] = useState(false)
|
||||
const [selectedType, setSelectedType] = useState(PollType.NON_WEIGHTED)
|
||||
const [endTimePicker, setEndTimePicker] = useState(new Date(new Date().getTime() + 10000000))
|
||||
const [endTimePicker, setEndTimePicker] = useState(new Date(new Date().getTime() + defaultPollDuration))
|
||||
|
||||
return (
|
||||
<Modal heading="Create a poll" setShowModal={setShowPollCreation} theme={theme}>
|
||||
|
|
Loading…
Reference in New Issue