Skip to content

Conversation

@NeOMakinG
Copy link
Collaborator

@NeOMakinG NeOMakinG commented Nov 28, 2025

Description

⚠️ please don't merge as it is, when the hdwallet PR is merged, deploy on an ephemeral env and test that our bundle size is fine, if not, export the new SUI dependency to its own chunk

⚠️ To be tested with shapeshift/hdwallet#752

Same as TRON:

  • Behind a flag
  • Support account management for SUI
  • Account discovery
  • Swap to SUI
  • Swap from SUI to any other chains
  • Near intents (only for the native asset)
  • Send native asset to another address
  • SUI native and tokens prices with coingecko

What this pr doesnt do:

  • Tokens discovery (will need to check that when we will have a swapper supporting other tokens
  • Swap to any SUI tokens
  • Send any SUI tokens (will be implemented after the first swapper so we can test)

Notes:

  • We use the same default derivation then the SUI client CLI, which is different from Trust wallet and some other wallets, if this is a blocker, we might want to use the same derivation they use? I was feeling like we wanted to support the default derivation SUI push through their CLI but maybe it's not super useful for our users as importing their private key wouldn't show their assets/native
  • We need to do a follow up to implement Cetus (big swapper doing big moves on SUI), to be able to support sui tokens and bring more marketing/revenues

Issue (if applicable)

Nothing baby

Risk

Medium, new chain under a flag

High Risk PRs Require 2 approvals

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

Testing

Engineering

Operations

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

Screenshots (if applicable)

https://jam.dev/c/402c5a3a-57b4-46fb-8666-e1f2b2ccf836

Summary by CodeRabbit

  • New Features

    • Full Sui mainnet support: view/manage Sui assets, derive accounts, estimate/sign/send Sui transactions, and track Sui transaction status.
    • Swaps/trading: unsigned Sui txs, fee estimation, and execution integrated into swap and multi-hop flows.
    • Wallet & plugin: Sui wallet integration and plugin activation with runtime feature-flag gating.
  • Chores

    • Added Sui feature flags, node URL config, and Sui client dependency.

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

@NeOMakinG NeOMakinG requested a review from a team as a code owner November 28, 2025 22:50
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 28, 2025

Warning

Rate limit exceeded

@gomesalexandre has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 19 minutes and 56 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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.

📥 Commits

Reviewing files that changed from the base of the PR and between 278867d and 3eec9f1.

⛔ Files ignored due to path filters (14)
  • packages/caip/src/adapters/coincap/generated/eip155_1/adapter.json is excluded by !**/generated/**
  • packages/caip/src/adapters/coincap/generated/eip155_137/adapter.json is excluded by !**/generated/**
  • packages/caip/src/adapters/coincap/generated/eip155_42161/adapter.json is excluded by !**/generated/**
  • packages/caip/src/adapters/coincap/generated/eip155_43114/adapter.json is excluded by !**/generated/**
  • packages/caip/src/adapters/coincap/generated/eip155_56/adapter.json is excluded by !**/generated/**
  • packages/caip/src/adapters/coincap/generated/eip155_8453/adapter.json is excluded by !**/generated/**
  • packages/caip/src/adapters/coincap/generated/solana_5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/adapter.json is excluded by !**/generated/**
  • packages/caip/src/adapters/coingecko/generated/eip155_1/adapter.json is excluded by !**/generated/**
  • packages/caip/src/adapters/coingecko/generated/eip155_43114/adapter.json is excluded by !**/generated/**
  • packages/caip/src/adapters/coingecko/generated/eip155_56/adapter.json is excluded by !**/generated/**
  • packages/caip/src/adapters/coingecko/generated/eip155_8453/adapter.json is excluded by !**/generated/**
  • packages/caip/src/adapters/coingecko/generated/solana_5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/adapter.json is excluded by !**/generated/**
  • packages/caip/src/adapters/coingecko/generated/sui_35834a8a/adapter.json is excluded by !**/generated/**
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (63)
  • .env (2 hunks)
  • .env.development (1 hunks)
  • headers/csps/chains/sui.ts (1 hunks)
  • headers/csps/index.ts (2 hunks)
  • package.json (2 hunks)
  • packages/caip/src/adapters/coingecko/index.ts (4 hunks)
  • packages/caip/src/adapters/coingecko/utils.test.ts (1 hunks)
  • packages/caip/src/adapters/coingecko/utils.ts (4 hunks)
  • packages/caip/src/constants.ts (8 hunks)
  • packages/chain-adapters/package.json (1 hunks)
  • packages/chain-adapters/src/index.ts (1 hunks)
  • packages/chain-adapters/src/sui/SuiChainAdapter.ts (1 hunks)
  • packages/chain-adapters/src/sui/index.ts (1 hunks)
  • packages/chain-adapters/src/sui/types.ts (1 hunks)
  • packages/chain-adapters/src/types.ts (8 hunks)
  • packages/swapper/src/swappers/ButterSwap/swapperApi/getTradeQuote.test.ts (1 hunks)
  • packages/swapper/src/swappers/ButterSwap/swapperApi/getTradeRate.test.ts (2 hunks)
  • packages/swapper/src/swappers/NearIntentsSwapper/NearIntentsSwapper.ts (1 hunks)
  • packages/swapper/src/swappers/NearIntentsSwapper/endpoints.ts (2 hunks)
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts (1 hunks)
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.ts (1 hunks)
  • packages/swapper/src/swappers/NearIntentsSwapper/types.ts (3 hunks)
  • packages/swapper/src/swappers/NearIntentsSwapper/utils/helpers/helpers.ts (2 hunks)
  • packages/swapper/src/thorchain-utils/getL1RateOrQuote.ts (1 hunks)
  • packages/swapper/src/types.ts (9 hunks)
  • packages/swapper/src/utils.ts (4 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/coingecko.ts (3 hunks)
  • scripts/generateAssetData/color-map.json (15 hunks)
  • scripts/generateAssetData/generateAssetData.ts (3 hunks)
  • scripts/generateAssetData/generateTrustWalletUrl/generateTrustWalletUrl.ts (1 hunks)
  • scripts/generateAssetData/sui/index.ts (1 hunks)
  • src/components/Modals/Send/utils.ts (3 hunks)
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx (3 hunks)
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx (2 hunks)
  • src/components/MultiHopTrade/hooks/useGetTradeQuotes/getTradeQuoteOrRateInput.ts (2 hunks)
  • src/config.ts (2 hunks)
  • src/constants/chains.ts (2 hunks)
  • src/context/PluginProvider/PluginProvider.tsx (1 hunks)
  • src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx (2 hunks)
  • src/hooks/useWalletSupportsChain/useWalletSupportsChain.ts (3 hunks)
  • src/lib/account/account.ts (3 hunks)
  • src/lib/account/sui.ts (1 hunks)
  • src/lib/asset-service/service/AssetService.ts (2 hunks)
  • src/lib/coingecko/constants.ts (2 hunks)
  • src/lib/coingecko/utils.ts (2 hunks)
  • src/lib/tradeExecution.ts (4 hunks)
  • src/lib/utils/sui.ts (1 hunks)
  • src/pages/RFOX/components/Stake/Bridge/hooks/useRfoxBridge.ts (2 hunks)
  • src/plugins/activePlugins.ts (2 hunks)
  • src/plugins/sui/index.tsx (1 hunks)
  • src/state/apis/swapper/helpers/swapperApiHelpers.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 (7 hunks)
  • src/state/slices/preferencesSlice/preferencesSlice.ts (2 hunks)
  • src/test/mocks/store.ts (1 hunks)
📝 Walkthrough

Walkthrough

Adds Sui mainnet support across the app: env/config flags and CSP, a Sui chain adapter and plugin, CAIP/constants and asset plumbing, CoinGecko and asset-generation integration, swapper / NearIntents additions, wallet/account derivation, UI send/trade/fee flows, state and feature-flag wiring, and tests/hooks updates.

Changes

Cohort / File(s) Summary
Env & Config
\.env, \.env.development, src/config.ts
Added VITE_FEATURE_SUI and VITE_SUI_NODE_URL env vars and validators; enabled feature in development env.
CSP / Headers
New CSP, headers/csps/chains/sui.ts, headers/csps/index.ts
New Sui CSP module built from env and registered in exported csps array (connect-src → SUI node URL).
Dependencies
package.json, packages/chain-adapters/package.json
Added @mysten/[email protected]; bumped multiple hdwallet packages.
Chain Adapter & Types
packages/chain-adapters/src/sui/*, packages/chain-adapters/src/index.ts, packages/chain-adapters/src/types.ts
New SuiChainAdapter implementation, Sui-specific types, and public exports wired into chain-adapters package (export * from './sui').
CAIP / Asset Constants & CoinGecko
packages/caip/src/constants.ts, packages/caip/src/adapters/coingecko/*, src/lib/coingecko/*
Added suiChainId/suiAssetId, namespace/reference/asset constants, CoinGecko platform mappings and parser support for Sui.
Swapper / NearIntents
packages/swapper/src/*, packages/swapper/src/swappers/NearIntentsSwapper/*, packages/swapper/src/thorchain-utils/*
Extended swapper types, deps, execution paths, fee retrieval and NearIntents endpoints to include Sui; added tests hooks and unsupported-case handling.
Asset Data Generation
scripts/generateAssetData/*, scripts/generateAssetData/sui/index.ts
New Sui asset fetcher, integrated into generator, Trust Wallet URL mapping updated, and color-map data changes.
Base Assets & Utilities
packages/utils/src/assetData/*, packages/utils/src/*
Added base Sui asset and wired Sui into getBaseAsset, chainId→feeAsset, namespace, short name, native fee reference utilities.
App Types & Known Chains
packages/types/src/base.ts, src/constants/chains.ts
Added KnownChainIds.SuiMainnet, added to second-class chains and feature-gated knownChainIds filter.
Account Derivation & Wallet Support
src/lib/account/sui.ts, src/lib/account/account.ts, src/hooks/useWalletSupportsChain/*
New deriveSuiAccountIdsAndMetadata, included in dispatcher; adds wallet support check for Sui via hdwallet-core.
Trade Execution & Swapper Helpers
src/lib/tradeExecution.ts, src/state/apis/swapper/helpers/swapperApiHelpers.ts, src/lib/utils/sui.ts
Added execSuiTransaction, assert/is/adapter helpers, getSuiTransactionStatus, and exposed assertGetSuiChainAdapter in swapper deps.
UI: Send / Trade / Fees
src/components/Modals/Send/utils.ts, src/components/MultiHopTrade/*, src/components/*/useGetTradeQuotes/*, src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
Added Sui cases for fee estimation, build/send flows, signing/broadcasting, getUnsigned/getFees hooks, and trade execution wiring.
Portfolio, State & Preferences
src/state/slices/*, src/state/migrations/index.ts, src/test/mocks/store.ts
Added Sui to portfolio/account utilities, opportunities mapping, migrations, preferences feature flag and mock store defaults.
Plugins
src/plugins/sui/index.tsx, src/plugins/activePlugins.ts, src/context/PluginProvider/PluginProvider.tsx
New Sui plugin registering a chain adapter (lazy RPC URL from config); added to active plugins and feature-gated in PluginProvider.
Misc / Color Map
scripts/generateAssetData/color-map.json
Updated color-map JSON entries (data-only token/network color mapping changes).

Sequence Diagram(s)

sequenceDiagram
    participant UI as UI (Send / Trade)
    participant Swapper as Swapper API
    participant Adapter as Sui Chain Adapter
    participant Wallet as Wallet (HDWallet)
    participant SuiNet as Sui Network

    UI->>Swapper: getUnsignedSuiTransaction(args)
    Swapper->>Adapter: buildSendApiTransaction(args)
    Adapter-->>Swapper: SuiSignTx (unsigned)

    UI->>Wallet: sign SuiSignTx
    Wallet->>Adapter: signTransaction (via adapter callbacks)
    Adapter-->>Wallet: signed payload
    Wallet-->>UI: signed tx

    UI->>Adapter: broadcastTransaction(signedTx)
    Adapter->>SuiNet: submitTransactionBlock(signedTx)
    SuiNet-->>Adapter: txHash

    loop Poll tx status
      UI->>Adapter: getSuiTransactionStatus(txHash)
      Adapter->>SuiNet: getTransactionBlock(showEffects=true)
      SuiNet-->>Adapter: effects/status
      Adapter-->>UI: TxStatus (Confirmed/Failed/Unknown)
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60–90 minutes

Areas requiring extra attention:

  • packages/chain-adapters/src/sui/SuiChainAdapter.ts — transaction construction, signing, signature formatting, fee estimation, dry-run behavior.
  • packages/swapper/src/types.ts and NearIntentsSwapper files — type additions, tokenId handling, fee-building assumptions.
  • src/lib/account/sui.ts and portfolio wiring — derivation correctness and accountId construction.
  • src/lib/utils/sui.ts and getSuiTransactionStatus — Sui client usage, effects parsing, and error mapping.
  • Plugin registration and lazy RPC wiring in src/plugins/sui/index.tsx and feature-flag gating across PluginProvider.

Possibly related PRs

Suggested labels

high risk

Suggested reviewers

  • NeOMakinG

Poem

🐰
I hopped in code with eager paws,
A Sui branch sprouted through the laws;
Adapters, swaps, and flags align,
A nimble plugin — now it's mine! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: sui support excluding tokens' accurately describes the main feature addition of SUI chain support while noting the important constraint that token swaps are excluded.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@NeOMakinG NeOMakinG changed the title Implement sui feat: sui support excluding tokens Nov 28, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (4)
packages/swapper/src/swappers/NearIntentsSwapper/utils/helpers/helpers.ts (1)

43-57: Consider simplifying the SUI lookup logic.

The current implementation checks for SUI in two ways:

  • Line 55: TOKEN_LOOKUP_CHAINS.includes(nearNetwork as any)
  • Line 57: asset.chainId === suiChainId

Since nearNetwork is derived from chainIdToNearIntentsChain[asset.chainId], these checks are redundant when the mapping includes SUI. This creates an inconsistency with Solana's pattern (which uses only the chainId check).

Consider one of these approaches for consistency and clarity:

Option 1: Match Solana's pattern (remove the array check)

-const TOKEN_LOOKUP_CHAINS = ['sui'] as const
-
 export const assetToNearIntentsAsset = async (asset: Asset): Promise<string | null> => {
   // ...
-  // NEP-245 chains (BSC, Polygon, Avalanche, Optimism), Solana, and SUI require token lookup
+  // NEP-245 chains (BSC, Polygon, Avalanche, Optimism, Tron), Solana, and SUI require token lookup
   // Asset IDs use hashed format that can't be generated from contract addresses
   const requiresLookup =
     NEP245_CHAINS.includes(nearNetwork as any) ||
-    TOKEN_LOOKUP_CHAINS.includes(nearNetwork as any) ||
     asset.chainId === solanaChainId ||
     asset.chainId === suiChainId

Option 2: Remove the redundant chainId check

-  // NEP-245 chains (BSC, Polygon, Avalanche, Optimism), Solana, and SUI require token lookup
+  // NEP-245 chains (BSC, Polygon, Avalanche, Optimism, Tron), Solana, and SUI require token lookup
   // Asset IDs use hashed format that can't be generated from contract addresses
   const requiresLookup =
     NEP245_CHAINS.includes(nearNetwork as any) ||
     TOKEN_LOOKUP_CHAINS.includes(nearNetwork as any) ||
-    asset.chainId === solanaChainId ||
-    asset.chainId === suiChainId
+    asset.chainId === solanaChainId
.env.development (1)

80-80: SUI feature flag wiring looks consistent; consider keeping keys ordered

VITE_FEATURE_SUI=true matches the existing feature-flag naming pattern and should integrate cleanly with the preferences/config wiring described in the learnings. dotenv-linter suggests placing this before VITE_FEATURE_SWAPPER_FIAT_RAMPS to keep keys ordered, but this is non-functional and can be done opportunistically.

src/components/MultiHopTrade/hooks/useGetTradeQuotes/getTradeQuoteOrRateInput.ts (1)

19-20: Sui trade input wiring looks good; consider a dedicated Sui chain-id type later

The new CHAIN_NAMESPACE.Sui branch correctly uses assertGetSuiChainAdapter and mirrors the Solana/Tron pattern for deriving sendAddress and constructing the quote/rate input, so behavior-wise this is fine.

Type-wise, casting the Sui chainId to CosmosSdkChainId is a bit of a stretch (same as the existing Solana branch). When/if a SuiChainId (or similar) alias is introduced in @shapeshiftoss/types, this case would be a good candidate to tighten the typing to reflect Sui explicitly.

Also applies to: 210-227

src/lib/utils/sui.ts (1)

5-5: Inconsistent import path.

This import uses a relative path from packages/ instead of the @shapeshiftoss/unchained-client package alias. This could cause build issues or module resolution problems.

-import { TxStatus } from 'packages/unchained-client/src/types'
+import { TxStatus } from '@shapeshiftoss/unchained-client'

Copy link
Contributor

@gomesalexandre gomesalexandre left a comment

Choose a reason for hiding this comment

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

few blocking bits, tackling as we speak

Copy link
Contributor

@gomesalexandre gomesalexandre left a comment

Choose a reason for hiding this comment

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

few more

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (2)
packages/chain-adapters/src/sui/SuiChainAdapter.ts (2)

174-180: Use BigInt for SUI gas parameters.

This was flagged in a previous review. The SUI SDK's setGasBudget() and setGasPrice() accept number | bigint, and using BigInt() provides better type alignment with SUI's u64 gas model.


339-339: Remove console.error before production.

This debug statement should be removed as the error is already handled by ErrorHandler. A previous review addressed this, but the console.error remains.

     } catch (err) {
-      console.error('[SUI broadcastTransaction] error:', err)
       return ErrorHandler(err, {
🧹 Nitpick comments (2)
packages/swapper/src/swappers/NearIntentsSwapper/utils/helpers/helpers.ts (1)

43-43: SUI token-lookup wiring matches existing pattern; consider tightening the comment

The new TOKEN_LOOKUP_CHAINS constant and the extended requiresLookup condition correctly route Sui (both native and tokens) through the token-lookup path alongside NEP‑245 chains and Solana, which is what we want for hashed asset IDs.

The only nit is that the comment now reads as if SUI were itself a NEP‑245 chain. For clarity, you could reword it like this:

-  // NEP-245 chains (BSC, Polygon, Avalanche, Optimism, TRON, SUI) and Solana require token lookup
+  // NEP-245 chains (BSC, Polygon, Avalanche, Optimism, TRON), plus SUI and Solana, require token lookup

This keeps the behavior as-is but makes the intent clearer for future readers.

Also applies to: 51-57

src/state/slices/preferencesSlice/preferencesSlice.ts (1)

21-31: Sui feature flag wiring is consistent; consider persisted-state migration

Adding Sui: boolean to FeatureFlags and initializing Sui: getConfig().VITE_FEATURE_SUI in initialState.featureFlags is aligned with the existing feature‑flag pattern and matches the new VITE_FEATURE_SUI env var.

One thing to double‑check: this slice is persisted, so older persisted preferences.featureFlags objects won’t have a Sui property. At runtime that just reads as undefined (falsy), so gating still behaves as “off”, but it does mean the persisted shape diverges from initialState.

If you want to strictly follow the migrations guideline for persisted slices, you may want a small migration that adds Sui: getConfig().VITE_FEATURE_SUI to existing preferences.featureFlags.

Also applies to: 155-166

Copy link
Contributor

@gomesalexandre gomesalexandre left a comment

Choose a reason for hiding this comment

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

Retested Monad/SUI after merge fix, CI fix, re-re-regen , looking gucci!

https://jam.dev/c/a8c7242f-f2b2-4689-818e-59f516efe9ef

Copy link
Contributor

@gomesalexandre gomesalexandre left a comment

Choose a reason for hiding this comment

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

Re-stamp after squash and confirming gome's happy

Image

@gomesalexandre gomesalexandre merged commit 1f458e4 into develop Dec 1, 2025
4 checks passed
@gomesalexandre gomesalexandre deleted the implement-sui branch December 1, 2025 14:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants