diff --git a/app/components/TransactionPool/index.tsx b/app/components/TransactionPool/index.tsx index cd4a357..f725f5b 100644 --- a/app/components/TransactionPool/index.tsx +++ b/app/components/TransactionPool/index.tsx @@ -23,7 +23,7 @@ export const TransactionProvider = ({ children } : { children: ReactNode}) => { const [pendingTransactions, setPendingTransactions] = useState([]); const [lastAddress, setLastAddress] = useState(''); const [viemClient, setClient] = useState(null) - const { selectedOption, bridgeProgram, eclipseRpc, withdrawApi, legacyAddress } = useNetwork(); + const { selectedOption, bridgeProgram, eclipseRpc, withdrawApi } = useNetwork(); const { evmWallet } = useWallets(); const fetchDeposits = async () => { @@ -43,7 +43,7 @@ export const TransactionProvider = ({ children } : { children: ReactNode}) => { } try { - const withdrawalsData = await getWithdrawalsByAddress(evmWallet?.address || '', withdrawApi, legacyAddress); + const withdrawalsData = await getWithdrawalsByAddress(evmWallet?.address || '', withdrawApi); setWithdrawals(withdrawalsData) withdrawalsData.forEach(async (item, index) => { await delay(index * 300); diff --git a/app/components/WithdrawDetails/index.tsx b/app/components/WithdrawDetails/index.tsx index 1ccc93c..2b44060 100644 --- a/app/components/WithdrawDetails/index.tsx +++ b/app/components/WithdrawDetails/index.tsx @@ -8,7 +8,6 @@ import { Transport, Chain, Account } from "viem"; import { useTransaction } from "../TransactionPool"; import { createPublicClient, http, WalletClient } from "viem"; import { mainnet, sepolia } from "viem/chains"; -import { getGasPrice } from "viem/actions"; import { CONTRACT_ABI, WITHDRAW_TX_FEE } from "../constants"; import { composeEclipsescanUrl, @@ -117,11 +116,7 @@ export const WithdrawDetails: React.FC = ({ ethStatus, ethAmount, }) => { - const [gasPrice, ethPrice, blockNumber] = useContext(EthereumDataContext) ?? [ - null, - null, - null, - ]; + const [_, ethPrice] = useContext(EthereumDataContext) ?? [0, 0]; const { transactions, deposits, @@ -201,56 +196,20 @@ export const WithdrawDetails: React.FC = ({ feeReceiver: tx[0].message.fee_receiver, feeWei: tx[0].message.fee_wei, }; - // Use the contract address from the withdrawal data (V2 API provides this) - const targetContractAddress = tx[0].bridge; try { - // Setup gas price for configured gas parameters - // - // message.feeWei (exact calculation from relayer) - // - // pub const CANONICAL_BRIDGE_AUTHORIZE_WITHDRAW_GAS_AMOUNT: u64 = 106_800_u64; - // - // pub async fn estimate_authorize_withdraw_fees(&self) -> eyre::Result { - // let gas_price = self - // .provider - // .estimate_gas_price() - // .await - // .wrap_err("failed to query CanonicalBridge provider estimate_gas_price")?; - // - // Ok((U256::from(CANONICAL_BRIDGE_AUTHORIZE_WITHDRAW_GAS_AMOUNT) * gas_price * 12) / 10) - // } - // - // let eth_fee_wei = self - // .canonical_bridge - // .estimate_authorize_withdraw_fees() - // .await?; - // - - // Calculate auth gas price from message.feeWei (deterministic) - let canonicalBridgeGasEstimate = (BigInt(106_800) * BigInt(12)) / BigInt(10); - let authGasPrice = BigInt(message.feeWei) / canonicalBridgeGasEstimate; - - // Get market gas price - let nodeGasPriceWei = await getGasPrice(client); // Should return bigint - let marketGasPriceWei = nodeGasPriceWei > ONE_GWEI ? nodeGasPriceWei : ONE_GWEI // 1 gwei - - // Determine use gas price: max(authGasPrice, marketPrice) - const useGasPrice = authGasPrice > marketGasPriceWei ? authGasPrice : marketGasPriceWei; - - // claimWithdraw is about 75k gas - let txResponse = await walletClient!.writeContract({ + // simulate transaction and send + const { request } = await client.simulateContract({ //@ts-ignore - address: targetContractAddress, + address: contractAddress, abi: CONTRACT_ABI, functionName: "claimWithdraw", args: [message], account, - gas: BigInt(100_000), // Set a 100k gas limit for the claim transaction - gasPrice: (useGasPrice * BigInt(12)) / BigInt(10), // Bid slightly more than formula value: BigInt(0), chain: isMainnet ? mainnet : sepolia, }); + let txResponse = await walletClient!.writeContract(request); if (!txResponse.startsWith("0x")) txResponse = `0x${txResponse}`; setButtonText("Confirming"); @@ -269,7 +228,7 @@ export const WithdrawDetails: React.FC = ({ ); setWithdrawals(updatedWithdrawals); } catch (error) { - console.log(`❌ Failed to claim from contract ${targetContractAddress}:`, error); + console.log(`❌ Failed to claim from contract ${contractAddress}:`, error); } setIsClaimFlowOpen(false); setButtonText("Claim Now"); diff --git a/app/contexts/NetworkContext.tsx b/app/contexts/NetworkContext.tsx index bc7532d..c37bb79 100644 --- a/app/contexts/NetworkContext.tsx +++ b/app/contexts/NetworkContext.tsx @@ -48,7 +48,6 @@ type NetworkContextType = { bridgeProgram: string; eclipseRpc: string; contractAddress: string; - legacyAddress: string; // V1 contract address for backward compatibility relayerAddress: string; configAccount: string; withdrawApi: string; @@ -66,8 +65,7 @@ export const NetworkProvider = ({ selectedOption, setSelectedOption, children }: const isMainnet = (selectedOption === Options.Mainnet); const bridgeProgram = isMainnet ? "br1xwubggTiEZ6b7iNZUwfA3psygFfaXGfZ1heaN9AW" : "br1t2MBNdtVRZk3taADwNLt142cVNkekXe1hn3qJVYb" const eclipseRpc = isMainnet ? "https://eclipse.lgns.net/" : "https://testnet.dev2.eclipsenetwork.xyz" - const contractAddress = isMainnet ? "0x867A8FcD5Bb6774d4d37fb342D669A35FF789a51" : "0x568a5e1Ad8F6FA834C0d28c9D29Fb3eB86fe84E9" - const legacyAddress = isMainnet ? "0x2B08D7cF7EafF0f5f6623d9fB09b080726D4be11" : "0xe49aaa25a10fd6e15dd7ddcb50904ca1e91f6e01" // V1 contract address for backward compatibility + const contractAddress = isMainnet ? "0x867A8FcD5Bb6774d4d37fb342D669A35FF789a51" : "0x21c6AAB98a41560df325F74055d11d79ECae7139" const relayerAddress = isMainnet ? "CrfbABN2sSvmoZLu9eDDfXpaC2nHg42R7AXbHs9eg4S9" : "ec1vCnQKsQSnTbcTyc3SH2azcDXZquiFB3QqtRvm3Px" const configAccount = isMainnet ? "B6UA9rd6Qrx9chsrcMWPV3EFnSb1cbnf7AA2wdkhkpqw" : "A3jHKVwNvrvTjnUPGKYei9jbPn7NcraD6H94ewWyfVMY" const withdrawApi = isMainnet ? "https://withdraw.api.prod.eclipse.xyz" : "https://withdraw.api.dev2.eclipsenetwork.xyz" @@ -80,7 +78,6 @@ export const NetworkProvider = ({ selectedOption, setSelectedOption, children }: bridgeProgram, eclipseRpc, contractAddress, - legacyAddress, relayerAddress, configAccount, withdrawApi, diff --git a/lib/withdrawUtils.ts b/lib/withdrawUtils.ts index 9fe0a56..1172217 100644 --- a/lib/withdrawUtils.ts +++ b/lib/withdrawUtils.ts @@ -96,7 +96,6 @@ export type WithdrawObject = [MessageEntry, Status]; export async function getWithdrawalsByAddress( address: string, withdrawApi: string, - legacyAddress: string, // V1 contract address for backward compatibility ): Promise { if (!withdrawApi) { return []; @@ -108,7 +107,7 @@ export async function getWithdrawalsByAddress( } const serverData = LosslessJSON.parse(await response.text()); - const result = parseWithdrawData(serverData, legacyAddress); + const result = parseWithdrawData(serverData); result.reverse(); return result; } @@ -132,50 +131,27 @@ export async function getWithdrawalPda( } } -function parseWithdrawData(data: any[], legacyAddress: string): WithdrawObject[] { +// New V3 format: { bridge, auth: { sender, message, message_hash, start_time }, status } +function parseWithdrawData(data: any[]): WithdrawObject[] { return data.map((entry) => { - // Check if this is the new V2 format (object with bridge and auth properties) - if (entry.bridge && entry.auth) { - // New V2 format: { bridge, auth: { sender, message, message_hash, start_time }, status } - const message: Message = { - from: entry.auth.message.from, - destination: entry.auth.message.destination, - amount_wei: entry.auth.message.amount_wei, - withdraw_id: BigInt(entry.auth.message.withdraw_id), - fee_receiver: entry.auth.message.fee_receiver, - fee_wei: entry.auth.message.fee_wei, - }; - - const messageEntry: MessageEntry = { - sender: entry.auth.sender, - message, - message_hash: entry.auth.message_hash, - start_time: entry.auth.start_time, - bridge: entry.bridge, - }; - - return [messageEntry, entry.status as Status]; - } else { - // Old V1 format: [entry, status] where entry has direct properties - const message: Message = { - from: entry[0].message.from, - destination: entry[0].message.destination, - amount_wei: entry[0].message.amount_wei, - withdraw_id: BigInt(entry[0].message.withdraw_id), - fee_receiver: entry[0].message.fee_receiver, - fee_wei: entry[0].message.fee_wei, - }; - - const messageEntry: MessageEntry = { - sender: entry[0].sender, - message, - message_hash: entry[0].message_hash, - start_time: entry[0].start_time, - bridge: legacyAddress, // Use config address for V1 backward compatibility - }; - - return [messageEntry, entry[1] as Status]; - } + const message: Message = { + from: entry.auth.message.from, + destination: entry.auth.message.destination, + amount_wei: entry.auth.message.amount_wei, + withdraw_id: BigInt(entry.auth.message.withdraw_id), + fee_receiver: entry.auth.message.fee_receiver, + fee_wei: entry.auth.message.fee_wei, + }; + + const messageEntry: MessageEntry = { + sender: entry.auth.sender, + message, + message_hash: entry.auth.message_hash, + start_time: entry.auth.start_time, + bridge: entry.bridge, + }; + + return [messageEntry, entry.status as Status]; }); }