-
Notifications
You must be signed in to change notification settings - Fork 198
feat: implement monad #11241
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
feat: implement monad #11241
Conversation
|
Warning Rate limit exceeded@gomesalexandre has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 13 minutes and 5 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 ignored due to path filters (1)
📒 Files selected for processing (1)
📝 WalkthroughWalkthroughAdds Monad blockchain support across configuration, types, adapters, asset generation, plugin registration, feature flags, wallet/ledger checks, and RPC client wiring; introduces a Monad EVM chain adapter and related utilities, environment variables, and asset-generation entries. Changes
Sequence Diagram(s)sequenceDiagram
participant UI as Client/UI
participant PP as PluginProvider
participant Plugin as Monad Plugin
participant Adapter as MonadChainAdapter
participant Viem as Viem PublicClient
participant Node as Monad RPC Node
UI->>PP: Request to enable chain / perform tx
PP->>Plugin: instantiate/register (if VITE_FEATURE_MONAD)
Plugin->>Adapter: build Adapter with VITE_MONAD_NODE_URL + knownTokens
UI->>Adapter: getAccount / broadcastTransaction / getFeeData
Adapter->>Viem: use public client for RPC calls (multicall, eth_call, eth_sendRawTx)
Viem->>Node: HTTP/WS RPC requests to VITE_MONAD_NODE_URL
Node-->>Viem: RPC responses
Viem-->>Adapter: returns balances / receipt / txHash
Adapter-->>UI: account info / tx result / fee data
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/constants/chains.ts (1)
8-25: Add MonadMainnet feature‑flag gating toknownChainIdsDefining
SECOND_CLASS_CHAINSwithKnownChainIds.MonadMainnetis fine, butknownChainIdscurrently doesn’t respect the Monad feature flag. Other chains (e.g. Tron) are excluded when their flag is off; Monad should follow the same pattern so it doesn’t appear inknownChainIdswhenVITE_FEATURE_MONAD(and the correspondingenabledFlagsentry) is disabled.Consider adding a guard like this (adjusting the flag key name to match
preferencesSlice):if (chainId === KnownChainIds.MonadMainnet && !enabledFlags.Monad) return falseThis keeps
knownChainIdsin sync with feature‑flag expectations for the new chain.
🧹 Nitpick comments (9)
.env.production (1)
30-31: LGTM! Monad environment configuration follows the established pattern.The new Monad-specific environment variables mirror the structure used for other EVM chains. The use of public RPC endpoints aligns with the PR objectives.
Note: Static analysis flagged key ordering (UnorderedKey), but this is a cosmetic issue. Consider alphabetizing keys within each section for consistency, but this is purely optional.
Also applies to: 60-60
src/lib/utils/monad.ts (2)
19-28: Consider more descriptive error message.The generic error message "invalid chain adapter" could be improved for debugging purposes.
Apply this diff:
if (!isMonadChainAdapter(adapter)) { - throw Error('invalid chain adapter') + throw Error(`Expected Monad chain adapter, but got adapter for chain: ${adapter?.getChainId?.() ?? 'unknown'}`) }
30-61: Add timeout and structured logging to RPC call.The fetch call lacks a timeout, which could cause indefinite blocking. Additionally, per coding guidelines, structured logging is preferred over
console.error.Apply this diff:
+import { moduleLogger } from '@/lib/logger' + +const logger = moduleLogger('monad') + export const getMonadTransactionStatus = async (txHash: string): Promise<TxStatus> => { const rpcUrl = getConfig().VITE_MONAD_NODE_URL try { - const response = await fetch(rpcUrl, { + const controller = new AbortController() + const timeoutId = setTimeout(() => controller.abort(), 30000) + + const response = await fetch(rpcUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ jsonrpc: '2.0', method: 'eth_getTransactionReceipt', params: [txHash], id: 1, }), + signal: controller.signal, }) + + clearTimeout(timeoutId) if (!response.ok) return TxStatus.Unknown const data = await response.json() const receipt = data?.result if (!receipt) return TxStatus.Pending // status is 0x0 for failed, 0x1 for confirmed if (receipt.status === '0x1') return TxStatus.Confirmed if (receipt.status === '0x0') return TxStatus.Failed return TxStatus.Unknown } catch (error) { - console.error('Error fetching Monad transaction status:', error) + logger.error({ error, txHash }, 'Error fetching Monad transaction status') return TxStatus.Unknown } }.env (1)
230-230: LGTM! Feature flag follows the established pattern.The VITE_FEATURE_MONAD flag is appropriately defaulted to
falsein the base environment file, with development environments enabling it as needed.Note: Static analysis flagged key ordering, but this is cosmetic. Consider sorting feature flags alphabetically for consistency, but this is purely optional.
.env.development (1)
34-36: Monad env vars are fine; optionally fix key ordering for dotenv‑linterThe new Monad HTTP/WS URLs, node URL, and
VITE_FEATURE_MONAD=truefit the existing patterns and match the intended feature‑flag behavior for dev.If
dotenv-linteris part of your checks and you want a clean run, you may want to move:
VITE_UNCHAINED_MONAD_HTTP_URL/VITE_UNCHAINED_MONAD_WS_URLabove the Optimism entries, andVITE_MONAD_NODE_URLaboveVITE_OPTIMISM_NODE_URL,VITE_FEATURE_MONADaboveVITE_FEATURE_TRON,to restore the expected key ordering.
Also applies to: 64-65, 90-92
src/state/slices/preferencesSlice/preferencesSlice.ts (1)
21-33: Monad feature flag is correctly added and initialized
Monadis added toFeatureFlagsand wired togetConfig().VITE_FEATURE_MONADininitialState.featureFlags, matching the existing pattern for other chain flags and the new config validator.If this preferences slice is part of persisted state, you may want to consider a small migration step to explicitly seed
featureFlags.Monadfor existing users, though at runtime a missing key will effectively behave asfalsein the current checks.Also applies to: 154-167
packages/chain-adapters/src/evm/EvmBaseAdapter.ts (1)
18-21: Monad integration into EvmBaseAdapter is sound; consider tweaking nativeCurrency name
KnownChainIds.MonadMainnetis correctly added toevmChainIds, andassertSupportsChainnow delegates tosupportsMonad(wallet)for the appropriate chain reference.- The
assertSwitchChaintargetNetworkentry for Monad uses the right explorer and wires into the existing EIP‑3085 flow as expected.Optional: to stay consistent with
baseAssetsand other networks, you might setname: 'Monad'(keepingsymbol: 'MON') in the MonadtargetNetworkentry, sonativeCurrency.namematches the actual asset name shown elsewhere.Also applies to: 70-81, 153-182, 256-260
packages/chain-adapters/src/evm/monad/MonadChainAdapter.ts (2)
99-102: Fragile enum key lookup.The indirect enum key lookup via
indexOfis brittle and harder to maintain. Consider returning the key directly.getName() { - const enumIndex = Object.values(ChainAdapterDisplayName).indexOf(ChainAdapterDisplayName.Monad) - return Object.keys(ChainAdapterDisplayName)[enumIndex] + return 'Monad' }
275-296: No fee tier differentiation.All fee tiers (fast, average, slow) return identical values. If Monad supports priority fees, consider applying multipliers to differentiate tiers. If not, this is acceptable as-is.
- Fix fee tier bug: use ...slow instead of ...fast in slow tier chainSpecific - Add feature flag gating for Monad assets in AssetService - Add feature flag gating for Monad in knownChainIds filtering - Simplify getName() method to return 'Monad' directly - Bump hdwallet packages to 1.62.17-monad.0 for Monad support 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
packages/chain-adapters/src/evm/monad/MonadChainAdapter.ts (2)
95-101: Optional: add explicit return types for display/name methodsTo align with the TypeScript guidelines about explicit return types, consider annotating these two methods:
getDisplayName(): ChainAdapterDisplayName { ... } getName(): string { ... }Behavior is fine as-is; this is just for consistency.
339-356: Optional: simplify sanctions check for readability inbroadcastTransactionThe current
Promise.allusage mixes a Promise and a boolean (receiverAddress !== CONTRACT_INTERACTION && assertAddressNotSanctioned(receiverAddress)), which works but is a bit opaque. For clarity and slightly stricter typing, consider:const checks = [assertAddressNotSanctioned(senderAddress)] if (receiverAddress !== CONTRACT_INTERACTION) { checks.push(assertAddressNotSanctioned(receiverAddress)) } await Promise.all(checks)Semantics stay identical; this just avoids the boolean short‑circuit inside
Promise.all.
📜 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)
package.json(2 hunks)packages/chain-adapters/src/evm/monad/MonadChainAdapter.ts(1 hunks)src/constants/chains.ts(2 hunks)src/lib/asset-service/service/AssetService.ts(2 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:
src/constants/chains.tssrc/lib/asset-service/service/AssetService.tspackages/chain-adapters/src/evm/monad/MonadChainAdapter.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:
src/constants/chains.tssrc/lib/asset-service/service/AssetService.tspackages/chain-adapters/src/evm/monad/MonadChainAdapter.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:
src/constants/chains.tssrc/lib/asset-service/service/AssetService.tspackages/chain-adapters/src/evm/monad/MonadChainAdapter.ts
🧠 Learnings (32)
📓 Common learnings
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: 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:
src/constants/chains.tssrc/lib/asset-service/service/AssetService.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:
src/constants/chains.tssrc/lib/asset-service/service/AssetService.ts
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Feature flags are stored in Redux state under `preferences.featureFlags`
Applied to files:
src/constants/chains.ts
📚 Learning: 2025-08-22T13:02:38.078Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10323
File: src/pages/Explore/Explore.tsx:91-92
Timestamp: 2025-08-22T13:02:38.078Z
Learning: In the ShapeShift web codebase, feature flags are consistently used as string literals with the useFeatureFlag hook (e.g., useFeatureFlag('RfoxFoxEcosystemPage')), not as enums. The hook accepts keyof FeatureFlags which provides type safety through the TypeScript type system rather than requiring an enum. This is the established pattern used throughout the entire codebase.
Applied to files:
src/constants/chains.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:
src/lib/asset-service/service/AssetService.tspackages/chain-adapters/src/evm/monad/MonadChainAdapter.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:
src/lib/asset-service/service/AssetService.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:
src/lib/asset-service/service/AssetService.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:
src/lib/asset-service/service/AssetService.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:
src/lib/asset-service/service/AssetService.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:
src/lib/asset-service/service/AssetService.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:
src/lib/asset-service/service/AssetService.tspackage.json
📚 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:
src/lib/asset-service/service/AssetService.tspackage.json
📚 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:
src/lib/asset-service/service/AssetService.ts
📚 Learning: 2025-11-19T22:20:25.661Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10767
File: package.json:324-324
Timestamp: 2025-11-19T22:20:25.661Z
Learning: In shapeshift/web package.json, the resolution "gridplus-sdk/bs58check": "2.1.2" is intentional and must not be removed. It forces gridplus-sdk's transitive bs58check dependency from 4.0.0 down to 2.1.2 because bs58check 4.0.0 breaks legacy address validation (due to bs58 v6.0.0 and noble/hash vs 2.1.2's bs58 v4.0.0 and create-hash).
Applied to files:
package.json
📚 Learning: 2025-08-08T20:16:12.898Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10222
File: package.json:202-202
Timestamp: 2025-08-08T20:16:12.898Z
Learning: In shapeshift/web, the semver package must be included in dependencies (not devDependencies) because hdwallet packages have transient dependencies that require semver but don't ship it themselves. This ensures semver is available at runtime for hdwallet functionality.
Applied to files:
package.json
📚 Learning: 2025-08-08T20:27:02.203Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10222
File: package.json:202-202
Timestamp: 2025-08-08T20:27:02.203Z
Learning: In shapeshift/web, while gomesalexandre generally prefers pinned dependencies for security, semver with a caret range (^7.7.2) is acceptable as an exception since it's already a transient dependency of many packages and is being made explicit for hdwallet support.
Applied to files:
package.json
📚 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:
package.jsonpackages/chain-adapters/src/evm/monad/MonadChainAdapter.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:
package.jsonpackages/chain-adapters/src/evm/monad/MonadChainAdapter.ts
📚 Learning: 2025-08-08T10:23:16.843Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10232
File: packages/unchained-client/openapitools.json:61-61
Timestamp: 2025-08-08T10:23:16.843Z
Learning: In shapeshift/web, for temporary “monkey patch” PRs (e.g., packages/unchained-client/openapitools.json using jsDelivr CDN refs like cosmos/mayachain), gomesalexandre is fine with branch-based URLs and does not want SHA pinning. Treat this as a scoped exception to their general preference for pinned dependencies/refs.
Applied to files:
package.json
📚 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/evm/monad/MonadChainAdapter.ts
📚 Learning: 2025-09-12T13:44:17.019Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/hooks/useSimulateEvmTransaction.ts:0-0
Timestamp: 2025-09-12T13:44:17.019Z
Learning: gomesalexandre prefers letting chain adapter errors throw naturally in useSimulateEvmTransaction rather than adding explicit error handling for missing adapters, consistent with his fail-fast approach and dismissal of defensive validation as "stale" in WalletConnect transaction simulation flows.
Applied to files:
packages/chain-adapters/src/evm/monad/MonadChainAdapter.ts
📚 Learning: 2025-10-15T15:57:39.956Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10810
File: src/plugins/walletConnectToDapps/utils/tenderly/index.ts:212-0
Timestamp: 2025-10-15T15:57:39.956Z
Learning: gomesalexandre uses discriminated union patterns (e.g., `isEIP1559 ? { max_fee_per_gas, max_priority_fee_per_gas } : { gas_price }`) in WalletConnect flows without additional validation guards, trusting that the runtime data structure ensures mutual exclusivity between EIP-1559 and legacy gas pricing fields.
Applied to files:
packages/chain-adapters/src/evm/monad/MonadChainAdapter.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/monad/MonadChainAdapter.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/evm/monad/MonadChainAdapter.ts
📚 Learning: 2025-09-12T13:43:50.695Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/hooks/useSimulateEvmTransaction.ts:91-95
Timestamp: 2025-09-12T13:43:50.695Z
Learning: gomesalexandre dismissed gas calculation overflow validation in useSimulateEvmTransaction hook as "stale", preferring to trust Tenderly's simulation data without defensive validation checks, consistent with his established pattern of relying on external service quality over defensive programming in WalletConnect flows.
Applied to files:
packages/chain-adapters/src/evm/monad/MonadChainAdapter.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/monad/MonadChainAdapter.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/evm/monad/MonadChainAdapter.ts
📚 Learning: 2025-09-11T22:53:19.837Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/EIP155TransactionConfirmation.tsx:27-31
Timestamp: 2025-09-11T22:53:19.837Z
Learning: gomesalexandre trusts Tenderly's data quality and doesn't want defensive validation for gas values (transaction?.gasLimit ?? transaction?.gas) in WalletConnect flows, preferring to rely on the external service providing valid hex values.
Applied to files:
packages/chain-adapters/src/evm/monad/MonadChainAdapter.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/evm/monad/MonadChainAdapter.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/evm/monad/MonadChainAdapter.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/evm/monad/MonadChainAdapter.ts
🧬 Code graph analysis (2)
src/lib/asset-service/service/AssetService.ts (1)
packages/caip/src/constants.ts (1)
monadChainId(71-71)
packages/chain-adapters/src/evm/monad/MonadChainAdapter.ts (8)
packages/caip/src/assetId/assetId.ts (1)
AssetId(17-17)packages/chain-adapters/src/evm/EvmBaseAdapter.ts (1)
ChainAdapterArgs(91-98)packages/types/src/base.ts (1)
RootBip44Params(5-9)packages/caip/src/constants.ts (2)
ASSET_REFERENCE(125-146)monadAssetId(18-18)packages/chain-adapters/src/types.ts (3)
Account(55-61)GetFeeDataInput(318-325)FeeDataEstimate(103-107)packages/chain-adapters/src/evm/types.ts (1)
GasFeeDataEstimate(76-80)packages/chain-adapters/src/utils/validateAddress.ts (1)
assertAddressNotSanctioned(7-24)packages/chain-adapters/src/error/ErrorHandler.ts (1)
ErrorHandler(28-73)
🔇 Additional comments (10)
src/lib/asset-service/service/AssetService.ts (1)
10-10: Monad asset gating is correctly wired and consistent with existing chainsThe
monadChainIdimport and theVITE_FEATURE_MONAD‑based filter follow the same pattern as the other chain feature flags, ensuring Monad assets stay hidden when the feature is disabled while preserving asset ordering. No issues from this change.Also applies to: 49-50
src/constants/chains.ts (2)
8-11: Monad added consistently to SECOND_CLASS_CHAINSIncluding
KnownChainIds.MonadMainnetalongside Tron follows the existing pattern for second‑class EVM-ish chains and looks correct.
24-24: Feature-flag gating for MonadMainnet matches existing patternThe
KnownChainIds.MonadMainnetcheck againstenabledFlags.Monadmirrors the other chain gates and will correctly hide Monad when the feature flag is off.package.json (2)
103-120: HDWallet monad builds kept in lockstepAll
@shapeshiftoss/hdwallet-*packages are upgraded uniformly to1.62.17-monad.0, which is what we want for consistent wallet behavior across vendors.
220-220: Viem upgrade approved; ensure EVM flows are re-verifiedBumping
viemto^2.40.3is reasonable, but since it’s widely used across EVM adapters, WalletConnect, and swappers, make sure CI plus critical EVM flows (send/swap on main EVM chains + Monad) are exercised after this change.packages/chain-adapters/src/evm/monad/MonadChainAdapter.ts (5)
56-93: Core Monad adapter wiring (BIP44, chain id, provider) looks correct
rootBip44ParamsusescoinType: Number(ASSET_REFERENCE.Monad)(60) andaccountNumber: 0, matching the “EVM-style” derivation used elsewhere in caip.assetId: monadAssetIdandchainId: KnownChainIds.MonadMainnetalign with the CAIP constants.- Using a dedicated
JsonRpcProvider+ Multicall3 contract while passing dummy unchained providers intoEvmBaseAdapteris a pragmatic way to reuse the base adapter without depending on an unchained backend.No issues from a correctness standpoint here.
111-147: Account + token balance handling is sound
- Native balance and nonce are fetched directly from the Monad RPC via
getBalanceandgetTransactionCount.- Known tokens are injected via the constructor, then resolved with multicall (plus an individual-call fallback) and filtered to non-zero balances before being returned in
chainSpecific.tokens.This matches expectations for an RPC-backed EVM adapter and should work well with the asset-service plugin wiring.
155-272: Multicall batching with graceful fallback is robust
- Token balances are fetched in batches of
BATCH_SIZEvia Multicall3, withallowFailure: trueso a single bad token doesn’t poison the whole batch.- Any multicall failure logs a warning and falls back to per-token
balanceOfcalls, with per-token try/catch to skip problematic contracts.This is a good balance between performance and resilience for Monad’s token set.
274-337: Gas fee data + fee estimates follow the shared EVM pattern
getFeeDatausesestimateGason the RPC and combines that withgetFeeDatainto fast/average/slow tiers, all currently sharing the same values, which is acceptable until Monad exposes differentiated pricing.- The tx fee calculation
bnOrZero(maxFeePerGas ?? gasPrice).times(gasLimitString).toFixed(0)is consistent with other EVM adapters and handles both EIP-1559 and legacy gas.Given this underpins swaps and sends, it’s worth double-checking on testnet/mainnet that the estimated fees are in the expected range for a few representative Monad transactions.
371-382: Tx history and parseTx stubs are acceptable; confirm no current consumers depend on themReturning an empty history and rejecting
parseTxwith a clear error makes it explicit that Monad doesn’t yet support these surfaces. That’s fine so long as no callers assume real history/parsing for Monad accounts today.Please just ensure any UI or services that consume tx history/parseTx either gate on chain support or tolerate the empty result / rejection for Monad.
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.
Retest after bump looking gucci, get in https://jam.dev/c/77ebe523-584b-4512-adf7-ac08121f9e33
- Import hyperEvm from viem/chains instead of custom definition - Use hyperEvm.id in viemClient and RelaySwapper - Requires viem 2.40.1+ (we have 2.40.3) Follows Monad pattern from PR #11241. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Description
Same as TRON but for monad:
It does contain:
Issue (if applicable)
Velocity baby
Risk
Medium but high as chain + swapper, at the convenience of the reviewer
Testing
-- Send from both native and erc20
-- Balances update check
-- Swap from any chain to Monad and monad longtail
-- Swap between monad assets
-- Verify balances are updating
Engineering
Operations
Screenshots (if applicable)
https://discord.com/channels/554694662431178782/1444473308346056734/1444512704252481630
Summary by CodeRabbit
New Features
Configuration
Integration
Preferences & Tests
✏️ Tip: You can customize this high-level summary in your review settings.