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-ui): support both bull and horse tokens on the bridge UI #13249

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
d5c771c
Get it of unnecessary provider
jscriptcoder Mar 2, 2023
8fbe076
Use reactivity and improve accessibility
jscriptcoder Mar 2, 2023
e7391e9
Added support for both tokens
jscriptcoder Mar 3, 2023
cab68fd
wip
jscriptcoder Mar 3, 2023
c60cb53
Fixed support for both tokens, bull and horse
jscriptcoder Mar 3, 2023
c9299d5
Add prettier
jscriptcoder Mar 3, 2023
cc015ae
Format BridgeForm
jscriptcoder Mar 3, 2023
cd6498e
Revert prettier change
jscriptcoder Mar 4, 2023
766ba57
Revert pnpm-lock file
jscriptcoder Mar 4, 2023
2b707e9
Revert SelectToken accessibility changes
jscriptcoder Mar 4, 2023
af1876f
Revert changes in Home
jscriptcoder Mar 4, 2023
2268023
Merge branch 'main' into 13243-featbridge-ui-support-both-bull-and-ho…
jscriptcoder Mar 4, 2023
b23a63e
Fix test
jscriptcoder Mar 4, 2023
18d11f6
Correct wording
jscriptcoder Mar 4, 2023
b9cf64c
Format Bull.svelte
jscriptcoder Mar 4, 2023
78a0e40
Add Unknown token logo
jscriptcoder Mar 5, 2023
4aef99e
Merge branch 'main' into 13243-featbridge-ui-support-both-bull-and-ho…
jscriptcoder Mar 5, 2023
a6f194a
Simplify TEST_ERC20
jscriptcoder Mar 5, 2023
964318d
Add prettier
jscriptcoder Mar 5, 2023
2af91a2
Merge branch 'main' into 13243-featbridge-ui-support-both-bull-and-ho…
jscriptcoder Mar 6, 2023
78451e7
Fix issue with vite replacing import.meta.env
jscriptcoder Mar 6, 2023
cef47b9
Another option to the problem with vite env vars
jscriptcoder Mar 6, 2023
c52d756
Add comment and rename map
jscriptcoder Mar 6, 2023
54f3554
Fix merge conflicts
jscriptcoder Mar 7, 2023
1c6fb53
Fix issues after feedback
jscriptcoder Mar 7, 2023
efe6c69
Changes on SelectToken
jscriptcoder Mar 7, 2023
428e956
Feedbacks addressed
jscriptcoder Mar 7, 2023
27ab6b3
Minor comment change
jscriptcoder Mar 7, 2023
c688576
Merge branch 'main' into 13243-featbridge-ui-support-both-bull-and-ho…
jscriptcoder Mar 7, 2023
1e8b973
Silence a11y warning
jscriptcoder Mar 7, 2023
830c5b9
Add an informative comment
jscriptcoder Mar 7, 2023
24874da
Fix build
jscriptcoder Mar 7, 2023
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
32 changes: 20 additions & 12 deletions packages/bridge-ui/.default.env
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
VITE_NODE_ENV=dev
VITE_L1_RPC_URL=""
VITE_L2_RPC_URL=""
VITE_TAIKO_BRIDGE_ADDRESS=""
VITE_MAINNET_BRIDGE_ADDRESS=""
VITE_TEST_ERC20_ADDRESS_MAINNET=""
VITE_MAINNET_TOKEN_VAULT_ADDRESS=""
VITE_TAIKO_TOKEN_VAULT_ADDRESS=""
VITE_TEST_ERC20_ADDRESS_MAINNET=""

VITE_RELAYER_URL=""

VITE_TEST_ERC20=[]

VITE_MAINNET_CHAIN_ID=
VITE_TAIKO_CHAIN_ID=
VITE_MAINNET_CHAIN_NAME=
VITE_TAIKO_CHAIN_NAME=
VITE_TAIKO_HEADER_SYNC_ADDRESS=
VITE_MAINNET_HEADER_SYNC_ADDRESS=
VITE_MAINNET_BRIDGE_ADDRESS=
VITE_TAIKO_BRIDGE_ADDRESS=

VITE_MAINNET_CHAIN_NAME=""
VITE_TAIKO_CHAIN_NAME=""

VITE_MAINNET_TOKEN_VAULT_ADDRESS=""
VITE_TAIKO_TOKEN_VAULT_ADDRESS=""

VITE_MAINNET_HEADER_SYNC_ADDRESS=""
VITE_TAIKO_HEADER_SYNC_ADDRESS=""

VITE_MAINNET_BRIDGE_ADDRESS=""
VITE_TAIKO_BRIDGE_ADDRESS=""

VITE_MAINNET_SIGNAL_SERVICE_ADDRESS=""
VITE_TAIKO_SIGNAL_SERVICE_ADDRESS=""
10 changes: 10 additions & 0 deletions packages/bridge-ui/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
root=true

[*]
end_of_line = lf
insert_final_newline = true

[*.{js,ts,svelte,css,json,yml,yaml}]
charset = utf-8
indent_style = space
indent_size = 2
16 changes: 16 additions & 0 deletions packages/bridge-ui/.prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"trailingComma": "all",
"tabWidth": 2,
"semi": true,
"singleQuote": true,
"bracketSameLine": true,

"plugins": [
"prettier-plugin-svelte"
],

"svelteSortOrder" : "options-scripts-markup-styles",
"svelteStrictMode": false,
"svelteAllowShorthand": true,
"svelteIndentScriptAndStyle": true
}
16 changes: 12 additions & 4 deletions packages/bridge-ui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,32 @@ You can use the following values in the `.env` file to spin up the Bridge UI loc

```
VITE_NODE_ENV=dev

VITE_L1_RPC_URL="https://l1rpc.internal.taiko.xyz/"
VITE_L2_RPC_URL="https://l2rpc.internal.taiko.xyz/"

VITE_L1_EXPLORER_URL="https://l1explorer.internal.taiko.xyz/"
VITE_L2_EXPLORER_URL="https://l2explorer.internal.taiko.xyz/"

VITE_RELAYER_URL="https://relayer.internal.taiko.xyz/"
VITE_TEST_ERC20_ADDRESS_MAINNET="0x3435A6180fBB1BAEc87bDC49915282BfBC328C70"
VITE_TEST_ERC20_SYMBOL_MAINNET="BULL"
VITE_TEST_ERC20_NAME_MAINNET="Bull Token"

VITE_TEST_ERC20=[{"address": "0x3435A6180fBB1BAEc87bDC49915282BfBC328C70", "symbol": "BLL", "name": "Bull Token"}, {"address": "0xAED64948E0d09f4eb07d8B76A65Cd3d517c6Fb15", "symbol": "HORSE", "name": "Horse Token"}]

VITE_MAINNET_CHAIN_ID=31336
VITE_TAIKO_CHAIN_ID=167001

VITE_MAINNET_CHAIN_NAME="Ethereum A2"
VITE_TAIKO_CHAIN_NAME="Taiko A2"

VITE_MAINNET_TOKEN_VAULT_ADDRESS="0x5E506e2E0EaD3Ff9d93859A5879cAA02582f77c3"
VITE_TAIKO_TOKEN_VAULT_ADDRESS="0x0000777700000000000000000000000000000002"

VITE_MAINNET_HEADER_SYNC_ADDRESS="0x9b557777Be33A8A2fE6aF93E017A0d139B439E5D"
VITE_TAIKO_HEADER_SYNC_ADDRESS="0x0000777700000000000000000000000000000001"

VITE_MAINNET_BRIDGE_ADDRESS="0xAE4C9bD0f7AE5398Df05043079596E2BF0079CE9"
VITE_TAIKO_BRIDGE_ADDRESS="0x0000777700000000000000000000000000000004"

VITE_MAINNET_SIGNAL_SERVICE_ADDRESS="0x162A36c9821eadeCFF9669A3940b7f72d055Cd1c"
VITE_TAIKO_SIGNAL_SERVICE_ADDRESS="0x0000777700000000000000000000000000000007"
```
```
1 change: 1 addition & 0 deletions packages/bridge-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"postcss-cli": "^7.1.2",
"postcss-loader": "^6.2.0",
"prettier": "2.7.1",
"prettier-plugin-svelte": "^2.9.0",
"rollup-plugin-node-builtins": "^2.0.0",
"rollup-plugin-polyfill-node": "^0.10.2",
"svelte": "^3.53.1",
Expand Down
128 changes: 73 additions & 55 deletions packages/bridge-ui/src/components/buttons/SelectToken.svelte
Original file line number Diff line number Diff line change
@@ -1,30 +1,35 @@
<script lang="ts">
import { getProvider } from '@wagmi/core'
import { token } from "../../store/token";
import { bridgeType } from "../../store/bridge";
import { ETH, tokens } from "../../domain/token";
import type { Token } from "../../domain/token";
import { BridgeType } from "../../domain/bridge";
import { ChevronDown, PlusCircle } from "svelte-heros-v2";
import { errorToast, successToast } from "../../utils/toast";
import { ethers } from "ethers";
import ERC20 from "../../constants/abi/ERC20";
import { getProvider } from '@wagmi/core';
import { token } from '../../store/token';
import { bridgeType } from '../../store/bridge';
import { ETH, tokens } from '../../domain/token';
import type { Token } from '../../domain/token';
import { BridgeType, type HTMLBridgeForm } from '../../domain/bridge';
import { ChevronDown, PlusCircle } from 'svelte-heros-v2';
import { errorToast, successToast } from '../../utils/toast';
import { ethers } from 'ethers';
import ERC20_ABI from '../../constants/abi/ERC20';
import { signer } from '../../store/signer';
import { userTokens, tokenService } from '../../store/userToken';
import { fromChain, toChain } from '../../store/chain';
import Erc20 from '../icons/ERC20.svelte';
import AddCustomErc20 from '../form/AddCustomERC20.svelte';

let dropdownElement: HTMLDivElement;
let showAddressField = false;
let loading = false;

async function select(t: Token) {
if (t === $token) return;

token.set(t);
if (t.symbol.toLowerCase() == ETH.symbol.toLowerCase()) {

if (t.symbol.toLowerCase() === ETH.symbol.toLowerCase()) {
bridgeType.set(BridgeType.ETH);
} else {
bridgeType.set(BridgeType.ERC20);
}

successToast(`Token changed to ${t.symbol.toUpperCase()}`);

// to close the dropdown on click
Expand All @@ -34,29 +39,33 @@
}
}

let showAddressField = false;

let loading = false;

async function addERC20(event: SubmitEvent) {
loading = true;

try {
loading = true;
const eventTarget = event.target as HTMLFormElement;
const eventTarget = event.target as HTMLBridgeForm;
const { customTokenAddress } = eventTarget;
const tokenAddress = customTokenAddress.value;
if(!ethers.utils.isAddress(tokenAddress)) {
throw new Error();

if (!ethers.utils.isAddress(tokenAddress)) {
throw new Error('Not a valid ERC20 address');
}

const provider = getProvider();
const contract = new ethers.Contract(tokenAddress, ERC20, provider);
const contract = new ethers.Contract(tokenAddress, ERC20_ABI, provider);

const userAddress = await $signer.getAddress();
const erc20Check = await contract.balanceOf(userAddress);

// This call makes sure the contract is a valid ERC20 contract,
// otherwise it throws and gets caught informing the user
// it's not a valid ERC20 address
await contract.balanceOf(userAddress);

const [tokenName, decimals, symbol] = await Promise.all([
contract.name(),
contract.decimals(),
contract.symbol(),
])
]);

const token = {
name: tokenName,
Expand All @@ -67,80 +76,89 @@
},
{
chainId: $toChain.id,
address: "0x00",
}
address: '0x00',
},
],
decimals: decimals,
symbol: symbol,
logoComponent: null,
}
const updateTokensList = await $tokenService.StoreToken(token, userAddress);
} as Token;

const updateTokensList = await $tokenService.StoreToken(
token,
userAddress,
);

select(token);

userTokens.set(updateTokensList);
eventTarget.reset();

showAddressField = false;
} catch(error) {
errorToast("Not a valid ERC20 address");
} catch (error) {
// TODO: what if something else happens within the try block?
errorToast('Not a valid ERC20 address');
console.error(error);
} finally {
loading = false;
}
}
let customTokens = [];
userTokens.subscribe(value => {
if(value)
customTokens = value;
})
</script>

<div class="dropdown dropdown-bottom" bind:this={dropdownElement}>
<!-- svelte-ignore a11y-label-has-associated-control -->
<label
role="button"
tabindex="0"
class="flex items-center justify-center hover:cursor-pointer"
>
class="flex items-center justify-center hover:cursor-pointer">
{#if $token.logoComponent}
<svelte:component this={$token.logoComponent} />
{:else}
<Erc20 />
{/if}
<p class="px-2 text-sm">{$token.symbol.toUpperCase()}</p>
<ChevronDown size='20' />
<ChevronDown size="20" />
</label>

<ul
role="listbox"
tabindex="0"
class="token-dropdown dropdown-content menu my-2 shadow-xl bg-dark-2 rounded-box p-2"
>
class="token-dropdown dropdown-content menu my-2 shadow-xl bg-dark-2 rounded-box p-2">
{#each tokens as t}
<li class="cursor-pointer w-full hover:bg-dark-5 px-4 py-4 rounded-none">
<button on:click={async () => await select(t)} class="flex hover:bg-dark-5">
<li class="cursor-pointer w-full hover:bg-dark-5 rounded-none">
<button
on:click={async () => await select(t)}
class="flex hover:bg-dark-5 p-4">
<svelte:component this={t.logoComponent} height={22} width={22} />
<span class="text-sm font-medium bg-transparent px-2"
>{t.symbol.toUpperCase()}</span
>
>{t.symbol.toUpperCase()}</span>
</button>
</li>
{/each}
{#each customTokens as t}
<li class="cursor-pointer w-full hover:bg-dark-5 px-4 py-4">
<button on:click={async () => await select(t)} class="flex hover:bg-dark-5">
{#each $userTokens as t}
<li class="cursor-pointer w-full hover:bg-dark-5">
<button
on:click={async () => await select(t)}
class="flex hover:bg-dark-5 p-4">
<Erc20 height={22} width={22} />
<span class="text-sm font-medium bg-transparent px-2"
>{t.symbol.toUpperCase()}</span
>
>{t.symbol.toUpperCase()}</span>
</button>
</li>
{/each}
<li class="cursor-pointer hover:bg-dark-5 px-4 py-4">
<button on:click={() => showAddressField = true} class="flex hover:bg-dark-5 justify-between items-center">
<PlusCircle size='25' />
<span class="text-sm font-medium bg-transparent flex-1 w-[100px] px-0 pl-2"
>Add Custom</span
>
<li class="cursor-pointer hover:bg-dark-5">
<button
on:click={() => (showAddressField = true)}
class="flex hover:bg-dark-5 justify-between items-center p-4">
<PlusCircle size="25" />
<span
class="text-sm font-medium bg-transparent flex-1 w-[100px] px-0 pl-2"
>Add Custom</span>
</button>
</li>
</ul>

{#if showAddressField}
<AddCustomErc20 bind:showAddressField addERC20={addERC20} bind:loading />
<AddCustomErc20 bind:showAddressField {addERC20} bind:loading />
{/if}
</div>
Loading