Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. 🗂️ Base branches to auto review (3)
Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the WalkthroughAdds RFQ support: new OneInchFusion provider and RFQ types, RFQ UI wiring (fetch/sign/submit), wait-for-receipt helper, native-wrap helpers and ABI, provider response tagging with SwapType, config and dependency updates, and tests. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant UI as Swap UI
participant SwapAPI as Swap
participant Provider as OneInchFusion
participant Wallet as EVM Signer
participant Chain as Network/Web3
participant Relayer as Fusion Relayer
UI->>SwapAPI: request quotes (may include RFQ)
SwapAPI->>Provider: getQuote(params)
Provider-->>SwapAPI: quote { type: rfq, getRFQObject }
SwapAPI-->>UI: quotes (RFQ includes rfqOptions via getRFQObject())
UI->>SwapAPI: request swap for selected RFQ quote
SwapAPI->>Provider: getSwap(quote)
Provider-->>SwapAPI: swap { transactions[], typedMessages[], rfq metadata }
SwapAPI-->>UI: swap payload (includes typedMessages)
UI->>Wallet: sign typedMessages (EIP‑712 v4) -> signatures
alt on-chain txs present
loop for each tx
UI->>Chain: sendTransaction(tx)
Chain-->>UI: txHash
end
UI->>Chain: waitForReceipt([txHash...]) --poll-->
Chain-->>UI: receipts ready
end
UI->>SwapAPI: submitRFQOrder(rfqOptions + signatures)
SwapAPI->>Provider: submitRFQOrder(options)
Provider->>Relayer: submit(order + signatures)
Relayer-->>Provider: orderHash
Provider-->>SwapAPI: orderHash
SwapAPI-->>UI: orderHash (persist activity)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60–90 minutes Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
💼 Build Files |
There was a problem hiding this comment.
Actionable comments posted: 16
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (12)
packages/signers/polkadot/src/index.ts (4)
49-55: Remove unsupported 5th arg to mnemonicToMiniSecret (breaks types; no effect at runtime).mnemonicToMiniSecret accepts up to 4 params (mnemonic, password?, wordlist?, onlyJs?). Passing a 5th 2048 is invalid for current @polkadot/util-crypto typings and will fail TS checks; BIP-39’s 2048 PBKDF2 iterations are already hardcoded internally, not configurable here. Drop the extra argument. (jsdocs.io)
- const seed = mnemonicToMiniSecret( - phrase, - password, - undefined, - options.onlyJS, - 2048, - ); + const seed = mnemonicToMiniSecret( + phrase, + password, + undefined, // default wordlist + options.onlyJS, + );
115-123: Async verify is not awaited; assert always passes.assert(this.verify(...)) receives a Promise, which is truthy; signature verification is effectively skipped. Await the result.
- assert( - this.verify( + assert( + await this.verify( bufferToHex(msgHashBuffer), bufferToHex(sig), bufferToHex(pair.publicKey), ), Errors.SigningErrors.UnableToVerify, );
126-134: Same here: await verify for ed25519 path.- assert( - this.verify( + assert( + await this.verify( bufferToHex(msgHashBuffer), bufferToHex(sig), bufferToHex(pair.publicKey), ), Errors.SigningErrors.UnableToVerify, );
137-145: Same here: await verify for sr25519 path.- assert( - this.verify( + assert( + await this.verify( bufferToHex(msgHashBuffer), bufferToHex(sig), bufferToHex(pair.publicKey), ), Errors.SigningErrors.UnableToVerify, );packages/extension/package.json (1)
92-143: Action required — fix vue-echarts / ECharts peer mismatch; CRX plugin OK
- vue-echarts@7.x targets ECharts v5 and is NOT compatible with ECharts v6. Either upgrade vue-echarts to v8 (v8 adds ECharts 6 peer support) or pin ECharts to v5. Location: packages/extension/package.json (lines 92–143).
- @crxjs/vite-plugin@2.2.0 is compatible with Vite 7 — no change required. Location: packages/extension/package.json (lines 92–143).
packages/swap/src/providers/rango/index.ts (2)
1124-1169: Solana totalGaslimit computation can throw and/or be NaN.
- totalGaslimit is used before initialization in the Solana branch, yielding NaN.
- It unconditionally deserializes a VersionedTransaction even when tx.kind is "legacy", which will throw.
Fix by initializing and branching on tx.kind.
- let totalGaslimit: number; + let totalGaslimit = 0; switch (res.networkTransactions.type) { case NetworkType.EVM: { - totalGaslimit = res.networkTransactions.transactions.reduce( + totalGaslimit = res.networkTransactions.transactions.reduce( (total: number, curVal: EVMTransaction) => total + toBN(curVal.gasLimit).toNumber(), 0, ); break; } case NetworkType.Solana: { - for ( - let i = 0, len = res.networkTransactions.transactions.length; - i < len; - i++ - ) { - const tx = res.networkTransactions.transactions[i]; - totalGaslimit += extractComputeBudget( - VersionedTransaction.deserialize( - Buffer.from(tx.serialized, "base64"), - ), - ); - } + for (const tx of res.networkTransactions.transactions) { + if (tx.kind === "versioned") { + totalGaslimit += extractComputeBudget( + VersionedTransaction.deserialize( + Buffer.from(tx.serialized, "base64"), + ), + ); + } else { + // Legacy tx: we don’t have a compute-budget extractor here; fall back to 0. + // Consider adding a legacy extractor or estimating via RPC if needed. + } + } break; }
1585-1596: Wrong condition for “unsigned” retry path in Solana sim helpers.Comments say “only works for unsigned transactions” but code runs on signed ones. Flip the condition.
- if (retryidx > 0 && signed) { + if (retryidx > 0 && !signed) { @@ - if (retryidx > 0 && signed) { + if (retryidx > 0 && !signed) {Also applies to: 1640-1650
packages/swap/src/providers/jupiter/index.ts (4)
468-475: Fix optional context access in catch.
contextis optional; accessingcontext.signalcan throw and mask real errors.- if (!context.signal.aborted) { + if (!context?.signal?.aborted) { console.error( `[Jupiter.getQuote] Error calling getQuote: ${String(err)}`, ); }
524-531: Same fix: optional context in getSwap catch.- if (!context.signal.aborted) { + if (!context?.signal?.aborted) { console.error( `[Jupiter.getSwap] Error calling getSwap: ${String(err)}`, ); }
1005-1011: Bug: Wrong null-check after parsing swap response.Checks
quoteinstead ofswap; will never catch a missing/empty swap and may throw erroneously.- if (!quote) { + if (!swap) { throw new Error( `Failed to get Jupiter swap at url ${url}, something went wrong and result is falsy`, ); }
1054-1075: Make sleep abort-safe when no signal is provided.Directly dereferencing
abortable.signalcan throw whenabortableorsignalis undefined.function sleep( duration: number, abortable?: { signal?: AbortSignal }, ): Promise<void> { - if (abortable.signal.aborted) return Promise.reject(abortable.signal.reason); + if (abortable?.signal?.aborted) { + return Promise.reject(abortable.signal.reason); + } if (duration <= 0) return Promise.resolve(); return new Promise<void>((res, rej) => { function onTimeout() { cleanupSleep(); res(); } function onAbortDuringSleep() { cleanupSleep(); - rej(abortable.signal!.reason); + rej(abortable?.signal?.reason); } function cleanupSleep() { - abortable?.signal?.removeEventListener("abort", onAbortDuringSleep); + abortable?.signal?.removeEventListener("abort", onAbortDuringSleep); clearTimeout(timeout); } - abortable?.signal?.addEventListener("abort", onAbortDuringSleep); + abortable?.signal?.addEventListener("abort", onAbortDuringSleep); const timeout = setTimeout(onTimeout, duration); }); }packages/swap/src/providers/oneInch/index.ts (1)
269-279: Avoid crash when FEE_CONFIGS path is missing.
- Issue: Accessing FEE_CONFIGS[this.name][...].fee can throw if any segment is undefined — make lookups null-safe.
- Locations: packages/swap/src/providers/oneInch/index.ts — lines 158-161 and 268-271.
- Apply the original suggested change (keep exactly as shown) to the occurrence at lines 268-271:
- const feeConfig = - FEE_CONFIGS[this.name][quote.meta.walletIdentifier].fee || 0; + const feeCfg = + FEE_CONFIGS[this.name]?.[quote.meta.walletIdentifier]; + const feePercent = feeCfg?.fee ?? 0; ... - fee: feeConfig * 100, + fee: feePercent * 100,
- Also apply the same null-safe pattern to the earlier occurrence at lines 158-161 (replace direct FEE_CONFIGS[this.name][meta.walletIdentifier] access with optional chaining + nullish coalescing).
🧹 Nitpick comments (44)
Dockerfile (1)
1-1: Slim image and make Yarn deterministic via Corepack.Apply:
FROM node:22.18-bookworm -RUN apt-get update -RUN apt-get install build-essential zip -y +RUN apt-get update && apt-get install -y --no-install-recommends build-essential zip \ + && rm -rf /var/lib/apt/lists/* ENV HOME /home ENV NODE_OPTIONS --max-old-space-size=8192 -RUN node -v && npm -v && yarn -v +RUN corepack enable && corepack prepare yarn@4.5.1 --activate +RUN node -v && npm -v && yarn -v WORKDIR /home.github/workflows/test-swap.yml (1)
12-12: Enable Corepack, enforce immutable installs, and cache Yarn v4 for speed.Add after setup-node:
- run: corepack enableReplace install step:
- run: yarn install --immutableCache Yarn 4 offline cache:
- uses: actions/cache@v4 with: path: | .yarn/cache .yarn/unplugged .yarn/build-state.yml .yarn/install-state.gz key: yarn4-${{ runner.os }}-${{ hashFiles('**/yarn.lock') }} restore-keys: | yarn4-${{ runner.os }}-.github/workflows/test-all.yml (1)
12-12: Same as swap workflow: Corepack + immutable + Yarn v4 cache.Replicate the steps from the swap workflow here (corepack enable, yarn --immutable, actions/cache for .yarn/*).
packages/request/package.json (1)
34-49: Tooling bumps LGTM; consider updating engines to drop EOL Node.This workspace targets Node 22; advertising
>=14.15.0can mislead consumers.Outside this hunk, adjust:
- "engines": { - "node": ">=14.15.0" - }, + "engines": { + "node": ">=18.18.0" + },packages/types/package.json (1)
27-31: Align @types/node across the monorepo and bump engines.node to >=18.18.0
- Found mixed @types/node: ^24.3.1 in packages/hw-wallets and packages/signers/{bitcoin,ethereum,kadena,polkadot}; ^22.18.1 in packages/{extension,extension-bridge,keyring,name-resolution,request,storage,swap,types,utils}. Unify to a single major (recommend ^22.18.1 to match the majority).
- All packages currently list "engines.node": ">=14.15.0" — ESLint v9 drops support for Node <18.18.0; update engines in each package.json. Suggested change:
"engines": { - "node": ">=14.15.0" + "node": ">=18.18.0" },packages/keyring/package.json (1)
37-41: Unify Node typings and engines
- @types/node is ^22 here while some packages use ^24. Standardize across the repo (recommend 22.x to match Node 22.18 runtime).
- Consider bumping engines.node to >=18.18.0 due to ESLint 9.
Use the monorepo audit script shared in types/package.json comment.
Also applies to: 50-51
packages/name-resolution/package.json (1)
45-46: Fix placeholder repository URLRepo URL still has <FILL_IT>.
Outside-changes patch:
- "url": "git+https://github.com/<FILL_IT>" + "url": "git+https://github.com/enkryptcom/enKrypt/tree/main/packages/name-resolution"packages/storage/package.json (1)
30-34: Standardize @types/node and engines across packagesSame note as other packages: align @types/node major across the workspace (recommend 22.x) and consider engines.node >=18.18.0 for ESLint 9.
Use the workspace audit script posted earlier.
Also applies to: 43-45
packages/signers/bitcoin/package.json (1)
35-39: Unify Node typings to match runtime (Node 22.18)This package uses @types/node ^24 while others use ^22. Recommend standardizing on ^22.18.x to match the repo’s Node version and avoid conflicting lib.dom/node type resolutions.
Use the audit script from types/package.json comment to list all versions in the workspace.
Also applies to: 48-49
packages/signers/ethereum/package.json (1)
35-39: Same: align @types/node major and enginesKeep @types/node consistent with the rest (recommend ^22.18.x) and consider updating engines.node >=18.18.0 for ESLint 9.
Use the workspace audit script from types/package.json.
Also applies to: 48-49
packages/signers/kadena/package.json (3)
16-20: Wire up ESLint in scripts (Prettier-only right now).You added ESLint deps but the script runs only Prettier. Recommend adding a dedicated ESLint task and keeping format separate.
"scripts": { - "build": "tsup src/index.ts --format esm,cjs --dts --clean", - "lint": "prettier --write .", + "build": "tsup src/index.ts --format esm,cjs --dts --clean", + "lint": "npm run lint:eslint && npm run format:check", + "lint:eslint": "eslint . --ext .ts", + "format:check": "prettier --check .", + "format:write": "prettier --write .", "test": "vitest run" },
21-23: Align engines with repo Node 22.x.Everything else in the repo targets Node 22.18.0; this still advertises Node 14. Suggest bumping to avoid accidental installs on unsupported Node.
"engines": { - "node": ">=14.15.0" + "node": ">=18.17.0" },Also applies to: 31-48
34-36: Avoid duplicating TypeScript-ESLint meta and individual packages.You have both @typescript-eslint/{eslint-plugin,parser} and the meta package typescript-eslint. Pick one approach to reduce version skew. Easiest: drop the meta package.
- "typescript-eslint": "8.43.0",Also applies to: 47-47
packages/extension-bridge/package.json (2)
32-36: ESLint not used in scripts.Same as other packages—add an ESLint script and separate format check.
"scripts": { "build": "tsup src/index.ts src/window/index.ts src/types.ts --clean --format esm,cjs --dts", - "test": "echo 'no-tests'", - "lint": "prettier --write ." + "test": "echo 'no-tests'", + "lint": "npm run lint:eslint && npm run format:check", + "lint:eslint": "eslint . --ext .ts", + "format:check": "prettier --check .", + "format:write": "prettier --write ." },Also applies to: 46-65
21-23: Set engines.node ≥18 to match CI/runtime.Prevent accidental installs on older Node when running Vitest/Vite config with import.meta.resolve.
"engines": { - "node": ">=14.15.0" + "node": ">=18.17.0" },Also applies to: 47-65
packages/swap/package.json (2)
21-23: Engines mismatch with repo Node 22.x.Bump to avoid running tests/build on Node 14.
"engines": { - "node": ">=14.15.0" + "node": ">=18.17.0" },Also applies to: 44-60
16-20: Add ESLint to scripts (Prettier-only now).Consistent with other packages.
"scripts": { - "build": "tsup src/index.ts --format esm,cjs --dts --clean", - "lint": "prettier --write .", + "build": "tsup src/index.ts --format esm,cjs --dts --clean", + "lint": "npm run lint:eslint && npm run format:check", + "lint:eslint": "eslint . --ext .ts", + "format:check": "prettier --check .", + "format:write": "prettier --write .", "test": "vitest run" },Also applies to: 44-60
packages/utils/package.json (2)
21-23: Raise engines.node to ≥18.Matches CI/build toolchain and avoids subtle ESM/crypto polyfill differences on older Node.
"engines": { - "node": ">=14.15.0" + "node": ">=18.17.0" },Also applies to: 32-50
16-20: Enable ESLint in scripts.Currently only Prettier runs.
"scripts": { - "build": "tsup src/index.ts --format esm,cjs --dts --clean", - "lint": "prettier --write .", + "build": "tsup src/index.ts --format esm,cjs --dts --clean", + "lint": "npm run lint:eslint && npm run format:check", + "lint:eslint": "eslint . --ext .ts", + "format:check": "prettier --check .", + "format:write": "prettier --write .", "test": "vitest run" },Also applies to: 32-50
packages/hw-wallets/package.json (2)
55-74: Ledger lib bumps—please smoke test on devices.Version bumps can affect tx serialization or app compatibility. Validate ETH EIP-712, SOL derivation, and BTC segwit signing on real devices before release.
21-23: Update engines and add ESLint script.Same rationale as other packages.
"engines": { - "node": ">=14.15.0" + "node": ">=18.17.0" }, "scripts": { - "build": "tsup src/index.ts --format esm,cjs --dts --clean", - "lint": "prettier --write .", + "build": "tsup src/index.ts --format esm,cjs --dts --clean", + "lint": "npm run lint:eslint && npm run format:check", + "lint:eslint": "eslint . --ext .ts", + "format:check": "prettier --check .", + "format:write": "prettier --write .", "test": "vitest run" },Also applies to: 24-41
packages/swap/src/utils/abi/wrapper.ts (2)
1-1: Export a named ABI and freeze literal types for better tooling.Exporting a named const and marking the array as const improves type inference (ethers/viem) and prevents accidental mutation.
-export default [ +export const WRAPPED_ABI = [ ... -]; + ] as const; + +export default WRAPPED_ABI;Also applies to: 153-153
114-114: Consider removing the legacy 'fallback' entry if unused.Some tooling ignores/complains about ABI entries with type 'fallback'. If you don’t rely on it, safe to drop to reduce noise.
packages/extension/configs/vitest.config.mts (1)
20-30: Safer path conversion for customResolver (Windows-friendly).Replacing the file:// prefix may mis-handle Windows paths. Use fileURLToPath for robust conversion.
-import { defineConfig } from 'vitest/config'; +import { defineConfig } from 'vitest/config'; +import { fileURLToPath } from 'node:url'; @@ - customResolver(source) { - return import.meta.resolve(source).replace(/^file:\/\//, ''); + customResolver(source) { + return fileURLToPath(new URL(import.meta.resolve(source))); },packages/name-resolution/src/index.ts (3)
27-28: Avoid commented-out init; gate SID behind a feature flag and exclude from initDone.Right now SID is still constructed but never initialized/used, adding dead weight and potential side effects. Prefer a boolean flag (e.g., enableSID) to conditionally construct/init and keep initDone strictly to active resolvers.
Example (outside this hunk):
// constructor this.sid = options.sid && options.sid.enabled ? new SIDResolver(options.sid) : undefined; const inits = [this.ens.init(), this.rns.init(), this.ud.init()]; this.initDone = Promise.all(inits);
35-36: Remove stale SID path from reverse resolution or guard it.Leaving the call commented invites drift. If SID is togglable, wrap with a runtime check instead of comments.
- // this.sid.resolveReverseName(address), + ...(this.sid ? [this.sid.resolveReverseName(address)] : []),
51-60: Signature rename is fine; remove commented SID branches to avoidpaymentIdChaindrift.
_paymentIdChainrename is OK. Remove the commented SID lines in packages/name-resolution/src/index.ts (// this.sid.init(), // this.sid.resolveReverseName(...), and the commented resolveAddress branch) — SID and types still referencepaymentIdChainin packages/name-resolution/src/sid/index.ts and packages/name-resolution/src/types.ts, so the comments will drift.packages/name-resolution/tests/resolver.test.ts (1)
23-25: Align test setup with disabled SID.Since you expect
spaceid.arbto resolve to null, also drop the SID config from the resolver options to avoid implying SID is used.Example (outside this hunk):
const resolver = new NameResolver({ ens: { node: "https://nodes.mewapi.io/rpc/eth" } });packages/name-resolution/tests/sid.test.ts (1)
4-4: Add a reason/comment for skipped suite and a tracking ticket.Skipping is fine, but please annotate why and when to re-enable (e.g., link to issue).
packages/swap/src/types/index.ts (1)
239-243: RFQOptions asanymakes downstream brittle.Define a minimal shape (e.g., maker, taker, expiry, salt, chainId, permit, etc.) to prevent misuse and enable validation. Keep an escape hatch via index signature if needed.
export interface RFQOptions { maker: string; taker: string; expiry: string; // unix sec chainId: number; order: unknown; // provider-specific signed order blob signatures?: string[]; [key: string]: unknown; }packages/swap/src/utils/approvals.ts (1)
108-116: Guard against native token to avoid bogus allowance calls.If callers ever pass the native token address by mistake, this will try to call allowance on a non-ERC20. Add a short-circuit.
Apply:
- import { GAS_LIMITS } from "../configs"; + import { GAS_LIMITS, NATIVE_TOKEN_ADDRESS } from "../configs"; @@ const getAllowanceTransactions = async (options: { fromToken: { address: string }; @@ }): Promise<EVMTransaction[]> => { const transactions: EVMTransaction[] = []; + // Native token doesn't require approvals + if (options.fromToken.address === NATIVE_TOKEN_ADDRESS) return transactions;packages/signers/polkadot/package.json (1)
21-30: Move commit tooling to dev and align Node engine with toolchain.
- @commitlint/cli should be a devDependency.
- eslint 9/ts 5.9 generally require Node >=18.18. Align engines.node to avoid installs on unsupported Node.
Apply:
"engines": { - "node": ">=14.15.0" + "node": ">=18.18.0" }, @@ "dependencies": { - "@commitlint/cli": "^19.8.1", "@enkryptcom/utils": "workspace:^", @@ "devDependencies": { + "@commitlint/cli": "^19.8.1",packages/extension/package.json (1)
25-90: Avoid shipping yarn as a runtime dep."yarn" should be a devDependency (or a root packageManager field). Keeping it in deps bloats installs.
"dependencies": { @@ - "yarn": "^1.22.22", @@ }, "devDependencies": { @@ + "yarn": "^1.22.22",packages/swap/tests/swap.test.ts (2)
80-95: Assert existence and fix typo for 1inch Fusion quote var.Prevent undefined access and improve naming.
- const oneInchFusionQuote = quotes.find( - (q) => q.provider === ProviderName.oneInchFusion, - ); + const oneInchFusionQuote = quotes.find( + (q) => q.provider === ProviderName.oneInchFusion, + ); + expect(oneInchFusionQuote, "Missing 1inch Fusion quote").to.exist; @@ - const swapOneInch = await enkryptSwap.getSwap(oneInceQuote!.quote); + const swapOneInch = await enkryptSwap.getSwap(oneInchQuote!.quote);
117-137: Repeat existence assert and fix variable typo in second case.- const oneInceQuote = quotes.find( + const oneInchQuote = quotes.find( (q) => q.provider === ProviderName.oneInch, ); @@ - const oneInchFusionQuote = quotes.find( + const oneInchFusionQuote = quotes.find( (q) => q.provider === ProviderName.oneInchFusion, ); + expect(oneInchFusionQuote, "Missing 1inch Fusion quote").to.exist; @@ - expect(oneInceQuote!.provider).to.be.eq(ProviderName.oneInch); + expect(oneInchQuote!.provider).to.be.eq(ProviderName.oneInch);packages/extension/src/ui/action/views/swap/index.vue (1)
841-847: Make RFQ options fetching resilient.If one RFQ provider errors, don’t fail the whole flow—use allSettled.
- const tradesRfqOptions = rfqTrades.map(t => t!.getRFQObject!()); + const tradesRfqOptions = rfqTrades.map(t => t!.getRFQObject!()); const statusObjects = await Promise.all(tradeStatusOptions); - const rfqOptionObjects = await Promise.all(tradesRfqOptions); + const rfqOptionResults = await Promise.allSettled(tradesRfqOptions); trades.forEach((t, idx) => (t!.status = statusObjects[idx])); - rfqTrades.forEach((t, idx) => (t!.rfqOptions = rfqOptionObjects[idx])); + rfqTrades.forEach((t, idx) => { + const r = rfqOptionResults[idx]; + if (r.status === "fulfilled") t!.rfqOptions = r.value; + });packages/swap/src/providers/paraswap/index.ts (1)
314-336: Add type on quote for consistency with swap responses.Several providers tag swap responses with SwapType; mirroring that on quotes helps downstream logic stay uniform.
const response: ProviderQuoteResponse = { fromTokenAmount: toBN(res.srcAmount), toTokenAmount: toBN(res.destAmount), additionalNativeFees: toBN(0), provider: this.name, + type: SwapType.regular, quote: { meta: { ...meta, priceRoute: res, }, options, provider: this.name, },packages/extension/src/providers/ethereum/networks/zksepolia.ts (1)
6-9: Rename zkgoerli -> zksepolia in zksepolia.tsReplace zkgoerliOptions/zkgoerli/default export with zksepoliaOptions/zksepolia (file: packages/extension/src/providers/ethereum/networks/zksepolia.ts — lines ~6,21,23). index.ts import (packages/extension/src/providers/ethereum/networks/index.ts:17) already uses zkSepoliaNode and needs no change.
-const zkgoerliOptions: EvmNetworkOptions = { +const zksepoliaOptions: EvmNetworkOptions = { @@ -const zkgoerli = new EvmNetwork(zkgoerliOptions); +const zksepolia = new EvmNetwork(zksepoliaOptions); -export default zkgoerli; +export default zksepolia;packages/swap/src/providers/oneInch/index.ts (1)
39-82: Exporting supportedNetworks is fine; consider freezing to avoid accidental mutation.Minor: prevent external mutation with Object.freeze or mark the shape readonly.
Example:
-export const supportedNetworks: { +export const supportedNetworks: Readonly<{ [key in SupportedNetworkName]?: { approvalAddress: string; chainId: string }; -} = { +}> = Object.freeze({ ... -}; +});packages/extension/src/ui/action/views/swap/views/swap-best-offer/index.vue (1)
267-267: Remove console logging or gate behind a debug flag.UI logs leak into production console. Strip or guard them.
Apply:
- console.log(trade); ... - console.log(`Trade ${index + 1}:`, { ... }); ... - console.log('starting wait'); ... - console.log('wait done'); ... - console.log(orderHash);Also applies to: 326-333, 449-456, 463-463
packages/swap/tests/oneInchFusion.test.ts (2)
82-85: Pad amount to 32 bytes instead of manual zero prefixing.Manual zeros are brittle. Use 64-nybble padding.
Apply:
- )}00000000000000000000000000000000000000000000000${numberToHex( - amount, - ).replace("0x", "")}`, + )}${numberToHex(amount).replace("0x", "").padStart(64, "0")}`,
49-57: Optional: Assert RFQ semantics instead of internal counts.Strengthen tests by asserting RFQ type and approval encoding for tx[0], not the number of txs.
You can add:
expect(swap?.type).to.eq('rfq'); expect((swap?.transactions[0] as EVMTransaction).to).to.eq(fromToken.address); expect(((swap?.transactions[0] as EVMTransaction).data as string).slice(0, 10)).to.eq('0x095ea7b3'); // approve selectorAlso applies to: 76-79
packages/swap/src/providers/oneInchFusion/index.ts (2)
167-176: Strip noisy console logs from provider.Provider-level logs will spam tests/consumers.
Remove the
console.log(...)calls and keepconsole.erroronly where actionable, or gate logs behind a debug flag.Also applies to: 234-236, 315-316
302-311: Status mapping: handle more Fusion statuses explicitly.Consider mapping
Expired,Cancelled, andUnfilleddistinctly for better UX/telemetry;PartiallyFilledmay be “success” depending on policy.Example:
if (status.status === OrderStatus.Filled) return TransactionStatus.success; if (status.status === OrderStatus.PartiallyFilled) return TransactionStatus.success; // or a dedicated status if (status.status === OrderStatus.Pending) return TransactionStatus.pending; if (status.status === OrderStatus.Expired || status.status === OrderStatus.Cancelled) return TransactionStatus.failed; return TransactionStatus.failed;
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
yarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (64)
.github/workflows/test-all.yml(1 hunks).github/workflows/test-swap.yml(1 hunks).nvmrc(1 hunks).vscode/settings.json(1 hunks)Dockerfile(1 hunks)package.json(1 hunks)packages/extension-bridge/package.json(2 hunks)packages/extension/configs/vitest.config.mts(1 hunks)packages/extension/package.json(6 hunks)packages/extension/src/providers/common/libs/new-features.ts(1 hunks)packages/extension/src/providers/ethereum/libs/activity-handlers/providers/etherscan/configs.ts(1 hunks)packages/extension/src/providers/ethereum/libs/assets-handlers/assetinfo-mew.ts(1 hunks)packages/extension/src/providers/ethereum/networks/cagaAnkara.ts(0 hunks)packages/extension/src/providers/ethereum/networks/coti-devnet.ts(0 hunks)packages/extension/src/providers/ethereum/networks/coti-testnet.ts(1 hunks)packages/extension/src/providers/ethereum/networks/form-testnet.ts(0 hunks)packages/extension/src/providers/ethereum/networks/form.ts(0 hunks)packages/extension/src/providers/ethereum/networks/index.ts(6 hunks)packages/extension/src/providers/ethereum/networks/skale/chaos.ts(0 hunks)packages/extension/src/providers/ethereum/networks/skale/index.ts(0 hunks)packages/extension/src/providers/ethereum/networks/tac.ts(1 hunks)packages/extension/src/providers/ethereum/networks/zkgoerli.ts(0 hunks)packages/extension/src/providers/ethereum/networks/zksepolia.ts(1 hunks)packages/extension/src/providers/polkadot/networks/index.ts(0 hunks)packages/extension/src/providers/polkadot/networks/unique/opal.ts(0 hunks)packages/extension/src/ui/action/views/swap/index.vue(2 hunks)packages/extension/src/ui/action/views/swap/libs/evm-gasvals.ts(1 hunks)packages/extension/src/ui/action/views/swap/libs/evm-waitreceipt.ts(1 hunks)packages/extension/src/ui/action/views/swap/types.ts(2 hunks)packages/extension/src/ui/action/views/swap/views/swap-best-offer/index.vue(8 hunks)packages/hw-wallets/package.json(3 hunks)packages/keyring/package.json(2 hunks)packages/name-resolution/package.json(3 hunks)packages/name-resolution/src/index.ts(2 hunks)packages/name-resolution/tests/resolver.test.ts(1 hunks)packages/name-resolution/tests/sid.test.ts(1 hunks)packages/request/package.json(2 hunks)packages/signers/bitcoin/package.json(2 hunks)packages/signers/ethereum/package.json(2 hunks)packages/signers/kadena/package.json(2 hunks)packages/signers/polkadot/package.json(2 hunks)packages/signers/polkadot/src/index.ts(1 hunks)packages/storage/package.json(2 hunks)packages/swap/package.json(2 hunks)packages/swap/src/common/estimateGasList.ts(0 hunks)packages/swap/src/configs.ts(2 hunks)packages/swap/src/index.ts(5 hunks)packages/swap/src/providers/changelly/index.ts(2 hunks)packages/swap/src/providers/jupiter/index.ts(2 hunks)packages/swap/src/providers/okx/index.ts(2 hunks)packages/swap/src/providers/oneInch/index.ts(3 hunks)packages/swap/src/providers/oneInchFusion/index.ts(1 hunks)packages/swap/src/providers/oneInchFusion/types.ts(1 hunks)packages/swap/src/providers/paraswap/index.ts(3 hunks)packages/swap/src/providers/rango/index.ts(2 hunks)packages/swap/src/providers/zerox/index.ts(3 hunks)packages/swap/src/types/index.ts(6 hunks)packages/swap/src/utils/abi/wrapper.ts(1 hunks)packages/swap/src/utils/approvals.ts(3 hunks)packages/swap/tests/oneInchFusion.test.ts(1 hunks)packages/swap/tests/swap.test.ts(3 hunks)packages/types/package.json(2 hunks)packages/types/src/networks.ts(3 hunks)packages/utils/package.json(2 hunks)
💤 Files with no reviewable changes (10)
- packages/extension/src/providers/ethereum/networks/form-testnet.ts
- packages/extension/src/providers/polkadot/networks/index.ts
- packages/swap/src/common/estimateGasList.ts
- packages/extension/src/providers/ethereum/networks/cagaAnkara.ts
- packages/extension/src/providers/polkadot/networks/unique/opal.ts
- packages/extension/src/providers/ethereum/networks/zkgoerli.ts
- packages/extension/src/providers/ethereum/networks/form.ts
- packages/extension/src/providers/ethereum/networks/skale/index.ts
- packages/extension/src/providers/ethereum/networks/coti-devnet.ts
- packages/extension/src/providers/ethereum/networks/skale/chaos.ts
🧰 Additional context used
🧬 Code graph analysis (10)
packages/extension/src/providers/ethereum/networks/coti-testnet.ts (1)
packages/extension/src/providers/ethereum/types/evm-network.ts (2)
EvmNetworkOptions(22-53)EvmNetwork(55-286)
packages/swap/src/providers/oneInchFusion/types.ts (1)
packages/swap/src/types/index.ts (2)
EVMTransaction(163-170)BN(47-47)
packages/extension/src/providers/ethereum/networks/tac.ts (2)
packages/extension/src/providers/ethereum/types/evm-network.ts (2)
EvmNetworkOptions(22-53)EvmNetwork(55-286)packages/extension/src/providers/ethereum/libs/activity-handlers/index.ts (1)
EtherscanActivity(10-10)
packages/extension/src/providers/ethereum/networks/zksepolia.ts (1)
packages/extension/src/providers/ethereum/types/evm-network.ts (2)
EvmNetworkOptions(22-53)EvmNetwork(55-286)
packages/extension/src/ui/action/views/swap/types.ts (1)
packages/swap/src/types/index.ts (1)
RFQOptionsResponse(254-257)
packages/swap/tests/oneInchFusion.test.ts (4)
packages/swap/src/types/index.ts (1)
EVMTransaction(163-170)packages/swap/src/providers/oneInch/index.ts (1)
ONEINCH_APPROVAL_ADDRESS(37-38)packages/swap/src/utils/approvals.ts (1)
TOKEN_AMOUNT_INFINITY_AND_BEYOND(8-9)packages/utils/src/index.ts (1)
numberToHex(46-46)
packages/swap/src/types/index.ts (1)
packages/swap/src/index.ts (1)
ProviderSwapResponse(270-270)
packages/swap/src/utils/approvals.ts (3)
packages/swap/src/types/index.ts (2)
BN(47-47)EVMTransaction(163-170)packages/swap/src/configs.ts (1)
GAS_LIMITS(143-143)packages/utils/src/index.ts (1)
numberToHex(46-46)
packages/swap/src/index.ts (1)
packages/swap/src/types/index.ts (1)
RFQOptionsResponse(254-257)
packages/swap/src/providers/oneInchFusion/index.ts (6)
packages/swap/src/types/index.ts (12)
TokenType(49-60)MinMaxResponse(205-210)getQuoteOptions(143-149)QuoteMetaOptions(107-114)EVMTransaction(163-170)ProviderQuoteResponse(218-230)SwapQuote(212-216)ProviderSwapResponse(259-276)RFQOptionsResponse(254-257)StatusOptions(244-247)StatusOptionsResponse(249-252)RFQOptions(239-242)packages/swap/src/providers/oneInch/index.ts (1)
supportedNetworks(39-82)packages/swap/src/utils/common.ts (1)
isEVMAddress(13-19)packages/swap/src/utils/approvals.ts (4)
TOKEN_AMOUNT_INFINITY_AND_BEYOND(8-9)getAllowanceTransactions(171-171)isSufficientWrappedAvailable(174-174)getNativeWrapTx(173-173)packages/swap/src/providers/oneInchFusion/types.ts (1)
OneInchSwapResponse(3-12)packages/swap/src/configs.ts (3)
NATIVE_TOKEN_ADDRESS(144-144)FEE_CONFIGS(142-142)DEFAULT_SLIPPAGE(148-148)
🪛 GitHub Check: test
packages/swap/tests/oneInchFusion.test.ts
[failure] 77-77: tests/oneInchFusion.test.ts > OneInchFusion Provider > it should return a quote non infinity approval
AssertionError: expected 1 to equal 2
- Expected
- Received
- 2
- 1
❯ tests/oneInchFusion.test.ts:77:47
[failure] 50-50: tests/oneInchFusion.test.ts > OneInchFusion Provider > it should return a quote infinity approval
AssertionError: expected 1 to equal 2
- Expected
- Received
- 2
- 1
❯ tests/oneInchFusion.test.ts:50:47
🪛 GitHub Actions: Test all swap providers
packages/swap/tests/oneInchFusion.test.ts
[error] 50-50: Step: 'cd packages/swap && yarn test' - OneInchFusion: test 'should return a quote infinity approval' failed. AssertionError: expected 1 to equal 2.
[error] 77-77: Step: 'cd packages/swap && yarn test' - OneInchFusion: test 'should return a quote non infinity approval' failed. AssertionError: expected 1 to equal 2.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: buildAll
🔇 Additional comments (39)
.nvmrc (1)
1-1: Node bump confirmed in .nvmrc — CI/Docker alignment unverified
- .nvmrc => v22.18.0 (confirmed).
- package.json engines in packages/* are set to >=14.15.0 (e.g., packages/hw-wallets, keyring, name-resolution, request, signers/*, storage, swap, types, utils) — not pinned to Node 22.
- Automated search couldn't locate/verify GitHub Actions workflows or Dockerfile FROM pins (ripgrep skipped files). Ensure actions/setup-node
node-versionand DockerFROM node:22.18.0are updated so CI and Docker remain in lockstep.package.json (1)
37-38: Dev tool bumps LGTM.No API surface impact; SWC/concurrently updates align with Node 22.
packages/extension/src/providers/ethereum/libs/assets-handlers/assetinfo-mew.ts (1)
145-149: No change required — Blockscout path already includes native tokengetBlockscoutBalances builds a nativeBalance (NATIVE_TOKEN_ADDRESS) and prepends it to token results, and its catch returns a native fallback ('0x0'), so the proposed guard is redundant (see packages/extension/src/providers/ethereum/libs/assets-handlers/blockscout.ts — native mapping ~lines 47–51 and fallback ~lines 81–85).
.vscode/settings.json (1)
12-13: Editor settings LGTM.Prettier as default formatter and disabled inline suggestions are fine for team consistency.
packages/keyring/package.json (1)
32-32: Unify @polkadot/util across packages and update lockfile
- packages/extension/package.json, packages/hw-wallets/package.json, packages/keyring/package.json, packages/signers/polkadot/package.json all declare "@polkadot/util": "^13.5.6".
- yarn.lock contains both 12.6.2 and 13.5.6 entries — run yarn install/upgrade (or yarn dedupe && yarn install) to ensure a single resolved version and commit the updated lockfile.
packages/name-resolution/package.json (2)
25-28: Tooling bumps look goodNo issues spotted with the TS/ESLint/viem bumps for dev-time usage.
Also applies to: 38-41
50-52: Confirm runtime dependency placement for @bonfida/spl-name-service and @ensdomains/address-encoder — OKBoth packages are listed under "dependencies" in packages/name-resolution/package.json; a scan of packages/name-resolution/src found no imports/requires of "viem".
packages/swap/package.json (1)
24-42: Keep @1inch/limit-order-sdk — it's required.packages/swap/src/providers/oneInchFusion/index.ts imports Bps from @1inch/limit-order-sdk (line 11) and uses new Bps(BigInt(...)) and Bps.fromPercent(100) when building quoteParams.integratorFee (lines 151–152).
packages/types/src/networks.ts (1)
31-31: Enum rename verified — downstream references updated; no stale names found.New entries exist in packages/types/src/networks.ts and are referenced in:
- packages/extension/src/providers/ethereum/networks/zksepolia.ts (NetworkNames.zkSyncSepolia)
- packages/extension/src/providers/ethereum/networks/coti-testnet.ts (NetworkNames.CotiTestnet)
- packages/extension/src/providers/ethereum/networks/tac.ts and packages/extension/src/providers/common/libs/new-features.ts (NetworkNames.TAC)
- activity-handlers etherscan configs reference TAC as well.
Search returned no matches for zkSyncGoerli or CotiDevnet.
packages/extension/src/providers/common/libs/new-features.ts (1)
3-3: LGTM: feature flag updated to TAC.packages/extension/src/providers/ethereum/networks/tac.ts (1)
7-21: Set coingeckoPlatform or harden EvmNetwork; EtherscanActivity OK.
- explorer.tac.build is a Blockscout instance and exposes an Etherscan‑compatible /api — EtherscanActivity should work.
- CoinGecko id "tac" exists; CoinGecko shows chain/ecosystem per asset rather than a single TAC platform id.
- Action (pick one): A) If CoingeckoPlatform has a matching value, add coingeckoPlatform to tacOptions. B) Preferable — remove the non‑null assertion in EvmNetwork and add runtime guards/fallbacks so missing coingeckoPlatform does not throw when users add custom tokens.
- File: packages/extension/src/providers/ethereum/networks/tac.ts (lines 7–21).
packages/swap/src/types/index.ts (4)
126-133: Add ProviderName.oneInchFusion — looks good.
321-323: Abstract ProviderWithRFQ is fine; ensure Fusion provider extends it.
158-161: SwapType set on all provider getSwap responses — resolved.Verified provider getSwap implementations (oneInch, oneInchFusion, paraswap, zerox, okx, rango, jupiter, changelly) each return type: SwapType.regular or SwapType.rfq.
263-276: typedMessages / getRFQObject — document format and lifecycle
- Document typedMessages: specify exact format (array of EVM typed-message payloads — e.g. JSON EIP‑712 typed-data strings), signing order/expectations and an example in packages/swap/src/types/index.ts (JSDoc or README).
- Require/getRFQObject: guarantee idempotence and that returned RFQ options are stable/cacheable between quote and submit (UI calls it at quote time and reuses the result); update provider implementations if they return ephemeral data.
Used by: packages/extension/src/ui/action/views/swap/index.vue (getRFQObject usage) and packages/extension/src/ui/action/views/swap/views/swap-best-offer/index.vue (typedMessages → EvmTypedMessageSigner).
packages/swap/src/utils/approvals.ts (3)
70-85: Wrap balance check looks correct.Using wrapper’s balanceOf + BN.gte is appropriate. No issues spotted.
87-102: Native wrap tx builder LGTM.deposit() encoding + hex-encoded value and a fixed gasLimit is fine, assuming GAS_LIMITS.Wrap exists and is hex.
109-109: Signature change ripple check.approvals.ts now expects:
fromToken: { address: string };Confirm every getAllowanceTransactions call passes a fromToken object with an address property. Call sites to check:
- packages/swap/src/providers/oneInchFusion/index.ts:177
- packages/swap/src/providers/zerox/index.ts:184
- packages/swap/src/providers/paraswap/index.ts:208, 304
- packages/swap/src/providers/oneInch/index.ts:194
Acceptable shapes: fromToken: options.fromToken or fromToken: { address: options.fromToken.address }.
packages/swap/src/providers/rango/index.ts (1)
1187-1192: Swap type tagging LGTM.Explicitly marking Rango swaps as regular is correct.
packages/swap/src/providers/paraswap/index.ts (1)
286-299: Graceful error handling on missing priceRoute looks good.Returning null instead of throwing avoids cascading failures. Thanks for the hardening.
packages/swap/src/providers/okx/index.ts (2)
37-38: LGTM: SwapType correctly wired into OKX provider.Importing SwapType aligns the provider with the new unified swap response shape.
425-426: LGTM: Response annotated with SwapType.regular.Consistent with other providers and the updated public types.
packages/swap/src/providers/changelly/index.ts (2)
34-35: LGTM: SwapType import added.
992-996: LGTM: SwapType.regular attached to swap response.packages/swap/src/providers/zerox/index.ts (2)
178-179: LGTM: Stricter error guard for ZeroX response.Returning null when transaction is missing avoids downstream NPEs.
262-263: LGTM: SwapType.regular included in response.packages/swap/src/providers/jupiter/index.ts (1)
45-45: LGTM: SwapType wired (import + response).Also applies to: 511-512
packages/swap/src/providers/oneInchFusion/types.ts (1)
1-12: LGTM: RFQ swap response shape looks sound.Fields align with EVMTransaction and BN usage across the codebase.
packages/swap/src/index.ts (4)
7-7: LGTM: OneInchFusion provider import added.
39-41: LGTM: RFQ types wired into public surface.
279-280: LGTM: ToTokenType now exported from module.
133-138: Confirm provider precedence after inserting OneInchFusion.Verified in packages/swap/src/index.ts: fromTokens are merged via [...this.providers].reverse() + Object.assign (merge at ~lines 146–147), so earlier entries in the providers array win. With OneInchFusion placed before Fusion (providers array ~lines 133–138), OneInchFusion will override Fusion on token key collisions — confirm this ordering is intended; if not, swap their order or adjust the merge logic.
packages/swap/src/providers/oneInch/index.ts (1)
18-19: LGTM: Tagging swap responses with SwapType.regular.packages/extension/src/providers/ethereum/networks/index.ts (5)
17-17: LGTM: zkSepolia import added.
98-99: LGTM: zkGoerli → zkSepolia mapping updated.
58-59: LGTM: coti-testnet import added.
78-79: LGTM: TAC network imported.
165-166: LGTM: TAC network exported.packages/extension/src/ui/action/views/swap/views/swap-best-offer/index.vue (1)
163-165: Avoid deep imports — import types from the package entrypoint or re-export them.Deep import '@enkryptcom/swap/src/types' is fragile; replace with the package root and, if needed, add re-exports in @enkryptcom/swap. Occurrences to fix: packages/extension/src/ui/action/views/swap/views/swap-best-offer/index.vue (ln 163), packages/extension/src/ui/action/views/swap/index.vue (ln 171), packages/extension/src/ui/action/views/swap/types.ts (ln 13).
-import { SwapType, WalletIdentifier } from '@enkryptcom/swap/src/types'; +import { SwapType, WalletIdentifier } from '@enkryptcom/swap';If these types aren't exported from the package entrypoint, re-export SwapType and WalletIdentifier from @enkryptcom/swap.
| include: ['crypto'], | ||
| }), |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Polyfills trimmed to ['crypto']—double-check Buffer/process use in tests.
If any tests use Buffer/process, they’ll now fail under jsdom.
🏁 Script executed:
#!/bin/bash
# Scan extension code/tests for Buffer or process usage that may need polyfills
rg -nP -C2 '\b(Buffer|process)\b' packages/extension/src packages/extension/tests || trueLength of output: 60719
Restore Buffer/process polyfills or refactor — Buffer is used widely in extension src
- Search found many Buffer usages under packages/extension/src (representative hits):
- packages/extension/src/ui/action/views/swap/index.vue:869 (Buffer.from(JSON.stringify(...))).
- packages/extension/src/ui/action/views/swap/libs/send-transactions.ts:196, 288, 306, 384 (Buffer.from for txs/signatures).
- packages/extension/src/ui/action/views/import-account/views/import-account-password.vue:85-86 (Buffer.from(privKey,'hex')).
- packages/extension/src/providers/solana/ui/libs/signin-message.ts:50-56 (Buffer.concat / Buffer.from).
- packages/extension/src/providers/bitcoin/libs/sign-message-utils.ts:3-11 (Buffer.alloc/Buffer.concat/Buffer.read/write).
- packages/extension/src/providers/polkadot/libs/blockies.ts:22-23 (Buffer.from(...).toString('base64')).
- Action: revert vitest.config.mts change (packages/extension/configs/vitest.config.mts — include Buffer/process polyfills, e.g., add 'buffer' and 'process') or update all tests/code to avoid Buffer/process; otherwise tests running under jsdom will break.
🤖 Prompt for AI Agents
In packages/extension/configs/vitest.config.mts around lines 9-10, the config
removed polyfills for Buffer/process causing many Buffer usages in
packages/extension/src to break under jsdom; restore the polyfills by reverting
the change or adding back 'buffer' and 'process' to the include/polyfill list
(or ensure the vitest setup injects Buffer and process shims before tests run),
then run the extension test suite to verify all Buffer-based usages pass.
| [NetworkNames.TAC]: 'https://explorer.tac.build/', | ||
| }; |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Verify TAC explorer compatibility with this handler
This map mixes Etherscan- and Blockscout-style endpoints. Confirm https://explorer.tac.build/ exposes the API shape your handler expects (e.g., /api?module=account... or Blockscout equivalents), and whether a trailing /api should be used.
Optionally validate:
If the API path differs, add a per-network override or adjust the endpoint accordingly.
🏁 Script executed:
#!/bin/bash
base="https://explorer.tac.build"
# Basic reachability
curl -sI "$base" | head -n1
# Probe common API patterns (may 404 if different—adjust accordingly)
curl -s "$base/api?module=block&action=eth_block_number" | head -c 200; echo
curl -s "$base/api/v2/stats" | head -c 200; echoLength of output: 261
Use Blockscout v2 for TAC or adapt the handler
Probed endpoints show /api returns JSON‑RPC (eth_blockNumber) and /api/v2 returns Blockscout v2 JSON (e.g., /api/v2/stats) — the explorer does not expose Etherscan "module=..." responses. Update packages/extension/src/providers/ethereum/libs/activity-handlers/providers/etherscan/configs.ts (lines 71–72) to use "https://explorer.tac.build/api/v2" or add a per-network override and change the handler to call Blockscout API shapes.
| cotiTestnetNode: cotiTestnetNode, | ||
| hoodi: hoodiNode, |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Fix key name for COTI testnet export.
Key should be cotiTestnet to match naming convention and consumers. Using cotiTestnetNode as the key is likely a breaking typo.
Apply:
- cotiTestnetNode: cotiTestnetNode,
+ cotiTestnet: cotiTestnetNode,🏁 Script executed:
#!/bin/bash
# Verify consumers expect `cotiTestnet`, not `cotiTestnetNode`
rg -n "cotiTestnet(Node)?" packages/extension -C2Length of output: 1949
Fix export key: use cotiTestnet (not cotiTestnetNode)
Key should match other network keys and the exported default (packages/extension/src/providers/ethereum/networks/coti-testnet.ts). Apply:
- cotiTestnetNode: cotiTestnetNode,
+ cotiTestnet: cotiTestnetNode,📝 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.
| cotiTestnetNode: cotiTestnetNode, | |
| hoodi: hoodiNode, | |
| cotiTestnet: cotiTestnetNode, | |
| hoodi: hoodiNode, |
🤖 Prompt for AI Agents
packages/extension/src/providers/ethereum/networks/index.ts around lines
144-145: the exported object uses the key "cotiTestnetNode" but should use
"cotiTestnet" to match the other network keys and the default export in
packages/extension/src/providers/ethereum/networks/coti-testnet.ts; rename the
key from cotiTestnetNode to cotiTestnet while keeping the value reference
(cotiTestnetNode) unchanged so other code continues to import by the
standardized key.
| import { SwapType } from '@enkryptcom/swap/src/types'; | ||
|
|
There was a problem hiding this comment.
🛠️ Refactor suggestion
Avoid deep import of SwapType.
Prefer importing from '@enkryptcom/swap' once it re-exports SwapType.
-import { SwapType } from '@enkryptcom/swap/src/types';
+import { SwapType } from '@enkryptcom/swap';📝 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.
| import { SwapType } from '@enkryptcom/swap/src/types'; | |
| import { SwapType } from '@enkryptcom/swap'; |
🤖 Prompt for AI Agents
In packages/extension/src/ui/action/views/swap/index.vue around lines 171 to
172, the file currently deep-imports SwapType from '@enkryptcom/swap/src/types';
replace that deep import with a top-level import from '@enkryptcom/swap' (i.e.
import { SwapType } from '@enkryptcom/swap') once the package re-exports it,
update any import references accordingly, and run type-check/build to ensure the
alias resolves and no other files rely on the deep path.
There was a problem hiding this comment.
Actionable comments posted: 3
♻️ Duplicate comments (2)
packages/swap/src/providers/oneInchFusion/index.ts (2)
256-261: Guard gasLimit when summing totalGaslimit (duplicate from prior review).gasLimit can be undefined in quote path; toBN(undefined) throws.
- totalGaslimit: res.transactions.reduce( - (total: number, curVal: EVMTransaction) => - total + toBN(curVal.gasLimit).toNumber(), - 0, - ), + totalGaslimit: res.transactions.reduce((total: number, curVal: EVMTransaction) => { + const gl = curVal.gasLimit ?? "0"; + return total + toBN(gl).toNumber(); + }, 0),
74-92: init(): return type mismatch with implementation (duplicate from prior review).The method is declared Promise but is synchronous and never returns a Promise. Make it async (preferred) or change return type to void.
- init(tokenList: TokenType[]): Promise<void> { + async init(tokenList: TokenType[]): Promise<void> { if (!OneInchFusion.isSupported(this.network)) return; this.fusionSdk = new FusionSDK({ network: Number(supportedNetworks[this.network].chainId), url: "https://fusion.1inch.io", }); tokenList.forEach((t) => { this.fromTokens[t.address] = t; if (!this.toTokens[this.network]) this.toTokens[this.network] = {}; this.toTokens[this.network][t.address] = { ...t, networkInfo: { name: this.network, isAddress: (address: string) => Promise.resolve(isEVMAddress(address)), }, }; }); }
🧹 Nitpick comments (6)
packages/swap/src/providers/oneInchFusion/index.ts (6)
74-92: Persist the provided tokenList.You have a tokenList field, but init() never assigns it.
async init(tokenList: TokenType[]): Promise<void> { if (!OneInchFusion.isSupported(this.network)) return; + this.tokenList = tokenList; this.fusionSdk = new FusionSDK({ network: Number(supportedNetworks[this.network].chainId), url: "https://fusion.1inch.io", });
117-129: Guard against uninitialized fusionSdk.If init() wasn’t called (or early-returned for unsupported), this.fusionSdk is undefined and calls below will throw.
private getOneInchSwap( options: getQuoteOptions, meta: QuoteMetaOptions, accurateEstimate: boolean, ): Promise<OneInchSwapResponse | null> { + if (!this.fusionSdk) return Promise.resolve(null);
207-218: Safer gas-limit application; handle type/length mismatches.estimateEVMGasList.result may be shorter or contain non-strings. Current code blindly indexes and assigns.
if (accurateGasEstimate) { if (accurateGasEstimate.isError) return null; - transactions.forEach((tx, idx) => { - tx.gasLimit = accurateGasEstimate.result[idx]; - }); + transactions.forEach((tx, idx) => { + const gl = accurateGasEstimate.result[idx]; + if (!gl) return; + tx.gasLimit = typeof gl === "string" ? gl : String(gl); + }); }
318-326: Harden submitRFQOrder parsing and error handling.JSON.parse on orderStruct can throw; add validation and clearer errors.
- const relayRequest = RelayerRequest.new({ - order: JSON.parse((options as any).orderStruct), + let orderObj; + try { + orderObj = JSON.parse((options as any).orderStruct); + } catch { + throw new Error("OneInchFusion: Invalid orderStruct JSON"); + } + const relayRequest = RelayerRequest.new({ + order: orderObj, extension: (options as any).extension, quoteId: (options as any).quoteId, signature: options.signatures[0], });
233-237: Replace generic console.error with structured logging or remove."herere" is not actionable; prefer a scoped logger with error context or surface the error to caller.
- .catch((e) => { - console.error(e, "herere"); - return null; - }); + .catch(() => null);
108-115: Action: Clarify/adjust min order handling — don’t treat 1 wei as a guaranteed usable minimum.File: packages/swap/src/providers/oneInchFusion/index.ts (lines 108–115)
- Fusion/RFQ has no protocol‑enforced per‑chain minimum (on‑chain limit = token integer unit/decimals), but resolvers/quoter/market‑makers often refuse to quote or fill very small orders.
- Recommend: compute a practical min from token decimals or query the Quoter/resolvers to determine a user‑facing minimum; add handling for quoter failures (e.g., 400 / inability to quote) and surface a clear UX message instead of silently accepting 1 wei.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
yarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (3)
packages/swap/package.json(1 hunks)packages/swap/src/configs.ts(2 hunks)packages/swap/src/providers/oneInchFusion/index.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- packages/swap/src/configs.ts
- packages/swap/package.json
🧰 Additional context used
🧬 Code graph analysis (1)
packages/swap/src/providers/oneInchFusion/index.ts (6)
packages/swap/src/types/index.ts (12)
TokenType(49-60)MinMaxResponse(205-210)getQuoteOptions(143-149)QuoteMetaOptions(107-114)EVMTransaction(163-170)ProviderQuoteResponse(218-230)SwapQuote(212-216)ProviderSwapResponse(259-276)RFQOptionsResponse(254-257)StatusOptions(244-247)StatusOptionsResponse(249-252)RFQOptions(239-242)packages/swap/src/providers/oneInch/index.ts (1)
supportedNetworks(39-82)packages/swap/src/utils/common.ts (1)
isEVMAddress(13-19)packages/swap/src/utils/approvals.ts (4)
TOKEN_AMOUNT_INFINITY_AND_BEYOND(8-9)getAllowanceTransactions(171-171)isSufficientWrappedAvailable(174-174)getNativeWrapTx(173-173)packages/swap/src/providers/oneInchFusion/types.ts (1)
OneInchSwapResponse(3-12)packages/swap/src/configs.ts (3)
NATIVE_TOKEN_ADDRESS(144-144)FEE_CONFIGS(142-142)DEFAULT_SLIPPAGE(148-148)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: buildAll
- GitHub Check: test
- GitHub Check: test
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (2)
packages/extension/src/ui/action/views/swap/views/swap-best-offer/index.vue (2)
434-450: Do not JSON.parse the signature; use the hex string directly.
EvmTypedMessageSignerreturns a hex string. Parsing can throw.- const typedMessageSigs: string[] = []; + const typedMessageSigs: string[] = []; + let rfqOrderHash: string | undefined; ... - if (sig.error) return Promise.reject(sig.error); - typedMessageSigs.push(JSON.parse(sig.result!)); + if (sig.error) return Promise.reject(sig.error); + typedMessageSigs.push(sig.result as string);
460-466: Use the returned RFQ orderHash and guard rfqOptions access.Avoid non‑null assertions; capture and use the actual hash returned by submitRFQOrder for activity logging. Optionally hydrate rfqOptions.
- const orderHash = await swap.value!.submitRFQOrder({ + rfqOrderHash = await swap.value!.submitRFQOrder({ options: { - ...pickedTrade.value.rfqOptions!.options, + ...(pickedTrade.value.rfqOptions?.options || {}), signatures: typedMessageSigs, }, - provider: pickedTrade.value.rfqOptions!.provider, + provider: pickedTrade.value.rfqOptions?.provider || pickedTrade.value.provider, }); - console.log(orderHash); + // Optional: hydrate for downstream consumers + pickedTrade.value.rfqOptions = { + provider: pickedTrade.value.provider, + options: { + ...(pickedTrade.value.rfqOptions?.options || {}), + orderHash: rfqOrderHash!, + }, + } as any; ... - transactionHash: `${pickedTrade.value.type === SwapType.regular ? txs[0].hash : pickedTrade.value.rfqOptions!.options.orderHash}-swap`, + transactionHash: `${ + pickedTrade.value.type === SwapType.regular + ? txs[0].hash + : (rfqOrderHash || pickedTrade.value.rfqOptions?.options.orderHash) + }-swap`,Also applies to: 499-499
🧹 Nitpick comments (5)
packages/extension/src/ui/action/views/swap-initiated/index.vue (2)
27-33: Polish copy; add a11y live region.Minor grammar fix and make the status update screen‑reader friendly.
- <p v-if="waitingToBeMined"> - Waiting for Transactions to be mined, this can take upto 30 - seconds + <p v-if="waitingToBeMined" aria-live="polite"> + Waiting for transactions to be mined. This can take up to ~30 seconds. </p>
98-101: Default the new prop to avoid regressions where it isn’t passed.Make the prop optional with a sane default to prevent runtime “missing required prop” in other call sites.
interface IProps { ... - waitingToBeMined: boolean; + waitingToBeMined?: boolean; ... } -defineProps<IProps>(); +const props = withDefaults(defineProps<IProps>(), { + waitingToBeMined: false, +});Also applies to: 108-114
packages/extension/src/ui/action/views/swap/views/swap-best-offer/index.vue (3)
269-269: Remove leftover debug log.Console noise in hot paths hurts UX and privacy.
- console.log(trade);
410-411: Guard optional transactions to avoid NPE.If transactions is undefined,
.lengththrows.- (gasTier.nativeValue === '0' && pickedTrade.value.transactions.length) + (gasTier.nativeValue === '0' && (pickedTrade.value.transactions?.length ?? 0))
453-461: Trim noisy logs; rethrow original error.Drop debug prints and avoid wrapping errors with
new Error(e)which loses stack/context.- console.log('starting wait'); await waitForReceipt( txs.map(tx => tx.hash), network.value!, 30, ); - console.log('wait done'); ... - } catch (e: any) { - throw new Error(e); + } catch (e: any) { + throw e; } finally {Also applies to: 469-471
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/extension/src/ui/action/views/swap-initiated/index.vue(2 hunks)packages/extension/src/ui/action/views/swap/views/swap-best-offer/index.vue(9 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: buildAll
- GitHub Check: test
- GitHub Check: test
🔇 Additional comments (4)
packages/extension/src/ui/action/views/swap/views/swap-best-offer/index.vue (4)
96-99: Prop wiring LGTM.Passing waiting‑to‑be‑mined through to SwapInitiated looks correct.
216-218: State additions LGTM.Separate refs for waitingToBeMined and swap are clear.
319-326: Confirm Swap API initialization; avoid{}cast.Starting Swap with
api: {} as anyrisks runtime failures later (e.g., submitRFQOrder). Wire the real API/client or a factory.Do we have a shared Swap API instance or factory in this repo? If yes, use it here; otherwise, expose one from @enkryptcom/swap and inject it.
454-458: Verify wait duration semantics.UI copy says “~30 seconds”; confirm the 3rd arg to waitForReceipt is seconds (not attempts/ms) to keep UX consistent.
packages/extension/src/ui/action/views/swap/views/swap-best-offer/index.vue
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (7)
packages/swap/src/providers/oneInchFusion/index.ts (7)
119-124: Guard against using SDK before init().Avoid runtime errors if a caller forgets to call init().
private getOneInchSwap( options: getQuoteOptions, meta: QuoteMetaOptions, accurateEstimate: boolean, ): Promise<OneInchSwapResponse | null> { + if (!this.fusionSdk) throw new Error("OneInchFusion: init() must be called before use");
214-219: Defensive mapping of gas estimates.Avoid out-of-bounds when result length differs; only set when present.
- if (accurateGasEstimate) { - if (accurateGasEstimate.isError) return null; - transactions.forEach((tx, idx) => { - tx.gasLimit = accurateGasEstimate.result[idx]; - }); - } + if (accurateGasEstimate) { + if (accurateGasEstimate.isError) return null; + transactions.forEach((tx, idx) => { + const gl = accurateGasEstimate.result[idx]; + if (gl) tx.gasLimit = gl; + }); + }
237-240: Improve error logging; remove placeholder.- .catch((e) => { - console.error(e, "herere"); - return null; - }); + .catch((e) => { + console.error("OneInchFusion.getOneInchSwap failed", e); + return null; + });
251-258: Compute $10 minimum safely (BigNumber, zero-guard).- const fromToken = new SwapToken(options.fromToken); - const minFrom = fromToken.toRaw( - new BigNumber(1) - .div(Number(fromUSDValue) / 10) - .toFixed(fromToken.token.decimals), - ); // minimum $10 worth of tokens - minMax.minimumFrom = minFrom; + const fromToken = new SwapToken(options.fromToken); + const priceUsd = new BigNumber(fromUSDValue || 0); + if (priceUsd.lte(0)) { + minMax.minimumFrom = toBN("1"); + } else { + const minFromHuman = new BigNumber(10).div(priceUsd); // $10 / price + minMax.minimumFrom = fromToken.toRaw( + minFromHuman.toFixed(fromToken.token.decimals), + ); + }
259-259: Drop noisy debug log.- console.log(`min from: ${minMax}`);
316-317: Guard getStatus against uninitialized SDK.- getStatus(options: StatusOptions): Promise<TransactionStatus> { - return this.fusionSdk.getOrderStatus(options.orderHash).then((status) => { + getStatus(options: StatusOptions): Promise<TransactionStatus> { + if (!this.fusionSdk) throw new Error("OneInchFusion: init() must be called before use"); + return this.fusionSdk.getOrderStatus(options.orderHash).then((status) => {
328-337: Guard submitRFQOrder against uninitialized SDK.submitRFQOrder(options: RFQOptions): Promise<string> { + if (!this.fusionSdk) throw new Error("OneInchFusion: init() must be called before use"); if (!options.signatures || !options.signatures.length) throw new Error("OneInchFusion: No signatures found");
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/swap/src/providers/oneInchFusion/index.ts(1 hunks)packages/swap/src/providers/oneInchFusion/types.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/swap/src/providers/oneInchFusion/types.ts
🧰 Additional context used
🧬 Code graph analysis (1)
packages/swap/src/providers/oneInchFusion/index.ts (5)
packages/swap/src/types/index.ts (14)
TokenType(49-60)ProviderFromTokenResponse(278-278)ProviderToTokenResponse(280-282)MinMaxResponse(205-210)getQuoteOptions(143-149)QuoteMetaOptions(107-114)EVMTransaction(163-170)ProviderQuoteResponse(218-230)SwapQuote(212-216)ProviderSwapResponse(259-276)RFQOptionsResponse(254-257)StatusOptions(244-247)StatusOptionsResponse(249-252)RFQOptions(239-242)packages/swap/src/providers/oneInch/index.ts (1)
supportedNetworks(39-82)packages/swap/src/utils/common.ts (1)
isEVMAddress(13-19)packages/swap/src/utils/approvals.ts (4)
TOKEN_AMOUNT_INFINITY_AND_BEYOND(8-9)getAllowanceTransactions(171-171)isSufficientWrappedAvailable(174-174)getNativeWrapTx(173-173)packages/swap/src/providers/oneInchFusion/types.ts (1)
OneInchSwapResponse(3-13)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: buildAll
🔇 Additional comments (5)
packages/swap/src/providers/oneInchFusion/index.ts (5)
270-274: Guard against undefined gasLimit when accurateEstimate=false.- totalGaslimit: res.transactions.reduce( - (total: number, curVal: EVMTransaction) => - total + toBN(curVal.gasLimit).toNumber(), - 0, - ), + totalGaslimit: res.transactions.reduce((total: number, curVal: EVMTransaction) => { + const gl = curVal.gasLimit ?? "0"; + return total + toBN(gl).toNumber(); + }, 0),
76-94: init() signature says Promise but never returns a Promise. Make it async.- init(tokenList: TokenType[]): Promise<void> { + async init(tokenList: TokenType[]): Promise<void> { if (!OneInchFusion.isSupported(this.network)) return; this.fusionSdk = new FusionSDK({ network: Number(supportedNetworks[this.network].chainId), url: "https://fusion.1inch.io", }); tokenList.forEach((t) => { this.fromTokens[t.address] = t; if (!this.toTokens[this.network]) this.toTokens[this.network] = {}; this.toTokens[this.network][t.address] = { ...t, networkInfo: { name: this.network, isAddress: (address: string) => Promise.resolve(isEVMAddress(address)), }, }; }); + return; }
169-177: Remove PII-heavy debug log (addresses, slippage).- console.log({ - ...quoteParams, - preset: quote.recommendedPreset, - walletAddress: options.fromAddress, - receiver: options.toAddress, - slippage: meta.slippage - ? Number(meta.slippage) - : Number(DEFAULT_SLIPPAGE), - });
284-296: Optional chain FEE_CONFIGS in swap response to avoid crashes.- const feeConfig = - FEE_CONFIGS[this.name][quote.meta.walletIdentifier].fee || 0; + const feeBps = + FEE_CONFIGS[this.name]?.[quote.meta.walletIdentifier]?.fee ?? 0; const response: ProviderSwapResponse = { fromTokenAmount: res.fromTokenAmount, provider: this.name, type: SwapType.rfq, toTokenAmount: res.toTokenAmount, transactions: res.transactions, typedMessages: res.typedMessages, additionalNativeFees: toBN(0), slippage: quote.meta.slippage || DEFAULT_SLIPPAGE, - fee: feeConfig / 100, + fee: feeBps / 100,
329-329: Do not log RFQ options; signatures are sensitive.- console.log(options); + // Avoid logging RFQ options (may include signatures and EIP-712 data)
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (4)
packages/swap/tests/oneInchFusion.test.ts (3)
51-57: Don’t hardcode the spender; assert method selector and amount only.For Fusion, spender should be the LOP/Fusion contract (not the Aggregation Router). Avoid brittle address assertions.
- expect(swap?.transactions[0].to).to.be.eq(fromToken.address); - expect((swap?.transactions[0] as EVMTransaction).data).to.be.eq( - `0x095ea7b3000000000000000000000000${ONEINCH_APPROVAL_ADDRESS.replace( - "0x", - "", - )}${TOKEN_AMOUNT_INFINITY_AND_BEYOND.replace("0x", "")}`, - ); + expect(swap?.transactions[0].to).to.be.eq(fromToken.address); + const data = (swap?.transactions[0] as EVMTransaction).data; + // approve(address,uint256) + expect(data.slice(0, 10)).to.be.eq("0x095ea7b3"); + // Amount = max uint256 + expect(data.endsWith(TOKEN_AMOUNT_INFINITY_AND_BEYOND.replace("0x", ""))).to.be.eq(true);
78-85: Avoid brittle ABI encoding in assertions; pad amount programmatically.Use hex padding instead of hardcoding zeros.
- expect((swap?.transactions[0] as EVMTransaction).data).to.be.eq( - `0x095ea7b3000000000000000000000000${ONEINCH_APPROVAL_ADDRESS.replace( - "0x", - "", - )}00000000000000000000000000000000000000000000000${numberToHex( - amount, - ).replace("0x", "")}`, - ); + const data = (swap?.transactions[0] as EVMTransaction).data; + expect(data.slice(0, 10)).to.be.eq("0x095ea7b3"); + const amountHex = numberToHex(amount).replace("0x", ""); + expect(data.endsWith(amountHex.padStart(64, "0"))).to.be.eq(true);
22-27: Avoid async describe; it’s not awaited and can mislead.Remove async; keep tests async inside
it(...).-describe("OneInchFusion Provider", async () => { +describe("OneInchFusion Provider", () => {packages/swap/src/providers/oneInchFusion/index.ts (1)
228-231: Tighten error log message (avoid stray “herere”).Keep logs useful and non-noisy.
- .catch((e) => { - console.error(e, "herere"); - return null; - }); + .catch((e) => { + console.error("OneInchFusion.getOneInchSwap error:", e); + return null; + });
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/swap/src/providers/oneInchFusion/index.ts(1 hunks)packages/swap/tests/oneInchFusion.test.ts(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
packages/swap/src/providers/oneInchFusion/index.ts (6)
packages/swap/src/types/index.ts (14)
TokenType(49-60)ProviderFromTokenResponse(278-278)ProviderToTokenResponse(280-282)MinMaxResponse(205-210)getQuoteOptions(143-149)QuoteMetaOptions(107-114)EVMTransaction(163-170)ProviderQuoteResponse(218-230)SwapQuote(212-216)ProviderSwapResponse(259-276)RFQOptionsResponse(254-257)StatusOptions(244-247)StatusOptionsResponse(249-252)RFQOptions(239-242)packages/swap/src/providers/oneInch/index.ts (1)
supportedNetworks(39-82)packages/swap/src/utils/common.ts (1)
isEVMAddress(13-19)packages/swap/src/utils/approvals.ts (1)
TOKEN_AMOUNT_INFINITY_AND_BEYOND(8-9)packages/swap/src/providers/oneInchFusion/types.ts (1)
OneInchSwapResponse(3-13)packages/swap/src/configs.ts (3)
NATIVE_TOKEN_ADDRESS(144-144)FEE_CONFIGS(142-142)DEFAULT_SLIPPAGE(148-148)
packages/swap/tests/oneInchFusion.test.ts (3)
packages/swap/src/types/index.ts (1)
EVMTransaction(163-170)packages/swap/src/providers/oneInch/index.ts (1)
ONEINCH_APPROVAL_ADDRESS(37-38)packages/swap/src/utils/approvals.ts (1)
TOKEN_AMOUNT_INFINITY_AND_BEYOND(8-9)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: buildAll
🔇 Additional comments (8)
packages/swap/tests/oneInchFusion.test.ts (1)
50-50: Allow variable tx count (don’t assert exactly 1).Fusion flows can require 1+ on-chain txs (approval only, or wrap+approval). Use ≥1.
- expect(swap?.transactions.length).to.be.eq(1); + expect(swap?.transactions.length).to.be.gte(1);Also applies to: 77-77
packages/swap/src/providers/oneInchFusion/index.ts (7)
138-138: Guard fee config access to prevent crashes when path is missing.- const feeConfig = FEE_CONFIGS[this.name][meta.walletIdentifier]; + const feeConfig = FEE_CONFIGS[this.name]?.[meta.walletIdentifier];
139-148: Guard CHAIN_TO_WRAPPER and reuse a local var.Avoid
.toString()on possibly undefined and repeated lookups.- const chainId = Number(supportedNetworks[this.network].chainId); - const quoteParams: QuoteParams = { + const chainId = Number(supportedNetworks[this.network].chainId); + const wrapper = CHAIN_TO_WRAPPER[chainId]; + if (isFromNative && !wrapper) return Promise.resolve(null); + const quoteParams: QuoteParams = { amount: options.amount.toString(), - fromTokenAddress: isFromNative - ? CHAIN_TO_WRAPPER[chainId].toString() - : options.fromToken.address, + fromTokenAddress: isFromNative ? wrapper.toString() : options.fromToken.address, toTokenAddress: options.toToken.address, enableEstimate: false, isPermit2: false, };
176-196: Reuse guarded wrapper in native wrap paths.Avoid unsafe
CHAIN_TO_WRAPPER[chainId].toString()calls.- fromToken: isFromNative - ? { address: CHAIN_TO_WRAPPER[chainId].toString() } - : options.fromToken, + fromToken: isFromNative ? { address: wrapper!.toString() } : options.fromToken,- contract: CHAIN_TO_WRAPPER[chainId].toString(), + contract: wrapper!.toString(), value: options.amount,- contract: CHAIN_TO_WRAPPER[chainId].toString(), + contract: wrapper!.toString(), value: options.amount,
259-263: Guard undefined gasLimit when accurateEstimate is false.Quotes may not have gas limits yet; summing undefined throws.
- totalGaslimit: res.transactions.reduce( - (total: number, curVal: EVMTransaction) => - total + toBN(curVal.gasLimit).toNumber(), - 0, - ), + totalGaslimit: res.transactions.reduce((total: number, curVal: EVMTransaction) => { + const gl = curVal.gasLimit ?? "0"; + return total + toBN(gl).toNumber(); + }, 0),
273-285: Fee config path can be undefined; use optional chaining + default.Prevent runtime errors and use a sane default.
- const feeConfig = - FEE_CONFIGS[this.name][quote.meta.walletIdentifier].fee || 0; + const feeBps = + FEE_CONFIGS[this.name]?.[quote.meta.walletIdentifier]?.fee ?? 0; const response: ProviderSwapResponse = { fromTokenAmount: res.fromTokenAmount, provider: this.name, type: SwapType.rfq, toTokenAmount: res.toTokenAmount, transactions: res.transactions, typedMessages: res.typedMessages, additionalNativeFees: toBN(0), slippage: quote.meta.slippage || DEFAULT_SLIPPAGE, - fee: feeConfig / 100, + fee: feeBps / 100,Confirm if
feeexpects ratio (0–1) or percent. If it’s ratio, dividing bps by 100 is off by 100x; it should bebps / 10_000.#!/bin/bash rg -nP --type=ts -C2 'interface\s+ProviderSwapResponse\b' packages/swap/src/types/index.ts rg -nP --type=ts -C2 '\bfee:\s*number' packages/swap/src/types/index.ts
76-94: init() signature mismatch (declares Promise but returns synchronously).Align the signature to avoid type errors and callers awaiting a non-promise.
- init(tokenList: TokenType[]): Promise<void> { + init(tokenList: TokenType[]): void { if (!OneInchFusion.isSupported(this.network)) return; this.fusionSdk = new FusionSDK({ network: Number(supportedNetworks[this.network].chainId), url: "https://fusion.1inch.io", }); tokenList.forEach((t) => { this.fromTokens[t.address] = t; if (!this.toTokens[this.network]) this.toTokens[this.network] = {}; this.toTokens[this.network][t.address] = { ...t, networkInfo: { name: this.network, isAddress: (address: string) => Promise.resolve(isEVMAddress(address)), }, }; }); }Run to find any callers that
awaitinit():#!/bin/bash rg -nP --type=ts -C2 '\bawait\s+\w+\.init\s*\('
64-64: Definite assignment for fusionSdk.Initialize or mark as definite to satisfy strictPropertyInitialization.
- fusionSdk: FusionSDK; + fusionSdk!: FusionSDK;
Summary by CodeRabbit
New Features
Improvements
Changes