Skip to content

Commit

Permalink
token contains the type
Browse files Browse the repository at this point in the history
  • Loading branch information
jscriptcoder committed Jul 24, 2023
1 parent 2220283 commit 637b94c
Show file tree
Hide file tree
Showing 12 changed files with 81 additions and 114 deletions.
86 changes: 44 additions & 42 deletions packages/bridge-ui-v2/src/components/Bridge/Bridge.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@
import { PUBLIC_L1_EXPLORER_URL } from '$env/static/public';
import { type Bridge, type BridgeArgs, bridges, type ERC20BridgeArgs, type ETHBridgeArgs } from '$libs/bridge';
import type { ERC20Bridge } from '$libs/bridge/ERC20Bridge';
import type { ETHBridge } from '$libs/bridge/ETHBridge';
import { chainContractsMap, chains } from '$libs/chain';
import { ApproveError, NoAllowanceRequiredError, SendERC20Error, SendMessageError } from '$libs/error';
import { ETHToken, getAddress, isDeployedCrossChain, isETH, tokens } from '$libs/token';
import { ETHToken, getAddress, isDeployedCrossChain, tokens, TokenType } from '$libs/token';
import { getConnectedWallet } from '$libs/util/getConnectedWallet';
import { type Account, account } from '$stores/account';
import { type Network, network } from '$stores/network';
Expand All @@ -25,7 +24,7 @@
import Amount from './Amount.svelte';
import { ProcessingFee } from './ProcessingFee';
import Recipient from './Recipient.svelte';
import { destNetwork, enteredAmount, processingFee, recipientAddress, selectedToken } from './state';
import { bridgeService, destNetwork, enteredAmount, processingFee, recipientAddress, selectedToken } from './state';
import SwitchChainsButton from './SwitchChainsButton.svelte';
let amountComponent: Amount;
Expand Down Expand Up @@ -119,13 +118,11 @@
}
async function bridge() {
if (!$selectedToken || !$network || !$destNetwork || !$account?.address) return;
if (!$bridgeService || !$selectedToken || !$network || !$destNetwork || !$account?.address) return;
try {
const walletClient = await getConnectedWallet($network.id);
let bridge: Bridge;
// Common arguments for both ETH and ERC20 bridges
let bridgeArgs = {
to: $recipientAddress || $account.address,
Expand All @@ -136,47 +133,52 @@
processingFee: $processingFee,
} as BridgeArgs;
if (isETH($selectedToken)) {
bridge = bridges.ETH as ETHBridge;
// Specific arguments for ETH bridge:
// - bridgeAddress
const bridgeAddress = chainContractsMap[$network.id].bridgeAddress;
bridgeArgs = { ...bridgeArgs, bridgeAddress } as ETHBridgeArgs;
} else {
bridge = bridges.ERC20 as ERC20Bridge;
// Specific arguments for ERC20 bridge
// - tokenAddress
// - tokenVaultAddress
// - isTokenAlreadyDeployed
const tokenAddress = await getAddress({
token: $selectedToken,
srcChainId: $network.id,
destChainId: $destNetwork.id,
});
if (!tokenAddress) {
throw new Error('token address not found');
switch ($selectedToken.type) {
case TokenType.ETH: {
// Specific arguments for ETH bridge:
// - bridgeAddress
const bridgeAddress = chainContractsMap[$network.id].bridgeAddress;
bridgeArgs = { ...bridgeArgs, bridgeAddress } as ETHBridgeArgs;
break;
}
const tokenVaultAddress = chainContractsMap[$network.id].tokenVaultAddress;
const isTokenAlreadyDeployed = await isDeployedCrossChain({
token: $selectedToken,
srcChainId: $network.id,
destChainId: $destNetwork.id,
});
case TokenType.ERC20: {
// Specific arguments for ERC20 bridge
// - tokenAddress
// - tokenVaultAddress
// - isTokenAlreadyDeployed
const tokenAddress = await getAddress({
token: $selectedToken,
srcChainId: $network.id,
destChainId: $destNetwork.id,
});
if (!tokenAddress) {
throw new Error('token address not found');
}
const tokenVaultAddress = chainContractsMap[$network.id].tokenVaultAddress;
const isTokenAlreadyDeployed = await isDeployedCrossChain({
token: $selectedToken,
srcChainId: $network.id,
destChainId: $destNetwork.id,
});
bridgeArgs = {
...bridgeArgs,
tokenAddress,
tokenVaultAddress,
isTokenAlreadyDeployed,
} as ERC20BridgeArgs;
break;
}
bridgeArgs = {
...bridgeArgs,
tokenAddress,
tokenVaultAddress,
isTokenAlreadyDeployed,
} as ERC20BridgeArgs;
default:
throw new Error('invalid token type');
}
const txHash = await bridge.bridge(bridgeArgs);
const txHash = await $bridgeService.bridge(bridgeArgs);
infoToast(
$t('bridge.bridge.tx', {
Expand Down
6 changes: 5 additions & 1 deletion packages/bridge-ui-v2/src/components/Bridge/state.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { Address, Chain, FetchBalanceResult } from '@wagmi/core';
import { writable } from 'svelte/store';
import { derived, writable } from 'svelte/store';

import { bridges } from '$libs/bridge';
import type { Token } from '$libs/token';

// Note: we could combine this with Context API, but since we'll only
Expand Down Expand Up @@ -35,3 +36,6 @@ export const errorComputingBalance = writable<boolean>(false);
// is a warning but the user must approve allowance before bridging
export const insufficientBalance = writable<boolean>(false);
export const insufficientAllowance = writable<boolean>(false);

// Derived state
export const bridgeService = derived(selectedToken, (token) => (token ? bridges[token.type] : null));
6 changes: 4 additions & 2 deletions packages/bridge-ui-v2/src/libs/bridge/bridges.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import type { TokenType } from '$libs/token';

import { ERC20Bridge } from './ERC20Bridge';
import { ERC721Bridge } from './ERC721Bridge';
import { ERC1155Bridge } from './ERC1155Bridge';
import { ETHBridge } from './ETHBridge';
import type { Bridge, BridgeType } from './types';
import type { Bridge } from './types';

export const bridges: Record<BridgeType, Bridge> = {
export const bridges: Record<TokenType, Bridge> = {
ETH: new ETHBridge(),
ERC20: new ERC20Bridge(),
ERC721: new ERC721Bridge(),
Expand Down
4 changes: 2 additions & 2 deletions packages/bridge-ui-v2/src/libs/bridge/checkBalanceToBridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { type Address, zeroAddress } from 'viem';

import { chainContractsMap } from '$libs/chain';
import { InsufficientAllowanceError, InsufficientBalanceError, RevertedWithFailedError } from '$libs/error';
import { getAddress, isETH, type Token } from '$libs/token';
import { getAddress, type Token,TokenType } from '$libs/token';
import { isDeployedCrossChain } from '$libs/token/isDeployedCrossChain';
import { getConnectedWallet } from '$libs/util/getConnectedWallet';

Expand Down Expand Up @@ -41,7 +41,7 @@ export async function checkBalanceToBridge({
processingFee,
} as BridgeArgs;

if (isETH(token)) {
if (token.type === TokenType.ETH) {
const { bridgeAddress } = chainContractsMap[srcChainId];

try {
Expand Down
4 changes: 2 additions & 2 deletions packages/bridge-ui-v2/src/libs/bridge/getMaxAmountToBridge.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Address } from 'viem';

import { chainContractsMap } from '$libs/chain';
import { isETH, type Token } from '$libs/token';
import { type Token,TokenType } from '$libs/token';
import { getConnectedWallet } from '$libs/util/getConnectedWallet';
import { getLogger } from '$libs/util/logger';

Expand Down Expand Up @@ -33,7 +33,7 @@ export async function getMaxAmountToBridge({
// For ERC20 tokens, we can bridge the whole balance
let maxAmount = balance;

if (isETH(token)) {
if (token.type === TokenType.ETH) {
// We cannot really compute the cost of bridging ETH without
if (!to || !srcChainId || !destChainId) {
throw Error('missing required arguments to compute cost');
Expand Down
13 changes: 0 additions & 13 deletions packages/bridge-ui-v2/src/libs/bridge/types.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,6 @@
import type { WalletClient } from '@wagmi/core';
import type { Address, Hex } from 'viem';

export enum BridgeType {
ETH = 'ETH',

// https://ethereum.org/en/developers/docs/standards/tokens/erc-20/
ERC20 = 'ERC20',

// https://ethereum.org/en/developers/docs/standards/tokens/erc-721/
ERC721 = 'ERC721',

// https://ethereum.org/en/developers/docs/standards/tokens/erc-1155/
ERC1155 = 'ERC1155',
}

// Bridge sendMessage(message: Message)
export type Message = {
// Message ID. Will be set in contract
Expand Down
5 changes: 2 additions & 3 deletions packages/bridge-ui-v2/src/libs/token/getAddress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import { NoTokenAddressError } from '$libs/error';
import { getLogger } from '$libs/util/logger';

import { getCrossChainAddress } from './getCrossChainAddress';
import { isETH } from './tokens';
import type { Token } from './types';
import { type Token,TokenType } from './types';

type GetAddressArgs = {
token: Token;
Expand All @@ -16,7 +15,7 @@ type GetAddressArgs = {
const log = getLogger('token:getAddress');

export async function getAddress({ token, srcChainId, destChainId }: GetAddressArgs) {
if (isETH(token)) return; // ETH doesn't have an address
if (token.type === TokenType.ETH) return; // ETH doesn't have an address

// Get the address for the token on the source chain
let address: Maybe<Address> = token.addresses[srcChainId];
Expand Down
5 changes: 2 additions & 3 deletions packages/bridge-ui-v2/src/libs/token/getBalance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import { type Address, zeroAddress } from 'viem';
import { getLogger } from '$libs/util/logger';

import { getAddress } from './getAddress';
import { isETH } from './tokens';
import type { Token } from './types';
import { type Token,TokenType } from './types';

type GetBalanceArgs = {
userAddress: Address;
Expand All @@ -19,7 +18,7 @@ const log = getLogger('token:getBalance');
export async function getBalance({ userAddress, token, srcChainId, destChainId }: GetBalanceArgs) {
let tokenBalance: FetchBalanceResult;

if (!token || isETH(token)) {
if (!token || token.type === TokenType.ETH) {
// If no token is passed in, we assume is ETH
tokenBalance = await fetchBalance({ address: userAddress });
} else {
Expand Down
5 changes: 2 additions & 3 deletions packages/bridge-ui-v2/src/libs/token/getCrossChainAddress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ import { getContract } from '@wagmi/core';
import { tokenVaultABI } from '$abi';
import { chainContractsMap } from '$libs/chain';

import { isETH } from './tokens';
import type { Token } from './types';
import { type Token,TokenType } from './types';

type GetCrossChainAddressArgs = {
token: Token;
Expand All @@ -13,7 +12,7 @@ type GetCrossChainAddressArgs = {
};

export function getCrossChainAddress({ token, srcChainId, destChainId }: GetCrossChainAddressArgs) {
if (isETH(token)) return; // ETH doesn't have an address
if (token.type === TokenType.ETH) return; // ETH doesn't have an address

const { tokenVaultAddress } = chainContractsMap[destChainId];

Expand Down
28 changes: 0 additions & 28 deletions packages/bridge-ui-v2/src/libs/token/tokens.test.ts

This file was deleted.

19 changes: 4 additions & 15 deletions packages/bridge-ui-v2/src/libs/token/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { zeroAddress } from 'viem';
import { PUBLIC_L1_CHAIN_ID, PUBLIC_L2_CHAIN_ID, PUBLIC_TEST_ERC20 } from '$env/static/public';
import { jsonParseWithDefault } from '$libs/util/jsonParseWithDefault';

import type { Token, TokenEnv } from './types';
import { type Token, type TokenEnv, TokenType } from './types';

export const ETHToken: Token = {
name: 'Ether',
Expand All @@ -13,6 +13,7 @@ export const ETHToken: Token = {
},
decimals: 18,
symbol: 'ETH',
type: TokenType.ETH,
};

export const TKOToken: Token = {
Expand All @@ -23,6 +24,7 @@ export const TKOToken: Token = {
},
decimals: 8,
symbol: 'TKO',
type: TokenType.ERC20,
};

export const testERC20Tokens: Token[] = jsonParseWithDefault<TokenEnv[]>(PUBLIC_TEST_ERC20, []).map(
Expand All @@ -35,21 +37,8 @@ export const testERC20Tokens: Token[] = jsonParseWithDefault<TokenEnv[]>(PUBLIC_
[PUBLIC_L2_CHAIN_ID]: zeroAddress,
},
decimals: 18,
type: TokenType.ERC20,
}),
);

export const tokens = [ETHToken, ...testERC20Tokens];

export function isETH(token: Token) {
// Should be fine just by checking the symbol
return token.symbol.toLocaleLowerCase() === ETHToken.symbol.toLocaleLowerCase();
}

export function isERC20(token: Token): boolean {
return !isETH(token);
}

export function isTestToken(token: Token): boolean {
const testTokenSymbols = testERC20Tokens.map((testToken) => testToken.symbol.toLocaleLowerCase());
return testTokenSymbols.includes(token.symbol.toLocaleLowerCase());
}
14 changes: 14 additions & 0 deletions packages/bridge-ui-v2/src/libs/token/types.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
import type { Address } from 'viem';

export enum TokenType {
ETH = 'ETH',

// https://ethereum.org/en/developers/docs/standards/tokens/erc-20/
ERC20 = 'ERC20',

// https://ethereum.org/en/developers/docs/standards/tokens/erc-721/
ERC721 = 'ERC721',

// https://ethereum.org/en/developers/docs/standards/tokens/erc-1155/
ERC1155 = 'ERC1155',
}

export type Token = {
name: string;
addresses: Record<string, Address>;
symbol: string;
decimals: number;
type: TokenType;
};

export type TokenEnv = {
Expand Down

0 comments on commit 637b94c

Please sign in to comment.