diff --git a/advanced/dapps/chain-abstraction-demo/app/hooks/useSendUsdc.tsx b/advanced/dapps/chain-abstraction-demo/app/hooks/useSendUsdc.tsx index e8e541814..fa20ad118 100644 --- a/advanced/dapps/chain-abstraction-demo/app/hooks/useSendUsdc.tsx +++ b/advanced/dapps/chain-abstraction-demo/app/hooks/useSendUsdc.tsx @@ -11,7 +11,7 @@ export default function useSendUsdc() { abi: erc20Abi, address: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831", // arbitrum usdc functionName: "transfer", - args: ["0x81D8C68Be5EcDC5f927eF020Da834AA57cc3Bd24", BigInt(500000)], + args: ["0x81D8C68Be5EcDC5f927eF020Da834AA57cc3Bd24", BigInt(6000000)], }); return tx; }; diff --git a/advanced/wallets/react-wallet-v2/src/components/MultibridgeRequestModal.tsx b/advanced/wallets/react-wallet-v2/src/components/MultibridgeRequestModal.tsx index ebb588ee9..1e9c767f5 100644 --- a/advanced/wallets/react-wallet-v2/src/components/MultibridgeRequestModal.tsx +++ b/advanced/wallets/react-wallet-v2/src/components/MultibridgeRequestModal.tsx @@ -3,9 +3,10 @@ import RequestDataCard from '@/components/RequestDataCard' import RequesDetailsCard from '@/components/RequestDetalilsCard' import RequestMethodCard from '@/components/RequestMethodCard' import { Divider, Text } from '@nextui-org/react' +import { web3wallet } from '@/utils/WalletConnectUtil' import RequestModal from './RequestModal' import ModalStore from '@/store/ModalStore' -import { useCallback, useEffect, useState } from 'react' +import { useCallback, useState } from 'react' import { bridgeFunds, BridgingRequest, @@ -13,9 +14,9 @@ import { supportedAssets } from '@/utils/MultibridgeUtil' import { getWallet } from '@/utils/EIP155WalletUtil' -import { providers } from 'ethers' -import { EIP155_CHAINS, TEIP155Chain } from '@/data/EIP155Data' + import { styledToast } from '@/utils/HelperUtil' +import { approveEIP155Request } from '@/utils/EIP155RequestHandlerUtil' interface IProps { onReject: () => void @@ -47,7 +48,6 @@ export default function MultibridgeRequestModal({ } const wallet = await getWallet(params) - const provider = new providers.JsonRpcProvider(EIP155_CHAINS[chainId as TEIP155Chain].rpc) const asset = getAssetByContractAddress(bridgingRequest.transfer.contract) if (!asset) { @@ -70,8 +70,7 @@ export default function MultibridgeRequestModal({ sort: 'time', singleTxOnly: true }, - wallet, - provider + wallet ) }, [params, chainId, bridgingRequest]) @@ -80,7 +79,15 @@ export default function MultibridgeRequestModal({ setIsLoadingApprove(true) try { await bridge() + const response = await approveEIP155Request(requestEvent) + await web3wallet.respondSessionRequest({ + topic, + response + }) } catch (e) { + console.log('Error') + console.error(e) + setIsLoadingApprove(false) styledToast((e as Error).message, 'error') return diff --git a/advanced/wallets/react-wallet-v2/src/utils/MultibridgeUtil.ts b/advanced/wallets/react-wallet-v2/src/utils/MultibridgeUtil.ts index f1991a25a..bc6bef362 100644 --- a/advanced/wallets/react-wallet-v2/src/utils/MultibridgeUtil.ts +++ b/advanced/wallets/react-wallet-v2/src/utils/MultibridgeUtil.ts @@ -4,8 +4,11 @@ import { getChainById } from './ChainUtil' import EIP155Lib from '@/lib/EIP155Lib' import { SmartAccountLib } from '@/lib/smart-accounts/SmartAccountLib' import { providers } from 'ethers' +import { EIP155_CHAINS, TEIP155Chain } from '@/data/EIP155Data' const BASE_URL = 'https://api.socket.tech/v2' +const WHITELIST_BRIDGES = 'across' +const AMOUNT_MULTIPLIER = 1.1 export const supportedAssets: Record> = { USDC: { @@ -152,6 +155,7 @@ async function getQuote(params: BridgingParams): Promise { urlParams.set('toTokenAddress', params.toAssetAddress) urlParams.set('fromAmount', params.amount.toString()) urlParams.set('userAddress', params.userAddress) + urlParams.set('includeBridges',WHITELIST_BRIDGES) if (params.uniqueRoutesPerBridge !== undefined) { urlParams.set('uniqueRoutesPerBridge', params.uniqueRoutesPerBridge.toString()) } @@ -226,8 +230,9 @@ async function getBridgeStatus(params: BridgeStatusParams): Promise { } -export async function bridgeFunds(bridgingParams: BridgingParams, wallet: EIP155Lib | SmartAccountLib, provider: providers.JsonRpcProvider): Promise { +export async function bridgeFunds(bridgingParams: BridgingParams, wallet: EIP155Lib | SmartAccountLib): Promise { console.log('Bridging funds', bridgingParams); + bridgingParams.amount = Math.round(bridgingParams.amount*1.1) const quote = await getQuote(bridgingParams) console.log('Fetched quote', quote); @@ -238,7 +243,9 @@ export async function bridgeFunds(bridgingParams: BridgingParams, wallet: EIP155 const apiReturnData = await getRouteTransactionData(route); const approvalData = apiReturnData.result.approvalData; const { allowanceTarget, minimumApprovalAmount } = approvalData; - + const sourceChainProvider = new providers.JsonRpcProvider(EIP155_CHAINS[`eip155:${bridgingParams.fromChainId}` as TEIP155Chain].rpc) + const sourceChainConnectedWallet = await wallet.connect(sourceChainProvider) + const walletAddress = wallet.getAddress() console.log({approvalData}); // approvalData from apiReturnData is null for native tokens // Values are returned for ERC20 tokens but token allowance needs to be checked @@ -262,10 +269,70 @@ export async function bridgeFunds(bridgingParams: BridgingParams, wallet: EIP155 amount: bridgingParams.amount }); console.log('Approval transaction fetched',approvalTransactionData); + const gasPrice = sourceChainProvider.getGasPrice() + const gasEstimate = await sourceChainProvider.estimateGas({ + from: walletAddress, + to: approvalTransactionData.result?.to, + value: "0x00", + data: approvalTransactionData.result?.data, + gasPrice: gasPrice, + }); + + const hash = await sourceChainConnectedWallet.sendTransaction({ + from: approvalTransactionData.result?.from, + to: approvalTransactionData.result?.to, + value: "0x00", + data: approvalTransactionData.result?.data, + gasPrice: gasPrice, + gasLimit: gasEstimate, + }) + const receipt = typeof hash === 'string' ? hash : hash?.hash + console.log("Approval Transaction", {receipt}); } - + } + const gasPrice = await sourceChainProvider.getGasPrice(); + let gasEstimate = BigInt('0x029a6b')*BigInt(4) + try { + const res = await sourceChainProvider.estimateGas({ + from: walletAddress, + to: apiReturnData.result.txTarget, + value: apiReturnData.result.value, + data: apiReturnData.result.txData, + gasPrice: gasPrice, + }); + gasEstimate = BigInt(res.toNumber()) + console.log('Gas Estimate', gasEstimate); + } catch{ + console.log('Failed gas estimate. Using default with 4x increase'); + } + + const hash = await sourceChainConnectedWallet.sendTransaction({ + from: walletAddress, + to: apiReturnData.result.txTarget, + data: apiReturnData.result.txData, + value: apiReturnData.result.value, + gasPrice: gasPrice, + gasLimit: gasEstimate, + }); + const receipt = typeof hash === 'string' ? hash : hash?.hash + console.log("Bridging Transaction : ", {receipt}); + let interations = 0 + while (interations < 20) { + const status = await getBridgeStatus({ + transactionHash: receipt, + fromChainId: bridgingParams.fromChainId, + toChainId: bridgingParams.toChainId + }); + console.log( + `SOURCE TX : ${status.result.sourceTxStatus}\nDEST TX : ${status.result.destinationTxStatus}` + ); + if (status.result.destinationTxStatus == "COMPLETED") { + console.log("BRIDGE COMPLETED. DEST TX HASH :", status.result.destinationTransactionHash); + return + } + await new Promise(resolve => setTimeout(resolve, 3500)); + interations++ } - } \ No newline at end of file diff --git a/advanced/wallets/react-wallet-v2/src/views/SessionSendTransactionModal.tsx b/advanced/wallets/react-wallet-v2/src/views/SessionSendTransactionModal.tsx index d0e92d28d..55f98f2a1 100644 --- a/advanced/wallets/react-wallet-v2/src/views/SessionSendTransactionModal.tsx +++ b/advanced/wallets/react-wallet-v2/src/views/SessionSendTransactionModal.tsx @@ -72,18 +72,21 @@ export default function SessionSendTransactionModal() { if (balance >= transfer.amount) { otherBalance = balance otherChain = Number(chain) - setShouldUseMultibridge(true) - setIsTypeResolved(true) + console.log('Found chain to bridge from', { otherBalance, requiredBalance: transfer.amount, otherChain }) - setBirdgingRequest({ + const bridgingRequest = { transfer, sourceChain: otherChain, targetChain: Number(parsedChainId) - }) + } + console.log({ bridgingRequest }) + setBirdgingRequest(bridgingRequest) + setShouldUseMultibridge(true) + setIsTypeResolved(true) return } } @@ -150,7 +153,7 @@ export default function SessionSendTransactionModal() { ) } - return !shouldUseMultibridge ? ( + return !shouldUseMultibridge && isTypeResolved ? (