Skip to content

Commit

Permalink
added final step of doing initial transfer request
Browse files Browse the repository at this point in the history
  • Loading branch information
KannuSingh committed Nov 5, 2024
1 parent 986e031 commit 28aa54e
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 192 deletions.
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
import { LoaderProps } from '@/components/ModalFooter'

import RequestMethodCard from '@/components/RequestMethodCard'
import { Avatar, Col, Container, Divider, Row, Text } from '@nextui-org/react'
import { Avatar, Col, Divider, Row, Text } from '@nextui-org/react'
import { walletkit } from '@/utils/WalletConnectUtil'
import RequestModal from './RequestModal'
import ModalStore from '@/store/ModalStore'
import { useCallback, useState } from 'react'
import {
bridgeFunds,
BridgingRequest,
convertTokenBalance,
decodeErc20Transaction,
getAssetByContractAddress,
supportedAssets
getAssetByContractAddress
} from '@/utils/MultibridgeUtil'
import { getWallet } from '@/utils/EIP155WalletUtil'

Expand All @@ -25,7 +22,7 @@ import { providers } from 'ethers'
interface IProps {
onReject: () => void
transactions?: Transaction[]
orchestrationId:string
orchestrationId: string
rejectLoader?: LoaderProps
}

Expand All @@ -35,13 +32,14 @@ export default function MultibridgeRequestModal({
onReject,
rejectLoader
}: IProps) {

const [isLoadingApprove, setIsLoadingApprove] = useState(false)
const bridgingTransactions = transactions?.slice(0, transactions.length - 1) || []
const initialTransaction = transactions?.[transactions.length - 1]
const eip155ChainsFundsSourcedFrom = transactions ? new Set(bridgingTransactions.map(transaction => transaction.chainId)) : new Set([])
console.log({eip155ChainsFundsSourcedFrom})
const initialTransaction = transactions?.[transactions.length - 1]
const eip155ChainsFundsSourcedFrom = transactions
? new Set(bridgingTransactions.map(transaction => transaction.chainId))
: new Set([])
const eip155ChainFundsDestination = initialTransaction?.chainId

// Get request and wallet data from store
const requestEvent = ModalStore.state.data?.requestEvent
const requestSession = ModalStore.state.data?.requestSession
Expand All @@ -51,128 +49,101 @@ export default function MultibridgeRequestModal({

const chainId = params?.chainId
const request = params?.request
const caService = new ChainAbstractionService();

// const bridge = useCallback(async () => {
// if (!bridgingRequest) {
// throw new Error('Bridging request is unavailable')
// }

// const wallet = await getWallet(params)

// const asset = getAssetByContractAddress(bridgingRequest.transfer.contract)
// if (!asset) {
// throw new Error('Source chain asset unavailable')
// }
// const sourceChainAssetAddress = supportedAssets[asset][bridgingRequest.sourceChain]
// if (!sourceChainAssetAddress) {
// throw new Error('Source chain asset address unavailable')
// }

// await bridgeFunds(
// {
// fromChainId: bridgingRequest.sourceChain,
// toChainId: bridgingRequest.targetChain,
// fromAssetAddress: sourceChainAssetAddress,
// toAssetAddress: bridgingRequest.transfer.contract,
// amount: bridgingRequest.transfer.amount,
// userAddress: wallet.getAddress(),
// uniqueRoutesPerBridge: true,
// sort: 'time',
// singleTxOnly: true
// },
// wallet
// )
// }, [params, bridgingRequest])
const caService = new ChainAbstractionService()

const bridgeRouteFunds = useCallback(async () => {
if (!transactions) {
throw new Error('Transactions are unavailable')
}

const wallet = await getWallet(params)
for(const transaction of bridgingTransactions){
console.log(
'Bridge funds from',
eip155ChainsFundsSourcedFrom,
'to',
eip155ChainFundsDestination
)
for (const transaction of bridgingTransactions) {
console.log('Bridging transaction', transaction)
const chainId = transaction.chainId
const chainProvider = new providers.JsonRpcProvider(
EIP155_CHAINS[chainId as TEIP155Chain].rpc
)
const chainConnectedWallet = await wallet.connect(chainProvider)
const walletAddress = wallet.getAddress()
console.log({walletAddress})
const gasPrice = await chainProvider.getGasPrice();
console.log({ gasPrice });

console.log('gasEstimation starting: ');
const gasPrice = await chainProvider.getGasPrice()
const gasEstimate = await chainProvider.estimateGas({
from: walletAddress,
to: transaction.to,
value: transaction.value,
data: transaction.data,
gasPrice: gasPrice,
});
gasPrice: gasPrice
})

const hash = await chainConnectedWallet.sendTransaction({
from: walletAddress,
to: transaction.to,
value: transaction.value,
data: transaction.data,
gasPrice: gasPrice,
gasLimit: gasEstimate,
});
const receipt = typeof hash === 'string' ? hash : hash?.hash;
console.log('Transaction broadcasted', { receipt });
gasLimit: gasEstimate
})
const receipt = typeof hash === 'string' ? hash : hash?.hash
console.log(`Transaction broadcasted on chain ${chainId} , ${{ receipt }}`)
}

// Call the polling function
try{
pollOrchestrationStatus(orchestrationId)
}catch(e){
try {
await pollOrchestrationStatus(orchestrationId)
} catch (e) {
console.error(e)
onReject()
}
}, [])

}, [])

async function pollOrchestrationStatus(orchestrationId:string, maxAttempts = 100, interval = 1500) {
async function pollOrchestrationStatus(
orchestrationId: string,
maxAttempts = 100,
interval = 1500
) {
for (let attempt = 0; attempt < maxAttempts; attempt++) {
const { status } = await caService.getOrchestrationStatus(orchestrationId);
console.log(attempt,'- Orchestration status:', status);
const { status } = await caService.getOrchestrationStatus(orchestrationId)
console.log(attempt, '- Orchestration status:', status)
if (status === 'completed') {
console.log('Bridging completed');
return; // Exit if the status is completed
console.log('Bridging completed')
return // Exit if the status is completed
}

// Wait for the specified interval before the next attempt
await new Promise(resolve => setTimeout(resolve, interval));
await new Promise(resolve => setTimeout(resolve, interval))
}

console.log('Max attempts reached. Orchestration not completed.');
throw new Error('Max attempts reached. Orchestration not completed.');
console.log('Max attempts reached. Orchestration not completed.')
throw new Error('Max attempts reached. Orchestration not completed.')
}

const onApprove = useCallback(async () => {
if (requestEvent && topic) {
setIsLoadingApprove(true)
try {
performance.mark('startInititalTransactionSend')
await bridgeRouteFunds()
// await bridge()
// performance.mark('startInititalTransactionSend')
// const response = await approveEIP155Request(requestEvent)
// performance.mark('endInititalTransactionSend')
// console.log(
// `Initial transaction send: ${
// performance.measure(
// 'initial-tx-send',
// 'startInititalTransactionSend',
// 'endInititalTransactionSend'
// ).duration
// } ms`
// )

// await walletkit.respondSessionRequest({
// topic,
// response
// })
const response = await approveEIP155Request(requestEvent)
performance.mark('endInititalTransactionSend')
console.log(
`Initial transaction send: ${
performance.measure(
'initial-tx-send',
'startInititalTransactionSend',
'endInititalTransactionSend'
).duration
} ms`
)

await walletkit.respondSessionRequest({
topic,
response
})
} catch (e) {
console.log('Error')
console.error(e)
Expand All @@ -190,9 +161,9 @@ export default function MultibridgeRequestModal({
return <Text>Request not found</Text>
}
const transfer = decodeErc20Transaction(request.params[0])
if(!transfer) {
if (!transfer) {
return <Text>Invalid transfer request</Text>
}
}

const asset = getAssetByContractAddress(transfer.contract)
const amount = convertTokenBalance(asset, transfer.amount)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,55 +1,54 @@
import axios from 'axios';
import { CA_ORCHESTRATOR_BASE_URL } from './ConstantsUtil';
import axios from 'axios'
import { CA_ORCHESTRATOR_BASE_URL } from './ConstantsUtil'

export interface Transaction {
from: string;
to: string;
value: string;
gas: string;
gasPrice: string;
data: string;
nonce: string;
maxFeePerGas: string;
maxPriorityFeePerGas: string;
chainId: string;
from: string
to: string
value: string
gas: string
gasPrice: string
data: string
nonce: string
maxFeePerGas: string
maxPriorityFeePerGas: string
chainId: string
}

interface CheckResponse {
requiresMultiChain: boolean;
requiresMultiChain: boolean
}

interface RouteResponse {
transactions: Transaction[];
orchestrationId: string;
transactions: Transaction[]
orchestrationId: string
}
interface OrchestrationStatusResponse {
status: "pending" | "completed" | "error",
status: 'pending' | 'completed' | 'error'
createdAt: number
}


export class ChainAbstractionService {
private baseUrl: string;
private projectId: string;
private baseUrl: string
private projectId: string

constructor() {
this.baseUrl = CA_ORCHESTRATOR_BASE_URL;
if(!process.env.NEXT_PUBLIC_PROJECT_ID){
throw new Error("Project ID is not defined");
this.baseUrl = CA_ORCHESTRATOR_BASE_URL
if (!process.env.NEXT_PUBLIC_PROJECT_ID) {
throw new Error('Project ID is not defined')
}
this.projectId = process.env.NEXT_PUBLIC_PROJECT_ID;
this.projectId = process.env.NEXT_PUBLIC_PROJECT_ID
}

async checkTransaction(transaction: Transaction): Promise<boolean> {
try {
const response = await axios.post<CheckResponse>(
`${this.baseUrl}/check?projectId=${this.projectId}`,
{ transaction }
);
return response.data.requiresMultiChain;
)
return response.data.requiresMultiChain
} catch (error) {
console.error('ChainAbstractionService: Error checking transaction:', error);
throw error;
console.error('ChainAbstractionService: Error checking transaction:', error)
throw error
}
}

Expand All @@ -58,23 +57,22 @@ export class ChainAbstractionService {
const response = await axios.post<RouteResponse>(
`${this.baseUrl}/route?projectId=${this.projectId}`,
{ transaction }
);
return response.data;
)
return response.data
} catch (error) {
console.error('ChainAbstractionService: Error routing transaction:', error);
throw error;
console.error('ChainAbstractionService: Error routing transaction:', error)
throw error
}
}
async getOrchestrationStatus(orchestrationId: string): Promise<OrchestrationStatusResponse> {
try {

const response = await axios.get<OrchestrationStatusResponse>(
`${this.baseUrl}/status?projectId=${this.projectId}&orchestrationId=${orchestrationId}`,
);
return response.data;
`${this.baseUrl}/status?projectId=${this.projectId}&orchestrationId=${orchestrationId}`
)
return response.data
} catch (error) {
console.error('ChainAbstractionService: Error getting orchestration status :', error);
throw error;
console.error('ChainAbstractionService: Error getting orchestration status :', error)
throw error
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
export const COSIGNER_BASE_URL = 'https://rpc.walletconnect.org/v1/sessions'
export const CA_ORCHESTRATOR_BASE_URL = 'https://rpc.walletconnect.org/v1/ca/orchestrator'
// export const CA_ORCHESTRATOR_BASE_URL = 'https://maksy.ngrok.dev/v1/ca/orchestrator'
Loading

0 comments on commit 28aa54e

Please sign in to comment.