Skip to content

Conversation

@slavastartsev
Copy link
Contributor

@slavastartsev slavastartsev commented Jun 5, 2025

Summary by CodeRabbit

  • New Features

    • Added detailed fee breakdowns for Bitcoin offramp quotes, providing greater transparency on fee components.
    • Introduced new utility functions to support blockchain operations and order processing.
    • Enhanced swap functionality with streamlined transaction execution and direct transaction ID retrieval.
  • Refactor

    • Improved type safety and consistency by adopting the Address type from the Viem library throughout the SDK.
    • Unified and simplified method signatures for quote and order operations.
    • Enhanced error handling and validation for blockchain addresses and parameters.
    • Updated network identifiers and standardized chain naming conventions.
    • Consolidated utility functions into a dedicated module for better code organization.
  • Bug Fixes

    • Corrected parameter ordering and updated network references in the test suite for improved reliability.
  • Chores

    • Added new dependency @gobob/sats-wagmi to support Bitcoin signing integration.
    • Updated submodule configurations to ignore local modifications.

@vercel
Copy link

vercel bot commented Jun 5, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
bob-docs ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jun 17, 2025 11:22am

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jun 5, 2025

Walkthrough

This update refactors the Gateway SDK and its example to use the viem library for Ethereum interactions and @gobob/sats-wagmi for Bitcoin signing, unifies and improves type safety across gateway types and methods, introduces detailed fee breakdowns for off-ramp quotes, and extracts utility functions for modularity. Test code and dependencies are updated accordingly.

Changes

File(s) Change Summary
sdk/examples/gateway.ts Refactored to use viem for Ethereum, @gobob/sats-wagmi for Bitcoin signing, unified quote execution, updated parameters and removed manual PSBT handling.
sdk/package.json Added dependency @gobob/sats-wagmi@^0.3.23.
sdk/src/gateway/client.ts Refactored imports, improved type safety, unified and updated method signatures, removed 'testnet' support, added error handling, extracted utilities, and updated fee handling.
sdk/src/gateway/types.ts Replaced generic address types with viem's Address, introduced Hex type usage, added chain ID mapping, improved parameter typing, and added ExecuteQuoteParams union type.
sdk/src/gateway/utils.ts Added new utility functions for hashing, Bitcoin script pubkey conversion, hex prefix handling, slugifying, order status parsing, and viem client creation.
sdk/test/gateway.test.ts Updated to use viem's zeroAddress, fixed parameter order, updated mocks for fee breakdown, replaced 'testnet' with 'signet', and improved type consistency.
.gitmodules Added ignore = dirty to all submodules to ignore local modifications in submodules when checking status.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant GatewaySDK
    participant ViemClient
    participant WalletClient
    participant XverseConnector

    User->>GatewaySDK: swapBtcForToken(evmAddress)
    GatewaySDK->>ViemClient: Create publicClient/walletClient
    GatewaySDK->>XverseConnector: Create btcSigner
    GatewaySDK->>GatewaySDK: getQuote({type: 'onramp', ...})
    GatewaySDK->>GatewaySDK: executeQuote(quote, params, walletClient, publicClient, btcSigner)
    GatewaySDK->>XverseConnector: btcSigner.signAllInputs(psbt)
    GatewaySDK->>GatewaySDK: Process signed PSBT, broadcast transaction
    GatewaySDK-->>User: Return transaction ID
Loading

Possibly related PRs

  • bob-collective/bob#616: Introduces and details the executeQuote method, which is unified and extended in this PR.
  • bob-collective/bob#625: Adds detailed fee breakdowns to offramp quotes and updates internal fee handling, related to gateway client internals.
  • bob-collective/bob#559: Adds new on-chain offramp order management methods and enriched order types, related to gateway client but focusing on different functionality.

Suggested reviewers

  • nakul1010
  • danielsimao
  • gregdhill

Poem

In the warren of code, a gateway anew,
With viem and wagmi, the chains we pursue.
Bitcoin and Bob, now friends in the flow,
Fee breakdowns revealed, so all rabbits know.
Utilities gathered, the toolkit grows strong—
Onward we hop, where blockchains belong!
🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate Unit Tests
  • Create PR with Unit Tests
  • Commit Unit Tests in branch chore/merge-interfaces
  • Post Copyable Unit Tests in Comment

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai auto-generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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: 3

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

845-846: Consider tracking the staking strategy availability.

The test is skipped because signet doesn't have staking strategies. This limitation should be documented or tracked to ensure it's addressed when strategies become available.

Would you like me to create an issue to track the implementation of staking strategies for the signet network?

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

110-111: Remove or uncomment the 'type' field.

The type field is commented out. Either remove it entirely if it's no longer needed, or uncomment it if it's still required for the API.

-    // /** @description Optionally filter the type of routes returned */
-    // type?: 'swap' | 'deposit' | 'withdraw' | 'claim';
sdk/src/gateway/client.ts (1)

606-722: Consider refactoring executeQuote for better maintainability.

While the unified executeQuote method improves API consistency, it's becoming quite complex with three different execution paths. Consider extracting each quote type's logic into separate private methods.

 async executeQuote(
     executeQuoteParams: ExecuteQuoteParams,
     walletClient: WalletClient<Transport, ViemChain, Account>,
     publicClient: PublicClient<Transport>,
     btcSigner: { signAllInputs: (psbtBase64: string) => Promise<string> }
 ): Promise<string> {
     if (executeQuoteParams.type === 'onramp') {
-        const { params, quote } = executeQuoteParams;
-        const { uuid, psbtBase64 } = await this.startOrder(quote, params);
-        // ... rest of onramp logic
+        return this.executeOnrampQuote(executeQuoteParams, btcSigner);
     } else if (executeQuoteParams.type === 'offramp') {
-        const { params } = executeQuoteParams;
-        // ... rest of offramp logic
+        return this.executeOfframpQuote(executeQuoteParams, walletClient, publicClient);
     } else {
-        const { params } = executeQuoteParams;
-        // ... rest of stake logic
+        return this.executeStakeQuote(executeQuoteParams, walletClient, publicClient);
     }
 }
+
+private async executeOnrampQuote(
+    executeQuoteParams: Extract<ExecuteQuoteParams, { type: 'onramp' }>,
+    btcSigner: { signAllInputs: (psbtBase64: string) => Promise<string> }
+): Promise<string> {
+    // Extract onramp logic here
+}
+
+private async executeOfframpQuote(
+    executeQuoteParams: Extract<ExecuteQuoteParams, { type: 'offramp' }>,
+    walletClient: WalletClient<Transport, ViemChain, Account>,
+    publicClient: PublicClient<Transport>
+): Promise<string> {
+    // Extract offramp logic here
+}
+
+private async executeStakeQuote(
+    executeQuoteParams: Extract<ExecuteQuoteParams, { type: 'stake' }>,
+    walletClient: WalletClient<Transport, ViemChain, Account>,
+    publicClient: PublicClient<Transport>
+): Promise<string> {
+    // Extract stake logic here
+}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9db3923 and 15fe8b8.

⛔ Files ignored due to path filters (1)
  • sdk/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (7)
  • sdk/examples/gateway.ts (1 hunks)
  • sdk/package.json (2 hunks)
  • sdk/src/gateway/client.ts (20 hunks)
  • sdk/src/gateway/types.ts (9 hunks)
  • sdk/src/gateway/utils.ts (1 hunks)
  • sdk/src/mempool.ts (2 hunks)
  • sdk/test/gateway.test.ts (21 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
sdk/src/gateway/utils.ts (2)
sdk/src/gateway/types.ts (2)
  • GatewayCreateOrderRequest (238-247)
  • OfframpOrderStatus (354-354)
crates/utils/src/bitcoin_client.rs (1)
  • network (275-278)
🪛 Gitleaks (8.26.0)
sdk/examples/gateway.ts

7-7: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🔇 Additional comments (21)
sdk/src/gateway/utils.ts (1)

1-69: Excellent modularization of utility functions!

The extraction of these utility functions into a dedicated module improves code organization and reusability. All implementations are correct and follow best practices:

  • calculateOpReturnHash properly uses ethers ABI encoding for data integrity
  • toHexScriptPubKey correctly handles Bitcoin address conversion
  • Hex utilities provide clean string manipulation
  • parseOrderStatus includes proper error handling for invalid inputs
  • viemClient uses the standard viem client creation pattern
sdk/package.json (3)

3-3: Version bump is appropriate for the refactoring scope.

The increment to 3.3.3 aligns with the feature additions and type safety improvements in this release.


44-44: Good addition of Bitcoin signing capability.

The @gobob/sats-wagmi dependency enables the Bitcoin signing functionality demonstrated in the updated example.


52-52: Pinning viem version ensures compatibility.

Fixing the viem version to 2.30.6 prevents potential breaking changes and ensures compatibility with the new typed Address usage patterns.

sdk/src/mempool.ts (2)

263-263: ⚠️ Potential issue

Fix incorrect promise handling that creates double-wrapped promises.

The current implementation returns Promise<Promise<T>> instead of Promise<T>. Since response.json() already returns a Promise, casting it as Promise<T> and returning from an async function creates a double-wrapped promise.

Apply this fix:

-        return response.json() as Promise<T>;
+        return response.json() as T;

Likely an incorrect or invalid review comment.


274-274: ⚠️ Potential issue

Fix incorrect promise handling that creates double-wrapped promises.

Same issue as in getJson - this creates Promise<Promise<T>> instead of the intended Promise<T>.

Apply this fix:

-        return response.text() as Promise<T>;
+        return response.text() as T;

Likely an incorrect or invalid review comment.

sdk/examples/gateway.ts (4)

1-6: Excellent integration of new dependencies and typed imports.

The imports properly leverage the new dependencies (@gobob/sats-wagmi, viem) and demonstrate the enhanced type safety with typed Address and client interfaces.


9-23: Well-structured client setup using the new patterns.

The viem client creation and XverseConnector setup properly demonstrate the updated SDK patterns. The typed Address parameter and proper client configuration align with the refactoring objectives.


24-49: Streamlined quote execution flow.

The refactored example effectively demonstrates the simplified quote execution using the new executeQuote method, replacing the previous manual PSBT handling with a cleaner API.


7-7: Static analysis false positive - this is a legitimate contract address.

The detected "Generic API Key" is actually the BOB tBTC v2 token contract address on the BOB network, which is a legitimate constant for the example.

🧰 Tools
🪛 Gitleaks (8.26.0)

7-7: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

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

4-4: LGTM! Good migration to viem types.

The replacement of ethers' ZeroAddress with viem's zeroAddress is consistent with the broader migration to viem types across the SDK.


9-9: LGTM! Correct addition of signet base URL.

The addition of SIGNET_GATEWAY_BASE_URL import aligns with the removal of 'testnet' support and introduction of 'signet' network.


143-143: LGTM! Consistent network name update.

The change from 'testnet' to 'signet' is consistent with the SDK's new network naming convention.


550-563: LGTM! Enhanced fee transparency with detailed breakdown.

The new feeBreakdown structure provides better visibility into fee components (inclusion, protocol, affiliate fees). This aligns with the PR objective of enhancing fee breakdowns for off-ramp operations.


772-774: LGTM! Correct parameter order for unified executeQuote.

The updated parameter order (walletClient, publicClient, btcSigner) aligns with the refactored executeQuote method signature in the client.


622-622:

✅ Verification successful

Verify the response format change.

The mock response changed from a quoted string to a plain value. This appears to be fixing a previous inconsistency where the response was double-encoded as a JSON string.


🏁 Script executed:

#!/bin/bash
# Description: Check if other tests or actual API responses use quoted strings for addresses

# Search for similar nock mocks returning addresses to verify consistency
rg -A 2 -B 2 "get.*address.*reply.*200.*['\"]0x" --type ts

# Check for any other instances of registry address responses
rg "offramp-registry-address.*reply" --type ts -A 3

Length of output: 392


Mock response format is consistent across tests

Verified that the only other address mock in sdk/test/gateway.test.ts (/offramp-registry-address) uses a template‐literal string (.reply(201, \${zeroAddress}`)`), and no tests return a double-encoded JSON string. The change at line 622 to return a plain hex string is aligned with existing tests.

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

356-368: LGTM! Excellent fee transparency design.

The OfframpFeeBreakdown interface provides granular fee visibility, breaking down total fees into inclusion, protocol, and affiliate components. This design enhances transparency for users.


542-578: LGTM! Well-designed discriminated union for quote execution.

The ExecuteQuoteParams discriminated union provides excellent type safety by enforcing specific constraints for each quote type (onramp, offramp, stake). The chain and address type constraints ensure compile-time safety.


373-374:

✅ Verification successful

Verify precision requirements for satoshi amounts.

The change from bigint to number for amountLockInSat is safe for typical Bitcoin amounts (up to ~90 million BTC), but consider if there are any edge cases that might require bigint precision.


🏁 Script executed:

#!/bin/bash
# Description: Check if there are any large satoshi amount calculations that might overflow

# Search for satoshi amount calculations and conversions
rg "amountLockInSat|satoshis?" --type ts -B 2 -A 2 | grep -E "(BigInt|Number|parseInt|parseFloat|\* 10\*\*)"

# Check for any existing bigint satoshi handling
ast-grep --pattern 'BigInt($_)'

Length of output: 5181


No precision concerns for OfframpQuote numeric type change

We’ve verified that both amountLockInSat and deadline (now number) are immediately converted back to BigInt in the gateway client, and typical satoshi values (≤ 9×10^15) and Unix timestamps stay well within the 2^53−1 safe-integer limit. No precision loss will occur.

• sdk/src/gateway/client.ts (≈lines 330–332):

satAmountToLock: BigInt(offrampQuote.amountLockInSat),
satFeesMax:      BigInt(offrampQuote.feeBreakdown.overallFeeSats),
orderCreationDeadline: BigInt(offrampQuote.deadline),

→ No changes required.

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

95-112: LGTM! Clear network support with proper error handling.

The constructor now clearly supports only 'mainnet', 'signet', and 'bob' networks, with appropriate error handling for invalid chains.


734-742: LGTM! Improved Bitcoin transaction handling.

The addition of hex prefix stripping and the ability to fetch transaction hex from Esplora when only a txid is provided improves the API's flexibility.

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

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

869-869: Minor: Mock response string update.

The change from '🎉' to 'request' makes the mock more realistic and professional.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between aef9038 and 6373e1e.

📒 Files selected for processing (2)
  • sdk/src/gateway/client.ts (16 hunks)
  • sdk/test/gateway.test.ts (27 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
sdk/test/gateway.test.ts (2)
sdk/src/gateway/client.ts (1)
  • MAINNET_GATEWAY_BASE_URL (68-68)
sdk/src/gateway/types.ts (3)
  • StakeParams (26-39)
  • GatewayQuote (218-235)
  • GatewayTokensInfo (334-339)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: test
🔇 Additional comments (18)
sdk/test/gateway.test.ts (7)

8-8: LGTM: Import update aligns with refactoring.

The import change correctly reflects the extraction of utility constants to a centralized location.


20-20: LGTM: Utility import moved to appropriate module.

Good refactoring - toHexScriptPubKey has been properly moved from client to the utils module, improving code organization.


48-55: LGTM: Consistent migration from ethers to viem addresses.

The replacement of ZeroAddress from ethers with zeroAddress from viem throughout the test suite ensures consistency with the new type system using viem's Address type.

Also applies to: 158-165, 208-224, 273-273, 285-285


142-142: LGTM: Network naming standardization.

The change from 'testnet' to 'signet' aligns with the client.ts changes that removed 'testnet' support and standardized on 'signet' for the test network.

Also applies to: 363-363, 449-449, 856-856, 888-888


63-69: LGTM: Parameter structure simplification.

The removal of nested params wrappers in getQuote calls reflects the streamlined API design mentioned in the AI summary.

Also applies to: 73-79, 83-89, 93-99, 103-111


555-561: LGTM: Fee breakdown structure update.

The mock response now includes detailed feeBreakdown objects instead of flat fee fields, correctly matching the new OfframpFeeBreakdown structure mentioned in the AI summary.


845-846: Good: Test properly skipped with clear reasoning.

The skip with FIXME comment clearly indicates that staking strategies are not available on signet, which aligns with the network changes.

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

1-62: LGTM: Comprehensive import reorganization improves type safety.

The import restructuring correctly integrates viem types (Address, Hex, isAddress, isAddressEqual) for better type safety and moves utility functions to a centralized utils module, improving code organization.


95-112: LGTM: Network configuration standardization.

The removal of 'testnet' support and mapping 'signet' to Chain.BOB_SEPOLIA creates cleaner network handling. This aligns with the test changes and provides better consistency.


131-148: LGTM: Enhanced method overloading with proper error handling.

The updated getQuote method with clear overloads for onramp/offramp and proper BigInt conversion improves type safety. The error message is also correctly spelled (addressing a past review comment).


150-193: LGTM: Type-safe parameter handling.

The getOnrampQuote method now uses proper typing with Address types and maintains backward compatibility with multiple input formats (chain ID, chain name, token address/symbol).


213-213: LGTM: Consistent token address resolution.

Using getTokenAddress for consistent token address resolution ensures proper handling of both token symbols and addresses.

Also applies to: 245-245


307-307: LGTM: Proper BigInt usage for token amounts.

The explicit BigInt conversion for amounts ensures type consistency throughout the offramp flow.

Also applies to: 466-466


540-542: LGTM: Enhanced address validation.

Using viem's isAddress function provides more robust EVM address validation compared to manual string checks.


552-552: LGTM: Proper type annotation for encoded data.

The explicit as Hex cast ensures the ABI encoded data meets viem's type requirements.


609-714: LGTM: Unified executeQuote method with improved type safety.

The refactored executeQuote method provides a clean, unified interface for onramp, offramp, and stake operations. The discriminated union types ensure type safety, and the BigInt conversions are consistent throughout.


758-758: LGTM: Consistent Address type usage.

The method signatures now properly use viem's Address type for all address parameters, improving type safety across the API.

Also applies to: 419-419, 887-887, 1055-1055


1017-1017: LGTM: Enhanced address validation in buildStake.

The use of isAddressEqual for address comparison and isAddress for validation provides more robust checking compared to string comparisons.

Also applies to: 1024-1024, 1030-1030

@slavastartsev slavastartsev changed the title Chore/merge interfaces feat: update gateway client api Jun 5, 2025
…into chore/merge-interfaces"

This reverts commit aef9038, reversing
changes made to 15fe8b8.
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: 3

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

144-150: Fix typo in error message (duplicate issue).

The error message contains a typo that was previously flagged.


379-379: BigInt usage inconsistency (duplicate issue).

This was previously flagged - the fee value is converted to BigInt but type system expects a number.


461-463: 8-decimal minimum constraint documentation (duplicate issue).

This limitation was previously flagged and should be documented.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ba8c00f and 887a895.

📒 Files selected for processing (4)
  • .gitmodules (1 hunks)
  • sdk/src/gateway/client.ts (15 hunks)
  • sdk/src/gateway/types.ts (7 hunks)
  • sdk/test/gateway.test.ts (27 hunks)
✅ Files skipped from review due to trivial changes (1)
  • .gitmodules
🚧 Files skipped from review as they are similar to previous changes (2)
  • sdk/test/gateway.test.ts
  • sdk/src/gateway/types.ts
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: test
🔇 Additional comments (14)
sdk/src/gateway/client.ts (14)

1-65: LGTM! Well-organized import restructuring.

The import reorganization properly consolidates Bitcoin and Viem-related utilities, and the extraction of utility functions to a separate module improves modularity and maintainability.


216-218: LGTM! Improved token address validation.

Using getTokenAddress function provides better centralized token validation compared to manual address checks.


422-422: LGTM! Improved type safety with typed Address.

The parameter type change from generic string to Address improves type safety and prevents invalid address inputs.


543-545: LGTM! Added proper address validation.

Using isAddress validation improves security by preventing invalid addresses from being processed.


555-555: LGTM! Improved type safety with Hex type.

Using the Hex type for strategyExtraData provides better type safety for hexadecimal strings.


608-637: Excellent refactoring of executeQuote method signatures.

The unified method signature using ExecuteQuoteParams improves maintainability and type safety. The overloaded signatures properly handle different parameter combinations for onramp vs offramp operations.


638-653: LGTM! Improved error handling and parameter destructuring.

The destructuring of executeQuoteParams and explicit error handling for missing btcSigner improves code clarity and prevents runtime errors.


654-694: LGTM! Consistent BigInt usage in offramp flow.

The offramp execution properly uses BigInt for amount comparisons and maintains type consistency throughout the flow.


696-733: LGTM! Improved staking flow implementation.

The staking execution uses proper parameter destructuring and maintains consistent BigInt usage for amounts.


778-778: LGTM! Consistent with other method parameter types.

The parameter type change to Address maintains consistency with other methods like getOfframpOrders.


907-907: LGTM! Improved return type specificity.

Using Address[] instead of generic EVM addresses provides better type safety for consumers of this method.


1037-1052: LGTM! Comprehensive address validation in buildStake.

The use of isAddressEqual for strategy matching and isAddress for address validation, combined with proper error messages, significantly improves the robustness of this method.


1075-1075: LGTM! Consistent typed Address parameter.

The parameter type change maintains consistency with the other order-related methods.


310-310:

✅ Verification successful

Verify BigInt usage consistency.

Using BigInt(params.amount) here but params.amount type may already be bigint. Ensure type consistency across the codebase.


🏁 Script executed:

#!/bin/bash
# Description: Check the type definition of amount parameter in OfframpQuoteParams
# Expected: Consistent bigint usage

ast-grep --pattern 'interface OfframpQuoteParams {
  $$$
  amount: $_
  $$$
}'

Length of output: 80


🏁 Script executed:

#!/bin/bash
# Search for the OfframpQuoteParams interface and its amount type
rg 'interface .*OfframpQuoteParams' -n
rg 'OfframpQuoteParams' -C3 -n

# Locate the fetchOfframpQuote method signature to inspect its parameters
rg 'fetchOfframpQuote' -n -A5

Length of output: 3816


🏁 Script executed:

#!/bin/bash
# Locate the definition of GatewayQuoteParams to inspect the type of `amount`
rg 'export (interface|type) GatewayQuoteParams' -n -A5 sdk/src/gateway/types.ts

Length of output: 352


🏁 Script executed:

#!/bin/bash
# Expand GatewayQuoteParams definition to include the `amount` field
rg 'export interface GatewayQuoteParams' -n -A20 sdk/src/gateway/types.ts

Length of output: 1025


OfframpQuoteParams.amount is number|string; BigInt conversion is correct and consistent

The OfframpQuoteParams type picks up amount: number | string from GatewayQuoteParams, and fetchOfframpQuote’s signature expects a bigint. Calling BigInt(params.amount) in getQuote is appropriate—other call sites already pass a bigint directly. No changes are needed.

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

🧹 Nitpick comments (2)
sdk/examples/gateway.ts (2)

24-33: Magic numbers & network mismatch hide intent

The example hard-codes:

  • amount: 10000000 (sats)
  • gasRefill: 10000 (sats)
  • Network.mainnet for the BTC signer while the swap uses 'bitcoin' / mainnet but targets the Bob test chain.

Consider:

  • Adding inline comments (// 0.1 BTC in sats) or helper constants for clarity.
  • Clarifying why a mainnet signer is used when the EVM side is on bob (testnet?) – this is easy to misread.

No code change required, but a brief comment prevents copy-paste errors.


35-35: Risky as Parameters<…> cast masks API drift

Forcing the result of getQuote to the input type of executeQuote relies on both staying structurally compatible.
When either signature evolves this line will silently compile and break at runtime.

If GatewaySDK#getQuote already returns the correct Quote type, widen executeQuote to accept that type instead of casting here:

-const quote = (await gatewaySDK.getQuote(quoteParams)) as Parameters<(typeof gatewaySDK)['executeQuote']>[0];
+const quote = await gatewaySDK.getQuote(quoteParams); // Quote

and update executeQuote’s signature if needed.

This preserves type-safety end-to-end.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 799ccd8 and 836b78d.

📒 Files selected for processing (1)
  • sdk/examples/gateway.ts (1 hunks)
🧰 Additional context used
🪛 Gitleaks (8.26.0)
sdk/examples/gateway.ts

7-7: 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 (1)
  • GitHub Check: test
🔇 Additional comments (2)
sdk/examples/gateway.ts (2)

7-7: False positive from Gitleaks – token address is public

The constant value flagged by Gitleaks is an on-chain ERC-20 address, not a secret.
Nothing to do here.


15-19: ```shell
#!/bin/bash

Locate the gateway example and display its initial lines

rg "gateway.ts" -l
sed -n '1,200p' sdk/examples/gateway.ts


</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

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: 3

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

614-617: Typo + missing typings in overloads still unresolved
This was flagged earlier and remains:

async executeQuote(exectueQuoteParams: …   ❌ typo
async executeQuote(exectueQuoteParams: …   ❌ typo

Provide correct spelling and strong types for clients.


665-667: Same in off-ramp branch – clone before writing

Repeat the cloning pattern here to keep the API side-effect-free.


647-649: Mutates caller-supplied params – surprising side-effect

params.toChain is reassigned in-place. Clone before normalising:

-            if (typeof params.toChain === 'number') {
-                params.toChain = chainIdMapping[params.toChain];
-            }
+            const localParams = { ...params };
+            if (typeof localParams.toChain === 'number') {
+                localParams.toChain = chainIdMapping[localParams.toChain];
+            }

Use localParams downstream to preserve referential transparency.

🧹 Nitpick comments (2)
sdk/src/gateway/client.ts (2)

74-79: Out-of-date JSDoc reference to “testnet”

The docstring still says @default "https://gateway-api-testnet.gobob.xyz" while the constant below points to the signet endpoint.
Update the comment to avoid confusion.

- * @default "https://gateway-api-testnet.gobob.xyz"
+ * @default "https://gateway-api-signet.gobob.xyz"

476-481: err is typed unknown – accessing err.message is unsafe

Either narrow the error type or fall back gracefully:

-        } catch (err) {
-            // Return false and 0n with an error message if fetching the quote fails
-            throw new Error(`Error fetching offramp quote: ${err.message || err}`);
+        } catch (err) {
+            const message =
+                typeof err === 'object' && err && 'message' in err ? (err as Error).message : String(err);
+            throw new Error(`Error fetching offramp quote: ${message}`);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 836b78d and c9f2315.

📒 Files selected for processing (2)
  • sdk/examples/gateway.ts (1 hunks)
  • sdk/src/gateway/client.ts (16 hunks)
🧰 Additional context used
🪛 Gitleaks (8.26.0)
sdk/examples/gateway.ts

7-7: 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 (1)
  • GitHub Check: test
🔇 Additional comments (2)
sdk/examples/gateway.ts (2)

20-21: Bitcoin signer instantiation is incomplete

XverseConnector typically needs a .connect() / .getSigner() flow before it can sign PSBTs.
Document or include that extra step, otherwise btcSigner.signAllInputs may be undefined at runtime.


24-33: Hard-coded token address flagged by gitleaks is benign

The constant BOB_TBTC_V2_TOKEN_ADDRESS is an on-chain contract address, not a secret key.
No remediation needed – consider suppressing the false-positive in your gitleaks config.

Signed-off-by: Gregory Hill <gregorydhill@outlook.com>
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 (4)
sdk/examples/gateway.ts (1)

15-19: zeroAddress placeholder breaks signing – still not fixed
The wallet client is instantiated with account: zeroAddress, so any later transaction signing (e.g. inside executeQuote) will revert. Replace with the connected EOA.

-    const walletClient = createWalletClient({
-        chain: bob,
-        transport: http(),
-        account: zeroAddress, // Use connected address here
-    });
+    const walletClient = createWalletClient({
+        chain: bob,
+        transport: http(),
+        account: evmAddress, // or the connected signer address
+    });
sdk/src/gateway/client.ts (3)

659-661: Same in-place mutation of params.fromChain
See comment above: clone before rewriting.


605-607: Overload signatures still use implicit any for clients
Previous review pointed this out; the overload declarations leak any, undermining type-safety.

-async executeQuote(executeQuoteParams: OnrampExecuteQuoteParams, clients): Promise<string>;
-async executeQuote(executeQuoteParams: OfframpExecuteQuoteParams, clients): Promise<string>;
+async executeQuote(
+  executeQuoteParams: OnrampExecuteQuoteParams,
+  clients: { walletClient: WalletClient<Transport, ViemChain, Account>; publicClient: PublicClient<Transport>; btcSigner: { signAllInputs(psbt: string): Promise<string> } }
+): Promise<string>;
+async executeQuote(
+  executeQuoteParams: OfframpExecuteQuoteParams,
+  clients: { walletClient: WalletClient<Transport, ViemChain, Account>; publicClient: PublicClient<Transport> }
+): Promise<string>;

149-156: params.toChain may be undefined, will throw on .toString()
When fromChain !== 'bitcoin', nothing guarantees toChain is present. Calling params.toChain.toString() on undefined throws before you reach the “Invalid quote arguments” check.

-        } else if (params.toChain.toString().toLowerCase() === 'bitcoin') {
+        } else if (params.toChain && params.toChain.toString().toLowerCase() === 'bitcoin') {
             ...
-            if (!params.fromToken) {
+            if (!params.toChain) {
+                throw new Error('`toChain` must be specified for offramp');
+            }
+            if (!params.fromToken) {
                 throw new Error('`fromToken` must be specified for offramp');
             }
🧹 Nitpick comments (4)
sdk/examples/gateway.ts (2)

24-32: Unused _quoteMaxOnramp variable
_quoteMaxOnramp is fetched but never referenced. Dead code hurts readability and confuses IDE/linters.

-    const _quoteMaxOnramp = await gatewaySDK.getQuote({
+    // Drop this call unless you intend to use the result
+    /* const _quoteMaxOnramp = await gatewaySDK.getQuote({
         ...
-    });
+    }); */

1-70: Formatting fails Prettier check
CI reports a Prettier violation for this file. Run pnpm prettier --write sdk/examples/gateway.ts to avoid blocking merges.

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

639-641: Mutates caller-supplied params (toChain) in-place
Directly rewriting params.toChain surprises callers who reuse the object.

-            if (typeof params.toChain === 'number') {
-                params.toChain = chainIdMapping[params.toChain];
-            }
+            const localParams = { ...params };
+            if (typeof localParams.toChain === 'number') {
+                localParams.toChain = chainIdMapping[localParams.toChain];
+            }

Apply the same pattern for the fromChain branch below (lines 659-661).


1-1: Prettier formatting check failed for this file
Run prettier --write sdk/src/gateway/client.ts to satisfy CI.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c9f2315 and ffcdfef.

📒 Files selected for processing (3)
  • sdk/examples/gateway.ts (1 hunks)
  • sdk/src/gateway/client.ts (19 hunks)
  • sdk/src/gateway/types.ts (7 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • sdk/src/gateway/types.ts
🧰 Additional context used
🪛 GitHub Actions: SDK
sdk/src/gateway/client.ts

[warning] 1-1: Prettier formatting check failed. Run 'prettier --write' to fix code style issues in this file.

sdk/examples/gateway.ts

[warning] 1-1: Prettier formatting check failed. Run 'prettier --write' to fix code style issues in this file.

🪛 Gitleaks (8.26.0)
sdk/examples/gateway.ts

7-7: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🔇 Additional comments (1)
sdk/src/gateway/client.ts (1)

675-677: ```shell
#!/bin/bash

Display context around the allowance comparison to inspect how 'allowance' is obtained and its units.

sed -n '650,740p' sdk/src/gateway/client.ts


</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

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: 3

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

146-147: Guard against missing toChain before calling .toString()

params.toChain is accessed unconditionally. When the caller omits this field (e.g. in an on-ramp flow) the expression throws before your own validation kicks in.

- } else if (params.toChain.toString().toLowerCase() === 'bitcoin') {
+ } else if (params.toChain && params.toChain.toString().toLowerCase() === 'bitcoin') {

596-598: Overload signatures leak any – type the clients parameter

Both overloads declare clients without a type, undoing the benefit of the strongly-typed implementation that follows.

-async executeQuote(executeQuoteParams: OnrampExecuteQuoteParams, clients): Promise<string>;
-async executeQuote(executeQuoteParams: OfframpExecuteQuoteParams, clients): Promise<string>;
+async executeQuote(
+  executeQuoteParams: OnrampExecuteQuoteParams,
+  clients: { walletClient: WalletClient<Transport, ViemChain, Account>; publicClient: PublicClient<Transport>; btcSigner: { signAllInputs(psbt: string): Promise<string> } }
+): Promise<string>;
+async executeQuote(
+  executeQuoteParams: OfframpExecuteQuoteParams,
+  clients: { walletClient: WalletClient<Transport, ViemChain, Account>; publicClient: PublicClient<Transport>; }
+): Promise<string>;
🧹 Nitpick comments (3)
sdk/src/gateway/client.ts (1)

666-668: Clarify TODO – fee comparison mixes units

The comment hints at possible unit confusion (sat vs token amount). Confirm the business rule and replace the TODO with explicit validation or conversion to prevent incorrect allowance checks.

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

648-657: Hard-coded private key-like strings flagged by scanners

Static analysis tagged these hex literals as “generic API keys”. They appear to be test addresses, but consider replacing with clearly dummy constants (e.g. '0xdead...beef') to avoid audit noise.


839-843: Simulated contract response uses placeholder '🎉'

simulateContract stubs return { request: '🎉' }. A non-hex string risks failing stricter type guards. Returning a deterministic hex (e.g. '0x1234') keeps the intent while remaining valid.

Also applies to: 899-903

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ffcdfef and f5eee7b.

📒 Files selected for processing (4)
  • sdk/examples/gateway.ts (1 hunks)
  • sdk/src/gateway/client.ts (16 hunks)
  • sdk/src/gateway/types.ts (6 hunks)
  • sdk/test/gateway.test.ts (27 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • sdk/examples/gateway.ts
  • sdk/src/gateway/types.ts
🧰 Additional context used
🪛 Gitleaks (8.26.0)
sdk/test/gateway.test.ts

646-646: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


649-649: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


764-764: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (3)
sdk/examples/gateway.ts (1)

15-20: zeroAddress placeholder still blocks transaction signing

The wallet client is instantiated with account: zeroAddress, so any subsequent walletClient.writeContract or executeQuote call will revert because there is no private key associated with the all-zero account. Replace the placeholder with the connected EOA (or remove the field and let walletClient infer the account from the connector).

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

146-147: params.toChain may be undefined – add a null-check before .toString()

If callers omit toChain (only supplying fromChain), the expression params.toChain.toString() will throw. Guard early:

if (!params.toChain) {
    throw new Error('`toChain` must be specified');
}
if (params.toChain.toString().toLowerCase() === 'bitcoin') 

596-599: Overload signatures still leak any – type the clients parameter

The two overloads keep clients untyped, so every call site falls back to any, nullifying the benefit of strong typings added in the implementation. Re-use the object-literal type used below:

-async executeQuote(executeQuoteParams: OnrampExecuteQuoteParams, clients): Promise<string>;
-async executeQuote(executeQuoteParams: OfframpExecuteQuoteParams, clients): Promise<string>;
+async executeQuote(
+    executeQuoteParams: OnrampExecuteQuoteParams,
+    clients: { walletClient: WalletClient<Transport, ViemChain, Account>; publicClient: PublicClient<Transport>; btcSigner: { signAllInputs(psbtBase64: string): Promise<string> } }
+): Promise<string>;
+async executeQuote(
+    executeQuoteParams: OfframpExecuteQuoteParams,
+    clients: { walletClient: WalletClient<Transport, ViemChain, Account>; publicClient: PublicClient<Transport>; }
+): Promise<string>;
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f5eee7b and fb97f29.

📒 Files selected for processing (2)
  • sdk/examples/gateway.ts (1 hunks)
  • sdk/src/gateway/client.ts (17 hunks)
🧰 Additional context used
🧠 Learnings (1)
sdk/src/gateway/client.ts (1)
Learnt from: slavastartsev
PR: bob-collective/bob#634
File: sdk/src/gateway/client.ts:136-140
Timestamp: 2025-06-17T11:18:53.153Z
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.
🧬 Code Graph Analysis (1)
sdk/src/gateway/client.ts (5)
sdk/src/gateway/strategy.ts (1)
  • StrategyClient (163-358)
sdk/src/gateway/types.ts (11)
  • GetQuoteParams (544-544)
  • GatewayQuote (223-240)
  • GatewayTokensInfo (339-344)
  • OfframpQuote (376-387)
  • OfframpCreateOrderParams (400-421)
  • OfframpOrder (448-469)
  • GatewayStartOrder (353-357)
  • OnrampExecuteQuoteParams (546-549)
  • OfframpExecuteQuoteParams (551-554)
  • ExecuteQuoteParams (558-558)
  • chainIdMapping (23-26)
sdk/src/gateway/tokens.ts (1)
  • getTokenAddress (372-386)
sdk/src/wallet/utxo.ts (1)
  • getAddressInfo (22-24)
sdk/src/gateway/utils.ts (1)
  • toHexScriptPubKey (29-33)
🪛 Gitleaks (8.26.0)
sdk/examples/gateway.ts

7-7: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

Comment on lines +44 to +51
const offrampQuote = await gatewaySDK.getQuote({
fromChain: 'bob',
fromToken: BOB_TBTC_V2_TOKEN_ADDRESS, // or "tBTC"
toChain: 'bitcoin',
toUserAddress: 'bc1qafk4yhqvj4wep57m62dgrmutldusqde8adh20d',
toToken: 'BTC',
amount: 10000000, // 0.1 BTC
});
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Possible unit mismatch – amount for off-ramp quote must be in token decimals, not satoshis

getQuote interprets amount as wrapped-token units (tBTC, 18 dec by default), but the example passes 10_000_000, i.e. 0.00000001 tBTC, while the comment says “0.1 BTC”.
Convert the desired BTC value to wrapped-token decimals before calling:

-        amount: 10000000, // 0.1 BTC
+        // 0.1 BTC in 18-dec wrapped token units
+        amount: 0.1 * 10 ** 18,

(or compute it programmatically to avoid FP error).

📝 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.

Suggested change
const offrampQuote = await gatewaySDK.getQuote({
fromChain: 'bob',
fromToken: BOB_TBTC_V2_TOKEN_ADDRESS, // or "tBTC"
toChain: 'bitcoin',
toUserAddress: 'bc1qafk4yhqvj4wep57m62dgrmutldusqde8adh20d',
toToken: 'BTC',
amount: 10000000, // 0.1 BTC
});
const offrampQuote = await gatewaySDK.getQuote({
fromChain: 'bob',
fromToken: BOB_TBTC_V2_TOKEN_ADDRESS, // or "tBTC"
toChain: 'bitcoin',
toUserAddress: 'bc1qafk4yhqvj4wep57m62dgrmutldusqde8adh20d',
// 0.1 BTC in 18-decimal wrapped-token units
amount: 0.1 * 10 ** 18,
});
🤖 Prompt for AI Agents
In sdk/examples/gateway.ts around lines 44 to 51, the amount passed to getQuote
is incorrectly specified in satoshis instead of wrapped-token decimals. To fix
this, convert the BTC amount (0.1 BTC) to the equivalent value in wrapped-token
decimals (18 decimals) before passing it as the amount parameter. This can be
done by multiplying 0.1 by 10^18 or computing it programmatically to avoid
floating point errors.

Comment on lines +667 to 669
// TODO: is this sat or token amount?
if (BigInt(quote.amountLockInSat) > allowance) {
const { request } = await publicClient.simulateContract({
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Allowance check compares satoshis to ERC-20 units – always fails for real amounts

quote.amountLockInSat is in satoshis (8 dec) while allowance is in the token’s own decimals (usually 18). The current comparison will typically think the allowance is sufficient when it is not (or vice-versa). Convert the satoshi amount to token units first:

-            // TODO: is this sat or token amount?
-            if (BigInt(quote.amountLockInSat) > allowance) {
+            const decimals = getTokenDecimals(tokenAddress) ?? 18;
+            const amountInToken = BigInt(quote.amountLockInSat) * BigInt(10 ** (decimals - 8));
+
+            if (amountInToken > allowance) {

This mirrors the conversion done in getBumpFeeRequirement.

📝 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.

Suggested change
// TODO: is this sat or token amount?
if (BigInt(quote.amountLockInSat) > allowance) {
const { request } = await publicClient.simulateContract({
const decimals = getTokenDecimals(tokenAddress) ?? 18;
const amountInToken = BigInt(quote.amountLockInSat) * BigInt(10 ** (decimals - 8));
if (amountInToken > allowance) {
const { request } = await publicClient.simulateContract({
// …
🤖 Prompt for AI Agents
In sdk/src/gateway/client.ts around lines 667 to 669, the allowance check
incorrectly compares satoshis (quote.amountLockInSat) directly to the token
allowance, which uses different decimals (usually 18). To fix this, convert
quote.amountLockInSat from satoshis to the token's decimal units before
comparing it to allowance, following the same conversion approach used in
getBumpFeeRequirement.

@gregdhill gregdhill merged commit 2509201 into master Jun 18, 2025
7 of 8 checks passed
@gregdhill gregdhill deleted the chore/merge-interfaces branch June 18, 2025 07:53
This was referenced Aug 29, 2025
@coderabbitai coderabbitai bot mentioned this pull request Oct 15, 2025
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.

4 participants