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

Superfluid Base Support #1893

Merged
merged 5 commits into from
Dec 17, 2024
Merged

Superfluid Base Support #1893

merged 5 commits into from
Dec 17, 2024

Conversation

CarlosQ96
Copy link
Collaborator

@CarlosQ96 CarlosQ96 commented Dec 16, 2024

Related to: #1879. (superfluid endpoints)

Related to: #1883 (Filters and account balance)

Related to: #1878 (verifying donations)

Summary by CodeRabbit

  • New Features

    • Introduced a new RecurringDonationEligibleProject class for managing donation eligibility.
    • Added a new method to fetch eligible recurring donation projects based on network ID.
    • Expanded token definitions with new entries, including "Coinbase Wrapped BTC" and a structured base for super tokens.
  • Bug Fixes

    • Enhanced error handling for fetching eligible projects.
  • Tests

    • Added a new test suite for verifying eligible recurring donation projects.
    • Commented out specific test cases related to transaction details for various networks.
  • Chores

    • Updated logic for handling super token balances based on network IDs.
    • Streamlined network ID handling in donation creation logic.

@CarlosQ96 CarlosQ96 changed the title Finish project endpoint for superfluid to read (wip) Superfluid Base Support (wip) Dec 16, 2024
@CarlosQ96 CarlosQ96 marked this pull request as ready for review December 16, 2024 21:58
Copy link
Contributor

coderabbitai bot commented Dec 16, 2024

Walkthrough

This pull request introduces enhancements to several files related to recurring donations and token management. The changes primarily focus on expanding super token definitions, improving network ID handling, and adding a new method to retrieve eligible recurring donation projects. The modifications span across multiple services and resolvers, introducing more flexible token and network-specific logic while maintaining the existing code structure.

Changes

File Change Summary
src/provider.ts - Added new DEGENx entry to superTokensToToken
- Introduced superTokensBase with expanded super token definitions
src/resolvers/recurringDonationResolver.ts - Added RecurringDonationEligibleProject class
- Implemented recurringDonationEligibleProjects query method
- Updated methods to support networkId filtering
src/resolvers/recurringDonationResolver.test.ts - Added new test suite for recurringDonationEligibleProjects
src/services/cronJobs/checkUserSuperTokenBalancesQueue.ts - Updated imports to include NETWORK_IDS and superTokensBase
- Modified super token data selection logic based on network ID
src/services/recurringDonationService.ts - Added networkId variable handling
- Removed environment-based network ID logic
migration/data/seedTokens.ts - Added new token entry for "Coinbase Wrapped BTC"
src/services/chains/index.test.ts - Commented out specific test cases related to transaction details for various networks

Possibly related PRs

  • Add base chain #1579: The changes in src/provider.ts regarding the addition of new network IDs for BASE_MAINNET and BASE_SEPOLIA are directly related to the modifications in the main PR, which also involves expanding token definitions and managing super tokens based on network IDs.

Suggested reviewers

  • Meriem-BM
  • mohammadranjbarz

Poem

🐰 Tokens dance, networks align,
Donations flow with design divine,
Super tokens spread their might,
Recurring gifts take graceful flight,
Code rabbit hops with pure delight! 🌈

Tip

CodeRabbit's docstrings feature is now available as part of our Early Access Program! Simply use the command @coderabbitai generate docstrings to have CodeRabbit automatically generate docstrings for your pull request. We would love to hear your feedback on Discord.


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>, 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. (Beta)
  • @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
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

🧹 Nitpick comments (8)
src/services/cronJobs/checkUserSuperTokenBalancesQueue.ts (1)

120-133: Simplify redundant assignment of superTokenDataArray

Since superTokenDataArray is already initialized to superTokens, reassigning it in the else if block is redundant. You can simplify the code by removing the redundant assignment.

Apply this diff to simplify the code:

 let superTokenDataArray = superTokens;

 if (
   recurringDonation.networkId === NETWORK_IDS.BASE_SEPOLIA ||
   recurringDonation.networkId === NETWORK_IDS.BASE_MAINNET
 ) {
   superTokenDataArray = superTokensBase;
- } else if (
-   recurringDonation.networkId === NETWORK_IDS.OPTIMISM_SEPOLIA ||
-   recurringDonation.networkId === NETWORK_IDS.OPTIMISTIC
- ) {
-   superTokenDataArray = superTokens;
 }
src/resolvers/recurringDonationResolver.test.ts (7)

32-35: Test suite needs additional test cases.

While the basic happy path is covered, consider adding test cases for:

  • Error scenarios (e.g., invalid network IDs)
  • Edge cases (e.g., projects with no anchor contracts)
  • Pagination and filtering capabilities

71-148: Consider improving test data setup and assertions.

The test case could be improved in several ways:

  1. Use descriptive variable names instead of generic ones (e.g., optimisticAnchorContract instead of anchorContractAddress)
  2. Add assertions for the isActive field of anchor contracts
  3. Consider testing the ordering of returned anchor contracts

Here's a suggested refactor:

- const anchorContractAddress = await addNewAnchorAddress({
+ const optimisticAnchorContract = await addNewAnchorAddress({
   project,
   owner: projectOwner,
   creator: projectOwner,
   address: generateRandomEtheriumAddress(),
   networkId: NETWORK_IDS.OPTIMISTIC,
   txHash: generateRandomEvmTxHash(),
 });

- const anchorContractAddressBASE = await addNewAnchorAddress({
+ const baseAnchorContract = await addNewAnchorAddress({
   project,
   owner: projectOwner,
   creator: projectOwner,
   address: generateRandomEtheriumAddress(),
   networkId: NETWORK_IDS.BASE_MAINNET,
   txHash: generateRandomEvmTxHash(),
 });

 // Add assertions for isActive field
+ assert.isTrue(optimisticContract.isActive, 'Optimistic contract should be active');
+ assert.isTrue(baseContract.isActive, 'BASE contract should be active');

149-149: Add validation test cases for recurring donation creation.

Consider adding test cases for:

  1. Invalid currency validation
  2. Invalid flowRate validation (negative values, zero, extremely large values)
  3. Network-specific validations for Superfluid tokens

Line range hint 1893-1893: Add concurrency test cases for recurring donation updates.

Consider adding test cases for:

  1. Concurrent updates to the same donation
  2. Partial updates (updating only specific fields)
  3. State transition validations (e.g., can't archive an active donation)

Line range hint 2071-2071: Enhance query test coverage.

Consider adding test cases for:

  1. Complex filter combinations (e.g., multiple networks + status + date range)
  2. Edge cases in sorting (null values, same values)
  3. Performance testing with large result sets

Line range hint 2489-2489: Add comprehensive status transition test cases.

Consider adding test cases for:

  1. All possible status transitions (create a transition matrix)
  2. Invalid status transitions
  3. Status updates with invalid permissions

Line range hint 1-31: Consider adding test documentation and improving error assertions.

  1. Add JSDoc comments for each test suite describing:
    • Purpose of the test suite
    • Test scenarios covered
    • Expected behaviors
  2. Use consistent error message assertions:
    • Create constants for expected error messages
    • Add type checking for error responses

Example documentation:

/**
 * Test suite for recurring donation eligible projects
 * 
 * Scenarios covered:
 * - Fetching projects with anchor contracts
 * - Multi-network support (OPTIMISTIC, BASE_MAINNET)
 * - Error cases
 * 
 * Expected behavior:
 * - Returns projects with active anchor contracts
 * - Includes network-specific contract addresses
 * - Properly handles error cases
 */
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between d12453d and 86fbca9.

📒 Files selected for processing (5)
  • src/provider.ts (1 hunks)
  • src/resolvers/recurringDonationResolver.test.ts (2 hunks)
  • src/resolvers/recurringDonationResolver.ts (8 hunks)
  • src/services/cronJobs/checkUserSuperTokenBalancesQueue.ts (2 hunks)
  • src/services/recurringDonationService.ts (1 hunks)
🔇 Additional comments (4)
src/resolvers/recurringDonationResolver.ts (1)

59-75: Proper definition of RecurringDonationEligibleProject class

The new RecurringDonationEligibleProject class is correctly defined with the necessary fields and appropriate decorators.

src/provider.ts (2)

45-46: Addition of 'DEGENx' mapping in superTokensToToken

The mapping for DEGENx to DEGEN has been correctly added to superTokensToToken.


49-114: New superTokensBase array correctly defined

The superTokensBase array has been properly defined with the necessary token details, including underlying tokens and their properties.

src/services/recurringDonationService.ts (1)

124-129: Verify the necessity of changing networkId from BASE_SEPOLIA to BASE_MAINNET

Ensure that overwriting networkId from BASE_SEPOLIA to BASE_MAINNET is appropriate and does not affect the logic elsewhere in the function or other parts of the code that rely on the original networkId value.

src/resolvers/recurringDonationResolver.ts Outdated Show resolved Hide resolved
Copy link
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

🧹 Nitpick comments (4)
src/resolvers/recurringDonationResolver.ts (4)

493-497: Consider extracting common filtering logic

The network and token filtering logic is duplicated across multiple queries. Consider extracting this into a reusable helper method to improve maintainability.

Example implementation:

private addNetworkAndTokenFilters(
  query: SelectQueryBuilder<RecurringDonation>,
  networkId?: number,
  filteredTokens?: string[]
): void {
  if (filteredTokens?.length > 0) {
    query.andWhere(`recurringDonation.currency IN (:...filteredTokens)`, {
      filteredTokens,
    });
  }

  if (networkId) {
    query.andWhere(`recurringDonation.networkId = :networkId`, {
      networkId,
    });
  }
}

This helper method can then be used in all queries:

this.addNetworkAndTokenFilters(query, networkId, filteredTokens);

Also applies to: 527-531, 665-669


760-763: Add validation for pagination parameters

Consider adding validation for page and limit parameters to ensure they are positive numbers and that limit has a reasonable maximum value.

@Min(1)
@Field(_type => Int, { nullable: true, defaultValue: 1 })
page: number = 1;

@Min(1)
@Max(100)
@Field(_type => Int, { nullable: true, defaultValue: 50 })
limit: number = 50;

797-799: Improve error message specificity

The current error message is too generic. Consider providing more specific error information while still maintaining security.

- throw new Error(
-   `Error fetching eligible projects for donation: ${error}`,
- );
+ throw new Error(
+   'Failed to fetch eligible projects. Please try again later or contact support if the issue persists.'
+ );

777-795: Improve SQL query formatting for better readability

The SQL query could be better formatted for readability. Also, consider adding a comment explaining the query's purpose.

+ // Fetch GivBack eligible projects with active anchor contracts
+ // Returns project details along with their associated anchor contract information
  return await Project.getRepository().query(`
    SELECT 
      project.id,
      project.slug,
      project.title,
      array_agg(json_build_object(
        'address', anchor_contract_address.address,
        'networkId', anchor_contract_address."networkId",
        'isActive', anchor_contract_address."isActive"
      )) as "anchorContracts"
    FROM project
    INNER JOIN anchor_contract_address 
      ON project.id = anchor_contract_address."projectId"
    WHERE project."isGivbackEligible" = true
      AND anchor_contract_address."isActive" = true
      ${networkFilter}
    GROUP BY 
      project.id, 
      project.slug, 
      project.title
    OFFSET $1
    LIMIT $2
  `, queryParams);
🧰 Tools
🪛 eslint

[error] 777-777: Insert ⏎········

(prettier/prettier)


[error] 795-795: Replace ·queryParams with ⏎········queryParams,⏎······

(prettier/prettier)

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 86fbca9 and 364cfbc.

📒 Files selected for processing (1)
  • src/resolvers/recurringDonationResolver.ts (8 hunks)
🧰 Additional context used
🪛 eslint
src/resolvers/recurringDonationResolver.ts

[error] 777-777: Insert ⏎········

(prettier/prettier)


[error] 795-795: Replace ·queryParams with ⏎········queryParams,⏎······

(prettier/prettier)

🔇 Additional comments (2)
src/resolvers/recurringDonationResolver.ts (2)

61-74: LGTM: Well-structured class definition

The RecurringDonationEligibleProject class is properly defined with appropriate TypeGraphQL decorators and clear field definitions.


188-189: LGTM: Clean addition of networkId field

The networkId field is properly added to UserRecurringDonationsArgs with correct typing and decoration.

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@CarlosQ96 CarlosQ96 force-pushed the feature_base_support_for_streams branch from 364cfbc to 7b62770 Compare December 16, 2024 22:12
@CarlosQ96 CarlosQ96 changed the title Superfluid Base Support (wip) Superfluid Base Support Dec 16, 2024
Copy link
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

🧹 Nitpick comments (1)
src/resolvers/recurringDonationResolver.ts (1)

757-804: Consider adding pagination metadata to the response.

The recurringDonationEligibleProjects query implementation looks good with proper SQL injection prevention using parameterized queries. However, consider enhancing the response to include pagination metadata (total count, hasNextPage, etc.) to help clients implement pagination controls effectively.

Apply this diff to add pagination metadata:

@ObjectType()
+class RecurringDonationEligibleProjectsResponse {
+  @Field(_type => [RecurringDonationEligibleProject])
+  projects: RecurringDonationEligibleProject[];
+
+  @Field(_type => Int)
+  totalCount: number;
+
+  @Field(_type => Boolean)
+  hasNextPage: boolean;
+}

@Query(_return => [RecurringDonationEligibleProject], { nullable: true })
async recurringDonationEligibleProjects(
  @Arg('networkId', { nullable: true }) networkId?: number,
  @Arg('page', _type => Int, { nullable: true, defaultValue: 1 })
  page: number = 1,
  @Arg('limit', _type => Int, { nullable: true, defaultValue: 50 })
  limit: number = 50,
-): Promise<RecurringDonationEligibleProject[]> {
+): Promise<RecurringDonationEligibleProjectsResponse> {
  try {
    const offset = (page - 1) * limit;

    const queryParams = [offset, limit];
    let networkFilter = '';
    let paramIndex = 3;
    if (networkId) {
      networkFilter = `AND anchor_contract_address."networkId" = $${paramIndex}`;
      queryParams.push(networkId);
      paramIndex++;
    }

+   // Get total count
+   const [{ count }] = await Project.getRepository().query(
+     `
+     SELECT COUNT(DISTINCT project.id) as count
+     FROM project
+     INNER JOIN anchor_contract_address ON project.id = anchor_contract_address."projectId"
+     WHERE project."isGivbackEligible" = true
+       AND anchor_contract_address."isActive" = true
+       ${networkFilter}
+     `,
+     networkId ? [networkId] : [],
+   );

+   const projects = await Project.getRepository().query(
      `
      SELECT 
        project.id,
        project.slug,
        project.title,
        array_agg(json_build_object(
          'address', anchor_contract_address.address,
          'networkId', anchor_contract_address."networkId",
          'isActive', anchor_contract_address."isActive"
        )) as "anchorContracts"
      FROM project
      INNER JOIN anchor_contract_address ON project.id = anchor_contract_address."projectId"
      WHERE project."isGivbackEligible" = true
        AND anchor_contract_address."isActive" = true
        ${networkFilter}
      GROUP BY project.id, project.slug, project.title
      OFFSET $1
      LIMIT $2
    `,
      queryParams,
    );

+   return {
+     projects,
+     totalCount: parseInt(count),
+     hasNextPage: parseInt(count) > offset + limit,
+   };
  } catch (error) {
    throw new Error(
      `Error fetching eligible projects for donation: ${error}`,
    );
  }
}
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 364cfbc and 8b8100d.

📒 Files selected for processing (3)
  • migration/data/seedTokens.ts (1 hunks)
  • src/resolvers/recurringDonationResolver.ts (8 hunks)
  • src/services/chains/index.test.ts (1 hunks)
🔇 Additional comments (8)
migration/data/seedTokens.ts (2)

1698-1707: LGTM! Token configuration is well-structured and complete.

The new cbBTC token entry follows the established pattern and includes all required fields with appropriate values. The configuration is properly documented with the Basescan URL reference.


1702-1705: Verify token contract address and CoinGecko ID.

Let's verify the token configuration against external sources.

✅ Verification successful

Token configuration verified successfully

The verification confirms:

  • CoinGecko ID "coinbase-wrapped-btc" exists and is valid
  • Token address format is correct (0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf)
  • Token symbol on CoinGecko matches (cbBTC)
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify token contract address and CoinGecko ID

# Check if the token exists on CoinGecko
echo "Verifying CoinGecko ID..."
curl -s "https://api.coingecko.com/api/v3/coins/coinbase-wrapped-btc" | jq '.id,.symbol'

# Note: We would typically verify the contract address on Basescan,
# but since we're in a sandbox environment, we'll just check the address format
echo "Verifying address format..."
if [[ "0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf" =~ ^0x[a-fA-F0-9]{40}$ ]]; then
    echo "Address format is valid"
else
    echo "Invalid address format"
fi

Length of output: 374

src/resolvers/recurringDonationResolver.ts (5)

61-74: LGTM! The new class definition is well-structured.

The RecurringDonationEligibleProject class is properly decorated with @ObjectType() and has appropriate field decorators. The class structure aligns well with the PR's objective of supporting Superfluid functionality.


187-189: LGTM! The networkId field addition is appropriate.

The addition of the optional networkId field to UserRecurringDonationsArgs is well-decorated and aligns with the filtering requirements.


434-439: LGTM! The filteredTokens parameter addition is appropriate.

The addition of the filteredTokens parameter with proper defaults and type decorations enhances the filtering capabilities.


493-497: LGTM! The token filtering implementation is correct.

The implementation of token filtering using a parameterized SQL query is secure and efficient.


527-531: LGTM! The network filtering implementation is correct.

The implementation of network filtering using a parameterized SQL query is secure and efficient.

src/services/chains/index.test.ts (1)

600-617: Verify if ZKEVM Cardano test cases should remain commented out.

The test cases for ZKEVM Cardano transactions have been commented out. Please verify if this is intentional and if it impacts the test coverage for the ZKEVM Cardano network support.

Run the following script to check test coverage for ZKEVM Cardano related code:

@CarlosQ96 CarlosQ96 merged commit f0c3fc8 into staging Dec 17, 2024
5 checks passed
@CarlosQ96 CarlosQ96 deleted the feature_base_support_for_streams branch December 17, 2024 00:01
CarlosQ96 added a commit that referenced this pull request Dec 17, 2024
* add includeUnlisted to FilterProjectQueryInputParams

* return proper projects

* add recipient address to streams when nonexistent (#1890)

* Superfluid Base Support (#1893)

* finish project endpoint for superfluid to read

* add filters for network and tokens for recurringdonations

* fix verification logic and emails for base network streams

* Update src/resolvers/recurringDonationResolver.ts

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* comment network test and add cbBTC to seeds

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

---------

Co-authored-by: Cherik <[email protected]>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
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