-
Notifications
You must be signed in to change notification settings - Fork 18
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
Conversation
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 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. WalkthroughThis 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
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
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? TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Additionally, you can add CodeRabbit Configuration File (
|
There was a problem hiding this 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");
withawait·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 todeleteExpiredDraftDonations
.- 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
src/resolvers/donationResolver.ts
Outdated
@Query(_returns => Donation, { nullable: true }) | ||
async getDonationById( | ||
@Arg('id', _type => Int) id: number, | ||
): Promise<Donation | null> { | ||
return findDonationById(id); | ||
} |
There was a problem hiding this comment.
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.
@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; | |
} |
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), | ||
}, | ||
], |
There was a problem hiding this comment.
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.
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)
…raph into feat/stellar_integration
There was a problem hiding this 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, |
There was a problem hiding this comment.
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.
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)
There was a problem hiding this 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 insrc/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 ofgetTokensDetails
.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
There was a problem hiding this 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
async renewDraftDonationExpirationDate( | ||
@Arg('id', _type => Int) id: number, | ||
): Promise<DraftDonation | null> { | ||
try { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dont need any restriction?
src/resolvers/donationResolver.ts
Outdated
@Query(_returns => Donation, { nullable: true }) | ||
async getDonationById( | ||
@Arg('id', _type => Int) id: number, | ||
): Promise<Donation | null> { | ||
return findDonationById(id); | ||
} |
There was a problem hiding this comment.
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
@Arg('toWalletMemo', { nullable: true }) toWalletMemo?: string, | ||
@Arg('qrCodeDataUrl', { nullable: true }) qrCodeDataUrl?: string, | ||
@Arg('isQRDonation', { nullable: true, defaultValue: false }) | ||
isQRDonation?: boolean, |
There was a problem hiding this comment.
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
case FilterField.AcceptFundOnStellar: | ||
acceptFundOnStellarSeen = true; | ||
return; |
There was a problem hiding this comment.
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( |
There was a problem hiding this comment.
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 => |
There was a problem hiding this comment.
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
case isStellarAddress(address): | ||
return ChainType.STELLAR; |
There was a problem hiding this comment.
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> { |
There was a problem hiding this comment.
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?
There was a problem hiding this 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 increateDraftDonationMutation
.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.
@Query(_returns => Donation, { nullable: true }) | ||
async getDonationById( | ||
@Arg('id', _type => Int) id: number, | ||
): Promise<Donation | null> { | ||
try { | ||
return findDonationById(id); | ||
} catch (e) { | ||
return null; | ||
} | ||
} |
There was a problem hiding this comment.
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.
@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; | |
} | |
} |
…raph into feat/stellar_integration
Summary by CodeRabbit
Summary by CodeRabbit
New Features
Bug Fixes
Documentation
Related to #1691 #1690 #1689 #1688