-
Notifications
You must be signed in to change notification settings - Fork 198
feat: implement avnu for starknet tokens swaps #11552
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
Conversation
📝 WalkthroughWalkthroughAdds AVNU Starknet swapper integration: new AvnuSwapper and API, AVNU SDK dependency, CSP and feature-flag wiring, Starknet token/treasury support and getKnownTokens, fee/nonce handling updates, UI icon and fee-call adjustments. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant UI as Trade UI
participant AvnuApi as AvnuSwapper / avnuApi
participant AvnuSDK as AVNU SDK
participant StarknetAdapter as Starknet ChainAdapter
participant StarknetRPC as Starknet RPC
User->>UI: Request AVNU quote
UI->>AvnuApi: getTradeQuote(sell,buy,amount)
AvnuApi->>AvnuSDK: fetchQuotes(...)
AvnuSDK-->>AvnuApi: quotes
AvnuApi->>StarknetAdapter: getFeeData({to,value,chainSpecific,sendMax})
StarknetAdapter->>StarknetRPC: estimateFee / get_nonce
StarknetRPC-->>StarknetAdapter: feeEstimate / nonce
StarknetAdapter-->>AvnuApi: feeData
AvnuApi-->>UI: TradeQuote (quoteId, routes, fees)
User->>UI: Confirm
UI->>AvnuApi: getUnsignedStarknetTransaction(quote,slippage)
AvnuApi->>AvnuSDK: quoteToCalls(quote)
AvnuSDK-->>AvnuApi: calldata/calls
AvnuApi->>StarknetRPC: get_nonce(account)
StarknetRPC-->>AvnuApi: nonce
AvnuApi->>StarknetAdapter: getFeeData({from,to,value,tokenContractAddress})
StarknetAdapter->>StarknetRPC: estimateFee(invoke)
StarknetRPC-->>StarknetAdapter: resourceBounds
StarknetAdapter-->>AvnuApi: fee/maxFee
AvnuApi-->>UI: unsigned tx payload (txHash, addressNList, _txDetails)
UI->>StarknetRPC: submit signed tx
StarknetRPC-->>UI: txHash
UI->>AvnuApi: checkTradeStatus(txHash)
AvnuApi->>StarknetRPC: getTransactionReceipt(txHash)
StarknetRPC-->>AvnuApi: receipt {execution_status}
AvnuApi-->>UI: TradeStatus (Confirmed/Failed/Pending)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
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
🧹 Nitpick comments (5)
packages/swapper/src/swappers/AvnuSwapper/utils/constants.ts (1)
4-10: Consider adding SupportedChainIds type structure.The coding guidelines specify: "Define supported chain IDs for each swapper in utils/constants.ts with both 'sell' and 'buy' properties following the pattern: SupportedChainIds type."
The current implementation uses a simple array, but the standard pattern includes separate sell/buy chain ID arrays:
type SupportedChainIds = { sell: ChainId[] buy: ChainId[] } export const AVNU_SUPPORTED_CHAIN_IDS: SupportedChainIds = { sell: [KnownChainIds.StarknetMainnet], buy: [KnownChainIds.StarknetMainnet], } as constHowever, if AVNU only supports same-chain swaps (Starknet → Starknet), the current simple array may be intentional.
Based on coding guidelines.
.env.development (1)
98-98: Consider alphabetical ordering for feature flags.The static analyzer suggests placing
VITE_FEATURE_AVNU_SWAPbeforeVITE_FEATURE_CETUS_SWAPfor consistency.packages/swapper/src/types.ts (1)
408-411: Consider replacingany[]with a more specific type forroutes.The
routes: any[]violates the coding guideline to avoidanytypes. Other swapper-specific metadata in this file uses explicit types (e.g.,sunioTransactionMetadata.route,chainflipSpecific). If the AVNU SDK provides a type for routes, consider importing and using it here for better type safety and maintainability.packages/swapper/src/utils.ts (1)
435-435: Consider adding type definition for Starknet receipt.The
anytype forreceiptworks but loses type safety. Consider defining a minimal type interface for the receipt properties used (execution_status).🔎 Suggested type definition
+type StarknetTransactionReceipt = { + execution_status?: 'SUCCEEDED' | 'REVERTED' | string +} + export const checkStarknetSwapStatus = async ({ // ... }): Promise<TradeStatus> => { try { const adapter = assertGetStarknetChainAdapter(starknetChainId) const provider = adapter.getStarknetProvider() - const receipt: any = await provider.getTransactionReceipt(txHash) + const receipt = await provider.getTransactionReceipt(txHash) as StarknetTransactionReceiptpackages/swapper/src/swappers/AvnuSwapper/endpoints.ts (1)
38-41: Default slippage inconsistency.The hardcoded fallback of
0.01(1%) differs fromDEFAULT_AVNU_SLIPPAGE_DECIMAL_PERCENTAGE(0.5%) defined in constants. Consider using the centralized constant for consistency.🔎 Suggested fix
+import { getDefaultSlippageDecimalPercentageForSwapper } from '../../../constants' +import { SwapperName } from '../../../types' + // Convert slippage from decimal percentage string to number for AVNU format (e.g., "0.01" = 1%) const slippage: number = slippageTolerancePercentageDecimal ? parseFloat(slippageTolerancePercentageDecimal) - : 0.01 + : parseFloat(getDefaultSlippageDecimalPercentageForSwapper(SwapperName.Avnu))
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
🧹 Nitpick comments (1)
packages/caip/src/adapters/coingecko/index.test.ts (1)
326-336: Consider adding test coverage for Starknet chain mapping.Since this PR adds Starknet token support and includes USDC mappings, consider adding a test case to verify that
chainIdToCoingeckoAssetPlatformcorrectly handles Starknet chain IDs, similar to the existing Ethereum test at line 328.📝 Example test case for Starknet
it('can get CoinGecko asset platform from Starknet ChainId', () => { const chainId = starknetChainId expect(chainIdToCoingeckoAssetPlatform(chainId)).toEqual(CoingeckoAssetPlatform.Starknet) })Note: This assumes
starknetChainIdconstant andCoingeckoAssetPlatform.Starknetare defined in the implementation.
📜 Review details
Configuration used: Organization 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.
📒 Files selected for processing (2)
packages/caip/src/adapters/coingecko/index.test.tspackages/caip/src/adapters/coingecko/utils.test.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{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 runyarn lint --fixandyarn type-checkafter making changes
Avoidletvariable assignments - preferconstwith inline IIFE switch statements or extract to functions for conditional logic
Files:
packages/caip/src/adapters/coingecko/utils.test.tspackages/caip/src/adapters/coingecko/index.test.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 inuseMemoand callbacks inuseCallbackwhere 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 usinguseColorModeValuehook
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()fromreact-polyglot
UseuseFeatureFlag('FlagName')hook to access feature flag values in components
Prefertypeoverinterfacefor type definitions
Use strict typing - avoidany
UseNominaltypes for domain identifiers (e.g.,WalletId,AccountId)
Import types from@shapeshiftoss/caipfor chain/account/asset IDs
UseuseAppSelectorfor Redux state
UseuseAppDispatchfor Redux actions
Memoize expensive computations withuseMemo
Memoize callbacks withuseCallback
**/*.{ts,tsx}: UseResult<T, E>pattern for error handling in swappers and APIs; ALWAYS useOk()andErr()from@sniptt/monads; AVOID throwing within swapper API implementations
ALWAYS use custom error classes from@shapeshiftoss/errorswith meaningful error codes for internationalization and relevant details in error objects
ALWAYS wrap async op...
Files:
packages/caip/src/adapters/coingecko/utils.test.tspackages/caip/src/adapters/coingecko/index.test.ts
**/*.test.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.test.{ts,tsx,js,jsx}: Write tests for critical business logic
Test edge cases and error conditions
Use descriptive test names that explain behavior
Keep tests isolated and independent
Mock external dependencies appropriately
Files:
packages/caip/src/adapters/coingecko/utils.test.tspackages/caip/src/adapters/coingecko/index.test.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
Usehandleprefix for event handlers with descriptive names in camelCase
Use descriptive boolean variable names withis,has,can,shouldprefixes
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 likedata,item,obj, and single-letter variable names except in loops
Avoid abbreviations in names unless they are widely understood
Avoid generic function names likefn,func, orcallback
Files:
packages/caip/src/adapters/coingecko/utils.test.tspackages/caip/src/adapters/coingecko/index.test.ts
🧠 Learnings (9)
📓 Common learnings
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: 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: NeOMakinG
Repo: shapeshift/web PR: 10323
File: src/pages/RFOX/components/Stake/components/StakeSummary.tsx:112-114
Timestamp: 2025-08-22T13:00:44.879Z
Learning: NeOMakinG prefers to keep PR changes minimal and focused on the core objectives, avoiding cosmetic or defensive code improvements that aren't directly related to the PR scope, even when they would improve robustness.
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10128
File: .cursor/rules/error-handling.mdc:266-274
Timestamp: 2025-07-29T10:35:22.059Z
Learning: NeOMakinG prefers less nitpicky suggestions on documentation and best practices files, finding overly detailed suggestions on minor implementation details (like console.error vs logger.error) too granular for cursor rules documentation.
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10380
File: src/pages/Dashboard/components/AccountList/AccountTable.tsx:60-0
Timestamp: 2025-09-02T08:34:08.157Z
Learning: NeOMakinG prefers code review comments to focus only on actual PR changes, not pre-existing code issues, unless there are critical security or correctness concerns directly related to the new functionality.
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10234
File: src/components/MultiHopTrade/hooks/useGetTradeQuotes/hooks/useTrackTradeQuotes.ts:42-86
Timestamp: 2025-08-08T11:41:22.794Z
Learning: NeOMakinG prefers not to include refactors in move-only PRs; such suggestions should be deferred to follow-up issues instead of being applied within the same PR.
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10380
File: src/components/Table/Table.theme.ts:177-180
Timestamp: 2025-09-02T12:38:46.940Z
Learning: NeOMakinG prefers to defer technical debt and CSS correctness issues (like improper hover selectors) to follow-up PRs when the current PR is already large and focused on major feature implementation, even when the issues are valid from a usability/technical perspective.
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to **/*.{ts,tsx} : Import types from `shapeshiftoss/caip` for chain/account/asset IDs
Applied to files:
packages/caip/src/adapters/coingecko/index.test.ts
📚 Learning: 2025-11-20T12:00:45.005Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11078
File: src/setupVitest.ts:11-15
Timestamp: 2025-11-20T12:00:45.005Z
Learning: In shapeshift/web, src/setupVitest.ts must redirect 'ethers' to 'ethers5' for shapeshiftoss/hdwallet-trezor (and -trezor-connect), same as ledger and shapeshift-multichain. Removing 'trezor' from the regex causes CI/Vitest failures due to ethers v6 vs v5 API differences.
Applied to files:
packages/caip/src/adapters/coingecko/index.test.ts
📚 Learning: 2025-08-17T21:53:03.806Z
Learnt from: 0xApotheosis
Repo: shapeshift/web PR: 10290
File: scripts/generateAssetData/color-map.json:41-47
Timestamp: 2025-08-17T21:53:03.806Z
Learning: In the ShapeShift web codebase, native assets (using CAIP-19 slip44 namespace like eip155:1/slip44:60, bip122:.../slip44:..., cosmos:.../slip44:...) are manually hardcoded and not generated via the automated asset generation script. Only ERC20/BEP20 tokens go through the asset generation process. The validation scripts should only validate generated assets, not manually added native assets.
Applied to files:
packages/caip/src/adapters/coingecko/index.test.ts
📚 Learning: 2025-12-26T15:45:47.558Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11515
File: scripts/generateAssetData/generateRelatedAssetIndex/generateRelatedAssetIndex.ts:100-122
Timestamp: 2025-12-26T15:45:47.558Z
Learning: In scripts/generateAssetData/generateRelatedAssetIndex/generateRelatedAssetIndex.ts, gomesalexandre is comfortable with the fetchBridgedCategoryMappings function lacking try-catch error handling for CoinGecko API calls. He prefers letting the script crash on API failures rather than adding defensive error handling, consistent with his fail-fast approach for asset generation scripts.
Applied to files:
packages/caip/src/adapters/coingecko/index.test.ts
📚 Learning: 2025-12-03T23:19:39.158Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11275
File: headers/csps/chains/plasma.ts:1-10
Timestamp: 2025-12-03T23:19:39.158Z
Learning: For CSP files in headers/csps/chains/, gomesalexandre prefers using Vite's loadEnv() pattern directly to load environment variables (e.g., VITE_PLASMA_NODE_URL, VITE_MONAD_NODE_URL) for consistency with existing second-class chain CSP files, rather than using getConfig() from src/config.ts, even though other parts of the codebase use validated config values.
Applied to files:
packages/caip/src/adapters/coingecko/index.test.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/caip/src/adapters/coingecko/index.test.ts
📚 Learning: 2025-12-04T22:57:50.850Z
Learnt from: kaladinlight
Repo: shapeshift/web PR: 11290
File: packages/chain-adapters/src/utxo/zcash/ZcashChainAdapter.ts:48-51
Timestamp: 2025-12-04T22:57:50.850Z
Learning: In packages/chain-adapters/src/**/*ChainAdapter.ts files, the getName() method uses the pattern `const enumIndex = Object.values(ChainAdapterDisplayName).indexOf(ChainAdapterDisplayName.XXX); return Object.keys(ChainAdapterDisplayName)[enumIndex]` to reverse-lookup the enum key from its value. This is the established pattern used consistently across almost all chain adapters (Bitcoin, Ethereum, Litecoin, Dogecoin, Polygon, Arbitrum, Cosmos, etc.) and should be preserved for consistency when adding new chain adapters.
Applied to files:
packages/caip/src/adapters/coingecko/index.test.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/caip/src/adapters/coingecko/index.test.ts
⏰ 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: Call / Static
🔇 Additional comments (2)
packages/caip/src/adapters/coingecko/utils.test.ts (1)
193-195: No issues found. The slip44 value9004is the correct SLIP-0044 registered coin type for StarkNet, andSN_MAINis the standard chain reference for StarkNet mainnet per the CAIP-2 specification. Both values are correctly defined inpackages/caip/src/constants.tsand accurately reflected in the test expectation.packages/caip/src/adapters/coingecko/index.test.ts (1)
3-8: LGTM: Import reorganization improves clarity.The explicit imports from the current module make dependencies clearer and follow TypeScript conventions.
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.
Conceptually LGTM, happy to get this in for the sake of progression. A few functional issues to be fixed either in this PR or as direct follow-up:
- Balance update doesn't seem to be consistently happy (see first STRK -> USDC failure, happy on refetch)
- Tx links are sad e.g this guy
- Was able to get into estimation failures on subsequent Txs i.e
Fee estimation failed: {"code":41,"message":"Transaction execution error","data":{"execution_error":"Invalid transaction nonce of contract at address 0x02c7ea72c15d2f118256618c31d390bd6180f9c8716ec290383f59c3d1a38d6f. Account nonce: 0x0000000000000000000000000000000000000000000000000000000000000006; got: 0x0000000000000000000000000000000000000000000000000000000000000005.","transaction_index":0}}- looks like we should ensure fresh nonce is always fetched vs. cached ? (see 5 vs. 6)
14b8d07 to
e5c24bd
Compare
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: 3
Fix all issues with AI Agents 🤖
In @packages/swapper/src/utils.ts:
- Around line 452-457: The code reads receipt.execution_status directly when
computing the status (variable named status) which may be missing or have
unexpected values; update the logic in the function using receipt to first
validate that receipt is an object and receipt.execution_status is a known
string (e.g., 'SUCCEEDED' | 'REVERTED' | 'PENDING'), then map those known values
to TxStatus.Confirmed, TxStatus.Failed, or TxStatus.Pending; for any
missing/unknown value use a safe default (TxStatus.Pending) or handle explicitly
(throw or log) before mapping so accessing receipt.execution_status cannot cause
a runtime error.
- Line 450: Replace the use of the any type for the receipt returned by
provider.getTransactionReceipt(txHash) with a safe type: either declare an
explicit StarknetTransactionReceipt type alias that captures fields you use
(e.g., execution_status and other accessed properties) and annotate receipt with
that type, or annotate it as unknown and add a runtime type guard function
(e.g., isStarknetTransactionReceipt) that narrows unknown to the proper shape
before using receipt; update the variable declaration for receipt and all
subsequent accesses to use the narrowed type via the guard to restore TypeScript
safety.
- Around line 439-468: In checkStarknetSwapStatus, replace the receipt:any with
the proper StarknetReceipt type from the chain adapter (use
assertGetStarknetChainAdapter(...). types/exports) and update the status mapping
to treat receipt.execution_status === 'REJECTED' the same as 'REVERTED' (map
both to TxStatus.Failed); keep using assertGetStarknetChainAdapter,
starknetChainId, provider.getTransactionReceipt, TxStatus and
return/createDefaultStatusResponse unchanged. Optionally, if you want to
populate buy amount, parse receipt.events or receipt.messages_sent for the
swapper contract event signatures, but that’s separate from the required type
and status fixes.
♻️ Duplicate comments (1)
packages/caip/src/adapters/coingecko/index.test.ts (1)
197-202: Fix the Starknet USDC contract address to include the leading zero.The assetReference is missing a leading zero. It should be
0x033068f6539f8e6e6b131e6b2b814e6c34a5224bc66947c47dab9dfee93b35fb(63 hex characters after 0x), not0x33068f6539f8e6e6b131e6b2b814e6c34a5224bc66947c47dab9dfee93b35fb(62 hex characters). Starknet addresses require the full 251-bit felt representation for proper address resolution on the network.🔎 Proposed fix
const usdcOnStarknet = toAssetId({ chainNamespace: CHAIN_NAMESPACE.Starknet, chainReference: CHAIN_REFERENCE.StarknetMainnet, assetNamespace: 'token', - assetReference: '0x33068f6539f8e6e6b131e6b2b814e6c34a5224bc66947c47dab9dfee93b35fb', + assetReference: '0x033068f6539f8e6e6b131e6b2b814e6c34a5224bc66947c47dab9dfee93b35fb', })
🧹 Nitpick comments (1)
.env.development (1)
95-95: Feature flag correctly enabled for development.The AVNU swap feature is properly activated in the development environment.
Optional: Consider reordering for consistency.
The dotenv-linter suggests placing
VITE_FEATURE_AVNU_SWAPbeforeVITE_FEATURE_CETUS_SWAPto maintain alphabetical ordering.🔎 Proposed reordering
VITE_FEATURE_WC_DIRECT_CONNECTION=true +VITE_FEATURE_AVNU_SWAP=true VITE_FEATURE_CETUS_SWAP=true -VITE_FEATURE_AVNU_SWAP=true VITE_FEATURE_NEAR=true
📜 Review details
Configuration used: Organization 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.
⛔ Files ignored due to path filters (13)
packages/caip/src/adapters/coincap/generated/eip155_1/adapter.jsonis excluded by!**/generated/**packages/caip/src/adapters/coincap/generated/eip155_10/adapter.jsonis excluded by!**/generated/**packages/caip/src/adapters/coincap/generated/eip155_137/adapter.jsonis excluded by!**/generated/**packages/caip/src/adapters/coincap/generated/eip155_42161/adapter.jsonis excluded by!**/generated/**packages/caip/src/adapters/coincap/generated/eip155_43114/adapter.jsonis excluded by!**/generated/**packages/caip/src/adapters/coincap/generated/eip155_56/adapter.jsonis excluded by!**/generated/**packages/caip/src/adapters/coincap/generated/eip155_8453/adapter.jsonis excluded by!**/generated/**packages/caip/src/adapters/coincap/generated/solana_5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/adapter.jsonis excluded by!**/generated/**packages/caip/src/adapters/coingecko/generated/eip155_1/adapter.jsonis excluded by!**/generated/**packages/caip/src/adapters/coingecko/generated/eip155_56/adapter.jsonis excluded by!**/generated/**packages/caip/src/adapters/coingecko/generated/eip155_8453/adapter.jsonis excluded by!**/generated/**packages/caip/src/adapters/coingecko/generated/solana_5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/adapter.jsonis excluded by!**/generated/**yarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (15)
.env.developmentheaders/csps/index.tspackages/caip/src/adapters/coingecko/index.test.tspackages/caip/src/adapters/coingecko/utils.test.tspackages/caip/src/adapters/coingecko/utils.tspackages/swapper/package.jsonpackages/swapper/src/swappers/NearIntentsSwapper/endpoints.tspackages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.tspackages/swapper/src/types.tspackages/swapper/src/utils.tspackages/utils/src/index.tssrc/components/Modals/Send/utils.tssrc/config.tssrc/state/slices/preferencesSlice/preferencesSlice.tssrc/test/mocks/store.ts
🚧 Files skipped from review as they are similar to previous changes (8)
- packages/swapper/src/types.ts
- packages/swapper/src/swappers/NearIntentsSwapper/endpoints.ts
- packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts
- headers/csps/index.ts
- src/state/slices/preferencesSlice/preferencesSlice.ts
- packages/swapper/package.json
- packages/caip/src/adapters/coingecko/utils.ts
- src/config.ts
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{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 runyarn lint --fixandyarn type-checkafter making changes
Avoidletvariable assignments - preferconstwith inline IIFE switch statements or extract to functions for conditional logic
Files:
packages/caip/src/adapters/coingecko/utils.test.tspackages/utils/src/index.tssrc/components/Modals/Send/utils.tspackages/swapper/src/utils.tspackages/caip/src/adapters/coingecko/index.test.tssrc/test/mocks/store.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 inuseMemoand callbacks inuseCallbackwhere 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 usinguseColorModeValuehook
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()fromreact-polyglot
UseuseFeatureFlag('FlagName')hook to access feature flag values in components
Prefertypeoverinterfacefor type definitions
Use strict typing - avoidany
UseNominaltypes for domain identifiers (e.g.,WalletId,AccountId)
Import types from@shapeshiftoss/caipfor chain/account/asset IDs
UseuseAppSelectorfor Redux state
UseuseAppDispatchfor Redux actions
Memoize expensive computations withuseMemo
Memoize callbacks withuseCallback
**/*.{ts,tsx}: UseResult<T, E>pattern for error handling in swappers and APIs; ALWAYS useOk()andErr()from@sniptt/monads; AVOID throwing within swapper API implementations
ALWAYS use custom error classes from@shapeshiftoss/errorswith meaningful error codes for internationalization and relevant details in error objects
ALWAYS wrap async op...
Files:
packages/caip/src/adapters/coingecko/utils.test.tspackages/utils/src/index.tssrc/components/Modals/Send/utils.tspackages/swapper/src/utils.tspackages/caip/src/adapters/coingecko/index.test.tssrc/test/mocks/store.ts
**/*.test.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.test.{ts,tsx,js,jsx}: Write tests for critical business logic
Test edge cases and error conditions
Use descriptive test names that explain behavior
Keep tests isolated and independent
Mock external dependencies appropriately
Files:
packages/caip/src/adapters/coingecko/utils.test.tspackages/caip/src/adapters/coingecko/index.test.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
Usehandleprefix for event handlers with descriptive names in camelCase
Use descriptive boolean variable names withis,has,can,shouldprefixes
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 likedata,item,obj, and single-letter variable names except in loops
Avoid abbreviations in names unless they are widely understood
Avoid generic function names likefn,func, orcallback
Files:
packages/caip/src/adapters/coingecko/utils.test.tspackages/utils/src/index.tssrc/components/Modals/Send/utils.tspackages/swapper/src/utils.tspackages/caip/src/adapters/coingecko/index.test.tssrc/test/mocks/store.ts
**/swapper{s,}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/error-handling.mdc)
ALWAYS use
makeSwapErrorRightfor swapper errors withTradeQuoteErrorenum for error codes and provide detailed error information
Files:
packages/swapper/src/utils.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/utils.ts
{.env.development,.env.production}
📄 CodeRabbit inference engine (CLAUDE.md)
Use
.env.developmentfor dev-only features and.env.productionfor prod settings
Files:
.env.development
🧠 Learnings (44)
📓 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: NeOMakinG
Repo: shapeshift/web PR: 10323
File: src/pages/RFOX/components/Stake/components/StakeSummary.tsx:112-114
Timestamp: 2025-08-22T13:00:44.879Z
Learning: NeOMakinG prefers to keep PR changes minimal and focused on the core objectives, avoiding cosmetic or defensive code improvements that aren't directly related to the PR scope, even when they would improve robustness.
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10128
File: .cursor/rules/error-handling.mdc:266-274
Timestamp: 2025-07-29T10:35:22.059Z
Learning: NeOMakinG prefers less nitpicky suggestions on documentation and best practices files, finding overly detailed suggestions on minor implementation details (like console.error vs logger.error) too granular for cursor rules documentation.
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10380
File: src/pages/Dashboard/components/AccountList/AccountTable.tsx:60-0
Timestamp: 2025-09-02T08:34:08.157Z
Learning: NeOMakinG prefers code review comments to focus only on actual PR changes, not pre-existing code issues, unless there are critical security or correctness concerns directly related to the new functionality.
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10234
File: src/components/MultiHopTrade/hooks/useGetTradeQuotes/hooks/useTrackTradeQuotes.ts:42-86
Timestamp: 2025-08-08T11:41:22.794Z
Learning: NeOMakinG prefers not to include refactors in move-only PRs; such suggestions should be deferred to follow-up issues instead of being applied within the same PR.
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10380
File: src/components/Table/Table.theme.ts:177-180
Timestamp: 2025-09-02T12:38:46.940Z
Learning: NeOMakinG prefers to defer technical debt and CSS correctness issues (like improper hover selectors) to follow-up PRs when the current PR is already large and focused on major feature implementation, even when the issues are valid from a usability/technical perspective.
📚 Learning: 2026-01-03T15:12:53.276Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11537
File: packages/caip/src/adapters/coincap/generate.ts:7-7
Timestamp: 2026-01-03T15:12:53.276Z
Learning: In shapeshift/web, when running scripts in the packages/caip area via yarn workspace shapeshiftoss/caip generate, the working directory is packages/caip. Use ../../.env to reach the monorepo root .env file instead of .env. Also note that the -T flag only controls which node_modules are used (root's), not the current working directory. Apply these guidelines to all TypeScript files under packages/caip (i.e., packages/caip/**/*.ts) where environment loading or path resolution could be affected.
Applied to files:
packages/caip/src/adapters/coingecko/utils.test.tspackages/caip/src/adapters/coingecko/index.test.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/utils/src/index.ts
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to **/*.{ts,tsx} : Import types from `shapeshiftoss/caip` for chain/account/asset IDs
Applied to files:
packages/utils/src/index.tspackages/swapper/src/utils.tspackages/caip/src/adapters/coingecko/index.test.ts
📚 Learning: 2025-11-24T21:20:30.085Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/naming-conventions.mdc:0-0
Timestamp: 2025-11-24T21:20:30.085Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Use named exports for components, functions, and utilities instead of default exports
Applied to files:
packages/utils/src/index.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/utils/src/index.tspackages/swapper/src/utils.ts
📚 Learning: 2025-08-17T21:53:03.806Z
Learnt from: 0xApotheosis
Repo: shapeshift/web PR: 10290
File: scripts/generateAssetData/color-map.json:41-47
Timestamp: 2025-08-17T21:53:03.806Z
Learning: In the ShapeShift web codebase, native assets (using CAIP-19 slip44 namespace like eip155:1/slip44:60, bip122:.../slip44:..., cosmos:.../slip44:...) are manually hardcoded and not generated via the automated asset generation script. Only ERC20/BEP20 tokens go through the asset generation process. The validation scripts should only validate generated assets, not manually added native assets.
Applied to files:
packages/utils/src/index.tspackages/caip/src/adapters/coingecko/index.test.ts
📚 Learning: 2025-08-05T23:36:13.214Z
Learnt from: premiumjibles
Repo: shapeshift/web PR: 10187
File: src/state/slices/preferencesSlice/selectors.ts:21-25
Timestamp: 2025-08-05T23:36:13.214Z
Learning: The AssetId type from 'shapeshiftoss/caip' package is a string type alias, so it can be used directly as a return type for cache key resolvers in re-reselect selectors without needing explicit string conversion.
Applied to files:
packages/utils/src/index.tspackages/swapper/src/utils.ts
📚 Learning: 2025-08-29T18:09:45.982Z
Learnt from: kaladinlight
Repo: shapeshift/web PR: 10376
File: vite.config.mts:136-137
Timestamp: 2025-08-29T18:09:45.982Z
Learning: In the ShapeShift web repository vite.config.mts, the commonjsOptions.exclude configuration using bare package name strings like ['shapeshiftoss/caip', 'shapeshiftoss/types'] works correctly for excluding specific packages from CommonJS transformation, despite theoretical concerns about module ID matching patterns.
Applied to files:
packages/utils/src/index.ts
📚 Learning: 2025-08-05T22:41:35.473Z
Learnt from: premiumjibles
Repo: shapeshift/web PR: 10187
File: src/pages/Assets/Asset.tsx:1-1
Timestamp: 2025-08-05T22:41:35.473Z
Learning: In the shapeshift/web codebase, component imports use direct file paths like '@/components/ComponentName/ComponentName' rather than barrel exports. The AssetAccountDetails component should be imported as '@/components/AssetAccountDetails/AssetAccountDetails', not from a directory index.
Applied to files:
packages/utils/src/index.ts
📚 Learning: 2025-09-04T13:22:35.399Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10380
File: src/state/slices/assetsSlice/selectors.ts:45-51
Timestamp: 2025-09-04T13:22:35.399Z
Learning: In shapeshift/web, the isPrimaryAsset function in src/lib/utils/asset.ts is intentionally designed to only treat null relatedAssetKey as primary (not undefined). The asset generation process specifically sets relatedAssetKey to null for primary assets, while undefined means the asset doesn't participate in grouping and should not be considered primary. Only assets with null relatedAssetKey or where relatedAssetKey === assetId are primary assets.
Applied to files:
packages/utils/src/index.ts
📚 Learning: 2025-09-04T17:29:59.479Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10380
File: src/components/TradeAssetSearch/hooks/useGetPopularAssetsQuery.tsx:28-33
Timestamp: 2025-09-04T17:29:59.479Z
Learning: In shapeshift/web, the useGetPopularAssetsQuery function in src/components/TradeAssetSearch/hooks/useGetPopularAssetsQuery.tsx intentionally uses primaryAssets[assetId] instead of falling back to assets[assetId]. The design distributes primary assets across chains by iterating through their related assets and adding the primary asset to each related asset's chain. This ensures primary assets appear in all chains where they have related assets, supporting the grouped asset system.
Applied to files:
packages/utils/src/index.ts
📚 Learning: 2025-09-04T17:35:57.584Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10380
File: src/state/slices/common-selectors.ts:164-178
Timestamp: 2025-09-04T17:35:57.584Z
Learning: In shapeshift/web, while the Asset type allows relatedAssetKey to be AssetId | null | undefined, the actual asset generation and processing system ensures relatedAssetKey is never undefined in practice. All asset creation utilities explicitly set it to either a specific AssetId (for grouped assets) or null (for primary/unique assets). The only undefined assignments occur during intermediate processing phases and get resolved during the final asset generation step.
Applied to files:
packages/utils/src/index.ts
📚 Learning: 2025-09-04T17:35:57.584Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10380
File: src/state/slices/common-selectors.ts:164-178
Timestamp: 2025-09-04T17:35:57.584Z
Learning: In shapeshift/web, while the Asset type allows relatedAssetKey to be AssetId | null | undefined, the actual asset generation and processing system ensures relatedAssetKey is never undefined in practice. All asset creation utilities explicitly set it to either a specific AssetId (for grouped assets) or null (for primary/unique assets). The only exception is temporary undefined assignment during portal asset processing, which gets resolved later in the pipeline.
Applied to files:
packages/utils/src/index.ts
📚 Learning: 2025-10-21T17:11:18.087Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10871
File: src/components/Modals/Send/hooks/useSendDetails/useSendDetails.tsx:426-428
Timestamp: 2025-10-21T17:11:18.087Z
Learning: In src/components/Modals/Send/hooks/useSendDetails/useSendDetails.tsx, within the handleInputChange function, use .toFixed() without arguments (not .toString()) when converting BigNumber amounts for input field synchronization. This avoids exponential notation in the input while preserving precision for presentational components like <Amount.Crypto /> and <Amount.Fiat /> to format appropriately.
Applied to files:
src/components/Modals/Send/utils.ts
📚 Learning: 2025-11-12T12:49:17.895Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11016
File: packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts:109-125
Timestamp: 2025-11-12T12:49:17.895Z
Learning: In packages/chain-adapters/src/evm/utils.ts, the getErc20Data function already includes a guard that returns an empty string when contractAddress is undefined (line 8: `if (!contractAddress) return ''`). This built-in handling means callers don't need to conditionally invoke getErc20Data—it safely handles both ERC20 tokens and native assets.
Applied to files:
src/components/Modals/Send/utils.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/utils.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/utils.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/utils.tssrc/test/mocks/store.ts
📚 Learning: 2025-12-04T11:05:01.146Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11281
File: packages/swapper/src/swappers/PortalsSwapper/utils/fetchSquidStatus.ts:98-106
Timestamp: 2025-12-04T11:05:01.146Z
Learning: In packages/swapper/src/swappers/PortalsSwapper/utils/fetchSquidStatus.ts, getSquidTrackingLink should return blockchain explorer links (using Asset.explorerTxLink) rather than API endpoints. For non-GMP Squid swaps: return source chain explorer link with sourceTxHash when pending/failed, and destination chain explorer link with destinationTxHash when confirmed.
Applied to files:
packages/swapper/src/utils.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/utils.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 **/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/utils.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/utils.tspackages/caip/src/adapters/coingecko/index.test.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/utils.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/utils.tspackages/caip/src/adapters/coingecko/index.test.ts
📚 Learning: 2025-12-09T21:07:22.474Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11335
File: packages/swapper/src/swappers/CetusSwapper/utils/helpers.ts:3-3
Timestamp: 2025-12-09T21:07:22.474Z
Learning: In packages/swapper/src/swappers/CetusSwapper, mysten/sui types (SuiClient, Transaction) must be imported from the nested path within cetusprotocol/aggregator-sdk (e.g., 'cetusprotocol/aggregator-sdk/node_modules/mysten/sui/client') because the aggregator SDK bundles its own version of mysten/sui. Direct imports from 'mysten/sui' break at runtime even when specified in package.json.
Applied to files:
packages/swapper/src/utils.ts
📚 Learning: 2025-10-23T14:27:19.073Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10857
File: src/plugins/walletConnectToDapps/eventsManager/useWalletConnectEventsHandler.ts:101-104
Timestamp: 2025-10-23T14:27:19.073Z
Learning: In WalletConnect wallet_switchEthereumChain and wallet_addEthereumChain requests, the chainId parameter is always present as per the protocol spec. Type guards checking for missing chainId in these handlers (like `if (!evmNetworkIdHex) return`) are solely for TypeScript compiler satisfaction, not real runtime edge cases.
Applied to files:
packages/swapper/src/utils.ts
📚 Learning: 2025-12-17T14:50:01.629Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11449
File: packages/chain-adapters/src/tron/TronChainAdapter.ts:570-596
Timestamp: 2025-12-17T14:50:01.629Z
Learning: In packages/chain-adapters/src/tron/TronChainAdapter.ts, the parseTx method uses `unknown` type for the txHashOrTx parameter intentionally. TRON is a "second-class chain" that works differently from other chains - it accepts either a string hash (to fetch TronTx via unchained client) or a TronTx object directly. The base chain-adapter interface is strongly typed and doesn't accommodate this flexible signature, so `unknown` is used as an appropriate escape hatch rather than a type safety issue.
Applied to files:
packages/swapper/src/utils.ts
📚 Learning: 2025-08-04T15:36:25.122Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10171
File: src/components/MultiHopTrade/components/TradeConfirm/components/ExpandedStepperSteps.tsx:458-458
Timestamp: 2025-08-04T15:36:25.122Z
Learning: In swap transaction handling, buy transaction hashes should always use the swapper's explorer (stepSource) because they are known by the swapper immediately upon swap execution. The conditional logic for using default explorers applies primarily to sell transactions which need to be detected/indexed by external systems like Thorchain or ViewBlock.
Applied to files:
packages/swapper/src/utils.ts
📚 Learning: 2025-08-14T17:54:32.563Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10276
File: src/pages/ThorChainLP/components/ReusableLpStatus/ReusableLpStatus.tsx:97-108
Timestamp: 2025-08-14T17:54:32.563Z
Learning: In ReusableLpStatus component (src/pages/ThorChainLP/components/ReusableLpStatus/ReusableLpStatus.tsx), the txAssets dependency is stable from first render because poolAsset, baseAsset, actionSide, and action are all defined first render, making the current txAssetsStatuses initialization pattern safe without needing useEffect synchronization.
Applied to files:
packages/swapper/src/utils.ts
📚 Learning: 2025-08-04T16:02:27.360Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10171
File: src/components/MultiHopTrade/components/TradeConfirm/components/ExpandedStepperSteps.tsx:458-458
Timestamp: 2025-08-04T16:02:27.360Z
Learning: In multi-hop swap transactions, last hop sell transactions might not be detected by the swapper (unlike buy transactions which are always known immediately). The conditional stepSource logic for last hop buy transactions (`isLastHopSellTxSeen ? stepSource : undefined`) serves as defensive programming for future multi-hop support with intermediate chains, even though multi-hop functionality is not currently supported in production.
Applied to files:
packages/swapper/src/utils.ts
📚 Learning: 2025-11-20T12:00:45.005Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11078
File: src/setupVitest.ts:11-15
Timestamp: 2025-11-20T12:00:45.005Z
Learning: In shapeshift/web, src/setupVitest.ts must redirect 'ethers' to 'ethers5' for shapeshiftoss/hdwallet-trezor (and -trezor-connect), same as ledger and shapeshift-multichain. Removing 'trezor' from the regex causes CI/Vitest failures due to ethers v6 vs v5 API differences.
Applied to files:
packages/caip/src/adapters/coingecko/index.test.ts
📚 Learning: 2025-12-12T16:20:33.904Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11377
File: src/lib/referral/api.ts:30-57
Timestamp: 2025-12-12T16:20:33.904Z
Learning: In shapeshift/web referral feature, the backend expects an EVM address (0x… viem Address) as the owner identifier, not a CAIP AccountId. Update useReferral to derive the first connected EVM address via fromAccountId + getAddress, and do not URL-encode it in the API path.
Applied to files:
packages/caip/src/adapters/coingecko/index.test.ts
📚 Learning: 2025-09-08T15:53:09.362Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10442
File: src/components/TradeAssetSearch/components/GroupedAssetList/GroupedAssetList.tsx:34-35
Timestamp: 2025-09-08T15:53:09.362Z
Learning: In DefaultAssetList.tsx, the GroupedAssetList component already receives the activeChainId prop correctly on line ~58, contrary to automated analysis that may flag it as missing.
Applied to files:
packages/caip/src/adapters/coingecko/index.test.ts
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: To add a new feature flag: (1) Add to `FeatureFlags` type in `src/state/slices/preferencesSlice/preferencesSlice.ts`, (2) Add environment variable validation in `src/config.ts`, (3) Add to initial state in `preferencesSlice.ts`, (4) Add to test mock in `src/test/mocks/store.ts`, (5) Set appropriate values in `.env`, `.env.development`, and `.env.production`
Applied to files:
src/test/mocks/store.ts.env.development
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Mock external dependencies appropriately
Applied to files:
src/test/mocks/store.ts
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Feature flags are stored in Redux state under `preferences.featureFlags`
Applied to files:
src/test/mocks/store.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:
src/test/mocks/store.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:
src/test/mocks/store.ts
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to src/config.ts : Default values always come from environment variables prefixed with `VITE_FEATURE_`
Applied to files:
.env.development
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to {.env.development,.env.production} : Use `.env.development` for dev-only features and `.env.production` for prod settings
Applied to files:
.env.development
📚 Learning: 2025-09-16T13:17:02.938Z
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.
Applied to files:
.env.development
📚 Learning: 2025-09-09T06:01:24.130Z
Learnt from: 0xApotheosis
Repo: shapeshift/web PR: 10424
File: .env.production:3-3
Timestamp: 2025-09-09T06:01:24.130Z
Learning: In Vite, environment variables have a fallback mechanism where .env.production takes precedence over .env, but variables defined only in .env will still be available in the production environment if not overridden in .env.production.
Applied to files:
.env.development
📚 Learning: 2025-12-03T23:19:39.158Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11275
File: headers/csps/chains/plasma.ts:1-10
Timestamp: 2025-12-03T23:19:39.158Z
Learning: For CSP files in headers/csps/chains/, gomesalexandre prefers using Vite's loadEnv() pattern directly to load environment variables (e.g., VITE_PLASMA_NODE_URL, VITE_MONAD_NODE_URL) for consistency with existing second-class chain CSP files, rather than using getConfig() from src/config.ts, even though other parts of the codebase use validated config values.
Applied to files:
.env.development
🧬 Code graph analysis (2)
src/components/Modals/Send/utils.ts (2)
packages/chain-adapters/src/types.ts (1)
GetFeeDataInput(353-360)packages/chain-adapters/src/starknet/types.ts (1)
GetFeeDataInput(21-24)
packages/swapper/src/utils.ts (3)
packages/swapper/src/types.ts (1)
TradeStatus(701-708)src/lib/utils/starknet.ts (1)
assertGetStarknetChainAdapter(16-27)packages/caip/src/constants.ts (1)
starknetChainId(91-91)
🪛 dotenv-linter (4.0.0)
.env.development
[warning] 95-95: [UnorderedKey] The VITE_FEATURE_AVNU_SWAP key should go before the VITE_FEATURE_CETUS_SWAP key
(UnorderedKey)
⏰ 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 (6)
src/test/mocks/store.ts (1)
175-175: LGTM!The AvnuSwap feature flag is correctly added to the mock store, following the established pattern and alphabetical ordering.
packages/caip/src/adapters/coingecko/utils.test.ts (1)
196-198: LGTM! Test coverage extended for Starknet native asset.The Starknet mainnet mapping follows the same pattern as other chain native assets in the test suite.
src/components/Modals/Send/utils.ts (1)
175-184: LGTM! Proper fee estimation input for Starknet.The implementation correctly constructs
GetFeeDataInputfor Starknet fee estimation, aligning with the pattern used for other chains (EVM, Solana, Near, etc.). All required fields (to,value,from) and optional fields (tokenContractAddress,sendMax) are properly mapped from function parameters.packages/utils/src/index.ts (2)
36-36: LGTM! Starknet token namespace support added correctly.The addition of
ASSET_NAMESPACE.starknetTokento theisTokenfunction is correct and follows the established pattern for recognizing token namespaces. This change directly supports the PR objective of enabling Starknet token swaps.
6-23: All new exports are actively used throughout the codebase and necessary for external consumption. The utilities include commonly-used helpers (bn, bnOrZero, makeAsset, isToken, etc.) that are imported across packages/swapper, scripts, state management, and UI components. No action required.packages/swapper/src/utils.ts (1)
2-10: LGTM!The import additions appropriately mirror the existing pattern for other chains (Sui, Solana) and provide the necessary types for Starknet swap status checking.
|
✅ Fixed - added leading zero to make it See: packages/caip/src/adapters/coingecko/index.test.ts:201 |
- Fix Starknet USDC contract address with leading zero for proper felt representation - Move TokenInfo type to ./types for better code organization - Add getNonce() method with deployment status check to prevent nonce errors - Add missing _txDetails fields required for v3 transaction hash computation - Update AVNU swapper to use new getNonce method from chain adapter 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
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
Fix all issues with AI Agents 🤖
In @packages/chain-adapters/src/starknet/StarknetChainAdapter.ts:
- Around line 1059-1062: The nonce fetch currently ignores RPC errors by
defaulting to '0x0'; update the fetch logic in the StarknetChainAdapter where
provider.fetch('starknet_getNonce', ['pending', from]) is called so it mirrors
the fee estimate error handling: after awaiting nonceResponse.json(), check if
nonceResult.error and throw a descriptive Error (e.g., `Failed to fetch nonce:
${nonceResult.error.message}`) before deriving `const nonce = nonceResult.result
|| '0x0'`; apply the same pattern used in the fee estimate/
buildSignAndBroadcastTransaction code paths to ensure consistent RPC error
handling.
- Around line 1123-1146: The current hardcoded tier multipliers in
StarknetChainAdapter.ts (variables slowMaxFee / averageMaxFee / fastMaxFee)
should be replaced with Starknet's fee estimation flow: call the
starknet_estimateFee RPC (or SDK estimateFee helper) to obtain suggestedMaxFee
and resource_bounds, then apply configurable margins (e.g., feeMarginPercentage
and resourceBoundsOverhead) to that suggestedMaxFee to derive tiered fees
instead of using fixed 1.8x/4.5x/10x multipliers; for priority tiers adjust
resource_bounds (max_amount / max_price_per_unit) or a small adjustable fee
margin per tier rather than inflating both amount and price by arbitrary
factors, and remove the BigInt multiplier math in calculateTxFee (or wherever
slowMaxFee/averageMaxFee/fastMaxFee are computed) so the adapter uses the
SDK/RPC estimated fee plus configurable overhead.
📜 Review details
Configuration used: Organization 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.
📒 Files selected for processing (4)
packages/caip/src/adapters/coingecko/index.test.tspackages/chain-adapters/src/starknet/StarknetChainAdapter.tspackages/chain-adapters/src/starknet/types.tspackages/swapper/src/swappers/AvnuSwapper/endpoints.ts
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{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 runyarn lint --fixandyarn type-checkafter making changes
Avoidletvariable assignments - preferconstwith inline IIFE switch statements or extract to functions for conditional logic
Files:
packages/chain-adapters/src/starknet/StarknetChainAdapter.tspackages/chain-adapters/src/starknet/types.tspackages/swapper/src/swappers/AvnuSwapper/endpoints.tspackages/caip/src/adapters/coingecko/index.test.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 inuseMemoand callbacks inuseCallbackwhere 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 usinguseColorModeValuehook
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()fromreact-polyglot
UseuseFeatureFlag('FlagName')hook to access feature flag values in components
Prefertypeoverinterfacefor type definitions
Use strict typing - avoidany
UseNominaltypes for domain identifiers (e.g.,WalletId,AccountId)
Import types from@shapeshiftoss/caipfor chain/account/asset IDs
UseuseAppSelectorfor Redux state
UseuseAppDispatchfor Redux actions
Memoize expensive computations withuseMemo
Memoize callbacks withuseCallback
**/*.{ts,tsx}: UseResult<T, E>pattern for error handling in swappers and APIs; ALWAYS useOk()andErr()from@sniptt/monads; AVOID throwing within swapper API implementations
ALWAYS use custom error classes from@shapeshiftoss/errorswith meaningful error codes for internationalization and relevant details in error objects
ALWAYS wrap async op...
Files:
packages/chain-adapters/src/starknet/StarknetChainAdapter.tspackages/chain-adapters/src/starknet/types.tspackages/swapper/src/swappers/AvnuSwapper/endpoints.tspackages/caip/src/adapters/coingecko/index.test.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
Usehandleprefix for event handlers with descriptive names in camelCase
Use descriptive boolean variable names withis,has,can,shouldprefixes
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 likedata,item,obj, and single-letter variable names except in loops
Avoid abbreviations in names unless they are widely understood
Avoid generic function names likefn,func, orcallback
Files:
packages/chain-adapters/src/starknet/StarknetChainAdapter.tspackages/chain-adapters/src/starknet/types.tspackages/swapper/src/swappers/AvnuSwapper/endpoints.tspackages/caip/src/adapters/coingecko/index.test.ts
**/swapper{s,}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/error-handling.mdc)
ALWAYS use
makeSwapErrorRightfor swapper errors withTradeQuoteErrorenum for error codes and provide detailed error information
Files:
packages/swapper/src/swappers/AvnuSwapper/endpoints.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/AvnuSwapper/endpoints.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/AvnuSwapper/endpoints.ts
packages/swapper/src/swappers/*/*.ts
📄 CodeRabbit inference engine (.cursor/rules/swapper.mdc)
packages/swapper/src/swappers/*/*.ts: All swappers must implement the Swapper interface from packages/swapper/src/types.ts
Implement filterAssetIdsBySellable method to filter assets by supported chain IDs in the sell property
Implement filterBuyAssetsBySellAssetId method to filter assets by supported chain IDs in the buy property
Reuse executeEvmTransaction utility for EVM-based swappers instead of implementing custom transaction execution
Files:
packages/swapper/src/swappers/AvnuSwapper/endpoints.ts
packages/swapper/src/swappers/*/endpoints.ts
📄 CodeRabbit inference engine (.cursor/rules/swapper.mdc)
packages/swapper/src/swappers/*/endpoints.ts: All swapper API implementations must implement the SwapperApi interface from packages/swapper/src/types.ts
Reuse checkEvmSwapStatus utility for checking EVM swap status instead of implementing custom status checks
Files:
packages/swapper/src/swappers/AvnuSwapper/endpoints.ts
**/*.test.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.test.{ts,tsx,js,jsx}: Write tests for critical business logic
Test edge cases and error conditions
Use descriptive test names that explain behavior
Keep tests isolated and independent
Mock external dependencies appropriately
Files:
packages/caip/src/adapters/coingecko/index.test.ts
🧠 Learnings (50)
📓 Common learnings
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: NeOMakinG
Repo: shapeshift/web PR: 10231
File: src/components/MultiHopTrade/components/TradeInput/components/HighlightedTokens.tsx:14-14
Timestamp: 2025-08-08T15:00:22.321Z
Learning: In shapeshift/web reviews for NeOMakinG, avoid nitpicks to change deep-relative imports to '@/…' alias paths within feature/non-refactor PRs; defer such style-only changes to a dedicated follow-up refactor unless they fix an issue.
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10323
File: src/components/ButtonWalletPredicate/ButtonWalletPredicate.tsx:7-7
Timestamp: 2025-08-27T09:47:06.275Z
Learning: In shapeshift/web project, NeOMakinG consistently prefers to defer UI/UX improvements and refactoring work (like the Drawer.Close hack fix in ButtonWalletPredicate.tsx) to follow-up PRs rather than expanding the scope of feature PRs, even when the improvements would enhance robustness.
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: NeOMakinG
Repo: shapeshift/web PR: 10323
File: src/pages/RFOX/components/Stake/components/StakeSummary.tsx:112-114
Timestamp: 2025-08-22T13:00:44.879Z
Learning: NeOMakinG prefers to keep PR changes minimal and focused on the core objectives, avoiding cosmetic or defensive code improvements that aren't directly related to the PR scope, even when they would improve robustness.
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10128
File: .cursor/rules/error-handling.mdc:266-274
Timestamp: 2025-07-29T10:35:22.059Z
Learning: NeOMakinG prefers less nitpicky suggestions on documentation and best practices files, finding overly detailed suggestions on minor implementation details (like console.error vs logger.error) too granular for cursor rules documentation.
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10380
File: src/pages/Dashboard/components/AccountList/AccountTable.tsx:60-0
Timestamp: 2025-09-02T08:34:08.157Z
Learning: NeOMakinG prefers code review comments to focus only on actual PR changes, not pre-existing code issues, unless there are critical security or correctness concerns directly related to the new functionality.
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10234
File: src/components/MultiHopTrade/hooks/useGetTradeQuotes/hooks/useTrackTradeQuotes.ts:42-86
Timestamp: 2025-08-08T11:41:22.794Z
Learning: NeOMakinG prefers not to include refactors in move-only PRs; such suggestions should be deferred to follow-up issues instead of being applied within the same PR.
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10380
File: src/components/Table/Table.theme.ts:177-180
Timestamp: 2025-09-02T12:38:46.940Z
Learning: NeOMakinG prefers to defer technical debt and CSS correctness issues (like improper hover selectors) to follow-up PRs when the current PR is already large and focused on major feature implementation, even when the issues are valid from a usability/technical perspective.
📚 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/chain-adapters/src/starknet/StarknetChainAdapter.tspackages/chain-adapters/src/starknet/types.tspackages/swapper/src/swappers/AvnuSwapper/endpoints.ts
📚 Learning: 2025-12-17T14:50:01.629Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11449
File: packages/chain-adapters/src/tron/TronChainAdapter.ts:570-596
Timestamp: 2025-12-17T14:50:01.629Z
Learning: In packages/chain-adapters/src/tron/TronChainAdapter.ts, the parseTx method uses `unknown` type for the txHashOrTx parameter intentionally. TRON is a "second-class chain" that works differently from other chains - it accepts either a string hash (to fetch TronTx via unchained client) or a TronTx object directly. The base chain-adapter interface is strongly typed and doesn't accommodate this flexible signature, so `unknown` is used as an appropriate escape hatch rather than a type safety issue.
Applied to files:
packages/chain-adapters/src/starknet/StarknetChainAdapter.tspackages/chain-adapters/src/starknet/types.tspackages/swapper/src/swappers/AvnuSwapper/endpoints.ts
📚 Learning: 2025-12-04T22:57:50.850Z
Learnt from: kaladinlight
Repo: shapeshift/web PR: 11290
File: packages/chain-adapters/src/utxo/zcash/ZcashChainAdapter.ts:48-51
Timestamp: 2025-12-04T22:57:50.850Z
Learning: In packages/chain-adapters/src/**/*ChainAdapter.ts files, the getName() method uses the pattern `const enumIndex = Object.values(ChainAdapterDisplayName).indexOf(ChainAdapterDisplayName.XXX); return Object.keys(ChainAdapterDisplayName)[enumIndex]` to reverse-lookup the enum key from its value. This is the established pattern used consistently across almost all chain adapters (Bitcoin, Ethereum, Litecoin, Dogecoin, Polygon, Arbitrum, Cosmos, etc.) and should be preserved for consistency when adding new chain adapters.
Applied to files:
packages/chain-adapters/src/starknet/StarknetChainAdapter.ts
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to **/*.{ts,tsx} : Prefer `type` over `interface` for type definitions
Applied to files:
packages/chain-adapters/src/starknet/StarknetChainAdapter.ts
📚 Learning: 2025-11-24T21:21:12.774Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/typescript-best-practices.mdc:0-0
Timestamp: 2025-11-24T21:21:12.774Z
Learning: Applies to **/*.{ts,tsx} : ALWAYS use utility types for common transformations in TypeScript
Applied to files:
packages/chain-adapters/src/starknet/StarknetChainAdapter.ts
📚 Learning: 2025-11-24T21:21:12.774Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/typescript-best-practices.mdc:0-0
Timestamp: 2025-11-24T21:21:12.774Z
Learning: Applies to **/*.{ts,tsx} : ALWAYS use descriptive property names in TypeScript type definitions
Applied to files:
packages/chain-adapters/src/starknet/StarknetChainAdapter.ts
📚 Learning: 2025-11-24T21:21:12.774Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/typescript-best-practices.mdc:0-0
Timestamp: 2025-11-24T21:21:12.774Z
Learning: Applies to **/*.{ts,tsx} : ALWAYS use explicit types for object shapes using interfaces or type aliases in TypeScript
Applied to files:
packages/chain-adapters/src/starknet/StarknetChainAdapter.ts
📚 Learning: 2025-11-24T21:21:12.774Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/typescript-best-practices.mdc:0-0
Timestamp: 2025-11-24T21:21:12.774Z
Learning: Applies to **/*.{ts,tsx} : ALWAYS use `as` instead of angle bracket syntax for type assertions in TypeScript
Applied to files:
packages/chain-adapters/src/starknet/StarknetChainAdapter.ts
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Prefer procedural and easy to understand code
Applied to files:
packages/chain-adapters/src/starknet/StarknetChainAdapter.ts
📚 Learning: 2025-11-24T21:20:30.085Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/naming-conventions.mdc:0-0
Timestamp: 2025-11-24T21:20:30.085Z
Learning: Applies to **/*.{ts,tsx} : Use suffixes like `Props`, `State`, `Config`, `Type` for interfaces and types when appropriate
Applied to files:
packages/chain-adapters/src/starknet/StarknetChainAdapter.ts
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to **/*.{ts,tsx} : Avoid 'any' types - use specific type annotations instead
Applied to files:
packages/chain-adapters/src/starknet/StarknetChainAdapter.ts
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to **/*.{ts,tsx} : Use strict typing - avoid `any`
Applied to files:
packages/chain-adapters/src/starknet/StarknetChainAdapter.ts
📚 Learning: 2025-11-24T21:20:30.085Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/naming-conventions.mdc:0-0
Timestamp: 2025-11-24T21:20:30.085Z
Learning: Applies to **/*.{ts,tsx} : Use PascalCase for types, interfaces, and enums with descriptive names
Applied to files:
packages/chain-adapters/src/starknet/StarknetChainAdapter.ts
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to **/*.{ts,tsx} : Import types from `shapeshiftoss/caip` for chain/account/asset IDs
Applied to files:
packages/chain-adapters/src/starknet/StarknetChainAdapter.tspackages/chain-adapters/src/starknet/types.tspackages/caip/src/adapters/coingecko/index.test.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/chain-adapters/src/starknet/StarknetChainAdapter.tspackages/chain-adapters/src/starknet/types.tspackages/caip/src/adapters/coingecko/index.test.ts
📚 Learning: 2025-11-12T12:49:17.895Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11016
File: packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts:109-125
Timestamp: 2025-11-12T12:49:17.895Z
Learning: In packages/chain-adapters/src/evm/utils.ts, the getErc20Data function already includes a guard that returns an empty string when contractAddress is undefined (line 8: `if (!contractAddress) return ''`). This built-in handling means callers don't need to conditionally invoke getErc20Data—it safely handles both ERC20 tokens and native assets.
Applied to files:
packages/chain-adapters/src/starknet/StarknetChainAdapter.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/AvnuSwapper/endpoints.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/AvnuSwapper/endpoints.ts
📚 Learning: 2025-12-09T21:06:15.748Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11335
File: packages/swapper/src/swappers/CetusSwapper/endpoints.ts:66-68
Timestamp: 2025-12-09T21:06:15.748Z
Learning: In packages/swapper/src/swappers/CetusSwapper/endpoints.ts, gomesalexandre is comfortable with throwing errors directly in getUnsignedSuiTransaction and similar transaction preparation methods, rather than using the Result pattern. The Result pattern with makeSwapErrorRight/TradeQuoteError is primarily for the main swapper API methods (getTradeQuote, getTradeRate), while helper/preparation methods can use throws.
Applied to files:
packages/swapper/src/swappers/AvnuSwapper/endpoints.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 **/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/AvnuSwapper/endpoints.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/AvnuSwapper/endpoints.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/AvnuSwapper/endpoints.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/AvnuSwapper/endpoints.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/AvnuSwapper/endpoints.ts
📚 Learning: 2025-12-09T21:07:22.474Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11335
File: packages/swapper/src/swappers/CetusSwapper/utils/helpers.ts:3-3
Timestamp: 2025-12-09T21:07:22.474Z
Learning: In packages/swapper/src/swappers/CetusSwapper, mysten/sui types (SuiClient, Transaction) must be imported from the nested path within cetusprotocol/aggregator-sdk (e.g., 'cetusprotocol/aggregator-sdk/node_modules/mysten/sui/client') because the aggregator SDK bundles its own version of mysten/sui. Direct imports from 'mysten/sui' break at runtime even when specified in package.json.
Applied to files:
packages/swapper/src/swappers/AvnuSwapper/endpoints.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/constants.ts : Register new swappers in packages/swapper/src/constants.ts with an entry in the swappers registry mapping SwapperName enum to swapper implementation
Applied to files:
packages/swapper/src/swappers/AvnuSwapper/endpoints.ts
📚 Learning: 2025-11-19T16:59:50.569Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11012
File: src/context/WalletProvider/Vultisig/components/Connect.tsx:24-59
Timestamp: 2025-11-19T16:59:50.569Z
Learning: In src/context/WalletProvider/*/components/Connect.tsx files across the ShapeShift web codebase, the established pattern for handling null/undefined adapter from getAdapter() is to simply check `if (adapter) { ... }` without an else clause. All wallet Connect components (Coinbase, Keplr, Phantom, Ledger, MetaMask, WalletConnectV2, KeepKey, Vultisig) follow this pattern—they reset loading state after the if block but do not show error messages when adapter is null. This is an intentional design decision and should be maintained for consistency.
Applied to files:
packages/swapper/src/swappers/AvnuSwapper/endpoints.ts
📚 Learning: 2025-09-12T13:44:17.019Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/hooks/useSimulateEvmTransaction.ts:0-0
Timestamp: 2025-09-12T13:44:17.019Z
Learning: gomesalexandre prefers letting chain adapter errors throw naturally in useSimulateEvmTransaction rather than adding explicit error handling for missing adapters, consistent with his fail-fast approach and dismissal of defensive validation as "stale" in WalletConnect transaction simulation flows.
Applied to files:
packages/swapper/src/swappers/AvnuSwapper/endpoints.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/AvnuSwapper/endpoints.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/AvnuSwapper/endpoints.ts
📚 Learning: 2025-08-22T12:58:26.590Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10323
File: src/components/Layout/Header/ActionCenter/components/GenericTransactionActionCard.tsx:108-111
Timestamp: 2025-08-22T12:58:26.590Z
Learning: In the RFOX GenericTransactionDisplayType flow in src/components/Layout/Header/ActionCenter/components/GenericTransactionActionCard.tsx, the txHash is always guaranteed to be present according to NeOMakinG, so defensive null checks for txLink are not needed in this context.
Applied to files:
packages/swapper/src/swappers/AvnuSwapper/endpoints.ts
📚 Learning: 2025-09-12T12:04:59.556Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/WalletConnectSigningModal/content/SendTransactionContent.tsx:0-0
Timestamp: 2025-09-12T12:04:59.556Z
Learning: The ShapeShift codebase's fromBaseUnit function correctly handles hex strings (like WalletConnect transaction.value) without manual conversion because bnOrZero -> bn -> new BigNumber() automatically detects and parses hex strings starting with "0x". gomesalexandre confirmed this with concrete evidence showing hex value 0x176d1c49189db correctly converts to 0.000412118294825435 ETH.
Applied to files:
packages/swapper/src/swappers/AvnuSwapper/endpoints.tspackages/caip/src/adapters/coingecko/index.test.ts
📚 Learning: 2025-09-12T12:04:59.556Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/WalletConnectSigningModal/content/SendTransactionContent.tsx:0-0
Timestamp: 2025-09-12T12:04:59.556Z
Learning: gomesalexandre confirmed that fromBaseUnit in the ShapeShift codebase correctly handles hex strings (like transaction.value from WalletConnect) without requiring manual hex-to-decimal conversion, as bnOrZero handles this automatically via BigNumber.js.
Applied to files:
packages/swapper/src/swappers/AvnuSwapper/endpoints.ts
📚 Learning: 2025-09-10T15:34:54.593Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10458
File: src/plugins/walletConnectToDapps/components/modals/EIP712MessageDisplay.tsx:46-59
Timestamp: 2025-09-10T15:34:54.593Z
Learning: After extensive testing by gomesalexandre in PR #10458, dApps do not send EIP-712 domain.chainId as hex or bigint values in practice. The simple String(domain.chainId) conversion is sufficient for real-world usage in WalletConnect dApps structured signing.
Applied to files:
packages/swapper/src/swappers/AvnuSwapper/endpoints.ts
📚 Learning: 2025-10-21T17:11:18.087Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10871
File: src/components/Modals/Send/hooks/useSendDetails/useSendDetails.tsx:426-428
Timestamp: 2025-10-21T17:11:18.087Z
Learning: In src/components/Modals/Send/hooks/useSendDetails/useSendDetails.tsx, within the handleInputChange function, use .toFixed() without arguments (not .toString()) when converting BigNumber amounts for input field synchronization. This avoids exponential notation in the input while preserving precision for presentational components like <Amount.Crypto /> and <Amount.Fiat /> to format appropriately.
Applied to files:
packages/swapper/src/swappers/AvnuSwapper/endpoints.ts
📚 Learning: 2025-08-05T16:39:58.598Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10191
File: src/pages/Explore/Explore.tsx:56-56
Timestamp: 2025-08-05T16:39:58.598Z
Learning: In the ShapeShift web codebase, the established pattern for handling floating point numbers is to use BigNumber operations (bnOrZero, bn) for calculations and convert to strings using .toString() before passing to UI components like Amount.Fiat, Amount.Crypto, and Amount.Percent. This prevents JavaScript floating point precision issues and maintains consistency across the application.
Applied to files:
packages/swapper/src/swappers/AvnuSwapper/endpoints.ts
📚 Learning: 2025-10-15T15:57:39.956Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10810
File: src/plugins/walletConnectToDapps/utils/tenderly/index.ts:212-0
Timestamp: 2025-10-15T15:57:39.956Z
Learning: gomesalexandre uses discriminated union patterns (e.g., `isEIP1559 ? { max_fee_per_gas, max_priority_fee_per_gas } : { gas_price }`) in WalletConnect flows without additional validation guards, trusting that the runtime data structure ensures mutual exclusivity between EIP-1559 and legacy gas pricing fields.
Applied to files:
packages/swapper/src/swappers/AvnuSwapper/endpoints.ts
📚 Learning: 2025-08-05T17:00:30.416Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10191
File: src/pages/Explore/components/AssetSearchRow.tsx:78-78
Timestamp: 2025-08-05T17:00:30.416Z
Learning: In BigNumber operations within the ShapeShift codebase, floating point literals like 0.01 should always be passed as strings like '0.01' to maintain precision. This applies to all BigNumber methods including .times(), .div(), .plus(), and .minus().
Applied to files:
packages/swapper/src/swappers/AvnuSwapper/endpoints.ts
📚 Learning: 2025-09-11T22:53:19.837Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/EIP155TransactionConfirmation.tsx:27-31
Timestamp: 2025-09-11T22:53:19.837Z
Learning: gomesalexandre trusts Tenderly's data quality and doesn't want defensive validation for gas values (transaction?.gasLimit ?? transaction?.gas) in WalletConnect flows, preferring to rely on the external service providing valid hex values.
Applied to files:
packages/swapper/src/swappers/AvnuSwapper/endpoints.ts
📚 Learning: 2025-09-12T13:43:19.770Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/utils/EIP155RequestHandlerUtil.ts:94-103
Timestamp: 2025-09-12T13:43:19.770Z
Learning: gomesalexandre has implemented a reliable gasLimit flow in WalletConnect dApps where Tenderly simulation provides gas estimates that get written to the form via setValue in GasSelectionMenu.tsx, making customTransactionData.gasLimit the primary reliable source. The sendTransaction.gasLimit fallback is kept as "paranoia" but may rarely be hit in practice due to this simulation-based architecture.
Applied to files:
packages/swapper/src/swappers/AvnuSwapper/endpoints.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/AvnuSwapper/endpoints.ts
📚 Learning: 2025-11-18T09:52:51.368Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10334
File: src/lib/user/api.ts:46-105
Timestamp: 2025-11-18T09:52:51.368Z
Learning: In the shapeshift/web repository, monadic error-handling with Result types (Ok/Err from sniptt/monads) is specific to the swapper domain and is not used anywhere else in the codebase. API helpers outside the swapper domain (e.g., user API, notification services) should use traditional throw/catch error handling patterns instead of Result monads.
Applied to files:
packages/swapper/src/swappers/AvnuSwapper/endpoints.ts
📚 Learning: 2025-12-22T23:36:06.927Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11513
File: src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeQuotes.tsx:293-308
Timestamp: 2025-12-22T23:36:06.927Z
Learning: In the swapper types (TradeQuote/TradeRate), the `steps` property is defined as a tuple type that guarantees at least one element: `steps: [TradeQuoteStep] | [TradeQuoteStep, TradeQuoteStep] | [TradeRateStep] | [TradeRateStep, TradeRateStep]`. Therefore, runtime guards checking for empty arrays when accessing steps elements are unnecessary - TypeScript's type system already prevents this scenario.
Applied to files:
packages/swapper/src/swappers/AvnuSwapper/endpoints.ts
📚 Learning: 2025-08-17T21:53:03.806Z
Learnt from: 0xApotheosis
Repo: shapeshift/web PR: 10290
File: scripts/generateAssetData/color-map.json:41-47
Timestamp: 2025-08-17T21:53:03.806Z
Learning: In the ShapeShift web codebase, native assets (using CAIP-19 slip44 namespace like eip155:1/slip44:60, bip122:.../slip44:..., cosmos:.../slip44:...) are manually hardcoded and not generated via the automated asset generation script. Only ERC20/BEP20 tokens go through the asset generation process. The validation scripts should only validate generated assets, not manually added native assets.
Applied to files:
packages/caip/src/adapters/coingecko/index.test.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/caip/src/adapters/coingecko/index.test.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/caip/src/adapters/coingecko/index.test.ts
📚 Learning: 2025-09-08T15:53:09.362Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10442
File: src/components/TradeAssetSearch/components/GroupedAssetList/GroupedAssetList.tsx:34-35
Timestamp: 2025-09-08T15:53:09.362Z
Learning: In DefaultAssetList.tsx, the GroupedAssetList component already receives the activeChainId prop correctly on line ~58, contrary to automated analysis that may flag it as missing.
Applied to files:
packages/caip/src/adapters/coingecko/index.test.ts
📚 Learning: 2025-12-12T16:20:33.904Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11377
File: src/lib/referral/api.ts:30-57
Timestamp: 2025-12-12T16:20:33.904Z
Learning: In shapeshift/web referral feature, the backend expects an EVM address (0x… viem Address) as the owner identifier, not a CAIP AccountId. Update useReferral to derive the first connected EVM address via fromAccountId + getAddress, and do not URL-encode it in the API path.
Applied to files:
packages/caip/src/adapters/coingecko/index.test.ts
📚 Learning: 2026-01-03T15:12:53.276Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11537
File: packages/caip/src/adapters/coincap/generate.ts:7-7
Timestamp: 2026-01-03T15:12:53.276Z
Learning: In shapeshift/web, when running scripts in the packages/caip area via yarn workspace shapeshiftoss/caip generate, the working directory is packages/caip. Use ../../.env to reach the monorepo root .env file instead of .env. Also note that the -T flag only controls which node_modules are used (root's), not the current working directory. Apply these guidelines to all TypeScript files under packages/caip (i.e., packages/caip/**/*.ts) where environment loading or path resolution could be affected.
Applied to files:
packages/caip/src/adapters/coingecko/index.test.ts
🧬 Code graph analysis (4)
packages/chain-adapters/src/starknet/StarknetChainAdapter.ts (2)
packages/chain-adapters/src/starknet/types.ts (4)
TokenInfo(16-22)RpcJsonResponse(39-45)StarknetNonceResult(47-47)GetFeeDataInput(29-32)packages/caip/src/assetId/assetId.ts (1)
AssetId(17-17)
packages/chain-adapters/src/starknet/types.ts (1)
packages/caip/src/assetId/assetId.ts (1)
AssetId(17-17)
packages/swapper/src/swappers/AvnuSwapper/endpoints.ts (4)
packages/swapper/src/types.ts (2)
SwapperApi(760-791)TradeStatus(701-708)packages/swapper/src/utils.ts (4)
isExecutableTradeQuote(331-332)getExecutableTradeStep(337-347)createDefaultStatusResponse(220-224)checkStarknetSwapStatus(439-468)src/lib/utils/starknet.ts (1)
assertGetStarknetChainAdapter(16-27)packages/chain-adapters/src/utils/bip44.ts (1)
toAddressNList(42-44)
packages/caip/src/adapters/coingecko/index.test.ts (2)
packages/caip/src/assetId/assetId.ts (1)
toAssetId(59-127)packages/caip/src/constants.ts (2)
CHAIN_NAMESPACE(93-102)CHAIN_REFERENCE(108-135)
⏰ 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: Call / Static
🔇 Additional comments (10)
packages/swapper/src/swappers/AvnuSwapper/endpoints.ts (3)
1-19: LGTM! Clean API structure and imports.The avnuApi implementation correctly follows the SwapperApi interface pattern with proper imports from AVNU SDK, chain adapters, and internal swapper utilities.
21-205: Excellent implementation of Starknet transaction preparation!The
getUnsignedStarknetTransactionmethod is well-structured with:
- Proper input validation and error handling
- Correct AVNU SDK integration with slippage conversion
- Complete Starknet v3 transaction format with all required fields
- Appropriate fee estimation with 5x gas amount and 2x gas price buffers
- All past review concerns addressed (adapter.getNonce() usage, complete _txDetails fields)
The resource bounds are correctly stored as BigInt for hash calculation and will be converted to hex during broadcast by the chain adapter.
207-227: LGTM! Fee and status methods follow established patterns.Both
getStarknetTransactionFeesandcheckTradeStatusare correctly implemented:
- Fee extraction validates the quote and provides meaningful error messages
- Status checking follows the standard pattern with appropriate fallback behavior
- Proper delegation to shared utility functions
packages/caip/src/adapters/coingecko/index.test.ts (1)
197-202: LGTM!The Starknet USDC asset integration is correct. The address now includes the proper leading zero (0x033...) as noted in the previous review, ensuring the full 63-hex-character felt representation required for Starknet mainnet.
Also applies to: 219-219
packages/chain-adapters/src/starknet/types.ts (2)
16-22: LGTM!The
TokenInfotype is well-structured with explicit types for all fields, using theAssetIdnominal type from@shapeshiftoss/caipand descriptive property names as per coding guidelines.
77-81: LGTM!The
StarknetTxDetailsextensions correctly implement Starknet v3 transaction fields. The literal union types (0 | 1) for data availability modes are appropriate (L1=0, L2=1), and all fields follow explicit typing conventions.packages/chain-adapters/src/starknet/StarknetChainAdapter.ts (4)
8-8: LGTM!The infrastructure setup for batched balance queries is well-designed. The dual RpcProvider approach (one for single calls, one for automatic batching) with clear explanatory comments, along with PQueue rate limiting (1 batch per 100ms), demonstrates thoughtful handling of RPC endpoint constraints. The
getKnownTokensdefault fallback avoids race conditions with asset service initialization.Also applies to: 40-40, 46-46, 67-89
157-266: LGTM!The
getAccountrefactor with batched balance queries is well-implemented. The batch size of 50, queue-based rate limiting, and automatic RPC batching viabatchedProvider(batch: 0) provide good balance between performance and reliability. Error handling returns zero balances for failed calls (defensive), and the final filter removes malformed tokens. The logic correctly separates native STRK balance from token balances.
305-319: LGTM!The nonce handling and deployment checks in the transaction building flow are correct. The
getNoncemethod safely returns'0x0'for undeployed accounts, andbuildSendApiTransaction(line 542-549) properly validates account deployment before any fee estimation or nonce fetching, providing a clear error message for undeployed accounts.Also applies to: 542-549, 601-604, 681-693
827-831: LGTM!The extended transaction details fields (
nonceDataAvailabilityMode,feeDataAvailabilityMode,tip,paymasterData,accountDeploymentData) correctly align with theStarknetTxDetailstype extensions and Starknet v3 transaction specification. Values are set appropriately (L1 DA modes = 0, tip = '0x0', empty arrays for optional fields).
a5538a1 to
1b8bfa1
Compare
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
🧹 Nitpick comments (2)
packages/swapper/src/swappers/AvnuSwapper/swapperApi/getTradeQuote.ts (2)
48-73: Consider removing redundant validation checks for required fields.The validation checks for
accountNumber(line 48) andreceiveAddress(line 66) are redundant since these are required (non-optional) fields inCommonTradeQuoteInput. TypeScript's type system already guarantees these values are defined.The
sendAddresscheck (line 57) is valid since it's an optional field in the input type.🔎 Proposed refactor to remove redundant checks
- if (accountNumber === undefined) { - return Err( - makeSwapErrorRight({ - message: `accountNumber is required`, - code: TradeQuoteError.UnknownError, - }), - ) - } - if (sendAddress === undefined) { return Err( makeSwapErrorRight({ message: `sendAddress is required`, code: TradeQuoteError.UnknownError, }), ) } - - if (receiveAddress === undefined) { - return Err( - makeSwapErrorRight({ - message: `receiveAddress is required`, - code: TradeQuoteError.UnknownError, - }), - ) - }
100-107: Remove redundant bestQuote validation.The check
if (!bestQuote)at line 100 is redundant because ifquotes.length > 0(validated at line 89), thenquotes[0]cannot beundefined.🔎 Proposed refactor to remove redundant check
if (!quotes || quotes.length === 0) { return Err( makeSwapErrorRight({ message: 'No quotes available for this trade pair', code: TradeQuoteError.NoRouteFound, }), ) } const bestQuote = quotes[0] - - if (!bestQuote) { - return Err( - makeSwapErrorRight({ - message: 'No valid quote returned from AVNU', - code: TradeQuoteError.QueryFailed, - }), - ) - }
📜 Review details
Configuration used: Organization 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.
📒 Files selected for processing (5)
packages/caip/src/adapters/coingecko/index.test.tspackages/swapper/src/swappers/AvnuSwapper/swapperApi/getTradeQuote.tspackages/swapper/src/swappers/AvnuSwapper/swapperApi/getTradeRate.tspackages/swapper/src/swappers/utils/helpers/helpers.tspackages/utils/src/treasury.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- packages/caip/src/adapters/coingecko/index.test.ts
- packages/swapper/src/swappers/AvnuSwapper/swapperApi/getTradeRate.ts
🧰 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 runyarn lint --fixandyarn type-checkafter making changes
Avoidletvariable assignments - preferconstwith inline IIFE switch statements or extract to functions for conditional logic
Files:
packages/swapper/src/swappers/utils/helpers/helpers.tspackages/utils/src/treasury.tspackages/swapper/src/swappers/AvnuSwapper/swapperApi/getTradeQuote.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 inuseMemoand callbacks inuseCallbackwhere 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 usinguseColorModeValuehook
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()fromreact-polyglot
UseuseFeatureFlag('FlagName')hook to access feature flag values in components
Prefertypeoverinterfacefor type definitions
Use strict typing - avoidany
UseNominaltypes for domain identifiers (e.g.,WalletId,AccountId)
Import types from@shapeshiftoss/caipfor chain/account/asset IDs
UseuseAppSelectorfor Redux state
UseuseAppDispatchfor Redux actions
Memoize expensive computations withuseMemo
Memoize callbacks withuseCallback
**/*.{ts,tsx}: UseResult<T, E>pattern for error handling in swappers and APIs; ALWAYS useOk()andErr()from@sniptt/monads; AVOID throwing within swapper API implementations
ALWAYS use custom error classes from@shapeshiftoss/errorswith meaningful error codes for internationalization and relevant details in error objects
ALWAYS wrap async op...
Files:
packages/swapper/src/swappers/utils/helpers/helpers.tspackages/utils/src/treasury.tspackages/swapper/src/swappers/AvnuSwapper/swapperApi/getTradeQuote.ts
**/swapper{s,}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/error-handling.mdc)
ALWAYS use
makeSwapErrorRightfor swapper errors withTradeQuoteErrorenum for error codes and provide detailed error information
Files:
packages/swapper/src/swappers/utils/helpers/helpers.tspackages/swapper/src/swappers/AvnuSwapper/swapperApi/getTradeQuote.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
Usehandleprefix for event handlers with descriptive names in camelCase
Use descriptive boolean variable names withis,has,can,shouldprefixes
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 likedata,item,obj, and single-letter variable names except in loops
Avoid abbreviations in names unless they are widely understood
Avoid generic function names likefn,func, orcallback
Files:
packages/swapper/src/swappers/utils/helpers/helpers.tspackages/utils/src/treasury.tspackages/swapper/src/swappers/AvnuSwapper/swapperApi/getTradeQuote.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/utils/helpers/helpers.tspackages/swapper/src/swappers/AvnuSwapper/swapperApi/getTradeQuote.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/utils/helpers/helpers.tspackages/swapper/src/swappers/AvnuSwapper/swapperApi/getTradeQuote.ts
🧠 Learnings (18)
📓 Common learnings
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10231
File: src/components/MultiHopTrade/components/TradeInput/components/HighlightedTokens.tsx:14-14
Timestamp: 2025-08-08T15:00:22.321Z
Learning: In shapeshift/web reviews for NeOMakinG, avoid nitpicks to change deep-relative imports to '@/…' alias paths within feature/non-refactor PRs; defer such style-only changes to a dedicated follow-up refactor unless they fix an issue.
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: 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: 11335
File: packages/swapper/src/swappers/CetusSwapper/utils/helpers.ts:3-3
Timestamp: 2025-12-09T21:07:22.474Z
Learning: In packages/swapper/src/swappers/CetusSwapper, mysten/sui types (SuiClient, Transaction) must be imported from the nested path within cetusprotocol/aggregator-sdk (e.g., 'cetusprotocol/aggregator-sdk/node_modules/mysten/sui/client') because the aggregator SDK bundles its own version of mysten/sui. Direct imports from 'mysten/sui' break at runtime even when specified in package.json.
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10323
File: src/pages/RFOX/components/Stake/components/StakeSummary.tsx:112-114
Timestamp: 2025-08-22T13:00:44.879Z
Learning: NeOMakinG prefers to keep PR changes minimal and focused on the core objectives, avoiding cosmetic or defensive code improvements that aren't directly related to the PR scope, even when they would improve robustness.
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10128
File: .cursor/rules/error-handling.mdc:266-274
Timestamp: 2025-07-29T10:35:22.059Z
Learning: NeOMakinG prefers less nitpicky suggestions on documentation and best practices files, finding overly detailed suggestions on minor implementation details (like console.error vs logger.error) too granular for cursor rules documentation.
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10380
File: src/pages/Dashboard/components/AccountList/AccountTable.tsx:60-0
Timestamp: 2025-09-02T08:34:08.157Z
Learning: NeOMakinG prefers code review comments to focus only on actual PR changes, not pre-existing code issues, unless there are critical security or correctness concerns directly related to the new functionality.
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10234
File: src/components/MultiHopTrade/hooks/useGetTradeQuotes/hooks/useTrackTradeQuotes.ts:42-86
Timestamp: 2025-08-08T11:41:22.794Z
Learning: NeOMakinG prefers not to include refactors in move-only PRs; such suggestions should be deferred to follow-up issues instead of being applied within the same PR.
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10380
File: src/components/Table/Table.theme.ts:177-180
Timestamp: 2025-09-02T12:38:46.940Z
Learning: NeOMakinG prefers to defer technical debt and CSS correctness issues (like improper hover selectors) to follow-up PRs when the current PR is already large and focused on major feature implementation, even when the issues are valid from a usability/technical perspective.
📚 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/utils/helpers/helpers.tspackages/utils/src/treasury.tspackages/swapper/src/swappers/AvnuSwapper/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/swappers/*/*.ts : Implement filterBuyAssetsBySellAssetId method to filter assets by supported chain IDs in the buy property
Applied to files:
packages/swapper/src/swappers/utils/helpers/helpers.tspackages/swapper/src/swappers/AvnuSwapper/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/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/utils/helpers/helpers.tspackages/utils/src/treasury.tspackages/swapper/src/swappers/AvnuSwapper/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/swappers/*/*.ts : Implement filterAssetIdsBySellable method to filter assets by supported chain IDs in the sell property
Applied to files:
packages/swapper/src/swappers/utils/helpers/helpers.tspackages/swapper/src/swappers/AvnuSwapper/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/swappers/*/*.ts : Reuse executeEvmTransaction utility for EVM-based swappers instead of implementing custom transaction execution
Applied to files:
packages/swapper/src/swappers/utils/helpers/helpers.tspackages/swapper/src/swappers/AvnuSwapper/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/swappers/**/*.ts : Avoid side effects in swap logic; ensure swap methods are deterministic and stateless
Applied to files:
packages/swapper/src/swappers/utils/helpers/helpers.ts
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to **/*.{ts,tsx} : Import types from `shapeshiftoss/caip` for chain/account/asset IDs
Applied to files:
packages/swapper/src/swappers/utils/helpers/helpers.tspackages/utils/src/treasury.ts
📚 Learning: 2025-12-09T21:07:22.474Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11335
File: packages/swapper/src/swappers/CetusSwapper/utils/helpers.ts:3-3
Timestamp: 2025-12-09T21:07:22.474Z
Learning: In packages/swapper/src/swappers/CetusSwapper, mysten/sui types (SuiClient, Transaction) must be imported from the nested path within cetusprotocol/aggregator-sdk (e.g., 'cetusprotocol/aggregator-sdk/node_modules/mysten/sui/client') because the aggregator SDK bundles its own version of mysten/sui. Direct imports from 'mysten/sui' break at runtime even when specified in package.json.
Applied to files:
packages/swapper/src/swappers/utils/helpers/helpers.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/utils/helpers/helpers.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/constants.ts : Register new swappers in packages/swapper/src/constants.ts with an entry in the swappers registry mapping SwapperName enum to swapper implementation
Applied to files:
packages/swapper/src/swappers/utils/helpers/helpers.ts
📚 Learning: 2025-10-23T14:27:19.073Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10857
File: src/plugins/walletConnectToDapps/eventsManager/useWalletConnectEventsHandler.ts:101-104
Timestamp: 2025-10-23T14:27:19.073Z
Learning: In WalletConnect wallet_switchEthereumChain and wallet_addEthereumChain requests, the chainId parameter is always present as per the protocol spec. Type guards checking for missing chainId in these handlers (like `if (!evmNetworkIdHex) return`) are solely for TypeScript compiler satisfaction, not real runtime edge cases.
Applied to files:
packages/swapper/src/swappers/utils/helpers/helpers.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 **/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/AvnuSwapper/swapperApi/getTradeQuote.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/AvnuSwapper/swapperApi/getTradeQuote.ts
📚 Learning: 2025-12-09T21:06:15.748Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11335
File: packages/swapper/src/swappers/CetusSwapper/endpoints.ts:66-68
Timestamp: 2025-12-09T21:06:15.748Z
Learning: In packages/swapper/src/swappers/CetusSwapper/endpoints.ts, gomesalexandre is comfortable with throwing errors directly in getUnsignedSuiTransaction and similar transaction preparation methods, rather than using the Result pattern. The Result pattern with makeSwapErrorRight/TradeQuoteError is primarily for the main swapper API methods (getTradeQuote, getTradeRate), while helper/preparation methods can use throws.
Applied to files:
packages/swapper/src/swappers/AvnuSwapper/swapperApi/getTradeQuote.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/AvnuSwapper/swapperApi/getTradeQuote.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/AvnuSwapper/swapperApi/getTradeQuote.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/AvnuSwapper/swapperApi/getTradeQuote.ts
🧬 Code graph analysis (2)
packages/swapper/src/swappers/utils/helpers/helpers.ts (1)
packages/utils/src/treasury.ts (1)
DAO_TREASURY_STARKNET(39-40)
packages/swapper/src/swappers/AvnuSwapper/swapperApi/getTradeQuote.ts (6)
packages/swapper/src/types.ts (3)
CommonTradeQuoteInput(194-199)TradeQuote(555-560)SwapErrorRight(105-111)packages/swapper/src/swappers/AvnuSwapper/utils/constants.ts (1)
AVNU_SUPPORTED_CHAIN_IDS(4-4)packages/swapper/src/swappers/AvnuSwapper/index.ts (1)
AVNU_SUPPORTED_CHAIN_IDS(1-1)packages/swapper/src/utils.ts (2)
makeSwapErrorRight(40-56)getInputOutputRate(315-329)packages/swapper/src/swappers/AvnuSwapper/utils/helpers.ts (1)
getTokenAddress(13-23)packages/swapper/src/swappers/utils/helpers/helpers.ts (1)
getTreasuryAddressFromChainId(74-82)
🔇 Additional comments (8)
packages/swapper/src/swappers/utils/helpers/helpers.ts (2)
28-28: LGTM!The import correctly adds the Starknet treasury constant following the existing pattern.
71-71: The Starknet treasury address mapping requires verification from the DAO before merging.The address
0x05513953e22e358a332636048723402f5fc31e19ae2c59750048e2d38141029fis not documented in ShapeShift's official FOX token page or Starknet's official documentation. ShapeShift's public treasury documentation currently lists treasuries only on Ethereum, Arbitrum, Base, Gnosis, Optimism, and Polygon—Starknet is absent. Before adding this mapping, confirm this address is an authorized DAO treasury address and have it documented in official channels to prevent potential fund loss.⛔ Skipped due to learnings
Learnt from: gomesalexandre Repo: shapeshift/web PR: 10751 File: src/Routes/RoutesCommon.tsx:190-190 Timestamp: 2025-10-13T11:55:57.439Z Learning: In the shapeshift/web codebase, there are multiple independent claim systems: Arbitrum bridge claims (removed in PR #10751), RFOX claims (in src/pages/RFOX/components/Claim/), and TCY claims (in src/pages/TCY/). Each has its own routes, components, and logic. When reviewing claim-related changes, distinguish which system is being modified and avoid suggesting changes to unrelated claim systems.packages/utils/src/treasury.ts (2)
18-18: LGTM!The addition of
StarknetMainnetto thetreasuryChainIdsarray is correct and properly expands theTreasuryChainIdtype.
39-40: LGTM!The constant definition follows the correct naming convention and the address format appears valid for Starknet (properly padded with leading zeros).
packages/swapper/src/swappers/AvnuSwapper/swapperApi/getTradeQuote.ts (4)
1-13: LGTM!Imports are appropriate and follow the swapper architecture patterns. The use of
@sniptt/monadsfor Result types and proper helper imports align with established conventions.
178-186: LGTM!Error handling properly follows the swapper architecture using the Result pattern with
makeSwapErrorRightand includes the error cause for debugging. The implementation correctly wraps exceptions inSwapErrorRightwith an appropriate error code.
111-121: LGTM!Fee estimation correctly uses the Starknet adapter's
getFeeDatawith appropriate parameters to simulate a token transfer for accurate fee calculation.
130-141: Verify the semantics of AVNU SDK'sintegratorFeesparameter and buyAmount calculation.The pattern in the codebase shows other swappers calculating different values for
buyAmountBeforeFeesCryptoBaseUnitandbuyAmountAfterFeesCryptoBaseUnitwhen protocol fees are involved (see ZrxSwapper, RelaySwapper, PortalsSwapper). However, AVNU sets both fields to the same value while also calculatingprotocolFeesas a percentage of the post-fee amount.Clarify:
- Does passing
integratorFeesto AVNU'sgetQuotescause the SDK to deduct these fees from the returnedbuyAmount, or is it just metadata?- If fees are deducted by the SDK, should
buyAmountBeforeFeesCryptoBaseUnitbe calculated to recover the pre-fee amount?
Description
1000 birds one stone:
Issue (if applicable)
Nothing to close
Risk
Low, under a flag
Testing
Engineering
Operations
Screenshots (if applicable)
Summary by CodeRabbit
New Features
Chores
Tests
✏️ Tip: You can customize this high-level summary in your review settings.