1
0
mirror of https://github.com/kremalicious/blog.git synced 2024-06-14 00:23:13 +02:00

use new web3-react

This commit is contained in:
Matthias Kretschmann 2019-11-22 21:26:50 +01:00
parent 32faba15eb
commit ab14272675
Signed by: m
GPG Key ID: 606EEEF3C479A91F
20 changed files with 881 additions and 15593 deletions

View File

@ -121,6 +121,12 @@ exports.onPostBuild = async ({ graphql }) => {
// https://github.com/ethereum/web3.js/issues/1105#issuecomment-446039296
exports.onCreateWebpackConfig = ({ actions }) => {
actions.setWebpackConfig({
resolve: {
alias: {
// replace native `scrypt` module with pure js `js-scrypt`
scrypt: 'js-scrypt'
}
},
plugins: [
// ignore these plugins completely
new webpack.IgnorePlugin(/^(?:electron|ws)$/)

15564
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -29,7 +29,11 @@
"not op_mini all"
],
"dependencies": {
"@ethersproject/providers": "^5.0.0-beta.145",
"@ethersproject/units": "^5.0.0-beta.131",
"@loadable/component": "^5.10.3",
"@web3-react/core": "^6.0.0-beta.15",
"@web3-react/injected-connector": "^6.0.0-beta.17",
"classnames": "^2.2.6",
"date-fns": "^2.8.1",
"dms2dec": "^1.1.0",
@ -81,8 +85,7 @@
"remark": "^11.0.1",
"remark-react": "^6.0.0",
"slugify": "^1.3.6",
"use-dark-mode": "^2.3.1",
"web3-react": "^5.0.5"
"use-dark-mode": "^2.3.1"
},
"devDependencies": {
"@babel/node": "^7.7.0",

View File

@ -1,12 +1,11 @@
@import 'variables';
.account {
font-size: $font-size-mini;
.accountWrap {
font-size: $font-size-small;
color: $brand-grey-light;
max-width: 8rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
margin-bottom: $spacer;
display: flex;
justify-content: space-between;
}
.identicon {
@ -15,5 +14,8 @@
display: inline-block;
vertical-align: middle;
margin-right: $spacer / 8;
}
.balance {
margin-left: $spacer;
}

View File

@ -1,12 +1,31 @@
import React from 'react'
import Blockies from 'react-blockies'
import { formatEther } from '@ethersproject/units'
import styles from './Account.module.scss'
import useWeb3, { getBalance } from '../../../hooks/use-web3'
const Account = ({ account }: { account: string }) => (
<div className={styles.account} title={account}>
<Blockies seed={account} scale={2} size={8} className={styles.identicon} />
{account}
</div>
)
export default function Account() {
const { library, account } = useWeb3()
const ethBalance = account && getBalance(account, library)
export default Account
const accountDisplay =
account &&
`${account.substring(0, 8)}...${account.substring(account.length - 4)}`
const balanceDisplay =
ethBalance && `Ξ${parseFloat(formatEther(ethBalance)).toPrecision(4)}`
return (
<div className={styles.accountWrap} title={account}>
<span className={styles.account}>
<Blockies
seed={account}
scale={2}
size={8}
className={styles.identicon}
/>
{accountDisplay}
</span>
<span className={styles.balance}>{balanceDisplay}</span>
</div>
)
}

View File

@ -0,0 +1,46 @@
import React from 'react'
import styles from './Alert.module.scss'
export function getTransactionMessage(transactionHash?: string) {
return {
transaction: `<a href="https://etherscan.io/tx/${transactionHash}" target="_blank">See your transaction on etherscan.io.</a>`,
waitingForUser: 'Waiting for your confirmation',
waitingConfirmation: 'Waiting for network confirmation, hang on',
success: 'Confirmed. You are awesome, thanks!'
}
}
const constructMessage = (
transactionHash: string,
message?: { text?: string }
) =>
transactionHash
? message &&
message.text +
'<br />' +
getTransactionMessage(transactionHash).transaction
: message && message.text
const classes = (status: string) =>
status === 'success'
? styles.success
: status === 'error'
? styles.error
: styles.alert
export default function Alert({
transactionHash,
message
}: {
transactionHash: string
message?: { text?: string; status?: string }
}) {
return (
<div
className={classes(message.status)}
dangerouslySetInnerHTML={{
__html: `${constructMessage(transactionHash, message)}`
}}
/>
)
}

View File

@ -1,49 +0,0 @@
import React from 'react'
import styles from './Alerts.module.scss'
export const alertMessages = (
networkName?: string,
transactionHash?: string
) => ({
noAccount:
'Web3 detected, but no account. Are you logged into your MetaMask account?',
noCorrectNetwork: `Please connect to <strong>Main</strong> network. You are on <strong>${networkName}</strong> right now.`,
noWeb3:
'No Web3 detected. Install <a href="https://metamask.io">MetaMask</a> or <a href="https://brave.com">Brave</a>.',
transaction: `<a href="https://etherscan.io/tx/${transactionHash}" target="_blank">See your transaction on etherscan.io.</a>`,
waitingForUser: 'Waiting for your confirmation',
waitingConfirmation: 'Waiting for network confirmation, hang on',
success: 'Confirmed. You are awesome, thanks!'
})
interface AlertProps {
transactionHash: string
message?: { text?: string; status?: string }
}
const constructMessage = (
transactionHash: string,
message?: { text?: string }
) =>
transactionHash
? message &&
message.text + '<br />' + alertMessages(null, transactionHash).transaction
: message && message.text
const classes = (status: string) =>
status === 'success'
? styles.success
: status === 'error'
? styles.error
: styles.alert
export default function Alerts({ transactionHash, message }: AlertProps) {
return (
<div
className={classes(message.status)}
dangerouslySetInnerHTML={{
__html: `${constructMessage(transactionHash, message)}`
}}
/>
)
}

View File

@ -3,7 +3,10 @@
.conversion {
font-size: $font-size-mini;
color: $brand-grey-light;
text-align: center;
text-align: left;
margin-top: $spacer / 4;
margin-left: $spacer * 1.4;
animation: fadeIn 0.5s 0.8s ease-out backwards;
span {
margin-left: $spacer / 2;

View File

@ -1,45 +1,44 @@
import React, { PureComponent } from 'react'
import { getFiat } from './utils'
import React, { useState, useEffect } from 'react'
import styles from './Conversion.module.scss'
export default class Conversion extends PureComponent<
{ amount: number },
{ euro: string; dollar: string }
> {
state = {
export async function getFiat(amount: number) {
const url = 'https://api.coinmarketcap.com/v1/ticker/ethereum/?convert=EUR'
const response = await fetch(url)
if (!response.ok) console.error(response.statusText)
const data = await response.json()
/* eslint-disable @typescript-eslint/camelcase */
const { price_usd, price_eur } = data[0]
const dollar = (amount * price_usd).toFixed(2)
const euro = (amount * price_eur).toFixed(2)
/* eslint-enable @typescript-eslint/camelcase */
return { dollar, euro }
}
export default function Conversion({ amount }: { amount: number }) {
const [conversion, setConversion] = useState({
euro: '0.00',
dollar: '0.00'
}
})
const { dollar, euro } = conversion
componentDidMount() {
this.getFiatResponse()
}
componentDidUpdate(prevProps: any) {
const { amount } = this.props
if (amount !== prevProps.amount) {
this.getFiatResponse()
}
}
async getFiatResponse() {
async function getFiatResponse() {
try {
const { dollar, euro } = await getFiat(this.props.amount)
this.setState({ euro, dollar })
const { dollar, euro } = await getFiat(amount)
setConversion({ euro, dollar })
} catch (error) {
console.error(error.message)
}
}
render() {
const { dollar, euro } = this.state
useEffect(() => {
getFiatResponse()
}, [amount])
return (
<div className={styles.conversion}>
<span>{dollar !== '0.00' && `= $ ${dollar}`}</span>
<span>{euro !== '0.00' && `= € ${euro}`}</span>
</div>
)
}
return (
<div className={styles.conversion}>
<span>{dollar !== '0.00' && `= $ ${dollar}`}</span>
<span>{euro !== '0.00' && `= € ${euro}`}</span>
</div>
)
}

View File

@ -88,15 +88,6 @@
}
}
.infoline {
flex-basis: 100%;
display: flex;
align-items: center;
justify-content: center;
margin-top: $spacer / 4;
animation: fadeIn 0.5s 0.8s ease-out backwards;
}
.message {
composes: message from './index.module.scss';
}

View File

@ -1,41 +1,44 @@
import React from 'react'
import React, { useState } from 'react'
import Input from '../../atoms/Input'
import Account from './Account'
import Conversion from './Conversion'
import styles from './InputGroup.module.scss'
export default function InputGroup({
amount,
onAmountChange,
sendTransaction,
selectedAccount
sendTransaction
}: {
amount: number
onAmountChange(target: any): void
sendTransaction(): void
selectedAccount?: string | null
sendTransaction(amount: number): void
}) {
const [amount, setAmount] = useState(0.03)
const onAmountChange = ({ target }: { target: any }) => {
setAmount(target.value)
}
return (
<div className={styles.inputGroup}>
<div className={styles.input}>
<Input
type="number"
value={amount}
onChange={onAmountChange}
min="0"
step="0.01"
/>
<div className={styles.currency}>
<span>ETH</span>
<div>
<Account />
<div className={styles.inputGroup}>
<div className={styles.input}>
<Input
type="number"
value={amount}
onChange={onAmountChange}
min="0"
step="0.01"
/>
<div className={styles.currency}>
<span>ETH</span>
</div>
</div>
<button
className="btn btn-primary"
onClick={() => sendTransaction(amount)}
>
Make it rain
</button>
</div>
<button className="btn btn-primary" onClick={() => sendTransaction()}>
Make it rain
</button>
<div className={styles.infoline}>
<Conversion amount={amount} />
{selectedAccount && <Account account={selectedAccount} />}
</div>
<Conversion amount={amount} />
</div>
)
}

View File

@ -1,72 +0,0 @@
import { Connectors } from 'web3-react'
// import TrezorApi from 'trezor-connect'
// import WalletConnectApi from '@walletconnect/web3-subprovider'
// import FortmaticApi from 'fortmatic'
// import PortisApi from '@portis/web3'
const {
InjectedConnector
// NetworkOnlyConnector,
// TrezorConnector,
// LedgerConnector,
// WalletConnectConnector,
// FortmaticConnector,
// PortisConnector
} = Connectors
// const supportedNetworkURLs = {
// 1: 'https://mainnet.infura.io/v3/60ab76e16df54c808e50a79975b4779f',
// 4: 'https://rinkeby.infura.io/v3/60ab76e16df54c808e50a79975b4779f'
// }
// const defaultNetwork = 1
const MetaMask = new InjectedConnector({
supportedNetworks: [1]
})
// const Network = new NetworkOnlyConnector({
// providerURL: supportedNetworkURLs[1]
// })
// const Trezor = new TrezorConnector({
// api: TrezorApi,
// supportedNetworkURLs,
// defaultNetwork,
// manifestEmail: 'noahwz@gmail.com',
// manifestAppUrl: 'https://codesandbox.io/s/6v5nrq2nqw'
// })
// const Ledger = new LedgerConnector({
// supportedNetworkURLs,
// defaultNetwork
// })
// const WalletConnect = new WalletConnectConnector({
// api: WalletConnectApi,
// bridge: 'https://bridge.walletconnect.org',
// supportedNetworkURLs,
// defaultNetwork
// })
// const Fortmatic = new FortmaticConnector({
// api: FortmaticApi,
// apiKey: 'pk_live_F95FEECB1BE324B5',
// logoutOnDeactivation: false
// })
// const Portis = new PortisConnector({
// api: PortisApi,
// dAppId: '211b48db-e8cc-4b68-82ad-bf781727ea9e',
// network: 'mainnet'
// })
export default {
MetaMask
// Network,
// Trezor,
// Ledger,
// WalletConnect,
// Fortmatic,
// Portis
}

View File

@ -1,38 +1,39 @@
import React, { useEffect, useState } from 'react'
import { useWeb3Context } from 'web3-react'
import React, { useState, useEffect } from 'react'
import useWeb3, { connectors, getErrorMessage } from '../../../hooks/use-web3'
import InputGroup from './InputGroup'
import Alerts, { alertMessages } from './Alerts'
import Alert, { getTransactionMessage } from './Alert'
import styles from './index.module.scss'
export default function Web3Donation({ address }: { address: string }) {
const {
setFirstValidConnector,
error,
connector,
library,
chainId,
account,
activate,
active,
account
} = useWeb3Context()
const [amount, setAmount] = useState(0.03)
error
} = useWeb3()
const [message, setMessage] = useState()
useEffect(() => {
setFirstValidConnector(['MetaMask'])
}, [])
setMessage(undefined)
error &&
setMessage({
status: 'error',
text: error.message
})
error &&
setMessage({
status: 'error',
text: getErrorMessage(error, chainId)
})
}, [connector, account, library, chainId, active, error])
const [transactionHash, setTransactionHash] = useState(undefined)
async function sendTransaction() {
async function sendTransaction(amount: number) {
const signer = library.getSigner()
setMessage({
status: 'loading',
text: alertMessages().waitingForUser
text: getTransactionMessage().waitingForUser
})
const tx = await signer.sendTransaction({
@ -42,68 +43,26 @@ export default function Web3Donation({ address }: { address: string }) {
setTransactionHash(tx.hash)
setMessage({
status: 'loading',
text: alertMessages().waitingConfirmation
text: getTransactionMessage().waitingConfirmation
})
// setMessage({
// status: 'success',
// text: alertMessages().success
// text: getTransactionMessage().success
// })
}
const onAmountChange = ({ target }: { target: any }) => {
setAmount(target.value)
}
return (
<div className={styles.web3}>
{active && !message ? (
<InputGroup
selectedAccount={account}
amount={amount}
onAmountChange={onAmountChange}
sendTransaction={sendTransaction}
/>
{!active && !message ? (
<button className="link" onClick={() => activate(connectors.MetaMask)}>
Activate Web3
</button>
) : library && account && !message ? (
<InputGroup sendTransaction={sendTransaction} />
) : (
message && (
<Alerts message={message} transactionHash={transactionHash} />
)
message && <Alert message={message} transactionHash={transactionHash} />
)}
</div>
)
}
// sendTransaction = () => {
// const { web3 } = this
// this.setState({
// inTransaction: true,
// message: { text: alertMessages().waitingForUser }
// })
// web3.eth
// .sendTransaction({
// from: this.state.selectedAccount,
// to: this.props.address,
// value: this.state.amount * 1e18 // ETH -> Wei
// })
// .once('transactionHash', transactionHash => {
// this.setState({
// transactionHash,
// message: { text: alertMessages().waitingConfirmation }
// })
// })
// .on('error', error =>
// this.setState({
// message: { status: 'error', text: error.message }
// })
// )
// .then(() => {
// this.setState({
// message: {
// status: 'success',
// text: alertMessages().success
// }
// })
// })
// }

View File

@ -1,39 +0,0 @@
export const getNetworkName = (netId: number) => {
let networkName
switch (netId) {
case 1:
networkName = 'Main'
break
case 2:
networkName = 'Morden'
break
case 3:
networkName = 'Ropsten'
break
case 4:
networkName = 'Rinkeby'
break
case 42:
networkName = 'Kovan'
break
default:
networkName = 'Private'
}
return networkName
}
export const getFiat = async (amount: number) => {
const url = 'https://api.coinmarketcap.com/v1/ticker/ethereum/?convert=EUR'
const response = await fetch(url)
if (!response.ok) console.error(response.statusText)
const data = await response.json()
/* eslint-disable @typescript-eslint/camelcase */
const { price_usd, price_eur } = data[0]
const dollar = (amount * price_usd).toFixed(2)
const euro = (amount * price_eur).toFixed(2)
/* eslint-enable @typescript-eslint/camelcase */
return { dollar, euro }
}

View File

@ -0,0 +1,75 @@
import { InjectedConnector } from '@web3-react/injected-connector'
// import { NetworkConnector } from '@web3-react/network-connector'
// import { WalletConnectConnector } from '@web3-react/walletconnect-connector'
// import { WalletLinkConnector } from '@web3-react/walletlink-connector'
// import { LedgerConnector } from '@web3-react/ledger-connector'
// import { TrezorConnector } from '@web3-react/trezor-connector'
// import { FrameConnector } from '@web3-react/frame-connector'
// import { AuthereumConnector } from '@web3-react/authereum-connector'
// import { FortmaticConnector } from '@web3-react/fortmatic-connector'
// import { PortisConnector } from '@web3-react/portis-connector'
// import { SquarelinkConnector } from '@web3-react/squarelink-connector'
// import { TorusConnector } from '@web3-react/torus-connector'
// const POLLING_INTERVAL = 8000
// const RPC_URLS: { [chainId: number]: string } = {
// 1: process.env.RPC_URL_1 as string,
// 4: process.env.RPC_URL_4 as string
// }
export const MetaMask = new InjectedConnector({
supportedChainIds: [1]
})
// export const network = new NetworkConnector({
// urls: { 1: RPC_URLS[1], 4: RPC_URLS[4] },
// defaultChainId: 1,
// pollingInterval: POLLING_INTERVAL
// })
// export const walletconnect = new WalletConnectConnector({
// rpc: { 1: RPC_URLS[1] },
// bridge: 'https://bridge.walletconnect.org',
// qrcode: true,
// pollingInterval: POLLING_INTERVAL
// })
// export const walletlink = new WalletLinkConnector({
// url: RPC_URLS[1],
// appName: 'web3-react example'
// })
// export const ledger = new LedgerConnector({
// chainId: 1,
// url: RPC_URLS[1],
// pollingInterval: POLLING_INTERVAL
// })
// export const trezor = new TrezorConnector({
// chainId: 1,
// url: RPC_URLS[1],
// pollingInterval: POLLING_INTERVAL,
// manifestEmail: 'dummy@abc.xyz',
// manifestAppUrl: 'http://localhost:1234'
// })
// export const frame = new FrameConnector({ supportedChainIds: [1] })
// export const authereum = new AuthereumConnector({ chainId: 42 })
// export const fortmatic = new FortmaticConnector({
// apiKey: process.env.FORTMATIC_API_KEY as string,
// chainId: 4
// })
// export const portis = new PortisConnector({
// dAppId: process.env.PORTIS_DAPP_ID as string,
// networks: [1, 100]
// })
// export const squarelink = new SquarelinkConnector({
// clientId: process.env.SQUARELINK_CLIENT_ID as string,
// networks: [1, 100]
// })
// export const torus = new TorusConnector({ chainId: 1 })

View File

@ -0,0 +1,99 @@
import { useState, useEffect } from 'react'
import { useWeb3React } from '@web3-react/core'
import { Web3ReactContextInterface } from '@web3-react/core/dist/types'
import * as connectors from './connectors'
import {
getLibrary,
getNetworkName,
getErrorMessage,
getBalance
} from './utils'
export { connectors, getLibrary, getNetworkName, getErrorMessage, getBalance }
export function useEagerConnect() {
const { MetaMask } = connectors
const { activate, active } = useWeb3React()
const [tried, setTried] = useState(false)
useEffect(() => {
MetaMask.isAuthorized().then(isAuthorized => {
if (isAuthorized) {
activate(MetaMask, undefined, true).catch(() => {
setTried(true)
})
} else {
setTried(true)
}
})
}, [])
// if the connection worked, wait until we get confirmation of that to flip the flag
useEffect(() => {
if (!tried && active) {
setTried(true)
}
}, [tried, active])
return tried
}
export function useInactiveListener(suppress = false) {
const { active, error, activate } = useWeb3React()
const { MetaMask } = connectors
useEffect((): any => {
const { ethereum } = window as any
if (ethereum && !active && !error && !suppress) {
const handleConnect = () => {
console.log("Handling 'connect' event")
activate(MetaMask)
}
const handleChainChanged = (chainId: string | number) => {
console.log("Handling 'chainChanged' event with payload", chainId)
activate(MetaMask)
}
const handleNetworkChanged = (networkId: string | number) => {
console.log("Handling 'networkChanged' event with payload", networkId)
activate(MetaMask)
}
const handleAccountsChanged = (accounts: string[]) => {
console.log("Handling 'accountsChanged' event with payload", accounts)
if (accounts.length > 0) {
activate(MetaMask)
}
}
ethereum.on('connect', handleConnect)
ethereum.on('chainChanged', handleChainChanged)
ethereum.on('networkChanged', handleNetworkChanged)
ethereum.on('accountsChanged', handleAccountsChanged)
return () => {
ethereum.removeListener('networkChanged', handleNetworkChanged)
ethereum.removeListener('accountsChanged', handleAccountsChanged)
}
}
}, [active, error, suppress, activate])
}
export default function useWeb3(): Web3ReactContextInterface {
const context = useWeb3React()
// handle logic to recognize the connector currently being activated
const [activatingConnector, setActivatingConnector] = useState()
useEffect(() => {
if (activatingConnector && activatingConnector === context.connector) {
setActivatingConnector(undefined)
}
}, [activatingConnector, context.connector])
// handle logic to eagerly connect to the injected ethereum provider, if it exists and has granted access already
const triedEager = useEagerConnect()
// handle logic to connect in reaction to certain events on the injected ethereum provider, if it exists
useInactiveListener(!triedEager || !!activatingConnector)
return context
}

View File

@ -0,0 +1,83 @@
import { useState, useEffect } from 'react'
import { UnsupportedChainIdError } from '@web3-react/core'
import {
NoEthereumProviderError,
UserRejectedRequestError
} from '@web3-react/injected-connector'
import { Web3Provider } from '@ethersproject/providers'
export function getLibrary(provider: any): Web3Provider {
const library = new Web3Provider(provider)
library.pollingInterval = 10000
return library
}
export function getNetworkName(netId: number) {
let networkName
switch (netId) {
case 1:
networkName = 'Main'
break
case 2:
networkName = 'Morden'
break
case 3:
networkName = 'Ropsten'
break
case 4:
networkName = 'Rinkeby'
break
case 42:
networkName = 'Kovan'
break
default:
networkName = 'Private'
}
return networkName
}
export function getErrorMessage(error: Error, chainId: number) {
if (error instanceof NoEthereumProviderError) {
return 'No Ethereum browser extension detected, install <a href="https://metamask.io">MetaMask</a> or <a href="https://brave.com">Brave</a>.'
} else if (error instanceof UnsupportedChainIdError) {
const networkName = getNetworkName(chainId)
return `Please connect to <strong>Main</strong> network. You are on <strong>${networkName}</strong> right now.`
} else if (error instanceof UserRejectedRequestError) {
return 'Please authorize this website to access your Ethereum account.'
} else {
console.error(error)
return 'An unknown error occurred. Check the console for more details.'
}
}
export function getBalance(account: string, library: any) {
const [ethBalance, setEthBalance] = useState()
useEffect((): any => {
if (library && account) {
let stale = false
library
.getBalance(account)
.then((balance: any) => {
if (!stale) {
setEthBalance(balance)
}
})
.catch(() => {
if (!stale) {
setEthBalance(null)
}
})
return () => {
stale = true
setEthBalance(undefined)
}
}
}, [library, account])
return ethBalance
}

View File

@ -2,15 +2,15 @@ import React from 'react'
import loadable from '@loadable/component'
import shortid from 'shortid'
import Helmet from 'react-helmet'
import { Web3ReactProvider } from '@web3-react/core'
import { Author } from '../@types/Site'
import { useSiteMetadata } from '../hooks/use-site-metadata'
import { getLibrary } from '../hooks/use-web3'
import Qr from '../components/atoms/Qr'
import Icon from '../components/atoms/Icon'
import connectors from '../components/molecules/Web3Donation/connectors'
import styles from './thanks.module.scss'
const Web3Provider = loadable(() => import('web3-react'))
const Web3Donation = loadable(() =>
const LazyWeb3Donation = loadable(() =>
import('../components/molecules/Web3Donation')
)
@ -36,7 +36,7 @@ export default function Thanks() {
)
return (
<>
<Web3ReactProvider getLibrary={getLibrary}>
<Helmet>
<title>Say thanks</title>
<meta name="robots" content="noindex,nofollow" />
@ -47,33 +47,30 @@ export default function Thanks() {
<header>
<h1 className={styles.title}>Say Thanks</h1>
</header>
<Web3Provider connectors={connectors} libraryName={'ethers.js'}>
<div className={styles.web3}>
<header>
<h4>Web3 Wallet</h4>
<p>Send Ether with MetaMask or Brave.</p>
</header>
<Web3Donation fallback={<div className={styles.loading}>Loading...</div>} address={author.ether} />
</div>
<div className={styles.web3}>
<header>
<h4>Web3 Wallet</h4>
<p>Send Ether with MetaMask or Brave.</p>
</header>
<div className={styles.coins}>
<header>
<h4>Any other wallets</h4>
<p>Send Bitcoin or Ether from any wallet.</p>
</header>
<LazyWeb3Donation
fallback={<div className={styles.loading}>Loading...</div>}
address={author.ether}
/>
</div>
{coins.map((address: string) => (
<Coin
key={shortid.generate()}
address={address}
author={author}
/>
))}
</div>
</Web3Provider>
<div className={styles.coins}>
<header>
<h4>Any other wallets</h4>
<p>Send Bitcoin or Ether from any wallet.</p>
</header>
{coins.map((address: string) => (
<Coin key={shortid.generate()} address={address} author={author} />
))}
</div>
</article>
</>
</Web3ReactProvider>
)
}

View File

@ -1,105 +0,0 @@
import React from 'react'
import loadable from '@loadable/component'
import shortid from 'shortid'
import Helmet from 'react-helmet'
import { Author } from '../@types/Site'
import { useSiteMetadata } from '../hooks/use-site-metadata'
import Qr from '../components/atoms/Qr'
import Icon from '../components/atoms/Icon'
import connectors from '../components/molecules/Web3Donation/connectors'
import styles from './thanks.module.scss'
<<<<<<< HEAD
const Web3Donation = loadable(() =>
import('../components/molecules/Web3Donation')
)
=======
const Web3Provider = lazy(() => import('web3-react'))
const Web3Donation = lazy(() => import('../components/molecules/Web3Donation'))
>>>>>>> refactor web3
const Coin = ({ address, author }: { address: string; author: Author }) => (
<div className={styles.coin}>
<Qr title={address} address={(author as any)[address]} />
</div>
)
const BackButton = () => (
<button
className={`link ${styles.buttonBack}`}
onClick={() => window.history.back()}
>
<Icon name="ChevronLeft" /> Go Back
</button>
)
export default function Thanks() {
const { author } = useSiteMetadata()
const coins = Object.keys(author).filter(
key => key === 'bitcoin' || key === 'ether'
)
return (
<>
<Helmet>
<title>Say thanks</title>
<meta name="robots" content="noindex,nofollow" />
</Helmet>
<article className={styles.thanks}>
<BackButton />
<header>
<h1 className={styles.title}>Say Thanks</h1>
</header>
<<<<<<< HEAD
<Web3Donation
fallback={<div className={styles.loading}>Loading...</div>}
address={author.ether}
/>
<div className={styles.coins}>
<header>
<h4>Any other wallets</h4>
<p>Send Bitcoin or Ether from any wallet.</p>
</header>
{coins.map((address: string) => (
<Coin key={shortid.generate()} address={address} author={author} />
))}
</div>
=======
{!isSSR && (
<Suspense fallback={<div className={styles.loading}>Loading...</div>}>
<Web3Provider connectors={connectors} libraryName={'ethers.js'}>
<div className={styles.web3}>
<header>
<h4>Web3 Wallet</h4>
<p>Send Ether with MetaMask or Brave.</p>
</header>
<Web3Donation address={author.ether} />
</div>
<div className={styles.coins}>
<header>
<h4>Any other wallets</h4>
<p>Send Bitcoin or Ether from any wallet.</p>
</header>
{coins.map((address: string) => (
<Coin
key={shortid.generate()}
address={address}
author={author}
/>
))}
</div>
</Web3Provider>
</Suspense>
)}
>>>>>>> refactor web3
</article>
</>
)
}