Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add swap transaction verification #175

Open
wants to merge 4 commits into
base: staging
Choose a base branch
from

Conversation

ae2079
Copy link
Collaborator

@ae2079 ae2079 commented Mar 11, 2025

Summary by CodeRabbit

  • New Features

    • Enhanced swap transaction management with improved status handling, including a new "SWAP_PENDING" state.
    • Expanded donation options now visible in the admin dashboard, allowing for better tracking of donation statuses.
    • Introduced a new environment variable for integration purposes.
  • Chores

    • Improved resource validation to bolster overall data consistency and reliability.

Copy link

coderabbitai bot commented Mar 11, 2025

Walkthrough

This update introduces several modifications to enhance the management of swap transactions. Key changes include the restructuring of the updateSwapDonationStatus function to use a more defined parameter type, the addition of a new donation status SWAP_PENDING, and the integration of validation capabilities into the Resource object. Furthermore, the logic for determining completed statuses in swap transactions has been expanded, and new interfaces have been defined to improve type safety in API responses.

Changes

File(s) Change Summary
src/repositories/swapRepository.ts Modified updateSwapDonationStatus function to use a structured status object instead of any type for swapStatus.
src/server/bootstrap.ts Assigned Resource.validate to the validate function imported from class-validator for resource validation.
src/services/cronJobs/syncSwapTransactions.ts Updated isCompletedStatus function to recognize both 'success' and 'destination_executed' as completed statuses.
src/services/squidService.ts Added new interfaces for data structure and updated getStatus return type to Promise<SquidStatusResponse>.
src/entities/donation.ts Added new status SWAP_PENDING to DONATION_STATUS constant.
src/repositories/projectRoundRecordRepository.ts, src/repositories/projectUserRecordRepository.ts Expanded status arrays in relevant functions to include DONATION_STATUS.SWAP_PENDING.
src/server/adminJs/tabs/donationTab.ts Updated donationTab object to include SWAP_PENDING in availableValues array.
.env.template Added new environment variable SQUID_INTEGRATOR_ID.

Suggested reviewers

  • aminlatifi
  • lovelgeorge99

Poem

Hopping through the code with glee,
New swaps and statuses set us free.
The cron job ticks, the API sings,
With every update, joy it brings.
Carrots and commits, in lines we trust—
A rabbit’s cheer for code robust!
🥕🐇


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e48cd25 and 8ea0e7b.

📒 Files selected for processing (1)
  • src/resolvers/donationResolver.ts (3 hunks)
🔇 Additional comments (3)
src/resolvers/donationResolver.ts (3)

887-887: Good initialization of default donation status.

The variable initialization provides a clear default state for new donations, making the code more readable and maintainable.


903-903: Appropriate status update for swap transactions.

Setting the donation status to SWAP_PENDING when swap data is present correctly differentiates between regular pending donations and those waiting for a swap transaction to complete, improving transaction tracking.


932-932:

✅ Verification successful

Good integration of dynamic status in donation data.

Including the dynamic donationStatus in the donation data object ensures the correct status is stored in the database, enabling better tracking and management of swap-related donations.


🏁 Script executed:

#!/bin/bash
# Verify that SWAP_PENDING status is handled properly in other parts of the codebase

echo "Checking for SWAP_PENDING status usage in entities/donation.ts..."
rg "SWAP_PENDING" --type ts

echo "Checking for handling of SWAP_PENDING status in relevant repositories..."
rg "SWAP_PENDING.*status" --type ts

Length of output: 945


Dynamic Donation Status Integration Approved

The integration of the dynamic donationStatus in the donation data object is well implemented. Verification shows that the SWAP_PENDING status is consistently defined (e.g., in src/entities/donation.ts) and referenced across multiple modules such as donationResolver.ts, donationTab.ts, and relevant repositories. This confirms that the dynamic status correctly propagates through the system, enabling robust tracking and management.

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 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>, please review it.
    • 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 gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @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 generate docstrings to generate docstrings for this 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

@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: 3

🧹 Nitpick comments (7)
src/services/cronJobs/syncSwapTransactions.ts (4)

18-27: Periodic job queue logging.

Logging the queue size every two minutes is helpful for monitoring. If advanced health checks or metrics are needed, consider capturing more data (like active vs. stalled jobs).


36-45: runCheckPendingSwapsCronJob scheduling.

Separating the logic for processing swaps and for scheduling them is good practice. Consider adding error handling in case addJobToCheckPendingSwaps fails to fetch or enqueue jobs.


47-67: addJobToCheckPendingSwaps function.

Fetching and enqueuing pending swaps is straightforward. If debugging is needed for failed jobs, it may be helpful to set removeOnFail: false to preserve error logs in the queue.


90-117: verifySwapTransaction function logic.

  1. Fetches the swap record.
  2. Retrieves status from an external API.
  3. Updates both the swap record and donation records.

The flow is clear. Verify that partial failures (e.g., updating donation fails, but swap status was updated) are unlikely to leave inconsistent states.

src/repositories/swapRepository.ts (3)

37-61: Add validation for chain ID parsing

In lines 54-55, the function parses fromChainId and toChainId as integers without any error handling. If these values cannot be parsed correctly (e.g., if they contain non-numeric characters), the function will throw an error. Consider adding validation or error handling for these conversions.

- fromChainId: parseInt(params.fromChainId),
- toChainId: parseInt(params.toChainId),
+ fromChainId: Number.isNaN(parseInt(params.fromChainId)) ? 0 : parseInt(params.fromChainId),
+ toChainId: Number.isNaN(parseInt(params.toChainId)) ? 0 : parseInt(params.toChainId),

Alternatively, if these fields should never be invalid, consider throwing a more descriptive error:

- fromChainId: parseInt(params.fromChainId),
- toChainId: parseInt(params.toChainId),
+ fromChainId: Number.isNaN(parseInt(params.fromChainId)) 
+   ? (() => { throw new Error(`Invalid fromChainId: ${params.fromChainId}`) })() 
+   : parseInt(params.fromChainId),
+ toChainId: Number.isNaN(parseInt(params.toChainId))
+   ? (() => { throw new Error(`Invalid toChainId: ${params.toChainId}`) })() 
+   : parseInt(params.toChainId),

7-11: Consider returning relations for comprehensive data

The getPendingSwaps function retrieves swap transactions without any related entities. Depending on how this data is used, you might want to include related entities like donations to avoid N+1 query problems.

export const getPendingSwaps = async (): Promise<SwapTransaction[]> => {
  return await SwapTransaction.createQueryBuilder('swap')
    .where('swap.status = :status', { status: SWAP_TRANSACTION_STATUS.PENDING })
+   .leftJoinAndSelect('swap.donation', 'donation')
    .getMany();
};

13-17: Consider including relations in getSwapById

The getSwapById function doesn't include related entities like donations. This could lead to inconsistencies when using this function vs. directly querying with relations. Consider adding an optional parameter to include relations.

export const getSwapById = async (
  id: number,
+ relations: string[] = [],
): Promise<SwapTransaction | null> => {
- return await SwapTransaction.findOne({ where: { id } });
+ return await SwapTransaction.findOne({ 
+   where: { id },
+   relations,
+ });
};

Then update the usage in updateSwapDonationStatus:

- const swap = await getSwapById(swapId);
+ const swap = await getSwapById(swapId, ['donation']);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 81a517a and f189be4.

📒 Files selected for processing (9)
  • src/repositories/swapRepository.ts (1 hunks)
  • src/server/bootstrap.ts (2 hunks)
  • src/services/cronJobs/syncSwapTransactions.ts (1 hunks)
  • src/services/squidService.ts (1 hunks)
  • src/entities/donation.ts (1 hunks)
  • src/repositories/projectRoundRecordRepository.ts (2 hunks)
  • src/repositories/projectUserRecordRepository.ts (1 hunks)
  • src/server/adminJs/tabs/donationTab.ts (1 hunks)
  • src/server/bootstrap.ts (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: test
🔇 Additional comments (12)
src/entities/donation.ts (1)

21-21: LGTM: Addition of the new SWAP_PENDING status

The new SWAP_PENDING status has been properly added to the DONATION_STATUS constant, which will allow tracking of donations that are waiting for a swap transaction to complete.

src/repositories/projectUserRecordRepository.ts (1)

56-60: Updated donation status array to include SWAP_PENDING status

The inclusion of DONATION_STATUS.SWAP_PENDING in the status array ensures that donations with pending swaps will be included in the project user record calculations. This is consistent with how other statuses are handled.

src/server/bootstrap.ts (2)

69-69: New import for the swap transaction cron job

The import for runCheckPendingSwapsCronJob has been correctly added to implement the new feature.


162-162: Added new cron job for checking pending swaps

The cron job has been properly integrated into the initialization sequence. This will enable periodic verification of pending swap transactions.

src/services/squidService.ts (2)

1-5: LGTM: Service setup and configuration

The imports and configuration retrieval for the Squid service are properly set up. The integrator ID is fetched from the application configuration.


6-30:

✅ Verification successful

LGTM: Implementation of the getStatus function with proper error handling

The getStatus function is well-implemented with appropriate error handling. It correctly:

  1. Makes a request to the Squid API with required parameters
  2. Includes the integrator ID in the headers
  3. Returns the response data
  4. Logs detailed error information when failures occur

Verify the format of the response data by checking the Squid API documentation:


🌐 Web query:

What is the response format for the Squid API status endpoint?

💡 Result:

The response format for Squid API status endpoints varies by implementation but generally includes these key elements based on different Squid-related APIs:

Common Status Response Components

  1. System Status (Squid v1 REST API)

    {
      "model": "SX-DC-8-1224",
      "serial": "240320200000",
      "activeState": "Running",
      "objType": "currentStatus",
      "temperatureUnits": "F",
      "firmware": "0.5.25384",
      "devices": [/* hardware details */]
    }

    Includes hardware/software status and operational metrics[3].

  2. Transaction Status (Squid Router)

    {
      "squidTransactionStatus": "SUCCESS",
      "id": "<transaction-hash>",
      "status": "completed",
      "gasStatus": "paid",
      "fromChainId": 1,
      "toChainId": 137
    }

    Tracks cross-chain transaction states with explicit status codes[9].

  3. API Health Check (Giant Squid)

    {
      squidStatus {
        height
      }
    }

    Returns blockchain height for endpoint health verification[5].

Key Fields Across Implementations

Field Type Example Values Description
Operational State "Running", "Disabled" Current system status[3][12]
Version Information "firmware": "0.5.25384" Software/hardware versions[3]
Network Metrics "height": 1834567 Blockchain synchronization status[5]
Transaction State "SUCCESS", "NEEDS_GAS" Cross-chain operation status[9]
Error Codes "status": 403 HTTP/API-specific status codes[4][8]

For production environments, most Squid APIs require security headers and return HATEOAS-style links for available operations[10][13]. The exact structure depends on the specific Squid implementation (AI proxy, blockchain router, or caching system).

Citations:


LGTM – Confirmed Response Format & Error Handling

The getStatus function is implemented correctly. It makes the appropriate GET request to the Squid API endpoint using the provided parameters, includes the integrator ID in the headers, returns the API response data, and logs errors appropriately. The web query confirms that Squid Transaction Status responses typically include fields like squidTransactionStatus, id, status, gasStatus, fromChainId, and toChainId, which aligns with the expectations of this implementation.

  • API Request: Uses axios.get with the correct endpoint and headers.
  • Response Handling: Returns result.data, which should contain the relevant fields as per Squid API documentation.
  • Error Handling: Logs both detailed API errors (if available) and the request parameters upon failure.

The response format verification from the documentation supports the current implementation. No further changes are required.

src/server/adminJs/tabs/donationTab.ts (1)

603-606: Add SWAP_PENDING donation status.

This update properly integrates the new SWAP_PENDING status. Ensure that transitions from/to this status are uniformly handled across the codebase to prevent orphaned states or confusion for administrators.

src/repositories/projectRoundRecordRepository.ts (1)

31-35: Include SWAP_PENDING in status filtering.

Adding SWAP_PENDING to both queries ensures donations with this status are accounted for in project round record calculations. Confirm that this status is valid in all relevant flows (e.g., a donation is never stuck in SWAP_PENDING incorrectly).

Also applies to: 160-164

src/services/cronJobs/syncSwapTransactions.ts (4)

1-16: Imports and Bull queue creation.

Imports and queue initialization look fine. Validate that redisConfig is properly connected and handles reconnections so that the queue operations remain stable under fluctuating network conditions.


28-35: Concurrent jobs configuration and cron expression.

The configurable concurrency and cron expression facilitate flexible deployments. Ensure that NUMBER_OF_VERIFY_SWAP_CONCURRENT_JOB is maintained within safe limits, and that frequent job runs won't cause unintended resource usage spikes.


69-88: processVerifySwapsJobs function.

The concurrency-based processing structure is good. Ensure exceptions propagating from verifySwapTransaction are managed as intended, so asynchronous failures don't get silently lost.


119-123: isCompletedStatus helper.

Restricting completed statuses to ['success'] is explicit. If future statuses indicate completion (e.g., 'partial_success'), remember to extend this list.

Comment on lines +19 to +35
export const updateSwapStatus = async (
id: number,
squidTransactionStatus: string,
): Promise<void> => {
const swap = await SwapTransaction.findOne({ where: { id } });
if (!swap) {
throw new Error(`Swap with id ${id} not found`);
}

const metadata = swap.metadata || {};
metadata.squidTransactionStatus = squidTransactionStatus;

await SwapTransaction.update(id, {
status: squidTransactionStatus,
metadata,
});
};
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Consider mapping the squidTransactionStatus to a valid SwapTransaction status

The function directly assigns the squidTransactionStatus string to the swap's status field in line 32. If the external Squid API uses different status values than your SWAP_TRANSACTION_STATUS enum, this could potentially introduce invalid status values. Consider mapping the external status to your application's status enum.


🏁 Script executed:

#!/bin/bash
# Check if the external Squid transaction statuses match our internal SWAP_TRANSACTION_STATUS enum values
echo "Checking SWAP_TRANSACTION_STATUS enum values:"
rg -A 10 "enum SWAP_TRANSACTION_STATUS" --type ts
echo -e "\nChecking for any Squid API status mapping:"
rg "squidTransactionStatus" --type ts | grep -v "swapRepository.ts"

Length of output: 538


Action Required: Map External Squid Status to a Valid Internal Status
The mapping of squidTransactionStatus to your internal SWAP_TRANSACTION_STATUS enum is currently missing. Without an explicit mapping, you risk saving an external status value that may not align with your application's defined enum. Please introduce a mapping layer (for instance, via a dictionary or function) to translate the external Squid status into one of your valid internal statuses before the update call.

  • Location: src/repositories/swapRepository.ts (lines 19–35)
  • Recommendation:
    • Add a mapping function or lookup table to convert the incoming squidTransactionStatus into a valid SWAP_TRANSACTION_STATUS value.
    • Review any related usages (e.g., in src/services/cronJobs/syncSwapTransactions.ts) to ensure consistency in status translations.

Comment on lines 77 to 81
if (swap.donation) {
swap.donation.status = DONATION_STATUS.PENDING;
swap.donation.transactionId = swapStatus.secondTxHash;
await swap.donation.save();
}
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify the correct donation status

According to the AI summary, a new status SWAP_PENDING was added to the DONATION_STATUS enum, but line 78 sets the donation status to PENDING. Verify if you should be using SWAP_PENDING instead.


🌐 Web query:

What's the difference between "PENDING" and "SWAP_PENDING" statuses in donation processing systems?

💡 Result:

The "PENDING" and "SWAP_PENDING" statuses in donation processing systems refer to distinct phases in different transaction contexts:

PENDING Status

  • General Meaning: Indicates a donation is awaiting further action before completion. Common reasons include:
    • Clearance periods: Donations may take 14 days to clear before funds are transferred to the charity’s account[1].
    • Verification: Requires donor confirmation or nonprofit review (e.g., matching gift submissions)[4][7].
    • Payment processing delays: ACH transfers or credit card approvals can take 5–7 business days[13].
    • Minimum transfer thresholds: Funds remain pending until the balance meets the currency’s transfer limit[1].

SWAP_PENDING Status

  • Blockchain/Crypto Context: Specific to cryptocurrency or token swaps, such as cross-chain transfers (e.g., Neo X blockchain transactions)[3][15]. It signifies:
    • A token exchange (e.g., N3 to Neo X) is initiated but awaiting validation or relay between networks.
    • Requires time for validators to confirm the swap via smart contracts or bridging protocols[3][15].

Key Differences

Aspect PENDING SWAP_PENDING
Environment Traditional fiat payment systems Blockchain/cryptocurrency networks
Primary Cause Banking delays, verification, limits Cross-chain validation or token swaps
Resolution Automatic after set periods Relies on blockchain validators
Examples ACH delays[13], matching gift holds[4] Neo X bridge transfers[3], crypto swaps[15]

In summary, "PENDING" is a broad status in traditional donation systems, while "SWAP_PENDING" applies narrowly to cryptocurrency swaps awaiting blockchain confirmation.

Citations:


Donation Status Correction for Blockchain Swaps

The current implementation sets the donation status to PENDING, which is generally used for fiat or non-swap donations. Since this repository handles cryptocurrency swaps, the donation should instead be marked with the SWAP_PENDING status to correctly reflect that the token exchange is awaiting blockchain validation.

  • Action Required: Change the assignment from DONATION_STATUS.PENDING to DONATION_STATUS.SWAP_PENDING.
  • Example Diff:
     if (swap.donation) {
    -  swap.donation.status = DONATION_STATUS.PENDING;
    +  swap.donation.status = DONATION_STATUS.SWAP_PENDING;
       swap.donation.transactionId = swapStatus.secondTxHash;
       await swap.donation.save();
     }
📝 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 (swap.donation) {
swap.donation.status = DONATION_STATUS.PENDING;
swap.donation.transactionId = swapStatus.secondTxHash;
await swap.donation.save();
}
if (swap.donation) {
swap.donation.status = DONATION_STATUS.SWAP_PENDING;
swap.donation.transactionId = swapStatus.secondTxHash;
await swap.donation.save();
}

Comment on lines 63 to 82
export const updateSwapDonationStatus = async (
swapId: number,
swapStatus: any,
): Promise<void> => {
const swap = await getSwapById(swapId);
if (!swap) {
throw new Error(`Swap with id ${swapId} not found`);
}

swap.secondTxHash = swapStatus.secondTxHash;
swap.toAmount = swapStatus.toAmount;
swap.status = swapStatus.squidTransactionStatus;
await swap.save();

if (swap.donation) {
swap.donation.status = DONATION_STATUS.PENDING;
swap.donation.transactionId = swapStatus.secondTxHash;
await swap.donation.save();
}
};
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Improve type safety and add transaction management

The swapStatus parameter is typed as any, which reduces type safety. Consider defining a proper interface for this parameter. Additionally, the function updates both the swap and its associated donation without transaction management. This could lead to inconsistent data if one operation succeeds and the other fails.

+ interface SwapStatus {
+   secondTxHash: string;
+   toAmount: number;
+   squidTransactionStatus: string;
+ }

- export const updateSwapDonationStatus = async (
-   swapId: number,
-   swapStatus: any,
- ): Promise<void> => {
+ export const updateSwapDonationStatus = async (
+   swapId: number,
+   swapStatus: SwapStatus,
+ ): Promise<void> => {
+   const queryRunner = SwapTransaction.getRepository().manager.connection.createQueryRunner();
+   
+   await queryRunner.connect();
+   await queryRunner.startTransaction();
+   
+   try {
      const swap = await getSwapById(swapId);
      if (!swap) {
        throw new Error(`Swap with id ${swapId} not found`);
      }

      swap.secondTxHash = swapStatus.secondTxHash;
      swap.toAmount = swapStatus.toAmount;
      swap.status = swapStatus.squidTransactionStatus;
      await swap.save();

      if (swap.donation) {
        swap.donation.status = DONATION_STATUS.PENDING;
        swap.donation.transactionId = swapStatus.secondTxHash;
        await swap.donation.save();
      }
+     
+     await queryRunner.commitTransaction();
+   } catch (error) {
+     await queryRunner.rollbackTransaction();
+     throw error;
+   } finally {
+     await queryRunner.release();
+   }
};

🏁 Script executed:

#!/bin/bash
# Check if SWAP_PENDING is being used in the donation entity as mentioned in the AI summary
echo "Checking DONATION_STATUS enum:"
rg -A 15 "enum DONATION_STATUS" --type ts

Length of output: 114


I'll need to verify that the DONATION_STATUS enum (or equivalent) is defined in the codebase since the initial rg command returned no output. To gather more conclusive information, please run the following shell script to search for any reference to DONATION_STATUS in all TypeScript files:

Once we have the output from this search, we can be more confident about the need (or not) to adjust the transaction management and type safety improvements suggested in the review comment.


🏁 Script executed:

#!/bin/bash
# Searching for all occurrences of DONATION_STATUS in the codebase
rg -n "DONATION_STATUS" --type ts

Length of output: 27186


Action Required: Enhance Type Safety and Ensure Atomic Updates

Please update the function as follows to address two concerns:

  • Type Safety: Replace the any type for swapStatus by defining a dedicated interface (e.g., SwapStatus) that explicitly declares the expected fields.
  • Transaction Management: Since the function updates both the swap and its associated donation, wrap these operations in a transaction. This ensures that inconsistent data won’t be left in the database if one of the operations fails.

Below is the suggested diff snippet:

+ interface SwapStatus {
+   secondTxHash: string;
+   toAmount: number;
+   squidTransactionStatus: string;
+ }
 
- export const updateSwapDonationStatus = async (
-   swapId: number,
-   swapStatus: any,
- ): Promise<void> => {
+ export const updateSwapDonationStatus = async (
+   swapId: number,
+   swapStatus: SwapStatus,
+ ): Promise<void> => {
+   const queryRunner = SwapTransaction.getRepository().manager.connection.createQueryRunner();
+   
+   await queryRunner.connect();
+   await queryRunner.startTransaction();
+   
+   try {
      const swap = await getSwapById(swapId);
      if (!swap) {
        throw new Error(`Swap with id ${swapId} not found`);
      }
 
      swap.secondTxHash = swapStatus.secondTxHash;
      swap.toAmount = swapStatus.toAmount;
      swap.status = swapStatus.squidTransactionStatus;
      await swap.save();
 
      if (swap.donation) {
        swap.donation.status = DONATION_STATUS.PENDING;
        swap.donation.transactionId = swapStatus.secondTxHash;
        await swap.donation.save();
      }
+     
+     await queryRunner.commitTransaction();
+   } catch (error) {
+     await queryRunner.rollbackTransaction();
+     throw error;
+   } finally {
+     await queryRunner.release();
+   }
};

Please ensure that the transaction is created from the correct repository/manager and that all operations inside the transaction behave as expected.

📝 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 const updateSwapDonationStatus = async (
swapId: number,
swapStatus: any,
): Promise<void> => {
const swap = await getSwapById(swapId);
if (!swap) {
throw new Error(`Swap with id ${swapId} not found`);
}
swap.secondTxHash = swapStatus.secondTxHash;
swap.toAmount = swapStatus.toAmount;
swap.status = swapStatus.squidTransactionStatus;
await swap.save();
if (swap.donation) {
swap.donation.status = DONATION_STATUS.PENDING;
swap.donation.transactionId = swapStatus.secondTxHash;
await swap.donation.save();
}
};
interface SwapStatus {
secondTxHash: string;
toAmount: number;
squidTransactionStatus: string;
}
export const updateSwapDonationStatus = async (
swapId: number,
swapStatus: SwapStatus,
): Promise<void> => {
const queryRunner = SwapTransaction.getRepository().manager.connection.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
const swap = await getSwapById(swapId);
if (!swap) {
throw new Error(`Swap with id ${swapId} not found`);
}
swap.secondTxHash = swapStatus.secondTxHash;
swap.toAmount = swapStatus.toAmount;
swap.status = swapStatus.squidTransactionStatus;
await swap.save();
if (swap.donation) {
swap.donation.status = DONATION_STATUS.PENDING;
swap.donation.transactionId = swapStatus.secondTxHash;
await swap.donation.save();
}
await queryRunner.commitTransaction();
} catch (error) {
await queryRunner.rollbackTransaction();
throw error;
} finally {
await queryRunner.release();
}
};

Copy link

@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

🧹 Nitpick comments (1)
.env.template (1)

3-4: Clarify DOCKER_IMAGE Tag Usage.
The DOCKER_IMAGE variable on line 3 now specifies the staging image (ghcr.io/generalmagicio/qacc-be:staging) and includes a comment with the production image tag. Please ensure that the staging value is intentional and that deployment scripts or environments are configured accordingly.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f189be4 and e48cd25.

📒 Files selected for processing (7)
  • src/repositories/swapRepository.ts (1 hunks)
  • src/services/cronJobs/syncSwapTransactions.ts (1 hunks)
  • src/services/squidService.ts (1 hunks)
  • .env.template (1 hunks)
  • src/repositories/swapRepository.ts (1 hunks)
  • src/services/cronJobs/syncSwapTransactions.ts (1 hunks)
  • src/services/squidService.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/services/cronJobs/syncSwapTransactions.ts
  • src/services/squidService.ts
  • src/services/cronJobs/syncSwapTransactions.ts
  • src/repositories/swapRepository.ts
  • src/repositories/swapRepository.ts
🔇 Additional comments (3)
.env.template (1)

5-5: Addition of SQUID_INTEGRATOR_ID.
The new environment variable SQUID_INTEGRATOR_ID="1234567890" is clearly added with an explanatory comment. Verify that the placeholder value is updated appropriately for production or testing environments as needed.

src/services/squidService.ts (2)

6-91: Good addition of type definitions for improved type safety!

The addition of these interfaces (ChainData, ChainInfo, TimeSpent, and SquidStatusResponse) brings much-needed type safety to the Squid API integration. This will help catch type-related issues at compile time rather than runtime.

Small suggestions:

  1. Consider adding JSDoc comments to these interfaces to document their purpose and usage
  2. The error field in SquidStatusResponse uses Record<string, any> which is very permissive - if the error structure is predictable, consider defining a more specific interface

98-100: Great improvement to the function signature!

Adding the return type Promise<SquidStatusResponse> to the getStatus function and properly typing the axios request improves type safety and makes the code more self-documenting.

Copy link
Collaborator

@lovelgeorge99 lovelgeorge99 left a comment

Choose a reason for hiding this comment

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

Thanks @ae2079

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