diff --git a/packages/bridge-ui/src/App.svelte b/packages/bridge-ui/src/App.svelte
index a6e8fe64ca2..efcacff5f57 100644
--- a/packages/bridge-ui/src/App.svelte
+++ b/packages/bridge-ui/src/App.svelte
@@ -159,7 +159,7 @@
const updatedStorageTxs: BridgeTransaction[] = txs.filter((tx) => {
const blockInfo = blockInfoMap.get(tx.fromChainId);
- if (blockInfo?.latestProcessedBlock >= tx.receipt.blockNumber) {
+ if (blockInfo?.latestProcessedBlock >= tx.receipt?.blockNumber) {
return false;
}
return true;
diff --git a/packages/bridge-ui/src/bridge/ERC20Bridge.ts b/packages/bridge-ui/src/bridge/ERC20Bridge.ts
index 71bb863da77..309e8a541df 100644
--- a/packages/bridge-ui/src/bridge/ERC20Bridge.ts
+++ b/packages/bridge-ui/src/bridge/ERC20Bridge.ts
@@ -1,4 +1,4 @@
-import { BigNumber, Contract, Signer } from 'ethers';
+import { BigNumber, Contract, ethers, Signer } from 'ethers';
import type { Transaction } from 'ethers';
import type {
ApproveOpts,
@@ -190,7 +190,23 @@ export class ERC20Bridge implements Bridge {
});
}
- return await contract.processMessage(opts.message, proof);
+ let processMessageTx;
+ try {
+ processMessageTx = await contract.processMessage(opts.message, proof);
+ } catch (error) {
+ if (error.code === ethers.errors.UNPREDICTABLE_GAS_LIMIT) {
+ processMessageTx = await contract.processMessage(
+ opts.message,
+ proof,
+ {
+ gasLimit: 1e6,
+ },
+ );
+ } else {
+ throw new Error(error);
+ }
+ }
+ return processMessageTx;
} else {
return await contract.retryMessage(opts.message, false);
}
diff --git a/packages/bridge-ui/src/bridge/ETHBridge.ts b/packages/bridge-ui/src/bridge/ETHBridge.ts
index 5b3ea01f2ba..74d4610ab62 100644
--- a/packages/bridge-ui/src/bridge/ETHBridge.ts
+++ b/packages/bridge-ui/src/bridge/ETHBridge.ts
@@ -1,4 +1,4 @@
-import { BigNumber, Contract } from 'ethers';
+import { BigNumber, Contract, ethers } from 'ethers';
import type { Transaction } from 'ethers';
import type {
ApproveOpts,
@@ -133,7 +133,23 @@ export class ETHBridge implements Bridge {
};
const proof = await this.prover.GenerateProof(proofOpts);
- return await contract.processMessage(opts.message, proof);
+ let processMessageTx;
+ try {
+ processMessageTx = await contract.processMessage(opts.message, proof);
+ } catch (error) {
+ if (error.code === ethers.errors.UNPREDICTABLE_GAS_LIMIT) {
+ processMessageTx = await contract.processMessage(
+ opts.message,
+ proof,
+ {
+ gasLimit: 1e6,
+ },
+ );
+ } else {
+ throw new Error(error);
+ }
+ }
+ return processMessageTx;
} else {
return await contract.retryMessage(opts.message, true);
}
diff --git a/packages/bridge-ui/src/components/InsufficientBalanceTooltip.svelte b/packages/bridge-ui/src/components/InsufficientBalanceTooltip.svelte
new file mode 100644
index 00000000000..1f1bc82d949
--- /dev/null
+++ b/packages/bridge-ui/src/components/InsufficientBalanceTooltip.svelte
@@ -0,0 +1,14 @@
+
+
+
+
+
+ You have insufficient balance to claim this transaction. Please wait for
+ the relayer to claim the transaction for you.
+
+
+
diff --git a/packages/bridge-ui/src/components/Transaction.svelte b/packages/bridge-ui/src/components/Transaction.svelte
index 89e36b64ca8..a718bea7066 100644
--- a/packages/bridge-ui/src/components/Transaction.svelte
+++ b/packages/bridge-ui/src/components/Transaction.svelte
@@ -4,7 +4,11 @@
import { ArrowTopRightOnSquare } from 'svelte-heros-v2';
import { MessageStatus } from '../domain/message';
import { Contract, ethers } from 'ethers';
- import { bridges, chainIdToTokenVaultAddress } from '../store/bridge';
+ import {
+ activeBridge,
+ bridges,
+ chainIdToTokenVaultAddress,
+ } from '../store/bridge';
import { signer } from '../store/signer';
import { pendingTransactions } from '../store/transactions';
import { errorToast, successToast } from '../utils/toast';
@@ -19,7 +23,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';
+ import { fetchFeeData, fetchSigner, switchNetwork } from '@wagmi/core';
import Bridge from '../constants/abi/Bridge';
import ButtonWithTooltip from './ButtonWithTooltip.svelte';
import TokenVault from '../constants/abi/TokenVault';
@@ -29,7 +33,7 @@
export let fromChain: Chain;
export let toChain: Chain;
- export let onTooltipClick: () => void;
+ export let onTooltipClick: (showInsufficientBalanceMessage: boolean) => void;
export let onShowTransactionDetailsClick: () => void;
let loading: boolean;
@@ -76,6 +80,14 @@
await switchChainAndSetSigner(chain);
}
+ // For now just handling this case for when the user has near 0 balance during their first bridge transaction to L2
+ // TODO: estimate Claim transaction
+ const userBalance = await $signer.getBalance('latest');
+ if (!userBalance.gt(ethers.utils.parseEther('0.0001'))) {
+ onTooltipClick(true);
+ return;
+ }
+
const tx = await $bridges
.get(
bridgeTx.message?.data === '0x' || !bridgeTx.message?.data
@@ -96,6 +108,7 @@
});
successToast($_('toast.transactionSent'));
+ transaction.status = MessageStatus.ClaimInProgress;
} catch (e) {
console.error(e);
errorToast($_('toast.errorSendingTransaction'));
@@ -226,7 +239,7 @@
-
+ onTooltipClick(false)}>
{#if !processable}
Pending
@@ -243,10 +256,11 @@
width={26}
controlsLayout={[]} />
- {:else if transaction.receipt && transaction.status === MessageStatus.New}
+ {:else if transaction.receipt && [MessageStatus.New, MessageStatus.ClaimInProgress].includes(transaction.status)}
{:else if transaction.status === MessageStatus.Retriable}
diff --git a/packages/bridge-ui/src/components/Transactions.svelte b/packages/bridge-ui/src/components/Transactions.svelte
index 2bc5b882c08..80f33a74735 100644
--- a/packages/bridge-ui/src/components/Transactions.svelte
+++ b/packages/bridge-ui/src/components/Transactions.svelte
@@ -3,11 +3,13 @@
import Transaction from './Transaction.svelte';
import TransactionDetail from './TransactionDetail.svelte';
import MessageStatusTooltip from './MessageStatusTooltip.svelte';
+ import InsufficientBalanceTooltip from './InsufficientBalanceTooltip.svelte';
import type { BridgeTransaction } from '../domain/transactions';
import { chainsRecord } from '../chain/chains';
let selectedTransaction: BridgeTransaction;
let showMessageStatusTooltip: boolean;
+ let showInsufficientBalance: boolean;
@@ -25,8 +27,12 @@
{#each $transactions as transaction}
{
- showMessageStatusTooltip = true;
+ onTooltipClick={(showInsufficientBalanceMessage = false) => {
+ if (showInsufficientBalanceMessage) {
+ showInsufficientBalance = true;
+ } else {
+ showMessageStatusTooltip = true;
+ }
}}
onShowTransactionDetailsClick={() => {
selectedTransaction = transaction;
@@ -47,5 +53,6 @@
onClose={() => (selectedTransaction = null)} />
{/if}
-
+
+
diff --git a/packages/bridge-ui/src/domain/message.ts b/packages/bridge-ui/src/domain/message.ts
index 0b7c1350d1a..2d01befb0c4 100644
--- a/packages/bridge-ui/src/domain/message.ts
+++ b/packages/bridge-ui/src/domain/message.ts
@@ -6,6 +6,7 @@ export enum MessageStatus {
Done,
Failed,
FailedReleased,
+ ClaimInProgress,
}
export type Message = {
|