add deposit event parse

add admin bridge
This commit is contained in:
Barry Gitarts 2021-02-23 13:27:50 -05:00
parent 02a4db6b80
commit 0c14af3a47
5 changed files with 222 additions and 3 deletions

View File

@ -7,6 +7,7 @@ import { Provider, Web3Provider } from '@ethersproject/providers'
import { Symfoni } from "./hardhat/SymfoniContext";
import { Greeter } from './components/Greeter';
import { Bridge } from './components/Bridge';
import { AdminBridge } from './components/AdminBridge';
import { getAndSetProvider } from './utils/network';
import { ERC20 } from './types/ERC20';
import { Bridge as IBridge } from './types/Bridge';
@ -26,6 +27,7 @@ function App() {
const [sntAvalanche, setSntAvalanche] = useState<ERC20>();
const [ethereumBridge, setEthereumBridge] = useState<IBridge>();
const [avalancheBridge, setAvalancheBridge] = useState<IBridge>();
const [isRelayer, setIsRelayer] = useState<boolean>();
useEffect(() => {
if (!provider) getAndSetProvider(setProvider);
@ -44,10 +46,11 @@ function App() {
}, [provider])
useEffect(() => {
//TODO use ethereum provider
if (!provider) return
//TODO implement ava bridge
const avalancheBridge: IBridge = getBridge(fujiAddress, fujiProvider);
avalancheBridge.isRelayer(account).then(isRelayer => {
setIsRelayer(isRelayer)
});
const ethereumBridge: IBridge = getBridge(ethereumAddress, provider);
setEthereumBridge(ethereumBridge);
setAvalancheBridge(avalancheBridge);
@ -77,6 +80,12 @@ function App() {
sntAvalanche={sntAvalanche}
ethereumBridge={ethereumBridge}
/>}
{!!isRelayer && <AdminBridge
account={account}
provider={provider}
sntEthereum={sntEthereum}
sntAvalanche={sntAvalanche}
ethereumBridge={ethereumBridge} />}
</div>
</Symfoni>
</ThemeProvider>

View File

@ -0,0 +1,155 @@
import React, { useContext, useEffect, useState } from 'react';
import { BridgeContext, SymfoniBridge } from "./../hardhat/SymfoniContext";
import { Wallet, providers, Contract, VoidSigner, BigNumberish } from "ethers";
import Typography from '@material-ui/core/Typography';
import { Bridge as IBridge } from "../types/Bridge"
import { SNT_ADDRESS } from "../constants/goerliAddress";
import { Formik, FormikProps } from 'formik';
import StatusTextField from './base/TextField';
import useStyles from '../styles/adminBridge';
import StatusButton from './base/Button';
import { ETHEREUM_CHAIN_ID, AVA_CHAIN_ID } from '../constants/networks';
import { createResourceID, createERCDepositData, toWei } from '../utils/helpers';
import { Web3Provider } from '@ethersproject/providers';
import { ERC20 } from "../types/ERC20";
import { fromWei } from "../utils/helpers"
import { getSetBalance } from "../utils/contracts";
import { ethereumSNTHandlerAddress } from "../constants/bridges";
import { getDepositEvents, EnrichedEvent } from "../utils/events";
type IBridgeInfo = {
amount: string,
account: string,
}
const wallet = Wallet.createRandom();
interface Props {
account: string,
provider: Web3Provider | undefined,
sntEthereum: ERC20 | undefined,
sntAvalanche: ERC20 | undefined,
ethereumBridge: IBridge | undefined,
}
const FUJI_BRIDGE = '0xE57Eb49689bCAE4dE61D326F7E79Bd14aB527f0f';
const GOERLI_BRIDGE = '0xD0E461b1Dc56503fC72565FA964C28E274146D44';
const fujiProvider = new providers.JsonRpcProvider("https://api.avax-test.network/ext/bc/C/rpc");
const goerliProvider = new providers.InfuraProvider("goerli");
const fujiSigner = new Wallet(wallet.privateKey, fujiProvider);
const fujiVoidSigner = new VoidSigner(wallet.address, fujiProvider);
const goerliVoidsigner = new VoidSigner(wallet.address, goerliProvider);
export const AdminBridge: React.FC<Props> = ({ account, provider, sntEthereum, sntAvalanche, ethereumBridge }) => {
const classes: any = useStyles()
const bridge: SymfoniBridge = useContext(BridgeContext);
const [message, setMessage] = useState("");
const [inputGreeting, setInputGreeting] = useState("");
const [goerliBridge, setGoerliBridge] = useState<IBridge>();
const [fujiBridge, setFujiBridge] = useState<IBridge>();
const [sntEthereumBalance, setSntEthereumBalance] = useState<BigNumberish>();
const [sntAvalancheBalance, setSntAvalancheBalance] = useState<BigNumberish>();
const [deposits, setDeposits] = useState<EnrichedEvent[]>();
const { fieldWidth } = classes;
useEffect(() => {
getDepositEvents(ethereumBridge, setDeposits)
const doAsync = async () => {
if (!bridge.instance) return
console.log("Bridge is deployed at ", bridge.instance.address)
let gBridge = new Contract(
GOERLI_BRIDGE,
bridge.instance.interface,
goerliVoidsigner
) as IBridge;
setGoerliBridge(gBridge);
let fBridge = new Contract(
FUJI_BRIDGE,
bridge.instance.interface,
fujiVoidSigner
) as IBridge;
setFujiBridge(fBridge);
};
doAsync();
}, [bridge])
useEffect(() => {
getSetBalance(sntEthereum, account, setSntEthereumBalance);
}, [account])
useEffect(() => {
getSetBalance(sntAvalanche, account, setSntAvalancheBalance);
}, [account])
return (
<Formik
initialValues={{
amount: '',
account
}}
onSubmit={async (values) => {
const { amount, account } = values;
const weiAmount = toWei(amount);
const resourceId = createResourceID(SNT_ADDRESS, ETHEREUM_CHAIN_ID);
const encodedData = createERCDepositData(toWei(amount), account);
if (!provider) return;
const signer = provider.getSigner()
const sntActiveProvider = sntEthereum?.connect(signer);
const activeBridge = ethereumBridge?.connect(signer);
if(!bridge || !bridge.instance) return
const approved = await sntActiveProvider?.allowance(account, ethereumSNTHandlerAddress);
if (approved?.lt(weiAmount)) {
const amt = approved.eq(0) ? weiAmount : toWei('0');
//TODO approve handler not bridge
await sntActiveProvider?.approve(ethereumSNTHandlerAddress, amt);
} else {
console.log({AVA_CHAIN_ID, resourceId, encodedData});
const deposit = await activeBridge?.deposit(
AVA_CHAIN_ID,
resourceId,
encodedData
);
if (deposit) {
const receipt = await deposit.wait(1);
console.log({receipt});
}
}
}}
>
{({
values,
errors,
handleSubmit,
handleChange,
handleBlur,
setFieldValue
}: FormikProps<IBridgeInfo>) => {
return (
<form className={classes.root} onSubmit={handleSubmit}>
<StatusTextField
className={fieldWidth}
name="amount"
label="Enter amount of SNT to send across bridge"
idFor="amount"
onChange={handleChange}
onBlur={handleBlur}
value={values.amount}
/>
<StatusTextField
className={fieldWidth}
name="account"
label="account receiving across bridge"
idFor="account"
onChange={handleChange}
onBlur={handleBlur}
value={values.account}
/>
<StatusButton
className={fieldWidth}
buttonText="Submit"
onClick={handleSubmit}
/>
</form>
)}
}
</Formik>
)
}

View File

@ -0,0 +1,34 @@
import { makeStyles } from '@material-ui/core/styles'
const useStyles = makeStyles(theme => ({
root: {
display: 'grid',
gridTemplateColumns: 'repeat(48, [col] 1fr)',
gridColumn: '3 / 45',
[theme.breakpoints.up('md')]: {
gridTemplateRows: '3rem 6rem 6rem 5rem',
gridColumn: '8 / 42',
},
marginTop: '3rem'
},
adornmentText: {
cursor: 'pointer',
color: '#4360DF'
},
balanceText: {
color: '#025ea2',
gridColumn: '3 / 49',
fontSize: '1.5rem'
},
title: {
gridColumn: '3 / 49'
},
fieldWidth: {
gridColumn: '3 / 49'
},
datePicker: {
borderRadius: '25px'
}
}))
export default useStyles

View File

@ -6,7 +6,7 @@ const useStyles = makeStyles(theme => ({
gridTemplateColumns: 'repeat(48, [col] 1fr)',
gridTemplateRows: '3rem 5rem auto auto',
[theme.breakpoints.up('md')]: {
gridTemplateRows: '4rem 4rem auto auto 6rem'
gridTemplateRows: '3rem 25rem'
}
}
}));

View File

@ -0,0 +1,21 @@
import { Bridge as IBridge } from "../types/Bridge";
import { Event } from "ethers";
export interface EnrichedEvent extends Event {
decoded?: Array<any>
}
export const getDepositEvents = async (ethereumBridge: IBridge|undefined, setState: Function) => {
if(!ethereumBridge) return
const events = ethereumBridge.filters.Deposit(null,null,null)
const deposits: Event[] = await ethereumBridge.queryFilter(events)
const enriched = deposits.map(d => {
const { data, topics, decode } = d
if (!decode) return
const decoded = decode(data, topics)
const newD: EnrichedEvent = d
newD.decoded = decoded
return newD
})
setState(enriched)
}