Web page to publish message to ETH
Change-Id: Ia775175c5134c949ec1630ea3ad5a254275fe570
This commit is contained in:
parent
366a045dd4
commit
3fd60e822a
|
@ -44,7 +44,10 @@
|
||||||
"eject": "react-scripts eject",
|
"eject": "react-scripts eject",
|
||||||
"ethers": "typechain --target ethers-v4 --outDir src/contracts 'contracts/*.json'",
|
"ethers": "typechain --target ethers-v4 --outDir src/contracts 'contracts/*.json'",
|
||||||
"deploy": "gh-pages -d build",
|
"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": {
|
"eslintConfig": {
|
||||||
"extends": "react-app"
|
"extends": "react-app"
|
||||||
|
|
|
@ -12,6 +12,7 @@ import WalletContext from '../providers/WalletContext';
|
||||||
import Wallet from "@project-serum/sol-wallet-adapter";
|
import Wallet from "@project-serum/sol-wallet-adapter";
|
||||||
import {BridgeProvider} from "../providers/BridgeContext";
|
import {BridgeProvider} from "../providers/BridgeContext";
|
||||||
import Assistant from "../pages/Assistant";
|
import Assistant from "../pages/Assistant";
|
||||||
|
import Message from "../pages/Message";
|
||||||
import {SOLANA_HOST} from "../config";
|
import {SOLANA_HOST} from "../config";
|
||||||
|
|
||||||
const {Header, Content, Footer} = Layout;
|
const {Header, Content, Footer} = Layout;
|
||||||
|
@ -39,7 +40,8 @@ function App() {
|
||||||
<Layout style={{height: '100%'}}>
|
<Layout style={{height: '100%'}}>
|
||||||
<HashRouter basename={"/"}>
|
<HashRouter basename={"/"}>
|
||||||
<Header style={{position: 'fixed', zIndex: 1, width: '100%'}}>
|
<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="/eth" style={{paddingRight: 20}}>Ethereum</Link>
|
||||||
<Link to="/solana">Solana</Link>
|
<Link to="/solana">Solana</Link>
|
||||||
{
|
{
|
||||||
|
@ -63,7 +65,7 @@ function App() {
|
||||||
<BridgeProvider>
|
<BridgeProvider>
|
||||||
<SolanaTokenProvider>
|
<SolanaTokenProvider>
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route path="/">
|
<Route path="/assistant">
|
||||||
<Assistant/>
|
<Assistant/>
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/solana">
|
<Route path="/solana">
|
||||||
|
@ -72,6 +74,9 @@ function App() {
|
||||||
<Route path="/eth">
|
<Route path="/eth">
|
||||||
<Transfer/>
|
<Transfer/>
|
||||||
</Route>
|
</Route>
|
||||||
|
<Route path="/">
|
||||||
|
<Message/>
|
||||||
|
</Route>
|
||||||
</Switch>
|
</Switch>
|
||||||
</SolanaTokenProvider>
|
</SolanaTokenProvider>
|
||||||
</BridgeProvider>
|
</BridgeProvider>
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import {PublicKey} from "@solana/web3.js";
|
import {PublicKey} from "@solana/web3.js";
|
||||||
|
|
||||||
const BRIDGE_ADDRESS = "0xf92cD566Ea4864356C5491c177A430C222d7e678";
|
const BRIDGE_ADDRESS = "0x254dffcd3277c0b1660f6d42efbb754edababc2b";
|
||||||
const WRAPPED_MASTER = "9A5e27995309a03f8B583feBdE7eF289FcCdC6Ae"
|
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 TOKEN_PROGRAM = new PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
|
||||||
|
|
||||||
const SOLANA_HOST = "https://solana-api.projectserum.com";
|
const SOLANA_HOST = "http://localhost:8899";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
BRIDGE_ADDRESS,
|
BRIDGE_ADDRESS,
|
||||||
|
|
|
@ -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;
|
Loading…
Reference in New Issue