Web page to publish message to ETH

Change-Id: Ia775175c5134c949ec1630ea3ad5a254275fe570
This commit is contained in:
Justin Schuldt 2021-07-02 13:24:33 -05:00 committed by Hendrik Hofstadt
parent 366a045dd4
commit 3fd60e822a
4 changed files with 115 additions and 6 deletions

View File

@ -44,7 +44,10 @@
"eject": "react-scripts eject",
"ethers": "typechain --target ethers-v4 --outDir src/contracts 'contracts/*.json'",
"deploy": "gh-pages -d build",
"deploy:ar": "arweave deploy-dir build --key-file "
"deploy:ar": "arweave deploy-dir build --key-file ",
"rm-contracts": "rm -rf src/contracts && rm -rf contracts",
"import-contracts": "mkdir -p ./contracts && cp -r ../ethereum/build/contracts/* ./contracts/ && npm run ethers",
"refresh-contracts": "npm run rm-contracts && npm run import-contracts"
},
"eslintConfig": {
"extends": "react-app"

View File

@ -12,6 +12,7 @@ import WalletContext from '../providers/WalletContext';
import Wallet from "@project-serum/sol-wallet-adapter";
import {BridgeProvider} from "../providers/BridgeContext";
import Assistant from "../pages/Assistant";
import Message from "../pages/Message";
import {SOLANA_HOST} from "../config";
const {Header, Content, Footer} = Layout;
@ -39,7 +40,8 @@ function App() {
<Layout style={{height: '100%'}}>
<HashRouter basename={"/"}>
<Header style={{position: 'fixed', zIndex: 1, width: '100%'}}>
<Link to="/" style={{paddingRight: 20}}>Assistant</Link>
<Link to="/" style={{paddingRight: 20}}>Message</Link>
<Link to="/assistant" style={{paddingRight: 20}}>Assistant</Link>
<Link to="/eth" style={{paddingRight: 20}}>Ethereum</Link>
<Link to="/solana">Solana</Link>
{
@ -63,7 +65,7 @@ function App() {
<BridgeProvider>
<SolanaTokenProvider>
<Switch>
<Route path="/">
<Route path="/assistant">
<Assistant/>
</Route>
<Route path="/solana">
@ -72,6 +74,9 @@ function App() {
<Route path="/eth">
<Transfer/>
</Route>
<Route path="/">
<Message/>
</Route>
</Switch>
</SolanaTokenProvider>
</BridgeProvider>

View File

@ -1,13 +1,13 @@
import {PublicKey} from "@solana/web3.js";
const BRIDGE_ADDRESS = "0xf92cD566Ea4864356C5491c177A430C222d7e678";
const BRIDGE_ADDRESS = "0x254dffcd3277c0b1660f6d42efbb754edababc2b";
const WRAPPED_MASTER = "9A5e27995309a03f8B583feBdE7eF289FcCdC6Ae"
const SOLANA_BRIDGE_PROGRAM = new PublicKey("WormT3McKhFJ2RkiGpdw9GKvNCrB2aB54gb2uV9MfQC");
const SOLANA_BRIDGE_PROGRAM = new PublicKey("Bridge1p5gheXUvJ6jGWGeCsgPKgnE3YgdGKRVCMY9o");
const TOKEN_PROGRAM = new PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
const SOLANA_HOST = "https://solana-api.projectserum.com";
const SOLANA_HOST = "http://localhost:8899";
export {
BRIDGE_ADDRESS,

101
web/src/pages/Message.tsx Normal file
View File

@ -0,0 +1,101 @@
import React, { useState, useEffect } from 'react';
import { Form, Input, Button, List } from 'antd';
import { ethers } from "ethers";
import { BRIDGE_ADDRESS } from "../config";
import { ImplementationFactory } from '../contracts/ImplementationFactory';
// @ts-ignore
if (window.ethereum === undefined) {
alert("Please install the MetaMask extension before using this experimental demo web UI");
}
// @ts-ignore
window.ethereum.enable();
// @ts-ignore
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();
function Message() {
const [form] = Form.useForm();
const [, forceUpdate] = useState({});
// map: { txHash: payloadString }
const [txHashToPayload, setTxHashToPayload] = useState<{ [txHash: string]: string }>({})
// To disable submit button at the beginning.
useEffect(() => {
forceUpdate({});
}, []);
const sendMessage = async ({ payload }: { payload: string }) => {
let nonceConst = Math.random() * 100000
let nonceBuffer = Buffer.alloc(4);
nonceBuffer.writeUInt32LE(nonceConst, 0)
let i = ImplementationFactory.connect(BRIDGE_ADDRESS, signer)
let res = await i.publishMessage(nonceBuffer, Buffer.from(payload, 'utf16le'), true)
await res.wait(1)
if (res.hash) {
setTxHashToPayload({ ...txHashToPayload, [res.hash]: payload })
}
form.resetFields(['payload'])
}
const rmTxHash = (txHash: string) => {
const { [txHash]: rm, ...others } = txHashToPayload
setTxHashToPayload(others)
return undefined // for typescript
}
return (
<>
<Form form={form} name="publish_message" layout="inline" onFinish={sendMessage}>
<Form.Item>
<h1><code>publishMessage</code></h1>
</Form.Item>
<Form.Item
name="payload"
rules={[{ required: true, message: 'Please enter a payload for the message.' }]}
>
<Input.TextArea placeholder="Payload to write to ETH" />
</Form.Item>
<Form.Item shouldUpdate>
{() => (
<Button
type="primary"
htmlType="submit"
disabled={
!form.isFieldsTouched(true) ||
!!form.getFieldsError().filter(({ errors }) => errors.length).length
}
>
Send to MetaMask
</Button>
)}
</Form.Item>
</Form>
{Object.keys(txHashToPayload).length >= 1 ? (
<List
dataSource={Object.keys(txHashToPayload)}
renderItem={item => (
<List.Item
actions={[<a onClick={() => rmTxHash(item)} >X</a>]}
>
<div style={{ display: 'flex', justifyContent: 'space-between', width: '100%' }}>
<h4><code>{item}</code></h4>
<h4><code><pre>{txHashToPayload[item]}</pre></code></h4>
</div>
</List.Item>
)}
/>
) : null}
</>
);
}
export default Message;