Skip to content

Conversation

@nakul1010
Copy link
Contributor

@nakul1010 nakul1010 commented Nov 6, 2025

📝 PR Description

  • Added support for creating orders on the V2 Offramp Registry.
  • Enabled bump fee and unlock order functionality for both V1 and V2 registries.
  • Replaced on-chain order detail fetching with API-based fetching for improved reliability and performance.

Summary by CodeRabbit

  • New Features

    • Affiliate fee support for offramp orders — specify affiliate recipient and fee when creating orders
    • Versioned offramp (V2) with user-visible operations to bump order fee and request refunds
  • Improvements

    • Quotes and orders now include affiliate data, solver fee, registry version, bump tracking, and user address
    • Order retrieval and lifecycle use API-backed registry data (no direct on-chain order reads)
  • Tests

    • Updated tests to validate affiliate flows, new order shape, and registry/version behavior

@nakul1010 nakul1010 self-assigned this Nov 6, 2025
@vercel
Copy link

vercel bot commented Nov 6, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
bob-docs Ready Ready Preview Comment Nov 14, 2025 1:08pm

@nakul1010 nakul1010 marked this pull request as draft November 6, 2025 10:58
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @nakul1010, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a comprehensive set of changes to the SDK to facilitate the integration of Offramp V2. The modifications primarily involve updating the data structures for offramp quotes and orders, refactoring the methods for fetching and processing order details to leverage a new API endpoint, and streamlining the way offramp registry addresses are resolved. These updates ensure compatibility with the new Offramp V2 contract, enhance the flexibility of fee handling, and improve the efficiency of order management within the SDK.

Highlights

  • Offramp V2 Integration: The SDK has been updated to support Offramp V2, introducing new parameters for affiliate fees and modifying the structure of offramp orders to align with the new contract version.
  • API-Driven Order Details Fetching: Offramp order details are now retrieved from a dedicated API endpoint instead of directly from on-chain contract calls, streamlining data access and processing.
  • Simplified Registry Address Retrieval: The method for obtaining the offramp registry address has been refactored to directly return a hardcoded address based on the chain ID, eliminating a previous API call.
  • ABI and Interface Updates: The offrampCaller ABI has been modified to include new fee parameters (satSolverFeeMax, satAffiliateFee, affiliateFeeRecipient) and the getOrderDetails function has been removed. Corresponding SDK interfaces (OfframpQuote, OfframpCreateOrderParams, OfframpOrder, OfframpRawOrder, BumpFeeParams, UnlockOrderParams) have been updated to reflect these changes.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 6, 2025

Warning

Rate limit exceeded

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

⌛ How to resolve this issue?

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

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 31db3e5 and a352dbe.

📒 Files selected for processing (2)
  • sdk/src/gateway/client.ts (15 hunks)
  • sdk/src/gateway/utils/common.ts (1 hunks)

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Introduces a versioned offramp ABI (offrampCallerV2) with affiliate-fee fields, renames and adds V2 contract calls (createOrderV2, bumpFeeOfExistingOrder, refundOrder), moves order retrieval to the API with mapRawOrderToOfframpOrder, updates client/types/quotes to carry affiliate and registry data, and removes old on-chain status parsing/getOrderDetails.

Changes

Cohort / File(s) Change Summary
ABI (versioning)
sdk/src/gateway/abi.ts
Added offrampCallerV2 export; renamed/changed createOrdercreateOrderV2 with satSolverFeeMax, satAffiliateFee, affiliateFeeRecipient; added bumpFeeOfExistingOrder and refundOrder; removed old getOrderDetails.
Client: mapping & flow updates
sdk/src/gateway/client.ts
Switched ABI import to offrampCallerV2; added mapRawOrderToOfframpOrder(); fetchOfframpOrder now queries API and maps raw order; create/bump/unlock flows updated to use V2 ABI and include affiliate and registryAddress fields; removed parseOrderStatus and eliminated some on-chain reads.
Types: offramp
sdk/src/gateway/types/offramp.ts
Import updated to offrampCallerV2; OfframpQuote now includes affiliateFeeRecipient; renamed satFeesMaxsatSolverFeeMax; added satAffiliateFee, affiliateFeeRecipient, offrampRegistryVersion, bumpFeeAmountInSats, userAddress; OfframpRawOrder expanded with registry/affiliate fields; BumpFeeParams/UnlockOrderParams now include offrampRegistryAddress.
Types: quote
sdk/src/gateway/types/quote.ts
Imported Address from viem; GatewayQuoteParams now accepts affiliateFeeSats? and affiliateFeeRecipient?.
Tests
sdk/test/gateway.test.ts
Updated mocks/assertions to reflect OfframpRawOrder additions and changed shapes; tests now call mapRawOrderToOfframpOrder(...); updated quote payloads to include affiliate fields and registry-address retrieval adjustments.
Utilities
sdk/src/gateway/utils/common.ts
Removed exported STATUSES constant and parseOrderStatus() function.
LayerZero
sdk/src/gateway/layerzero.ts
Added OFFRAMP_COMPOSER constant and replaced hardcoded composer address usages with it.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant User
    participant SDK as Gateway SDK
    participant API as Offramp API
    participant Mapper as Order Mapper

    User->>SDK: fetchOfframpOrder(orderId, registryAddress?)
    SDK->>API: GET /orders?orderId&registryAddress
    API-->>SDK: OfframpRawOrder
    SDK->>Mapper: mapRawOrderToOfframpOrder(OfframpRawOrder)
    Mapper-->>SDK: OfframpOrder (affiliate fields, registryVersion, unlockable)
    SDK-->>User: OfframpOrder
Loading
sequenceDiagram
    autonumber
    participant User
    participant SDK as Gateway SDK
    participant Registry as Registry Resolver
    participant API as Offramp API

    User->>SDK: fetchOfframpQuote(..., affiliateFeeRecipient?)
    SDK->>Registry: getTargetOfframpRegistryAddress(chainId)
    Registry-->>SDK: registryAddress
    SDK->>API: request quote (affiliate_fee, affiliateFeeRecipient)
    API-->>SDK: OfframpQuote
    SDK-->>User: OfframpQuote
Loading
sequenceDiagram
    autonumber
    participant User
    participant SDK as Gateway SDK
    participant ABI as ABI Descriptor
    participant Chain as Chain/Contract

    User->>SDK: createOfframpOrderV2(args...)
    SDK->>ABI: use offrampCallerV2 descriptor
    SDK->>Chain: writeContract.createOrderV2(args: satSolverFeeMax, satAffiliateFee, affiliateFeeRecipient, ...)
    Chain-->>SDK: txReceipt
    SDK-->>User: txReceipt
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • Focus areas:
    • mapRawOrderToOfframpOrder: numeric/string parsing, nullable fields, unlockable logic.
    • ABI changes: argument names/order for createOrderV2, bumpFeeOfExistingOrder, refundOrder.
    • Ensure consistency of affiliate fields across quote, order, create, bump, unlock flows.
    • RegistryAddress propagation into bump/unlock and fetch flows.
    • Verify removal of parseOrderStatus/getOrderDetails and no residual on-chain reads where API mapping is intended.

Possibly related PRs

Suggested reviewers

  • danielsimao
  • slavastartsev
  • gregdhill

Poem

🐇 I hop through ABI fields anew,

I nibble fees and map each view.
Registry, affiliate—lined in a row,
I stitch raw orders, tidy and slow.
Hooray, V2 — the rabbit says "let's go!" 🎉

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: SDK changes Offramp V2' is directly related to the main changes in the changeset, which focus on migrating from Offramp V1 to V2 with comprehensive ABI updates and new functionality.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

❤️ Share

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

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces significant changes for the Offramp V2 SDK, including support for affiliate fees, refactoring order detail fetching to use an API instead of direct contract calls, and simplifying fee bump logic on the client side. The changes are well-structured and align with the goal of a V2 upgrade. My review includes a few suggestions to improve robustness and test reliability, such as enhancing type safety when parsing API responses and addressing issues in the test suite related to mock data and unmocked network calls. Overall, this is a solid step forward for the SDK.

…eat/offramp-v2

# Conflicts:
#	sdk/src/gateway/client.ts
@nakul1010 nakul1010 marked this pull request as ready for review November 11, 2025 06:49
@nakul1010 nakul1010 changed the title (WIP)feat: SDK changes Offramp V2 feat: SDK changes Offramp V2 Nov 11, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
sdk/src/gateway/client.ts (1)

199-228: Type assertions bypass TypeScript safety.

As noted in a previous review, this function uses multiple type assertions (order.status as OfframpOrderStatus, order.offrampRegistryAddress as Address, etc.) which can lead to runtime errors if the API returns unexpected data.

Consider using Zod or custom type guards to validate the API response at runtime:

import { z } from 'zod';

const OfframpRawOrderSchema = z.object({
    orderId: z.string(),
    token: z.string().refine(isAddress),
    status: z.enum(['Active', 'Accepted', 'Processed', 'Refunded']),
    offrampRegistryAddress: z.string().refine(isAddress),
    // ... other fields
});

public async mapRawOrderToOfframpOrder(order: OfframpRawOrder): Promise<OfframpOrder> {
    const validated = OfframpRawOrderSchema.parse(order); // Throws if invalid
    // Now TypeScript knows the types are correct
    ...
}
🧹 Nitpick comments (2)
sdk/src/gateway/client.ts (2)

195-197: Consider adding version validation.

The method defaults to V2 for any version other than 1. While this may be intentional (forward compatibility), it could mask bugs if an invalid version is passed.

Consider adding a check:

 private getOfframpAbi(version: number) {
-    return version === 1 ? offrampCallerV1 : offrampCallerV2;
+    if (version === 1) return offrampCallerV1;
+    if (version === 2) return offrampCallerV2;
+    throw new Error(`Unsupported offramp registry version: ${version}`);
 }

536-590: LGTM with minor naming inconsistency.

The affiliate fee handling is correct, with proper validation and normalization to zeroAddress when not provided. Note that the parameter is named affiliate_fee (line 542) here but affiliateFeeSats in GatewayQuoteParams (line 52 of quote.ts) - consider standardizing the naming for consistency.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 57948e2 and 112246c.

📒 Files selected for processing (5)
  • sdk/src/gateway/abi.ts (2 hunks)
  • sdk/src/gateway/client.ts (17 hunks)
  • sdk/src/gateway/types/offramp.ts (7 hunks)
  • sdk/src/gateway/types/quote.ts (2 hunks)
  • sdk/test/gateway.test.ts (9 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-06-17T11:18:53.195Z
Learnt from: slavastartsev
Repo: bob-collective/bob PR: 634
File: sdk/src/gateway/client.ts:136-140
Timestamp: 2025-06-17T11:18:53.195Z
Learning: The codebase has a requirement not to introduce discriminated unions in the Gateway SDK client methods, including the getQuote method return types in sdk/src/gateway/client.ts.

Applied to files:

  • sdk/src/gateway/types/quote.ts
  • sdk/test/gateway.test.ts
  • sdk/src/gateway/types/offramp.ts
  • sdk/src/gateway/client.ts
🧬 Code graph analysis (3)
sdk/test/gateway.test.ts (1)
sdk/src/gateway/types/offramp.ts (1)
  • OfframpRawOrder (148-165)
sdk/src/gateway/types/offramp.ts (1)
sdk/src/gateway/abi.ts (1)
  • offrampCallerV2 (80-172)
sdk/src/gateway/client.ts (2)
sdk/src/gateway/abi.ts (2)
  • offrampCallerV1 (41-78)
  • offrampCallerV2 (80-172)
sdk/src/gateway/types/offramp.ts (5)
  • OfframpRawOrder (148-165)
  • OfframpOrder (86-121)
  • OfframpOrderStatus (13-13)
  • BumpFeeParams (173-176)
  • UnlockOrderParams (178-182)
🪛 Gitleaks (8.29.0)
sdk/test/gateway.test.ts

[high] 691-691: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

⏰ 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: test
🔇 Additional comments (15)
sdk/src/gateway/types/quote.ts (1)

1-1: LGTM! Clean addition of affiliate fee support.

The import of Address and the two new optional fields (affiliateFeeSats and affiliateFeeRecipient) are well-typed and maintain backward compatibility.

Also applies to: 51-54

sdk/src/gateway/abi.ts (2)

41-78: LGTM! V1 ABI correctly defines bump and refund operations.

The ABI definition for offrampCallerV1 is properly structured with the necessary functions for fee bumping and order refunds.


80-172: LGTM! V2 ABI properly extends functionality with affiliate support.

The V2 ABI includes the enhanced createOrder function with satSolverFeeMax, satAffiliateFee, and affiliateFeeRecipient fields. Note that bumpFeeOfExistingOrder and refundOrder are duplicated between V1 and V2, which is acceptable for versioning but means both ABIs need updates if these functions change.

sdk/test/gateway.test.ts (4)

658-680: LGTM! Test properly validates V2 order creation.

The test correctly validates the new affiliate fee fields (satSolverFeeMax, satAffiliateFee, affiliateFeeRecipient) in the offramp order creation flow.


688-722: LGTM! Test correctly uses the new mapping function.

The test properly constructs a mock OfframpRawOrder with all new fields and uses mapRawOrderToOfframpOrder to validate the transformation. The previous issue with field naming (evmTx vs refundedEvmTx) appears to be resolved.


739-745: LGTM! Test reflects the new static registry address approach.

The test correctly validates that getOfframpRegistryAddress() returns the expected testnet registry address without requiring an API call.


964-965: Test skipped pending V2 contract deployment.

This test for offramp gas cost estimation is appropriately skipped until the V2 Offramp Registry contracts are deployed to mainnet and testnet. The TODO comment aligns with similar TODOs in sdk/src/gateway/client.ts lines 95 and 100.

Please ensure this test is re-enabled once the V2 contracts are deployed and the registry addresses are updated.

sdk/src/gateway/types/offramp.ts (3)

2-2: LGTM! Type definitions properly migrated to V2.

The import change to offrampCallerV2 and the update to OfframpQuote (adding affiliateFeeRecipient, removing registryAddress) correctly reflect the V2 API changes. The registry address is now handled separately at the call site level.

Also applies to: 43-44, 61-61


68-72: LGTM! Well-documented field additions for V2.

The new fields in OfframpCreateOrderParams and OfframpOrder are properly documented:

  • satSolverFeeMax (renamed from satFeesMax) clarifies the fee's purpose
  • Affiliate fields enable fee tracking and distribution
  • offrampRegistryVersion enables ABI version selection
  • bumpFeeAmountInSats supports dynamic fee bumping logic

Also applies to: 94-94, 112-120


159-164: LGTM! Raw order type and params updated consistently.

OfframpRawOrder correctly includes all new fields as strings (matching the API response format), and BumpFeeParams/UnlockOrderParams now accept offrampRegistryAddress to support operations across multiple registry versions.

Also applies to: 175-175, 181-181

sdk/src/gateway/client.ts (5)

405-408: LGTM! Affiliate parameters properly handled in onramp quote.

The code correctly checks that both affiliateFeeRecipient and affiliateFeeSats are provided before adding them to the query parameters, ensuring affiliate fee data is complete.


484-492: LGTM! Clean registry address resolution.

The method correctly returns the appropriate registry address based on chain ID and throws a clear error for unsupported chains. Note that this method uses the constants with TODO comments (lines 95, 100), so it will need verification once V2 contracts are deployed.


614-622: LGTM! Order creation correctly uses V2 ABI with affiliate support.

The createOfframpOrder method properly uses offrampCallerV2 and includes all new fields (satSolverFeeMax, satAffiliateFee, affiliateFeeRecipient) in the order arguments.


639-671: LGTM! Bump and unlock correctly support multi-version registries.

Both methods properly:

  1. Accept offrampRegistryAddress as a parameter
  2. Fetch order details via API to determine the registry version
  3. Use getOfframpAbi() to select the appropriate ABI
  4. Validate order state before proceeding

The null check on bumpFeeAmountInSats (line 653) correctly prevents unnecessary bump fee transactions.

Also applies to: 680-716


92-100: V2 registry addresses flagged as TODO: confirm deployment status and whether runtime validation is needed.

The review comment is factually accurate—both TODOs exist at lines 95 and 100, and the referenced skipped test exists at line 965 of the test file. Code verification confirms V2 ABI support is imported and used, but no runtime validation prevents address misuse if deployed addresses don't match the hardcoded constants.

Key findings:

  • No deployment timeline, contract status, or address validity info found in codebase
  • No runtime guards or validation to prevent V2 operations with potentially incorrect addresses
  • Current addresses are hardcoded with no environment-based fallback or configuration

To resolve: Confirm the V2 contract deployment status externally and determine whether the code should include validation to prevent operations until correct addresses are in place.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
sdk/src/gateway/client.ts (1)

197-226: Type assertions bypass runtime safety checks.

This method uses multiple type assertions (e.g., order.status as OfframpOrderStatus, order.offrampRegistryAddress as Address) without validation. As noted in a previous review, using type guards or a validation library like Zod would provide better runtime safety if the API returns unexpected data.

🧹 Nitpick comments (1)
sdk/test/gateway.test.ts (1)

751-765: Consider mocking the contract call for better test isolation.

This test calls canOrderBeUnlocked, which performs a readContract call to fetch the claim delay. While the previous review noted this is acceptable because the registry address is valid, mocking this call would make the test faster, more deterministic, and able to run offline.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 112246c and e9f2371.

📒 Files selected for processing (4)
  • sdk/src/gateway/client.ts (17 hunks)
  • sdk/src/gateway/types/offramp.ts (7 hunks)
  • sdk/src/gateway/utils/common.ts (0 hunks)
  • sdk/test/gateway.test.ts (9 hunks)
💤 Files with no reviewable changes (1)
  • sdk/src/gateway/utils/common.ts
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-06-17T11:18:53.195Z
Learnt from: slavastartsev
Repo: bob-collective/bob PR: 634
File: sdk/src/gateway/client.ts:136-140
Timestamp: 2025-06-17T11:18:53.195Z
Learning: The codebase has a requirement not to introduce discriminated unions in the Gateway SDK client methods, including the getQuote method return types in sdk/src/gateway/client.ts.

Applied to files:

  • sdk/src/gateway/types/offramp.ts
  • sdk/test/gateway.test.ts
🧬 Code graph analysis (3)
sdk/src/gateway/types/offramp.ts (1)
sdk/src/gateway/abi.ts (1)
  • offrampCallerV2 (80-172)
sdk/src/gateway/client.ts (2)
sdk/src/gateway/abi.ts (2)
  • offrampCallerV1 (41-78)
  • offrampCallerV2 (80-172)
sdk/src/gateway/types/offramp.ts (5)
  • OfframpRawOrder (124-141)
  • OfframpOrder (86-121)
  • OfframpOrderStatus (13-13)
  • BumpFeeParams (149-152)
  • UnlockOrderParams (154-158)
sdk/test/gateway.test.ts (2)
sdk/src/gateway/client.ts (1)
  • SIGNET_GATEWAY_BASE_URL (82-82)
sdk/src/gateway/types/offramp.ts (1)
  • OfframpOrderStatus (13-13)
🪛 Gitleaks (8.29.0)
sdk/test/gateway.test.ts

[high] 678-678: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🔇 Additional comments (18)
sdk/test/gateway.test.ts (5)

662-684: LGTM! Test updated to match V2 offramp contract.

The test correctly includes the new affiliate fee fields and uses the updated field naming (satSolverFeeMax, satAffiliateFee, affiliateFeeRecipient) that aligns with the V2 offramp ABI.


692-726: Test now uses mapping function for better consistency.

The test has been improved to use mapRawOrderToOfframpOrder for constructing expected results, which reduces duplication of mapping logic and makes the test more maintainable. The field naming issue from the previous review (evmTx vs refundedEvmTx) has also been resolved.


743-748: LGTM! Test correctly validates static registry address lookup.

The test has been updated to reflect the change from dynamic registry address fetching to static, chain-specific address constants.


968-969: Skipped test blocks V2 gas cost feature validation.

This test remains skipped pending V2 offramp registry deployment. Once the new registry is deployed and the address is updated in the constants, this test should be re-enabled to validate the gas cost estimation feature.


890-948: LGTM! Test correctly updated to spy on static registry address method.

The test spy has been updated from fetchOfframpRegistryAddress to getTargetOfframpRegistryAddress, correctly reflecting the change from dynamic fetching to static lookup.

sdk/src/gateway/types/offramp.ts (4)

2-44: LGTM! OfframpQuote updated for V2 contract.

The import has been updated to use offrampCallerV2, and the OfframpQuote type correctly replaces the dynamic registryAddress field with affiliateFeeRecipient, aligning with the V2 contract requirements where registry addresses are now statically determined by chain.


57-83: LGTM! CreateOrderParams aligned with V2 ABI structure.

The type correctly specifies offrampCallerV2 ABI and includes the new V2 contract fields: satSolverFeeMax, satAffiliateFee, and affiliateFeeRecipient. The field renaming from satFeesMax to satSolverFeeMax is more descriptive and clearly indicates this fee is for the solver.


85-141: LGTM! Enhanced order types support versioning and affiliate fees.

The OfframpOrder and OfframpRawOrder types have been extended with essential fields:

  • offrampRegistryVersion enables handling both V1 and V2 registries
  • Affiliate fee fields (satAffiliateFee, affiliateFeeRecipient) support the new revenue-sharing model
  • bumpFeeAmountInSats provides users with fee bump guidance
  • userAddress enables user-specific order filtering

All fields are well-documented and the raw/domain type separation is maintained correctly.


148-157: LGTM! Operation params now include registry address.

Both BumpFeeParams and UnlockOrderParams correctly include offrampRegistryAddress, which is necessary for supporting multiple registry versions (V1 and V2) and directing operations to the correct contract.

sdk/src/gateway/client.ts (9)

90-98: Mainnet V2 registry address needs to be updated before deployment.

The MAINNET_TARGET_OFFRAMP_REGISTRY_ADDRESS constant has a TODO comment indicating it needs to be replaced with the new V2 address. This must be completed before the V2 offramp feature can be enabled on mainnet.


193-195: LGTM! Version-based ABI selection supports V1/V2 registries.

The method cleanly selects the appropriate ABI based on version, defaulting to V2 for future versions.


403-406: LGTM! Affiliate parameters correctly added to onramp quotes.

The implementation properly requires both affiliateFeeRecipient and affiliateFeeSats together, preventing partial affiliate configuration.


482-490: LGTM! Static registry address lookup improves reliability.

Replacing dynamic registry address fetching with static, chain-specific constants improves reliability and performance, as stated in the PR objectives.


534-589: LGTM! Offramp quote correctly handles affiliate parameters.

The implementation properly:

  • Makes affiliate parameters optional
  • Requires both affiliate parameters together when provided
  • Defaults affiliateFeeRecipient to zeroAddress when not specified
  • Maintains consistency with the onramp flow

599-628: LGTM! Order creation uses V2 ABI with affiliate fee support.

The method correctly uses offrampCallerV2 and populates all V2-specific fields including satSolverFeeMax, satAffiliateFee, and affiliateFeeRecipient.


637-668: LGTM! Fee bumping now supports both V1 and V2 registries.

The implementation correctly:

  • Accepts explicit offrampRegistryAddress parameter
  • Validates that fee bumping is needed via bumpFeeAmountInSats
  • Uses version-specific ABI selection
  • Uses the API-provided bump fee amount

678-714: LGTM! Order unlocking supports both V1 and V2 registries.

Consistent with fee bumping, this implementation correctly handles registry address and version-specific ABI selection for both V1 and V2 registries.


722-783: LGTM! Order fetching now uses API instead of on-chain reads.

The changes successfully replace on-chain order fetching with API-based fetching, improving reliability and performance as stated in the PR objectives. Both methods correctly use mapRawOrderToOfframpOrder for consistent data transformation.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
sdk/src/gateway/client.ts (1)

1-1: Fix code formatting with Prettier.

The pipeline reports code style issues detected by Prettier.

Run the following command to fix formatting:

prettier --write sdk/src/gateway/client.ts
♻️ Duplicate comments (1)
sdk/src/gateway/client.ts (1)

187-216: Type assertions bypass runtime safety—consider validation.

Similar to the previous review comment, this function uses multiple type assertions (order.status as OfframpOrderStatus, order.offrampRegistryAddress as Address, etc.) that bypass TypeScript's type safety. If the API returns unexpected data, this will cause runtime errors.

Consider using validation guards or a library like Zod to validate the raw API response before casting:

private validateOfframpOrderStatus(status: string): OfframpOrderStatus {
    const validStatuses: OfframpOrderStatus[] = ['Active', 'Accepted', 'Processed', 'Refunded'];
    if (!validStatuses.includes(status as OfframpOrderStatus)) {
        throw new Error(`Invalid order status: ${status}`);
    }
    return status as OfframpOrderStatus;
}

public async mapRawOrderToOfframpOrder(order: OfframpRawOrder): Promise<OfframpOrder> {
    const status = this.validateOfframpOrderStatus(order.status);
    
    if (!isAddress(order.offrampRegistryAddress)) {
        throw new Error(`Invalid registry address: ${order.offrampRegistryAddress}`);
    }
    const offrampRegistryAddress = order.offrampRegistryAddress as Address;
    // ... rest of mapping
}
🧹 Nitpick comments (1)
sdk/src/gateway/client.ts (1)

183-185: Add version parameter validation.

The method assumes version will be either 1 or 2, but doesn't validate this. Invalid versions (0, negative, >2) will default to V2, which may not be the desired behavior.

Consider adding validation:

 private getOfframpAbi(version: number) {
+    if (version !== 1 && version !== 2) {
+        throw new Error(`Unsupported offramp registry version: ${version}`);
+    }
     return version === 1 ? offrampCallerV1 : offrampCallerV2;
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e9f2371 and 8d7bf8a.

📒 Files selected for processing (1)
  • sdk/src/gateway/client.ts (14 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-06-17T11:18:53.195Z
Learnt from: slavastartsev
Repo: bob-collective/bob PR: 634
File: sdk/src/gateway/client.ts:136-140
Timestamp: 2025-06-17T11:18:53.195Z
Learning: The codebase has a requirement not to introduce discriminated unions in the Gateway SDK client methods, including the getQuote method return types in sdk/src/gateway/client.ts.

Applied to files:

  • sdk/src/gateway/client.ts
🧬 Code graph analysis (1)
sdk/src/gateway/client.ts (2)
sdk/src/gateway/abi.ts (2)
  • offrampCallerV1 (41-78)
  • offrampCallerV2 (80-172)
sdk/src/gateway/types/offramp.ts (5)
  • OfframpRawOrder (124-141)
  • OfframpOrder (86-121)
  • OfframpOrderStatus (13-13)
  • BumpFeeParams (149-152)
  • UnlockOrderParams (154-158)
🪛 GitHub Actions: SDK
sdk/src/gateway/client.ts

[warning] 1-1: Code style issues found by Prettier. Run 'prettier --write' to fix.

⏰ 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: test
🔇 Additional comments (8)
sdk/src/gateway/client.ts (8)

24-24: LGTM! Versioned ABI imports align with V2 support.

The import of both offrampCallerV1 and offrampCallerV2 correctly supports the new versioned offramp functionality.


393-396: LGTM! Affiliate fee parameters properly propagated.

The conditional addition of affiliate fee query parameters is correctly implemented, ensuring both affiliateFeeRecipient and affiliateFeeSats are provided together.


449-465: LGTM! Affiliate fee propagation is consistent.

The affiliate fee parameters are correctly passed through to fetchOfframpQuote, maintaining consistency with the onramp flow.


529-584: LGTM! Affiliate fee handling with reasonable defaults.

The implementation correctly:

  • Conditionally appends affiliate parameters to the API query when both are provided
  • Normalizes affiliateFeeRecipient to zeroAddress when not provided
  • Includes the normalized value in the returned quote

This ensures downstream code always receives a valid address.


594-623: LGTM! New orders correctly use V2 ABI with extended parameters.

The method properly:

  • Uses offrampCallerV2 for new order creation
  • Includes the new V2 fields: satSolverFeeMax, satAffiliateFee, and affiliateFeeRecipient
  • Maintains backward compatibility by using versioned ABIs for existing orders

632-664: LGTM! Enhanced with version-aware ABI selection and precise fee calculation.

The improvements include:

  • Registry address parameterization for multi-registry support
  • More precise fee bump validation using bumpFeeAmountInSats instead of a boolean flag
  • Dynamic ABI selection based on the order's registry version

The exact bump amount check (line 646-648) provides better UX compared to a simple boolean.


673-709: LGTM! Consistent version-aware implementation.

The changes mirror the pattern in bumpFeeForOfframpOrder:

  • Registry address parameterization
  • API-based order fetching
  • Dynamic ABI selection based on order version

This ensures compatibility with both V1 and V2 registries.


717-778: LGTM! Architectural shift to API-based order fetching improves reliability.

The changes implement the key PR objective:

  • fetchOfframpOrder now retrieves data from the API instead of on-chain reads
  • Both methods use the new mapRawOrderToOfframpOrder for consistent data transformation
  • Registry address parameterization supports multi-registry queries

This approach improves performance and reliability as noted in the PR description.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
sdk/test/gateway.test.ts (1)

692-726: Circular testing: mapping function testing itself.

Line 714 generates expectedResult by calling mapRawOrderToOfframpOrder on the mock data, and Line 726 compares the output of getOfframpOrders (which internally uses the same mapRawOrderToOfframpOrder) against this result. This creates circular testing where the mapping function effectively tests itself, which doesn't validate correctness.

Consider manually constructing expectedResult with explicit field values or at minimum asserting individual critical fields:

-const expectedResult = await gatewaySDK.mapRawOrderToOfframpOrder(mockResponse[0]);
+const expectedResult: OfframpOrder = {
+    orderId: '0x0',
+    token: '0x4496ebE7C8666a8103713EE6e0c08cA0cD25b888',
+    satAmountLocked: BigInt('0x3e8'),
+    satSolverFeeMax: BigInt('0x181'),
+    satAffiliateFee: BigInt('0x181'),
+    affiliateFeeRecipient: zeroAddress,
+    status: OfframpOrderStatus.Processed,
+    btcTx: 'e8d52d6ef6ebf079f2d082dc683c9455178b64e0685c10e93882effaedde4474',
+    refundedEvmTx: null,
+    orderTimestamp: 1743679342,
+    shouldFeesBeBumped: false,
+    bumpFeeAmountInSats: null,
+    userAddress: zeroAddress,
+    offrampRegistryAddress: '0x70e5e53b4f48be863a5a076ff6038a91377da0dd',
+    offrampRegistryVersion: '0x0',
+    submitOrderEvmTx: '0xc02c65d88719d92a189d36da2f71108df3cc4d2611e711a5e049c896a4e06283',
+};
🧹 Nitpick comments (1)
sdk/test/gateway.test.ts (1)

972-973: Test skipped pending V2 deployment.

The test is appropriately skipped with a clear TODO indicating it depends on V2 offramp registry contract deployment. This is acceptable technical debt.

Once the V2 contract is deployed, remember to unskip this test and update the registry address. Would you like me to open a tracking issue for this task?

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 91d7e43 and dd4787d.

📒 Files selected for processing (1)
  • sdk/test/gateway.test.ts (8 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-06-17T11:18:53.195Z
Learnt from: slavastartsev
Repo: bob-collective/bob PR: 634
File: sdk/src/gateway/client.ts:136-140
Timestamp: 2025-06-17T11:18:53.195Z
Learning: The codebase has a requirement not to introduce discriminated unions in the Gateway SDK client methods, including the getQuote method return types in sdk/src/gateway/client.ts.

Applied to files:

  • sdk/test/gateway.test.ts
🧬 Code graph analysis (1)
sdk/test/gateway.test.ts (1)
sdk/src/gateway/types/offramp.ts (1)
  • OfframpRawOrder (124-141)
🪛 Gitleaks (8.29.0)
sdk/test/gateway.test.ts

[high] 695-695: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

@nakul1010
Copy link
Contributor Author

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces significant and well-structured changes to support Offramp V2, including affiliate fees and moving order detail fetching from on-chain calls to an API. The refactoring improves the SDK's architecture by centralizing order data and simplifying client-side logic. My review includes a few suggestions to improve robustness and maintainability, mainly concerning data validation from API responses and naming consistency.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
sdk/test/gateway.test.ts (1)

870-915: Offramp executeQuote test nock is now out of sync with the client’s query parameters

fetchOfframpQuote always sends userAddress in the query:

const queryParams = new URLSearchParams({
  amountInWrappedToken: amountInToken.toString(),
  token,
  userAddress,
});

But the test stubs:

const searchParams = new URLSearchParams({
  amountInWrappedToken: '1000',
  token: outputTokenAddress,
});
nock(SIGNET_GATEWAY_BASE_URL)
  .get(`/offramp-quote?${searchParams}`)
  .reply(201, { ... });

Because the actual request includes userAddress, it will not match this nock, causing a real network call or a failing test. Updating the stub to allow arbitrary query params (or to include userAddress) will fix this:

-        nock(`${SIGNET_GATEWAY_BASE_URL}`)
-            .get(`/offramp-quote?${searchParams}`)
-            .reply(201, {
+        nock(`${SIGNET_GATEWAY_BASE_URL}`)
+            .get('/offramp-quote')
+            .query(true)
+            .reply(201, {
🧹 Nitpick comments (5)
sdk/test/gateway.test.ts (2)

755-769: Prefer using the imported registry constant instead of hard‑coding the address

In canOrderBeUnlocked, the test passes a hard‑coded registry address string that appears to correspond to the imported TESTNET_TARGET_OFFRAMP_REGISTRY_ADDRESS. Using the constant here would:

  • Remove duplication,
  • Keep tests in sync if the registry address ever changes.

Example:

-        const result = await gatewaySDK.canOrderBeUnlocked(
-            status,
-            orderTimestamp,
-            '0x70e5e53b4f48be863a5a076ff6038a91377da0dd' as Address
-        );
+        const result = await gatewaySDK.canOrderBeUnlocked(
+            status,
+            orderTimestamp,
+            TESTNET_TARGET_OFFRAMP_REGISTRY_ADDRESS as Address
+        );

972-999: get offramp gas cost test tightly depends on live RPCs

This test asserts gasFee > 0 for BOB and Ethereum quotes, but getOfframpCreateOrderGasCost calls estimateFeesPerGas, getGasPrice, and estimateContractGas on real RPC endpoints. If those endpoints are unavailable or estimation fails, the method catches the error and returns gasFee = 0, causing this test to fail.

Consider mocking the viem client / public client for gas estimation (or getOfframpCreateOrderGasCost itself) so the test remains deterministic and doesn’t depend on external infra.

Also applies to: 1000-1045

sdk/src/gateway/types/offramp.ts (1)

2-2: Offramp V2 types are consistent with the new ABI and client usage

Structurally, the type updates line up with the V2 ABI and client logic:

  • OfframpQuote carries affiliateFeeRecipient, which is then threaded into OfframpCreateOrderParams.
  • OfframpCreateOrderParams now uses offrampCallerV2 and createOrderV2, with tuple components matching the ABI (satAmountToLock, satSolverFeeMax, satAffiliateFee, affiliateFeeRecipient, etc.).
  • OfframpOrder and OfframpRawOrder are extended to include registry address, affiliate fee fields, registry version, bump‑fee amount, and user address, which the client maps in mapRawOrderToOfframpOrder.
  • BumpFeeParams and UnlockOrderParams now include offrampRegistryAddress, aligning with how the client performs on‑chain calls.

One thing worth double‑checking (together with client.ts): that feeBreakdown.overallFeeSats, satSolverFeeMax, and satAffiliateFee are kept consistent with how the Solidity contract interprets them (i.e., whether overallFeeSats already includes affiliate fees or not), so that the user’s amountReceiveInSat matches on‑chain behavior.

Also applies to: 31-45, 58-83, 85-121, 123-141, 149-152, 154-158

sdk/src/gateway/client.ts (2)

24-24: Offramp order mapping via mapRawOrderToOfframpOrder is coherent; consider caching claim delay

The new mapRawOrderToOfframpOrder + getOfframpOrders flow looks solid:

  • Raw fields are converted to the richer OfframpOrder shape with BigInt where appropriate.
  • New fields (satAffiliateFee, affiliateFeeRecipient, offrampRegistryVersion, bumpFeeAmountInSats, userAddress) are correctly mapped from OfframpRawOrder.
  • canOrderBeUnlocked is computed per order using claimDelayAbi and the given registry address, which makes unlockability logic explicit.

If you expect many orders per user, you might consider caching the CLAIM_DELAY per offrampRegistryAddress inside canOrderBeUnlocked to avoid multiple identical readContract calls, but that’s an optimization, not a blocker.

Also applies to: 183-212, 708-717, 719-739


445-458: Potentially sending userAddress=undefined to the offramp quote API when fromUserAddress is absent

In getOfframpQuote you always pass params.fromUserAddress as Address:

const quote = await this.fetchOfframpQuote(
  tokenAddress,
  BigInt(params.amount || 0),
  params.fromUserAddress as Address,
  params.toUserAddress,
  params.affiliateFeeRecipient,
  params.affiliateFeeSats
);

fetchOfframpQuote then does:

const queryParams = new URLSearchParams({
  amountInWrappedToken: amountInToken.toString(),
  token,
  userAddress: userAddress,
});

If params.fromUserAddress is omitted (e.g., your get offramp gas cost ... with no from user address test), this will result in userAddress=undefined in the query string. Depending on how the backend validates this field, that may be brittle or error‑prone.

Given you already synthesize a fallback address in getOfframpCreateOrderGasCost when fromUserAddress is missing, consider doing something similar here, for example:

const effectiveFromUser =
  (params.fromUserAddress as Address | undefined) ?? zeroAddress;
const quote = await this.fetchOfframpQuote(
  tokenAddress,
  BigInt(params.amount || 0),
  effectiveFromUser,
  params.toUserAddress,
  params.affiliateFeeRecipient,
  params.affiliateFeeSats
);

This keeps the API request well‑formed even when callers don’t provide fromUserAddress.

Also applies to: 524-537

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dd4787d and 51f48b0.

📒 Files selected for processing (4)
  • sdk/src/gateway/abi.ts (2 hunks)
  • sdk/src/gateway/client.ts (14 hunks)
  • sdk/src/gateway/types/offramp.ts (7 hunks)
  • sdk/test/gateway.test.ts (8 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • sdk/src/gateway/abi.ts
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-06-17T11:18:53.195Z
Learnt from: slavastartsev
Repo: bob-collective/bob PR: 634
File: sdk/src/gateway/client.ts:136-140
Timestamp: 2025-06-17T11:18:53.195Z
Learning: The codebase has a requirement not to introduce discriminated unions in the Gateway SDK client methods, including the getQuote method return types in sdk/src/gateway/client.ts.

Applied to files:

  • sdk/src/gateway/client.ts
  • sdk/src/gateway/types/offramp.ts
  • sdk/test/gateway.test.ts
🧬 Code graph analysis (3)
sdk/src/gateway/client.ts (2)
sdk/src/gateway/types/offramp.ts (5)
  • OfframpRawOrder (124-141)
  • OfframpOrder (86-121)
  • OfframpOrderStatus (13-13)
  • BumpFeeParams (149-152)
  • UnlockOrderParams (154-158)
sdk/src/gateway/abi.ts (1)
  • offrampCallerV2 (41-133)
sdk/src/gateway/types/offramp.ts (1)
sdk/src/gateway/abi.ts (1)
  • offrampCallerV2 (41-133)
sdk/test/gateway.test.ts (2)
sdk/src/gateway/types/offramp.ts (1)
  • OfframpRawOrder (124-141)
sdk/src/gateway/client.ts (1)
  • MAINNET_GATEWAY_BASE_URL (76-76)
⏰ 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: test
🔇 Additional comments (7)
sdk/test/gateway.test.ts (4)

8-12: Centralizing gateway constants and types in tests looks good

Importing MAINNET_GATEWAY_BASE_URL, SIGNET_GATEWAY_BASE_URL and OfframpRawOrder from the SDK keeps tests aligned with the client implementation and avoids string/type drift. No issues here.

Also applies to: 19-22


648-663: Offramp V2 args and affiliate fields are wired correctly in the create‑quote test

The test payload and expectations for createOfframpOrder correctly reflect the new V2 ABI:

  • satSolverFeeMax derived from feeBreakdown.overallFeeSats.
  • satAffiliateFee from feeBreakdown.affiliateFeeSats.
  • affiliateFeeRecipient flowing from the quote into the contract args.

This gives good coverage of the new order‑creation surface.

Also applies to: 675-684


691-711: Nice reuse of mapRawOrderToOfframpOrder in the offramp orders test

Using a typed OfframpRawOrder[] and deriving expectedResult via gatewaySDK.mapRawOrderToOfframpOrder keeps this test resilient to future mapping changes and avoids duplicating mapping logic in the test. The mock shape matches OfframpRawOrder (including the new registry/affiliate fields), so this looks solid.

Also applies to: 714-727


743-753: Fetch offramp registry address test correctly targets the new API flow

The test for fetchOfframpRegistryAddress now stubs /offramp-registry-address and asserts the returned value, matching the updated client method. This is a straightforward and accurate check of the new behavior.

sdk/src/gateway/client.ts (3)

389-392: Affiliate fee query parameters are threaded correctly through onramp/offramp quotes

For both onramp and offramp:

  • When affiliateFeeRecipient and affiliateFeeSats are provided in GetQuoteParams, you append affiliateFee and affiliateFeeRecipient to the respective quote URLs.
  • fetchOfframpQuote mirrors this behavior and normalizes affiliateFeeRecipient to a non‑nullable value (affiliateFeeRecipient ?? zeroAddress), which is then returned in the OfframpQuote.

This keeps the HTTP surface and the in‑memory OfframpQuote consistent for affiliate flow. Looks good.

Also applies to: 524-546, 560-577


627-657: Bump/unlock flows now correctly use registry‑aware API order data

The changes to bumpFeeForOfframpOrder, unlockOfframpOrder, and fetchOfframpOrder look consistent:

  • Both bump/unlock now require offrampRegistryAddress and use /offramp-order (with registryAddress and orderId query params) to obtain a fully mapped OfframpOrder.
  • bumpFeeForOfframpOrder checks that the order is Active and that bumpFeeAmountInSats is non‑null before calling bumpFeeOfExistingOrder on offrampCallerV2.
  • unlockOfframpOrder disallows Processed/Refunded orders, re‑checks unlockability via canOrderBeUnlocked, and then calls refundOrder on offrampCallerV2.

Error handling on the API read path (!response.ok branch) is also reasonable. Overall this is a clean move away from direct on‑chain reads toward centralized API mapping.

Also applies to: 666-700, 741-769


560-577: Verify fee breakdown semantics with backend and contract team

The review concern is well-founded based on available evidence:

  • Test data shows overallFeeSats: 932 = inclusionFeeSats: 930 + protocolFeeSats: 1 + affiliateFeeSats: 1, indicating overallFeeSats is the sum of all fee components.
  • Current code passes both satSolverFeeMax = overallFeeSats (932) and satAffiliateFee = affiliateFeeSats (1) separately to the contract.
  • If the contract expects satSolverFeeMax to represent only the solver-portion (i.e., overallFeeSats - affiliateFeeSats = 931), this creates double-counting.

The JSDoc comment on satSolverFeeMax ("Max sats to be paid as fees") is ambiguous and does not clarify whether it should include or exclude the affiliate portion.

Confirm with the offramp contract and backend team whether satSolverFeeMax should be:

  • overallFeeSats (as currently implemented), or
  • overallFeeSats - affiliateFeeSats (solver-only portion)

Then adjust lines 608–609 and the secondary location (589–618) if needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants