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

Feat: stellar integration #1753

Merged
merged 15 commits into from
Aug 12, 2024
Merged

Feat: stellar integration #1753

merged 15 commits into from
Aug 12, 2024

Conversation

Meriem-BM
Copy link
Collaborator

@Meriem-BM Meriem-BM commented Aug 7, 2024

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Added support for the Stellar blockchain, including network integration and token management.
    • Introduced new fields in donation and draft donation entities for enhanced tracking and metadata.
    • Enhanced donation and draft donation functionality with additional methods for managing statuses and metadata.
    • Improved wallet address validation with support for Stellar addresses.
    • Added new environment variables to enable Stellar API connectivity.
  • Bug Fixes

    • Improved error handling for donation-related functions and queries, enhancing robustness.
  • Documentation

    • Updated localization files to include new messages related to Stellar support.

Related to #1691 #1690 #1689 #1688

Copy link
Contributor

coderabbitai bot commented Aug 7, 2024

Warning

Rate limit exceeded

@Meriem-BM has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 19 minutes and 30 seconds before requesting another review.

How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

Commits

Files that changed from the base of the PR and between 12bcb3a and 92b0319.

Walkthrough

This update enriches the project by integrating Stellar blockchain functionalities. Key enhancements include new environment variables for Stellar API access, expanded data structures for managing tokens and donations, and improved functionalities for handling QR donations. These changes streamline interactions with the Stellar network and enhance the application's overall capability to manage diverse donation scenarios.

Changes

File(s) Change Summary
config/... Added STELLAR_HORIZON_API_URL and STELLAR_SCAN_API_URL for Stellar API connectivity.
migration/... Introduced new properties like isQR in ITokenData and a memo field in project address functions.
src/provider.ts, src/utils/validators/... Updated to support Stellar network IDs and added validation for Stellar wallet addresses.
src/repositories/..., src/resolvers/... Enhanced repository functions and resolvers to handle new fields and improve GraphQL queries for donations.
src/utils/errorMessages.ts, src/utils/locales/... Added new error message constants and localization entries for Stellar-related errors.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant DonationResolver
    participant ProjectAddressRepository
    participant StellarAPI

    User->>DonationResolver: Create Donation
    DonationResolver->>ProjectAddressRepository: Add Project Address with details
    ProjectAddressRepository->>StellarAPI: Verify transaction
    StellarAPI-->>ProjectAddressRepository: Transaction result
    ProjectAddressRepository-->>DonationResolver: Donation creation result
    DonationResolver-->>User: Response with donation status
Loading

🐰 In fields of code, I leap and bound,
New features sprout from the ground.
Stellar shines with tokens bright,
Donations dance in the moonlight.
With every hop, our app does grow,
Hooray for changes! Let’s all go! 🌟


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 as 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.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

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: 2

Outside diff range, codebase verification and nitpick comments (13)
src/types/network.ts (1)

4-4: Add a trailing comma for consistency.

To maintain consistency with the existing enum values, add a trailing comma after the STELLAR value.

-  STELLAR = 'STELLAR'
+  STELLAR = 'STELLAR',
migration/1722379846122-AddMemoToProjectAddressFields.ts (7)

1-1: Use single quotes for consistency.

Replace double quotes with single quotes to maintain consistency with common TypeScript/JavaScript practices.

-import { MigrationInterface, QueryRunner } from "typeorm";
+import { MigrationInterface, QueryRunner } from 'typeorm';
Tools
GitHub Check: test

[failure] 1-1:
Replace "typeorm" with 'typeorm'


3-3: Format the class declaration for better readability.

Add line breaks around the implements MigrationInterface for better readability.

-export class AddMemoToProjectAddressFields1722379846122 implements MigrationInterface {
+export class AddMemoToProjectAddressFields1722379846122
+  implements MigrationInterface
+{
Tools
GitHub Check: test

[failure] 3-3:
Replace ·implements·MigrationInterface· with ⏎··implements·MigrationInterface⏎


4-4: Remove unnecessary blank line.

Remove the unnecessary blank line for better readability.

-
Tools
GitHub Check: test

[failure] 4-4:
Delete ⏎··


6-6: Format the query for better readability.

Format the query to improve readability.

-        await queryRunner.query(`ALTER TABLE "project_address" ADD COLUMN IF NOT EXISTS "memo" VARCHAR`);
+        await queryRunner.query(
+            `ALTER TABLE "project_address" ADD COLUMN IF NOT EXISTS "memo" VARCHAR`
+        );
Tools
GitHub Check: test

[failure] 6-6:
Replace ········await·queryRunner.query(ALTER·TABLE·"project_address"·ADD·COLUMN·IF·NOT·EXISTS·"memo"·VARCHAR`` with ····await·queryRunner.query(⏎······ALTER·TABLE·"project_address"·ADD·COLUMN·IF·NOT·EXISTS·"memo"·VARCHAR`,⏎····`


7-7: Reduce indentation level.

Reduce the indentation level to match the surrounding code.

-        
Tools
GitHub Check: test

[failure] 7-7:
Replace ···· with ··


9-9: Remove unnecessary blank line.

Remove the unnecessary blank line for better readability.

-
Tools
GitHub Check: test

[failure] 9-9:
Delete ··


10-11: Format the query for better readability.

Format the query to improve readability.

-        await queryRunner.query(`ALTER TABLE "project_address" DROP COLUMN IF EXISTS "memo"`);
+        await queryRunner.query(
+            `ALTER TABLE "project_address" DROP COLUMN IF EXISTS "memo"`
+        );
Tools
GitHub Check: test

[failure] 10-10:
Replace ····await·queryRunner.query(ALTER·TABLE·"project_address"·DROP·COLUMN·IF·EXISTS·"memo"); with await·queryRunner.query(⏎······ALTER·TABLE·"project_address"·DROP·COLUMN·IF·EXISTS·"memo",


[failure] 11-11:
Replace ·· with ····);⏎

migration/1723025859680-AddExpirationDateToDraftDonation.ts (2)

1-1: Use single quotes for consistency.

Replace double quotes with single quotes to maintain consistency with common TypeScript/JavaScript practices.

-import { MigrationInterface, QueryRunner } from "typeorm";
+import { MigrationInterface, QueryRunner } from 'typeorm';
Tools
GitHub Check: test

[failure] 1-1:
Replace "typeorm" with 'typeorm'


3-3: Format the class declaration for better readability.

Add line breaks around the implements MigrationInterface for better readability.

-export class AddExpirationDateToDraftDonation1723025859680 implements MigrationInterface {
+export class AddExpirationDateToDraftDonation1723025859680
+  implements MigrationInterface
+{
Tools
GitHub Check: test

[failure] 3-3:
Replace ·implements·MigrationInterface· with ⏎··implements·MigrationInterface⏎

src/repositories/draftDonationRepository.ts (1)

Line range hint 27-39:
Fix typographical error in function name.

The function name delecteExpiredDraftDonations should be corrected to deleteExpiredDraftDonations.

- export async function delecteExpiredDraftDonations(hours: number) {
+ export async function deleteExpiredDraftDonations(hours: number) {
src/utils/errorMessages.ts (1)

203-203: Add a period at the end of the error message.

For consistency with other error messages, add a period at the end.

-  DRAFT_DONATION_NOT_FOUND: 'Draft donation not found'
+  DRAFT_DONATION_NOT_FOUND: 'Draft donation not found.'
src/resolvers/projectResolver.ts (1)

2203-2220: Ensure proper error handling and logging.

The getTokensDetails function includes error handling and logging. However, it is not currently tested. Please add tests to ensure the function's correctness and reliability.

  • The function is defined in src/resolvers/projectResolver.ts and is not used or tested elsewhere in the codebase.
Analysis chain

Ensure proper error handling and logging.

The getTokensDetails function includes error handling and logging. Ensure that the error handling and logging are implemented correctly.

However, ensure that this function is tested thoroughly.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the `getTokensDetails` function is tested.

# Test: Search for the `getTokensDetails` function usage in the test files. Expect: The function is tested.
rg --type typescript -A 5 $'getTokensDetails'

Length of output: 79


Script:

#!/bin/bash
# Description: Verify the `getTokensDetails` function is tested.

# Test: Search for the `getTokensDetails` function usage in the test files. Expect: The function is tested.
rg --type ts -A 5 'getTokensDetails' --glob '*test*'

Length of output: 52


Script:

#!/bin/bash
# Description: Verify the `getTokensDetails` function is defined and used in the codebase.

# Search for the `getTokensDetails` function definition.
rg --type ts 'async getTokensDetails'

# Search for the `getTokensDetails` function usage across the entire codebase.
rg --type ts 'getTokensDetails'

Length of output: 271

Comment on lines 1069 to 1074
@Query(_returns => Donation, { nullable: true })
async getDonationById(
@Arg('id', _type => Int) id: number,
): Promise<Donation | null> {
return findDonationById(id);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Ensure proper error handling in getDonationById method.

The method getDonationById does not handle the case where the donation is not found. Consider adding error handling to provide a more informative response.

-  async getDonationById(
-    @Arg('id', _type => Int) id: number,
-  ): Promise<Donation | null> {
-    return findDonationById(id);
-  }
+  async getDonationById(
+    @Arg('id', _type => Int) id: number,
+  ): Promise<Donation | null> {
+    const donation = await findDonationById(id);
+    if (!donation) {
+      throw new Error(i18n.__(translationErrorMessagesKeys.DONATION_NOT_FOUND));
+    }
+    return donation;
+  }
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
@Query(_returns => Donation, { nullable: true })
async getDonationById(
@Arg('id', _type => Int) id: number,
): Promise<Donation | null> {
return findDonationById(id);
}
@Query(_returns => Donation, { nullable: true })
async getDonationById(
@Arg('id', _type => Int) id: number,
): Promise<Donation | null> {
const donation = await findDonationById(id);
if (!donation) {
throw new Error(i18n.__(translationErrorMessagesKeys.DONATION_NOT_FOUND));
}
return donation;
}

Comment on lines +134 to +147
switch: [
{
is: ChainType.SOLANA,
then: Joi.string().pattern(solanaProgramIdRegex),
},
{
is: ChainType.STELLAR,
then: Joi.string().pattern(stellarWalletAddressRegex),
},
{
is: ChainType.EVM,
then: Joi.string().pattern(ethereumWalletAddressRegex),
},
],
Copy link
Contributor

Choose a reason for hiding this comment

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

Fix the use of then within the switch statement.

Static analysis tools flagged the use of then within the switch statement. Replace then with appropriate conditional logic.

-    switch: [
-      {
-        is: ChainType.SOLANA,
-        then: Joi.string().pattern(solanaProgramIdRegex),
-      },
-      {
-        is: ChainType.STELLAR,
-        then: Joi.string().pattern(stellarWalletAddressRegex),
-      },
-      {
-        is: ChainType.EVM,
-        then: Joi.string().pattern(ethereumWalletAddressRegex),
-      },
-    ],
+    is: Joi.alternatives().try(
+      { is: ChainType.SOLANA, then: Joi.string().pattern(solanaProgramIdRegex) },
+      { is: ChainType.STELLAR, then: Joi.string().pattern(stellarWalletAddressRegex) },
+      { is: ChainType.EVM, then: Joi.string().pattern(ethereumWalletAddressRegex) }
+    ),
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
switch: [
{
is: ChainType.SOLANA,
then: Joi.string().pattern(solanaProgramIdRegex),
},
{
is: ChainType.STELLAR,
then: Joi.string().pattern(stellarWalletAddressRegex),
},
{
is: ChainType.EVM,
then: Joi.string().pattern(ethereumWalletAddressRegex),
},
],
is: Joi.alternatives().try(
{ is: ChainType.SOLANA, then: Joi.string().pattern(solanaProgramIdRegex) },
{ is: ChainType.STELLAR, then: Joi.string().pattern(stellarWalletAddressRegex) },
{ is: ChainType.EVM, then: Joi.string().pattern(ethereumWalletAddressRegex) }
),
Tools
Biome

[error] 137-137: Do not add then to an object.

(lint/suspicious/noThenProperty)


[error] 141-141: Do not add then to an object.

(lint/suspicious/noThenProperty)


[error] 145-145: Do not add then to an object.

(lint/suspicious/noThenProperty)

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

isTokenEligibleForGivback: token.isGivbackEligible,
segmentNotified: false,
toWalletAddress: donation.toWalletAddress,
donationAnonymous: donation.userId ? false : true,
Copy link
Contributor

Choose a reason for hiding this comment

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

Simplify boolean assignment.

The use of a ternary operator to assign a boolean value can be simplified.

- donationAnonymous: donation.userId ? false : true,
+ donationAnonymous: !donation.userId,
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
donationAnonymous: donation.userId ? false : true,
donationAnonymous: !donation.userId,
Tools
Biome

[error] 101-101: 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)

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

Outside diff range, codebase verification and nitpick comments (1)
src/resolvers/projectResolver.ts (1)

Unused Function Detected: getTokensDetails

The getTokensDetails function in src/resolvers/projectResolver.ts does not appear to be used anywhere in the codebase. Please verify whether this function is necessary or if its usage is planned for future implementation.

  • Location: src/resolvers/projectResolver.ts
Analysis chain

Line range hint 225-242: LGTM! Verify usage of getTokensDetails.

The getTokensDetails method is well-implemented with appropriate error handling and logging.

Ensure that its usage is consistent across the codebase.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify all function calls to `getTokensDetails`.

# Test: Search for the function usage. Expect: Consistent usage across the codebase.
rg --type typescript -A 5 $'getTokensDetails'

Length of output: 79


Script:

#!/bin/bash
# Description: Verify all function calls to `getTokensDetails`.

# Test: Search for the function usage. Expect: Consistent usage across the codebase.
rg --type ts -A 5 $'getTokensDetails'

Length of output: 656

Copy link
Collaborator

@mohammadranjbarz mohammadranjbarz left a comment

Choose a reason for hiding this comment

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

Thanks @Meriem-BM for implementing this big PR
I just left some comments for you, would appreciate it if you can apply them

src/provider.ts Outdated Show resolved Hide resolved
src/resolvers/draftDonationResolver.ts Show resolved Hide resolved
Comment on lines +385 to +388
async renewDraftDonationExpirationDate(
@Arg('id', _type => Int) id: number,
): Promise<DraftDonation | null> {
try {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Dont need any restriction?

Comment on lines 1069 to 1074
@Query(_returns => Donation, { nullable: true })
async getDonationById(
@Arg('id', _type => Int) id: number,
): Promise<Donation | null> {
return findDonationById(id);
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please add test cases for this endpoint

Comment on lines +59 to +62
@Arg('toWalletMemo', { nullable: true }) toWalletMemo?: string,
@Arg('qrCodeDataUrl', { nullable: true }) qrCodeDataUrl?: string,
@Arg('isQRDonation', { nullable: true, defaultValue: false })
isQRDonation?: boolean,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please add more test cases for this endpoint to cover new conditions like passing these enw params

Comment on lines +558 to +560
case FilterField.AcceptFundOnStellar:
acceptFundOnStellarSeen = true;
return;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please a test case to cover this filter condition

@@ -2197,4 +2221,23 @@ export class ProjectResolver {
throw error;
}
}

@Query(_returns => Token)
async getTokensDetails(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please add test cases for this new endpoint

@@ -18,6 +19,9 @@ export const isEvmAddress = (address: string): boolean => {
return ethers.utils.isAddress(address);
};

export const isStellarAddress = (address: string): boolean =>
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please add some unit tests for this function

Comment on lines +33 to +34
case isStellarAddress(address):
return ChainType.STELLAR;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Add a test case to cover this condition

};

// Check for transactions
async function checkTransactions(donation: DraftDonation): Promise<void> {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is it possible to write a test case for this funciton?

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

Outside diff range, codebase verification and nitpick comments (1)
test/graphqlQueries.ts (1)

55-59: Consider documenting new parameters in createDraftDonationMutation.

The new parameters $useDonationBox, $relevantDonationTxHash, $toWalletMemo, $qrCodeDataUrl, and $isQRDonation enhance the mutation's functionality. Ensure these parameters are documented to clarify their purpose and usage.

Comment on lines +1069 to +1078
@Query(_returns => Donation, { nullable: true })
async getDonationById(
@Arg('id', _type => Int) id: number,
): Promise<Donation | null> {
try {
return findDonationById(id);
} catch (e) {
return null;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Ensure proper error handling in getDonationById method.

The method getDonationById lacks error handling for cases where the donation is not found. Consider adding error handling to provide a more informative response.

  async getDonationById(
    @Arg('id', _type => Int) id: number,
  ): Promise<Donation | null> {
    try {
      const donation = await findDonationById(id);
      if (!donation) {
        throw new Error(i18n.__(translationErrorMessagesKeys.DONATION_NOT_FOUND));
      }
      return donation;
    } catch (e) {
      logger.error('getDonationById error', e);
      throw e;
    }
  }
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
@Query(_returns => Donation, { nullable: true })
async getDonationById(
@Arg('id', _type => Int) id: number,
): Promise<Donation | null> {
try {
return findDonationById(id);
} catch (e) {
return null;
}
}
@Query(_returns => Donation, { nullable: true })
async getDonationById(
@Arg('id', _type => Int) id: number,
): Promise<Donation | null> {
try {
const donation = await findDonationById(id);
if (!donation) {
throw new Error(i18n.__(translationErrorMessagesKeys.DONATION_NOT_FOUND));
}
return donation;
} catch (e) {
logger.error('getDonationById error', e);
throw e;
}
}

@Meriem-BM Meriem-BM merged commit aea8862 into staging Aug 12, 2024
5 checks passed
@Meriem-BM Meriem-BM deleted the feat/stellar_integration branch August 12, 2024 22:26
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