-
Notifications
You must be signed in to change notification settings - Fork 197
feat: implement cetus for sui tokens swaps #11240
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
* fix: restore desktop accounts page routing When the wallet route was removed from desktop in commit 3356c29, the accounts page routing was also removed, causing /wallet/accounts to redirect to /trade instead of showing account details. This restores the accounts route for desktop while keeping other /wallet/* routes redirecting to /trade as intended. Fixes #11058 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * refactor: unify accounts routing to use /accounts path Changed from dual routing (/wallet/accounts on desktop, /accounts on mobile) to a unified /accounts route that works on both platforms. Changes: - Wrapped Accounts component with Main layout and DashboardHeader - Removed /wallet/accounts route from Desktop Dashboard - Updated all link generators to use /accounts path - Removed conditional basePath logic This simplifies the codebase and provides consistent routing across platforms. Related to #11058 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * feat: make it better * refactor: unify accounts routing and complete wallet route removal cleanup This refactor addresses routing issues from PR #10923 that removed the desktop wallet route but left incomplete cleanup. Routing Changes: - Unified all account routes from /wallet/accounts to /accounts - Updated route parsing hooks (useRouteAccountId, useRouteAssetId) - Updated all link generators to use /accounts path - Desktop /accounts list redirects to /trade (only specific account pages work) - Mobile /accounts list works as expected Component Cleanup (PR #10923 missed items): - Removed desktop wallet tabs (Overview, Wallet, DeFi, Activity) - Removed desktop net worth display from account pages - Deleted orphaned DashboardTab.tsx component (69 lines) - Removed unused route props from AccountDetails, AssetAccountDetails, Asset - Made AssetHeader consistent across all account pages Bug Fixes: - AccountEntryRow now routes to account pages instead of asset pages - Fixed AccountToken redirect path - Updated MixPanel tracking for new route structure - Cleaned up sitemap.txt (removed 4 deprecated routes) Fixes #11058, #11175 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * feat: cleanup --------- Co-authored-by: Claude <[email protected]> Co-authored-by: Jibles <[email protected]>
Bumps [node-forge](https://github.com/digitalbazaar/forge) from 1.3.1 to 1.3.2. - [Changelog](https://github.com/digitalbazaar/forge/blob/main/CHANGELOG.md) - [Commits](digitalbazaar/forge@v1.3.1...v1.3.2) --- updated-dependencies: - dependency-name: node-forge dependency-version: 1.3.2 dependency-type: indirect ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Update UserMenu.tsx Co-authored-by: gomes <[email protected]>
|
Warning Rate limit exceeded@gomesalexandre has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 5 minutes and 33 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughAdds Cetus Sui swapper: feature flag and env entries, CSP connect-src additions, Cetus SDK dependency, new Cetus swapper implementation (quotes, rates, unsigned tx, fees), helper utilities, Sui chain-adapter changes, UI icon, state/feature gating, tests, and a migration entry. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant User
participant UI
participant CetusAPI as CetusSwapper API
participant Helpers as Cetus Helpers
participant SDK as Cetus SDK
participant ChainAdapter as SuiChainAdapter
participant SuiNet as Sui Network
User->>UI: choose Cetus and submit swap params
UI->>CetusAPI: getTradeQuote(params)
CetusAPI->>Helpers: findBestPool(sellCoinType,buyCoinType)
Helpers->>SDK: query pools
SDK-->>Helpers: pool list
Helpers-->>CetusAPI: selected pool
CetusAPI->>Helpers: calculateSwapAmounts(pool,assets,amount)
Helpers->>SDK: preswap
SDK-->>Helpers: estimated amounts & fee
Helpers-->>CetusAPI: estimates
CetusAPI->>ChainAdapter: getFeeData()
ChainAdapter->>SuiNet: getReferenceGasPrice()
SuiNet-->>ChainAdapter: gasPrice
ChainAdapter-->>CetusAPI: fee data
CetusAPI-->>UI: TradeQuote (amounts, fees)
UI->>CetusAPI: getUnsignedSuiTransaction(quote)
CetusAPI->>Helpers: determineSwapDirection(...)
CetusAPI->>SDK: buildSwapPayload & tx bytes
SDK-->>CetusAPI: intentMessageBytes, txBytes
CetusAPI-->>UI: unsigned tx (addressNList, intentMessageBytes)
UI->>SuiNet: broadcast signed tx
SuiNet-->>UI: txHash
UI->>CetusAPI: checkTradeStatus(txHash)
CetusAPI->>ChainAdapter: checkSuiSwapStatus(txHash)
ChainAdapter->>SuiNet: query tx status
SuiNet-->>ChainAdapter: status
ChainAdapter-->>CetusAPI: TradeStatus
CetusAPI-->>UI: trade status
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
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 |
278867d to
3eec9f1
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: 7
🧹 Nitpick comments (6)
packages/chain-adapters/src/sui/SuiChainAdapter.ts (1)
464-467: Document the rationale for the hardcoded gas estimate.The
50_000_000n(50M MIST) gas estimate is a reasonable approximation for simple token transfers, but consider adding a comment explaining this value. If actual token transfer costs vary significantly, users could experience transaction failures or overpay.if (tokenId && tokenId.startsWith('0x') && tokenId.includes('::')) { + // Pre-estimated gas for standard token transfers + // Based on typical Sui token transfer costs; includes 20% buffer const estimatedGas = 50_000_000n const gasBudget = ((estimatedGas * 120n) / 100n).toString() const txFee = estimatedGas.toString().env (1)
232-232: Consider reordering for consistency.The linter suggests placing
VITE_FEATURE_CETUS_SWAPbeforeVITE_FEATURE_TRONto maintain alphabetical ordering.Apply this diff to fix the ordering:
VITE_FEATURE_TRON=false +VITE_FEATURE_CETUS_SWAP=false VITE_SUI_NODE_URL=https://fullnode.mainnet.sui.io:443 -VITE_FEATURE_CETUS_SWAP=false VITE_FEATURE_MONAD=false.env.development (1)
94-94: Consider reordering for consistency.The linter suggests placing
VITE_FEATURE_CETUS_SWAPbeforeVITE_FEATURE_MONADto maintain alphabetical ordering.Apply this diff to fix the ordering:
+VITE_FEATURE_CETUS_SWAP=true VITE_FEATURE_TRON=true VITE_FEATURE_MONAD=true -VITE_FEATURE_CETUS_SWAP=truepackages/swapper/src/swappers/CetusSwapper/swapperApi/getTradeRate.ts (1)
116-150: Simplify rates array construction.The
ratesarray is created empty and then a single element is pushed. Consider returning the array literal directly for clarity.- const protocolFees: Record<AssetId, ProtocolFee> = {} - - const rates: TradeRate[] = [] - - const tradeRate: TradeRate = { + const protocolFees: Record<AssetId, ProtocolFee> = {} + + const tradeRate: TradeRate = { id: uuid(), // ... rest of tradeRate } - rates.push(tradeRate) - - return Ok(rates) + return Ok([tradeRate])packages/swapper/src/swappers/CetusSwapper/endpoints.ts (1)
101-105: Document or extract magic bytes as constants.The intent message prefix bytes
[0, 0, 0]are SUI-specific protocol values (intent scope, version, app ID). Consider extracting these as named constants for clarity.+const SUI_INTENT_SCOPE_TRANSACTION_DATA = 0 +const SUI_INTENT_VERSION = 0 +const SUI_INTENT_APP_ID = 0 + const intentMessage = new Uint8Array(3 + transactionBytes.length) - intentMessage[0] = 0 - intentMessage[1] = 0 - intentMessage[2] = 0 + intentMessage[0] = SUI_INTENT_SCOPE_TRANSACTION_DATA + intentMessage[1] = SUI_INTENT_VERSION + intentMessage[2] = SUI_INTENT_APP_ID intentMessage.set(transactionBytes, 3)packages/swapper/src/swappers/CetusSwapper/utils/helpers.ts (1)
61-85: Function name vs. implementation mismatch.
findBestPoolsuggests optimal pool selection, but the implementation returns the first pool with any liquidity. Consider renaming tofindPoolWithLiquidityor enhancing to select by highest liquidity.To actually find the best pool by liquidity:
- const poolWithLiquidity = pools.find(pool => { - const hasLiquidity = pool.liquidity && bnOrZero(pool.liquidity).gt(0) - return hasLiquidity - }) + const poolsWithLiquidity = pools.filter(pool => { + return pool.liquidity && bnOrZero(pool.liquidity).gt(0) + }) + + if (poolsWithLiquidity.length === 0) { + console.warn('[Cetus] No pools with liquidity found for', sellCoinType, buyCoinType, { + totalPools: pools.length, + pools: pools.map(p => ({ id: p.poolAddress, liquidity: p.liquidity })), + }) + return undefined + } + + const poolWithLiquidity = poolsWithLiquidity.reduce((best, current) => + bnOrZero(current.liquidity).gt(bnOrZero(best.liquidity)) ? current : best + )
Reorder imports to comply with ESLint rules by moving local imports after external dependencies. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Fix three critical issues in Cetus swapper implementation: 1. Decimals assignment bug (CRITICAL): - decimalsB was incorrectly checking coinTypeB instead of coinTypeA - This caused wrong decimal precision in swap calculations - Fixed to use correct conditional based on coinTypeA 2. Slippage calculation bug (CRITICAL): - amount_limit was using (1 + slippage) instead of (1 - slippage) - Per Cetus docs: when by_amount_in=true, amount_limit is minimum output - Fixed isBuyAmount parameter from false to true 3. Remove unused DEFAULT_SLIPPAGE constant: - Defined as 0.5 (50%) which conflicts with correct 0.005 (0.5%) - Constant was completely unused - Removed to avoid confusion 4. Fix coingecko adapter test failures: - Restored missing chain exports (bitcoin, ethereum, polygon, etc.) - Added SUI USDC to test expectations - All 14 tests now pass 5. Update Cetus SDK to 5.4.0: - Pin exact version (no caret) per CodeRabbit recommendation - Verified type-check passes with new version 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Remove inaccurate comment claiming tx.splitCoins "handles merging and splitting automatically". splitCoins only operates on a single coin object and does not automatically merge multiple coins. Current implementation uses first coin object only. Multi-coin merging can be implemented later if needed. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
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
♻️ Duplicate comments (2)
packages/swapper/src/swappers/CetusSwapper/endpoints.ts (1)
56-58: SDK instance mutation violates determinism and statefulness guidelines.Setting
sdk.senderAddress = frommutates the shared singleton, violating the guideline "Avoid side effects in swap logic; ensure swap methods are deterministic and stateless." This creates non-deterministic behavior where concurrent operations could interfere with each other.Consider creating a per-transaction SDK instance or using SDK methods that accept the sender address as a parameter rather than mutating instance state.
packages/chain-adapters/src/sui/SuiChainAdapter.ts (1)
279-291: Single-coin selection for Sui tokens can fail with fragmented balances (same concern as prior review)Both the send path and the fee-estimation path split from
coins.data[0]only. If the first coin object has insufficient balance while the user has enough total balance across multiple coins of the same type,tx.splitCoins/tx.buildwill fail even though the account as a whole can covervalue.At minimum, it would be better to verify that the chosen coin’s
balancecoversvalueand surface a clear error when it doesn’t, instead of failing deep in transaction building. Longer term, multi-coin selection/aggregation would avoid this edge-case entirely.A minimal improvement could look like:
- if (tokenId) { - // Token transfer transaction - tokenId is the coin type (e.g., 0x...::module::Type) - // We need to get coin objects of this type owned by the sender - const coins = await this.client.getCoins({ - owner: from, - coinType: tokenId, - }) - - if (!coins.data || coins.data.length === 0) { - throw new Error(`No coins found for type ${tokenId}`) - } - - const [coinToSend] = tx.splitCoins(tx.object(coins.data[0].coinObjectId), [value]) - tx.transferObjects([coinToSend], to) - } else { + if (tokenId) { + const coins = await this.client.getCoins({ + owner: from, + coinType: tokenId, + }) + + if (!coins.data || coins.data.length === 0) { + throw new Error(`No coins found for type ${tokenId}`) + } + + const primaryCoin = coins.data[0] + + if (BigInt(primaryCoin.balance) < BigInt(value)) { + throw new Error( + `Insufficient balance in primary coin object for type ${tokenId}; ` + + `coin consolidation is not yet supported.`, + ) + } + + const [coinToSend] = tx.splitCoins(tx.object(primaryCoin.coinObjectId), [value]) + tx.transferObjects([coinToSend], to) + } else { // Native SUI transfer const [coin] = tx.splitCoins(tx.gas, [value]) tx.transferObjects([coin], to) }and similarly in
getFeeData:- if (tokenId) { - // Token transfer - get coin objects for this token type - const coins = await this.client.getCoins({ - owner: from, - coinType: tokenId, - }) - - if (!coins.data || coins.data.length === 0) { - throw new Error(`No coins found for type ${tokenId}`) - } - - const [coin] = tx.splitCoins(tx.object(coins.data[0].coinObjectId), [value]) - tx.transferObjects([coin], to) - } else { + if (tokenId) { + const coins = await this.client.getCoins({ + owner: from, + coinType: tokenId, + }) + + if (!coins.data || coins.data.length === 0) { + throw new Error(`No coins found for type ${tokenId}`) + } + + const primaryCoin = coins.data[0] + + if (BigInt(primaryCoin.balance) < BigInt(value)) { + throw new Error( + `Insufficient balance in primary coin object for type ${tokenId}; ` + + `coin consolidation is not yet supported.`, + ) + } + + const [coin] = tx.splitCoins(tx.object(primaryCoin.coinObjectId), [value]) + tx.transferObjects([coin], to) + } else { const [coin] = tx.splitCoins(tx.gas, [value]) tx.transferObjects([coin], to) }This keeps the current “first coin only” behavior but avoids opaque failures when balances are fragmented.
Also applies to: 487-499
🧹 Nitpick comments (1)
packages/chain-adapters/src/sui/SuiChainAdapter.ts (1)
120-210: Token enumeration and Sui coin assetId generation look good; consider trimming debug logsThe new
getAccountlogic correctly:
- Fetches native + all balances concurrently.
- Filters out the native SUI coin and zero balances.
- Normalizes
coinTypeaddresses and usesASSET_NAMESPACE.suiCoin+toAssetIdfor stable Sui token assetIds.- Falls back cleanly when metadata is missing or fails.
The only concern is the multiple
console.log/console.warncalls in this hot path, which can be noisy in production. Consider removing them or routing through the project’s structured logging utilities if ongoing visibility is needed.Also applies to: 213-219
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (2)
packages/caip/src/adapters/coingecko/generated/index.tsis excluded by!**/generated/**yarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (6)
package.json(1 hunks)packages/caip/src/adapters/coingecko/index.test.ts(2 hunks)packages/chain-adapters/src/sui/SuiChainAdapter.ts(4 hunks)packages/swapper/src/swappers/CetusSwapper/endpoints.ts(1 hunks)packages/swapper/src/swappers/CetusSwapper/utils/constants.ts(1 hunks)packages/swapper/src/swappers/CetusSwapper/utils/helpers.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- package.json
🧰 Additional context used
📓 Path-based instructions (10)
**/*.{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/CetusSwapper/utils/constants.tspackages/caip/src/adapters/coingecko/index.test.tspackages/swapper/src/swappers/CetusSwapper/endpoints.tspackages/swapper/src/swappers/CetusSwapper/utils/helpers.tspackages/chain-adapters/src/sui/SuiChainAdapter.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/CetusSwapper/utils/constants.tspackages/caip/src/adapters/coingecko/index.test.tspackages/swapper/src/swappers/CetusSwapper/endpoints.tspackages/swapper/src/swappers/CetusSwapper/utils/helpers.tspackages/chain-adapters/src/sui/SuiChainAdapter.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/CetusSwapper/utils/constants.tspackages/swapper/src/swappers/CetusSwapper/endpoints.tspackages/swapper/src/swappers/CetusSwapper/utils/helpers.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/CetusSwapper/utils/constants.tspackages/caip/src/adapters/coingecko/index.test.tspackages/swapper/src/swappers/CetusSwapper/endpoints.tspackages/swapper/src/swappers/CetusSwapper/utils/helpers.tspackages/chain-adapters/src/sui/SuiChainAdapter.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/CetusSwapper/utils/constants.tspackages/swapper/src/swappers/CetusSwapper/endpoints.tspackages/swapper/src/swappers/CetusSwapper/utils/helpers.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/CetusSwapper/utils/constants.tspackages/swapper/src/swappers/CetusSwapper/endpoints.tspackages/swapper/src/swappers/CetusSwapper/utils/helpers.ts
packages/swapper/src/swappers/*/utils/constants.ts
📄 CodeRabbit inference engine (.cursor/rules/swapper.mdc)
Define supported chain IDs for each swapper in utils/constants.ts with both 'sell' and 'buy' properties following the pattern: SupportedChainIds type
Files:
packages/swapper/src/swappers/CetusSwapper/utils/constants.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
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/CetusSwapper/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/CetusSwapper/endpoints.ts
🧠 Learnings (43)
📓 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: 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: 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: 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
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/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/CetusSwapper/utils/constants.tspackages/caip/src/adapters/coingecko/index.test.tspackages/swapper/src/swappers/CetusSwapper/endpoints.tspackages/swapper/src/swappers/CetusSwapper/utils/helpers.tspackages/chain-adapters/src/sui/SuiChainAdapter.ts
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/**/*.ts : Use TypeScript with explicit types (e.g., SupportedChainIds) for all code in the Swapper system
Applied to files:
packages/swapper/src/swappers/CetusSwapper/utils/constants.tspackages/swapper/src/swappers/CetusSwapper/utils/helpers.tspackages/chain-adapters/src/sui/SuiChainAdapter.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/CetusSwapper/utils/constants.tspackages/caip/src/adapters/coingecko/index.test.tspackages/chain-adapters/src/sui/SuiChainAdapter.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/CetusSwapper/utils/constants.tspackages/caip/src/adapters/coingecko/index.test.tspackages/swapper/src/swappers/CetusSwapper/utils/helpers.tspackages/chain-adapters/src/sui/SuiChainAdapter.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/CetusSwapper/utils/constants.tspackages/caip/src/adapters/coingecko/index.test.tspackages/swapper/src/swappers/CetusSwapper/utils/helpers.tspackages/chain-adapters/src/sui/SuiChainAdapter.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/CetusSwapper/utils/constants.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/CetusSwapper/utils/constants.tspackages/swapper/src/swappers/CetusSwapper/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/CetusSwapper/utils/constants.tspackages/swapper/src/swappers/CetusSwapper/endpoints.tspackages/swapper/src/swappers/CetusSwapper/utils/helpers.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/CetusSwapper/utils/constants.tspackages/swapper/src/swappers/CetusSwapper/endpoints.tspackages/swapper/src/swappers/CetusSwapper/utils/helpers.tspackages/chain-adapters/src/sui/SuiChainAdapter.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/swapper/src/swappers/CetusSwapper/utils/constants.tspackages/chain-adapters/src/sui/SuiChainAdapter.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.tspackages/chain-adapters/src/sui/SuiChainAdapter.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.tspackages/swapper/src/swappers/CetusSwapper/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 : All swapper API implementations must implement the SwapperApi interface from packages/swapper/src/types.ts
Applied to files:
packages/swapper/src/swappers/CetusSwapper/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/CetusSwapper/endpoints.tspackages/swapper/src/swappers/CetusSwapper/utils/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/CetusSwapper/endpoints.tspackages/swapper/src/swappers/CetusSwapper/utils/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/**/*.test.ts : Write unit tests for swapper methods and API endpoints
Applied to files:
packages/swapper/src/swappers/CetusSwapper/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/CetusSwapper/endpoints.tspackages/swapper/src/swappers/CetusSwapper/utils/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/swappers/*/*.ts : All swappers must implement the Swapper interface from packages/swapper/src/types.ts
Applied to files:
packages/swapper/src/swappers/CetusSwapper/endpoints.tspackages/swapper/src/swappers/CetusSwapper/utils/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/swappers/**/*.ts : Avoid side effects in swap logic; ensure swap methods are deterministic and stateless
Applied to files:
packages/swapper/src/swappers/CetusSwapper/endpoints.tspackages/swapper/src/swappers/CetusSwapper/utils/helpers.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/CetusSwapper/endpoints.tspackages/chain-adapters/src/sui/SuiChainAdapter.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/swappers/CetusSwapper/endpoints.tspackages/swapper/src/swappers/CetusSwapper/utils/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/swappers/**/*.ts : Validate inputs and log errors for debugging in Swapper system implementations
Applied to files:
packages/swapper/src/swappers/CetusSwapper/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/**/*.ts : Use PascalCase for types, interfaces, and enums in the Swapper system
Applied to files:
packages/swapper/src/swappers/CetusSwapper/utils/helpers.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/CetusSwapper/utils/helpers.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/CetusSwapper/utils/helpers.tspackages/chain-adapters/src/sui/SuiChainAdapter.ts
📚 Learning: 2025-11-03T05:46:24.190Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10985
File: packages/swapper/src/swappers/PortalsSwapper/getPortalsTradeRate/getPortalsTradeRate.tsx:130-141
Timestamp: 2025-11-03T05:46:24.190Z
Learning: In packages/swapper/src/swappers/PortalsSwapper/getPortalsTradeRate/getPortalsTradeRate.tsx, gomesalexandre prefers "let it crash" approach when Portals returns zero outputAmount or 100% buffer causing division by zero, rather than adding defensive guards to surface zero quotes. He wants to fail fast with exceptions that bubble up to the try/catch wrapper, surfacing upstream data issues rather than masking them with defensive programming.
Applied to files:
packages/swapper/src/swappers/CetusSwapper/utils/helpers.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/CetusSwapper/utils/helpers.ts
📚 Learning: 2025-08-10T21:09:25.643Z
Learnt from: premiumjibles
Repo: shapeshift/web PR: 10215
File: src/components/MultiHopTrade/hooks/useGetTradeRateInput.ts:65-67
Timestamp: 2025-08-10T21:09:25.643Z
Learning: In the MultiHopTrade components, `selectInputBuyAsset` and `selectInputSellAsset` selectors from `tradeInputSlice` always return defined values because they have default values in the initial state (BTC for buyAsset, ETH for sellAsset, with fallback to defaultAsset). Null checks for these assets are unnecessary when using these selectors.
Applied to files:
packages/swapper/src/swappers/CetusSwapper/utils/helpers.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/sui/SuiChainAdapter.ts
📚 Learning: 2025-08-26T19:04:38.672Z
Learnt from: kaladinlight
Repo: shapeshift/web PR: 10369
File: packages/chain-adapters/src/cosmossdk/CosmosSdkBaseAdapter.ts:167-176
Timestamp: 2025-08-26T19:04:38.672Z
Learning: In packages/chain-adapters/src/cosmossdk/CosmosSdkBaseAdapter.ts, when processing assets from data.assets.reduce(), the team prefers using empty catch blocks to gracefully skip any assets that fail processing, rather than specific error type handling, to avoid useless noise and ensure robust asset filtering.
Applied to files:
packages/chain-adapters/src/sui/SuiChainAdapter.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/chain-adapters/src/sui/SuiChainAdapter.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/chain-adapters/src/sui/SuiChainAdapter.ts
📚 Learning: 2025-08-13T15:52:25.116Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10272
File: src/context/WalletProvider/MobileWallet/mobileMessageHandlers.ts:61-0
Timestamp: 2025-08-13T15:52:25.116Z
Learning: In the ShapeShift web codebase, specifically in src/context/WalletProvider/MobileWallet/mobileMessageHandlers.ts, message variants in the Message union type do not include inline comments documenting their expected return types. The codebase follows a pattern of keeping these type definitions clean without such documentation comments.
Applied to files:
packages/chain-adapters/src/sui/SuiChainAdapter.ts
📚 Learning: 2025-10-13T11:55:57.439Z
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.
Applied to files:
packages/chain-adapters/src/sui/SuiChainAdapter.ts
📚 Learning: 2025-10-01T07:42:40.195Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10596
File: src/components/Layout/Header/NavBar/WalletConnectedMenu.tsx:77-99
Timestamp: 2025-10-01T07:42:40.195Z
Learning: In WalletConnectedMenu.tsx's handleReconnectWallet handler, gomesalexandre prefers throwing an error for unsupported wallet types in the default case rather than gracefully handling with a fallback. His reasoning: "if we have a problem here, we have bigger problems" - only supported wallets (KeepKey, Ledger, MetaMask, Coinbase, Phantom) should reach the reconnect flow when disconnected/locked, so encountering an unsupported type indicates a larger architectural issue that should be surfaced explicitly rather than masked with graceful degradation.
Applied to files:
packages/chain-adapters/src/sui/SuiChainAdapter.ts
📚 Learning: 2025-08-29T07:07:49.332Z
Learnt from: premiumjibles
Repo: shapeshift/web PR: 10386
File: src/components/MultiHopTrade/components/VerifyAddresses/VerifyAddresses.tsx:272-294
Timestamp: 2025-08-29T07:07:49.332Z
Learning: In UTXO sell address verification flow in VerifyAddresses.tsx, the user wants address verification to be marked as "verified/complete" before starting the change address fetch, not after. The verification step and change address fetch should be treated as separate sequential operations in the UI flow.
Applied to files:
packages/chain-adapters/src/sui/SuiChainAdapter.ts
📚 Learning: 2025-09-12T10:44:46.723Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/WalletConnectSigningModal/content/SendTransactionContent.tsx:0-0
Timestamp: 2025-09-12T10:44:46.723Z
Learning: gomesalexandre dismissed a clipboard error handling suggestion in PR #10461 for SendTransactionContent.tsx, demonstrating that the current navigator.clipboard.writeText implementation works as expected and preferring to keep it simple without additional try/catch error handling.
Applied to files:
packages/chain-adapters/src/sui/SuiChainAdapter.ts
📚 Learning: 2025-11-25T21:43:10.838Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11170
File: patches/@shapeshiftoss+bitcoinjs-lib+7.0.0-shapeshift.0.patch:9-19
Timestamp: 2025-11-25T21:43:10.838Z
Learning: In shapeshift/web, gomesalexandre will not expand PR scope to fix latent bugs in unused API surface (like bitcoinjs-lib patch validation methods) when comprehensive testing proves the actual used code paths work correctly, preferring to avoid costly hdwallet/web verdaccio publish cycles and full regression testing for conceptual issues with zero runtime impact.
Applied to files:
packages/chain-adapters/src/sui/SuiChainAdapter.ts
📚 Learning: 2025-10-07T03:44:27.350Z
Learnt from: 0xApotheosis
Repo: shapeshift/web PR: 10760
File: src/components/ManageHiddenAssets/ManageHiddenAssetsList.tsx:78-84
Timestamp: 2025-10-07T03:44:27.350Z
Learning: In the ShapeShift web codebase, the following are stable references and do not need to be included in useCallback/useMemo dependency arrays:
- `navigate` from `useBrowserRouter()` hook
- Modal control objects (like `walletDrawer`) from `useModal()` hook (including their `isOpen`, `close`, and `open` methods)
- These are backed by stable context providers
Applied to files:
packages/chain-adapters/src/sui/SuiChainAdapter.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/chain-adapters/src/sui/SuiChainAdapter.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/chain-adapters/src/sui/SuiChainAdapter.ts
📚 Learning: 2025-09-12T12:08:15.823Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/WalletConnectModalManager.tsx:226-233
Timestamp: 2025-09-12T12:08:15.823Z
Learning: In WalletConnect dApps integration, EthSignTransactionCallRequest and EthSendTransactionCallRequest have identical transaction parameter structures (from, to, data, etc.) per JSON-RPC spec - only the method field differs. This makes it safe to type-cast between them when passing transaction parameters to components like EIP155TransactionConfirmation that process the underlying transaction data regardless of the originating method.
Applied to files:
packages/chain-adapters/src/sui/SuiChainAdapter.ts
🧬 Code graph analysis (5)
packages/swapper/src/swappers/CetusSwapper/utils/constants.ts (1)
packages/caip/src/constants.ts (1)
suiChainId(81-81)
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(83-90)CHAIN_REFERENCE(96-118)
packages/swapper/src/swappers/CetusSwapper/endpoints.ts (3)
packages/swapper/src/utils.ts (3)
isExecutableTradeQuote(308-309)getExecutableTradeStep(314-324)checkSuiSwapStatus(353-387)src/lib/utils/sui.ts (1)
assertGetSuiChainAdapter(14-23)packages/swapper/src/swappers/CetusSwapper/utils/helpers.ts (5)
getCetusSDK(8-14)getCoinType(16-26)findBestPool(61-85)calculateSwapAmounts(93-135)determineSwapDirection(28-40)
packages/swapper/src/swappers/CetusSwapper/utils/helpers.ts (1)
packages/caip/src/assetId/assetId.ts (1)
fromAssetId(140-172)
packages/chain-adapters/src/sui/SuiChainAdapter.ts (2)
packages/caip/src/assetId/assetId.ts (1)
toAssetId(59-127)packages/caip/src/constants.ts (1)
ASSET_NAMESPACE(120-128)
🔇 Additional comments (14)
packages/swapper/src/swappers/CetusSwapper/utils/constants.ts (1)
1-10: LGTM! Clean implementation of Cetus chain support.The constants file correctly follows the established swapper pattern with explicit types, proper imports from
@shapeshiftoss/caip, and a well-formed type guard. The readonly array and type guard will enable compile-time and runtime chain validation throughout the Cetus swapper.packages/swapper/src/swappers/CetusSwapper/endpoints.ts (4)
27-40: LGTM! Clean delegation pattern.The
getTradeQuoteandgetTradeRatemethods correctly delegate to their respective implementations while conforming to theSwapperApiinterface.
60-120: LGTM! Solid transaction construction logic.The implementation correctly:
- Validates and retrieves pool with appropriate error handling
- Calculates swap amounts and determines direction
- Applies slippage protection with correct parameters
- Constructs the SUI transaction with proper intent message format (3-byte prefix)
- Derives BIP44 address path appropriately
123-131: LGTM! Proper fee extraction with validation.The method correctly validates the trade quote type, retrieves the executable step, and ensures the network fee is present before returning it.
133-147: LGTM! Proper status check implementation.The method appropriately handles the case where no transaction hash exists by returning
Unknownstatus, and correctly delegates to the reusablecheckSuiSwapStatusutility for actual status checking.packages/swapper/src/swappers/CetusSwapper/utils/helpers.ts (7)
8-14: LGTM! Appropriate singleton pattern for SDK initialization.The lazy-loaded singleton pattern with dynamic import is suitable for SDK initialization, reducing initial bundle size while ensuring a single SDK instance throughout the application lifecycle.
16-26: LGTM! Correct coin type conversion.The function properly handles the special case of native SUI tokens (converting from
slip44:784format to Cetus's expected0x2::sui::SUIformat) while passing through other token asset references unchanged.
28-40: LGTM! Clear swap direction logic.The function correctly determines the swap direction by checking both possible coin type orientations in the pool, with appropriate error handling when the pool doesn't match the requested pair.
42-59: LGTM! Correct slippage calculation logic.The function properly applies slippage tolerance:
- For buy amounts (minimum output): reduces by slippage factor
(1 - slippage)- For sell amounts (maximum input): increases by slippage factor
(1 + slippage)Both calculations correctly protect against unfavorable price movements.
61-85: LGTM! Robust pool selection logic.The function correctly queries for pools, filters for liquidity, and provides useful diagnostic logging when no liquid pools are found. The use of
bnOrZeroensures safe numeric comparisons.
87-91: LGTM! Clean result type definition.The type appropriately uses string fields for all amount values, which is correct for representing base unit amounts without precision loss.
93-135: LGTM! Correct swap amount calculation.The function properly:
- Determines swap direction and coin types
- Correctly assigns decimals for both pool coins (lines 105-106 logic is correct: when
pool.coinTypeA === sellCoinType, decimalsA gets sell precision and decimalsB gets buy precision, and vice versa)- Validates preswap results before returning
- Returns undefined for invalid swap scenarios (no result or zero output)
packages/caip/src/adapters/coingecko/index.test.ts (1)
178-183: USDC on Sui mapping test looks consistent and correctThe new
usdcOnSuiassetId and its inclusion in theusd-coinexpectations follow the existing multi-chain USDC pattern and correctly use Sui chain namespace/reference andcoinnamespace.Also applies to: 192-193
packages/chain-adapters/src/sui/SuiChainAdapter.ts (1)
4-10: CAIP imports and root BIP44 params are wired correctly for SuiUsing
ASSET_REFERENCE.SuiforcoinTypeandsuiChainId/suiAssetIdfrom@shapeshiftoss/caipaligns this adapter with the shared CAIP constants and keeps chain metadata centralized.Also applies to: 40-44
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
- Remove all debug console.log statements from SUI chain adapter - Change TradeQuoteError from UnknownError to InternalError for assertion failures (accountNumber, suiAsset) - Revert unintended comment removal in useSendActionSubscriber 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Fixes whitescreen issue in Edge/Chromium browsers where SVG imports without ?url suffix fail with: "Failed to load module script: Expected JavaScript module but the server responded with a MIME type of 'image/svg+xml'" Same fix as PR #11070 for orbs.svg, now applied to Jupiter and Relay swapper icons. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
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 (1)
packages/chain-adapters/src/sui/SuiChainAdapter.ts (1)
120-189: Token balance + assetId mapping is solid; normalize helper could be hoisted.The concurrent
getBalance/getAllBalancescall, SUI-native filtering, CAIP-19coinassetIds, and metadata fallbacks all look correct and robust. If you want to tighten things slightly, consider movingnormalizeCoinTypeout of themapcallback (e.g., to a private method) so it isn’t redefined per token and can be reused elsewhere if needed.Also applies to: 192-199
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (2)
packages/chain-adapters/src/sui/SuiChainAdapter.ts(4 hunks)packages/swapper/src/swappers/CetusSwapper/swapperApi/getTradeQuote.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx,js,jsx}: Never assume a library is available - always check imports/package.json first
Prefer composition over inheritance
Write self-documenting code with clear variable and function names
Keep functions small and focused on a single responsibility
Avoid deep nesting - use early returns instead
Prefer procedural and easy to understand code
Never expose, log, or commit secrets, API keys, or credentials
Validate all inputs, especially user inputs
Handle errors gracefully with meaningful messages
Don't silently catch and ignore exceptions
Log errors appropriately for debugging
Provide fallback behavior when possible
Use appropriate data structures for the task
Never add code comments unless explicitly requested
When modifying code, do not add comments that reference previous implementations or explain what changed. Comments should only describe the current logic and functionality.
Use meaningful names for branches, variables, and functions
Always 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/sui/SuiChainAdapter.tspackages/swapper/src/swappers/CetusSwapper/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/chain-adapters/src/sui/SuiChainAdapter.tspackages/swapper/src/swappers/CetusSwapper/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/chain-adapters/src/sui/SuiChainAdapter.tspackages/swapper/src/swappers/CetusSwapper/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/CetusSwapper/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/CetusSwapper/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/CetusSwapper/swapperApi/getTradeQuote.ts
🧠 Learnings (49)
📓 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: 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: gomesalexandre
Repo: shapeshift/web PR: 11240
File: packages/swapper/src/swappers/CetusSwapper/endpoints.ts:56-58
Timestamp: 2025-12-01T22:01:37.954Z
Learning: In packages/swapper/src/swappers/CetusSwapper/endpoints.ts, gomesalexandre is comfortable with mutating the shared Cetus SDK singleton instance (sdk.senderAddress = from) when required by the SDK API, preferring pragmatic working code over theoretical statelessness concerns.
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.
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
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`
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
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
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
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
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/chain-adapters/src/sui/SuiChainAdapter.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/chain-adapters/src/sui/SuiChainAdapter.tspackages/swapper/src/swappers/CetusSwapper/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/chain-adapters/src/sui/SuiChainAdapter.tspackages/swapper/src/swappers/CetusSwapper/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/**/*.ts : Use TypeScript with explicit types (e.g., SupportedChainIds) for all code in the Swapper system
Applied to files:
packages/chain-adapters/src/sui/SuiChainAdapter.tspackages/swapper/src/swappers/CetusSwapper/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/chain-adapters/src/sui/SuiChainAdapter.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/sui/SuiChainAdapter.ts
📚 Learning: 2025-08-26T19:04:38.672Z
Learnt from: kaladinlight
Repo: shapeshift/web PR: 10369
File: packages/chain-adapters/src/cosmossdk/CosmosSdkBaseAdapter.ts:167-176
Timestamp: 2025-08-26T19:04:38.672Z
Learning: In packages/chain-adapters/src/cosmossdk/CosmosSdkBaseAdapter.ts, when processing assets from data.assets.reduce(), the team prefers using empty catch blocks to gracefully skip any assets that fail processing, rather than specific error type handling, to avoid useless noise and ensure robust asset filtering.
Applied to files:
packages/chain-adapters/src/sui/SuiChainAdapter.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/chain-adapters/src/sui/SuiChainAdapter.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/chain-adapters/src/sui/SuiChainAdapter.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/chain-adapters/src/sui/SuiChainAdapter.ts
📚 Learning: 2025-08-13T15:52:25.116Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10272
File: src/context/WalletProvider/MobileWallet/mobileMessageHandlers.ts:61-0
Timestamp: 2025-08-13T15:52:25.116Z
Learning: In the ShapeShift web codebase, specifically in src/context/WalletProvider/MobileWallet/mobileMessageHandlers.ts, message variants in the Message union type do not include inline comments documenting their expected return types. The codebase follows a pattern of keeping these type definitions clean without such documentation comments.
Applied to files:
packages/chain-adapters/src/sui/SuiChainAdapter.ts
📚 Learning: 2025-09-12T10:44:46.723Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/WalletConnectSigningModal/content/SendTransactionContent.tsx:0-0
Timestamp: 2025-09-12T10:44:46.723Z
Learning: gomesalexandre dismissed a clipboard error handling suggestion in PR #10461 for SendTransactionContent.tsx, demonstrating that the current navigator.clipboard.writeText implementation works as expected and preferring to keep it simple without additional try/catch error handling.
Applied to files:
packages/chain-adapters/src/sui/SuiChainAdapter.ts
📚 Learning: 2025-11-25T21:43:10.838Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11170
File: patches/@shapeshiftoss+bitcoinjs-lib+7.0.0-shapeshift.0.patch:9-19
Timestamp: 2025-11-25T21:43:10.838Z
Learning: In shapeshift/web, gomesalexandre will not expand PR scope to fix latent bugs in unused API surface (like bitcoinjs-lib patch validation methods) when comprehensive testing proves the actual used code paths work correctly, preferring to avoid costly hdwallet/web verdaccio publish cycles and full regression testing for conceptual issues with zero runtime impact.
Applied to files:
packages/chain-adapters/src/sui/SuiChainAdapter.ts
📚 Learning: 2025-08-29T07:07:49.332Z
Learnt from: premiumjibles
Repo: shapeshift/web PR: 10386
File: src/components/MultiHopTrade/components/VerifyAddresses/VerifyAddresses.tsx:272-294
Timestamp: 2025-08-29T07:07:49.332Z
Learning: In UTXO sell address verification flow in VerifyAddresses.tsx, the user wants address verification to be marked as "verified/complete" before starting the change address fetch, not after. The verification step and change address fetch should be treated as separate sequential operations in the UI flow.
Applied to files:
packages/chain-adapters/src/sui/SuiChainAdapter.ts
📚 Learning: 2025-10-13T11:55:57.439Z
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.
Applied to files:
packages/chain-adapters/src/sui/SuiChainAdapter.ts
📚 Learning: 2025-09-12T11:56:19.437Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/utils/tenderly/index.ts:0-0
Timestamp: 2025-09-12T11:56:19.437Z
Learning: gomesalexandre rejected verbose try/catch error handling for address validation in Tenderly integration (PR #10461), calling the approach "ugly" but still implemented safety measures in commit ad7e424b89, preferring cleaner safety implementations over defensive programming patterns.
Applied to files:
packages/chain-adapters/src/sui/SuiChainAdapter.ts
📚 Learning: 2025-10-01T07:42:40.195Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10596
File: src/components/Layout/Header/NavBar/WalletConnectedMenu.tsx:77-99
Timestamp: 2025-10-01T07:42:40.195Z
Learning: In WalletConnectedMenu.tsx's handleReconnectWallet handler, gomesalexandre prefers throwing an error for unsupported wallet types in the default case rather than gracefully handling with a fallback. His reasoning: "if we have a problem here, we have bigger problems" - only supported wallets (KeepKey, Ledger, MetaMask, Coinbase, Phantom) should reach the reconnect flow when disconnected/locked, so encountering an unsupported type indicates a larger architectural issue that should be surfaced explicitly rather than masked with graceful degradation.
Applied to files:
packages/chain-adapters/src/sui/SuiChainAdapter.ts
📚 Learning: 2025-09-10T15:35:46.223Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10458
File: src/plugins/walletConnectToDapps/components/modals/EIP155SignTypedDataConfirmation.tsx:55-55
Timestamp: 2025-09-10T15:35:46.223Z
Learning: gomesalexandre prefers fail-fast early returns over graceful degradation when critical data is missing in WalletConnect flows (like peer metadata in EIP155SignTypedDataConfirmation.tsx). He favors "safety first, always double-wrap" approach and believes missing peer metadata indicates bigger problems that should be surfaced explicitly rather than masked with partial UI rendering.
Applied to files:
packages/chain-adapters/src/sui/SuiChainAdapter.ts
📚 Learning: 2025-08-27T09:47:06.275Z
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.
Applied to files:
packages/chain-adapters/src/sui/SuiChainAdapter.ts
📚 Learning: 2025-08-08T15:00:49.887Z
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.
Applied to files:
packages/chain-adapters/src/sui/SuiChainAdapter.ts
📚 Learning: 2025-09-17T22:40:30.149Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10569
File: src/plugins/walletConnectToDapps/components/WalletConnectSigningModal/WalletConnectModalSigningFooter.tsx:121-129
Timestamp: 2025-09-17T22:40:30.149Z
Learning: gomesalexandre maintains strict scope discipline even for style/UI PRs in shapeshift/web, declining functionally correct UX improvements (like keeping Cancel button enabled during gas simulation loading) when they fall outside the PR's stated styling objectives, demonstrating his consistent pattern of deferring valid but tangential improvements to separate efforts.
Applied to files:
packages/chain-adapters/src/sui/SuiChainAdapter.ts
📚 Learning: 2025-09-12T13:16:27.004Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/EIP712MessageDisplay.tsx:21-24
Timestamp: 2025-09-12T13:16:27.004Z
Learning: gomesalexandre declined to add error boundaries to WalletConnect modals in PR #10461, stating "no error boundaries in this pr ser", consistent with his preference to keep PR scope focused and defer tangential improvements to separate efforts.
Applied to files:
packages/chain-adapters/src/sui/SuiChainAdapter.ts
📚 Learning: 2025-09-13T16:45:17.166Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/WalletConnectSigningModal/StructuredMessage/StructuredMessage.tsx:0-0
Timestamp: 2025-09-13T16:45:17.166Z
Learning: gomesalexandre appreciates safety-focused suggestions for UI rendering in WalletConnect components, specifically defensive programming approaches that prevent null/undefined values from displaying as literal "null"/"undefined" strings in the user interface.
Applied to files:
packages/chain-adapters/src/sui/SuiChainAdapter.ts
📚 Learning: 2025-09-08T22:00:48.005Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10418
File: src/plugins/walletConnectToDapps/components/header/WalletConnectToDappsHeaderButton.tsx:0-0
Timestamp: 2025-09-08T22:00:48.005Z
Learning: gomesalexandre dismissed an aria-label accessibility suggestion with "meh" in PR #10418 for WalletConnectToDappsHeaderButton.tsx, consistent with the team's pattern of deferring minor a11y improvements to follow-up PRs rather than expanding feature PR scope.
Applied to files:
packages/chain-adapters/src/sui/SuiChainAdapter.ts
📚 Learning: 2025-09-12T12:00:33.924Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/SendTransactionConfirmation.tsx:42-50
Timestamp: 2025-09-12T12:00:33.924Z
Learning: gomesalexandre prefers maintaining consistency with existing code patterns in WalletConnect modals, including side-effects-during-render for error handling (showErrorToast + handleReject), rather than introducing isolated refactors that would make the codebase inconsistent.
Applied to files:
packages/chain-adapters/src/sui/SuiChainAdapter.ts
📚 Learning: 2025-08-08T15:00:22.321Z
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.
Applied to files:
packages/chain-adapters/src/sui/SuiChainAdapter.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/chain-adapters/src/sui/SuiChainAdapter.ts
📚 Learning: 2025-10-07T03:44:27.350Z
Learnt from: 0xApotheosis
Repo: shapeshift/web PR: 10760
File: src/components/ManageHiddenAssets/ManageHiddenAssetsList.tsx:78-84
Timestamp: 2025-10-07T03:44:27.350Z
Learning: In the ShapeShift web codebase, the following are stable references and do not need to be included in useCallback/useMemo dependency arrays:
- `navigate` from `useBrowserRouter()` hook
- Modal control objects (like `walletDrawer`) from `useModal()` hook (including their `isOpen`, `close`, and `open` methods)
- These are backed by stable context providers
Applied to files:
packages/chain-adapters/src/sui/SuiChainAdapter.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/chain-adapters/src/sui/SuiChainAdapter.tspackages/swapper/src/swappers/CetusSwapper/swapperApi/getTradeQuote.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/chain-adapters/src/sui/SuiChainAdapter.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/chain-adapters/src/sui/SuiChainAdapter.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/chain-adapters/src/sui/SuiChainAdapter.ts
📚 Learning: 2025-09-12T12:08:15.823Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/WalletConnectModalManager.tsx:226-233
Timestamp: 2025-09-12T12:08:15.823Z
Learning: In WalletConnect dApps integration, EthSignTransactionCallRequest and EthSendTransactionCallRequest have identical transaction parameter structures (from, to, data, etc.) per JSON-RPC spec - only the method field differs. This makes it safe to type-cast between them when passing transaction parameters to components like EIP155TransactionConfirmation that process the underlying transaction data regardless of the originating method.
Applied to files:
packages/chain-adapters/src/sui/SuiChainAdapter.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/CetusSwapper/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/CetusSwapper/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/CetusSwapper/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 : Validate inputs and log errors for debugging in Swapper system implementations
Applied to files:
packages/swapper/src/swappers/CetusSwapper/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 : All swappers must implement the Swapper interface from packages/swapper/src/types.ts
Applied to files:
packages/swapper/src/swappers/CetusSwapper/swapperApi/getTradeQuote.ts
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/index.ts : Export unique functions and types from packages/swapper/src/index.ts only if needed for external consumption
Applied to files:
packages/swapper/src/swappers/CetusSwapper/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/**/*.test.ts : Write unit tests for swapper methods and API endpoints
Applied to files:
packages/swapper/src/swappers/CetusSwapper/swapperApi/getTradeQuote.ts
📚 Learning: 2025-11-03T05:46:24.190Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10985
File: packages/swapper/src/swappers/PortalsSwapper/getPortalsTradeRate/getPortalsTradeRate.tsx:130-141
Timestamp: 2025-11-03T05:46:24.190Z
Learning: In packages/swapper/src/swappers/PortalsSwapper/getPortalsTradeRate/getPortalsTradeRate.tsx, gomesalexandre prefers "let it crash" approach when Portals returns zero outputAmount or 100% buffer causing division by zero, rather than adding defensive guards to surface zero quotes. He wants to fail fast with exceptions that bubble up to the try/catch wrapper, surfacing upstream data issues rather than masking them with defensive programming.
Applied to files:
packages/swapper/src/swappers/CetusSwapper/swapperApi/getTradeQuote.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/CetusSwapper/swapperApi/getTradeQuote.ts
📚 Learning: 2025-07-29T15:04:28.083Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10139
File: src/components/MultiHopTrade/components/TradeConfirm/components/ExpandableStepperSteps.tsx:109-115
Timestamp: 2025-07-29T15:04:28.083Z
Learning: In src/components/MultiHopTrade/components/TradeConfirm/components/ExpandableStepperSteps.tsx, the component is used under an umbrella that 100% of the time contains the quote, making the type assertion `activeTradeQuote?.steps[currentHopIndex] as TradeQuoteStep` safe. Adding conditional returns before hooks would violate React's Rules of Hooks.
Applied to files:
packages/swapper/src/swappers/CetusSwapper/swapperApi/getTradeQuote.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} : ALWAYS use custom error classes from `shapeshiftoss/errors` with meaningful error codes for internationalization and relevant details in error objects
Applied to files:
packages/swapper/src/swappers/CetusSwapper/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/CetusSwapper/swapperApi/getTradeQuote.ts
📚 Learning: 2025-07-31T03:51:48.479Z
Learnt from: premiumjibles
Repo: shapeshift/web PR: 10154
File: src/state/apis/swapper/helpers/swapperApiHelpers.ts:57-60
Timestamp: 2025-07-31T03:51:48.479Z
Learning: In src/state/apis/swapper/helpers/swapperApiHelpers.ts, the getState parameter in processQuoteResultWithRatios uses `() => unknown` type instead of `() => ReduxState` to avoid type compatibility issues elsewhere in the codebase.
Applied to files:
packages/swapper/src/swappers/CetusSwapper/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/CetusSwapper/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/CetusSwapper/swapperApi/getTradeQuote.ts
🧬 Code graph analysis (2)
packages/chain-adapters/src/sui/SuiChainAdapter.ts (2)
packages/caip/src/assetId/assetId.ts (1)
toAssetId(59-127)packages/caip/src/constants.ts (1)
ASSET_NAMESPACE(120-128)
packages/swapper/src/swappers/CetusSwapper/swapperApi/getTradeQuote.ts (6)
packages/swapper/src/utils.ts (2)
makeSwapErrorRight(31-47)getInputOutputRate(292-306)src/state/apis/swapper/types.ts (1)
TradeQuoteError(39-39)packages/swapper/src/swappers/CetusSwapper/utils/constants.ts (1)
isSupportedChainId(6-10)packages/caip/src/constants.ts (1)
suiAssetId(23-23)packages/swapper/src/swappers/CetusSwapper/utils/helpers.ts (4)
getCetusSDK(8-14)getCoinType(16-26)findBestPool(61-85)calculateSwapAmounts(93-135)packages/caip/src/assetId/assetId.ts (1)
AssetId(17-17)
🔇 Additional comments (10)
packages/swapper/src/swappers/CetusSwapper/swapperApi/getTradeQuote.ts (7)
1-19: LGTM!Imports are well-organized, using proper types from
@shapeshiftoss/*packages and the Result pattern from@sniptt/monadsas per coding guidelines.
21-35: LGTM!Function signature follows the swapper pattern with explicit return type and proper use of
Result<TradeQuote[], SwapErrorRight>.
37-75: LGTM!Validations follow best practices with early returns, appropriate error codes (
InternalErrorfor preconditions,UnsupportedChainfor chain validation), and useful error details.
77-103: LGTM!SDK initialization, pool discovery, and swap calculation are well-structured with appropriate error codes (
NoRouteFound,QueryFailed) for different failure modes.
105-128: LGTM!Rate calculation uses the shared utility, and fee estimation properly handles missing
receiveAddresswith a valid SUI-format dummy address. The adapter assertion is within the try-catch block.
130-146: Verify whether protocol fees should be populated.
swapResult.estimatedFeeAmountis returned fromcalculateSwapAmountsbut is not used here. TheprotocolFeesrecord is empty, andbuyAmountBeforeFeesCryptoBaseUnitequalsbuyAmountAfterFeesCryptoBaseUnit.If
estimatedAmountOutfrom Cetus already reflects fees deducted, this is correct. However, ifestimatedFeeAmountrepresents additional protocol fees that should be displayed to users, consider populatingprotocolFees:- const protocolFees: Record<AssetId, ProtocolFee> = {} + const protocolFees: Record<AssetId, ProtocolFee> = swapResult.estimatedFeeAmount !== '0' + ? { + [buyAsset.assetId]: { + amountCryptoBaseUnit: swapResult.estimatedFeeAmount, + requiresBalance: false, + asset: buyAsset, + }, + } + : {}
169-177: LGTM!Error handling properly uses the Result pattern, catches all exceptions, extracts meaningful error messages, and returns an appropriate
QueryFailederror code.packages/chain-adapters/src/sui/SuiChainAdapter.ts (3)
4-10: CAIP-based Sui chain/asset wiring looks good.Using
ASSET_REFERENCE.SuiforcoinTypeandsuiChainId/suiAssetIdplustoAssetIdis consistent with the CAIP constants and keeps Sui BIP44/assetId derivation centralized.Also applies to: 40-43
250-270: Token send path viagetCoins+splitCoinsis wired correctly.Casting
gasBudget/gasPriceto numbers and usinggetCoins({ owner: from, coinType: tokenId })withsplitCoinson the selected coin object matches the Sui SDK’s expectations and aligns the token send flow with the native SUI branch.
438-459: Please verify the hard-coded token gas estimate is safe across mainnet tokens.The token
getFeeDatafast‑path uses a fixedestimatedGas = 50_000_000n(with a 20% buffer) and skips building/dry‑running a transaction. This is likely fine for typical transfers, but if any token transfer consistently needs more gas, users could see “insufficient gas budget” failures.Can you confirm from Cetus/Sui mainnet testing that
50_000_000n(and the derivedgasBudget) is large enough for the heaviest expected token transfers? If not, it might be worth bumping this value or extracting it to a named constant that can be tuned.Also applies to: 466-477
gomesalexandre
left a 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.
Seems to do the thing
https://jam.dev/c/8e52508a-db43-4676-b181-ccd8ad1564a4
@NeOMakinG probably worth doing a regen before merging re:
Try very well known token like USDC to USDT on sui and the contrary
Only seeing 2 tokens on SUI, USDC and SUI as a token
|
Merging, tomorrows regen will do the trick, need velocity there/sleep and I'll have another rebase if we wait |
…and implementation guide This update transforms the swapper-integration skill from basic guidance into a comprehensive, production-ready integration framework based on analysis of 3 major swapper PRs (Bebop, NEAR Intents, Cetus) and deep understanding of the swapper abstraction. ## Major Enhancements ### Phase 0: Proactive Research (NEW) - Use WebFetch/WebSearch to research swapper APIs BEFORE asking user - Automatically find documentation, chain support, existing integrations - Only ask user for what can't be found online ### Expanded allowed-tools - Added WebFetch, WebSearch for autonomous research - Added AskUserQuestion for structured multi-question prompts - Added gh pr:* for PR research ### Deep Swapper Categorization - EVM Direct Transaction (Bebop, 0x, Portals) - Deposit-to-Address (Chainflip, NEAR Intents, THORChain) - Gasless Order-Based (CowSwap) - Solana-Only (Jupiter) - Chain-Specific (Cetus/Sui, Tron, etc.) ### Complete Implementation Guide - Step-by-step file creation order (10 files) - Full code templates for each file with actual TypeScript - Detailed explanations of monadic error handling - HTTP service factory with caching pattern - Rate calculation strategies ### Swapper-Specific Metadata Deep Dive - When to use vs when to skip - THREE places to wire (types, quote, TWO extraction points) - Critical: Both useTradeButtonProps AND tradeExecution.ts - Example flows from NEAR Intents ### Registration Checklist (9 steps) - SwapperConfig types - Constants registration - CSP headers with examples - Feature flags (3 files) - UI icon integration - Environment variables (.env patterns) - Test mocks ### Proactive Gotcha Prevention - 10 critical bugs to check BEFORE testing - Based on real issues from Bebop/NEAR Intents/Cetus PRs - Slippage format, checksumming, hex conversion, response parsing ### Testing Framework - Automated checks (type-check, lint, build) - 11-point manual testing checklist - 6-point edge case testing - Rate vs quote delta verification ### Common Errors & Solutions - 8 common error messages with exact fixes - Direct mapping from error → solution - Based on actual PR comments and fixes ## Key Insights from PR Analysis ### From Bebop PR (#11000) - Dual routing with partial failure handling - Affiliate fee delta issues (rate vs quote) - Hex → decimal conversion patterns - Address checksumming requirements ### From NEAR Intents PR (#11016) - Deposit-to-address metadata flow - Status polling with swap metadata - Cross-chain EVM/UTXO/Solana handling - OneClick SDK integration patterns ### From Cetus PR (#11240) - Sui chain-specific adaptations - Non-EVM transaction metadata - Chain adapter fee estimation - Token vs coin namespace handling ## Skill Quality Improvements - 1500+ lines of comprehensive guidance (3x expansion) - Code templates with actual imports and types - File structure with exact locations - Integration checklist (28 items) - Three-phase workflow (Research → Implement → Test) ## Technical Depth - Monadic Result<T, SwapErrorRight> pattern explained - HTTP service with caching (createCache, makeSwapperAxiosServiceMonadic) - Chain adapter usage for fee estimation - Native token marker handling - TradeQuote vs TradeRate differences - accountNumber: undefined requirement for rates ## Documentation Template - Complete INTEGRATION.md structure - API details section - Implementation notes with code - Known gotchas documentation - Testing strategies 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
…and implementation guide This update transforms the swapper-integration skill from basic guidance into a comprehensive, production-ready integration framework based on analysis of 3 major swapper PRs (Bebop, NEAR Intents, Cetus) and deep understanding of the swapper abstraction. ## Major Enhancements ### Phase 0: Proactive Research (NEW) - Use WebFetch/WebSearch to research swapper APIs BEFORE asking user - Automatically find documentation, chain support, existing integrations - Only ask user for what can't be found online ### Expanded allowed-tools - Added WebFetch, WebSearch for autonomous research - Added AskUserQuestion for structured multi-question prompts - Added gh pr:* for PR research ### Deep Swapper Categorization - EVM Direct Transaction (Bebop, 0x, Portals) - Deposit-to-Address (Chainflip, NEAR Intents, THORChain) - Gasless Order-Based (CowSwap) - Solana-Only (Jupiter) - Chain-Specific (Cetus/Sui, Tron, etc.) ### Complete Implementation Guide - Step-by-step file creation order (10 files) - Full code templates for each file with actual TypeScript - Detailed explanations of monadic error handling - HTTP service factory with caching pattern - Rate calculation strategies ### Swapper-Specific Metadata Deep Dive - When to use vs when to skip - THREE places to wire (types, quote, TWO extraction points) - Critical: Both useTradeButtonProps AND tradeExecution.ts - Example flows from NEAR Intents ### Registration Checklist (9 steps) - SwapperConfig types - Constants registration - CSP headers with examples - Feature flags (3 files) - UI icon integration - Environment variables (.env patterns) - Test mocks ### Proactive Gotcha Prevention - 10 critical bugs to check BEFORE testing - Based on real issues from Bebop/NEAR Intents/Cetus PRs - Slippage format, checksumming, hex conversion, response parsing ### Testing Framework - Automated checks (type-check, lint, build) - 11-point manual testing checklist - 6-point edge case testing - Rate vs quote delta verification ### Common Errors & Solutions - 8 common error messages with exact fixes - Direct mapping from error → solution - Based on actual PR comments and fixes ## Key Insights from PR Analysis ### From Bebop PR (#11000) - Dual routing with partial failure handling - Affiliate fee delta issues (rate vs quote) - Hex → decimal conversion patterns - Address checksumming requirements ### From NEAR Intents PR (#11016) - Deposit-to-address metadata flow - Status polling with swap metadata - Cross-chain EVM/UTXO/Solana handling - OneClick SDK integration patterns ### From Cetus PR (#11240) - Sui chain-specific adaptations - Non-EVM transaction metadata - Chain adapter fee estimation - Token vs coin namespace handling ## Skill Quality Improvements - 1500+ lines of comprehensive guidance (3x expansion) - Code templates with actual imports and types - File structure with exact locations - Integration checklist (28 items) - Three-phase workflow (Research → Implement → Test) ## Technical Depth - Monadic Result<T, SwapErrorRight> pattern explained - HTTP service with caching (createCache, makeSwapperAxiosServiceMonadic) - Chain adapter usage for fee estimation - Native token marker handling - TradeQuote vs TradeRate differences - accountNumber: undefined requirement for rates ## Documentation Template - Complete INTEGRATION.md structure - API details section - Implementation notes with code - Known gotchas documentation - Testing strategies 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
* feat: display current nonce in WalletConnect transaction advanced parameters Fetches and displays the current/next nonce for the account in the advanced parameters section instead of showing "Nonce..." placeholder text. Users can now see what nonce will be automatically used if they don't set a custom one. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * feat: massively enhance swapper-integration skill with deep research and implementation guide This update transforms the swapper-integration skill from basic guidance into a comprehensive, production-ready integration framework based on analysis of 3 major swapper PRs (Bebop, NEAR Intents, Cetus) and deep understanding of the swapper abstraction. ## Major Enhancements ### Phase 0: Proactive Research (NEW) - Use WebFetch/WebSearch to research swapper APIs BEFORE asking user - Automatically find documentation, chain support, existing integrations - Only ask user for what can't be found online ### Expanded allowed-tools - Added WebFetch, WebSearch for autonomous research - Added AskUserQuestion for structured multi-question prompts - Added gh pr:* for PR research ### Deep Swapper Categorization - EVM Direct Transaction (Bebop, 0x, Portals) - Deposit-to-Address (Chainflip, NEAR Intents, THORChain) - Gasless Order-Based (CowSwap) - Solana-Only (Jupiter) - Chain-Specific (Cetus/Sui, Tron, etc.) ### Complete Implementation Guide - Step-by-step file creation order (10 files) - Full code templates for each file with actual TypeScript - Detailed explanations of monadic error handling - HTTP service factory with caching pattern - Rate calculation strategies ### Swapper-Specific Metadata Deep Dive - When to use vs when to skip - THREE places to wire (types, quote, TWO extraction points) - Critical: Both useTradeButtonProps AND tradeExecution.ts - Example flows from NEAR Intents ### Registration Checklist (9 steps) - SwapperConfig types - Constants registration - CSP headers with examples - Feature flags (3 files) - UI icon integration - Environment variables (.env patterns) - Test mocks ### Proactive Gotcha Prevention - 10 critical bugs to check BEFORE testing - Based on real issues from Bebop/NEAR Intents/Cetus PRs - Slippage format, checksumming, hex conversion, response parsing ### Testing Framework - Automated checks (type-check, lint, build) - 11-point manual testing checklist - 6-point edge case testing - Rate vs quote delta verification ### Common Errors & Solutions - 8 common error messages with exact fixes - Direct mapping from error → solution - Based on actual PR comments and fixes ## Key Insights from PR Analysis ### From Bebop PR (#11000) - Dual routing with partial failure handling - Affiliate fee delta issues (rate vs quote) - Hex → decimal conversion patterns - Address checksumming requirements ### From NEAR Intents PR (#11016) - Deposit-to-address metadata flow - Status polling with swap metadata - Cross-chain EVM/UTXO/Solana handling - OneClick SDK integration patterns ### From Cetus PR (#11240) - Sui chain-specific adaptations - Non-EVM transaction metadata - Chain adapter fee estimation - Token vs coin namespace handling ## Skill Quality Improvements - 1500+ lines of comprehensive guidance (3x expansion) - Code templates with actual imports and types - File structure with exact locations - Integration checklist (28 items) - Three-phase workflow (Research → Implement → Test) ## Technical Depth - Monadic Result<T, SwapErrorRight> pattern explained - HTTP service with caching (createCache, makeSwapperAxiosServiceMonadic) - Chain adapter usage for fee estimation - Native token marker handling - TradeQuote vs TradeRate differences - accountNumber: undefined requirement for rates ## Documentation Template - Complete INTEGRATION.md structure - API details section - Implementation notes with code - Known gotchas documentation - Testing strategies 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * feat: reverts * fix: remove references to missing companion files Remove references to @reference.md, @common-gotchas.md, @examples.md that don't exist. The skill already contains all needed information inline. Addresses CodeRabbit review feedback. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * fix: remove all companion file references Remove all references to non-existent @reference.md, @common-gotchas.md, and @examples.md files. The skill contains all needed information inline. Addresses CodeRabbit critical feedback. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * fix: address CodeRabbit feedback on swapper skill Updates swapper integration skill to address CodeRabbit review comments: Feature flag pattern fixes: - Replace placeholder [SwapperName]Swap with actual example (BebopSwap) - Update getEnabledSwappers to show direct flag destructuring pattern - Fix isCrossAccountTradeSupported to use enum values not placeholders - Align all examples with actual codebase implementation Markdown formatting improvements: - Convert 8 bold emphasis sections to proper headings (#### and ###) - Add language specifiers to 4 code blocks (text, markdown) - Fix heading structure for better lint compliance These changes improve accuracy and ensure the skill matches the actual patterns used in the ShapeShift codebase. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> --------- Co-authored-by: Claude <[email protected]>
Description
Two zozio one stone:
Issue (if applicable)
Nop, follow up for sui support
Risk
Medium, behind a flag, new swapper, could be high but hey need velocity
Testing
Note:
Balances are not updated for the receive account if its internal account send (account 0 to 1), will be fixed by the same issue than TRON
Engineering
Operations
Screenshots (if applicable)
https://jam.dev/c/b082639f-b862-4b34-9509-45adc88e65ae
Summary by CodeRabbit
New Features
Configuration
Behavior
Chores
✏️ Tip: You can customize this high-level summary in your review settings.