Skip to content

Commit

Permalink
Merge pull request #250 from G7DAO/feat/update-bridge-sdk
Browse files Browse the repository at this point in the history
Feat/update bridge sdk
  • Loading branch information
elclandestin0 authored Dec 13, 2024
2 parents ddd89d6 + c08d037 commit dfd8303
Show file tree
Hide file tree
Showing 8 changed files with 351 additions and 232 deletions.
2 changes: 1 addition & 1 deletion webapps/world-builder-dashboard/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"clsx": "^1.2.1",
"dayjs": "^1.11.11",
"dotenv": "^16.4.7",
"game7-bridge-sdk": "^0.0.69",
"game7-bridge-sdk": "^0.0.70",
"history": "^5.3.0",
"prettier-plugin-tailwindcss": "^0.6.5",
"react": "^18.2.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ const AllowanceSelector = ({ balance, onChange, allowance, amount, disabled, tok
return `Infinite ${token?.symbol}`
}
const formattedAllowance = ethers.utils.formatUnits(allowance, token.decimals)
console.log('Formatted Allowance Display:', formattedAllowance, token.symbol)
return `${formattedAllowance} ${token?.symbol}`
}

Expand All @@ -34,10 +33,8 @@ const AllowanceSelector = ({ balance, onChange, allowance, amount, disabled, tok
store={combobox}
variant='unstyled'
onOptionSubmit={(val: string) => {
console.log('Submitted Value:', val)
try {
const amountInWei = ethers.utils.parseUnits(val, token.decimals)
console.log('Parsed Amount in Wei:', amountInWei.toString())
onChange(amountInWei)
} catch (e) {
console.error('Error parsing units:', e)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// External Libraries
import React, { useState } from 'react'
import React, { useEffect, useState } from 'react'
import { useMutation, useQueryClient } from 'react-query'
import { useNavigate } from 'react-router-dom'
// Constants
Expand Down Expand Up @@ -27,6 +27,8 @@ interface ActionButtonProps {
balance?: string
nativeBalance?: string
gasFees?: string[]
bridgeAllowance?: ethers.BigNumber | null
nativeAllowance?: ethers.BigNumber | null
}

const ActionButton: React.FC<ActionButtonProps> = ({
Expand All @@ -40,7 +42,9 @@ const ActionButton: React.FC<ActionButtonProps> = ({
decimals,
balance,
nativeBalance,
gasFees
gasFees,
bridgeAllowance,
nativeAllowance
}) => {
const {
connectedAccount,
Expand All @@ -59,38 +63,46 @@ const ActionButton: React.FC<ActionButtonProps> = ({
const [showApproval, setShowApproval] = useState(false)
const [startingTokenIndex, setStartingTokenIndex] = useState(0)
const [allowancesVerified, setAllowancesVerified] = useState(false)
let bridgeTokenAllowance: ethers.BigNumber = ethers.BigNumber.from(0)
let nativeTokenAllowance: ethers.BigNumber = ethers.BigNumber.from(0)


useEffect(() => {
console.log('bridger changed')
setAllowancesVerified(false)
}, [bridger])

const checkAllowances = async () => {
if (!bridger || !connectedAccount) return null;


// For testing only!
if (amount === '3') {
console.log('Starting token index set to 0');
if (amount === '0.01') {
setStartingTokenIndex(0);
setShowApproval(true);
return false;
}

if (allowancesVerified) {
console.log('Allowances already verified, skipping check');
return true;
console.log('Allowances already verified, skipping check')
return true
}

bridgeTokenAllowance = await bridger.getAllowance(selectedLowNetwork.rpcs[0], connectedAccount) ?? ethers.BigNumber.from(0)
nativeTokenAllowance = await bridger.getNativeAllowance(selectedLowNetwork.rpcs[0], connectedAccount) ?? ethers.BigNumber.from(0)

const amountBN = ethers.utils.parseUnits(amount, decimals)

const needsBridgeTokenApproval = bridgeTokenAllowance !== null && bridgeTokenAllowance.lt(amountBN)
const needsNativeTokenApproval = nativeTokenAllowance !== null && nativeTokenAllowance.lt(amountBN)
if (bridgeAllowance === null) {
const needsNativeTokenApproval = nativeAllowance !== null && nativeAllowance?.lt(amountBN)
if (needsNativeTokenApproval) {
setStartingTokenIndex(0)
setShowApproval(true)
return false
}
} else {
const needsBridgeTokenApproval = bridgeAllowance?.lt(amountBN)
const needsNativeTokenApproval = nativeAllowance !== null && nativeAllowance?.lt(amountBN)

if (needsBridgeTokenApproval || needsNativeTokenApproval) {
setStartingTokenIndex(!needsBridgeTokenApproval && needsNativeTokenApproval ? 1 : 0)
setShowApproval(true)
return false
if (needsBridgeTokenApproval || needsNativeTokenApproval) {
setStartingTokenIndex(needsBridgeTokenApproval ? 0 : 1)
setShowApproval(true)
return false
}
}

setAllowancesVerified(true)
Expand Down Expand Up @@ -152,26 +164,23 @@ const ActionButton: React.FC<ActionButtonProps> = ({
toNetwork: selectedHighNetwork.chainId,
connectedAccount: connectedAccount
});

if (bridger?.isDeposit) {
if (selectedBridgeToken.address != ZERO_ADDRESS) {
const tx = await bridger?.transfer({ amount: amountToSend, signer, destinationProvider })
await tx?.wait()
return {
type: 'DEPOSIT',
amount: amount,
lowNetworkChainId: selectedLowNetwork.chainId,
highNetworkChainId: selectedHighNetwork.chainId,
lowNetworkHash: tx?.hash,
lowNetworkTimestamp: Date.now() / 1000,
completionTimestamp: Date.now() / 1000,
newTransaction: true,
symbol: symbol,
status:
destinationTokenAddress === ZERO_ADDRESS
? BridgeTransferStatus.DEPOSIT_GAS_PENDING
: BridgeTransferStatus.DEPOSIT_ERC20_NOT_YET_CREATED
}
const tx = await bridger?.transfer({ amount: amountToSend, signer, destinationProvider })
await tx?.wait()
return {
type: 'DEPOSIT',
amount: amount,
lowNetworkChainId: selectedLowNetwork.chainId,
highNetworkChainId: selectedHighNetwork.chainId,
lowNetworkHash: tx?.hash,
lowNetworkTimestamp: Date.now() / 1000,
completionTimestamp: Date.now() / 1000,
newTransaction: true,
symbol: symbol,
status:
destinationTokenAddress === ZERO_ADDRESS
? BridgeTransferStatus.DEPOSIT_GAS_PENDING
: BridgeTransferStatus.DEPOSIT_ERC20_NOT_YET_CREATED
}
} else {
const tx = await bridger?.transfer({ amount: amountToSend, signer, destinationProvider })
Expand Down Expand Up @@ -228,7 +237,6 @@ const ActionButton: React.FC<ActionButtonProps> = ({
console.log('Setting allowancesVerified to true');
setShowApproval(false)
setAllowancesVerified(true)
console.log('Triggering transfer');
transfer.mutate(amount)
}

Expand All @@ -237,21 +245,40 @@ const ActionButton: React.FC<ActionButtonProps> = ({
console.log('Current allowancesVerified state:', allowancesVerified);

if (allowancesVerified) {
console.log('Allowances already verified, proceeding to transfer');
transfer.mutate(amount)
return
}

console.log('Checking allowances before transfer');
const allowancesOk = await checkAllowances()
console.log('Allowances check result:', allowancesOk);

if (allowancesOk) {
console.log('Allowances OK, proceeding to transfer');
transfer.mutate(amount)
}
}

const tokens = (() => {
const nativeToken = getTokensForNetwork(
direction === 'DEPOSIT' ? selectedLowNetwork.chainId : selectedHighNetwork.chainId,
connectedAccount
).find(
token => direction === 'DEPOSIT' ?
token.symbol === selectedHighNetwork.nativeCurrency?.symbol :
token.symbol === selectedLowNetwork.nativeCurrency?.symbol
)!
if (bridgeAllowance === null && nativeAllowance !== null) {
return [nativeToken];
}
if (nativeAllowance === null && bridgeAllowance !== null) {
return [selectedBridgeToken];
}

if (nativeAllowance === null && bridgeAllowance === null) {
return [];
}

return [selectedBridgeToken, nativeToken];
})();

return (
<>
<button
Expand All @@ -277,21 +304,7 @@ const ActionButton: React.FC<ActionButtonProps> = ({
bridger={bridger}
decimals={decimals}
startingTokenIndex={startingTokenIndex}
tokens={(() => {
const nativeToken = getTokensForNetwork(
selectedLowNetwork.chainId,
connectedAccount
).find(token => token.symbol === selectedHighNetwork.nativeCurrency?.symbol)!;

if (bridgeTokenAllowance !== null && nativeTokenAllowance !== null) {
return [selectedBridgeToken, nativeToken];
} else if (bridgeTokenAllowance !== null) {
return [selectedBridgeToken];
} else if (nativeTokenAllowance !== null) {
return [nativeToken];
}
return [];
})()}
tokens={tokens}
amount={amount}
onApprovalComplete={handleApprovalComplete}
gasFees={gasFees ?? []}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
// Libraries
import { useEffect, useState } from 'react'
import { useQuery } from 'react-query'
import {
DEFAULT_STAKE_NATIVE_POOL_ID,
getNetworks,
L1_MAIN_NETWORK,
L1_NETWORK,
L2_MAIN_NETWORK,
Expand Down Expand Up @@ -31,6 +29,7 @@ import { useCoinGeckoAPI } from '@/hooks/useCoinGeckoAPI'
import { DepositDirection } from '@/pages/BridgePage/BridgePage'
import { getStakeNativeTxData } from '@/utils/bridge/stakeContractInfo'
import { getTokensForNetwork, Token } from '@/utils/tokens'
import { useBridger } from '@/hooks/useBridger'

const BridgeView = ({
direction,
Expand Down Expand Up @@ -80,82 +79,19 @@ const BridgeView = ({
setSelectedBridgeToken(token)
}

const networks = getNetworks(selectedNetworkType)
const { getEstimatedFee } = useBridger()

const estimatedFee = useQuery(
['estimatedFee', bridger, connectedAccount, value],
async () => {
// Early return if required values are missing
if (!bridger || !connectedAccount || !value) {
return { parentFee: '0', childFee: '0', totalFee: '0' }
}

try {
const originNetwork = networks?.find((n) => n.chainId === bridger.originNetwork.chainId)
if (!originNetwork) {
console.warn("Can't find origin network, returning zero fees")
return { parentFee: '0', childFee: '0', totalFee: '0' }
}

const decimals = tokenInformation?.decimalPlaces ?? 18
const parsedValue = value ? ethers.utils.parseUnits(value, decimals) : ethers.utils.parseEther('0')

// Ensure we have valid RPC endpoints
const originProvider = direction === 'DEPOSIT' ?
selectedLowNetwork.rpcs[0] :
selectedHighNetwork.rpcs[0]
const destinationProvider = direction === 'DEPOSIT' ?
selectedHighNetwork.rpcs[0] :
undefined

if (!originProvider) {
console.warn("Missing origin provider, returning zero fees")
return { parentFee: '0', childFee: '0', totalFee: '0' }
}

// Add retry logic for the gas estimation
let attempts = 0
const maxAttempts = 3

while (attempts < maxAttempts) {
try {
const gasAndFee = await bridger.getGasAndFeeEstimation(
parsedValue,
originProvider,
connectedAccount,
destinationProvider
)

const parentFee = ethers.utils.formatEther(gasAndFee?.estimatedFee ?? '0')
const childFee = gasAndFee?.childNetworkEstimation
? ethers.utils.formatEther(gasAndFee.childNetworkEstimation.estimatedFee)
: '0'
const estimatedFee = getEstimatedFee({
bridger,
value,
direction,
selectedLowNetwork,
selectedHighNetwork,
tokenInformation
})

return {
parentFee,
childFee,
totalFee: String(Number(parentFee) + Number(childFee))
}
} catch (e) {
attempts++
if (attempts === maxAttempts) throw e
// Wait before retrying
await new Promise(resolve => setTimeout(resolve, 1000))
}
}
} catch (e) {
console.error('Fee estimation failed:', e)
return { parentFee: '0', childFee: '0', totalFee: '0' }
}
},
{
enabled: !!connectedAccount && !!selectedLowNetwork && !!selectedHighNetwork && !!value && !!bridger,
retry: 2,
retryDelay: 1000,
staleTime: 30000,
cacheTime: 60000,
}
)
const [bridgeTokenAllowance, setBridgeTokenAllowance] = useState<ethers.BigNumber | null>(null)
const [nativeTokenAllowance, setNativeTokenAllowance] = useState<ethers.BigNumber | null>(null)

useEffect(() => {
if (selectedBridgeToken && connectedAccount && selectedHighNetwork && selectedLowNetwork) {
Expand All @@ -178,20 +114,23 @@ const BridgeView = ({
) ?? null
setSelectedNativeToken(token)
}
console.log('in use effect 2')
const _bridger: Bridger = new Bridger(originChainId, destinationChainId, selectedBridgeToken.tokenAddressMap)
setBridger(_bridger)
const fetchAllowances = async () => {
try {
const bridgeTokenAllowance = await _bridger.getAllowance(selectedLowNetwork.rpcs[0], connectedAccount)
const nativeTokenAllowance = await _bridger.getNativeAllowance(selectedLowNetwork.rpcs[0], connectedAccount)
console.log(bridgeTokenAllowance, nativeTokenAllowance)
console.log('fetching allowances')
const bridgeTokenAllowance = await _bridger.getAllowance(direction === 'DEPOSIT' ? selectedLowNetwork.rpcs[0] : selectedHighNetwork.rpcs[0], connectedAccount)
console.log('bridgeTokenAllowance', bridgeTokenAllowance)
const nativeTokenAllowance = await _bridger.getNativeAllowance(direction === 'DEPOSIT' ? selectedLowNetwork.rpcs[0] : selectedHighNetwork.rpcs[0], connectedAccount)
console.log('nativeTokenAllowance', nativeTokenAllowance)
if (bridgeTokenAllowance && nativeTokenAllowance) {
console.log(
ethers.utils.formatUnits(bridgeTokenAllowance!, selectedBridgeToken.decimals),
ethers.utils.formatEther(nativeTokenAllowance!)
)
}
setBridgeTokenAllowance(bridgeTokenAllowance as ethers.BigNumber | null)
setNativeTokenAllowance(nativeTokenAllowance as ethers.BigNumber | null)
} catch (error) {
console.error('Error fetching allowances:', error)
}
Expand Down Expand Up @@ -370,6 +309,8 @@ const BridgeView = ({
balance={tokenInformation?.tokenBalance}
nativeBalance={nativeTokenInformation?.tokenBalance}
gasFees={[estimatedFee.data?.parentFee ?? '', estimatedFee.data?.childFee ?? '']}
bridgeAllowance={bridgeTokenAllowance}
nativeAllowance={nativeTokenAllowance}
/>
</div>
)
Expand Down
Loading

0 comments on commit dfd8303

Please sign in to comment.