feat: add Stargate V2 swapper#12262
Conversation
Integrate Stargate V2 (LayerZero) as a cross-chain bridge swapper. - 14 EVM chains supported (ETH, ARB, OP, BASE, POLYGON, BSC, AVAX, etc.) - On-chain quotes via quoteOFT/quoteSend contract calls - USDC, USDT, ETH, mETH, EURC asset support - Transaction status tracking via LayerZero scan API - Feature-flagged (disabled by default)
- Add VITE_FEATURE_STARGATE_SWAP to .env.development and .env.production - Remove unused CSP domain from Stargate.ts - Fix unsafe double cast in fetchStargateTrade
Replace dead scan.layerzero-api.com with working api-mainnet.layerzero-scan.com for status tracking.
Odos integration is incomplete and unrelated to Stargate. Moving all Odos references to a dedicated feat/odos-swapper branch. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds a Stargate cross-chain swapper: feature flag and config, CSP entry, full Stargate swapper implementation (constants, types, ABI helpers, service, endpoints, quote/rate/fee/tx logic, status checks), UI/state wiring, tests, and e2e fixture. Changes
Sequence DiagramsequenceDiagram
actor User
participant UI as UI / Swapper
participant Api as App API (stargateApi)
participant Contract as Stargate Contract
participant EVM as EVM Adapter
participant LZScan as LayerZero Scan
User->>UI: Select Stargate & request quote
UI->>Api: getTradeQuote(input)
Api->>Contract: quoteOFT & quoteSend (ABI calls)
Contract-->>Api: quote responses (amounts, fees)
Api->>EVM: getFees()/estimate gas
EVM-->>Api: fee estimates
Api-->>UI: TradeQuote[] (includes stargateTransactionMetadata)
UI->>Api: getUnsignedEvmTransaction / getEvmTransactionFees
Api->>EVM: buildCustomApiTx / getFees
EVM-->>Api: unsigned tx / fees
Api-->>UI: Unsigned tx / fee data
UI->>Api: checkTradeStatus(txHash)
Api->>LZScan: Query LayerZero Scan for message status
LZScan-->>Api: message status (INFLIGHT/CONFIRMING/DELIVERED/FAILED)
Api-->>UI: TxStatus (+ optional buyTxHash)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
.env (1)
120-120: Feature flag placement and trailing newline.Static analysis flagged two minor issues:
VITE_FEATURE_STARGATE_SWAPshould be ordered beforeVITE_FEATURE_STARKNETfor alphabetical consistency- Missing blank line at end of file
These are minor formatting nits that don't affect functionality.
🔧 Optional fix for ordering and trailing newline
Move the flag to maintain alphabetical order:
VITE_FEATURE_ACROSS_SWAP=true VITE_FEATURE_DEBRIDGE_SWAP=true -VITE_FEATURE_STARGATE_SWAP=false +VITE_FEATURE_STARGATE_SWAP=false VITE_FEATURE_USERBACK=trueAnd ensure a trailing newline at end of file.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.env at line 120, Move the VITE_FEATURE_STARGATE_SWAP entry so it appears alphabetically before VITE_FEATURE_STARKNET (i.e., place the line "VITE_FEATURE_STARGATE_SWAP=false" above the "VITE_FEATURE_STARKNET" variable) and ensure the .env file ends with a single trailing newline character; update only ordering and add the final blank line.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.env.production:
- Line 12: The VITE_FEATURE_STARGATE_SWAP env var is placed inside the Mixpanel
section causing dotenv-linter ordering errors; move the line defining
VITE_FEATURE_STARGATE_SWAP=false into the feature-flags block (the group where
other VITE_FEATURE_* keys live) so the variable is grouped with other feature
flags and the dotenv-linter ordering issue is resolved.
In
`@packages/swapper/src/swappers/StargateSwapper/getTradeQuote/getTradeQuote.ts`:
- Around line 12-29: The early validation Errs for missing addresses should
include a structured TradeQuoteError code and details so callers can distinguish
them; update the two returns that check input.sendAddress and
input.receiveAddress to call makeSwapErrorRight with a TradeQuoteError value
(e.g., TradeQuoteError.MISSING_SEND_ADDRESS and
TradeQuoteError.MISSING_RECEIVE_ADDRESS or a single
TradeQuoteError.MISSING_REQUIRED_ADDRESS) and include a details object naming
the missing field (e.g., { field: 'sendAddress' } / { field: 'receiveAddress'
}); keep using the existing Err wrapper and functions (makeSwapErrorRight, Err)
and only add the code and details properties to the error payload so downstream
callers can inspect error.code and error.details.
In `@packages/swapper/src/swappers/StargateSwapper/utils/fetchStargateTrade.ts`:
- Around line 174-182: The sendParam object currently sets minAmountLD to 0n
which ignores the selected/default slippage; before calling encodeSend() you
must compute minAmountLD = detailDstAmountLD * (1 -
slippageTolerancePercentageDecimal) (rounded down to an integer) and assign that
to sendParam.minAmountLD so the encoded send calldata will revert on fills below
the slippage-protected amount; update the same logic wherever sendParam is
constructed (references: sendParam, minAmountLD, detailDstAmountLD,
slippageTolerancePercentageDecimal, and encodeSend()) to ensure slippage is
applied consistently across all occurrences.
---
Nitpick comments:
In @.env:
- Line 120: Move the VITE_FEATURE_STARGATE_SWAP entry so it appears
alphabetically before VITE_FEATURE_STARKNET (i.e., place the line
"VITE_FEATURE_STARGATE_SWAP=false" above the "VITE_FEATURE_STARKNET" variable)
and ensure the .env file ends with a single trailing newline character; update
only ordering and add the final blank line.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 2d5a00af-084f-461b-8763-03f6ef61b0fd
⛔ Files ignored due to path filters (1)
src/components/MultiHopTrade/components/TradeInput/components/SwapperIcon/stargate-icon.pngis excluded by!**/*.png
📒 Files selected for processing (23)
.env.env.development.env.productionheaders/csps/defi/swappers/Stargate.tsheaders/csps/index.tspackages/swapper/src/constants.tspackages/swapper/src/index.tspackages/swapper/src/swappers/StargateSwapper/StargateSwapper.tspackages/swapper/src/swappers/StargateSwapper/constant.tspackages/swapper/src/swappers/StargateSwapper/endpoints.tspackages/swapper/src/swappers/StargateSwapper/getTradeQuote/getTradeQuote.tspackages/swapper/src/swappers/StargateSwapper/getTradeRate/getTradeRate.tspackages/swapper/src/swappers/StargateSwapper/index.tspackages/swapper/src/swappers/StargateSwapper/types.tspackages/swapper/src/swappers/StargateSwapper/utils/fetchStargateTrade.tspackages/swapper/src/swappers/StargateSwapper/utils/helpers.tspackages/swapper/src/swappers/StargateSwapper/utils/stargateService.tspackages/swapper/src/types.tssrc/components/MultiHopTrade/components/TradeInput/components/SwapperIcon/SwapperIcon.tsxsrc/config.tssrc/state/helpers.tssrc/state/slices/preferencesSlice/preferencesSlice.tssrc/test/mocks/store.ts
…es, add tests - Apply slippage to sendParam.minAmountLD before encodeSend() so on-chain fills worse than quote+slippage will revert (was hardcoded 0n, ignoring slippage) - Add TradeQuoteError.InternalError codes to sendAddress/receiveAddress validation errors in getTradeQuote so callers can distinguish input errors from route failures - Move VITE_FEATURE_STARGATE_SWAP into the feature-flags section in .env.production - Add getTradeQuote.test.ts with 9 test cases covering happy path, error cases, slippage application, fee structure, and step metadata Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
🧹 Nitpick comments (3)
packages/swapper/src/swappers/StargateSwapper/utils/fetchStargateTrade.ts (3)
287-293: Consider logging the fee estimation failure.The catch block silently falls back to a hardcoded gas limit estimate. Per coding guidelines, errors should be logged for debugging, especially when they affect user-visible values (network fees).
♻️ Suggested improvement
return feeData.networkFeeCryptoBaseUnit - } catch { + } catch (e) { + console.warn('[Stargate] Fee estimation failed, using fallback gas limit', { + error: e instanceof Error ? e.message : String(e), + sellAsset: sellAsset.assetId, + }) return evm.calcNetworkFeeCryptoBaseUnit({ ...average, supportsEIP1559, gasLimit: '500000', }) }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/swapper/src/swappers/StargateSwapper/utils/fetchStargateTrade.ts` around lines 287 - 293, The catch block in fetchStargateTrade is swallowing the fee-estimation error; change it to catch (error) and log the error before returning the fallback: call your existing logger (e.g., logger.error or processLogger.error) or console.error with a clear message and include the error object and context (average, supportsEIP1559) and then return evm.calcNetworkFeeCryptoBaseUnit({ ...average, supportsEIP1559, gasLimit: '500000' }).
241-245: Simplify redundant type assertions.The
rawMessagingFeeis cast to the same type twice. Consider adding proper return type todecodeQuoteSendResultor cast once.♻️ Suggested simplification
const rawMessagingFee = decodeQuoteSendResult(quoteSendResult.data as Hex) +const typedMessagingFee = rawMessagingFee as { nativeFee: bigint; lzTokenFee: bigint } const messagingFee: StargateMessagingFee = { - nativeFee: (rawMessagingFee as { nativeFee: bigint; lzTokenFee: bigint }).nativeFee, - lzTokenFee: (rawMessagingFee as { nativeFee: bigint; lzTokenFee: bigint }).lzTokenFee, + nativeFee: typedMessagingFee.nativeFee, + lzTokenFee: typedMessagingFee.lzTokenFee, }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/swapper/src/swappers/StargateSwapper/utils/fetchStargateTrade.ts` around lines 241 - 245, The code redundantly casts rawMessagingFee twice; update the decodeQuoteSendResult return type to include { nativeFee: bigint; lzTokenFee: bigint } or cast its single result once and destructure to build messagingFee. Locate decodeQuoteSendResult and change its signature to return the proper typed object, or in fetchStargateTrade.ts cast rawMessagingFee once (e.g., const { nativeFee, lzTokenFee } = decodeQuoteSendResult(...) as { nativeFee: bigint; lzTokenFee: bigint }) and then construct the StargateMessagingFee using those variables instead of repeating the type assertion.
296-301: HardcodedgasLimitin metadata is later compared with fee estimation.While
stargateTransactionMetadata.gasLimitis hardcoded to'500000', theexecuteSwapendpoint extracts this value and compares it against the fee-estimatedgasLimitusingBigNumber.max(gasLimitFromApi ?? '0', feeData.gasLimit). This ensures the final transaction uses the higher of the two values, mitigating the risk of insufficient gas.However, estimating
gasLimitduring the quote phase (whenevm.getFeesis available) and storing the actual estimate in metadata would be more efficient than hardcoding a fallback value.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/swapper/src/swappers/StargateSwapper/utils/fetchStargateTrade.ts` around lines 296 - 301, stargateTransactionMetadata currently hardcodes gasLimit to '500000'; instead, when evm.getFees is available during quote construction in fetchStargateTrade, call evm.getFees (or reuse existing fees lookup) to estimate gas and set stargateTransactionMetadata.gasLimit to that estimated value (stringified) rather than the fixed '500000', so executeSwap’s BigNumber.max(gasLimitFromApi ?? '0', feeData.gasLimit) can pick the accurate higher value; update the metadata assignment that creates stargateTransactionMetadata (referencing sendCalldata, txValue, contractAddress) to use the estimated feeData.gasLimit when present and fall back to the previous hardcoded value only if no estimate exists.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@packages/swapper/src/swappers/StargateSwapper/utils/fetchStargateTrade.ts`:
- Around line 287-293: The catch block in fetchStargateTrade is swallowing the
fee-estimation error; change it to catch (error) and log the error before
returning the fallback: call your existing logger (e.g., logger.error or
processLogger.error) or console.error with a clear message and include the error
object and context (average, supportsEIP1559) and then return
evm.calcNetworkFeeCryptoBaseUnit({ ...average, supportsEIP1559, gasLimit:
'500000' }).
- Around line 241-245: The code redundantly casts rawMessagingFee twice; update
the decodeQuoteSendResult return type to include { nativeFee: bigint;
lzTokenFee: bigint } or cast its single result once and destructure to build
messagingFee. Locate decodeQuoteSendResult and change its signature to return
the proper typed object, or in fetchStargateTrade.ts cast rawMessagingFee once
(e.g., const { nativeFee, lzTokenFee } = decodeQuoteSendResult(...) as {
nativeFee: bigint; lzTokenFee: bigint }) and then construct the
StargateMessagingFee using those variables instead of repeating the type
assertion.
- Around line 296-301: stargateTransactionMetadata currently hardcodes gasLimit
to '500000'; instead, when evm.getFees is available during quote construction in
fetchStargateTrade, call evm.getFees (or reuse existing fees lookup) to estimate
gas and set stargateTransactionMetadata.gasLimit to that estimated value
(stringified) rather than the fixed '500000', so executeSwap’s
BigNumber.max(gasLimitFromApi ?? '0', feeData.gasLimit) can pick the accurate
higher value; update the metadata assignment that creates
stargateTransactionMetadata (referencing sendCalldata, txValue, contractAddress)
to use the estimated feeData.gasLimit when present and fall back to the previous
hardcoded value only if no estimate exists.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 123a4865-9897-4233-97b3-31d3c646d7a4
📒 Files selected for processing (4)
.env.productionpackages/swapper/src/swappers/StargateSwapper/getTradeQuote/getTradeQuote.test.tspackages/swapper/src/swappers/StargateSwapper/getTradeQuote/getTradeQuote.tspackages/swapper/src/swappers/StargateSwapper/utils/fetchStargateTrade.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/swapper/src/swappers/StargateSwapper/getTradeQuote/getTradeQuote.ts
75e32fc to
e0c5912
Compare
Tests fail with "generated/ethereum/runtime not found" if the OpenAPI clients haven't been generated. Document the required generate step and the correct vi.importActual pattern for mocks. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Destructure decodeQuoteSendResult with single cast instead of double - Add console.warn in fee-estimation catch block (matches swapper pattern) - Capture gasLimit from evm.getFees and use in stargateTransactionMetadata - Move VITE_FEATURE_STARGATE_SWAP to correct alphabetical position in .env Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…e, error cases - ETH (mainnet) → ETH (Arbitrum): verifies native txValue = nativeFee + sellAmount - USDC (Arbitrum) → USDC (Mainnet): verifies reverse direction with Arbitrum sell chain - Unsupported buy chain: complements existing sell-chain error test - No Stargate contract for sell asset (FOX): expects UnsupportedTradePair error - Extend viemClientByChainId mock to cover arbitrumChainId Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Unit tests (20 total, +6 new pairs): - USDC ETH → Optimism, Base, Polygon - USDT ETH → USDT Arbitrum - ETH → ETH Base native bridge - USDC Base → USDC Arbitrum (L2-to-L2) test-data/assets.ts: - Add USDT_MAINNET, USDT_ARBITRUM - Add USDC_OPTIMISM, USDC_BASE, USDC_POLYGON - Add ETH_BASE, MATIC, BSC_USDC - Add baseChainId, polygonChainId imports E2E fixture: - stargate-usdc-eth-to-arb.yaml for agent-browser manual/automated QA Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (3)
packages/swapper/src/swappers/utils/test-data/assets.ts (1)
262-374: Optional: reduce fixture duplication with a small asset factory.Not blocking, but a helper for repeated token metadata would reduce copy/paste drift across future Stargate fixture additions.
♻️ Example refactor direction
+type EvmTokenFixtureInput = { + assetId: string + chainId: string + symbol: string + name: string + precision: number + color: string + icon: string + explorer: string +} + +const createEvmTokenFixture = (input: EvmTokenFixtureInput): Asset => ({ + ...input, + explorerAddressLink: `${input.explorer}/address/`, + explorerTxLink: `${input.explorer}/tx/`, + relatedAssetKey: null, +})🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/swapper/src/swappers/utils/test-data/assets.ts` around lines 262 - 374, Many assets in assets.ts (e.g., USDT_MAINNET, USDT_ARBITRUM, USDC_OPTIMISM, USDC_BASE, USDC_POLYGON, ETH_BASE, MATIC, BSC_USDC) repeat the same fields; create a small factory helper (e.g., makeErc20Asset / makeAsset) that accepts the unique pieces (assetId, chainId, symbol, name, optional precision, explorer base URL, icon, color, relatedAssetKey) and fills common defaults (precision, explorerAddressLink/TxLink format, relatedAssetKey=null) and replace repeated literal objects with factory calls to reduce duplication and drift. Ensure the factory preserves special network-only fields (like networkName, networkColor for ETH_BASE) via optional overrides and update each exported constant to call the factory with its unique values.packages/swapper/src/swappers/StargateSwapper/utils/fetchStargateTrade.ts (1)
275-299: Robust gas estimation with sensible fallback.The try-catch pattern ensures quote generation doesn't fail on gas estimation errors, falling back to a conservative estimate. The warning log includes useful context for debugging.
Consider extracting the default gas limit to a named constant for clarity:
♻️ Optional: Extract magic number to constant
+const DEFAULT_STARGATE_GAS_LIMIT = '500000' + // ... in the function - let gasLimit = '500000' + let gasLimit = DEFAULT_STARGATE_GAS_LIMIT🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/swapper/src/swappers/StargateSwapper/utils/fetchStargateTrade.ts` around lines 275 - 299, Replace the magic string '500000' by introducing a named constant (e.g. DEFAULT_GAS_LIMIT) and use it to initialize gasLimit and as the fallback gasLimit passed into evm.calcNetworkFeeCryptoBaseUnit; update the async block around evm.getFees / evm.calcNetworkFeeCryptoBaseUnit so gasLimit is initialized from DEFAULT_GAS_LIMIT and the same constant is used in the catch branch, keeping the rest of the logic intact (symbols to edit: gasLimit, networkFeeCryptoBaseUnit, evm.getFees, evm.calcNetworkFeeCryptoBaseUnit, average, supportsEIP1559, sellAsset.assetId).e2e/fixtures/stargate-usdc-eth-to-arb.yaml (1)
86-90: Consider extending bridge completion timeout to reduce flakiness.Line 89’s 180s cap is tight for cross-chain settlement under congestion. Increasing to 300s is a safer default for CI stability.
Suggested timeout adjustment
- name: Wait for Stargate bridge completion instruction: > Cross-chain Stargate bridges take 1-3 minutes (LayerZero messaging). - Wait up to 180 seconds for the swap to complete. Check every 10 seconds. + Wait up to 300 seconds for the swap to complete. Check every 10 seconds. Look for: trade page reappearing, success notification, Arbitrum USDC balance increased, or "Awaiting swap" disappearing. A feedback dialog may appear — dismiss it with "Maybe Later".🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@e2e/fixtures/stargate-usdc-eth-to-arb.yaml` around lines 86 - 90, Update the "Wait for Stargate bridge completion" step in the stargate-usdc-eth-to-arb fixture to increase the bridge completion timeout from 180 seconds to 300 seconds to reduce CI flakiness; locate the YAML step titled "Wait for Stargate bridge completion" and change the wait cap (currently "Wait up to 180 seconds") to "Wait up to 300 seconds" while keeping the polling interval (every 10 seconds) and the success checks (trade page reappearing, success notification, Arbitrum USDC) unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.env:
- Line 365: dotenv-linter flags a missing trailing newline at EOF for the .env
file containing VITE_AGENTIC_SERVER_BASE_URL; fix it by editing the .env file
and adding a single blank line (newline character) after the last line (the
VITE_AGENTIC_SERVER_BASE_URL entry) so the file ends with a newline and the
EndingBlankLine warning is cleared.
In `@e2e/fixtures/stargate-usdc-eth-to-arb.yaml`:
- Around line 50-66: Relax the brittle hardcoded numeric expectations in the
quote and fee test steps: update the "Quote shown..." expected from the strict
"~$0.98-$1.00 USDC" to a broader or percentage-based tolerance (e.g. accept any
receive amount within ±10% of $1 or a generic "≈ $1 USDC") and change the
protocol fee expectation in the "Verify protocol fee is displayed" step from
"roughly $0.005-$0.01 for a $1 swap" to a flexible check that asserts the fee
label (Stargate/oft fee) is present and that the displayed fee is non-zero or
within a wider percent range (e.g. 0.1%–5%), so the steps "Quote shown with
receive amount..." and "Protocol fee visible..." accept normal routing/fee
variance for tiny notional swaps.
---
Nitpick comments:
In `@e2e/fixtures/stargate-usdc-eth-to-arb.yaml`:
- Around line 86-90: Update the "Wait for Stargate bridge completion" step in
the stargate-usdc-eth-to-arb fixture to increase the bridge completion timeout
from 180 seconds to 300 seconds to reduce CI flakiness; locate the YAML step
titled "Wait for Stargate bridge completion" and change the wait cap (currently
"Wait up to 180 seconds") to "Wait up to 300 seconds" while keeping the polling
interval (every 10 seconds) and the success checks (trade page reappearing,
success notification, Arbitrum USDC) unchanged.
In `@packages/swapper/src/swappers/StargateSwapper/utils/fetchStargateTrade.ts`:
- Around line 275-299: Replace the magic string '500000' by introducing a named
constant (e.g. DEFAULT_GAS_LIMIT) and use it to initialize gasLimit and as the
fallback gasLimit passed into evm.calcNetworkFeeCryptoBaseUnit; update the async
block around evm.getFees / evm.calcNetworkFeeCryptoBaseUnit so gasLimit is
initialized from DEFAULT_GAS_LIMIT and the same constant is used in the catch
branch, keeping the rest of the logic intact (symbols to edit: gasLimit,
networkFeeCryptoBaseUnit, evm.getFees, evm.calcNetworkFeeCryptoBaseUnit,
average, supportsEIP1559, sellAsset.assetId).
In `@packages/swapper/src/swappers/utils/test-data/assets.ts`:
- Around line 262-374: Many assets in assets.ts (e.g., USDT_MAINNET,
USDT_ARBITRUM, USDC_OPTIMISM, USDC_BASE, USDC_POLYGON, ETH_BASE, MATIC,
BSC_USDC) repeat the same fields; create a small factory helper (e.g.,
makeErc20Asset / makeAsset) that accepts the unique pieces (assetId, chainId,
symbol, name, optional precision, explorer base URL, icon, color,
relatedAssetKey) and fills common defaults (precision,
explorerAddressLink/TxLink format, relatedAssetKey=null) and replace repeated
literal objects with factory calls to reduce duplication and drift. Ensure the
factory preserves special network-only fields (like networkName, networkColor
for ETH_BASE) via optional overrides and update each exported constant to call
the factory with its unique values.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: aa0dcd51-efcc-4225-96bb-3ac2bd15977d
📒 Files selected for processing (6)
.envAGENTS.mde2e/fixtures/stargate-usdc-eth-to-arb.yamlpackages/swapper/src/swappers/StargateSwapper/getTradeQuote/getTradeQuote.test.tspackages/swapper/src/swappers/StargateSwapper/utils/fetchStargateTrade.tspackages/swapper/src/swappers/utils/test-data/assets.ts
✅ Files skipped from review due to trivial changes (1)
- AGENTS.md
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/swapper/src/swappers/StargateSwapper/getTradeQuote/getTradeQuote.test.ts
|
|
||
| # agentic chat | ||
| VITE_AGENTIC_SERVER_BASE_URL=https://api.agent.shapeshift.com | ||
| VITE_AGENTIC_SERVER_BASE_URL=https://api.agent.shapeshift.com No newline at end of file |
There was a problem hiding this comment.
Add trailing blank line to satisfy dotenv-linter.
dotenv-linter reports EndingBlankLine at Line 365. Add a newline at EOF to clear the warning.
🔧 Minimal fix
VITE_AGENTIC_SERVER_BASE_URL=https://api.agent.shapeshift.com
+📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| VITE_AGENTIC_SERVER_BASE_URL=https://api.agent.shapeshift.com | |
| VITE_AGENTIC_SERVER_BASE_URL=https://api.agent.shapeshift.com | |
🧰 Tools
🪛 dotenv-linter (4.0.0)
[warning] 365-365: [EndingBlankLine] No blank line at the end of the file
(EndingBlankLine)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.env at line 365, dotenv-linter flags a missing trailing newline at EOF for
the .env file containing VITE_AGENTIC_SERVER_BASE_URL; fix it by editing the
.env file and adding a single blank line (newline character) after the last line
(the VITE_AGENTIC_SERVER_BASE_URL entry) so the file ends with a newline and the
EndingBlankLine warning is cleared.
| Wait up to 15 seconds for a quote to appear. Verify that: | ||
| 1. The "You Get" field shows a USDC amount close to $1 (slightly less due to fees) | ||
| 2. Stargate appears as the swapper source (look for "Stargate" label) | ||
| 3. The "Preview Trade" button is enabled | ||
| If multiple swappers are shown, check that Stargate is one of them. | ||
| expected: > | ||
| Quote shown with receive amount ~$0.98-$1.00 USDC, Stargate visible as source, | ||
| Preview Trade button enabled | ||
| screenshot: true | ||
|
|
||
| - name: Verify protocol fee is displayed | ||
| instruction: > | ||
| In the quote view, look for a fee breakdown section. Verify that a protocol fee | ||
| is shown (the Stargate OFT fee, typically 0.5-1% of the swap amount). | ||
| Note the fee amount shown. | ||
| expected: Protocol fee visible, roughly $0.005-$0.01 for a $1 swap | ||
| screenshot: true |
There was a problem hiding this comment.
Hardcoded quote/fee ranges are too strict for a $1 cross-chain swap.
Line 56 (~$0.98-$1.00) and Line 65 ($0.005-$0.01) are brittle and can fail under normal fee/route variance, especially at tiny notional size. This will introduce flaky e2e runs.
Proposed fixture expectation hardening
- name: Wait for Stargate quote
instruction: >
Wait up to 15 seconds for a quote to appear. Verify that:
- 1. The "You Get" field shows a USDC amount close to $1 (slightly less due to fees)
+ 1. The "You Get" field shows a non-zero USDC amount lower than the sell amount
2. Stargate appears as the swapper source (look for "Stargate" label)
3. The "Preview Trade" button is enabled
If multiple swappers are shown, check that Stargate is one of them.
expected: >
- Quote shown with receive amount ~$0.98-$1.00 USDC, Stargate visible as source,
+ Quote shown with non-zero receive amount below sell amount, Stargate visible as source,
Preview Trade button enabled
@@
- name: Verify protocol fee is displayed
instruction: >
In the quote view, look for a fee breakdown section. Verify that a protocol fee
- is shown (the Stargate OFT fee, typically 0.5-1% of the swap amount).
+ is shown (amount may vary by route and market conditions).
Note the fee amount shown.
- expected: Protocol fee visible, roughly $0.005-$0.01 for a $1 swap
+ expected: Protocol fee visible and greater than $0.00📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| Wait up to 15 seconds for a quote to appear. Verify that: | |
| 1. The "You Get" field shows a USDC amount close to $1 (slightly less due to fees) | |
| 2. Stargate appears as the swapper source (look for "Stargate" label) | |
| 3. The "Preview Trade" button is enabled | |
| If multiple swappers are shown, check that Stargate is one of them. | |
| expected: > | |
| Quote shown with receive amount ~$0.98-$1.00 USDC, Stargate visible as source, | |
| Preview Trade button enabled | |
| screenshot: true | |
| - name: Verify protocol fee is displayed | |
| instruction: > | |
| In the quote view, look for a fee breakdown section. Verify that a protocol fee | |
| is shown (the Stargate OFT fee, typically 0.5-1% of the swap amount). | |
| Note the fee amount shown. | |
| expected: Protocol fee visible, roughly $0.005-$0.01 for a $1 swap | |
| screenshot: true | |
| Wait up to 15 seconds for a quote to appear. Verify that: | |
| 1. The "You Get" field shows a non-zero USDC amount lower than the sell amount | |
| 2. Stargate appears as the swapper source (look for "Stargate" label) | |
| 3. The "Preview Trade" button is enabled | |
| If multiple swappers are shown, check that Stargate is one of them. | |
| expected: > | |
| Quote shown with non-zero receive amount below sell amount, Stargate visible as source, | |
| Preview Trade button enabled | |
| screenshot: true | |
| - name: Verify protocol fee is displayed | |
| instruction: > | |
| In the quote view, look for a fee breakdown section. Verify that a protocol fee | |
| is shown (amount may vary by route and market conditions). | |
| Note the fee amount shown. | |
| expected: Protocol fee visible and greater than $0.00 | |
| screenshot: true |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@e2e/fixtures/stargate-usdc-eth-to-arb.yaml` around lines 50 - 66, Relax the
brittle hardcoded numeric expectations in the quote and fee test steps: update
the "Quote shown..." expected from the strict "~$0.98-$1.00 USDC" to a broader
or percentage-based tolerance (e.g. accept any receive amount within ±10% of $1
or a generic "≈ $1 USDC") and change the protocol fee expectation in the "Verify
protocol fee is displayed" step from "roughly $0.005-$0.01 for a $1 swap" to a
flexible check that asserts the fee label (Stargate/oft fee) is present and that
the displayed fee is non-zero or within a wider percent range (e.g. 0.1%–5%), so
the steps "Quote shown with receive amount..." and "Protocol fee visible..."
accept normal routing/fee variance for tiny notional swaps.
Enable VITE_FEATURE_STARGATE_SWAP feature flag. Stargate V2 is fully implemented with cross-chain USDC bridging via LayerZero, ERC-20 approval flow, and slippage handling. Also fix wallet-health.yaml to use `fill` for password input instead of JS eval + press char-by-char, which was unreliable and based on an outdated assumption about React controlled inputs. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
♻️ Duplicate comments (1)
.env (1)
365-365:⚠️ Potential issue | 🟡 MinorAdd trailing newline at EOF (still failing dotenv-linter).
Line 365 needs a final blank line to clear
EndingBlankLine.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.env at line 365, The .env file is missing a trailing newline which triggers dotenv-linter's EndingBlankLine error; open the .env containing the VITE_AGENTIC_SERVER_BASE_URL entry and add a final blank line (ensure the file ends with a newline character after the last line VITE_AGENTIC_SERVER_BASE_URL=https://api.agent.shapeshift.com) and save so the linter no longer flags EndingBlankLine.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In @.env:
- Line 365: The .env file is missing a trailing newline which triggers
dotenv-linter's EndingBlankLine error; open the .env containing the
VITE_AGENTIC_SERVER_BASE_URL entry and add a final blank line (ensure the file
ends with a newline character after the last line
VITE_AGENTIC_SERVER_BASE_URL=https://api.agent.shapeshift.com) and save so the
linter no longer flags EndingBlankLine.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 85135e69-d0d2-4806-b08e-47fcae04014e
📒 Files selected for processing (2)
.enve2e/fixtures/wallet-health.yaml
Description
Integrates Stargate V2 as a new cross-chain swapper. Stargate is a liquidity bridge protocol built on LayerZero that enables native asset transfers across chains without wrapped tokens.
Supports cross-chain swaps of USDC, USDT, ETH and other assets between Ethereum, Arbitrum, Optimism, Base, and other Stargate-supported chains.
Issue (if applicable)
closes #
Risk
Low — new swapper integration, entirely behind
VITE_FEATURE_STARGATE_SWAPfeature flag. No changes to existing swap flows or other swappers.Stargate V2 bridge contracts only. ERC20 approval +
send()call to Stargate pool contracts. No changes to existing swappers or EVM flows.Testing
Engineering
VITE_FEATURE_STARGATE_SWAP=truein.env.developmentOperations
Screenshots (if applicable)
Quote — Protocol: Stargate selected (USDC Ethereum → USDC Arbitrum One)

Confirm Details — Swap via Stargate in ~1m

Swap complete

On-chain verification
Summary by CodeRabbit
New Features
UI
Chores
Security
Tests
Assets