Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(bridge): bridge design #369

Merged
merged 33 commits into from
Dec 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
aae1769
fix(bridge): wagmi init
shadab-taiko Nov 28, 2022
bebf14e
feat(bridge): implement design
shadab-taiko Nov 30, 2022
7b7bb89
feat(bridge): add processing fee mock
shadab-taiko Nov 30, 2022
b5d2258
Merge branch 'main' into bridge-design
shadab-taiko Nov 30, 2022
c894fd2
fix(bridge): review fixes
shadab-taiko Dec 1, 2022
ba42bc7
feat(bridge): add default case and test
shadab-taiko Dec 1, 2022
06bed43
fix(bridge): update test
shadab-taiko Dec 1, 2022
296b533
Merge branch 'main' into bridge-design
cyberhorsey Dec 1, 2022
bbf404f
feat(bridge): single field bridge form
shadab-taiko Dec 2, 2022
48f77c9
fix(bridge): processing fee
shadab-taiko Dec 2, 2022
fe29c86
Merge branch 'bridge-design' of github.com-taiko:taikochain/taiko-mon…
shadab-taiko Dec 2, 2022
53e3dd8
feat(bridge-ui): Transactions (#372)
cyberhorsey Dec 2, 2022
6973191
feat: add chain selector
shadab-taiko Dec 5, 2022
ae5b62e
Merge branch 'bridge-design' of github.com-taiko:taikochain/taiko-mon…
shadab-taiko Dec 5, 2022
8e3ca63
Merge branch 'main' of github.com-taiko:taikochain/taiko-mono into br…
shadab-taiko Dec 5, 2022
3f3c61d
make ETH/TKO use ts
cyberhorsey Dec 5, 2022
b6fd634
ignore components folder
cyberhorsey Dec 5, 2022
8191a6f
inline block avatar
cyberhorsey Dec 5, 2022
3584ff1
switch ethereum chain, chain navbar selection, default store values, …
cyberhorsey Dec 5, 2022
64b3a9e
test coverage for switchEthereumChain
cyberhorsey Dec 5, 2022
25fbac4
list
cyberhorsey Dec 5, 2022
8a2dd49
Merge branch 'main' into bridge-design
cyberhorsey Dec 5, 2022
9d57e61
readapt bridge form to work
cyberhorsey Dec 5, 2022
32df1d5
Merge branch 'bridge-design' of github.com:taikochain/taiko-mono into…
cyberhorsey Dec 5, 2022
a0c67dd
text
cyberhorsey Dec 6, 2022
309e341
feat(bridge): switch chain modal styles
shadab-taiko Dec 6, 2022
90a7595
fix(bridge): chain dropdown styles
shadab-taiko Dec 6, 2022
72864f3
tests
cyberhorsey Dec 6, 2022
89076be
rpc urls + reactive balanes
cyberhorsey Dec 6, 2022
94fb2cd
import type
cyberhorsey Dec 6, 2022
1fffdcd
Merge branch 'main' into bridge-design
cyberhorsey Dec 6, 2022
b33a18b
cli test
cyberhorsey Dec 6, 2022
b81108f
Merge branch 'bridge-design' of github.com:taikochain/taiko-mono into…
cyberhorsey Dec 6, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/bridge-ui/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&display=swap" rel="stylesheet">

<title>Bridge</title>
</head>
<body>
Expand Down
1 change: 1 addition & 0 deletions packages/bridge-ui/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export default {
preset: "ts-jest",
testEnvironment: "jsdom",
testPathIgnorePatterns: ["<rootDir>/node_modules/"],
coveragePathIgnorePatterns: ["<rootDir>/src/components/"],
testTimeout: 40 * 1000,
watchPathIgnorePatterns: ["node_modules"],
};
11 changes: 8 additions & 3 deletions packages/bridge-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,19 @@
"ts-loader": "^9.2.6",
"tslib": "^2.4.0",
"typescript": "^4.6.4",
"vite": "^3.0.0"
"vite": "^3.0.0",
"vite-plugin-static-copy": "^0.12.0"
},
"dependencies": {
"@ethersproject/experimental": "^5.7.0",
"@lottiefiles/svelte-lottie-player": "^0.2.0",
"@sveltestack/svelte-query": "^1.6.0",
"@wagmi/core": "^0.7.5",
"axios": "^1.2.0",
"ethers": "^5.7.1",
"extend-expect": "link:@testing-library/jest-dom/extend-expect",
"identicon.js": "^2.3.3",
"svelte-i18n": "^3.5.1",
"svelte-spa-router": "^3.2.0",
"wagmi": "^0.8.6"
"svelte-spa-router": "^3.2.0"
}
}
30 changes: 26 additions & 4 deletions packages/bridge-ui/src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,23 @@
import { wrap } from "svelte-spa-router/wrap";
import QueryProvider from "./components/providers/QueryProvider.svelte";
import Router from "svelte-spa-router";
import Navbar from "./components/Navbar.svelte";
import { SvelteToast } from "@zerodevx/svelte-toast";
import { SvelteToast, toast } from "@zerodevx/svelte-toast";

import Home from "./pages/home/Home.svelte";
import { setupI18n } from "./i18n";
import { BridgeType } from "./domain/bridge";
import ETHBridge from "./eth/bridge";
import { bridges, chainIdToBridgeAddress } from "./store/bridge";
import { CHAIN_MAINNET, CHAIN_TKO } from "./domain/chain";
import ERC20Bridge from "./erc20/bridge";
import { pendingTransactions } from "./store/transactions";
import Navbar from "./components/Navbar.svelte";
import { signer } from "./store/signer";
import type { Transactioner } from "./domain/transactions";
import { RelayerService } from "./relayer/service";

setupI18n({ withLocale: "en" });
import { CHAIN_MAINNET, CHAIN_TKO } from "./domain/chain";
import SwitchEthereumChainModal from "./components/modals/SwitchEthereumChainModal.svelte";

const ethBridge = new ETHBridge();
const erc20Bridge = new ERC20Bridge();
Expand All @@ -30,6 +35,20 @@
return store;
});

const relayerURL = import.meta.env.VITE_RELAYER_URL;

const transactioner: Transactioner = new RelayerService(relayerURL);

pendingTransactions.subscribe((store) => {
store.forEach(async (tx) => {
await $signer.provider.waitForTransaction(tx.hash, 3);
toast.push("Transaction completed!");
const s = store;
s.pop();
pendingTransactions.set(s);
});
});

const routes = {
"/": wrap({
component: Home,
Expand All @@ -41,10 +60,12 @@

<QueryProvider>
<main>
<Navbar />
<Navbar {transactioner} />
<Router {routes} />
</main>
<SvelteToast />

<SwitchEthereumChainModal />
</QueryProvider>

<style global lang="postcss">
Expand All @@ -54,5 +75,6 @@

main {
margin: 0;
font-family: "Inter", sans-serif;
}
</style>
46 changes: 46 additions & 0 deletions packages/bridge-ui/src/app.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
.btn.btn-wide {
width: 194px;
height: 56px;
}

.btn.btn-token-select {
width: 140px;
height: 60px;
}

.btn.btn-square {
border-radius: 4px;
}

/* Invert accent button colors */
.btn.btn-accent {
background-color: hsla(var(--af) / var(--tw-bg-opacity, 1));
border-color: hsla(var(--af) / var(--tw-bg-opacity, 1));
height: 60px;
}

.btn.btn-accent:hover {
background-color: hsla(var(--a) / var(--tw-bg-opacity, 1));
border-color: hsla(var(--a) / var(--tw-bg-opacity, 1));
}

.dropdown .dropdown-content {
border-radius: 0 0 var(--rounded-box) var(--rounded-box);
}

.input-group .input.input-primary {
border-radius: 0.5rem;
}

.form-control .input-group :first-child {
border-radius: 0.5rem;
}

.form-control .input-group :last-child {
border-radius: 0.5rem;
}

.taiko-banner {
background-image: url('assets/taiko-banner.svg');
background-repeat: no-repeat;
}
1 change: 1 addition & 0 deletions packages/bridge-ui/src/assets/lottie/loader.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"nm":"Comp 1","mn":"","layers":[{"ty":4,"nm":"Shape Layer 2","mn":"","sr":1,"st":0,"op":300,"ip":0,"hd":false,"cl":"","ln":"","ddd":0,"bm":0,"tt":0,"hasMask":false,"td":0,"ao":0,"ks":{"a":{"a":0,"k":[-22.637,19.301,0],"ix":1},"s":{"a":0,"k":[33.33333333333334,33.33333333333334,100],"ix":6},"sk":{"a":0,"k":0},"p":{"a":0,"k":[100.02066666666668,100.00000000000003,0],"ix":2},"sa":{"a":0,"k":0},"o":{"a":0,"k":80,"ix":11},"r":{"a":1,"k":[{"o":{"x":0.472,"y":0.326},"i":{"x":0.526,"y":0.673},"s":[0],"t":0},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[183],"t":60}],"ix":10}},"ef":[],"shapes":[{"ty":"gr","bm":0,"cl":"","ln":"","hd":false,"mn":"ADBE Vector Group","nm":"Ellipse 1","ix":1,"cix":2,"np":3,"it":[{"ty":"el","bm":0,"cl":"","ln":"","hd":false,"mn":"ADBE Vector Shape - Ellipse","nm":"Ellipse Path 1","d":1,"p":{"a":0,"k":[0,0],"ix":3},"s":{"a":0,"k":[368.602,368.602],"ix":2}},{"ty":"st","bm":0,"cl":"","ln":"","hd":false,"mn":"ADBE Vector Graphic - Stroke","nm":"Stroke 1","lc":2,"lj":1,"ml":4,"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":49,"ix":5},"d":[],"c":{"a":0,"k":[0.9882,0.0588,0.7529],"ix":3}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[-22.699,19.301],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]},{"ty":"tm","bm":0,"cl":"","ln":"","hd":false,"mn":"ADBE Vector Filter - Trim","nm":"Trim Paths 1","ix":2,"e":{"a":1,"k":[{"o":{"x":0.559,"y":0},"i":{"x":0.504,"y":1},"s":[1],"t":0},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[50],"t":30}],"ix":2},"o":{"a":0,"k":0,"ix":3},"s":{"a":1,"k":[{"o":{"x":0.579,"y":0},"i":{"x":0.438,"y":1},"s":[0],"t":30},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[49],"t":60}],"ix":1},"m":1}],"ind":0},{"ty":4,"nm":"Shape Layer 1","mn":"","sr":1,"st":0,"op":300,"ip":0,"hd":false,"cl":"","ln":"","ddd":0,"bm":0,"tt":0,"hasMask":false,"td":0,"ao":0,"ks":{"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[33.33333333333334,33.33333333333334,100],"ix":6},"sk":{"a":0,"k":0},"p":{"a":0,"k":[107.56633333333339,93.56633333333338,0],"ix":2},"sa":{"a":0,"k":0},"o":{"a":0,"k":10,"ix":11},"r":{"a":0,"k":0,"ix":10}},"ef":[],"shapes":[{"ty":"gr","bm":0,"cl":"","ln":"","hd":false,"mn":"ADBE Vector Group","nm":"Ellipse 1","ix":1,"cix":2,"np":3,"it":[{"ty":"el","bm":0,"cl":"","ln":"","hd":false,"mn":"ADBE Vector Shape - Ellipse","nm":"Ellipse Path 1","d":1,"p":{"a":0,"k":[0,0],"ix":3},"s":{"a":0,"k":[368.602,368.602],"ix":2}},{"ty":"st","bm":0,"cl":"","ln":"","hd":false,"mn":"ADBE Vector Graphic - Stroke","nm":"Stroke 1","lc":2,"lj":1,"ml":4,"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":49,"ix":5},"d":[],"c":{"a":0,"k":[0.698,0.0588,0.5373],"ix":3}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[-22.699,19.301],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":1}],"ddd":0,"h":200,"w":200,"meta":{"a":"","k":"","d":"","g":"@lottiefiles/toolkit-js 0.17.3","tc":"#ffffff"},"v":"5.5.0","fr":30,"op":60,"ip":0,"assets":[]}
15 changes: 15 additions & 0 deletions packages/bridge-ui/src/assets/taiko-banner.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
64 changes: 56 additions & 8 deletions packages/bridge-ui/src/components/AddressDropdown.svelte
Original file line number Diff line number Diff line change
@@ -1,16 +1,32 @@
<script lang="ts">
import { onMount } from "svelte";
import { _ } from "svelte-i18n";
import { toast } from "@zerodevx/svelte-toast";

import { addressSubsection } from "../utils/addressSubsection";
import { onMount } from "svelte";
import { signer } from "../store/signer";
import { pendingTransactions } from "../store/transactions";
import ChevDown from "./icons/ChevDown.svelte";
import { toast } from "@zerodevx/svelte-toast";
import { getAddressAvatarFromIdenticon } from "../utils/addressAvatar";
import type { BridgeTransaction } from "src/domain/transactions";
import { LottiePlayer } from "@lottiefiles/svelte-lottie-player";
import type { Signer } from "ethers";

export let transactions: BridgeTransaction[] = [];

let address: string;
let addressAvatarImgData: string;
onMount(async () => {
address = await $signer.getAddress();
setAddress($signer);
});

$: setAddress($signer).catch((e) => console.error(e));

async function setAddress(signer: Signer) {
address = await signer.getAddress();
addressAvatarImgData = getAddressAvatarFromIdenticon(address);
}

async function copyToClipboard(clip: string) {
await navigator.clipboard.writeText(clip);
}
Expand All @@ -25,15 +41,42 @@
}
</script>

<div class="dropdown dropdown-end">
<label tabindex="0" class="btn m-1">
<span class="pr-2">{addressSubsection(address)}</span>
<div class="dropdown dropdown-bottom">
<button tabindex="0" class="btn btn-wide justify-around">
<span class="font-normal flex-1 text-left">
{#if $pendingTransactions && $pendingTransactions.length}
{$pendingTransactions.length} Pending
<div class="inline-block">
<LottiePlayer
src="/lottie/loader.json"
autoplay={true}
loop={true}
controls={false}
renderer="svg"
background="transparent"
height={26}
width={26}
controlsLayout={[]}
/>
</div>
{:else}
<img
width="26"
height="26"
src="data:image/png;base64,{addressAvatarImgData}"
class="rounded-full mr-2 inline-block"
alt="avatar"
/>

{addressSubsection(address)}
{/if}
</span>

<ChevDown />
</label>
</button>
<ul
tabindex="0"
class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-52"
class="dropdown-content menu p-2 shadow bg-dark-3 rounded-box w-[194px]"
>
<li>
<span
Expand All @@ -46,5 +89,10 @@
>Disconnect</span
>
</li>
{#if transactions && transactions.length}
<li>
<span class="cursor-pointer"> {transactions.length} Transactions</span>
</li>
{/if}
</ul>
</div>
70 changes: 70 additions & 0 deletions packages/bridge-ui/src/components/ChainDropdown.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<script lang="ts">
import { _ } from "svelte-i18n";

import ChevDown from "./icons/ChevDown.svelte";
import { fromChain } from "../store/chain";
import MetaMask from "./icons/MetaMask.svelte";
import { switchEthereumChain } from "../utils/switchEthereumChain";
import { ethereum } from "../store/ethereum";
import { CHAIN_MAINNET, CHAIN_TKO } from "../domain/chain";
import type { Chain } from "../domain/chain";
import { ethers } from "ethers";
import { signer } from "../store/signer";
const changeChain = async (chain: Chain) => {
await switchEthereumChain($ethereum, chain);
const provider = new ethers.providers.Web3Provider(window.ethereum);
await provider.send("eth_requestAccounts", []);

signer.set(provider.getSigner());
};
</script>

<div class="dropdown dropdown-bottom mr-4">
<button tabindex="0" class="btn btn-wide justify-around">
<span class="font-normal flex-1 text-left">
{#if $fromChain}
<svelte:component this={$fromChain.icon} />
<span class="ml-2">{$fromChain.name}</span>
{:else}
<span class="ml-2">Invalid Chain</span>
{/if}
</span>

<ChevDown />
</button>
<ul
tabindex="0"
class="dropdown-content flex menu p-2 shadow bg-dark-3 rounded-box w-[194px]"
>
<li>
<button
class="flex items-center px-2 py-4 hover:bg-dark-5 rounded-xl justify-around"
on:click={async () => {
await changeChain(CHAIN_MAINNET);
}}
>
<svelte:component this={CHAIN_MAINNET.icon} height={24} />
<span class="pl-1.5 text-left flex-1">{CHAIN_MAINNET.name}</span>
<MetaMask />
</button>
</li>
<li>
<button
class="flex items-center px-2 py-4 hover:bg-dark-5 rounded-xl justify-around"
on:click={async () => {
await changeChain(CHAIN_TKO);
}}
>
<svelte:component this={CHAIN_TKO.icon} height={24} />
<span class="pl-1.5 text-left flex-1">{CHAIN_TKO.name}</span>
<MetaMask />
</button>
</li>
</ul>
</div>

<style>
.menu li > span {
padding-left: 0px;
}
</style>
34 changes: 28 additions & 6 deletions packages/bridge-ui/src/components/Navbar.svelte
Original file line number Diff line number Diff line change
@@ -1,19 +1,41 @@
<script>
<script lang="ts">
import Connect from "./buttons/Connect.svelte";
import Logo from "./icons/Logo.svelte";
import { signer } from "../store/signer";
import AddressDropdown from "./AddressDropdown.svelte";
import type {
BridgeTransaction,
Transactioner,
} from "../domain/transactions";
import type { Signer } from "ethers";
import { fromChain } from "../store/chain";
import ChainDropdown from "./ChainDropdown.svelte";
import type { Chain } from "../domain/chain";

export let transactioner: Transactioner;
let transactions: BridgeTransaction[];

$: getTransactions($signer, $fromChain);

async function getTransactions(signer: Signer, chain: Chain) {
if (!signer || !chain) return;
transactions = await transactioner.GetAllByAddress(
await signer.getAddress(),
chain.id
);
}
</script>

<div class="navbar bg-base-100">
<div class="flex-1">
<nav class="navbar h-[125px] py-8 px-32">
<div class="navbar-end justify-start">
<Logo />
</div>
<div class="flex-none">
<div class="navbar-end">
{#if $signer}
<AddressDropdown />
<ChainDropdown />
<AddressDropdown {transactions} />
{:else}
<Connect />
{/if}
</div>
</div>
</nav>
11 changes: 11 additions & 0 deletions packages/bridge-ui/src/components/TaikoBanner.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script>
import { _ } from "svelte-i18n";
import SelectChain from "./form/SelectChain.svelte";
</script>

<div class="taiko-banner bg-cover bg-center bg-no-repeat w-full h-36 rounded-lg py-4 flex flex-col items-center justify-center">
<h1 class="text-2xl font-bold">
{$_("home.title")}
</h1>
<SelectChain />
</div>
Loading