Skip to content

Fix depositFromBasketCurrency unsupported currency handling and add r…#380

Merged
Junman140 merged 1 commit into
Pi-Defi-world:devfrom
efuncode:feat
Jun 4, 2026
Merged

Fix depositFromBasketCurrency unsupported currency handling and add r…#380
Junman140 merged 1 commit into
Pi-Defi-world:devfrom
efuncode:feat

Conversation

@efuncode

@efuncode efuncode commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

close #281

Summary by CodeRabbit

  • Bug Fixes

    • Enhanced deposit currency validation to properly reject unsupported currencies (e.g., JPY) and provide clearer error messages indicating which currencies are supported.
  • Tests

    • Added test coverage to verify that unsupported deposit currencies are correctly rejected with appropriate error responses.

@drips-wave

drips-wave Bot commented Jun 2, 2026

Copy link
Copy Markdown

@efuncode Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@coderabbitai

coderabbitai Bot commented Jun 2, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR enhances currency validation in the basket deposit controller. The depositBodySchema now validates that provided currencies are either allowed or forbidden-but-accepted, returning a clear 400 error instead of silently accepting unsupported currencies. Error messaging is updated to list allowed currencies, and comprehensive tests verify the new validation behavior.

Changes

Currency Validation Enhancement

Layer / File(s) Summary
Currency validation imports and schema
src/controllers/mintController.ts
Adds FORBIDDEN_DEPOSIT_CURRENCIES to basket config imports and removes duplicate convertLocalToUsd import. Updates depositBodySchema.currency field with uppercase transform and refinement validation that currency exists in either allowed or forbidden deposit currency lists.
Error handling and test coverage
src/controllers/mintController.ts, src/controllers/mintController.test.ts
Updates depositFromBasketCurrency error message to explicitly state provided currency is not supported and lists only the allowed basket currencies. Adds test case verifying that unsupported basket currencies like "JPY" are rejected with 400 AppError containing clear currency validation message.

Possibly related PRs

  • Pi-Defi-world/acbu-backend#351: Overlaps on src/controllers/mintController.ts depositBodySchema and depositFromBasketCurrency validation; adds fintech_tx_id validation and idempotency handling alongside currency validation changes.
  • Pi-Defi-world/acbu-backend#225: Modifies the same depositFromBasketCurrency basket deposit handling for currency validation and conversion before limit checking.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~15 minutes

Poem

🐰 A currency that slipped right through the gate,
now caught by schema's watchful, stricter state.
No silent 503 shall pass today—
A 400 error shows the proper way!
With tests to guard what currencies may stay. ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is minimal and only contains 'close #281' without filling out the provided template structure with summary, scope, and validation information. Fill out the complete template including a detailed summary of changes, selection of scope checkboxes, validation steps performed, and proper issue/PR link formatting.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly indicates the main change: fixing unsupported currency handling in depositFromBasketCurrency and adding a regression test.
Linked Issues check ✅ Passed The code changes directly address issue #281: invalid currency codes now return HTTP 400 instead of reaching the conversion layer, and a regression test was added.
Out of Scope Changes check ✅ Passed All code changes are directly related to fixing unsupported currency validation in depositFromBasketCurrency; duplicate import cleanup is a minor in-scope improvement.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/controllers/mintController.test.ts`:
- Around line 128-148: The test currently expects depositFromBasketCurrency to
call next with an AppError for unsupported currency "JPY", but
depositBodySchema.safeParse fails first and the handler responds with
res.status(400).json(...); update the test to assert the HTTP 400 response
payload (inspect res.status and res.json/mock.calls) for the validation error
instead of reading next.mock.calls, or alternatively move the
unsupported-currency check in depositFromBasketCurrency to run before
depositBodySchema.safeParse so next receives an AppError; refer to
depositFromBasketCurrency, depositBodySchema.safeParse, AppError, and the test
helpers res and next when making the change.

In `@src/controllers/mintController.ts`:
- Around line 265-278: The currency zod schema currently enforces .length(3)
which rejects values like USDC/USDT before your forbidden-vs-allowed logic can
run; remove the .length(3) constraint and keep only normalization/shape rules
(e.g., .string().transform(v => v.toUpperCase())) so safeParse succeeds for 3+
letter codes, then move the allow/forbid decision out of the schema into the
controller flow: after parsing (where safeParse is used) call
depositFromBasketCurrency (or the existing
isAllowedDepositCurrency/isForbiddenDepositCurrency checks) and return the
specific DEPOSIT_ONLY_BASKET_CURRENCIES or INVALID_CURRENCY responses based on
those checks, ensuring BASKET_CURRENCIES and FORBIDDEN_DEPOSIT_CURRENCIES remain
the source of truth.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: cb769657-44aa-4b71-b161-3604a92936ad

📥 Commits

Reviewing files that changed from the base of the PR and between 493d266 and 94434ab.

📒 Files selected for processing (2)
  • src/controllers/mintController.test.ts
  • src/controllers/mintController.ts

Comment on lines +128 to +148
it("rejects unsupported basket deposit currencies with a clear error", async () => {
const res = makeRes();
const next = makeNext();
await depositFromBasketCurrency(
{
apiKey: { id: "key-1", userId: "user-1", organizationId: null, permissions: [], rateLimit: 100 },
body: {
currency: "JPY",
amount: "100",
wallet_address: "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF",
},
} as unknown as AuthRequest,
res,
next,
);

const err = (next as jest.Mock).mock.calls[0][0] as AppError;
expect(err).toBeInstanceOf(AppError);
expect(err.statusCode).toBe(400);
expect(err.message).toContain("currency must be one of");
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

This regression test is asserting the wrong failure path.

For "JPY", depositBodySchema.safeParse() fails and depositFromBasketCurrency() responds with res.status(400).json(...); it does not forward an AppError to next. As written, next.mock.calls[0] will be undefined here, so the test won't cover the intended behavior.

Either assert the 400 response payload, or move unsupported-currency handling back below schema validation before expecting next to receive an AppError.

🧰 Tools
🪛 ESLint

[error] 128-128: Delete

(prettier/prettier)


[error] 129-129: Delete

(prettier/prettier)


[error] 130-130: Delete

(prettier/prettier)


[error] 131-131: Delete

(prettier/prettier)


[error] 132-132: Delete

(prettier/prettier)


[error] 133-133: Replace ·id:·"key-1",·userId:·"user-1",·organizationId:·null,·permissions:·[],·rateLimit:·100·},␍ with ⏎··········id:·"key-1",⏎··········userId:·"user-1",⏎··········organizationId:·null,⏎··········permissions:·[],⏎··········rateLimit:·100,⏎········},

(prettier/prettier)


[error] 134-134: Delete

(prettier/prettier)


[error] 135-135: Delete

(prettier/prettier)


[error] 136-136: Delete

(prettier/prettier)


[error] 137-137: Delete

(prettier/prettier)


[error] 138-138: Delete

(prettier/prettier)


[error] 139-139: Delete

(prettier/prettier)


[error] 140-140: Delete

(prettier/prettier)


[error] 141-141: Delete

(prettier/prettier)


[error] 142-142: Delete

(prettier/prettier)


[error] 143-143: Delete

(prettier/prettier)


[error] 144-144: Delete

(prettier/prettier)


[error] 145-145: Delete

(prettier/prettier)


[error] 146-146: Delete

(prettier/prettier)


[error] 147-147: Delete

(prettier/prettier)


[error] 148-148: Delete

(prettier/prettier)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/controllers/mintController.test.ts` around lines 128 - 148, The test
currently expects depositFromBasketCurrency to call next with an AppError for
unsupported currency "JPY", but depositBodySchema.safeParse fails first and the
handler responds with res.status(400).json(...); update the test to assert the
HTTP 400 response payload (inspect res.status and res.json/mock.calls) for the
validation error instead of reading next.mock.calls, or alternatively move the
unsupported-currency check in depositFromBasketCurrency to run before
depositBodySchema.safeParse so next receives an AppError; refer to
depositFromBasketCurrency, depositBodySchema.safeParse, AppError, and the test
helpers res and next when making the change.

Comment on lines +265 to +278
currency: z
.string()
.length(3)
.transform((value) => value.toUpperCase())
.refine(
(currency) =>
isAllowedDepositCurrency(currency) || isForbiddenDepositCurrency(currency),
{
message: `Currency must be one of: ${[
...BASKET_CURRENCIES,
...FORBIDDEN_DEPOSIT_CURRENCIES,
].join(", ")}`,
},
),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Don't collapse unsupported and forbidden currencies into the generic schema error path.

z.string().length(3) rejects USDC/USDT before the forbidden-currency branch can run, and unsupported 3-letter codes like JPY now stop at safeParse() and return the generic "Invalid request" response from Lines 299-304. That makes the explicit deposit errors at Lines 307-321 unreachable for the cases this PR is trying to improve.

If you want the controller to return the clearer DEPOSIT_ONLY_BASKET_CURRENCIES / INVALID_CURRENCY responses, keep this schema focused on normalization/shape validation and leave the allow-vs-forbid decision to depositFromBasketCurrency.

🧰 Tools
🪛 ESLint

[error] 270-271: Delete ⏎·······

(prettier/prettier)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/controllers/mintController.ts` around lines 265 - 278, The currency zod
schema currently enforces .length(3) which rejects values like USDC/USDT before
your forbidden-vs-allowed logic can run; remove the .length(3) constraint and
keep only normalization/shape rules (e.g., .string().transform(v =>
v.toUpperCase())) so safeParse succeeds for 3+ letter codes, then move the
allow/forbid decision out of the schema into the controller flow: after parsing
(where safeParse is used) call depositFromBasketCurrency (or the existing
isAllowedDepositCurrency/isForbiddenDepositCurrency checks) and return the
specific DEPOSIT_ONLY_BASKET_CURRENCIES or INVALID_CURRENCY responses based on
those checks, ensuring BASKET_CURRENCIES and FORBIDDEN_DEPOSIT_CURRENCIES remain
the source of truth.

@Junman140 Junman140 merged commit 7af5023 into Pi-Defi-world:dev Jun 4, 2026
2 of 3 checks passed
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.

depositFromBasketCurrency silently accepts unknown currencies – M

2 participants