Skip to content

Conversation

@gomesalexandre
Copy link
Contributor

@gomesalexandre gomesalexandre commented Dec 2, 2025

Description

TODO: test me when Near Intents API is back online
Does what it says on the box

Issue (if applicable)

closes #11253

Risk

High Risk PRs Require 2 approvals

What protocols, transaction types, wallets or contract interactions might be affected by this PR?

Low/None

Testing

  • Swap a low amount with Near intents
  • Ensure the amount too low: err is surfaced

Engineering

  • ^

Operations

  • 🏁 My feature is behind a flag and doesn't require operations testing (yet)
  • ^

Screenshots (if applicable)

Summary by CodeRabbit

  • Bug Fixes
    • Improved error handling and messaging for swap operations to provide clearer feedback when trade amounts fall below minimum requirements, helping users understand what adjustments may be needed.
    • Enhanced validation for token pair combinations to better identify and properly handle edge cases involving unsupported or invalid tokens during the swap process.

✏️ Tip: You can customize this high-level summary in your review settings.

@gomesalexandre gomesalexandre requested a review from a team as a code owner December 2, 2025 09:11
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 2, 2025

📝 Walkthrough

Walkthrough

Add error handling for "Amount is too low" API responses in the NEAR Intents swapper. When the API returns this error, the code extracts the minimum required amount via regex and returns a TradeAmountTooSmall error. Existing token validation error handling is preserved.

Changes

Cohort / File(s) Summary
NEAR Intents Swapper API Error Handling
packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts, packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.ts
Add ApiError handling for "Amount is too low" messages: extract minimum amount via regex and return TradeAmountTooSmall error. Reorganize error guards to handle invalid token pairs separately, preserving existing UnsupportedTradePair logic. Import createTradeAmountTooSmallErr utility.

Estimated Code Review Effort

🎯 2 (Simple) | ⏱️ ~15 minutes

  • Regex pattern for minimum amount extraction—verify it correctly parses the API error message format
  • Assumptions about error message structure and format consistency across API responses
  • Correct import and application of createTradeAmountTooSmallErr with parameters

Possibly Related PRs

Suggested Reviewers

  • premiumjibles

Poem

🐰 A minimum amount, we now can see,
When trading tokens by the NEAR decree—
Extract the sum from errors so bright,
And show the trader what's needed just right! ✨

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding handling for 'amount too low' scenarios in the Near Intents swapper.
Linked Issues check ✅ Passed The PR implements the core objective from issue #11253: surfacing the minimum amount required by the Near Intents swapper when an amount is too low.
Out of Scope Changes check ✅ Passed All changes are scoped to Near Intents error handling for 'amount too low' scenarios, directly addressing the linked issue without introducing unrelated modifications.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat_handle_amount_too_low

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between b444178 and b453b19.

📒 Files selected for processing (2)
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts (2 hunks)
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,js,jsx}: Never assume a library is available - always check imports/package.json first
Prefer composition over inheritance
Write self-documenting code with clear variable and function names
Keep functions small and focused on a single responsibility
Avoid deep nesting - use early returns instead
Prefer procedural and easy to understand code
Never expose, log, or commit secrets, API keys, or credentials
Validate all inputs, especially user inputs
Handle errors gracefully with meaningful messages
Don't silently catch and ignore exceptions
Log errors appropriately for debugging
Provide fallback behavior when possible
Use appropriate data structures for the task
Never add code comments unless explicitly requested
When modifying code, do not add comments that reference previous implementations or explain what changed. Comments should only describe the current logic and functionality.
Use meaningful names for branches, variables, and functions
Always run yarn lint --fix and yarn type-check after making changes
Avoid let variable assignments - prefer const with inline IIFE switch statements or extract to functions for conditional logic

Files:

  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Avoid useEffect where practical - use it only when necessary and following best practices
Avoid 'any' types - use specific type annotations instead
For default values with user overrides, use computed values (useMemo) instead of useEffect - pattern: userSelected ?? smartDefault ?? fallback
When function parameters are unused due to interface requirements, refactor the interface or implementation to remove them rather than prefixing with underscore
Sanitize data before displaying to prevent XSS
Memoize aggressively - wrap component variables in useMemo and callbacks in useCallback where possible
For static JSX icon elements (e.g., <TbCopy />) that don't depend on state/props, define them as constants outside the component to avoid re-renders instead of using useMemo
Account for light/dark mode using useColorModeValue hook
Account for responsive mobile designs in all UI components
When applying styles, use the existing standards and conventions of the codebase
Use Chakra UI components and conventions
All copy/text must use translation keys - never hardcode strings
Use the translation hook: useTranslate() from react-polyglot
Use useFeatureFlag('FlagName') hook to access feature flag values in components
Prefer type over interface for type definitions
Use strict typing - avoid any
Use Nominal types for domain identifiers (e.g., WalletId, AccountId)
Import types from @shapeshiftoss/caip for chain/account/asset IDs
Use useAppSelector for Redux state
Use useAppDispatch for Redux actions
Memoize expensive computations with useMemo
Memoize callbacks with useCallback

**/*.{ts,tsx}: Use Result<T, E> pattern for error handling in swappers and APIs; ALWAYS use Ok() and Err() from @sniptt/monads; AVOID throwing within swapper API implementations
ALWAYS use custom error classes from @shapeshiftoss/errors with meaningful error codes for internationalization and relevant details in error objects
ALWAYS wrap async op...

Files:

  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.ts
**/swapper{s,}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/error-handling.mdc)

ALWAYS use makeSwapErrorRight for swapper errors with TradeQuoteError enum for error codes and provide detailed error information

Files:

  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.ts
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/naming-conventions.mdc)

**/*.{js,jsx,ts,tsx}: Use camelCase for variables, functions, and methods with descriptive names that explain the purpose
Use verb prefixes for functions that perform actions (e.g., fetch, validate, execute, update, calculate)
Use UPPER_SNAKE_CASE for constants and configuration values with descriptive names
Use handle prefix for event handlers with descriptive names in camelCase
Use descriptive boolean variable names with is, has, can, should prefixes
Use named exports for components, functions, and utilities instead of default exports
Use descriptive import names and avoid renaming imports unless necessary
Avoid non-descriptive variable names like data, item, obj, and single-letter variable names except in loops
Avoid abbreviations in names unless they are widely understood
Avoid generic function names like fn, func, or callback

Files:

  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.ts
packages/swapper/**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/swapper.mdc)

packages/swapper/**/*.ts: Use TypeScript with explicit types (e.g., SupportedChainIds) for all code in the Swapper system
Use camelCase for variable and function names in the Swapper system
Use PascalCase for types, interfaces, and enums in the Swapper system
Use kebab-case for filenames in the Swapper system

Files:

  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.ts
packages/swapper/src/swappers/**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/swapper.mdc)

packages/swapper/src/swappers/**/*.ts: Adhere to the Swapper directory structure: each swapper resides in packages/swapper/src/swappers// with required files (SwapperName.ts, endpoints.ts, types.ts, utils/constants.ts, utils/helpers.ts)
Validate inputs and log errors for debugging in Swapper system implementations
Swapper files must be located in packages/swapper/src/swappers/ directory structure and not placed outside this location
Avoid side effects in swap logic; ensure swap methods are deterministic and stateless

Files:

  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.ts
🧠 Learnings (20)
📓 Common learnings
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11016
File: packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts:109-145
Timestamp: 2025-11-12T12:18:00.863Z
Learning: NEAR Intents swapper: The NEAR 1Click API does not provide gas limit estimation logic like other swappers (e.g., magic gasLimit fields). For ERC20 token swaps in getTradeQuote, accurate fee estimation requires token approval and sufficient balance; without these prerequisites, fees may display as 0 or use inaccurate native transfer estimates. This is a known limitation of the NEAR Intents integration.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/EIP712MessageDisplay.tsx:21-24
Timestamp: 2025-09-12T13:16:27.004Z
Learning: gomesalexandre declined to add error boundaries to WalletConnect modals in PR #10461, stating "no error boundaries in this pr ser", consistent with his preference to keep PR scope focused and defer tangential improvements to separate efforts.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11170
File: patches/@shapeshiftoss+bitcoinjs-lib+7.0.0-shapeshift.0.patch:9-19
Timestamp: 2025-11-25T21:43:10.838Z
Learning: In shapeshift/web, gomesalexandre will not expand PR scope to fix latent bugs in unused API surface (like bitcoinjs-lib patch validation methods) when comprehensive testing proves the actual used code paths work correctly, preferring to avoid costly hdwallet/web verdaccio publish cycles and full regression testing for conceptual issues with zero runtime impact.
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10231
File: src/components/AssetSearch/components/AssetList.tsx:2-2
Timestamp: 2025-08-08T15:00:49.887Z
Learning: Project shapeshift/web: NeOMakinG prefers avoiding minor a11y/UI nitpicks (e.g., adding aria-hidden to decorative icons in empty states like src/components/AssetSearch/components/AssetList.tsx) within feature PRs; defer such suggestions to a follow-up instead of blocking the PR.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10418
File: src/plugins/walletConnectToDapps/components/header/WalletConnectToDappsHeaderButton.tsx:0-0
Timestamp: 2025-09-08T22:00:48.005Z
Learning: gomesalexandre dismissed an aria-label accessibility suggestion with "meh" in PR #10418 for WalletConnectToDappsHeaderButton.tsx, consistent with the team's pattern of deferring minor a11y improvements to follow-up PRs rather than expanding feature PR scope.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11016
File: packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.ts:25-38
Timestamp: 2025-11-12T13:01:06.086Z
Learning: In the swapper architecture (packages/swapper), input validation for sell amounts (e.g., checking sellAmount > 0) is handled by the application layer before reaching individual swapper implementations. Swapper methods like getTradeRate and getTradeQuote can assume inputs have already been validated upstream, so defensive guards for basic input validation (amount > 0, valid addresses, etc.) are unnecessary at the swapper layer.
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/error-handling.mdc:0-0
Timestamp: 2025-11-24T21:20:17.804Z
Learning: Applies to **/swapper{s,}/**/*.{ts,tsx} : ALWAYS use `makeSwapErrorRight` for swapper errors with `TradeQuoteError` enum for error codes and provide detailed error information
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10206
File: src/config.ts:127-128
Timestamp: 2025-08-07T11:20:44.614Z
Learning: gomesalexandre prefers required environment variables without default values in the config file (src/config.ts). They want explicit configuration and fail-fast behavior when environment variables are missing, rather than having fallback defaults.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/ContractInteractionBreakdown.tsx:0-0
Timestamp: 2025-09-13T16:45:18.813Z
Learning: gomesalexandre prefers aggressively deleting unused/obsolete code files ("ramboing") rather than fixing technical issues in code that won't be used, demonstrating his preference for keeping codebases clean and PR scope focused.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10458
File: src/plugins/walletConnectToDapps/types.ts:7-7
Timestamp: 2025-09-10T15:34:29.604Z
Learning: gomesalexandre is comfortable relying on transitive dependencies (like abitype through ethers/viem) rather than explicitly declaring them in package.json, preferring to avoid package.json bloat when the transitive dependency approach works reliably in practice.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10503
File: .env:56-56
Timestamp: 2025-09-16T13:17:02.938Z
Learning: gomesalexandre prefers to enable feature flags globally in the base .env file when the intent is to activate features everywhere, even when there are known issues like crashes, demonstrating his preference for intentional global feature rollouts over cautious per-environment enablement.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10249
File: src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx:447-503
Timestamp: 2025-08-13T17:07:10.763Z
Learning: gomesalexandre prefers relying on TypeScript's type system for validation rather than adding defensive runtime null checks when types are properly defined. They favor a TypeScript-first approach over defensive programming with runtime validations.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10276
File: src/hooks/useActionCenterSubscribers/useThorchainLpDepositActionSubscriber.tsx:61-66
Timestamp: 2025-08-14T17:51:47.556Z
Learning: gomesalexandre is not concerned about structured logging and prefers to keep console.error usage as-is rather than implementing structured logging patterns, even when project guidelines suggest otherwise.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10413
File: src/components/Modals/FiatRamps/fiatRampProviders/onramper/utils.ts:29-55
Timestamp: 2025-09-02T14:26:19.028Z
Learning: gomesalexandre prefers to keep preparatory/reference code simple until it's actively consumed, rather than implementing comprehensive error handling, validation, and robustness improvements upfront. They prefer to add these improvements when the code is actually being used in production.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10276
File: src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx:396-402
Timestamp: 2025-08-14T17:55:57.490Z
Learning: gomesalexandre is comfortable with functions/variables that return undefined or true (tri-state) when only the truthy case matters, preferring to rely on JavaScript's truthy/falsy behavior rather than explicitly returning boolean values.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10783
File: src/context/ModalStackProvider/useModalRegistration.ts:30-41
Timestamp: 2025-10-16T11:14:40.657Z
Learning: gomesalexandre prefers to add lint rules (like typescript-eslint/strict-boolean-expressions for truthiness checks on numbers) to catch common issues project-wide rather than relying on code review to catch them.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10206
File: src/lib/moralis.ts:47-85
Timestamp: 2025-08-07T11:22:16.983Z
Learning: gomesalexandre prefers console.error over structured logging for Moralis API integration debugging, as they find it more conventional and prefer to examine XHR requests directly rather than rely on structured logs for troubleshooting.
📚 Learning: 2025-11-24T21:20:17.804Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/error-handling.mdc:0-0
Timestamp: 2025-11-24T21:20:17.804Z
Learning: Applies to **/swapper{s,}/**/*.{ts,tsx} : ALWAYS use `makeSwapErrorRight` for swapper errors with `TradeQuoteError` enum for error codes and provide detailed error information

Applied to files:

  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.ts
📚 Learning: 2025-11-03T22:31:30.786Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10985
File: packages/swapper/src/swappers/PortalsSwapper/getPortalsTradeQuote/getPortalsTradeQuote.ts:0-0
Timestamp: 2025-11-03T22:31:30.786Z
Learning: In packages/swapper/src/swappers/PortalsSwapper, the rate and quote files intentionally use different approaches for calculating buyAmountBeforeSlippageCryptoBaseUnit: getPortalsTradeRate.tsx uses minOutputAmount / (1 - buffer) for conservative estimates, while getPortalsTradeQuote.ts uses outputAmount / (1 - buffer) for final quote display. This difference is validated by on-chain simulation testing and is intentional.

Applied to files:

  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.ts
📚 Learning: 2025-11-12T12:18:00.863Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11016
File: packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts:109-145
Timestamp: 2025-11-12T12:18:00.863Z
Learning: NEAR Intents swapper: The NEAR 1Click API does not provide gas limit estimation logic like other swappers (e.g., magic gasLimit fields). For ERC20 token swaps in getTradeQuote, accurate fee estimation requires token approval and sufficient balance; without these prerequisites, fees may display as 0 or use inaccurate native transfer estimates. This is a known limitation of the NEAR Intents integration.

Applied to files:

  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.ts
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/swappers/**/*.ts : Validate inputs and log errors for debugging in Swapper system implementations

Applied to files:

  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.ts
📚 Learning: 2025-11-12T13:01:06.086Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11016
File: packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.ts:25-38
Timestamp: 2025-11-12T13:01:06.086Z
Learning: In the swapper architecture (packages/swapper), input validation for sell amounts (e.g., checking sellAmount > 0) is handled by the application layer before reaching individual swapper implementations. Swapper methods like getTradeRate and getTradeQuote can assume inputs have already been validated upstream, so defensive guards for basic input validation (amount > 0, valid addresses, etc.) are unnecessary at the swapper layer.

Applied to files:

  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.ts
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/swappers/*/*.ts : Implement filterBuyAssetsBySellAssetId method to filter assets by supported chain IDs in the buy property

Applied to files:

  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.ts
📚 Learning: 2025-11-03T05:46:24.190Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10985
File: packages/swapper/src/swappers/PortalsSwapper/getPortalsTradeRate/getPortalsTradeRate.tsx:130-141
Timestamp: 2025-11-03T05:46:24.190Z
Learning: In packages/swapper/src/swappers/PortalsSwapper/getPortalsTradeRate/getPortalsTradeRate.tsx, gomesalexandre prefers "let it crash" approach when Portals returns zero outputAmount or 100% buffer causing division by zero, rather than adding defensive guards to surface zero quotes. He wants to fail fast with exceptions that bubble up to the try/catch wrapper, surfacing upstream data issues rather than masking them with defensive programming.

Applied to files:

  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.ts
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/swappers/*/*.ts : Implement filterAssetIdsBySellable method to filter assets by supported chain IDs in the sell property

Applied to files:

  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.ts
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/swappers/*/*.ts : Reuse executeEvmTransaction utility for EVM-based swappers instead of implementing custom transaction execution

Applied to files:

  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.ts
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/swappers/*/utils/constants.ts : Define supported chain IDs for each swapper in utils/constants.ts with both 'sell' and 'buy' properties following the pattern: SupportedChainIds type

Applied to files:

  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/index.ts : Export unique functions and types from packages/swapper/src/index.ts only if needed for external consumption

Applied to files:

  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.ts
📚 Learning: 2025-08-11T09:46:41.060Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10219
File: src/components/MultiHopTrade/components/TradeInput/TradeInput.tsx:167-172
Timestamp: 2025-08-11T09:46:41.060Z
Learning: In the shapeshift/web repository, the display cache logic for trade quotes (using `selectUserAvailableTradeQuotes` and `selectUserUnavailableTradeQuotes`) is intentionally kept the same between `TradeInput.tsx` and `TradeQuotes.tsx` components. The `hasQuotes` computation in `TradeInput.tsx` uses these display cache selectors by design, matching the pattern used in `TradeQuotes.tsx`.

Applied to files:

  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.ts
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/swappers/*/endpoints.ts : Reuse checkEvmSwapStatus utility for checking EVM swap status instead of implementing custom status checks

Applied to files:

  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.ts
📚 Learning: 2025-07-31T03:51:48.479Z
Learnt from: premiumjibles
Repo: shapeshift/web PR: 10154
File: src/state/apis/swapper/helpers/swapperApiHelpers.ts:57-60
Timestamp: 2025-07-31T03:51:48.479Z
Learning: In src/state/apis/swapper/helpers/swapperApiHelpers.ts, the getState parameter in processQuoteResultWithRatios uses `() => unknown` type instead of `() => ReduxState` to avoid type compatibility issues elsewhere in the codebase.

Applied to files:

  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.ts
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/swappers/*/endpoints.ts : All swapper API implementations must implement the SwapperApi interface from packages/swapper/src/types.ts

Applied to files:

  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.ts
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/**/*.ts : Use TypeScript with explicit types (e.g., SupportedChainIds) for all code in the Swapper system

Applied to files:

  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.ts
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/**/*.test.ts : Write unit tests for swapper methods and API endpoints

Applied to files:

  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.ts
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/swappers/**/*.ts : Avoid side effects in swap logic; ensure swap methods are deterministic and stateless

Applied to files:

  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.ts
📚 Learning: 2025-11-24T21:20:17.804Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/error-handling.mdc:0-0
Timestamp: 2025-11-24T21:20:17.804Z
Learning: Applies to **/*.{ts,tsx} : Use `Result<T, E>` pattern for error handling in swappers and APIs; ALWAYS use `Ok()` and `Err()` from `sniptt/monads`; AVOID throwing within swapper API implementations

Applied to files:

  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.ts
🧬 Code graph analysis (2)
packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts (3)
packages/swapper/src/swappers/NearIntentsSwapper/utils/oneClickService.ts (1)
  • ApiError (17-17)
packages/swapper/src/utils.ts (2)
  • makeSwapErrorRight (31-47)
  • createTradeAmountTooSmallErr (49-57)
src/state/apis/swapper/types.ts (1)
  • TradeQuoteError (39-39)
packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.ts (3)
packages/swapper/src/swappers/NearIntentsSwapper/utils/oneClickService.ts (1)
  • ApiError (17-17)
packages/swapper/src/utils.ts (2)
  • makeSwapErrorRight (31-47)
  • createTradeAmountTooSmallErr (49-57)
src/state/apis/swapper/types.ts (1)
  • TradeQuoteError (39-39)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Install and Cache
🔇 Additional comments (5)
packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts (2)

23-27: LGTM! Import additions are correct.

The added import of createTradeAmountTooSmallErr is properly sourced from the utils module and used appropriately in the error handling logic below.


304-329: Verify the NEAR Intents API error message format against the external SDK and add fallback logging.

The error handling at lines 317-327 depends on the exact error message format from @defuse-protocol/one-click-sdk-typescript (v0.1.1-0.2, pre-release). The pattern matches "Amount is too low" (case-sensitive) and extracts a number via /try at least (\d+)/. If the API response differs in format, capitalization, or number representation, the regex silently fails and the code falls through to a generic "QueryFailed" error, losing the minimum amount information that this PR is designed to surface.

Observations:

  • This identical pattern is duplicated in getTradeRate.ts:325 (potential future maintenance issue)
  • PortalsSwapper uses a similar regex-based approach (/Expected slippage is (.*?)%/), showing the pattern has precedent in the codebase
  • No test coverage or documentation in the repository specifies the expected error message format
  • If the regex match fails, there is no debug logging to help diagnose why the minimum amount extraction failed

Add a fallback log statement to capture unmatched "Amount is too low" errors for debugging during API testing:

if (error.body?.message?.includes('Amount is too low')) {
  const match = error.body.message.match(/try at least (\d+)/)
  if (match) {
    const minAmountCryptoBaseUnit = match[1]
    return Err(
      createTradeAmountTooSmallErr({
        minAmountCryptoBaseUnit,
        assetId: sellAsset.assetId,
      }),
    )
  } else {
    console.error('[NEAR Intents] Failed to extract minimum amount from message:', error.body.message)
  }
}

Consider consolidating the duplicated logic into a shared helper once the API format is confirmed.

packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.ts (3)

25-29: LGTM!

The import of createTradeAmountTooSmallErr is correct and necessary for the new "amount too low" error handling added below.


324-335: No action required - the implementation is correct.

The regex pattern /try at least (\d+)/ correctly extracts the minimum amount as a string from the error message, which matches the expected minAmountCryptoBaseUnit: string parameter type. The error handling properly falls back to the generic error handler if the regex fails to match, and the implementation follows the Result pattern with appropriate error codes.

The same pattern is consistently applied in both getTradeRate.ts and getTradeQuote.ts, and all type signatures align correctly with the createTradeAmountTooSmallErr function expectations.


311-322: Verify the exact API error message format when the NEAR Intents API comes online.

The code uses case-sensitive string matching for 'tokenIn is not valid' and 'tokenOut is not valid'. The exact error message format returned by the NEAR Intents 1Click API is not documented in the repository or test fixtures. When the API is available, confirm the API returns these exact strings with this precise casing to ensure the error handling works as intended.


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.

Copy link
Collaborator

@NeOMakinG NeOMakinG left a comment

Choose a reason for hiding this comment

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

image

Here we go!

@NeOMakinG NeOMakinG enabled auto-merge (squash) December 2, 2025 20:25
@NeOMakinG NeOMakinG merged commit cd7a9ec into develop Dec 2, 2025
4 checks passed
@NeOMakinG NeOMakinG deleted the feat_handle_amount_too_low branch December 2, 2025 20:34
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.

Add minimum amount to trade in swapper for Tron tokens

3 participants