Conversation
- Add Plasma chain constants and types (chain ID: eip155:9745) - Create Plasma chain adapter extending EvmBaseAdapter - Add Plasma plugin with feature flag gating (VITE_FEATURE_PLASMA) - Wire Plasma into account derivation and wallet support detection - Add transaction status polling via public RPC - Configure viem and ethers providers for Plasma - Add Plasma to CoinGecko integration and asset generation - Add CSP headers for Plasma RPC endpoint - Generate Plasma assets from CoinGecko token list Plasma uses SLIP44:60 (Ethereum derivation path) and is configured to use public RPC at https://rpc.plasma.to 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
- Add PlasmaMainnet to evmChainIds array - Add Plasma to ChainSpecificFeeData type mapping - Add Plasma network metadata to EvmBaseAdapter targetNetwork 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Add documentation for: - packages/chain-adapters/src/types.ts (ChainSpecificFeeData mapping) - packages/chain-adapters/src/evm/EvmBaseAdapter.ts (evmChainIds array and targetNetwork) - packages/chain-adapters/src/[type]/index.ts (export chain adapter) - packages/contracts/src/viemClient.ts (viem client setup for EVM) - packages/contracts/src/ethersProviderSingleton.ts (ethers provider for EVM) - scripts/generateAssetData/coingecko.ts (asset generation helper) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
📝 WalkthroughWalkthroughThis PR adds comprehensive Plasma EVM chain support to the ShapeShift application. It introduces Plasma chain constants, a specialized EVM chain adapter with multicall token batching, asset definitions, environment configuration, wallet integration, Relay swapper support, Ledger gating, and transaction status polling across the frontend and backend infrastructure. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Areas requiring extra attention:
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro Disabled knowledge base sources:
📒 Files selected for processing (2)
🧰 Additional context used📓 Path-based instructions (7)**/*.{ts,tsx,js,jsx}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
**/*.{ts,tsx}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
**/*.test.{ts,tsx,js,jsx}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
**/*.{js,jsx,ts,tsx}📄 CodeRabbit inference engine (.cursor/rules/naming-conventions.mdc)
Files:
**/swapper{s,}/**/*.{ts,tsx}📄 CodeRabbit inference engine (.cursor/rules/error-handling.mdc)
Files:
packages/swapper/**/*.ts📄 CodeRabbit inference engine (.cursor/rules/swapper.mdc)
Files:
packages/swapper/src/swappers/**/*.ts📄 CodeRabbit inference engine (.cursor/rules/swapper.mdc)
Files:
🧠 Learnings (19)📓 Common learnings📚 Learning: 2025-08-17T21:53:03.806ZApplied to files:
📚 Learning: 2025-11-20T12:00:45.005ZApplied to files:
📚 Learning: 2025-11-24T21:20:57.909ZApplied to files:
📚 Learning: 2025-11-24T21:20:04.979ZApplied to files:
📚 Learning: 2025-10-15T15:57:39.956ZApplied to files:
📚 Learning: 2025-11-24T21:20:57.909ZApplied to files:
📚 Learning: 2025-11-24T21:20:57.909ZApplied to files:
📚 Learning: 2025-11-24T21:20:57.909ZApplied to files:
📚 Learning: 2025-11-24T21:20:57.909ZApplied to files:
📚 Learning: 2025-11-24T21:20:57.909ZApplied to files:
📚 Learning: 2025-11-24T21:20:57.909ZApplied to files:
📚 Learning: 2025-11-24T21:20:57.909ZApplied to files:
📚 Learning: 2025-11-24T21:20:57.909ZApplied to files:
📚 Learning: 2025-08-05T23:36:13.214ZApplied to files:
📚 Learning: 2025-09-04T17:29:59.479ZApplied to files:
📚 Learning: 2025-09-04T13:00:47.748ZApplied to files:
📚 Learning: 2025-09-04T17:35:57.584ZApplied to files:
📚 Learning: 2025-09-04T17:35:57.584ZApplied to files:
🧬 Code graph analysis (1)packages/swapper/src/swappers/utils/helpers/helpers.ts (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
🔇 Additional comments (3)
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 |
Add comprehensive Plasma chain support across the entire codebase. Fixes: - Add PlasmaMainnet to ChainSpecificGetFeeDataInput type mapping - Add ethers 6.11.1 dependency to chain-adapters - Add Plasma to EvmBaseAdapter assertSupportsChain switch - Add Plasma to Ledger app gate (getLedgerAppName & getCoin) - Make Portals gracefully skip unsupported chains instead of throwing - Add Plasma to Portals constants - Update Plasma icon URLs to correct CoinGecko assets - Add Plasma to Relay swapper support - Add Plasma to accountIdToLabel for account selection in swapper - Add Plasma to opportunities mapping Documentation: - Add Gotcha 12: Missing Ledger App Gate Entries - Add Gotcha 13: Portals API Unsupported Chains - Add Gotcha 14: Missing accountIdToLabel Case - Add Step 5.4: Research & Add Swapper Support 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Add migration 233 to clear assets and update encoded asset data. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
packages/chain-adapters/src/utils/ledgerAppGate.ts (1)
50-82: Remove or defer Plasma coin mapping until hdwallet adds Plasma supportThe
'Plasma'coin identifier in the getCoin function references a chain that is not yet supported in hdwallet (v2.2.1 docs do not list Plasma as a supported cryptocurrency). Ledger users attempting to validate their app for Plasma will fail at runtime whenwallet.validateCurrentApp('Plasma')is called. Either defer this mapping until hdwallet officially adds Plasma support, or verify that a newer hdwallet version with Plasma support is already available and being used by this project.packages/caip/src/constants.ts (1)
209-230: Add plasmaAssetId to FEE_ASSET_IDS array.The FEE_ASSET_IDS array is missing
plasmaAssetId. All native chain assets (ETH, AVAX, POL, ARB, etc.) are included in this array for fee calculations, and Plasma's native asset should follow the same pattern.Apply this diff to add the missing entry:
arbitrumNovaAssetId, baseAssetId, monadAssetId, + plasmaAssetId, solAssetId, tronAssetId,
♻️ Duplicate comments (2)
packages/chain-adapters/package.json (1)
46-46: Confirm temporary ethers pin and associated past comment.Line 46 adds an explicit
[email protected]pin. The past comment ("remove me and ensure CI is happy, retest when hdwallet is published, local versioning shenanigans") indicates this is temporary.Clarify whether this is:
- A placeholder that should be removed/updated once hdwallet publishes, or
- A permanent, intentional pin for the EVM adapter.
packages/swapper/package.json (1)
42-42: Address version mismatch: hdwallet-core differs from root package.json.The hdwallet-core version here is
1.62.22-plasma.0, but rootpackage.jsonspecifies1.62.23-plasma.1. This inconsistency needs clarification (intentional or oversight).Also note the past comment: "update me to actual upstream when hdwallet is published"—confirm whether this should remain as a reminder or is stale.
🧹 Nitpick comments (12)
src/state/slices/portfolioSlice/utils/index.ts (1)
24-32: Plasma labeling looks consistent; verify wallet support handling forplasmaChainId.
- Importing
plasmaChainIdfrom@shapeshiftoss/caipand routing it through the sharedmiddleEllipsis(pubkey)branch inaccountIdToLabelis consistent with how other EVM/Cosmos-style chains are labeled. No issues there and it matches the CAIP‑first approach used elsewhere.- However,
isAssetSupportedByWalletstill has a closedswitchoverchainIdthat doesn’t includeplasmaChainId, so plasma assets will currently be treated as unsupported by all HDWallets wherever this helper is used. Given this PR adds a new chain and mentions tested Sends/Receives/Relay swaps, please double‑check whether plasma should:
- remain intentionally unsupported here (e.g. only usable via flows that bypass this helper), or
- get its own case mapping to the correct
supports*predicate once hdwallet-core exposes it (or whatever pattern you intend for plasma wallet support).If plasma is meant to be supported by the same app as another EVM network, you’ll likely want to mirror that case here; otherwise, this helper may silently gate plasma UX behind the default
falsebranch.Based on learnings, importing CAIP chain IDs and keeping support checks explicit in one place matches the project’s patterns.
Also applies to: 77-99, 361-403
.env.development (1)
65-65: Plasma env vars look correct; consider reordering to satisfy dotenv‑linter
VITE_PLASMA_NODE_URLandVITE_FEATURE_PLASMAvalues align with the rest of the Plasma wiring. To keep dotenv‑linter happy, you may want to reorder them to match the existing key ordering conventions (node URLs and feature flags are currently ordered, and these insertions trigger UnorderedKey warnings).Also applies to: 95-95
.env.production (1)
61-61: Node URL addition looks good; consider fixing dotenv key ordering
VITE_PLASMA_NODE_URLis consistent with other node URLs. To satisfy dotenv-linter’sUnorderedKeywarning, you can move it beforeVITE_POLYGON_NODE_URLto keep keys ordered.VITE_OPTIMISM_NODE_URL=https://api.optimism.shapeshift.com/api/v1/jsonrpc VITE_BNBSMARTCHAIN_NODE_URL=https://api.bnbsmartchain.shapeshift.com/api/v1/jsonrpc +VITE_PLASMA_NODE_URL=https://rpc.plasma.to VITE_POLYGON_NODE_URL=https://api.polygon.shapeshift.com/api/v1/jsonrpc VITE_GNOSIS_NODE_URL=https://api.gnosis.shapeshift.com/api/v1/jsonrpc VITE_ARBITRUM_NODE_URL=https://api.arbitrum.shapeshift.com/api/v1/jsonrpc VITE_ARBITRUM_NOVA_NODE_URL=https://api.arbitrum-nova.shapeshift.com/api/v1/jsonrpc VITE_BASE_NODE_URL=https://api.base.shapeshift.com/api/v1/jsonrpc VITE_MONAD_NODE_URL=https://rpc.monad.xyz -VITE_PLASMA_NODE_URL=https://rpc.plasma.tosrc/lib/portals/utils.ts (1)
56-60: Graceful handling of unsupported Portals chains is a good change; small typing/refactor nitThe new behavior of:
- filtering out unsupported networks for token listing, and
- returning
{}for unsupported chains infetchPortalsAccountavoids throwing on chains Portals doesn’t support and matches the “skip instead of fail” intent.
One small improvement for clarity/robustness:
- Prefer
Array.isArray(networks)instead oftypeof networks === 'object'when derivingsupportedNetworks:- const supportedNetworks = typeof networks === 'object' ? networks.filter(isSome) : undefined + const supportedNetworks = Array.isArray(networks) ? networks.filter(isSome) : undefinedFunctionally equivalent today, but more explicit about the expected shape and future‑proof if
networksever stops being an array.Also applies to: 283-289
src/plugins/plasma/index.tsx (1)
1-47: Plasma chain adapter plugin wiring looks correct; tiny optimization possibleThe plugin correctly:
- gates on the
Plasmafeature flag,- instantiates
plasma.ChainAdapterwithrpcUrlfromgetConfig().VITE_PLASMA_NODE_URL, and- builds
knownTokensby restricting assets toplasmaChainId+erc20.One small optional improvement: you call
fromAssetId(asset.assetId)in both thefilterandmapsteps. You could compute it once per asset and reuse it:- const knownTokens = assetService.assets - .filter(asset => { - const { chainId, assetNamespace } = fromAssetId(asset.assetId) - return chainId === plasmaChainId && assetNamespace === 'erc20' - }) - .map(asset => ({ - assetId: asset.assetId, - contractAddress: fromAssetId(asset.assetId).assetReference, - symbol: asset.symbol, - name: asset.name, - precision: asset.precision, - })) + const knownTokens = assetService.assets + .map(asset => { + const { chainId, assetNamespace, assetReference } = fromAssetId(asset.assetId) + if (chainId !== plasmaChainId || assetNamespace !== 'erc20') return undefined + return { + assetId: asset.assetId, + contractAddress: assetReference, + symbol: asset.symbol, + name: asset.name, + precision: asset.precision, + } + }) + .filter( + (token): token is NonNullable<typeof token> => Boolean(token), + )Not required, but it avoids double CAIP parsing if you ever run this over a large asset set.
src/lib/utils/plasma.ts (2)
19-28: Consider improving error message for debugging.The generic "invalid chain adapter" message doesn't provide context about what was expected or received.
Apply this diff to include more diagnostic information:
if (!isPlasmaChainAdapter(adapter)) { - throw Error('invalid chain adapter') + throw Error(`Expected Plasma chain adapter for chainId ${chainId}, but got ${adapter?.getChainId?.() ?? 'unknown'}`) }
30-60: Consider including txHash in error logging.The error log would benefit from including the transaction hash for debugging failed status lookups.
Apply this diff to improve error diagnostics:
} catch (error) { - console.error('Error fetching Plasma transaction status:', error) + console.error(`Error fetching Plasma transaction status for ${txHash}:`, error) return TxStatus.Unknown }packages/chain-adapters/src/evm/plasma/PlasmaChainAdapter.ts (5)
68-92: Avoidas anytype assertions.The constructor uses
as anytwice (lines 73 and 81), which violates the coding guideline to never useanytype unless absolutely necessary.Consider creating proper stub types for these cases:
+import type { TransactionParser } from '../types' + +type StubParser = Pick<TransactionParser<KnownChainIds.PlasmaMainnet>, 'parse'> + constructor(args: ChainAdapterArgs) { - const dummyParser = { + const dummyParser: StubParser = { parse: () => { throw new Error('Transaction parsing is not supported for Plasma') }, - } as any + } super({ assetId: plasmaAssetId, chainId: DEFAULT_CHAIN_ID, rootBip44Params: ChainAdapter.rootBip44Params, - parser: dummyParser, + parser: dummyParser as TransactionParser<KnownChainIds.PlasmaMainnet>, supportedChainIds: SUPPORTED_CHAIN_IDS, - providers: {} as any, + providers: {} as Record<string, never>, rpcUrl: args.rpcUrl, })
142-144: Inconsistent error handling pattern.
getAccountthrows a genericError, whilebroadcastTransactionusesErrorHandler. For consistency and proper error translation, consider usingErrorHandlerhere as well.} catch (err) { - throw new Error(`Failed to get account: ${err}`) + return ErrorHandler(err, { + translation: 'chainAdapters.errors.getAccount', + }) }
147-149: Simplify async wrapper.
getKnownPlasmaTokenswraps a synchronous value inPromise.resolve. Since the caller usesawait, this works, but if the intent is to keep this synchronous, consider returning the value directly and updating the call site.-private getKnownPlasmaTokens(): Promise<TokenInfo[]> { - return Promise.resolve(this.knownTokens) +private getKnownPlasmaTokens(): TokenInfo[] { + return this.knownTokens }Then update line 117:
-const knownTokens = await this.getKnownPlasmaTokens() +const knownTokens = this.getKnownPlasmaTokens()
283-286: Inconsistent error handling in fee methods.Both
getGasFeeDataandgetFeeDatathrow genericErrorinstead of usingErrorHandler. For consistency withbroadcastTransaction, consider usingErrorHandlerwith appropriate translation keys.} catch (err) { - throw new Error(`Failed to get gas fee data: ${err}`) + return ErrorHandler(err, { + translation: 'chainAdapters.errors.getGasFeeData', + }) }} catch (err) { - throw new Error(`Failed to get fee data: ${err}`) + return ErrorHandler(err, { + translation: 'chainAdapters.errors.getFeeData', + }) }Also applies to: 325-328
119-125: Consider extracting repeated type definition.The token balance type is defined inline 4 times throughout the file. Consider extracting it to a type alias for better maintainability.
+type TokenBalance = { + assetId: AssetId + balance: string + symbol: string + name: string + precision: number +}Then use
TokenBalanceandTokenBalance[]in place of the inline definitions at lines 119-125, 154-161, 188-195, and 233-240.
NeOMakinG
left a comment
There was a problem hiding this comment.
https://jam.dev/c/b5cd04a2-904d-41f5-9e18-2a089403c9e0
Better than hyperevm for this one, everything seems to work as expected minus getting rate limited and multicall not working!
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (3)
.env.development (2)
66-66: Reorder VITE_PLASMA_NODE_URL to maintain alphabetical grouping within the nodes section.VITE_PLASMA_NODE_URL should be positioned after VITE_OPTIMISM_NODE_URL and before VITE_POLYGON_NODE_URL to maintain alphabetical order.
VITE_BASE_NODE_URL=https://dev-api.base.shapeshift.com/api/v1/jsonrpc + VITE_PLASMA_NODE_URL=https://rpc.plasma.to VITE_MONAD_NODE_URL=https://rpc.monad.xyz - VITE_PLASMA_NODE_URL=https://rpc.plasma.to # Swap me back to 9R as-needed
95-95: Reorder VITE_FEATURE_PLASMA and verify base .env configuration.VITE_FEATURE_PLASMA should come before VITE_FEATURE_SUNIO_SWAP to maintain alphabetical order in the feature flags section. Additionally, confirm that the base
.envfile explicitly setsVITE_FEATURE_PLASMA=falseto ensure the feature is disabled by default and only enabled in development.VITE_FEATURE_MONAD=true - VITE_FEATURE_PLASMA=true VITE_FEATURE_CETUS_SWAP=true + VITE_FEATURE_PLASMA=true VITE_FEATURE_SUNIO_SWAP=truePlease verify the base
.envfile containsVITE_FEATURE_PLASMA=false..env.production (1)
63-63: Reorder VITE_PLASMA_NODE_URL to maintain alphabetical grouping within the nodes section.VITE_PLASMA_NODE_URL should be positioned after VITE_OPTIMISM_NODE_URL and before VITE_POLYGON_NODE_URL to maintain alphabetical order within the nodes section.
VITE_BASE_NODE_URL=https://api.base.shapeshift.com/api/v1/jsonrpc + VITE_PLASMA_NODE_URL=https://rpc.plasma.to VITE_MONAD_NODE_URL=https://rpc.monad.xyz - VITE_PLASMA_NODE_URL=https://rpc.plasma.to VITE_THORCHAIN_NODE_URL=https://api.thorchain.shapeshift.com/lcd
📜 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 (1)
yarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (27)
.env.development(2 hunks).env.production(1 hunks)headers/csps/index.ts(2 hunks)package.json(1 hunks)packages/caip/src/adapters/coingecko/utils.ts(3 hunks)packages/caip/src/constants.ts(5 hunks)packages/chain-adapters/src/types.ts(6 hunks)packages/chain-adapters/src/utils/ledgerAppGate.ts(2 hunks)packages/types/src/base.ts(2 hunks)packages/utils/src/assetData/baseAssets.ts(1 hunks)packages/utils/src/assetData/getBaseAsset.ts(2 hunks)packages/utils/src/chainIdToFeeAssetId.ts(2 hunks)packages/utils/src/getAssetNamespaceFromChainId.ts(1 hunks)packages/utils/src/getChainShortName.ts(1 hunks)packages/utils/src/getNativeFeeAssetReference.ts(1 hunks)scripts/generateAssetData/color-map.json(5 hunks)scripts/generateAssetData/generateAssetData.ts(3 hunks)src/config.ts(2 hunks)src/constants/chains.ts(2 hunks)src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx(2 hunks)src/hooks/useWalletSupportsChain/useWalletSupportsChain.ts(3 hunks)src/plugins/activePlugins.ts(2 hunks)src/state/migrations/index.ts(1 hunks)src/state/slices/opportunitiesSlice/mappings.ts(1 hunks)src/state/slices/portfolioSlice/utils/index.ts(2 hunks)src/state/slices/preferencesSlice/preferencesSlice.ts(2 hunks)src/test/mocks/store.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (22)
- src/state/slices/opportunitiesSlice/mappings.ts
- packages/types/src/base.ts
- src/state/slices/preferencesSlice/preferencesSlice.ts
- src/test/mocks/store.ts
- src/state/migrations/index.ts
- src/hooks/useWalletSupportsChain/useWalletSupportsChain.ts
- packages/utils/src/assetData/baseAssets.ts
- packages/utils/src/chainIdToFeeAssetId.ts
- packages/utils/src/assetData/getBaseAsset.ts
- packages/chain-adapters/src/utils/ledgerAppGate.ts
- packages/utils/src/getChainShortName.ts
- packages/utils/src/getNativeFeeAssetReference.ts
- src/state/slices/portfolioSlice/utils/index.ts
- src/config.ts
- src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx
- package.json
- packages/utils/src/getAssetNamespaceFromChainId.ts
- packages/caip/src/constants.ts
- headers/csps/index.ts
- scripts/generateAssetData/generateAssetData.ts
- src/constants/chains.ts
- packages/chain-adapters/src/types.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx,js,jsx}: Never assume a library is available - always check imports/package.json first
Prefer composition over inheritance
Write self-documenting code with clear variable and function names
Keep functions small and focused on a single responsibility
Avoid deep nesting - use early returns instead
Prefer procedural and easy to understand code
Never expose, log, or commit secrets, API keys, or credentials
Validate all inputs, especially user inputs
Handle errors gracefully with meaningful messages
Don't silently catch and ignore exceptions
Log errors appropriately for debugging
Provide fallback behavior when possible
Use appropriate data structures for the task
Never add code comments unless explicitly requested
When modifying code, do not add comments that reference previous implementations or explain what changed. Comments should only describe the current logic and functionality.
Use meaningful names for branches, variables, and functions
Always runyarn lint --fixandyarn type-checkafter making changes
Avoidletvariable assignments - preferconstwith inline IIFE switch statements or extract to functions for conditional logic
Files:
packages/caip/src/adapters/coingecko/utils.tssrc/plugins/activePlugins.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Avoid useEffect where practical - use it only when necessary and following best practices
Avoid 'any' types - use specific type annotations instead
For default values with user overrides, use computed values (useMemo) instead of useEffect - pattern:userSelected ?? smartDefault ?? fallback
When function parameters are unused due to interface requirements, refactor the interface or implementation to remove them rather than prefixing with underscore
Sanitize data before displaying to prevent XSS
Memoize aggressively - wrap component variables inuseMemoand callbacks inuseCallbackwhere possible
For static JSX icon elements (e.g.,<TbCopy />) that don't depend on state/props, define them as constants outside the component to avoid re-renders instead of using useMemo
Account for light/dark mode usinguseColorModeValuehook
Account for responsive mobile designs in all UI components
When applying styles, use the existing standards and conventions of the codebase
Use Chakra UI components and conventions
All copy/text must use translation keys - never hardcode strings
Use the translation hook:useTranslate()fromreact-polyglot
UseuseFeatureFlag('FlagName')hook to access feature flag values in components
Prefertypeoverinterfacefor type definitions
Use strict typing - avoidany
UseNominaltypes for domain identifiers (e.g.,WalletId,AccountId)
Import types from@shapeshiftoss/caipfor chain/account/asset IDs
UseuseAppSelectorfor Redux state
UseuseAppDispatchfor Redux actions
Memoize expensive computations withuseMemo
Memoize callbacks withuseCallback
**/*.{ts,tsx}: UseResult<T, E>pattern for error handling in swappers and APIs; ALWAYS useOk()andErr()from@sniptt/monads; AVOID throwing within swapper API implementations
ALWAYS use custom error classes from@shapeshiftoss/errorswith meaningful error codes for internationalization and relevant details in error objects
ALWAYS wrap async op...
Files:
packages/caip/src/adapters/coingecko/utils.tssrc/plugins/activePlugins.ts
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/naming-conventions.mdc)
**/*.{js,jsx,ts,tsx}: Use camelCase for variables, functions, and methods with descriptive names that explain the purpose
Use verb prefixes for functions that perform actions (e.g., fetch, validate, execute, update, calculate)
Use UPPER_SNAKE_CASE for constants and configuration values with descriptive names
Usehandleprefix for event handlers with descriptive names in camelCase
Use descriptive boolean variable names withis,has,can,shouldprefixes
Use named exports for components, functions, and utilities instead of default exports
Use descriptive import names and avoid renaming imports unless necessary
Avoid non-descriptive variable names likedata,item,obj, and single-letter variable names except in loops
Avoid abbreviations in names unless they are widely understood
Avoid generic function names likefn,func, orcallback
Files:
packages/caip/src/adapters/coingecko/utils.tssrc/plugins/activePlugins.ts
{.env.development,.env.production}
📄 CodeRabbit inference engine (CLAUDE.md)
Use
.env.developmentfor dev-only features and.env.productionfor prod settings
Files:
.env.development.env.production
🧠 Learnings (16)
📓 Common learnings
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10206
File: src/config.ts:127-128
Timestamp: 2025-08-07T11:20:44.614Z
Learning: gomesalexandre prefers required environment variables without default values in the config file (src/config.ts). They want explicit configuration and fail-fast behavior when environment variables are missing, rather than having fallback defaults.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/ContractInteractionBreakdown.tsx:0-0
Timestamp: 2025-09-13T16:45:18.813Z
Learning: gomesalexandre prefers aggressively deleting unused/obsolete code files ("ramboing") rather than fixing technical issues in code that won't be used, demonstrating his preference for keeping codebases clean and PR scope focused.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10458
File: src/plugins/walletConnectToDapps/types.ts:7-7
Timestamp: 2025-09-10T15:34:29.604Z
Learning: gomesalexandre is comfortable relying on transitive dependencies (like abitype through ethers/viem) rather than explicitly declaring them in package.json, preferring to avoid package.json bloat when the transitive dependency approach works reliably in practice.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10503
File: .env:56-56
Timestamp: 2025-09-16T13:17:02.938Z
Learning: gomesalexandre prefers to enable feature flags globally in the base .env file when the intent is to activate features everywhere, even when there are known issues like crashes, demonstrating his preference for intentional global feature rollouts over cautious per-environment enablement.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10249
File: src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx:447-503
Timestamp: 2025-08-13T17:07:10.763Z
Learning: gomesalexandre prefers relying on TypeScript's type system for validation rather than adding defensive runtime null checks when types are properly defined. They favor a TypeScript-first approach over defensive programming with runtime validations.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10276
File: src/hooks/useActionCenterSubscribers/useThorchainLpDepositActionSubscriber.tsx:61-66
Timestamp: 2025-08-14T17:51:47.556Z
Learning: gomesalexandre is not concerned about structured logging and prefers to keep console.error usage as-is rather than implementing structured logging patterns, even when project guidelines suggest otherwise.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10413
File: src/components/Modals/FiatRamps/fiatRampProviders/onramper/utils.ts:29-55
Timestamp: 2025-09-02T14:26:19.028Z
Learning: gomesalexandre prefers to keep preparatory/reference code simple until it's actively consumed, rather than implementing comprehensive error handling, validation, and robustness improvements upfront. They prefer to add these improvements when the code is actually being used in production.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10276
File: src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx:396-402
Timestamp: 2025-08-14T17:55:57.490Z
Learning: gomesalexandre is comfortable with functions/variables that return undefined or true (tri-state) when only the truthy case matters, preferring to rely on JavaScript's truthy/falsy behavior rather than explicitly returning boolean values.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10783
File: src/context/ModalStackProvider/useModalRegistration.ts:30-41
Timestamp: 2025-10-16T11:14:40.657Z
Learning: gomesalexandre prefers to add lint rules (like typescript-eslint/strict-boolean-expressions for truthiness checks on numbers) to catch common issues project-wide rather than relying on code review to catch them.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10206
File: src/lib/moralis.ts:47-85
Timestamp: 2025-08-07T11:22:16.983Z
Learning: gomesalexandre prefers console.error over structured logging for Moralis API integration debugging, as they find it more conventional and prefer to examine XHR requests directly rather than rely on structured logs for troubleshooting.
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to **/*.{ts,tsx} : Import types from `shapeshiftoss/caip` for chain/account/asset IDs
Applied to files:
packages/caip/src/adapters/coingecko/utils.ts
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/swappers/*/utils/constants.ts : Define supported chain IDs for each swapper in utils/constants.ts with both 'sell' and 'buy' properties following the pattern: SupportedChainIds type
Applied to files:
packages/caip/src/adapters/coingecko/utils.ts
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/swappers/*/*.ts : Implement filterBuyAssetsBySellAssetId method to filter assets by supported chain IDs in the buy property
Applied to files:
packages/caip/src/adapters/coingecko/utils.ts
📚 Learning: 2025-08-17T21:53:03.806Z
Learnt from: 0xApotheosis
Repo: shapeshift/web PR: 10290
File: scripts/generateAssetData/color-map.json:41-47
Timestamp: 2025-08-17T21:53:03.806Z
Learning: In the ShapeShift web codebase, native assets (using CAIP-19 slip44 namespace like eip155:1/slip44:60, bip122:.../slip44:..., cosmos:.../slip44:...) are manually hardcoded and not generated via the automated asset generation script. Only ERC20/BEP20 tokens go through the asset generation process. The validation scripts should only validate generated assets, not manually added native assets.
Applied to files:
packages/caip/src/adapters/coingecko/utils.tsscripts/generateAssetData/color-map.json
📚 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/caip/src/adapters/coingecko/utils.ts
📚 Learning: 2025-09-08T15:53:09.362Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10442
File: src/components/TradeAssetSearch/components/GroupedAssetList/GroupedAssetList.tsx:34-35
Timestamp: 2025-09-08T15:53:09.362Z
Learning: In DefaultAssetList.tsx, the GroupedAssetList component already receives the activeChainId prop correctly on line ~58, contrary to automated analysis that may flag it as missing.
Applied to files:
packages/caip/src/adapters/coingecko/utils.ts
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/swappers/*/*.ts : Implement filterAssetIdsBySellable method to filter assets by supported chain IDs in the sell property
Applied to files:
packages/caip/src/adapters/coingecko/utils.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/caip/src/adapters/coingecko/utils.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/caip/src/adapters/coingecko/utils.ts
📚 Learning: 2025-10-23T14:27:19.073Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10857
File: src/plugins/walletConnectToDapps/eventsManager/useWalletConnectEventsHandler.ts:101-104
Timestamp: 2025-10-23T14:27:19.073Z
Learning: In WalletConnect wallet_switchEthereumChain and wallet_addEthereumChain requests, the chainId parameter is always present as per the protocol spec. Type guards checking for missing chainId in these handlers (like `if (!evmNetworkIdHex) return`) are solely for TypeScript compiler satisfaction, not real runtime edge cases.
Applied to files:
packages/caip/src/adapters/coingecko/utils.ts
📚 Learning: 2025-11-05T23:37:30.632Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10912
File: src/context/WalletProvider/NewWalletViews/NewWalletViewsSwitch.tsx:290-290
Timestamp: 2025-11-05T23:37:30.632Z
Learning: In the ShapeShift web codebase, `isMobile` imported from '@/lib/globals' is a module-level constant (defined as `export const isMobile = Boolean(window?.isShapeShiftMobile)`) that is evaluated once at module load time. It is a stable reference that does not need to be included in useCallback/useMemo/useEffect dependency arrays.
Applied to files:
src/plugins/activePlugins.ts
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to src/config.ts : Default values always come from environment variables prefixed with `VITE_FEATURE_`
Applied to files:
.env.development.env.production
📚 Learning: 2025-12-03T23:19:39.158Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11275
File: headers/csps/chains/plasma.ts:1-10
Timestamp: 2025-12-03T23:19:39.158Z
Learning: For CSP files in headers/csps/chains/, gomesalexandre prefers using Vite's loadEnv() pattern directly to load environment variables (e.g., VITE_PLASMA_NODE_URL, VITE_MONAD_NODE_URL) for consistency with existing second-class chain CSP files, rather than using getConfig() from src/config.ts, even though other parts of the codebase use validated config values.
Applied to files:
.env.development.env.production
📚 Learning: 2025-09-09T06:01:24.130Z
Learnt from: 0xApotheosis
Repo: shapeshift/web PR: 10424
File: .env.production:3-3
Timestamp: 2025-09-09T06:01:24.130Z
Learning: In Vite, environment variables have a fallback mechanism where .env.production takes precedence over .env, but variables defined only in .env will still be available in the production environment if not overridden in .env.production.
Applied to files:
.env.development.env.production
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to {.env.development,.env.production} : Use `.env.development` for dev-only features and `.env.production` for prod settings
Applied to files:
.env.development
🧬 Code graph analysis (1)
packages/caip/src/adapters/coingecko/utils.ts (2)
packages/caip/src/assetId/assetId.ts (1)
toAssetId(59-127)packages/caip/src/constants.ts (3)
CHAIN_NAMESPACE(87-94)CHAIN_REFERENCE(100-124)plasmaChainId(76-76)
🪛 dotenv-linter (4.0.0)
.env.development
[warning] 66-66: [UnorderedKey] The VITE_PLASMA_NODE_URL key should go before the VITE_POLYGON_NODE_URL key
(UnorderedKey)
[warning] 95-95: [UnorderedKey] The VITE_FEATURE_PLASMA key should go before the VITE_FEATURE_TRON key
(UnorderedKey)
.env.production
[warning] 63-63: [UnorderedKey] The VITE_PLASMA_NODE_URL key should go before the VITE_POLYGON_NODE_URL key
(UnorderedKey)
🔇 Additional comments (3)
scripts/generateAssetData/color-map.json (1)
4683-4683: Verify these token additions align with Plasma chain support.This file shows color mappings for ERC20 tokens on Ethereum, Avalanche, BSC, and Base—but the PR objective states this is adding Plasma chain support. None of the changes include Plasma-specific token identifiers.
Clarify whether:
- These token additions support the Plasma ecosystem (e.g., tokens bridged to Plasma) but aren't Plasma-native assets
- Plasma chain color entries exist elsewhere in this PR
- These changes are unrelated to the Plasma feature and shouldn't be in this PR
Also applies to: 8702-8702, 12342-12342, 13753-13753, 14649-14649
src/plugins/activePlugins.ts (1)
17-17: LGTM! Plasma plugin correctly registered.The import and array entry for the plasma plugin are correctly positioned alphabetically and follow the established pattern for adding new chain plugins.
Also applies to: 43-43
.env.production (1)
1-70: No action needed—the.envstructure is correct.The base
.envfile does not containVITE_FEATURE_PLASMAand should not. The feature flag is properly configured with a code-level default offalseinsrc/config.ts(line 97), which applies to production. Development overrides this withVITE_FEATURE_PLASMA=truein.env.development, enabling the feature for testing. This is the correct pattern.Likely an incorrect or invalid review comment.
- Update PlasmaChainAdapter to use proper multicall implementation - Import MULTICALL3_CONTRACT from @shapeshiftoss/contracts instead of hardcoding - Import multicall3Abi from viem instead of inline definition - Add PQueue throttling to prevent rate limiting issues - Wrap all provider calls in requestQueue.add() - Update chain-integration skill with multicall and throttling patterns - Update swapper-integration skill with rate limiting guidance - Note: CoinGecko does support 'plasma' as valid platform ID
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (1)
packages/chain-adapters/src/evm/plasma/PlasmaChainAdapter.ts (1)
89-93: Adjust rate limiting to 25 req/s.The current configuration allows ~20 req/s (1 request per 50ms), but based on previous feedback, Plasma requires throttling at 25 req/s to avoid rate limiting issues.
Apply this diff to fix the rate limit:
this.requestQueue = new PQueue({ intervalCap: 1, - interval: 50, + interval: 40, concurrency: 1, })This changes the rate from 20 req/s (1000ms/50ms) to 25 req/s (1000ms/40ms).
🧹 Nitpick comments (3)
.claude/skills/chain-integration/SKILL.md (2)
1044-1044: Specify language for code fence.The code block at line 1044 is missing a language identifier. Add a language specifier to the opening fence for proper syntax highlighting.
-\``` +\```
1060-1060: Wrap bare URLs in markdown links.Lines 1060, 1065, 1066, and 1068 contain bare URLs. Wrap them in markdown link syntax for better readability and CSP compliance in the rendered documentation.
Example:
-Check if your chain's viem chain definition exists (e.g., `plasma` from 'viem/chains') +Check if your chain's viem chain definition exists (e.g., `plasma` from [viem/chains](https://github.com/wevm/viem/tree/main/src/chains))Also applies to: 1065-1068
.env (1)
236-236: Reorder for alphabetical consistency.The feature flag should be placed before
VITE_FEATURE_SUNIO_SWAPto maintain alphabetical ordering (MONAD → PLASMA → SUNIO_SWAP).Apply this diff to fix the ordering:
VITE_FEATURE_CETUS_SWAP=false VITE_FEATURE_SUNIO_SWAP=false VITE_FEATURE_MONAD=false +VITE_FEATURE_PLASMA=false -VITE_FEATURE_PLASMA=falseBased on learnings, ensure the feature flag is also added to
src/state/slices/preferencesSlice/preferencesSlice.ts,src/config.ts, andsrc/test/mocks/store.tsper the standard feature flag pattern.
📜 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 (1)
yarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (4)
.claude/skills/chain-integration/SKILL.md(6 hunks).claude/skills/swapper-integration/SKILL.md(1 hunks).env(1 hunks)packages/chain-adapters/src/evm/plasma/PlasmaChainAdapter.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{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/evm/plasma/PlasmaChainAdapter.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/evm/plasma/PlasmaChainAdapter.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/evm/plasma/PlasmaChainAdapter.ts
🧠 Learnings (36)
📓 Common learnings
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.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10206
File: src/config.ts:127-128
Timestamp: 2025-08-07T11:20:44.614Z
Learning: gomesalexandre prefers required environment variables without default values in the config file (src/config.ts). They want explicit configuration and fail-fast behavior when environment variables are missing, rather than having fallback defaults.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/ContractInteractionBreakdown.tsx:0-0
Timestamp: 2025-09-13T16:45:18.813Z
Learning: gomesalexandre prefers aggressively deleting unused/obsolete code files ("ramboing") rather than fixing technical issues in code that won't be used, demonstrating his preference for keeping codebases clean and PR scope focused.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10458
File: src/plugins/walletConnectToDapps/types.ts:7-7
Timestamp: 2025-09-10T15:34:29.604Z
Learning: gomesalexandre is comfortable relying on transitive dependencies (like abitype through ethers/viem) rather than explicitly declaring them in package.json, preferring to avoid package.json bloat when the transitive dependency approach works reliably in practice.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10503
File: .env:56-56
Timestamp: 2025-09-16T13:17:02.938Z
Learning: gomesalexandre prefers to enable feature flags globally in the base .env file when the intent is to activate features everywhere, even when there are known issues like crashes, demonstrating his preference for intentional global feature rollouts over cautious per-environment enablement.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10249
File: src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx:447-503
Timestamp: 2025-08-13T17:07:10.763Z
Learning: gomesalexandre prefers relying on TypeScript's type system for validation rather than adding defensive runtime null checks when types are properly defined. They favor a TypeScript-first approach over defensive programming with runtime validations.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10276
File: src/hooks/useActionCenterSubscribers/useThorchainLpDepositActionSubscriber.tsx:61-66
Timestamp: 2025-08-14T17:51:47.556Z
Learning: gomesalexandre is not concerned about structured logging and prefers to keep console.error usage as-is rather than implementing structured logging patterns, even when project guidelines suggest otherwise.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10413
File: src/components/Modals/FiatRamps/fiatRampProviders/onramper/utils.ts:29-55
Timestamp: 2025-09-02T14:26:19.028Z
Learning: gomesalexandre prefers to keep preparatory/reference code simple until it's actively consumed, rather than implementing comprehensive error handling, validation, and robustness improvements upfront. They prefer to add these improvements when the code is actually being used in production.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10276
File: src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx:396-402
Timestamp: 2025-08-14T17:55:57.490Z
Learning: gomesalexandre is comfortable with functions/variables that return undefined or true (tri-state) when only the truthy case matters, preferring to rely on JavaScript's truthy/falsy behavior rather than explicitly returning boolean values.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10783
File: src/context/ModalStackProvider/useModalRegistration.ts:30-41
Timestamp: 2025-10-16T11:14:40.657Z
Learning: gomesalexandre prefers to add lint rules (like typescript-eslint/strict-boolean-expressions for truthiness checks on numbers) to catch common issues project-wide rather than relying on code review to catch them.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10206
File: src/lib/moralis.ts:47-85
Timestamp: 2025-08-07T11:22:16.983Z
Learning: gomesalexandre prefers console.error over structured logging for Moralis API integration debugging, as they find it more conventional and prefer to examine XHR requests directly rather than rely on structured logs for troubleshooting.
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: To add a new feature flag: (1) Add to `FeatureFlags` type in `src/state/slices/preferencesSlice/preferencesSlice.ts`, (2) Add environment variable validation in `src/config.ts`, (3) Add to initial state in `preferencesSlice.ts`, (4) Add to test mock in `src/test/mocks/store.ts`, (5) Set appropriate values in `.env`, `.env.development`, and `.env.production`
Applied to files:
.env
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to src/config.ts : Default values always come from environment variables prefixed with `VITE_FEATURE_`
Applied to files:
.env
📚 Learning: 2025-12-03T23:19:39.158Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11275
File: headers/csps/chains/plasma.ts:1-10
Timestamp: 2025-12-03T23:19:39.158Z
Learning: For CSP files in headers/csps/chains/, gomesalexandre prefers using Vite's loadEnv() pattern directly to load environment variables (e.g., VITE_PLASMA_NODE_URL, VITE_MONAD_NODE_URL) for consistency with existing second-class chain CSP files, rather than using getConfig() from src/config.ts, even though other parts of the codebase use validated config values.
Applied to files:
.env
📚 Learning: 2025-11-12T12:48:02.977Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11016
File: packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts:93-93
Timestamp: 2025-11-12T12:48:02.977Z
Learning: In the swapper architecture, timeout handling is implemented at the abstraction layer in packages/swapper/src/swapper.ts using timeoutMonadic, which wraps all calls to individual swapper implementations. Individual swapper implementations (e.g., NearIntentsSwapper, PortalsSwapper, etc.) should NOT use timeoutMonadic directly—they simply return their results and the abstraction layer handles timeout concerns centrally.
Applied to files:
.claude/skills/swapper-integration/SKILL.md
📚 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 **/api/**/*.{ts,tsx} : ALWAYS use `timeoutMonadic` for API calls with appropriate timeout values and handle timeout errors gracefully
Applied to files:
.claude/skills/swapper-integration/SKILL.md
📚 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:
.claude/skills/swapper-integration/SKILL.md
📚 Learning: 2025-12-04T22:57:50.850Z
Learnt from: kaladinlight
Repo: shapeshift/web PR: 11290
File: packages/chain-adapters/src/utxo/zcash/ZcashChainAdapter.ts:48-51
Timestamp: 2025-12-04T22:57:50.850Z
Learning: In packages/chain-adapters/src/**/*ChainAdapter.ts files, the getName() method uses the pattern `const enumIndex = Object.values(ChainAdapterDisplayName).indexOf(ChainAdapterDisplayName.XXX); return Object.keys(ChainAdapterDisplayName)[enumIndex]` to reverse-lookup the enum key from its value. This is the established pattern used consistently across almost all chain adapters (Bitcoin, Ethereum, Litecoin, Dogecoin, Polygon, Arbitrum, Cosmos, etc.) and should be preserved for consistency when adding new chain adapters.
Applied to files:
.claude/skills/chain-integration/SKILL.mdpackages/chain-adapters/src/evm/plasma/PlasmaChainAdapter.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:
.claude/skills/chain-integration/SKILL.mdpackages/chain-adapters/src/evm/plasma/PlasmaChainAdapter.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:
.claude/skills/chain-integration/SKILL.md
📚 Learning: 2025-09-12T13:44:17.019Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/hooks/useSimulateEvmTransaction.ts:0-0
Timestamp: 2025-09-12T13:44:17.019Z
Learning: gomesalexandre prefers letting chain adapter errors throw naturally in useSimulateEvmTransaction rather than adding explicit error handling for missing adapters, consistent with his fail-fast approach and dismissal of defensive validation as "stale" in WalletConnect transaction simulation flows.
Applied to files:
.claude/skills/chain-integration/SKILL.mdpackages/chain-adapters/src/evm/plasma/PlasmaChainAdapter.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:
.claude/skills/chain-integration/SKILL.mdpackages/chain-adapters/src/evm/plasma/PlasmaChainAdapter.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:
.claude/skills/chain-integration/SKILL.mdpackages/chain-adapters/src/evm/plasma/PlasmaChainAdapter.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:
.claude/skills/chain-integration/SKILL.mdpackages/chain-adapters/src/evm/plasma/PlasmaChainAdapter.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:
.claude/skills/chain-integration/SKILL.md
📚 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:
.claude/skills/chain-integration/SKILL.mdpackages/chain-adapters/src/evm/plasma/PlasmaChainAdapter.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:
.claude/skills/chain-integration/SKILL.mdpackages/chain-adapters/src/evm/plasma/PlasmaChainAdapter.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:
.claude/skills/chain-integration/SKILL.md
📚 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:
.claude/skills/chain-integration/SKILL.mdpackages/chain-adapters/src/evm/plasma/PlasmaChainAdapter.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:
.claude/skills/chain-integration/SKILL.mdpackages/chain-adapters/src/evm/plasma/PlasmaChainAdapter.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:
.claude/skills/chain-integration/SKILL.md
📚 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:
.claude/skills/chain-integration/SKILL.md
📚 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:
.claude/skills/chain-integration/SKILL.md
📚 Learning: 2025-09-16T08:47:31.440Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10528
File: src/plugins/walletConnectToDapps/utils/createApprovalNamespaces.ts:39-47
Timestamp: 2025-09-16T08:47:31.440Z
Learning: In WalletConnect dApps createApprovalNamespaces logic, required namespaces have different semantics than optional namespaces. Required namespaces are validated upfront in the UI - users cannot proceed without accounts for all required chains, and required chains are always selected and unselectable. Therefore, additional filtering by selectedChainIds is unnecessary for required namespaces since the validation flow guarantees they will be supported and selected.
Applied to files:
.claude/skills/chain-integration/SKILL.md
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to src/state/slices/**/*.ts : Migrations are required when changing persisted state structure (see `src/state/migrations/`)
Applied to files:
.claude/skills/chain-integration/SKILL.md
📚 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:
.claude/skills/chain-integration/SKILL.md
📚 Learning: 2025-11-24T21:21:12.774Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/typescript-best-practices.mdc:0-0
Timestamp: 2025-11-24T21:21:12.774Z
Learning: Applies to **/*.{ts,tsx} : ALWAYS use type guards for runtime type checking in TypeScript
Applied to files:
packages/chain-adapters/src/evm/plasma/PlasmaChainAdapter.ts
📚 Learning: 2025-11-24T21:21:12.774Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/typescript-best-practices.mdc:0-0
Timestamp: 2025-11-24T21:21:12.774Z
Learning: Applies to **/*.{ts,tsx} : ALWAYS use type guards instead of type assertions when possible in TypeScript
Applied to files:
packages/chain-adapters/src/evm/plasma/PlasmaChainAdapter.ts
📚 Learning: 2025-11-24T21:21:12.774Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/typescript-best-practices.mdc:0-0
Timestamp: 2025-11-24T21:21:12.774Z
Learning: Applies to **/*.{ts,tsx} : ALWAYS use `is` prefix for type guard functions in TypeScript
Applied to files:
packages/chain-adapters/src/evm/plasma/PlasmaChainAdapter.ts
📚 Learning: 2025-11-24T21:21:12.774Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/typescript-best-practices.mdc:0-0
Timestamp: 2025-11-24T21:21:12.774Z
Learning: Applies to **/*.{ts,tsx} : ALWAYS create custom type guards for complex types in TypeScript
Applied to files:
packages/chain-adapters/src/evm/plasma/PlasmaChainAdapter.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/evm/plasma/PlasmaChainAdapter.ts
📚 Learning: 2025-09-12T10:35:51.632Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/utils/tenderly/index.ts:33-45
Timestamp: 2025-09-12T10:35:51.632Z
Learning: gomesalexandre consistently dismisses CodeRabbit suggestions about replacing console.error/console.warn with structured logging in API integration code, preferring simple console logging for debugging Tenderly transaction simulation APIs in WalletConnect flows.
Applied to files:
packages/chain-adapters/src/evm/plasma/PlasmaChainAdapter.ts
📚 Learning: 2025-08-11T09:45:51.174Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10219
File: src/components/MultiHopTrade/components/TradeInput/TradeInput.tsx:175-180
Timestamp: 2025-08-11T09:45:51.174Z
Learning: gomesalexandre prefers truthy checks over explicit boolean comparisons (e.g., `walletSupportsSellAssetChain` instead of `walletSupportsSellAssetChain === true`) when dealing with tri-state values (boolean | null) in TypeScript, as the falsy behavior for null/undefined is intentional and acceptable.
Applied to files:
packages/chain-adapters/src/evm/plasma/PlasmaChainAdapter.ts
📚 Learning: 2025-12-09T21:06:09.903Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11335
File: packages/swapper/src/swappers/CetusSwapper/endpoints.ts:66-68
Timestamp: 2025-12-09T21:06:09.903Z
Learning: In packages/swapper/src/swappers/CetusSwapper/endpoints.ts, gomesalexandre is comfortable with throwing errors directly in getUnsignedSuiTransaction and similar transaction preparation methods, rather than using the Result pattern. The Result pattern with makeSwapErrorRight/TradeQuoteError is primarily for the main swapper API methods (getTradeQuote, getTradeRate), while helper/preparation methods can use throws.
Applied to files:
packages/chain-adapters/src/evm/plasma/PlasmaChainAdapter.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/evm/plasma/PlasmaChainAdapter.ts
📚 Learning: 2025-10-16T11:14:40.657Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10783
File: src/context/ModalStackProvider/useModalRegistration.ts:30-41
Timestamp: 2025-10-16T11:14:40.657Z
Learning: gomesalexandre prefers to add lint rules (like typescript-eslint/strict-boolean-expressions for truthiness checks on numbers) to catch common issues project-wide rather than relying on code review to catch them.
Applied to files:
packages/chain-adapters/src/evm/plasma/PlasmaChainAdapter.ts
🪛 dotenv-linter (4.0.0)
.env
[warning] 236-236: [UnorderedKey] The VITE_FEATURE_PLASMA key should go before the VITE_FEATURE_SUNIO_SWAP key
(UnorderedKey)
🪛 LanguageTool
.claude/skills/chain-integration/SKILL.md
[uncategorized] ~639-~639: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...ueue.add(() => ...)` - This prevents rate limiting issues with public RPCs 5. **Direct RPC...
(EN_COMPOUND_ADJECTIVE_INTERNAL)
🪛 markdownlint-cli2 (0.18.1)
.claude/skills/chain-integration/SKILL.md
1044-1044: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
1060-1060: Bare URL used
(MD034, no-bare-urls)
1065-1065: Bare URL used
(MD034, no-bare-urls)
1066-1066: Bare URL used
(MD034, no-bare-urls)
1068-1068: Bare URL used
(MD034, no-bare-urls)
🔇 Additional comments (11)
.claude/skills/swapper-integration/SKILL.md (1)
258-284: Well-documented rate limiting pattern.The new "Key Pattern: Rate Limiting and Throttling" section clearly documents a practical pattern for implementing request queuing on chain adapters and swappers that directly interact with RPC/API endpoints. The examples properly show both swapper service and provider call patterns, and the use-case clarification (public endpoints) is helpful.
.claude/skills/chain-integration/SKILL.md (7)
1390-1409: Gotcha 11 excellently documents a subtle EVM chain requirement.The documentation clearly explains why
assertSupportsChainneeds explicit cases for each chain inEvmBaseAdapter, even when hdwallet properly implements the support interfaces. This gotcha prevents a common integration mistake where developers assume the wallet's_supportsChainNameflag is sufficient.
1411-1448: Gotcha 12 is critical and well-emphasizes the scope.This gotcha correctly and emphatically documents that
ledgerAppGate.tschanges are needed for ALL wallet types (not just Ledger), and that missing cases cause misleading "Unsupported chainId" errors even during native wallet derivation. The example error message and the bold "CRITICAL" label appropriately highlight this integration blocker.
1450-1494: Gotcha 13 documents an important portfolio state bug.The documentation clearly explains how unsupported chains in Portals can cascade into account removal from Redux state, and provides the correct graceful-skip pattern. This prevents a confusing symptom where accounts briefly appear then vanish.
1496-1538: Gotcha 14 maps UI symptom (missing dropdown) to root cause (missing switch case).The documentation connects observable symptoms in the swapper UI (no dropdown, account unselectable, balance shows in header but input shows 0) to the missing
accountIdToLabelswitch case. This symptom-to-cause mapping is invaluable for future integrators who might encounter the same issue.
1366-1388: Gotcha 10 documents essential rate-limiting pattern for EVM chains.The PQueue throttling pattern (
intervalCap: 1, interval: 50, concurrency: 1) is clearly explained with concrete implementation guidance. This prevents 429 errors and connection issues from public RPCs—a common gotcha for chains using public endpoints.
1036-1111: New swapper support section provides systematic research guidance.The addition of Step 5.4 guides integrators through researching and implementing swapper support (Relay, 0x, CowSwap, etc.) with specific documentation links and implementation patterns. This fills a gap in the original guide and prevents incomplete integrations where a chain works but swaps don't.
1559-1570: Updated checklist correctly marks critical files.The additions to the checklist appropriately flag
ledgerAppGate.tsandportfolioSlice/utils/index.ts(accountIdToLabel) as CRITICAL, emphasizing they must not be overlooked. The annotations explaining why (with Gotcha references) make the checklist actionable.packages/chain-adapters/src/evm/plasma/PlasmaChainAdapter.ts (3)
149-265: LGTM: Token balance retrieval implementation.The multicall-based token balance retrieval with fallback to individual calls is well-designed. The batching strategy (500 tokens per batch), error handling, and requestQueue integration provide good resilience against RPC failures and rate limits.
267-332: LGTM: Gas fee estimation logic.The fee estimation correctly calculates
txFee = (maxFeePerGas ?? gasPrice) × gasLimitfor each tier. Using identical fees for fast/average/slow is appropriate for chains without a mature fee market.
334-377: LGTM: Transaction broadcasting with proper safeguards.The broadcast implementation correctly validates addresses against sanctions lists before submitting transactions. The stub implementations for subscriptions, history, and parsing are appropriate for an initial chain adapter implementation.
- Remove Plasma from Portals supported networks configuration - Prevents unwanted API calls to portals/v2/account?networks[]=plasma - Plasma is not supported by Portals, should gracefully skip instead - Add Plasma to isNativeEvmAsset helper for proper native token detection - Fix CoinGecko adapter test to include Plasma in expected results - Note: Plasma does NOT need Tenderly gas overrides like Monad - Note: Plasma is NOT supported by Near Intents swapper
Description
Test me with hdwallet fren
Issue (if applicable)
closes N/A
Risk
Low, new chain, under flag
Testing
Test:
Engineering
Operations
Screenshots (if applicable)
https://jam.dev/c/e512e61b-d21f-4522-bd55-1eeea374e31c
https://jam.dev/c/abed37f6-2227-4826-9b59-02250c914d64
Summary by CodeRabbit
New Features
Chores
✏️ Tip: You can customize this high-level summary in your review settings.