Skip to content

Integrate UI with request links#375

Merged
pawell24 merged 7 commits intodevelopfrom
feature/x-chain-request-links
Sep 14, 2024
Merged

Integrate UI with request links#375
pawell24 merged 7 commits intodevelopfrom
feature/x-chain-request-links

Conversation

@pawell24
Copy link
Copy Markdown
Contributor

@pawell24 pawell24 commented Sep 10, 2024

Summary by CodeRabbit

  • New Features

    • Introduced a new TokenSelector component for enhanced token selection during payment requests.
    • Added cross-chain transaction handling capabilities, allowing users to fulfill payment requests with any token on any chain.
    • Implemented dynamic transaction processing based on selected chain and token.
    • Enhanced token price calculation and conversion utilities for improved DeFi functionalities.
    • Improved transaction tracking with detailed status updates and links to transaction explorers.
    • Added functionality for managing token decimal precision for accurate financial calculations.
  • Chores

    • Updated project dependencies to include the Squid SDK and associated types, enhancing overall functionality.

@vercel
Copy link
Copy Markdown

vercel bot commented Sep 10, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
peanut-ui ❌ Failed (Inspect) Sep 14, 2024 0:19am

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Sep 10, 2024

Walkthrough

Walkthrough

The changes introduce two new dependencies to the project, enhancing its capabilities with the Squid SDK and associated types. The CreateLinkConfirmView and InitialView components have been updated to include a new property for handling token decimals and a context for transaction handling, respectively. The InitialView component also incorporates a TokenSelector for user selection of tokens, facilitating cross-chain transaction fulfillment. Additionally, utility functions for token price calculations and context management have been added or modified to support these features.

Changes

File Change Summary
package.json Added dependencies: @0xsquid/sdk (^2.8.24), @0xsquid/squid-types (^0.1.104). Updated @squirrel-labs/peanut-sdk from ^0.4.67 to ^0.5.0.
src/components/Create/Link/Confirm.view.tsx Added selectedTokenDecimals to context for token decimal management.
src/components/Request/Pay/Views/Initial.view.tsx Introduced tokenSelectorContext for transaction handling; added TokenSelector component.
src/components/Request/Pay/utils.ts Added utility functions for token price calculations and conversions.
src/context/tokenSelector.context.tsx Enhanced context to manage selectedTokenDecimals state.
src/utils/fetch.utils.ts Modified fetchTokenPrice to include token decimals in the response.
src/utils/general.utils.ts Updated updatePeanutPreferences to include decimals in preferences storage; added switchNetwork function.
src/components/Claim/useClaimLink.tsx Refactored network switching logic to use switchNetworkUtil.
src/components/Create/useCreateLink.tsx Refactored network switching logic to use switchNetworkUtil.
src/components/Claim/Link/Onchain/Success.view.tsx Removed checkTransactionStatus function and modified loopUntilSuccess for transaction status updates.
src/components/Request/Pay/Views/Success.view.tsx Enhanced transaction tracking and state management for cross-chain transactions.
src/components/utils/utils.ts Added functions for checking transaction status and looping until success.

Tip

OpenAI O1 model for chat
  • We have deployed OpenAI's latest O1 model for chat.
  • OpenAI claims that this model has superior reasoning capabilities than their GPT-4o model.
  • Please share any feedback with us in the discussions post.

Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 3585c9d and 571f4da.

Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
Files selected for processing (1)
  • package.json (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • package.json

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Outside diff range, codebase verification and nitpick comments (1)
src/components/Request/Pay/Views/Initial.view.tsx (1)

48-133: LGTM, but address the commented-out code blocks.

The code changes are approved.

However, please address the following:

  • There are commented-out code blocks from lines 77-90 that seem to be related to estimating the fromAmount using the Squid SDK. If this code is no longer needed, please remove it. If it is still relevant, uncomment it and ensure it is properly integrated with the rest of the code.
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between a2f8342 and e527e24.

Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
Files selected for processing (2)
  • package.json (1 hunks)
  • src/components/Request/Pay/Views/Initial.view.tsx (6 hunks)
Additional comments not posted (1)
package.json (1)

12-13: LGTM!

The code changes are approved.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Outside diff range and nitpick comments (1)
src/context/tokenSelector.context.tsx (1)

35-35: Consider a different default value for selectedTokenDecimals.

The code changes are approved.

However, the initial value of 18 for selectedTokenDecimals may not be appropriate for all tokens. Consider using a more generic default value, such as 0 or undefined, and updating it based on the token's actual decimal places.

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between e527e24 and 24f4b80.

Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
Files selected for processing (7)
  • package.json (2 hunks)
  • src/components/Create/Link/Confirm.view.tsx (2 hunks)
  • src/components/Request/Pay/Views/Initial.view.tsx (6 hunks)
  • src/components/Request/Pay/utils.ts (1 hunks)
  • src/context/tokenSelector.context.tsx (8 hunks)
  • src/utils/fetch.utils.ts (1 hunks)
  • src/utils/general.utils.ts (3 hunks)
Files skipped from review as they are similar to previous changes (1)
  • package.json
Additional context used
Biome
src/context/tokenSelector.context.tsx

[error] 107-107: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

Additional comments not posted (17)
src/utils/fetch.utils.ts (1)

29-29: LGTM!

The code changes are approved for the following reasons:

  • The decimals property is correctly retrieved from the json.data.contracts array based on the provided chainId.
  • The find method is used efficiently to locate the desired contract object.
  • The optional chaining operator ?. is used to safely access the decimals property, preventing potential errors.

The addition of the decimals property enhances the functionality of the fetchTokenPrice function by providing useful information about the token's decimal precision.

src/components/Request/Pay/utils.ts (2)

3-9: LGTM!

The code changes are approved.


25-83: LGTM!

The code changes are approved. The function correctly calculates the fromAmount considering the token prices and slippage, while handling various edge cases and potential issues.

Some key points:

  • Handles zero address tokens by replacing them with the NATIVE_TOKEN_ADDRESS.
  • Normalizes token prices to account for different decimal counts, ensuring consistent calculations.
  • Applies slippage percentage to the fromAmount using BigNumber calculations to avoid floating-point issues.
  • Handles errors by logging them and returning null.
src/context/tokenSelector.context.tsx (5)

13-13: LGTM!

The code changes are approved.


53-53: LGTM!

The code changes are approved.


63-63: LGTM!

The code changes are approved.

Also applies to: 73-73, 81-81, 92-92, 96-96


107-107: LGTM!

The code changes are approved.

Also applies to: 110-110

Tools
Biome

[error] 107-107: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


119-119: LGTM!

The code changes are approved.

src/components/Create/Link/Confirm.view.tsx (2)

44-46: LGTM!

The code changes are approved.


167-167: LGTM!

The code changes are approved.

src/components/Request/Pay/Views/Initial.view.tsx (5)

3-5: LGTM!

The code changes are approved.


14-17: LGTM!

The code changes are approved.


Line range hint 27-53: LGTM!

The code changes are approved.


56-163: LGTM!

The code changes in the handleOnNext function are approved. The updates introduce significant enhancements to the transaction handling logic, allowing for cross-chain transactions and flexibility in fulfilling payment requests with different tokens and chains.


Line range hint 209-257: LGTM!

The code changes are approved. The addition of the TokenSelector component and the informative label enhances the user experience by providing flexibility in choosing the token and chain for fulfilling the payment request.

src/utils/general.utils.ts (2)

659-667: LGTM!

The changes to the updatePeanutPreferences function are approved. The addition of the optional decimals parameter and its inclusion in the data object enhance the function's capability to store additional data related to peanut preferences in local storage.

Also applies to: 676-676


696-696: LGTM!

The change to the data object in the getPeanutPreferences function is approved. Initializing the decimals property to undefined ensures consistency with the changes made to the updatePeanutPreferences function.

open()
}

const switchNetwork = async (chainId: string) => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need a new function to switch networks?

If we need it, lets use it consistently on all pages

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 7dcb640 and b1009b4.

Files selected for processing (2)
  • src/components/Request/Pay/Views/Initial.view.tsx (6 hunks)
  • src/components/Request/Pay/utils.ts (1 hunks)
Files skipped from review due to trivial changes (1)
  • src/components/Request/Pay/utils.ts
Additional comments not posted (2)
src/components/Request/Pay/Views/Initial.view.tsx (2)

30-30: LGTM! The addition of the selectedTokenDecimals property and the usage of the TokenSelector component enhance the user experience.

The changes are approved.

Also applies to: 232-232


227-230: LGTM! The informative comment enhances the user experience by providing flexibility in fulfilling the payment request.

The changes are approved.

Comment on lines +40 to +52
const switchNetwork = async (chainId: string) => {
try {
await switchNetworkUtil({
chainId,
currentChainId: currentChain?.id,
setLoadingState,
switchChainAsync,
})
console.log(`Switched to chain ${chainId}`)
} catch (error) {
console.error('Failed to switch network:', error)
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move the switchNetwork function to a separate utility file for reusability and consistency across the codebase.

The switchNetwork function is a utility function that can be reused in other parts of the codebase. Moving it to a separate utility file will promote reusability and consistency.

Apply this diff to move the function to a separate utility file (e.g., src/utils/network.utils.ts):

-const switchNetwork = async (chainId: string) => {
-    try {
-        await switchNetworkUtil({
-            chainId,
-            currentChainId: currentChain?.id,
-            setLoadingState,
-            switchChainAsync,
-        })
-        console.log(`Switched to chain ${chainId}`)
-    } catch (error) {
-        console.error('Failed to switch network:', error)
-    }
-}

Then, import and use the function from the utility file:

import { switchNetwork } from '@/utils/network.utils'

Comment on lines +55 to +136
if (selectedChainID !== currentChain) {
await switchNetwork(selectedChainID)
}
try {
setErrorState({ showError: false, errorMessage: '' })
if (!unsignedTx) return
await assertValues({ tokenValue: requestLinkData.tokenAmount })
if (selectedChainID === requestLinkData.chainId && selectedTokenAddress === requestLinkData.tokenAddress) {
await assertValues({ tokenValue: requestLinkData.tokenAmount })
setLoadingState('Sign in wallet')
const hash = await sendTransactions({
preparedDepositTxs: { unsignedTxs: [unsignedTx] },
feeOptions: undefined,
})

setLoadingState('Sign in wallet')
setLoadingState('Executing transaction')

const hash = await sendTransactions({
preparedDepositTxs: { unsignedTxs: [unsignedTx] },
feeOptions: undefined,
})
await peanut.submitRequestLinkFulfillment({
chainId: requestLinkData.chainId,
hash: hash ?? '',
payerAddress: address ?? '',
link: requestLinkData.link,
apiUrl: '/api/proxy/patch/',
})

setLoadingState('Executing transaction')
const currentDate = new Date().toISOString()
utils.saveRequestLinkFulfillmentToLocalStorage({
details: {
...requestLinkData,
destinationChainFulfillmentHash: hash ?? '',
createdAt: currentDate,
},
link: requestLinkData.link,
})

await peanut.submitRequestLinkFulfillment({
chainId: requestLinkData.chainId,
hash: hash ?? '',
payerAddress: address ?? '',
link: requestLinkData.link,
apiUrl: '/api/proxy/patch/',
})
setTransactionHash(hash ?? '')
onNext()
} else {
setLoadingState('Sign in wallet')

const currentDate = new Date().toISOString()
utils.saveRequestLinkFulfillmentToLocalStorage({
details: {
...requestLinkData,
destinationChainFulfillmentHash: hash ?? '',
createdAt: currentDate,
},
link: requestLinkData.link,
})
const xchainUnsignedTxs = await peanut.prepareXchainRequestFulfillmentTransaction({
fromToken: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE',
fromChainId: selectedChainID,
senderAddress: address ?? '',
recipientAddress: requestLinkData.recipientAddress as string,
destinationChainId: requestLinkData.chainId,
destinationToken: requestLinkData.tokenAddress,
link: requestLinkData.link,
squidRouterUrl: 'https://apiplus.squidrouter.com/v2/route',
apiUrl: '/api/proxy/get',
provider: await peanut.getDefaultProvider(selectedChainID),
tokenType: selectedTokenAddress === ADDRESS_ZERO ? EPeanutLinkType.native : EPeanutLinkType.erc20,
fromTokenDecimals: selectedTokenDecimals as number,
})

const { unsignedTxs } = xchainUnsignedTxs
const hash = await sendTransactions({
preparedDepositTxs: { unsignedTxs },
feeOptions: undefined,
})
setLoadingState('Executing transaction')

await peanut.submitRequestLinkFulfillment({
chainId: requestLinkData.chainId,
hash: hash ?? '',
payerAddress: address ?? '',
link: requestLinkData.link,
apiUrl: '/api/proxy/patch/',
})

setTransactionHash(hash ?? '')
onNext()
const currentDate = new Date().toISOString()
utils.saveRequestLinkFulfillmentToLocalStorage({
details: {
...requestLinkData,
destinationChainFulfillmentHash: hash ?? '',
createdAt: currentDate,
},
link: requestLinkData.link,
})

setTransactionHash(hash ?? '')
onNext()
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider refactoring the handleOnNext function for better readability and maintainability.

The handleOnNext function is quite large and can be refactored for better readability and maintainability. Here are a few suggestions:

  1. Extract the logic for handling the case when the selected chain and token match the request data into a separate function (e.g., handleMatchingChainAndToken).
  2. Extract the logic for handling the case when the selected chain and token do not match the request data into a separate function (e.g., handleCrossChainFulfillment).
  3. Move the common logic for submitting the request link fulfillment and saving it to local storage into a separate function (e.g., submitAndSaveFulfillment).

Apply this diff to refactor the function:

-const handleOnNext = async () => {
-    if (selectedChainID !== currentChain) {
-        await switchNetwork(selectedChainID)
-    }
-    try {
-        setErrorState({ showError: false, errorMessage: '' })
-        if (!unsignedTx) return
-        if (selectedChainID === requestLinkData.chainId && selectedTokenAddress === requestLinkData.tokenAddress) {
-            await assertValues({ tokenValue: requestLinkData.tokenAmount })
-            setLoadingState('Sign in wallet')
-            const hash = await sendTransactions({
-                preparedDepositTxs: { unsignedTxs: [unsignedTx] },
-                feeOptions: undefined,
-            })
-
-            setLoadingState('Executing transaction')
-
-            await peanut.submitRequestLinkFulfillment({
-                chainId: requestLinkData.chainId,
-                hash: hash ?? '',
-                payerAddress: address ?? '',
-                link: requestLinkData.link,
-                apiUrl: '/api/proxy/patch/',
-            })
-
-            const currentDate = new Date().toISOString()
-            utils.saveRequestLinkFulfillmentToLocalStorage({
-                details: {
-                    ...requestLinkData,
-                    destinationChainFulfillmentHash: hash ?? '',
-                    createdAt: currentDate,
-                },
-                link: requestLinkData.link,
-            })
-
-            setTransactionHash(hash ?? '')
-            onNext()
-        } else {
-            setLoadingState('Sign in wallet')
-
-            const xchainUnsignedTxs = await peanut.prepareXchainRequestFulfillmentTransaction({
-                fromToken: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE',
-                fromChainId: selectedChainID,
-                senderAddress: address ?? '',
-                recipientAddress: requestLinkData.recipientAddress as string,
-                destinationChainId: requestLinkData.chainId,
-                destinationToken: requestLinkData.tokenAddress,
-                link: requestLinkData.link,
-                squidRouterUrl: 'https://apiplus.squidrouter.com/v2/route',
-                apiUrl: '/api/proxy/get',
-                provider: await peanut.getDefaultProvider(selectedChainID),
-                tokenType: selectedTokenAddress === ADDRESS_ZERO ? EPeanutLinkType.native : EPeanutLinkType.erc20,
-                fromTokenDecimals: selectedTokenDecimals as number,
-            })
-
-            const { unsignedTxs } = xchainUnsignedTxs
-            const hash = await sendTransactions({
-                preparedDepositTxs: { unsignedTxs },
-                feeOptions: undefined,
-            })
-            setLoadingState('Executing transaction')
-
-            await peanut.submitRequestLinkFulfillment({
-                chainId: requestLinkData.chainId,
-                hash: hash ?? '',
-                payerAddress: address ?? '',
-                link: requestLinkData.link,
-                apiUrl: '/api/proxy/patch/',
-            })
-
-            const currentDate = new Date().toISOString()
-            utils.saveRequestLinkFulfillmentToLocalStorage({
-                details: {
-                    ...requestLinkData,
-                    destinationChainFulfillmentHash: hash ?? '',
-                    createdAt: currentDate,
-                },
-                link: requestLinkData.link,
-            })
-
-            setTransactionHash(hash ?? '')
-            onNext()
-        }
-    } catch (error) {
-        const errorString = utils.ErrorHandler(error)
-        setErrorState({
-            showError: true,
-            errorMessage: errorString,
-        })
-        console.error('Error while submitting request link fulfillment:', error)
-    } finally {
-        setLoadingState('Idle')
-    }
-}
+const handleMatchingChainAndToken = async () => {
+    await assertValues({ tokenValue: requestLinkData.tokenAmount })
+    setLoadingState('Sign in wallet')
+    const hash = await sendTransactions({
+        preparedDepositTxs: { unsignedTxs: [unsignedTx] },
+        feeOptions: undefined,
+    })
+    await submitAndSaveFulfillment(hash)
+}
+
+const handleCrossChainFulfillment = async () => {
+    setLoadingState('Sign in wallet')
+    const xchainUnsignedTxs = await peanut.prepareXchainRequestFulfillmentTransaction({
+        fromToken: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE',
+        fromChainId: selectedChainID,
+        senderAddress: address ?? '',
+        recipientAddress: requestLinkData.recipientAddress as string,
+        destinationChainId: requestLinkData.chainId,
+        destinationToken: requestLinkData.tokenAddress,
+        link: requestLinkData.link,
+        squidRouterUrl: 'https://apiplus.squidrouter.com/v2/route',
+        apiUrl: '/api/proxy/get',
+        provider: await peanut.getDefaultProvider(selectedChainID),
+        tokenType: selectedTokenAddress === ADDRESS_ZERO ? EPeanutLinkType.native : EPeanutLinkType.erc20,
+        fromTokenDecimals: selectedTokenDecimals as number,
+    })
+    const { unsignedTxs } = xchainUnsignedTxs
+    const hash = await sendTransactions({
+        preparedDepositTxs: { unsignedTxs },
+        feeOptions: undefined,
+    })
+    await submitAndSaveFulfillment(hash)
+}
+
+const submitAndSaveFulfillment = async (hash: string) => {
+    setLoadingState('Executing transaction')
+    await peanut.submitRequestLinkFulfillment({
+        chainId: requestLinkData.chainId,
+        hash: hash ?? '',
+        payerAddress: address ?? '',
+        link: requestLinkData.link,
+        apiUrl: '/api/proxy/patch/',
+    })
+    const currentDate = new Date().toISOString()
+    utils.saveRequestLinkFulfillmentToLocalStorage({
+        details: {
+            ...requestLinkData,
+            destinationChainFulfillmentHash: hash ?? '',
+            createdAt: currentDate,
+        },
+        link: requestLinkData.link,
+    })
+    setTransactionHash(hash ?? '')
+    onNext()
+}
+
+const handleOnNext = async () => {
+    if (selectedChainID !== currentChain) {
+        await switchNetwork(selectedChainID)
+    }
+    try {
+        setErrorState({ showError: false, errorMessage: '' })
+        if (!unsignedTx) return
+        if (selectedChainID === requestLinkData.chainId && selectedTokenAddress === requestLinkData.tokenAddress) {
+            await handleMatchingChainAndToken()
+        } else {
+            await handleCrossChainFulfillment()
+        }
+    } catch (error) {
+        const errorString = utils.ErrorHandler(error)
+        setErrorState({
+            showError: true,
+            errorMessage: errorString,
+        })
+        console.error('Error while submitting request link fulfillment:', error)
+    } finally {
+        setLoadingState('Idle')
+    }
+}
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (selectedChainID !== currentChain) {
await switchNetwork(selectedChainID)
}
try {
setErrorState({ showError: false, errorMessage: '' })
if (!unsignedTx) return
await assertValues({ tokenValue: requestLinkData.tokenAmount })
if (selectedChainID === requestLinkData.chainId && selectedTokenAddress === requestLinkData.tokenAddress) {
await assertValues({ tokenValue: requestLinkData.tokenAmount })
setLoadingState('Sign in wallet')
const hash = await sendTransactions({
preparedDepositTxs: { unsignedTxs: [unsignedTx] },
feeOptions: undefined,
})
setLoadingState('Sign in wallet')
setLoadingState('Executing transaction')
const hash = await sendTransactions({
preparedDepositTxs: { unsignedTxs: [unsignedTx] },
feeOptions: undefined,
})
await peanut.submitRequestLinkFulfillment({
chainId: requestLinkData.chainId,
hash: hash ?? '',
payerAddress: address ?? '',
link: requestLinkData.link,
apiUrl: '/api/proxy/patch/',
})
setLoadingState('Executing transaction')
const currentDate = new Date().toISOString()
utils.saveRequestLinkFulfillmentToLocalStorage({
details: {
...requestLinkData,
destinationChainFulfillmentHash: hash ?? '',
createdAt: currentDate,
},
link: requestLinkData.link,
})
await peanut.submitRequestLinkFulfillment({
chainId: requestLinkData.chainId,
hash: hash ?? '',
payerAddress: address ?? '',
link: requestLinkData.link,
apiUrl: '/api/proxy/patch/',
})
setTransactionHash(hash ?? '')
onNext()
} else {
setLoadingState('Sign in wallet')
const currentDate = new Date().toISOString()
utils.saveRequestLinkFulfillmentToLocalStorage({
details: {
...requestLinkData,
destinationChainFulfillmentHash: hash ?? '',
createdAt: currentDate,
},
link: requestLinkData.link,
})
const xchainUnsignedTxs = await peanut.prepareXchainRequestFulfillmentTransaction({
fromToken: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE',
fromChainId: selectedChainID,
senderAddress: address ?? '',
recipientAddress: requestLinkData.recipientAddress as string,
destinationChainId: requestLinkData.chainId,
destinationToken: requestLinkData.tokenAddress,
link: requestLinkData.link,
squidRouterUrl: 'https://apiplus.squidrouter.com/v2/route',
apiUrl: '/api/proxy/get',
provider: await peanut.getDefaultProvider(selectedChainID),
tokenType: selectedTokenAddress === ADDRESS_ZERO ? EPeanutLinkType.native : EPeanutLinkType.erc20,
fromTokenDecimals: selectedTokenDecimals as number,
})
const { unsignedTxs } = xchainUnsignedTxs
const hash = await sendTransactions({
preparedDepositTxs: { unsignedTxs },
feeOptions: undefined,
})
setLoadingState('Executing transaction')
await peanut.submitRequestLinkFulfillment({
chainId: requestLinkData.chainId,
hash: hash ?? '',
payerAddress: address ?? '',
link: requestLinkData.link,
apiUrl: '/api/proxy/patch/',
})
setTransactionHash(hash ?? '')
onNext()
const currentDate = new Date().toISOString()
utils.saveRequestLinkFulfillmentToLocalStorage({
details: {
...requestLinkData,
destinationChainFulfillmentHash: hash ?? '',
createdAt: currentDate,
},
link: requestLinkData.link,
})
setTransactionHash(hash ?? '')
onNext()
}
const handleMatchingChainAndToken = async () => {
await assertValues({ tokenValue: requestLinkData.tokenAmount })
setLoadingState('Sign in wallet')
const hash = await sendTransactions({
preparedDepositTxs: { unsignedTxs: [unsignedTx] },
feeOptions: undefined,
})
await submitAndSaveFulfillment(hash)
}
const handleCrossChainFulfillment = async () => {
setLoadingState('Sign in wallet')
const xchainUnsignedTxs = await peanut.prepareXchainRequestFulfillmentTransaction({
fromToken: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE',
fromChainId: selectedChainID,
senderAddress: address ?? '',
recipientAddress: requestLinkData.recipientAddress as string,
destinationChainId: requestLinkData.chainId,
destinationToken: requestLinkData.tokenAddress,
link: requestLinkData.link,
squidRouterUrl: 'https://apiplus.squidrouter.com/v2/route',
apiUrl: '/api/proxy/get',
provider: await peanut.getDefaultProvider(selectedChainID),
tokenType: selectedTokenAddress === ADDRESS_ZERO ? EPeanutLinkType.native : EPeanutLinkType.erc20,
fromTokenDecimals: selectedTokenDecimals as number,
})
const { unsignedTxs } = xchainUnsignedTxs
const hash = await sendTransactions({
preparedDepositTxs: { unsignedTxs },
feeOptions: undefined,
})
await submitAndSaveFulfillment(hash)
}
const submitAndSaveFulfillment = async (hash: string) => {
setLoadingState('Executing transaction')
await peanut.submitRequestLinkFulfillment({
chainId: requestLinkData.chainId,
hash: hash ?? '',
payerAddress: address ?? '',
link: requestLinkData.link,
apiUrl: '/api/proxy/patch/',
})
const currentDate = new Date().toISOString()
utils.saveRequestLinkFulfillmentToLocalStorage({
details: {
...requestLinkData,
destinationChainFulfillmentHash: hash ?? '',
createdAt: currentDate,
},
link: requestLinkData.link,
})
setTransactionHash(hash ?? '')
onNext()
}
const handleOnNext = async () => {
if (selectedChainID !== currentChain) {
await switchNetwork(selectedChainID)
}
try {
setErrorState({ showError: false, errorMessage: '' })
if (!unsignedTx) return
if (selectedChainID === requestLinkData.chainId && selectedTokenAddress === requestLinkData.tokenAddress) {
await handleMatchingChainAndToken()
} else {
await handleCrossChainFulfillment()
}
} catch (error) {
const errorString = utils.ErrorHandler(error)
setErrorState({
showError: true,
errorMessage: errorString,
})
console.error('Error while submitting request link fulfillment:', error)
} finally {
setLoadingState('Idle')
}
}

Comment on lines +203 to +212
try {
await switchNetworkUtil({
chainId,
currentChainId: currentChain?.id,
setLoadingState,
switchChainAsync,
})
console.log(`Switched to chain ${chainId}`)
} catch (error) {
console.error('Failed to switch network:', error)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is great, it seems like you standardized the behavior. Thats nice! x

Comment on lines +83 to +92
try {
await switchNetworkUtil({
chainId,
currentChainId: currentChain?.id,
setLoadingState,
switchChainAsync,
})
console.log(`Switched to chain ${chainId}`)
} catch (error) {
console.error('Failed to switch network:', error)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

idg this - why are you wrapping switchNetworkUtil in switchNetwork and adding an error log? whats the point?

.trim()
}

export const switchNetwork = async ({
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between b1009b4 and d5e015c.

Files selected for processing (1)
  • src/components/Request/Pay/Views/Initial.view.tsx (6 hunks)
Additional comments not posted (2)
src/components/Request/Pay/Views/Initial.view.tsx (2)

26-30: LGTM!

The destructuring of values from useAccount and tokenSelectorContext looks good. These values are likely used for handling the connection status, user address, current chain, and selected chain/token details for cross-chain transactions.


224-229: LGTM!

The label provides clear information to the user about the flexibility of fulfilling the payment request with any token on any chain. The inclusion of the TokenSelector component allows the user to easily select the desired token and chain for fulfillment.

Comment on lines +55 to +133
if (selectedChainID !== currentChain) {
await switchNetwork(selectedChainID)
}
try {
setErrorState({ showError: false, errorMessage: '' })
if (!unsignedTx) return
await assertValues({ tokenValue: requestLinkData.tokenAmount })
if (selectedChainID === requestLinkData.chainId && selectedTokenAddress === requestLinkData.tokenAddress) {
await assertValues({ tokenValue: requestLinkData.tokenAmount })
setLoadingState('Sign in wallet')
const hash = await sendTransactions({
preparedDepositTxs: { unsignedTxs: [unsignedTx] },
feeOptions: undefined,
})

setLoadingState('Sign in wallet')
setLoadingState('Executing transaction')

const hash = await sendTransactions({
preparedDepositTxs: { unsignedTxs: [unsignedTx] },
feeOptions: undefined,
})
await peanut.submitRequestLinkFulfillment({
chainId: requestLinkData.chainId,
hash: hash ?? '',
payerAddress: address ?? '',
link: requestLinkData.link,
apiUrl: '/api/proxy/patch/',
})

setLoadingState('Executing transaction')
const currentDate = new Date().toISOString()
utils.saveRequestLinkFulfillmentToLocalStorage({
details: {
...requestLinkData,
destinationChainFulfillmentHash: hash ?? '',
createdAt: currentDate,
},
link: requestLinkData.link,
})

await peanut.submitRequestLinkFulfillment({
chainId: requestLinkData.chainId,
hash: hash ?? '',
payerAddress: address ?? '',
link: requestLinkData.link,
apiUrl: '/api/proxy/patch/',
})
setTransactionHash(hash ?? '')
onNext()
} else {
setLoadingState('Sign in wallet')

const currentDate = new Date().toISOString()
utils.saveRequestLinkFulfillmentToLocalStorage({
details: {
...requestLinkData,
destinationChainFulfillmentHash: hash ?? '',
createdAt: currentDate,
},
link: requestLinkData.link,
})
const xchainUnsignedTxs = await peanut.prepareXchainRequestFulfillmentTransaction({
fromToken: selectedTokenAddress,
fromChainId: selectedChainID,
senderAddress: address ?? '',
link: requestLinkData.link,
squidRouterUrl: 'https://apiplus.squidrouter.com/v2/route',
apiUrl: '/api/proxy/get',
provider: await peanut.getDefaultProvider(selectedChainID),
tokenType: selectedTokenAddress === ADDRESS_ZERO ? EPeanutLinkType.native : EPeanutLinkType.erc20,
fromTokenDecimals: selectedTokenDecimals as number,
})

const { unsignedTxs } = xchainUnsignedTxs
const hash = await sendTransactions({
preparedDepositTxs: { unsignedTxs },
feeOptions: undefined,
})
setLoadingState('Executing transaction')

await peanut.submitRequestLinkFulfillment({
chainId: requestLinkData.chainId,
hash: hash ?? '',
payerAddress: address ?? '',
link: requestLinkData.link,
apiUrl: '/api/proxy/patch/',
})

setTransactionHash(hash ?? '')
onNext()
const currentDate = new Date().toISOString()
utils.saveRequestLinkFulfillmentToLocalStorage({
details: {
...requestLinkData,
destinationChainFulfillmentHash: hash ?? '',
createdAt: currentDate,
},
link: requestLinkData.link,
})

setTransactionHash(hash ?? '')
onNext()
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider refactoring the handleOnNext function for better readability and maintainability.

The handleOnNext function is quite large and can be refactored for better readability and maintainability. Here are a few suggestions:

  1. Extract the logic for handling the case when the selected chain and token match the request data into a separate function (e.g., handleMatchingChainAndToken).
  2. Extract the logic for handling the case when the selected chain and token do not match the request data into a separate function (e.g., handleCrossChainFulfillment).
  3. Move the common logic for submitting the request link fulfillment and saving it to local storage into a separate function (e.g., submitAndSaveFulfillment).

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Outside diff range and nitpick comments (1)
src/components/utils/utils.ts (1)

3-14: LGTM with a suggestion!

The checkTransactionStatus function is implemented correctly and follows best practices for making API requests. The error handling ensures that any errors are caught and logged to the console.

Consider adding type annotations for the response data to improve type safety and code readability. For example:

-export async function checkTransactionStatus(txHash: string): Promise<void> {
+export async function checkTransactionStatus(txHash: string): Promise<TransactionStatusResponse> {
   try {
     const response = await axios.get('https://apiplus.squidrouter.com/v2/status', {
       params: { transactionId: txHash },
       headers: { 'x-integrator-id': '11CBA45B-5EE9-4331-B146-48CCD7ED4C7C' },
     })
-    return response.data
+    return response.data as TransactionStatusResponse
   } catch (error) {
     console.error('Error fetching transaction status:', error)
     throw error
   }
 }

+interface TransactionStatusResponse {
+  // Define the structure of the response data
+  // Example:
+  // squidTransactionStatus: string
+  // toChain: {
+  //   chainData: {
+  //     chainId: string
+  //   }
+  //   transactionId: string
+  //   transactionUrl: string
+  // }
+}
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between d5e015c and 3585c9d.

Files selected for processing (4)
  • src/components/Claim/Link/Onchain/Success.view.tsx (2 hunks)
  • src/components/Request/Pay/Views/Initial.view.tsx (5 hunks)
  • src/components/Request/Pay/Views/Success.view.tsx (2 hunks)
  • src/components/utils/utils.ts (1 hunks)
Additional context used
Biome
src/components/Request/Pay/Views/Initial.view.tsx

[error] 58-58: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)

Additional comments not posted (14)
src/components/Request/Pay/Views/Success.view.tsx (6)

5-7: LGTM!

The imports are necessary for the component to function correctly and access shared state.


14-16: LGTM!

The state variable is correctly typed and initialized to hold the transaction details for the destination chain.


17-17: LGTM!

The constant variable is correctly constructed to provide a direct link to the Axelar transaction page.


19-19: LGTM!

The useContext hook is correctly used to access the selectedChainID from the tokenSelectorContext.


21-25: LGTM!

The useEffect hook is correctly used to start the loop for checking the transaction status on component mount.


36-66: LGTM!

The conditional rendering and display of transaction details with explorer links enhance the user experience and provide valuable information to the users.

src/components/Claim/Link/Onchain/Success.view.tsx (2)

9-9: LGTM!

The import statement for the loopUntilSuccess function is correct.


49-49: Verify the loopUntilSuccess function correctly sets the explorer URL.

The changes to streamline the handling of transaction status updates by invoking the loopUntilSuccess function with the setExplorerUrlDestChainWithTxHash parameter look good. This refactoring improves modularity and maintainability of the codebase, aligning with the PR objective of integrating the UI with request links.

Please ensure that the loopUntilSuccess function correctly sets the explorer URL for the destination chain transaction hash. You can verify this by running the following script:

Expect the loopUntilSuccess function to contain logic for setting the explorer URL using the setExplorerUrlDestChainWithTxHash function.

Verification successful

Verification successful: loopUntilSuccess function correctly sets the explorer URL.

The loopUntilSuccess function in src/components/utils/utils.ts correctly sets the explorer URL for the destination chain transaction hash using the setExplorerUrlDestChainWithTxHash function. The logic ensures that the URL is set only when the transaction status is successful, aligning with the intended functionality.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the `loopUntilSuccess` function sets the explorer URL for the destination chain transaction hash.

# Test: Search for the `loopUntilSuccess` function implementation.
ast-grep --lang typescript --pattern $'function loopUntilSuccess($_, $_) {
  $$$
}'

Length of output: 2379

src/components/Request/Pay/Views/Initial.view.tsx (6)

31-31: LGTM!

The integration with the tokenSelectorContext allows the component to access the selected token and chain information, which is crucial for handling cross-chain transaction fulfillment and improving the user experience.


38-51: LGTM!

The createXChainUnsignedTx function encapsulates the logic for preparing cross-chain transactions, making the code more modular and reusable. The usage of the selected token and chain information ensures that the transactions are prepared based on the user's selection, enhancing the flexibility of the payment request fulfillment process.


53-67: LGTM!

The useEffect hook ensures that the transaction fee is re-estimated whenever the selected token changes, providing an up-to-date estimate to the user. The usage of the createXChainUnsignedTx function and the peanut.calculateCrossChainTxFee method ensures that the transaction fee is accurately estimated based on the selected token and chain, improving the user experience and transparency.

Tools
Biome

[error] 58-58: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


88-155: LGTM!

The changes to the handleOnNext function introduce a more flexible payment request fulfillment process, allowing users to fulfill the request with any token on any chain. The function handles both direct and cross-chain fulfillment scenarios, ensuring a seamless user experience. The usage of the createXChainUnsignedTx function and the peanut.submitRequestLinkFulfillment method ensures that the cross-chain fulfillment process is handled correctly, while the saving of the fulfillment details to local storage allows users to track their past fulfillments.


251-251: LGTM!

The addition of the TokenSelector component allows users to select the token and chain for fulfilling the payment request, enhancing the user experience by providing flexibility in the payment request fulfillment process.


253-279: LGTM!

The changes to the transaction fee display logic ensure that the transaction fee is accurately displayed based on the selected token and chain. The usage of the estimatedGasCost for direct fulfillment and the txFee for cross-chain fulfillment provides transparency to the user. The MoreInfo component is used effectively to provide additional information about the transaction fee, enhancing the user experience.

Comment on lines +16 to +47
export async function loopUntilSuccess(
txHash: string,
setExplorerUrlDestChainWithTxHash: (value: { transactionId: string; transactionUrl: string }) => void
) {
let intervalId = setInterval(async () => {
const result = await checkTransactionStatus(txHash)

//@ts-ignore
if (result.squidTransactionStatus === 'success') {
//@ts-ignore
const explorerUrl = utils.getExplorerUrl(result.toChain.chainData.chainId.toString())
if (explorerUrl) {
setExplorerUrlDestChainWithTxHash({
//@ts-ignore
transactionUrl: explorerUrl + '/tx/' + result.toChain.transactionId,
//@ts-ignore
transactionId: result.toChain.transactionId,
})
} else {
setExplorerUrlDestChainWithTxHash({
//@ts-ignore
transactionUrl: result.toChain.transactionUrl,
//@ts-ignore
transactionId: result.toChain.transactionId,
})
}
clearInterval(intervalId)
} else {
console.log('Checking status again...')
}
}, 5000)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved with suggestions for improvement!

The loopUntilSuccess function implements a polling mechanism to check the transaction status until it is successful. The use of setInterval is appropriate for periodically checking the status, and the function correctly updates the explorer URL and transaction ID using the callback function when the status is successful.

Consider the following suggestions to improve the code:

  1. Properly type the result object and its properties to avoid using @ts-ignore comments. Define an interface for the result object based on the expected structure of the API response.

  2. Add a maximum number of retries or a timeout to prevent infinite polling in case of issues. For example, you can introduce a maxRetries parameter and keep track of the number of retries. If the maximum retries are exceeded, clear the interval and handle the failure scenario appropriately.

Here's an example of how you can refactor the code:

-export async function loopUntilSuccess(
+export async function loopUntilSuccess(
   txHash: string,
-  setExplorerUrlDestChainWithTxHash: (value: { transactionId: string; transactionUrl: string }) => void
+  setExplorerUrlDestChainWithTxHash: (value: { transactionId: string; transactionUrl: string }) => void,
+  maxRetries: number = 10
 ) {
+  let retryCount = 0
   let intervalId = setInterval(async () => {
     const result = await checkTransactionStatus(txHash)

-    //@ts-ignore
-    if (result.squidTransactionStatus === 'success') {
-      //@ts-ignore
-      const explorerUrl = utils.getExplorerUrl(result.toChain.chainData.chainId.toString())
+    if (result.squidTransactionStatus === 'success') {
+      const explorerUrl = utils.getExplorerUrl(result.toChain.chainData.chainId.toString())
       if (explorerUrl) {
         setExplorerUrlDestChainWithTxHash({
-          //@ts-ignore
-          transactionUrl: explorerUrl + '/tx/' + result.toChain.transactionId,
-          //@ts-ignore
-          transactionId: result.toChain.transactionId,
+          transactionUrl: explorerUrl + '/tx/' + result.toChain.transactionId,
+          transactionId: result.toChain.transactionId,
         })
       } else {
         setExplorerUrlDestChainWithTxHash({
-          //@ts-ignore
-          transactionUrl: result.toChain.transactionUrl,
-          //@ts-ignore
-          transactionId: result.toChain.transactionId,
+          transactionUrl: result.toChain.transactionUrl,
+          transactionId: result.toChain.transactionId,
         })
       }
       clearInterval(intervalId)
+    } else if (retryCount >= maxRetries) {
+      console.error('Maximum retries exceeded. Transaction status check failed.')
+      clearInterval(intervalId)
+      // Handle the failure scenario, e.g., show an error message to the user
     } else {
       console.log('Checking status again...')
+      retryCount++
     }
   }, 5000)
 }

+interface TransactionStatusResult {
+  squidTransactionStatus: string
+  toChain: {
+    chainData: {
+      chainId: string
+    }
+    transactionId: string
+    transactionUrl: string
+  }
+}
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export async function loopUntilSuccess(
txHash: string,
setExplorerUrlDestChainWithTxHash: (value: { transactionId: string; transactionUrl: string }) => void
) {
let intervalId = setInterval(async () => {
const result = await checkTransactionStatus(txHash)
//@ts-ignore
if (result.squidTransactionStatus === 'success') {
//@ts-ignore
const explorerUrl = utils.getExplorerUrl(result.toChain.chainData.chainId.toString())
if (explorerUrl) {
setExplorerUrlDestChainWithTxHash({
//@ts-ignore
transactionUrl: explorerUrl + '/tx/' + result.toChain.transactionId,
//@ts-ignore
transactionId: result.toChain.transactionId,
})
} else {
setExplorerUrlDestChainWithTxHash({
//@ts-ignore
transactionUrl: result.toChain.transactionUrl,
//@ts-ignore
transactionId: result.toChain.transactionId,
})
}
clearInterval(intervalId)
} else {
console.log('Checking status again...')
}
}, 5000)
}
export async function loopUntilSuccess(
txHash: string,
setExplorerUrlDestChainWithTxHash: (value: { transactionId: string; transactionUrl: string }) => void,
maxRetries: number = 10
) {
let retryCount = 0
let intervalId = setInterval(async () => {
const result = await checkTransactionStatus(txHash)
if (result.squidTransactionStatus === 'success') {
const explorerUrl = utils.getExplorerUrl(result.toChain.chainData.chainId.toString())
if (explorerUrl) {
setExplorerUrlDestChainWithTxHash({
transactionUrl: explorerUrl + '/tx/' + result.toChain.transactionId,
transactionId: result.toChain.transactionId,
})
} else {
setExplorerUrlDestChainWithTxHash({
transactionUrl: result.toChain.transactionUrl,
transactionId: result.toChain.transactionId,
})
}
clearInterval(intervalId)
} else if (retryCount >= maxRetries) {
console.error('Maximum retries exceeded. Transaction status check failed.')
clearInterval(intervalId)
// Handle the failure scenario, e.g., show an error message to the user
} else {
console.log('Checking status again...')
retryCount++
}
}, 5000)
}
interface TransactionStatusResult {
squidTransactionStatus: string
toChain: {
chainData: {
chainId: string
}
transactionId: string
transactionUrl: string
}
}

@coderabbitai coderabbitai bot mentioned this pull request Oct 13, 2024
1 task
This was referenced Dec 17, 2024
@coderabbitai coderabbitai bot mentioned this pull request Apr 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants