Skip to content

Commit

Permalink
feat(bridge): non-mm wallets (#438)
Browse files Browse the repository at this point in the history
* feat(bridge): add transaction list

* fix(bridge): remove console.log

* transaction impl

* test

* wip, local storage for transactons, claiming, new stores, deprecate relayer

* claim

* tests

* jest

* pending tx

* proof validation

* tests

* process message requires manual gas limit

* jest

* mm mobile code

* mm mobile

* custom fee

* value not data

* fee

* jest

* rm log

* tests

* tests

* erc20 bridging

* token vault address refactor

* bridge opts

* bridge fix

* get canonicalToBridged for cross layer tokens

* golang lint

* rm console log

* feat(bridge): non mm wallets

* env rename, add bridge address and test erc20 dynamically, remove tko

* fix number input

* wip tx view

* reactive tx list

* show Pending state if message header is not synced

* tests

* Update packages/bridge-ui/.default.env

Co-authored-by: dave | d1onys1us <dave@taiko.xyz>

* Update packages/bridge-ui/src/components/Loader.svelte

Co-authored-by: dave | d1onys1us <dave@taiko.xyz>

* Update packages/bridge-ui/src/app.css

Co-authored-by: dave | d1onys1us <dave@taiko.xyz>

* rm old way of doing bridge tx's

* unused css

* feat(bridge): switch network using wagmi

* Fetch tx on signer load

* feat(bridge): style changes

* rm switchethereumchain, useless function now

* jest

* fix(bridge): non mm wallets

* fix(bridge): workaround for process.env.NODE_DEBUG

* chore(bridge): add vite mjs file to gitignore

* fix(bridge): production build

* add deps for wagmi

* bump wagmi

* fix wagmi

Co-authored-by: Jeffery Walsh <cyberhorsey@gmail.com>
Co-authored-by: jeff <113397187+cyberhorsey@users.noreply.github.com>
Co-authored-by: dave | d1onys1us <dave@taiko.xyz>
  • Loading branch information
4 people committed Dec 20, 2022
1 parent d5532f6 commit 7f3ac3b
Show file tree
Hide file tree
Showing 19 changed files with 1,029 additions and 243 deletions.
5 changes: 4 additions & 1 deletion packages/bridge-ui/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,7 @@ dist-ssr
*.njsproj
*.sln
*.sw?
.env
.env

# vite
vite.config.ts.timestamp-*.mjs
4 changes: 2 additions & 2 deletions packages/bridge-ui/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ export default {
],
coverageThreshold: {
global: {
statements: 98.45,
branches: 86,
statements: 98.36,
branches: 85,
functions: 96,
lines: 100,
},
Expand Down
5 changes: 4 additions & 1 deletion packages/bridge-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,14 @@
"vite-plugin-static-copy": "^0.12.0"
},
"dependencies": {
"@coinbase/wallet-sdk": "^3.6.3",
"@ethersproject/experimental": "^5.7.0",
"@lottiefiles/svelte-lottie-player": "^0.2.0",
"@sveltestack/svelte-query": "^1.6.0",
"@wagmi/core": "^0.7.5",
"@wagmi/connectors": "^0.1.1",
"@wagmi/core": "^0.8.0",
"axios": "^1.2.0",
"buffer": "^6.0.3",
"ethers": "^5.7.1",
"extend-expect": "link:@testing-library/jest-dom/extend-expect",
"identicon.js": "^2.3.3",
Expand Down
56 changes: 55 additions & 1 deletion packages/bridge-ui/src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@
import Router from "svelte-spa-router";
import { SvelteToast } from "@zerodevx/svelte-toast";
import type { SvelteToastOptions } from "@zerodevx/svelte-toast";
import {
configureChains,
createClient,
InjectedConnector,
} from "@wagmi/core";
import { publicProvider } from "@wagmi/core/providers/public";
import { jsonRpcProvider } from "@wagmi/core/providers/jsonRpc";
import { CoinbaseWalletConnector } from "@wagmi/core/connectors/coinbaseWallet";
import { WalletConnectConnector } from "@wagmi/core/connectors/walletConnect";
import Home from "./pages/home/Home.svelte";
import { setupI18n } from "./i18n";
Expand All @@ -19,9 +28,16 @@
import Navbar from "./components/Navbar.svelte";
import { signer } from "./store/signer";
import type { Transactioner } from "./domain/transactions";
import { wagmiClient } from "./store/wagmi";
setupI18n({ withLocale: "en" });
import { chains, CHAIN_MAINNET, CHAIN_TKO } from "./domain/chain";
import {
chains,
CHAIN_MAINNET,
CHAIN_TKO,
mainnet,
taiko,
} from "./domain/chain";
import SwitchEthereumChainModal from "./components/modals/SwitchEthereumChainModal.svelte";
import { ProofService } from "./proof/service";
import { ethers } from "ethers";
Expand All @@ -45,6 +61,44 @@
CHAIN_TKO.id,
new ethers.providers.JsonRpcProvider(import.meta.env.VITE_L2_RPC_URL)
);
providers.set(providerMap);
const {
chains: wagmiChains,
provider,
webSocketProvider,
} = configureChains(
[mainnet, taiko],
[
publicProvider(),
jsonRpcProvider({
rpc: (chain) => ({
http: providerMap.get(chain.id).connection.url,
}),
}),
]
);
$wagmiClient = createClient({
provider,
connectors: [
new InjectedConnector({
chains: wagmiChains,
}),
new CoinbaseWalletConnector({
chains: wagmiChains,
options: {
appName: "Taiko Bridge",
},
}),
new WalletConnectConnector({
chains: wagmiChains,
options: {
qrcode: true,
},
}),
],
});
providers.set(providerMap);
Expand Down
7 changes: 4 additions & 3 deletions packages/bridge-ui/src/components/ChainDropdown.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@
import ChevDown from "./icons/ChevDown.svelte";
import { fromChain, toChain } 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";
import { switchNetwork } from "@wagmi/core";
const changeChain = async (chain: Chain) => {
await switchEthereumChain($ethereum, chain);
await switchNetwork({
chainId: chain.id,
});
const provider = new ethers.providers.Web3Provider(window.ethereum);
await provider.send("eth_requestAccounts", []);
Expand Down
17 changes: 9 additions & 8 deletions packages/bridge-ui/src/components/Transaction.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,9 @@
import { Contract, ethers } from "ethers";
import { bridges } from "../store/bridge";
import { signer } from "../store/signer";
import { pendingTransactions, transactions } from "../store/transactions";
import { pendingTransactions } from "../store/transactions";
import { errorToast, successToast } from "../utils/toast";
import { _ } from "svelte-i18n";
import { switchEthereumChain } from "../utils/switchEthereumChain";
import { ethereum } from "../store/ethereum";
import {
fromChain as fromChainStore,
toChain as toChainStore,
Expand All @@ -22,6 +20,7 @@
import { LottiePlayer } from "@lottiefiles/svelte-lottie-player";
import HeaderSync from "../constants/abi/HeaderSync";
import { providers } from "../store/providers";
import { fetchSigner, switchNetwork } from "@wagmi/core";
export let transaction: BridgeTransaction;
Expand All @@ -36,7 +35,9 @@
async function claim(bridgeTx: BridgeTransaction) {
if (fromChain.id !== bridgeTx.message.destChainId.toNumber()) {
const chain = chains[bridgeTx.message.destChainId.toNumber()];
await switchEthereumChain($ethereum, chain);
await switchNetwork({
chainId: chain.id,
});
const provider = new ethers.providers.Web3Provider(window.ethereum);
await provider.send("eth_requestAccounts", []);
Expand All @@ -46,7 +47,8 @@
} else {
toChainStore.set(CHAIN_MAINNET);
}
signer.set(provider.getSigner());
const wagmiSigner = await fetchSigner();
signer.set(wagmiSigner);
}
try {
Expand Down Expand Up @@ -77,7 +79,7 @@
async function isProcessable() {
if (!transaction.receipt) return false;
if (!transaction.message) return false;
if (transaction.status === MessageStatus.Done) return true;
if (transaction.status !== MessageStatus.New) return true;
const contract = new Contract(
chains[transaction.message.destChainId.toNumber()].headerSyncAddress,
Expand All @@ -89,8 +91,7 @@
const srcBlock = await $providers
.get(chains[transaction.message.srcChainId.toNumber()].id)
.getBlock(latestSyncedHeader);
return transaction.receipt.blockNumber <= srcBlock.number;
return transaction.receipt.blockNumber >= srcBlock.number;
}
</script>

Expand Down
139 changes: 91 additions & 48 deletions packages/bridge-ui/src/components/buttons/Connect.svelte
Original file line number Diff line number Diff line change
@@ -1,62 +1,105 @@
<script lang="ts">
import { onDestroy } from "svelte";
import { BigNumber, ethers } from "ethers";
import { signer } from "../../store/signer";
import { _ } from "svelte-i18n";
import { CHAIN_MAINNET, CHAIN_TKO } from "../..//domain/chain";
import {
connect as wagmiConnect,
Connector,
fetchSigner,
watchAccount,
watchNetwork,
} from "@wagmi/core";
import { CHAIN_MAINNET, CHAIN_TKO } from "../../domain/chain";
import { fromChain, toChain } from "../../store/chain";
import { ethereum } from "../../store/ethereum";
import { isSwitchEthereumChainModalOpen } from "../../store/modal";
import {
isSwitchEthereumChainModalOpen,
isConnectWalletModalOpen,
} from "../../store/modal";
import { errorToast, successToast } from "../../utils/toast";
import Modal from "../modals/Modal.svelte";
import { wagmiClient } from "../../store/wagmi";
import MetaMask from "../icons/MetaMask.svelte";
import WalletConnect from "../icons/WalletConnect.svelte";
import CoinbaseWallet from "../icons/CoinbaseWallet.svelte";
import { transactioner, transactions } from "../../store/transactions";
async function connect() {
try {
const getAccounts = async () => {
ethereum.set(window.ethereum);
const provider = new ethers.providers.Web3Provider(window.ethereum);
await provider.send("eth_requestAccounts", []);
const s = provider.getSigner();
signer.set(s);
transactions.set(
await $transactioner.GetAllByAddress(await s.getAddress())
);
};
const changeChain = async (chainId: number) => {
if (chainId === CHAIN_TKO.id) {
fromChain.set(CHAIN_TKO);
toChain.set(CHAIN_MAINNET);
} else if (chainId === CHAIN_MAINNET.id) {
fromChain.set(CHAIN_MAINNET);
toChain.set(CHAIN_TKO);
} else {
isSwitchEthereumChainModalOpen.set(true);
}
};
await getAccounts();
const { chainId } = await $signer.provider.getNetwork();
await changeChain(chainId);
window.ethereum.on("chainChanged", async (chainId) => {
await changeChain(BigNumber.from(chainId).toNumber());
});
window.ethereum.on("accountsChanged", async (accounts) => {
await getAccounts();
});
successToast("Connected");
} catch (e) {
console.log(e);
errorToast("Error connecting to wallet");
const changeChain = async (chainId: number) => {
if (chainId === CHAIN_TKO.id) {
fromChain.set(CHAIN_TKO);
toChain.set(CHAIN_MAINNET);
} else if (chainId === CHAIN_MAINNET.id) {
fromChain.set(CHAIN_MAINNET);
toChain.set(CHAIN_TKO);
} else {
isSwitchEthereumChainModalOpen.set(true);
}
};
let unwatchNetwork;
let unwatchAccount;
async function setSigner() {
const wagmiSigner = await fetchSigner();
signer.set(wagmiSigner);
return wagmiSigner;
}
async function connectWithConnector(connector: Connector) {
const { chain } = await wagmiConnect({ connector });
await setSigner();
await changeChain(chain.id);
unwatchNetwork = watchNetwork(
async (network) => await changeChain(network.chain.id)
);
unwatchAccount = watchAccount(async () => {
const s = await setSigner();
transactions.set(
await $transactioner.GetAllByAddress(await s.getAddress())
);
});
successToast("Connected");
}
const iconMap = {
metamask: MetaMask,
walletconnect: WalletConnect,
"coinbase wallet": CoinbaseWallet,
};
onDestroy(() => {
if (unwatchNetwork) {
unwatchNetwork();
}
if (unwatchAccount) {
unwatchAccount();
}
});
</script>

<button class="btn btn-md md:btn-wide" on:click={async () => await connect()}
<button
class="btn btn-md md:btn-wide"
on:click={() => ($isConnectWalletModalOpen = true)}
>{$_("nav.connect")}</button
>

<Modal
title={$_("connectModal.title")}
isOpen={$isConnectWalletModalOpen}
onClose={() => ($isConnectWalletModalOpen = false)}
>
<div class="flex flex-col items-center space-y-4 space-x-0 p-8">
{#each $wagmiClient.connectors as connector}
<button
class="btn flex items-center justify-start md:pl-32 space-x-4 w-full"
on:click={() => connectWithConnector(connector)}
>
<div class="h-7 w-7 flex items-center justify-center">
<svelte:component this={iconMap[connector.name.toLowerCase()]} />
</div>
<span>{connector.name}</span>
</button>
{/each}
</div>
</Modal>
7 changes: 4 additions & 3 deletions packages/bridge-ui/src/components/form/SelectChain.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@
import ArrowRightLeft from "../icons/ArrowRightLeft.svelte";
import { fromChain, toChain } from "../../store/chain";
import { CHAIN_MAINNET, CHAIN_TKO } from "../../domain/chain";
import { ethereum } from "../../store/ethereum";
import { signer } from "../../store/signer";
import { switchEthereumChain } from "../../utils/switchEthereumChain";
import { ethers } from "ethers";
import { errorToast, successToast } from "../../utils/toast";
import { switchNetwork } from "@wagmi/core";
const toggleChains = async () => {
try {
const chain = $fromChain === CHAIN_MAINNET ? CHAIN_TKO : CHAIN_MAINNET;
await switchEthereumChain($ethereum, chain);
await switchNetwork({
chainId: chain.id,
});
const provider = new ethers.providers.Web3Provider(window.ethereum);
await provider.send("eth_requestAccounts", []);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<img style="height: 28px" src="https://avatars.githubusercontent.com/u/1885080?s=200&v=4" alt="Coinbase Wallet">
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<img width={40} height={40} src="https://github.com/WalletConnect/walletconnect-assets/raw/master/Logo/Blue%20(Default)/Logo.svg" alt="">
Loading

0 comments on commit 7f3ac3b

Please sign in to comment.