allow user to enable/disable token transfers to vault
This commit is contained in:
parent
d0797caa69
commit
448c38b7ee
|
@ -1,4 +1,4 @@
|
||||||
import React from 'react';
|
import React, { useContext, useState, useEffect } from 'react';
|
||||||
import { Formik } from 'formik';
|
import { Formik } from 'formik';
|
||||||
import EmbarkJS from 'Embark/EmbarkJS';
|
import EmbarkJS from 'Embark/EmbarkJS';
|
||||||
import LPVault from 'Embark/contracts/LPVault';
|
import LPVault from 'Embark/contracts/LPVault';
|
||||||
|
@ -7,9 +7,14 @@ import Button from '@material-ui/core/Button';
|
||||||
import TextField from '@material-ui/core/TextField';
|
import TextField from '@material-ui/core/TextField';
|
||||||
import Snackbar from '@material-ui/core/Snackbar';
|
import Snackbar from '@material-ui/core/Snackbar';
|
||||||
import MenuItem from '@material-ui/core/MenuItem';
|
import MenuItem from '@material-ui/core/MenuItem';
|
||||||
import web3 from 'Embark/web3';
|
import FormControlLabel from '@material-ui/core/FormControlLabel'
|
||||||
import { MySnackbarContentWrapper } from './base/SnackBars';
|
import Switch from '@material-ui/core/Switch'
|
||||||
|
import web3 from 'Embark/web3'
|
||||||
|
import { MySnackbarContentWrapper } from './base/SnackBars'
|
||||||
import { currencies, TOKEN_ICON_API, getTokenLabel } from '../utils/currencies'
|
import { currencies, TOKEN_ICON_API, getTokenLabel } from '../utils/currencies'
|
||||||
|
import { toEther } from '../utils/conversions'
|
||||||
|
import { getLpAllowance, standardTokenApproval } from '../utils/initialize'
|
||||||
|
import { FundingContext } from '../context'
|
||||||
|
|
||||||
const { donate } = LiquidPledging.methods
|
const { donate } = LiquidPledging.methods
|
||||||
const hoursToSeconds = hours => hours * 60 * 60
|
const hoursToSeconds = hours => hours * 60 * 60
|
||||||
|
@ -18,125 +23,178 @@ const addFunderSucessMsg = response => {
|
||||||
return `Funder created with ID of ${idGiver}`
|
return `Funder created with ID of ${idGiver}`
|
||||||
}
|
}
|
||||||
|
|
||||||
const CreateFunding = ({ refreshTable }) => (
|
const CreateFunding = ({ refreshTable }) => {
|
||||||
<Formik
|
const context = useContext(FundingContext)
|
||||||
initialValues={{ funderId: '', receiverId: '', tokenAddress : '', amount: '' }}
|
const { account } = context
|
||||||
onSubmit={async (values, { setSubmitting, resetForm, setStatus }) => {
|
const [balances, setBalances] = useState({})
|
||||||
const { funderId, receiverId, tokenAddress, amount } = values
|
const [allowances, setAllowances] = useState({})
|
||||||
const account = await web3.eth.getCoinbase()
|
|
||||||
const args = [funderId, receiverId, tokenAddress, web3.utils.toWei(amount, 'ether')];
|
|
||||||
|
|
||||||
const toSend = donate(...args);
|
|
||||||
|
|
||||||
const estimateGas = await toSend.estimateGas();
|
const updateBalancesAllowances = () => {
|
||||||
|
const latestBalances = {}
|
||||||
toSend.send({ from: account, gas: estimateGas + 2000 })
|
const latestAllowances = {}
|
||||||
.then(res => {
|
currencies.forEach(async c => {
|
||||||
console.log({res})
|
if (c.contract) {
|
||||||
setStatus({
|
const amount = await c.contract.methods.balanceOf(account).call()
|
||||||
snackbar: { variant: 'success', message: 'funding provided!' }
|
const allowance = await getLpAllowance(c.contract)
|
||||||
})
|
latestBalances[c.value] = toEther(amount)
|
||||||
refreshTable()
|
latestAllowances[c.value] = toEther(allowance)
|
||||||
})
|
} else {
|
||||||
.catch(e => {
|
latestBalances[c.value] = '0'
|
||||||
console.log({e})
|
latestAllowances[c.value] = '0'
|
||||||
setStatus({
|
}
|
||||||
snackbar: { variant: 'error', message: 'There was an error' }
|
})
|
||||||
})
|
setBalances(latestBalances)
|
||||||
})
|
setAllowances(latestAllowances)
|
||||||
}}
|
}
|
||||||
>
|
|
||||||
{({
|
const toggleAllowance = e => {
|
||||||
values,
|
const token = currencies[e.target.value]
|
||||||
errors,
|
const allowance = allowances[token.value]
|
||||||
touched,
|
standardTokenApproval(
|
||||||
handleChange,
|
token.contract,
|
||||||
handleBlur,
|
Number(allowance) ? '0' : undefined
|
||||||
handleSubmit,
|
).then(res => {
|
||||||
setFieldValue,
|
const { events: { Approval: { returnValues: { value } } } } = res
|
||||||
setStatus,
|
setAllowances(state => ({ ...state, [token.value]: toEther(value) }))
|
||||||
status
|
})
|
||||||
}) => (
|
}
|
||||||
<form autoComplete="off" onSubmit={handleSubmit} style={{ display: 'flex', flexDirection: 'column' }}>
|
|
||||||
<TextField
|
useEffect(() => {
|
||||||
id="funderId"
|
if (account) updateBalancesAllowances()
|
||||||
name="funderId"
|
}, account)
|
||||||
label="Funder Id"
|
|
||||||
placeholder="Funder Id"
|
return (
|
||||||
margin="normal"
|
<Formik
|
||||||
variant="outlined"
|
initialValues={{ funderId: '', receiverId: '', tokenAddress : '', amount: '' }}
|
||||||
onChange={handleChange}
|
onSubmit={async (values, { setSubmitting, resetForm, setStatus }) => {
|
||||||
onBlur={handleBlur}
|
const { funderId, receiverId, tokenAddress, amount } = values
|
||||||
value={values.funderId || ''}
|
const args = [funderId, receiverId, tokenAddress, web3.utils.toWei(amount, 'ether')];
|
||||||
/>
|
|
||||||
<TextField
|
const toSend = donate(...args);
|
||||||
id="receiverId"
|
|
||||||
name="receiverId"
|
const estimateGas = await toSend.estimateGas()
|
||||||
label="Receiver Id"
|
|
||||||
placeholder="Receiver Id"
|
toSend.send({ from: account, gas: estimateGas + 2000 })
|
||||||
margin="normal"
|
.then(res => {
|
||||||
variant="outlined"
|
console.log({res})
|
||||||
helperText="The receiver of the funding can be any admin, giver, delegate or a project"
|
setStatus({
|
||||||
onChange={handleChange}
|
snackbar: { variant: 'success', message: 'funding provided!' }
|
||||||
onBlur={handleBlur}
|
})
|
||||||
value={values.receiverId || ''}
|
refreshTable()
|
||||||
/>
|
})
|
||||||
<TextField
|
.catch(e => {
|
||||||
id="tokenAddress"
|
console.log({e})
|
||||||
name="tokenAddress"
|
setStatus({
|
||||||
select
|
snackbar: { variant: 'error', message: 'There was an error' }
|
||||||
label="Select token for funding"
|
})
|
||||||
placeholder="Select token for funding"
|
})
|
||||||
margin="normal"
|
}}
|
||||||
variant="outlined"
|
>
|
||||||
onChange={handleChange}
|
{({
|
||||||
onBlur={handleBlur}
|
values,
|
||||||
value={values.tokenAddress || ''}
|
errors,
|
||||||
>
|
touched,
|
||||||
{currencies.map(option => (
|
handleChange,
|
||||||
<MenuItem style={{ display: 'flex', alignItems: 'center' }} key={option.value} value={option.value}>
|
handleBlur,
|
||||||
<div style={{ display: 'flex', alignItems: 'center' }} >
|
handleSubmit,
|
||||||
{option.icon || <img
|
setFieldValue,
|
||||||
src={option.img || `${TOKEN_ICON_API}/${option.value}.png`}
|
setStatus,
|
||||||
style={{ width: option.width, marginRight: '3%' }}
|
status
|
||||||
/>}
|
}) => (
|
||||||
{option.label}
|
<form autoComplete="off" onSubmit={handleSubmit} style={{ display: 'flex', flexDirection: 'column' }}>
|
||||||
</div>
|
<TextField
|
||||||
</MenuItem>
|
id="funderId"
|
||||||
))}
|
name="funderId"
|
||||||
</TextField>
|
label="Funder Id"
|
||||||
<TextField
|
placeholder="Funder Id"
|
||||||
id="amount"
|
margin="normal"
|
||||||
name="amount"
|
variant="outlined"
|
||||||
label={`Amount of ${getTokenLabel(values.tokenAddress) || 'tokens'} to provide`}
|
onChange={handleChange}
|
||||||
placeholder="Amount of tokens to provide"
|
onBlur={handleBlur}
|
||||||
margin="normal"
|
value={values.funderId || ''}
|
||||||
variant="outlined"
|
|
||||||
onChange={handleChange}
|
|
||||||
onBlur={handleBlur}
|
|
||||||
value={values.amount || ''}
|
|
||||||
/>
|
|
||||||
<Button variant="contained" color="primary" type="submit">
|
|
||||||
PROVIDE FUNDING
|
|
||||||
</Button>
|
|
||||||
{status && <Snackbar
|
|
||||||
anchorOrigin={{
|
|
||||||
vertical: 'bottom',
|
|
||||||
horizontal: 'left',
|
|
||||||
}}
|
|
||||||
open={!!status.snackbar}
|
|
||||||
autoHideDuration={6000}
|
|
||||||
onClose={() => setStatus(null)}
|
|
||||||
>
|
|
||||||
<MySnackbarContentWrapper
|
|
||||||
onClose={() => setStatus(null)}
|
|
||||||
variant={status.snackbar.variant}
|
|
||||||
message={status.snackbar.message}
|
|
||||||
/>
|
/>
|
||||||
</Snackbar>}
|
<TextField
|
||||||
</form>
|
id="receiverId"
|
||||||
)}
|
name="receiverId"
|
||||||
</Formik>
|
label="Receiver Id"
|
||||||
)
|
placeholder="Receiver Id"
|
||||||
|
margin="normal"
|
||||||
|
variant="outlined"
|
||||||
|
helperText="The receiver of the funding can be any admin, giver, delegate or a project"
|
||||||
|
onChange={handleChange}
|
||||||
|
onBlur={handleBlur}
|
||||||
|
value={values.receiverId || ''}
|
||||||
|
/>
|
||||||
|
<TextField
|
||||||
|
id="tokenAddress"
|
||||||
|
name="tokenAddress"
|
||||||
|
select
|
||||||
|
label="Select token for funding"
|
||||||
|
placeholder="Select token for funding"
|
||||||
|
margin="normal"
|
||||||
|
variant="outlined"
|
||||||
|
onChange={handleChange}
|
||||||
|
onBlur={handleBlur}
|
||||||
|
value={values.tokenAddress || ''}
|
||||||
|
>
|
||||||
|
{currencies.map((option, idx) => (
|
||||||
|
<MenuItem style={{ display: 'flex', alignItems: 'center' }} key={option.value} value={option.value}>
|
||||||
|
<div style={{ display: 'flex', alignItems: 'center' }} >
|
||||||
|
{option.icon || <img
|
||||||
|
src={option.img || `${TOKEN_ICON_API}/${option.value}.png`}
|
||||||
|
style={{ width: option.width, marginRight: '3%' }}
|
||||||
|
/>}
|
||||||
|
{option.label}
|
||||||
|
<span style={{ marginLeft: '10%' }}>Your Balance: <strong>{balances[option.value]}</strong></span>
|
||||||
|
<FormControlLabel
|
||||||
|
style={{ marginLeft: '10%' }}
|
||||||
|
onClick={e => e.stopPropagation()}
|
||||||
|
control={
|
||||||
|
<Switch
|
||||||
|
checked={!!Number(allowances[option.value])}
|
||||||
|
onChange={toggleAllowance}
|
||||||
|
value={idx}
|
||||||
|
color="primary"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
label="Enabled"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</TextField>
|
||||||
|
<TextField
|
||||||
|
id="amount"
|
||||||
|
name="amount"
|
||||||
|
label={`Amount of ${getTokenLabel(values.tokenAddress) || 'tokens'} to provide`}
|
||||||
|
placeholder="Amount of tokens to provide"
|
||||||
|
margin="normal"
|
||||||
|
variant="outlined"
|
||||||
|
onChange={handleChange}
|
||||||
|
onBlur={handleBlur}
|
||||||
|
value={values.amount || ''}
|
||||||
|
/>
|
||||||
|
<Button variant="contained" color="primary" type="submit">
|
||||||
|
PROVIDE FUNDING
|
||||||
|
</Button>
|
||||||
|
{status && <Snackbar
|
||||||
|
anchorOrigin={{
|
||||||
|
vertical: 'bottom',
|
||||||
|
horizontal: 'left',
|
||||||
|
}}
|
||||||
|
open={!!status.snackbar}
|
||||||
|
autoHideDuration={6000}
|
||||||
|
onClose={() => setStatus(null)}
|
||||||
|
>
|
||||||
|
<MySnackbarContentWrapper
|
||||||
|
onClose={() => setStatus(null)}
|
||||||
|
variant={status.snackbar.variant}
|
||||||
|
message={status.snackbar.message}
|
||||||
|
/>
|
||||||
|
</Snackbar>}
|
||||||
|
</form>
|
||||||
|
)}
|
||||||
|
</Formik>
|
||||||
|
)}
|
||||||
|
|
||||||
export default CreateFunding
|
export default CreateFunding
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import StandardToken from 'Embark/contracts/StandardToken'
|
import web3 from 'Embark/web3'
|
||||||
import SNT from 'Embark/contracts/SNT'
|
import SNT from 'Embark/contracts/SNT'
|
||||||
import sntIco from 'cryptocurrency-icons/svg/color/snt.svg'
|
import sntIco from 'cryptocurrency-icons/svg/color/snt.svg'
|
||||||
|
|
||||||
|
@ -15,7 +15,8 @@ export const currencies = [
|
||||||
{
|
{
|
||||||
value: SNT._address,
|
value: SNT._address,
|
||||||
label: 'Status (SNT)',
|
label: 'Status (SNT)',
|
||||||
img: sntIco
|
img: sntIco,
|
||||||
|
contract: SNT
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: '0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359',
|
value: '0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359',
|
||||||
|
|
|
@ -25,19 +25,19 @@ export const vaultPledgingNeedsInit = async () => {
|
||||||
return needsInit
|
return needsInit
|
||||||
}
|
}
|
||||||
|
|
||||||
export const standardTokenApproval = async () => {
|
export const standardTokenApproval = async (contract, amount = '10000000') => {
|
||||||
const { approve } = SNT.methods
|
const { methods: { approve } } = contract || SNT
|
||||||
const spender = LiquidPledging._address
|
const spender = LiquidPledging._address
|
||||||
return await approve(
|
return await approve(
|
||||||
spender,
|
spender,
|
||||||
web3.utils.toWei('10000000', 'tether')
|
web3.utils.toWei(amount, 'tether')
|
||||||
).send()
|
).send()
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getLpAllowance = async () => {
|
export const getLpAllowance = async contract => {
|
||||||
const { allowance } = SNT.methods
|
const { methods: { allowance } } = contract || SNT
|
||||||
const account = await web3.eth.getCoinbase()
|
const account = await web3.eth.getCoinbase()
|
||||||
const spender = LiquidPledging._address
|
const spender = LiquidPledging._address
|
||||||
const allowanceAmt = Number(await allowance(account, spender).call())
|
const allowanceAmt = await allowance(account, spender).call()
|
||||||
return allowanceAmt
|
return allowanceAmt
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue