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

Support some USDC transfer on mainnet #570

Merged
merged 6 commits into from
Nov 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion packages/apps/src/components/cross-chain-info.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export default function CrossChainInfo({ fee, bridge, maxMargin, isLoadingMaxMar
{formatBalance(fee.value, fee.token.decimals, { precision: 6 })} {fee.token.symbol}
</span>
) : (
<Tooltip content="No relayer available, please check the transfer amount">
<Tooltip content="Liquidity is not enough">
<Image width={16} height={16} alt="Fee" src="/images/warning.svg" />
</Tooltip>
)}
Expand Down
45 changes: 41 additions & 4 deletions packages/apps/src/components/relayer-manage-modal.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import SegmentedTabs, { SegmentedTabsProps } from "@/ui/segmented-tabs";
import Tooltip from "@/ui/tooltip";
import Image from "next/image";
import { PropsWithChildren, useEffect, useMemo, useState } from "react";
import { PropsWithChildren, useCallback, useEffect, useMemo, useState } from "react";
import { BalanceInput } from "./balance-input";
import FeeRateInput from "./fee-rate-input";
import { LnRelayerInfo } from "@/types/graphql";
import { CheckLnBridgeExistResponseData, CheckLnBridgeExistVariables, LnRelayerInfo } from "@/types/graphql";
import { getChainConfig } from "@/utils/chain";
import { useNetwork, useSwitchNetwork } from "wagmi";
import { formatBalance } from "@/utils/balance";
Expand All @@ -14,6 +14,9 @@ import { formatFeeRate, isValidFeeRate } from "@/utils/misc";
import { TransactionReceipt } from "viem";
import { Token } from "@/types/token";
import { Subscription, from } from "rxjs";
import { useApolloClient } from "@apollo/client";
import { QUERY_CHECK_LNBRIDGE_EXIST } from "@/config/gql";
import { notification } from "@/ui/notification";

type TabKey = "update" | "deposit" | "withdraw";
const Modal = dynamic(() => import("@/ui/modal"), { ssr: false });
Expand Down Expand Up @@ -69,6 +72,36 @@ export default function RelayerManageModal({ relayerInfo, isOpen, onClose, onSuc

const { chain } = useNetwork();
const { switchNetwork } = useSwitchNetwork();
const apolloClient = useApolloClient();

const isLnBridgeExist = useCallback(async () => {
if (sourceChain && targetChain && sourceToken && targetToken) {
const { data: lnbridgeData } = await apolloClient.query<
CheckLnBridgeExistResponseData,
CheckLnBridgeExistVariables
>({
query: QUERY_CHECK_LNBRIDGE_EXIST,
variables: {
fromChainId: sourceChain.id,
toChainId: targetChain.id,
fromToken: sourceToken.address,
toToken: targetToken.address,
},
fetchPolicy: "no-cache",
});

if (lnbridgeData.checkLnBridgeExist) {
return true;
}
}

notification.warn({
title: "Deposit failed",
description: `The bridge does not exist.`,
});
console.warn("[isLnBridgeExist]", sourceChain?.id, targetChain?.id, sourceToken?.address, targetToken?.address);
return false;
}, [apolloClient, sourceChain, targetChain, sourceToken, targetToken]);

useEffect(() => {
const _category = relayerInfo?.bridge;
Expand Down Expand Up @@ -204,7 +237,9 @@ export default function RelayerManageModal({ relayerInfo, isOpen, onClose, onSuc
await targetApprove(depositAmount.formatted);
} else {
setBusy(true);
receipt = await depositMargin(depositAmount.formatted);
if (await isLnBridgeExist()) {
receipt = await depositMargin(depositAmount.formatted);
}
}
} else if (bridgeCategory === "lnbridgev20-opposite") {
if (chain?.id !== sourceChain?.id) {
Expand All @@ -214,7 +249,9 @@ export default function RelayerManageModal({ relayerInfo, isOpen, onClose, onSuc
await sourceApprove(depositAmount.formatted);
} else {
setBusy(true);
receipt = await updateFeeAndMargin(depositAmount.formatted, baseFee.formatted, feeRate.formatted);
if (await isLnBridgeExist()) {
receipt = await updateFeeAndMargin(depositAmount.formatted, baseFee.formatted, feeRate.formatted);
}
}
}
} else if (activeKey === "withdraw") {
Expand Down
60 changes: 45 additions & 15 deletions packages/apps/src/components/relayer-register.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
import Button from "@/ui/button";
import { Divider } from "@/ui/divider";
import StepNumber from "@/ui/step-number";
import { PropsWithChildren, useEffect, useState } from "react";
import { PropsWithChildren, useCallback, useEffect, useState } from "react";
import ChainSelect from "./chain-select";
import TokenSelect from "./token-select";
import { ChainConfig } from "@/types/chain";
import { ChainConfig, ChainID } from "@/types/chain";
import { Token, TokenSymbol } from "@/types/token";
import { BridgeCategory } from "@/types/bridge";
import { useAccount, useNetwork, useSwitchNetwork } from "wagmi";
import { Address, useAccount, useNetwork, useSwitchNetwork } from "wagmi";
import Image from "next/image";
import { formatFeeRate, getChainLogoSrc, getTokenLogoSrc, isValidFeeRate } from "@/utils/misc";
import Tooltip from "@/ui/tooltip";
Expand All @@ -21,8 +21,13 @@ import { getParsedCrossChain } from "@/utils/cross-chain";
import { useConnectModal } from "@rainbow-me/rainbowkit";
import { formatBalance } from "@/utils/balance";
import { useApolloClient } from "@apollo/client";
import { QUERY_SPECIAL_RELAYER } from "@/config/gql";
import { SpecialRelayerResponseData, SpecialRelayerVariables } from "@/types/graphql";
import { QUERY_CHECK_LNBRIDGE_EXIST, QUERY_SPECIAL_RELAYER } from "@/config/gql";
import {
CheckLnBridgeExistResponseData,
CheckLnBridgeExistVariables,
SpecialRelayerResponseData,
SpecialRelayerVariables,
} from "@/types/graphql";
import { notification } from "@/ui/notification";
import { useRelayer } from "@/hooks/use-relayer";
import dynamic from "next/dynamic";
Expand Down Expand Up @@ -107,6 +112,35 @@ export default function RelayerRegister() {
}
};

const isLnBridgeExist = useCallback(async () => {
if (sourceChain && targetChain && sourceToken && targetToken) {
const { data: lnbridgeData } = await apolloClient.query<
CheckLnBridgeExistResponseData,
CheckLnBridgeExistVariables
>({
query: QUERY_CHECK_LNBRIDGE_EXIST,
variables: {
fromChainId: sourceChain.id,
toChainId: targetChain.id,
fromToken: sourceToken.address,
toToken: targetToken.address,
},
fetchPolicy: "no-cache",
});

if (lnbridgeData.checkLnBridgeExist) {
return true;
}
}

notification.warn({
title: "Deposit failed",
description: `The bridge does not exist.`,
});
console.warn("[isLnBridgeExist]", sourceChain?.id, targetChain?.id, sourceToken?.address, targetToken?.address);
return false;
}, [apolloClient, sourceChain, targetChain, sourceToken, targetToken]);

useEffect(() => {
const availableCategories = new Set<BridgeCategory>();

Expand Down Expand Up @@ -219,6 +253,10 @@ export default function RelayerRegister() {
setSourceChain(undefined);
setTargetChain(undefined);
setSourceToken(undefined);
setBridgeCategory(undefined);
setMargin({ formatted: 0n, value: "" });
setBaseFee({ formatted: 0n, value: "" });
setFeeRate({ formatted: 0, value: "" });
setCurrentStep(Step.ONE);
setCompleteMargin(false);
}}
Expand Down Expand Up @@ -270,10 +308,6 @@ export default function RelayerRegister() {
} else if (targetToken?.type !== "native" && margin.formatted > (targetAllowance?.value || 0n)) {
try {
setIsSettingDefaultMargin(true);
if (await isRegistered()) {
setIsSettingDefaultMargin(false);
return;
}
await targetApprove(margin.formatted);
} catch (err) {
console.error(err);
Expand All @@ -283,7 +317,7 @@ export default function RelayerRegister() {
} else {
try {
setIsSettingDefaultMargin(true);
if (await isRegistered()) {
if ((await isRegistered()) || !(await isLnBridgeExist())) {
setIsSettingDefaultMargin(false);
return;
}
Expand Down Expand Up @@ -340,10 +374,6 @@ export default function RelayerRegister() {
) {
try {
setBusy(true);
if (await isRegistered()) {
setBusy(false);
return;
}
await sourceApprove(margin.formatted);
} catch (err) {
console.error(err);
Expand All @@ -353,7 +383,7 @@ export default function RelayerRegister() {
} else {
try {
setBusy(true);
if (await isRegistered()) {
if ((await isRegistered()) || !(await isLnBridgeExist())) {
setBusy(false);
return;
}
Expand Down
12 changes: 12 additions & 0 deletions packages/apps/src/config/chains/arbitrum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,17 @@ export const arbitrumChain: ChainConfig = {
{ target: { network: "bsc", symbol: "USDT" }, bridge: { category: "lnbridgev20-default" } },
],
},
{
decimals: 6,
symbol: "USDC",
name: "USDC",
type: "erc20",
address: "0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8",
logo: "usdc.svg",
cross: [
{ target: { network: "mantle", symbol: "USDC" }, bridge: { category: "lnbridgev20-default" } },
{ target: { network: "scroll", symbol: "USDC" }, bridge: { category: "lnbridgev20-default" } },
],
},
],
};
12 changes: 12 additions & 0 deletions packages/apps/src/config/chains/mantle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,17 @@ export const mantleChain: ChainConfig = {
{ target: { network: "scroll", symbol: "USDT" }, bridge: { category: "lnbridgev20-default" } },
],
},
{
decimals: 6,
symbol: "USDC",
name: "USDC",
type: "erc20",
address: "0x09Bc4E0D864854c6aFB6eB9A9cdF58aC190D0dF9",
logo: "usdc.svg",
cross: [
{ target: { network: "arbitrum", symbol: "USDC" }, bridge: { category: "lnbridgev20-default" } },
{ target: { network: "scroll", symbol: "USDC" }, bridge: { category: "lnbridgev20-default" } },
],
},
],
};
12 changes: 12 additions & 0 deletions packages/apps/src/config/chains/scroll.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,17 @@ export const scrollChain: ChainConfig = {
{ target: { network: "zksync", symbol: "USDT" }, bridge: { category: "lnbridgev20-default" } },
],
},
{
decimals: 6,
symbol: "USDC",
name: "USDC",
type: "erc20",
address: "0x06eFdBFf2a14a7c8E15944D1F4A48F9F95F663A4",
logo: "usdc.svg",
cross: [
{ target: { network: "mantle", symbol: "USDC" }, bridge: { category: "lnbridgev20-default" } },
{ target: { network: "arbitrum", symbol: "USDC" }, bridge: { category: "lnbridgev20-default" } },
],
},
],
};
9 changes: 9 additions & 0 deletions packages/apps/src/config/chains/zksync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,14 @@ export const zksyncChain: ChainConfig = {
{ target: { network: "scroll", symbol: "USDT" }, bridge: { category: "lnbridgev20-default" } },
],
},
{
decimals: 6,
symbol: "USDC",
name: "USDC",
type: "erc20",
address: "0x3355df6D4c9C3035724Fd0e3914dE96A5a83aaf4",
logo: "usdc.svg",
cross: [],
},
],
};
6 changes: 6 additions & 0 deletions packages/apps/src/config/gql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,9 @@ export const QUERY_TX_PROGRESS = gql`
}
}
`;

export const QUERY_CHECK_LNBRIDGE_EXIST = gql`
query checkLnBridgeExist($fromChainId: Int, $toChainId: Int, $fromToken: String, $toToken: String) {
checkLnBridgeExist(fromChainId: $fromChainId, toChainId: $toChainId, fromToken: $fromToken, toToken: $toToken)
}
`;
8 changes: 4 additions & 4 deletions packages/apps/src/providers/relayer-provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ export default function RelayerProvider({ children }: PropsWithChildren<unknown>
if (address && bridgeClient) {
try {
const receipt = await bridgeClient.targetApprove(amount, address);
notifyTransaction(receipt, sourceChain);
notifyTransaction(receipt, targetChain);

setTargetAllowance(await bridgeClient.getTargetAllowance(address));

Expand All @@ -175,15 +175,15 @@ export default function RelayerProvider({ children }: PropsWithChildren<unknown>
}
}
},
[address, bridgeClient, sourceChain],
[address, bridgeClient, targetChain],
);

const depositMargin = useCallback(
async (margin: bigint) => {
if (address && defaultBridge) {
try {
const receipt = await defaultBridge.depositMargin(margin);
notifyTransaction(receipt, sourceChain);
notifyTransaction(receipt, targetChain);

const a = await defaultBridge.getTargetAllowance(address);
const b = await defaultBridge.getTargetBalance(address);
Expand All @@ -197,7 +197,7 @@ export default function RelayerProvider({ children }: PropsWithChildren<unknown>
}
}
},
[address, defaultBridge, sourceChain],
[address, defaultBridge, targetChain],
);

const setFeeAndRate = useCallback(
Expand Down
13 changes: 12 additions & 1 deletion packages/apps/src/types/graphql.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { TokenSymbol } from "./token";
import { BridgeCategory } from "./bridge";
import { Network } from "./chain";
import { ChainID, Network } from "./chain";
import { Address } from "viem";

export enum RecordStatus {
Expand Down Expand Up @@ -165,3 +165,14 @@ export interface TxProgressResponseData {
export interface TxProgressVariables {
txHash: string;
}

export interface CheckLnBridgeExistResponseData {
checkLnBridgeExist: boolean | null;
}

export interface CheckLnBridgeExistVariables {
fromChainId: ChainID;
toChainId: ChainID;
fromToken: Address;
toToken: Address;
}
Loading