bridge_ui: initial commit

Change-Id: I35315035270dece70c5dcb511f4b2e5c6494452b
This commit is contained in:
Evan Gray 2021-07-23 11:59:01 -04:00 committed by Evan Gray
parent 514560f52c
commit 5e37afdb82
23 changed files with 70010 additions and 0 deletions

27
bridge_ui/.gitignore vendored Normal file
View File

@ -0,0 +1,27 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# ethereum contracts
/contracts
/src/ethers-contracts

78
bridge_ui/README.md Normal file
View File

@ -0,0 +1,78 @@
# Getting Started with Create React App
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
## Available Scripts
In the project directory, you can run:
### `npm start`
Runs the app in the development mode.\
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
The page will reload if you make edits.\
You will also see any lint errors in the console.
### `npm test`
_Note: this first runs `build-contracts`_
Launches the test runner in the interactive watch mode.\
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
### `npm run build`
_Note: this first runs `build-contracts`_
Builds the app for production to the `build` folder.\
It correctly bundles React in production mode and optimizes the build for the best performance.
The build is minified and the filenames include the hashes.\
Your app is ready to be deployed!
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
### `npm run build-contracts`
This runs the build in the ethereum folder, copies the compiled contracts, and runs typechain on them. This is automatically run on `postinstall`
### `npm run eject`
**Note: this is a one-way operation. Once you `eject`, you cant go back!**
If you arent satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point youre on your own.
You dont have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldnt feel obligated to use this feature. However we understand that this tool wouldnt be useful if you couldnt customize it when you are ready for it.
## Learn More
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
To learn React, check out the [React documentation](https://reactjs.org/).
### Code Splitting
This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
### Analyzing the Bundle Size
This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
### Making a Progressive Web App
This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
### Advanced Configuration
This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
### Deployment
This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
### `npm run build` fails to minify
This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)

69356
bridge_ui/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

49
bridge_ui/package.json Normal file
View File

@ -0,0 +1,49 @@
{
"name": "test_ui",
"version": "0.1.0",
"private": true,
"dependencies": {
"@material-ui/core": "^4.12.2",
"@metamask/detect-provider": "^1.2.0",
"@project-serum/sol-wallet-adapter": "^0.2.5",
"@solana/wallet-base": "^0.0.1",
"@solana/web3.js": "^1.22.0",
"@typechain/ethers-v5": "^7.0.1",
"ethers": "^5.4.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "4.0.3"
},
"scripts": {
"postinstall": "npm run build-contracts",
"start": "react-scripts start",
"build": "npm run build-contracts && react-scripts build",
"test": "npm run build-contracts && react-scripts test",
"eject": "react-scripts eject",
"build-contracts": "npm run build --prefix ../ethereum && node scripts/copyContracts.js && typechain --target=ethers-v5 --out-dir=src/ethers-contracts contracts/*.json"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@openzeppelin/contracts": "^4.2.0",
"@truffle/hdwallet-provider": "^1.4.1",
"copy-dir": "^1.3.0",
"truffle": "^5.4.1"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -0,0 +1,44 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Wormhole Token Bridge"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" />
<title>Wormhole Token Bridge</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -0,0 +1,25 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#010114",
"background_color": "#010114"
}

View File

@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:

View File

@ -0,0 +1,2 @@
const copydir = require("copy-dir");
copydir.sync("../ethereum/build/contracts", "./contracts");

138
bridge_ui/src/App.js Normal file
View File

@ -0,0 +1,138 @@
import {
AppBar,
Button,
Grid,
Link,
makeStyles,
MenuItem,
TextField,
Toolbar,
Typography,
} from "@material-ui/core";
import { useCallback } from "react";
import EthereumSignerKey from "./components/EthereumSignerKey";
import SolanaWalletKey from "./components/SolanaWalletKey";
import { useEthereumProvider } from "./contexts/EthereumProviderContext";
import { Bridge__factory } from "./ethers-contracts";
import wormholeLogo from "./icons/wormhole.svg";
import { ETH_TOKEN_BRIDGE_ADDRESS } from "./utils/consts";
const useStyles = makeStyles((theme) => ({
appBar: {
borderBottom: `.5px solid ${theme.palette.divider}`,
"& > .MuiToolbar-root": {
height: 82,
margin: "auto",
maxWidth: 1100,
},
},
spacer: {
flex: 1,
width: "100vw",
},
link: {
color: theme.palette.text.primary,
marginLeft: theme.spacing(6),
},
sideBar: {
position: "fixed",
top: 0,
left: 0,
height: 733,
maxHeight: "80vh",
width: 50,
borderRight: `.5px solid ${theme.palette.divider}`,
borderBottom: `.5px solid ${theme.palette.divider}`,
},
content: {
margin: theme.spacing(10.5, 8),
},
transferBox: {
width: 540,
margin: "auto",
border: `.5px solid ${theme.palette.divider}`,
padding: theme.spacing(5.5, 12),
},
arrow: {
display: "flex",
alignItems: "center",
justifyContent: "center",
},
transferField: {
marginTop: theme.spacing(5),
},
transferButton: {
marginTop: theme.spacing(7.5),
textTransform: "none",
width: "100%",
},
}));
function App() {
const classes = useStyles();
const provider = useEthereumProvider();
const handleClick = useCallback(() => {
const bridge = Bridge__factory.connect(ETH_TOKEN_BRIDGE_ADDRESS, provider);
bridge.chainId().then((n) => console.log(n));
}, [provider]);
return (
<>
<AppBar position="static" color="inherit" className={classes.appBar}>
<Toolbar>
<img src={wormholeLogo} alt="Wormhole Logo" />
<div className={classes.spacer} />
<Link className={classes.link}>Placeholder</Link>
<Link className={classes.link}>Placeholder</Link>
<Link className={classes.link}>Placeholder</Link>
</Toolbar>
</AppBar>
<div className={classes.sideBar}></div>
<div className={classes.content}>
<div className={classes.transferBox}>
<Grid container>
<Grid item xs={4}>
<Typography>To</Typography>
<TextField select fullWidth value="ETH">
<MenuItem value="ETH">Ethereum</MenuItem>
<MenuItem value="SOL">Solana</MenuItem>
</TextField>
<EthereumSignerKey />
</Grid>
<Grid item xs={4} className={classes.arrow}>
&rarr;
</Grid>
<Grid item xs={4}>
<Typography>From</Typography>
<TextField select fullWidth value="SOL">
<MenuItem value="ETH">Ethereum</MenuItem>
<MenuItem value="SOL">Solana</MenuItem>
</TextField>
<SolanaWalletKey />
</Grid>
</Grid>
<TextField
placeholder="Asset"
fullWidth
className={classes.transferField}
/>
<TextField
placeholder="Amount"
type="number"
fullWidth
className={classes.transferField}
/>
<Button
color="primary"
variant="contained"
className={classes.transferButton}
onClick={handleClick}
>
Transfer
</Button>
</div>
</div>
</>
);
}
export default App;

View File

@ -0,0 +1,34 @@
import { Typography } from "@material-ui/core";
import { useEffect, useState } from "react";
import { useEthereumProvider } from "../contexts/EthereumProviderContext";
const EthereumSignerKey = () => {
const provider = useEthereumProvider();
const [pk, setPk] = useState("");
// TODO: should this be moved to the context?
useEffect(() => {
let mounted = true;
provider
?.getSigner()
.getAddress()
.then((pk) => {
if (mounted) {
setPk(pk);
}
})
.catch(() => {
console.error("Failed to get signer address");
});
return () => {
mounted = false;
};
}, [provider]);
if (!pk) return null;
return (
<Typography>
{pk.substring(0, 6)}...{pk.substr(pk.length - 4)}
</Typography>
);
};
export default EthereumSignerKey;

View File

@ -0,0 +1,15 @@
import { Typography } from "@material-ui/core";
import { useSolanaWallet } from "../contexts/SolanaWalletContext";
const SolanaWalletKey = () => {
const { wallet } = useSolanaWallet();
const pk = wallet?.publicKey?.toString();
if (!pk) return null;
return (
<Typography>
{pk.substring(0, 3)}...{pk.substr(pk.length - 3)}
</Typography>
);
};
export default SolanaWalletKey;

View File

@ -0,0 +1,56 @@
import detectEthereumProvider from "@metamask/detect-provider";
import { ethers } from "ethers";
import React, { ReactChildren, useContext, useEffect, useState } from "react";
type Provider = ethers.providers.Web3Provider | undefined;
const EthereumProviderContext = React.createContext<Provider>(undefined);
export const EthereumProviderProvider = ({
children,
}: {
children: ReactChildren;
}) => {
const [provider, setProvider] = useState<Provider>(undefined);
useEffect(() => {
let mounted = true;
detectEthereumProvider()
.then((detectedProvider) => {
if (detectedProvider) {
if (mounted) {
const ethersProvider = new ethers.providers.Web3Provider(
// @ts-ignore
detectedProvider
);
ethersProvider
.send("eth_requestAccounts", [])
.then(() => {
if (mounted) {
setProvider(ethersProvider);
}
})
.catch(() => {
console.error(
"An error occurred while requesting eth accounts"
);
});
}
} else {
console.log("Please install MetaMask");
}
})
.catch(() => console.log("Please install MetaMask"));
return () => {
mounted = false;
};
}, []);
//TODO: useEffect provider.on("network") to refresh on network changes
//TODO: detect account change
return (
<EthereumProviderContext.Provider value={provider}>
{children}
</EthereumProviderContext.Provider>
);
};
export const useEthereumProvider = () => {
return useContext(EthereumProviderContext);
};

View File

@ -0,0 +1,57 @@
import React, {
ReactChildren,
useContext,
useEffect,
useMemo,
useState,
} from "react";
import Wallet from "@project-serum/sol-wallet-adapter";
import { SOLANA_HOST } from "../utils/consts";
interface ISolanaWalletContext {
connected: boolean;
wallet: Wallet | undefined;
}
const getDefaultWallet = () => new Wallet("https://www.sollet.io", SOLANA_HOST);
const SolanaWalletContext = React.createContext<ISolanaWalletContext>({
connected: false,
wallet: undefined,
});
export const SolanaWalletProvider = ({
children,
}: {
children: ReactChildren;
}) => {
const wallet = useMemo(getDefaultWallet, []);
const [connected, setConnected] = useState(false);
useEffect(() => {
wallet.on("connect", () => {
setConnected(true);
console.log("Connected to wallet " + wallet.publicKey?.toBase58());
});
wallet.on("disconnect", () => {
setConnected(false);
console.log("Disconnected from wallet");
});
wallet.connect();
return () => {
wallet.disconnect();
};
}, [wallet]);
console.log(`Connected state: ${connected}`);
//TODO: useEffect to refresh on network changes
// ensure users of the context refresh on connect state change
const contextValue = useMemo(
() => ({ connected, wallet }),
[wallet, connected]
);
return (
<SolanaWalletContext.Provider value={contextValue}>
{children}
</SolanaWalletContext.Provider>
);
};
export const useSolanaWallet = () => {
return useContext(SolanaWalletContext);
};

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 25.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 34 34" style="enable-background:new 0 0 34 34;" xml:space="preserve">
<style type="text/css">
.st0{clip-path:url(#SVGID_2_);}
.st1{fill:#FD3503;}
.st2{fill:#0074FF;}
.st3{fill:#00EFD8;}
</style>
<g>
<defs>
<rect id="SVGID_1_" x="3" y="0.5" width="178" height="33"/>
</defs>
<clipPath id="SVGID_2_">
<use xlink:href="#SVGID_1_" style="overflow:visible;"/>
</clipPath>
<g class="st0">
<path class="st1" d="M14.4,17c0-5.2-2-10.1-5.6-13.8C8.7,3,8.5,3,8.3,3H3.7C3.5,3,3.3,3,3.2,3.2C3.1,3.3,3,3.5,3,3.7v4.8
c0,0.2,0.1,0.3,0.2,0.5C3.3,9,3.5,9.1,3.6,9.1c2,0.2,3.8,1.1,5.2,2.5c1.3,1.5,2.1,3.4,2.1,5.4c0,2-0.7,3.9-2.1,5.4
c-1.3,1.5-3.2,2.4-5.2,2.5c-0.2,0-0.3,0.1-0.5,0.2C3.1,25.2,3,25.4,3,25.6v4.8c0,0.1,0,0.2,0.1,0.3c0,0.1,0.1,0.2,0.1,0.2
C3.3,30.9,3.3,31,3.4,31S3.6,31,3.7,31h4.6c0.2,0,0.4-0.1,0.5-0.2C12.4,27.1,14.4,22.2,14.4,17z"/>
<path class="st2" d="M31,25.6c0-0.2-0.1-0.3-0.2-0.5c-0.1-0.1-0.3-0.2-0.5-0.2c-2-0.2-3.8-1.1-5.2-2.5c-1.3-1.5-2.1-3.4-2.1-5.4
c0-2,0.7-3.9,2.1-5.4c1.3-1.5,3.2-2.4,5.2-2.5c0.2,0,0.3-0.1,0.5-0.2C30.9,8.8,31,8.6,31,8.4V3.7c0-0.2-0.1-0.4-0.2-0.5
C30.7,3,30.5,3,30.3,3h-4.6c-0.2,0-0.4,0.1-0.5,0.2c-3.6,3.7-5.6,8.7-5.6,13.8c0,5.2,2,10.1,5.6,13.8c0.1,0.1,0.3,0.2,0.5,0.2h4.6
c0.2,0,0.4-0.1,0.5-0.2c0.1-0.1,0.2-0.3,0.2-0.5V25.6z"/>
<path class="st3" d="M13.5,0.5c-0.1,0-0.3,0-0.4,0.1c-0.1,0.1-0.2,0.1-0.3,0.3s-0.1,0.2-0.1,0.4c0,0.1,0,0.3,0,0.4
c1.9,4.9,2.9,10.2,2.9,15.4c0,5.3-1,10.5-2.9,15.4c0,0.1-0.1,0.2,0,0.4c0,0.1,0.1,0.2,0.1,0.4s0.2,0.2,0.3,0.3
c0.1,0.1,0.2,0.1,0.4,0.1h7c0.1,0,0.3,0,0.4-0.1c0.1-0.1,0.2-0.1,0.3-0.3c0.1-0.1,0.1-0.2,0.1-0.4c0-0.1,0-0.3-0.1-0.4
c-1.9-4.9-2.9-10.2-2.9-15.4c0-5.3,1-10.5,2.9-15.4c0-0.1,0.1-0.2,0.1-0.4c0-0.1-0.1-0.2-0.1-0.4c-0.1-0.1-0.2-0.2-0.3-0.3
s-0.2-0.1-0.4-0.1H13.5z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -0,0 +1,20 @@
<svg width="178" height="33" viewBox="0 0 178 33" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0)">
<path d="M48.5187 22.3901H47.9445L44.817 9.57212H41.0327L38.3514 22.3901H37.7772L34.1085 9.047H31.4272L35.823 24.6022H36.4634H37.8887H38.3845H39.6941H40.1899L42.929 11.6685L46.0977 24.6022H46.6803H47.9899H48.4857H49.911H50.4357L54.2448 9.047H51.7123L48.5187 22.3901Z" fill="white"/>
<path d="M71.0428 11.0442C70.3028 10.2612 69.4117 9.63658 68.4235 9.20832C67.3095 8.73612 66.1091 8.50236 64.8994 8.52198C63.691 8.50159 62.4918 8.73539 61.3795 9.20832C60.3901 9.63454 59.4987 10.2594 58.7602 11.0442C58.0515 11.7928 57.497 12.6738 57.1283 13.6368C56.7649 14.57 56.5772 15.5625 56.5747 16.5642V17.0893C56.5793 18.0785 56.7612 19.0588 57.1118 19.9837C57.4743 20.9382 58.0187 21.8131 58.7148 22.5597C59.4496 23.3473 60.3364 23.9775 61.3217 24.4121C62.4509 24.8975 63.6707 25.1358 64.8994 25.1109C66.1294 25.1347 67.3504 24.8965 68.4813 24.4121C69.4641 23.9753 70.3492 23.3454 71.0841 22.5597C71.7802 21.8139 72.3234 20.9387 72.6829 19.9837C73.0369 19.0596 73.2203 18.0789 73.2241 17.0893V16.5642C73.2217 15.5625 73.034 14.57 72.6705 13.6368C72.3022 12.6745 71.7492 11.7938 71.0428 11.0442ZM69.7744 19.7687C69.3501 20.6219 68.6944 21.3383 67.8823 21.8361C66.9818 22.3726 65.947 22.6409 64.8994 22.6093C63.8518 22.6413 62.8169 22.3731 61.9166 21.8361C61.1045 21.3383 60.4488 20.6219 60.0244 19.7687C59.5774 18.8526 59.3523 17.844 59.3675 16.8247C59.3493 15.7939 59.5804 14.774 60.0409 13.8518C60.4697 12.9937 61.1349 12.2763 61.9579 11.7844C62.8498 11.2651 63.8679 11.0031 64.8994 11.0277C65.9353 10.9995 66.9584 11.2616 67.8534 11.7844C68.6699 12.2805 69.33 12.9971 69.7579 13.8518C70.2185 14.774 70.4495 15.7939 70.4313 16.8247C70.4465 17.844 70.2215 18.8526 69.7744 19.7687Z" fill="white"/>
<path d="M81.0079 10.4612C80.2202 11.3802 79.7379 12.5218 79.628 13.7277V9.04708H77.4136V24.6023H80.2105V16.1837C80.2105 14.629 80.6237 13.4424 81.4499 12.6154C82.2762 11.7885 83.4784 11.375 85.0318 11.375H86.0234V8.86926H85.4987C83.5046 8.87202 82.0077 9.40264 81.0079 10.4612Z" fill="white"/>
<path d="M109.981 9.42741C109.073 8.84226 108.007 8.55333 106.928 8.60045H106.812C105.736 8.55203 104.672 8.84114 103.768 9.42741C102.929 10.0346 102.295 10.8825 101.95 11.8587C101.875 12.0489 101.818 12.2722 101.756 12.4665C101.698 12.2598 101.64 12.053 101.57 11.8587C101.242 10.881 100.616 10.0308 99.7808 9.42741C98.8782 8.8412 97.8151 8.55207 96.7401 8.60045H96.6245C95.5533 8.55076 94.4937 8.84011 93.5962 9.42741C92.7653 10.0355 92.1409 10.8841 91.8073 11.8587C91.7099 12.1185 91.6272 12.3835 91.5594 12.6526V9.04704H89.3491V24.6022H92.1626V15.2823C92.1626 13.9799 92.5096 12.9668 93.212 12.2391C93.5704 11.8731 94.0017 11.5865 94.4777 11.3978C94.9538 11.209 95.4642 11.1224 95.9758 11.1434C96.4571 11.1169 96.9383 11.196 97.3858 11.3753C97.8333 11.5546 98.2362 11.8296 98.5662 12.1812C99.1859 12.8676 99.4958 13.8434 99.4958 15.1087V24.6187H102.293V15.2989C102.293 13.995 102.641 12.9806 103.338 12.2556C103.696 11.8896 104.128 11.6031 104.604 11.4143C105.08 11.2256 105.59 11.1389 106.102 11.1599C106.583 11.1334 107.064 11.2126 107.512 11.3919C107.959 11.5711 108.362 11.8462 108.692 12.1978C109.317 12.8842 109.629 13.86 109.626 15.1252V24.6353H112.406V15.7496C112.439 14.4385 112.237 13.1321 111.811 11.8918C111.475 10.8981 110.835 10.0358 109.981 9.42741Z" fill="white"/>
<path d="M125.379 8.5839H125.263C124.127 8.53453 123.005 8.85038 122.061 9.48527C121.266 10.0813 120.66 10.8937 120.314 11.8256V3.33679H117.521V24.6022H120.314V15.6296C120.26 14.4444 120.661 13.2834 121.433 12.3838C121.81 11.972 122.273 11.6477 122.788 11.4334C123.303 11.2191 123.859 11.1202 124.416 11.1433C124.922 11.1233 125.427 11.2061 125.899 11.3866C126.372 11.5671 126.804 11.8416 127.168 12.1936C127.536 12.5849 127.82 13.0477 128.003 13.5534C128.186 14.059 128.263 14.5968 128.229 15.1334V24.6022H131.026V15.7165C131.026 13.4258 130.55 11.6643 129.597 10.4322C128.644 9.19998 127.238 8.5839 125.379 8.5839Z" fill="white"/>
<path d="M149.448 11.0441C148.709 10.2602 147.818 9.6355 146.829 9.20825C145.717 8.73532 144.517 8.50152 143.309 8.52191C142.099 8.50106 140.899 8.73487 139.785 9.20825C138.796 9.6355 137.905 10.2602 137.166 11.0441C136.458 11.7926 135.905 12.6737 135.538 13.6367C135.172 14.5694 134.985 15.5623 134.984 16.5641V17.0892C134.987 18.0786 135.169 19.0593 135.521 19.9836C135.882 20.9389 136.427 21.8141 137.124 22.5596C137.858 23.3471 138.743 23.9773 139.727 24.412C140.858 24.8965 142.079 25.1347 143.309 25.1108C144.538 25.1348 145.757 24.8966 146.887 24.412C147.872 23.9764 148.758 23.3464 149.494 22.5596C150.189 21.813 150.732 20.9381 151.093 19.9836C151.445 19.0593 151.627 18.0786 151.63 17.0892V16.5641C151.629 15.5627 151.442 14.5702 151.08 13.6367C150.71 12.6743 150.156 11.7935 149.448 11.0441ZM148.184 19.7686C147.758 20.6209 147.103 21.3371 146.292 21.836C145.391 22.3719 144.357 22.6401 143.309 22.6092C142.261 22.6413 141.227 22.373 140.326 21.836C139.513 21.3393 138.857 20.6226 138.434 19.7686C137.987 18.8526 137.762 17.844 137.777 16.8246C137.76 15.7943 137.989 14.7749 138.446 13.8517C138.878 12.9943 139.544 12.2773 140.368 11.7843C141.259 11.2646 142.278 11.0026 143.309 11.0276C144.345 10.9994 145.368 11.2615 146.263 11.7843C147.079 12.2816 147.738 12.9979 148.168 13.8517C148.625 14.7749 148.854 15.7943 148.837 16.8246C148.851 17.8434 148.628 18.8516 148.184 19.7686Z" fill="white"/>
<path d="M153.844 3.34094V5.55307H155.996V24.6022H158.789V5.55307V3.34094H155.996H153.844Z" fill="white"/>
<path d="M178 16.0969C178.008 14.8286 177.735 13.5744 177.198 12.4252C176.663 11.2781 175.817 10.3041 174.757 9.61351C173.503 8.84431 172.05 8.46443 170.58 8.52192C169.412 8.49533 168.254 8.72978 167.188 9.20826C166.269 9.63187 165.458 10.2598 164.817 11.0441C164.196 11.8069 163.726 12.6812 163.433 13.6201C163.132 14.5723 162.98 15.5654 162.982 16.5641V17.0893C162.983 18.0715 163.135 19.0477 163.433 19.9836C163.726 20.9226 164.196 21.7969 164.817 22.5596C165.47 23.354 166.297 23.9878 167.234 24.412C168.341 24.9012 169.543 25.1399 170.754 25.1108C171.885 25.1319 173.009 24.9238 174.059 24.4989C174.998 24.1132 175.827 23.5027 176.475 22.7209C177.127 21.9206 177.567 20.9695 177.756 19.9547H175.137C174.934 20.7396 174.439 21.4172 173.753 21.8484C172.869 22.4291 171.826 22.7183 170.77 22.6754C169.75 22.7199 168.74 22.45 167.878 21.9022C167.127 21.3881 166.55 20.6567 166.226 19.8058C165.914 19.0139 165.738 18.1752 165.705 17.3249H178.025L178 16.0969ZM167.829 11.7264C168.646 11.196 169.607 10.9316 170.58 10.9697C171.509 10.9335 172.428 11.1661 173.228 11.6395C173.931 12.0916 174.479 12.7482 174.798 13.5209C175.029 14.074 175.179 14.6575 175.244 15.2534H165.788C165.872 14.7532 166.01 14.2638 166.201 13.7938C166.528 12.9592 167.094 12.2399 167.829 11.7264Z" fill="white"/>
<path d="M11.4106 16.4979C11.4209 11.3373 9.41314 6.37758 5.81677 2.6794C5.68541 2.54747 5.5071 2.47311 5.321 2.47266H0.702138C0.519155 2.47266 0.343676 2.54541 0.214287 2.67491C0.0848984 2.8044 0.012207 2.98 0.012207 3.16314V7.91404C0.0128761 8.08995 0.0801841 8.25908 0.20057 8.38724C0.320955 8.5154 0.485455 8.59306 0.660835 8.60458C2.64046 8.76756 4.48639 9.66985 5.83195 11.1322C7.17751 12.5946 7.92422 14.51 7.92376 16.4979C7.92422 18.4859 7.17751 20.4014 5.83195 21.8637C4.48639 23.3261 2.64046 24.2284 0.660835 24.3913C0.485802 24.4038 0.321872 24.4817 0.201679 24.6097C0.0814862 24.7376 0.0138413 24.9062 0.012207 25.0818V29.8534C0.012207 29.9441 0.030059 30.0339 0.0647317 30.1177C0.0994043 30.2014 0.15022 30.2776 0.214287 30.3417C0.278354 30.4058 0.354396 30.4567 0.438103 30.4914C0.52181 30.5261 0.611534 30.544 0.702138 30.544H5.321C5.5071 30.5435 5.68541 30.4691 5.81677 30.3372C9.4189 26.6344 11.4272 21.6659 11.4106 16.4979Z" fill="#FD3503"/>
<path d="M28.0271 25.0818C28.0254 24.9062 27.9578 24.7376 27.8376 24.6097C27.7174 24.4817 27.5535 24.4038 27.3784 24.3913C25.3992 24.2274 23.5538 23.3249 22.2084 21.8627C20.863 20.4006 20.116 18.4856 20.1155 16.4979C20.116 14.5102 20.863 12.5954 22.2084 11.1332C23.5538 9.67107 25.3992 8.76849 27.3784 8.60458C27.5538 8.59306 27.7183 8.5154 27.8387 8.38724C27.9591 8.25908 28.0264 8.08995 28.0271 7.91404V3.16314C28.0271 2.98 27.9544 2.8044 27.825 2.67491C27.6956 2.54541 27.5201 2.47266 27.3371 2.47266H22.7182C22.5322 2.47311 22.3539 2.54747 22.2225 2.6794C18.6216 6.37559 16.6093 11.3356 16.6162 16.4979C16.6084 21.6605 18.6209 26.6208 22.2225 30.3165C22.3539 30.4485 22.5322 30.5228 22.7182 30.5233H27.3371C27.5201 30.5233 27.6956 30.4505 27.825 30.321C27.9544 30.1915 28.0271 30.0159 28.0271 29.8327V25.0818Z" fill="#0074FF"/>
<path d="M10.4898 0C10.3629 0.000640413 10.2382 0.0321867 10.1263 0.0919129C10.0144 0.151639 9.91871 0.237725 9.84752 0.342768C9.77633 0.447811 9.73178 0.568628 9.71771 0.694773C9.70364 0.820918 9.72048 0.948599 9.76678 1.06677C11.6862 5.98497 12.6739 11.2178 12.6794 16.4979C12.6738 21.7793 11.6862 27.0135 9.76678 31.9332C9.72048 32.0514 9.70364 32.1791 9.71771 32.3052C9.73178 32.4313 9.77633 32.5522 9.84752 32.6572C9.91871 32.7622 10.0144 32.8483 10.1263 32.9081C10.2382 32.9678 10.3629 32.9993 10.4898 33H17.5131C17.6399 32.9996 17.7647 32.9683 17.8766 32.9085C17.9885 32.8488 18.0841 32.7625 18.155 32.6573C18.226 32.5521 18.27 32.431 18.2834 32.3048C18.2968 32.1786 18.2792 32.051 18.2319 31.9332C16.3196 27.0122 15.339 21.778 15.34 16.4979C15.3389 11.2191 16.3196 5.98632 18.2319 1.06677C18.2792 0.94896 18.2968 0.821348 18.2834 0.695126C18.27 0.568905 18.226 0.447903 18.155 0.342667C18.0841 0.237431 17.9885 0.151197 17.8766 0.0914587C17.7647 0.0317204 17.6399 0.000325328 17.5131 0H10.4898Z" fill="#00EFD8"/>
</g>
<defs>
<clipPath id="clip0">
<rect width="178" height="33" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 9.5 KiB

19
bridge_ui/src/index.js Normal file
View File

@ -0,0 +1,19 @@
import { CssBaseline } from "@material-ui/core";
import { ThemeProvider } from "@material-ui/core/styles";
import ReactDOM from "react-dom";
import App from "./App";
import { EthereumProviderProvider } from "./contexts/EthereumProviderContext";
import { SolanaWalletProvider } from "./contexts/SolanaWalletContext.tsx";
import { theme } from "./muiTheme";
ReactDOM.render(
<ThemeProvider theme={theme}>
<CssBaseline />
<SolanaWalletProvider>
<EthereumProviderProvider>
<App />
</EthereumProviderProvider>
</SolanaWalletProvider>
</ThemeProvider>,
document.getElementById("root")
);

24
bridge_ui/src/muiTheme.js Normal file
View File

@ -0,0 +1,24 @@
import { createTheme, responsiveFontSizes } from "@material-ui/core";
export const theme = responsiveFontSizes(
createTheme({
palette: {
type: "dark",
background: {
default: "#010114",
paper: "#010114",
},
divider: "#FFFFFF",
primary: {
main: "#0074FF",
},
},
overrides: {
MuiButton: {
root: {
borderRadius: 0,
},
},
},
})
);

1
bridge_ui/src/react-app-env.d.ts vendored Normal file
View File

@ -0,0 +1 @@
/// <reference types="react-scripts" />

View File

@ -0,0 +1,2 @@
export const SOLANA_HOST = 'http://localhost:8899'
export const ETH_TOKEN_BRIDGE_ADDRESS = "0x254dffcd3277c0b1660f6d42efbb754edababc2b"

26
bridge_ui/tsconfig.json Normal file
View File

@ -0,0 +1,26 @@
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
},
"include": [
"src"
]
}