Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DNM] fix(sdk-router): use /rfq endpoint for calculating the RFQ quote [SLT-436] #3373

Open
wants to merge 24 commits into
base: master
Choose a base branch
from

Conversation

ChiTimesChi
Copy link
Collaborator

@ChiTimesChi ChiTimesChi commented Nov 6, 2024

Description

WIP, will match the description below once completed

Summary by CodeRabbit

  • New Features

    • Introduced a new utility function for address comparison.
    • Added a function to retrieve the best relayer quote with improved error handling.
  • Bug Fixes

    • Enhanced address comparison in various functions to ensure robust equality checks.
  • Tests

    • Expanded test coverage for the new relayer quote functionality and address comparison utility.
    • Removed outdated tests related to the applyQuote function.
  • Refactor

    • Simplified logic for fetching and filtering tickers in the FastBridgeRouterSet class.
    • Updated method signatures to reflect changes in functionality.

68d91fb: synapse-interface preview link
1560611: synapse-interface preview link

Copy link
Contributor

coderabbitai bot commented Nov 6, 2024

Walkthrough

The changes in this pull request primarily involve the introduction of a new utility function isSameAddress for address comparison, replacing inline comparisons in various modules. The getModuleWithAddress method in synapseModuleSet.ts has been updated accordingly. Additionally, multiple tests have been enhanced or added for the getAllQuotes and getBestRelayerQuote functions, improving test coverage. The FastBridgeRouterSet class has undergone significant refactoring to focus on tickers instead of quotes, and several functions related to quotes have been removed or altered to reflect these changes.

Changes

File Path Change Summary
packages/sdk-router/src/module/synapseModuleSet.ts Introduced isSameAddress utility function; updated getModuleWithAddress to use this function.
packages/sdk-router/src/rfq/api.integration.test.ts Renamed getAllQuotes test; added new test suite for getBestRelayerQuote with multiple scenarios.
packages/sdk-router/src/rfq/api.test.ts Added tests for getBestRelayerQuote; modified existing tests to align with new promise structure.
packages/sdk-router/src/rfq/api.ts Added types PutRFQRequestAPI, PutRFQResponseAPI, RelayerQuote; introduced getBestRelayerQuote function.
packages/sdk-router/src/rfq/fastBridgeRouterSet.ts Refactored methods to focus on tickers; renamed and updated filtering logic.
packages/sdk-router/src/rfq/quote.test.ts Removed tests related to applyQuote function; eliminated associated helper functions.
packages/sdk-router/src/rfq/quote.ts Removed applyQuote function, altering quote application logic.
packages/sdk-router/src/utils/addressUtils.test.ts Added comprehensive test suite for isSameAddress function covering various scenarios.
packages/sdk-router/src/utils/addressUtils.ts Introduced isSameAddress function for case-insensitive address comparison.
packages/sdk-router/src/utils/handleNativeToken.ts Updated isNativeToken to use isSameAddress for address comparison.
packages/sdk-router/src/utils/logs.ts Modified getMatchingTxLog to use isSameAddress for log address comparison.

Possibly related PRs

  • feat(synapse-interface): bridge quote uuid #2900: This PR introduces a new property pendingLabel to the BridgeTransactionButton component, which is related to the handling of bridge transactions, similar to the changes made in the main PR regarding address comparisons in the getModuleWithAddress method.
  • feat(sdk-router)!: add support for FastBridgeRouterV2 #2957: The changes in this PR involve the introduction of a new BridgeQuoteOptions interface, which may relate to the overall structure and handling of bridge transactions, connecting to the refactoring done in the main PR.
  • feat(contracts-rfq): rework permisionless cancellation [SLT-489] #3382: This PR focuses on enhancing the cancellation functionality within the RFQ contracts, which may relate to the overall transaction handling and logic improvements seen in the main PR.
  • Updating the bridge map #3400: The removal of the WLD token from the bridge map indicates a restructuring of token handling, which aligns with the changes made in the main PR regarding address comparisons and transaction handling.

Suggested labels

needs-go-generate-contrib/promexporter

Suggested reviewers

  • aureliusbtc
  • trajan0x
  • bigboydiamonds
  • abtestingalpha

🐰 In the code we hop and play,
New functions come to light today.
With tests that check and verify,
Our changes soar, they reach the sky!
Address checks now smooth and bright,
In our code, all feels just right! 🌟


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ 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.
    • Generate unit testing code for this file.
    • 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 generate unit testing code for this file.
    • @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 generate unit testing code.
    • @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.

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

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

cloudflare-workers-and-pages bot commented Nov 6, 2024

Deploying sanguine-fe with  Cloudflare Pages  Cloudflare Pages

Latest commit: 2a0dff3
Status: ✅  Deploy successful!
Preview URL: https://88a6aa6a.sanguine-fe.pages.dev
Branch Preview URL: https://feat-sdk-rfq-endpoint.sanguine-fe.pages.dev

View logs

Copy link

codecov bot commented Nov 6, 2024

Codecov Report

Attention: Patch coverage is 79.62963% with 11 lines in your changes missing coverage. Please review.

Project coverage is 34.22366%. Comparing base (aec6dce) to head (e1a1a77).
Report is 47 commits behind head on master.

Files with missing lines Patch % Lines
packages/sdk-router/src/rfq/fastBridgeRouterSet.ts 44.44444% 10 Missing ⚠️
packages/sdk-router/src/rfq/api.ts 96.15385% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@                 Coverage Diff                  @@
##              master       #3373          +/-   ##
====================================================
+ Coverage   13.60118%   34.22366%   +20.62248%     
====================================================
  Files            313         525         +212     
  Lines          30490       33471        +2981     
  Branches          82          86           +4     
====================================================
+ Hits            4147       11455        +7308     
+ Misses         25869       21000        -4869     
- Partials         474        1016         +542     
Flag Coverage Δ
explorer ?
packages 90.30418% <79.62963%> (-0.14416%) ⬇️
promexporter ?

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link

codecov bot commented Nov 8, 2024

Bundle Report

Changes will decrease total bundle size by 3.51MB (-9.84%) ⬇️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
sdk-router-@synapsecns/sdk-router-esm 260.32kB 5.67kB (2.22%) ⬆️
sdk-router-@synapsecns/sdk-router-cjs 119.31kB 2.07kB (1.76%) ⬆️
explorer-ui-server-cjs* 724.74kB 141.33kB (-16.32%) ⬇️
explorer-ui-client-array-push* 2.17MB 146.44kB (-6.33%) ⬇️
synapse-interface-client-array-push 7.41MB 134.08kB (1.84%) ⬆️
synapse-interface-server-cjs 1.66MB 162.1kB (10.85%) ⬆️
widget-cjs-esm* 271.27kB 2.03kB (-0.74%) ⬇️
docs-bridge-client-array-push* 7.34MB 564.21kB (-7.14%) ⬇️
docs-bridge-server-cjs* 11.57MB 3.31MB (-22.22%) ⬇️
synapse-constants-esm-cjs* 174.63kB 174.63kB (100%) ⬆️
synapse-constants-cjs-esm* 174.18kB 174.18kB (100%) ⬆️

ℹ️ *Bundle size includes cached data from a previous commit

@ChiTimesChi ChiTimesChi changed the title [WIP] fix(sdk-router): use /rfq endpoint for calculating the RFQ quote [SLT-436] [DNM] fix(sdk-router): use /rfq endpoint for calculating the RFQ quote [SLT-436] Nov 11, 2024
@ChiTimesChi
Copy link
Collaborator Author

@coderabbitai full review

Copy link
Contributor

coderabbitai bot commented Nov 11, 2024

✅ Actions performed

Full review triggered.

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

🧹 Outside diff range and nitpick comments (15)
packages/sdk-router/src/utils/addressUtils.ts (1)

1-3: Basic implementation looks good but needs address validation.

The function correctly handles case-insensitive comparison and null/undefined checks. However, as this is used in a blockchain context, it should validate the address format.

Consider adding address format validation:

 export const isSameAddress = (addr1?: string, addr2?: string): boolean => {
+  const isValidAddress = (addr?: string) => {
+    return typeof addr === 'string' && 
+           addr.startsWith('0x') && 
+           addr.length === 42 &&
+           /^0x[0-9a-f]{40}$/i.test(addr)
+  }
+  if (!addr1 || !addr2 || !isValidAddress(addr1) || !isValidAddress(addr2)) {
+    return false
+  }
   return addr1.toLowerCase() === addr2.toLowerCase()
 }

For better performance in hot paths, consider caching the lowercase results:

 export const isSameAddress = (addr1?: string, addr2?: string): boolean => {
+  // Cache lowercase addresses in a WeakMap if this function is called frequently
+  const lowercaseCache = new WeakMap<string, string>()
+  const toLowerCached = (addr: string) => {
+    if (!lowercaseCache.has(addr)) {
+      lowercaseCache.set(addr, addr.toLowerCase())
+    }
+    return lowercaseCache.get(addr)!
+  }
   return !!addr1 && !!addr2 && toLowerCached(addr1) === toLowerCached(addr2)
 }
packages/sdk-router/src/rfq/quote.test.ts (1)

Line range hint 10-44: Consider adding validation tests for quote data

The test data includes critical fields like addresses and amounts, but there are no tests verifying input validation. Consider adding tests for:

  • Invalid addresses
  • Negative or zero amounts
  • Mismatched chain IDs

Example test cases to add:

it('should throw on invalid addresses', () => {
  const invalidQuoteAPI = {
    ...quoteAPI,
    origin_token_addr: '0xinvalid'
  }
  expect(() => unmarshallFastBridgeQuote(invalidQuoteAPI)).toThrow()
})

it('should throw on negative amounts', () => {
  const invalidQuoteAPI = {
    ...quoteAPI,
    dest_amount: '-1000'
  }
  expect(() => unmarshallFastBridgeQuote(invalidQuoteAPI)).toThrow()
})
packages/sdk-router/src/rfq/api.integration.test.ts (3)

8-10: Consider investigating and addressing test flakiness

The presence of retry logic suggests these tests are unstable. While retrying is a valid temporary solution, it would be beneficial to:

  1. Investigate the root cause of the flakiness
  2. Add comments documenting known causes of instability
  3. Consider implementing more robust test setup/teardown

33-43: Expand test coverage for successful quote scenarios

Consider adding test cases for:

  1. Different token pairs (not just ETH to ETH)
  2. Various amount ranges
  3. Validation of quote calculation accuracy
  4. Verification of all returned quote fields

45-79: Enhance error validation in zero quote tests

The test structure and cleanup are well implemented. However, consider:

  1. Validating the specific error messages being logged
  2. Adding assertions for expected error conditions
  3. Testing additional edge cases (e.g., zero amount)
- expect(console.error).toHaveBeenCalled()
+ expect(console.error).toHaveBeenCalledWith(
+   expect.stringContaining('expected error message')
+ )
packages/sdk-router/src/utils/addressUtils.test.ts (3)

1-11: Consider adding documentation for test addresses

The test data setup is well-structured, but could benefit from documentation explaining:

  • Why these specific addresses were chosen
  • How the checksum variants were generated
  • What the last digit difference signifies

Add JSDoc comments above the constant declarations:

+/** Test address for Alice, intentionally differing from Bob's address in last digit */
 const lowerCaseAlice = '0x0123456789abcdef0123456789abcdef01234567'
+/** EIP-55 checksummed version of Alice's address */
 const checkSumdAlice = '0x0123456789abcDEF0123456789abCDef01234567'

5-5: Fix typo in variable name 'checkSumd'

The variable name contains a typo: checkSumd should be checkSummed

-const checkSumdAlice = '0x0123456789abcDEF0123456789abCDef01234567'
+const checkSummedAlice = '0x0123456789abcDEF0123456789abCDef01234567'
-      expect(isSameAddress(checkSumdAlice, checkSumdAlice)).toBe(true)
-      expect(isSameAddress(checkSumdBob, checkSumdBob)).toBe(true)
+      expect(isSameAddress(checkSummedAlice, checkSummedAlice)).toBe(true)
+      expect(isSameAddress(checkSummedBob, checkSummedBob)).toBe(true)

Also applies to: 19-19, 20-20


106-107: Consider improving TypeScript type handling

Instead of using type assertions with as any, consider creating a proper type for the function parameters that allows null.

-      expect(isSameAddress(null as any, lowerCaseAlice)).toBe(false)
-      expect(isSameAddress(lowerCaseAlice, null as any)).toBe(false)
-      expect(isSameAddress(null as any, null as any)).toBe(false)
+      expect(isSameAddress(null as Address | null, lowerCaseAlice)).toBe(false)
+      expect(isSameAddress(lowerCaseAlice, null as Address | null)).toBe(false)
+      expect(isSameAddress(null as Address | null, null as Address | null)).toBe(false)

Consider adding a type definition in the main utility file:

type Address = string;

Also applies to: 111-111

packages/sdk-router/src/rfq/api.test.ts (1)

119-261: Great test coverage, consider adding edge cases

The test suite is comprehensive and well-structured, covering success scenarios, timeouts, missing fields, and error conditions. Consider adding these edge cases:

  1. Malformed dest_amount that isn't parseable
  2. Negative dest_amount
  3. Extremely large dest_amount (near max safe integer)

Here's a suggested implementation:

it('when the response dest_amount is malformed', async () => {
  const responseWithMalformedAmount = { ...quoteFound, dest_amount: 'not-a-number' }
  fetchMock.mockResponseOnce(JSON.stringify(responseWithMalformedAmount))
  const result = await getBestRelayerQuote(ticker, bigAmount, userAddress)
  expect(result).toEqual(quoteZero)
  expect(console.error).toHaveBeenCalled()
})

it('when the response dest_amount is negative', async () => {
  const responseWithNegativeAmount = { ...quoteFound, dest_amount: '-1000' }
  fetchMock.mockResponseOnce(JSON.stringify(responseWithNegativeAmount))
  const result = await getBestRelayerQuote(ticker, bigAmount, userAddress)
  expect(result).toEqual(quoteZero)
  expect(console.error).toHaveBeenCalled()
})

it('when the response dest_amount is extremely large', async () => {
  const responseWithLargeAmount = { 
    ...quoteFound, 
    dest_amount: '115792089237316195423570985008687907853269984665640564039457584007913129639935' // 2^256 - 1
  }
  fetchMock.mockResponseOnce(JSON.stringify(responseWithLargeAmount))
  const result = await getBestRelayerQuote(ticker, bigAmount, userAddress)
  expect(result).toEqual(quoteZero)
  expect(console.error).toHaveBeenCalled()
})
packages/sdk-router/src/rfq/api.ts (3)

26-26: Reminder: Make integrator_id a required field

There is a TODO comment indicating that integrator_id should be made required in the PutRFQRequestAPI type. Addressing this will ensure that integrator identification is consistently provided in API requests.

Would you like assistance in updating the type definition and related code to make integrator_id required?


Line range hint 90-90: Follow-up on TODO: Add active quotes once fixed

The TODO comment suggests adding active quotes to the quote_types array when they are fixed. Please ensure this is tracked so that active quotes can be integrated into the RFQ process promptly.

Let me know if you'd like me to open a GitHub issue to track this task.


110-117: Enhance response validation and error handling

Currently, the code checks if rfqResponse.success is false but does not handle cases where success might be undefined or missing. Strengthening the validation can prevent unexpected errors.

Consider updating the condition to explicitly check for truthiness:

- if (!rfqResponse.success) {
+ if (rfqResponse.success !== true) {

Additionally, ensure that all necessary fields are present and valid before proceeding.

packages/sdk-router/src/rfq/fastBridgeRouterSet.ts (3)

120-131: Consider adding tests for getBestRelayerQuote integration

The code block starting at line 120, where getBestRelayerQuote is used within filteredTickers.map, is not covered by tests according to static analysis tools. Adding unit tests for this integration would enhance reliability and ensure that the quote retrieval logic behaves as expected.

Would you like assistance in writing unit tests for this code segment?

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 120-120: packages/sdk-router/src/rfq/fastBridgeRouterSet.ts#L120
Added line #L120 was not covered by tests


271-274: Add tests for getOriginAmountOut usage

The call to getOriginAmountOut at line 271 within filterTickersWithPossibleSwap is not covered by tests. Including tests for this method call would help verify that the origin queries are correctly generated for the provided tickers.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 271-271: packages/sdk-router/src/rfq/fastBridgeRouterSet.ts#L271
Added line #L271 was not covered by tests


314-314: Address the TODO: "don't filter by age here"

There is a TODO comment at line 314 indicating that age filtering should not occur here. Consider moving the age filtering logic to the appropriate place or clarify if age filtering is needed at this step.

Would you like assistance in refactoring this logic?

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 36efe55 and e0127e3.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (12)
  • packages/sdk-router/src/module/synapseModuleSet.ts (2 hunks)
  • packages/sdk-router/src/rfq/api.integration.test.ts (1 hunks)
  • packages/sdk-router/src/rfq/api.test.ts (3 hunks)
  • packages/sdk-router/src/rfq/api.ts (2 hunks)
  • packages/sdk-router/src/rfq/fastBridgeRouterSet.ts (3 hunks)
  • packages/sdk-router/src/rfq/quote.test.ts (1 hunks)
  • packages/sdk-router/src/rfq/quote.ts (0 hunks)
  • packages/sdk-router/src/sdk.ts (1 hunks)
  • packages/sdk-router/src/utils/addressUtils.test.ts (1 hunks)
  • packages/sdk-router/src/utils/addressUtils.ts (1 hunks)
  • packages/sdk-router/src/utils/handleNativeToken.ts (2 hunks)
  • packages/synapse-interface/package.json (1 hunks)
💤 Files with no reviewable changes (1)
  • packages/sdk-router/src/rfq/quote.ts
🧰 Additional context used
🪛 GitHub Check: codecov/patch
packages/sdk-router/src/rfq/fastBridgeRouterSet.ts

[warning] 120-120: packages/sdk-router/src/rfq/fastBridgeRouterSet.ts#L120
Added line #L120 was not covered by tests


[warning] 133-134: packages/sdk-router/src/rfq/fastBridgeRouterSet.ts#L133-L134
Added lines #L133 - L134 were not covered by tests


[warning] 271-271: packages/sdk-router/src/rfq/fastBridgeRouterSet.ts#L271
Added line #L271 was not covered by tests


[warning] 277-277: packages/sdk-router/src/rfq/fastBridgeRouterSet.ts#L277
Added line #L277 was not covered by tests


[warning] 319-319: packages/sdk-router/src/rfq/fastBridgeRouterSet.ts#L319
Added line #L319 was not covered by tests


[warning] 322-322: packages/sdk-router/src/rfq/fastBridgeRouterSet.ts#L322
Added line #L322 was not covered by tests


[warning] 324-324: packages/sdk-router/src/rfq/fastBridgeRouterSet.ts#L324
Added line #L324 was not covered by tests

🔇 Additional comments (14)
packages/sdk-router/src/utils/handleNativeToken.ts (1)

5-5: LGTM! Clean import of the address utility

The addition of the isSameAddress import follows good practices and maintains clean import organization.

packages/sdk-router/src/rfq/quote.test.ts (2)

Line range hint 46-52: LGTM! The marshalling tests are well-structured.

The bi-directional conversion tests are clear and focused. They properly verify the data transformation between API and internal representations.


Line range hint 1-52: Verify test coverage after removing applyQuote tests

While the marshalling tests are well-implemented, the removal of several test cases (applyQuote related tests) has significantly reduced the test coverage. Please ensure that the quote calculation functionality is now properly tested wherever it has been moved to (likely in the API integration tests).

✅ Verification successful

Let me gather more specific information about the quote calculation tests.


Based on the results from our verification scripts, I can now provide a final response:

The removal of applyQuote tests is justified as the functionality is covered elsewhere

The verification shows that quote-related functionality has been moved to a more appropriate location in the API integration tests (packages/sdk-router/src/rfq/api.integration.test.ts), which now includes:

  • Tests for successful quote calculations with non-zero amounts
  • Edge case tests for zero-amount quotes
  • Integration with actual relayer responses

The original test file's focus on marshalling/unmarshalling is correct as it's now a pure data transformation unit test.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for new RFQ quote calculation tests
rg -l "test|spec|describe.*rfq.*quote" --type ts

# Look for the new location of quote calculation logic
ast-grep --pattern 'function $_(quote: FastBridgeQuote, amount: $_) {
  $$$
}'

Length of output: 6512


Script:

#!/bin/bash
# Check for quote calculation tests in the API integration tests and router tests
rg -A 10 "describe.*quote|test.*quote" packages/sdk-router/src/rfq/api.integration.test.ts packages/sdk-router/src/rfq/fastBridgeRouter.test.ts

# Look for quote calculation logic in the router implementation
rg -A 10 "class.*FastBridgeRouter|function.*quote" packages/sdk-router/src/rfq/fastBridgeRouter.ts

Length of output: 2431


Script:

#!/bin/bash
# Check for quote calculation tests in the router set tests
rg -A 10 "describe.*quote|test.*quote" packages/sdk-router/src/rfq/fastBridgeRouterSet.test.ts

# Look for quote calculation logic in the router set
rg -A 10 "getQuote|calculateQuote" packages/sdk-router/src/rfq/fastBridgeRouterSet.ts

Length of output: 184

packages/sdk-router/src/rfq/api.integration.test.ts (1)

20-31: LGTM! Well-structured test setup

The test fixtures are clearly defined and use constants appropriately. The setup provides a good foundation for the test cases.

packages/sdk-router/src/sdk.ts (1)

30-30: Verify implementation status of RFQ endpoint integration

The PR objective mentions moving RFQ quote calculation to use the /rfq endpoint, but the implementation appears incomplete. The current changes only add a test build indicator.

Let's verify the implementation status:

packages/sdk-router/src/utils/addressUtils.test.ts (2)

50-80: LGTM! Comprehensive test coverage for different addresses

The test cases thoroughly cover all format combinations with bidirectional testing, ensuring robust validation of address differences.


1-1: Verify implementation of isSameAddress utility

Let's ensure the implementation exists and matches these test cases.

✅ Verification successful

Implementation of isSameAddress utility is present and matches test usage

The implementation exists in addressUtils.ts and follows a straightforward pattern:

  • Takes two optional string parameters (addr1, addr2)
  • Returns boolean after case-insensitive comparison
  • Handles undefined/null cases via truthiness checks

Implementation and tests for isSameAddress are properly aligned

The implementation correctly handles all test cases including:

  • Case-insensitive comparison of valid addresses (lowercase, uppercase, checksum)
  • Proper handling of undefined values
  • Null value checks
  • Empty string validation

The simple implementation using toLowerCase() matches the comprehensive test coverage, ensuring reliable address comparison across all scenarios.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for the isSameAddress implementation
echo "Searching for isSameAddress implementation..."
ast-grep --pattern 'export function isSameAddress($_: $_, $_: $_) {
  $$$
}'

# Verify the file exists
echo "Verifying file existence..."
fd --type f "addressUtils.ts" --exec cat {}

Length of output: 443


Script:

#!/bin/bash
# Let's verify the test cases to ensure complete coverage
cat packages/sdk-router/src/utils/addressUtils.test.ts

Length of output: 4335

packages/sdk-router/src/module/synapseModuleSet.ts (2)

9-9: LGTM! Good utility function extraction.

The addition of the isSameAddress utility import follows good software engineering practices by centralizing address comparison logic.


74-74: LGTM! Verify consistent address comparison usage.

The refactoring to use isSameAddress improves code maintainability. Let's verify that all address comparisons in the codebase follow this pattern.

packages/sdk-router/src/rfq/api.test.ts (2)

4-10: LGTM: Import changes and utility updates align with the new RFQ endpoint integration

The new imports and utility function modifications properly support the transition to using the /rfq endpoint for quote calculations.

Also applies to: 17-20


73-73: LGTM: Existing test adaptations maintain coverage

The modifications correctly adapt the existing tests to the new API response format while maintaining the same test scenarios and coverage.

Also applies to: 110-110

packages/sdk-router/src/rfq/api.ts (2)

119-124: Avoid logging sensitive information

Logging the entire rfqResponse object when an error occurs may expose sensitive data, such as user addresses or quote details.

[security]

Apply this diff to limit the logged information:

 console.error(
   'Error fetching quote: missing dest_amount or relayer_address in response:',
-  rfqResponse
+  {
+    quote_id: rfqResponse.quote_id,
+    reason: rfqResponse.reason,
+  }
 )

This change ensures that only relevant, non-sensitive information is logged.


131-134: Include null checks for optional fields

While quoteID and relayerAddress are optional in the RelayerQuote type, they are critical for downstream processes.

Please verify that the absence of quoteID or relayerAddress does not lead to issues elsewhere in the codebase. Run the following script to search for usages that assume these fields are present:

✅ Verification successful

Optional fields are handled correctly throughout the codebase

The codebase properly handles the optional nature of quoteID and relayerAddress:

  • The RelayerQuote type explicitly marks both fields as optional with ?
  • Test cases specifically cover scenarios with undefined quoteID
  • No direct property access without null checks was found
  • The only usage in integration tests uses ?. optional chaining
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find usages of RelayerQuote where quoteID or relayerAddress are assumed to be non-null.

# Search for destructuring assignments that might assume the fields are present.
rg -A2 'const.*{.*quoteID.*}.*=.*' src/

# Search for direct property accesses without null checks.
rg '\.quoteID\b' src/

Length of output: 226


Script:

#!/bin/bash
# Search for usages of quoteID and relayerAddress
rg --type-add 'ts:*.ts' --type ts -A 3 'quoteID|relayerAddress'

# Search for RelayerQuote type definition
ast-grep --pattern 'type RelayerQuote = {
  $$$
}'

Length of output: 2749

packages/sdk-router/src/rfq/fastBridgeRouterSet.ts (1)

315-316: Verify time units of quote.updatedAt when calculating age

In the calculation of age at line 315, ensure that quote.updatedAt is in milliseconds to match Date.now(). If quote.updatedAt is in seconds, you should multiply it by 1000 to convert it to milliseconds before performing the subtraction.

@@ -27,6 +27,7 @@ class SynapseSDK {
* @param {Provider[]} providers - The Ethereum providers for the respective chains.
*/
constructor(chainIds: number[], providers: Provider[]) {
console.log('GM - this is a test build')
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

Remove debug console.log statement

This debug statement should not be committed to production code as it would pollute the logs of applications using the SDK.

Apply this diff to remove the debug statement:

-    console.log('GM - this is a test build')
📝 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
console.log('GM - this is a test build')

@@ -40,7 +40,7 @@
"@reduxjs/toolkit": "^1.9.5",
"@rtk-query/graphql-request-base-query": "^2.2.0",
"@segment/analytics-next": "^1.53.0",
"@synapsecns/sdk-router": "^0.11.6",
"@synapsecns/sdk-router": "file:../sdk-router",
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

Deployment blocker: Remove local file reference

Since this is marked as DNM (Do Not Merge), remember to revert this change before deployment:

-    "@synapsecns/sdk-router": "file:../sdk-router",
+    "@synapsecns/sdk-router": "^0.11.6",

This is critical because:

  1. Local file references don't work in production environments
  2. Version pinning is important for deployment stability
📝 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
"@synapsecns/sdk-router": "file:../sdk-router",
"@synapsecns/sdk-router": "^0.11.6",

💡 Codebase verification

Local SDK reference needs to be updated before deployment

The repository structure confirms that both packages exist under packages/ directory, but using a local file reference (file:../sdk-router) instead of a versioned dependency is problematic for production deployment. This needs to be reverted to a proper version (currently other packages use ^0.11.6).

  • packages/synapse-interface/package.json: Revert to "@synapsecns/sdk-router": "^0.11.6" before merging
  • Multiple other packages (widget, rest-api) are using the versioned dependency ^0.11.6, which indicates this is the current production version
🔗 Analysis chain

Verify local SDK development setup

The change to use a local SDK version is appropriate for development, but please ensure:

  1. The local SDK build process is documented
  2. All developers can successfully build and test the changes
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if sdk-router package exists and has necessary build files
if [ -d "../sdk-router" ]; then
    echo "SDK directory exists"
    cat ../sdk-router/package.json | jq '.scripts'
    # Check for build instructions
    fd -t f "README|CONTRIBUTING" ../sdk-router
else
    echo "Error: sdk-router directory not found"
    exit 1
fi

Length of output: 120


Script:

#!/bin/bash
# Let's verify the repository structure and package locations
fd -t d "sdk-router|synapse-interface" .

# Check package.json files in the repository
fd -t f "package.json" . --exec cat {} | jq -c '{name: .name, dependencies: .dependencies}'

Length of output: 7395

packages/sdk-router/src/rfq/api.ts Show resolved Hide resolved
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

🧹 Outside diff range and nitpick comments (3)
packages/sdk-router/src/rfq/api.ts (3)

25-26: Address the TODO comment regarding integrator_id

The integrator_id should be required for proper request tracking and attribution. This is important for security and analytics purposes.

Would you like me to help implement the required integrator_id change?


114-115: Document the limitation of quote_types

The comment mentions adding active quotes later, but the current implementation only supports 'passive' quotes. Consider documenting this limitation in the function's JSDoc.

Add this to the function's documentation:

 /**
  * Hits Quoter API /rfq PUT endpoint to get the best quote for a given ticker and origin amount.
+ * Note: Currently only supports 'passive' quote types. Active quotes will be added in the future.
  *
  * @returns A promise that resolves to the best quote.
  * Will return a zero quote if the request fails or times out.
  */

133-134: Enhance error logging for better debugging

The current error messages could be more specific and include relevant context for debugging. Consider adding request details and structuring the error messages.

Improve error logging:

-      console.error('Error fetching quote:', response.statusText)
+      console.error('RFQ API request failed:', {
+        status: response.status,
+        statusText: response.statusText,
+        ticker: `${ticker.originToken.token}-${ticker.destToken.token}`,
+        chainIds: `${ticker.originToken.chainId}-${ticker.destToken.chainId}`,
+      })

-      console.error(
-        'No RFQ quote returned:',
-        rfqResponse.reason ?? 'Unknown reason'
-      )
+      console.error('RFQ API returned unsuccessful response:', {
+        reason: rfqResponse.reason ?? 'Unknown reason',
+        quoteType: rfqResponse.quote_type,
+        ticker: `${ticker.originToken.token}-${ticker.destToken.token}`,
+      })

-      console.error(
-        'Error fetching quote: missing dest_amount or relayer_address in response:',
-        rfqResponse
-      )
+      console.error('RFQ API response missing required fields:', {
+        hasDestAmount: !!rfqResponse.dest_amount,
+        hasRelayerAddress: !!rfqResponse.relayer_address,
+        quoteType: rfqResponse.quote_type,
+      })

-      console.error('No RFQ quote returned')
+      console.error('RFQ API returned zero or negative dest_amount:', {
+        destAmount: rfqResponse.dest_amount,
+        quoteType: rfqResponse.quote_type,
+      })

-      console.error('Error fetching quote:', error)
+      console.error('RFQ API request failed with error:', {
+        error: error instanceof Error ? error.message : String(error),
+        ticker: `${ticker.originToken.token}-${ticker.destToken.token}`,
+      })

Also applies to: 139-144, 146-151, 154-156, 163-164

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between e0127e3 and 1501333.

📒 Files selected for processing (2)
  • packages/sdk-router/src/rfq/api.ts (2 hunks)
  • packages/sdk-router/src/utils/logs.ts (2 hunks)
🔇 Additional comments (2)
packages/sdk-router/src/utils/logs.ts (1)

5-5: LGTM! Good modularization of address comparison logic.

The import of isSameAddress aligns with the codebase's effort to standardize address comparison operations.

packages/sdk-router/src/rfq/api.ts (1)

17-21: Consider increasing the EXPIRATION_WINDOW

The current 1000ms window might be too short for relayers to respond, especially during high network latency or congestion. Consider increasing this value to provide a more reliable window for quote responses.

Let's analyze the typical response times:

✅ Verification successful

Let me gather more specific information about RFQ timing configurations:


The EXPIRATION_WINDOW of 1000ms is appropriate

Based on the test cases and implementation:

  • The API has a timeout of 2000ms (API_TIMEOUT)
  • Tests consider responses up to 1900ms as acceptable (OK_RESPONSE_TIME)
  • The 1000ms EXPIRATION_WINDOW is sufficient since:
    • It's used as a parameter in RFQ requests to inform relayers about the quote validity period
    • The actual API timeout (2000ms) provides enough buffer for the round-trip communication
    • Test cases validate that responses within this window work correctly
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any configuration or documentation about response times
rg -i "response.*time|latency|timeout" --type ts

Length of output: 6612


Script:

#!/bin/bash
# Search for RFQ-related timing configurations and tests
rg -A 5 "EXPIRATION_WINDOW|API_TIMEOUT" --type ts

Length of output: 1879


Script:

#!/bin/bash
# Search for RFQ test cases to understand timing expectations
cat packages/sdk-router/src/rfq/api.test.ts

Length of output: 8289

packages/sdk-router/src/utils/logs.ts Show resolved Hide resolved
packages/sdk-router/src/rfq/api.ts Show resolved Hide resolved
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: 1

🧹 Outside diff range and nitpick comments (2)
packages/sdk-router/src/rfq/api.ts (2)

12-21: Consider environment-specific configuration for API settings

The hardcoded API URL and timeout values should be configurable based on the environment (development, staging, production).

Consider:

  1. Moving these values to a configuration file
  2. Making them environment-dependent
  3. Allowing override through environment variables
-const API_URL = 'https://rfq-api.omnirpc.io'
-const API_TIMEOUT = 2000
-const EXPIRATION_WINDOW = 1000
+const API_URL = process.env.RFQ_API_URL || 'https://rfq-api.omnirpc.io'
+const API_TIMEOUT = Number(process.env.RFQ_API_TIMEOUT) || 2000
+const EXPIRATION_WINDOW = Number(process.env.RFQ_EXPIRATION_WINDOW) || 1000

106-166: Add retry logic for transient failures

While the error handling is comprehensive, the function could benefit from retry logic for transient failures, which are common in network requests.

Consider implementing exponential backoff:

const getQuoteWithRetry = async (
  rfqRequest: PutRFQRequestAPI,
  maxRetries = 3,
  baseDelay = 500
): Promise<Response> => {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await fetchWithTimeout(`${API_URL}/rfq`, API_TIMEOUT, {
        method: 'PUT',
        body: JSON.stringify(rfqRequest),
        headers: {
          'Content-Type': 'application/json',
        },
      });
      if (response.ok) return response;
      if (response.status < 500) break; // Don't retry client errors
    } catch (error) {
      if (i === maxRetries - 1) throw error;
    }
    await new Promise(resolve => setTimeout(resolve, baseDelay * Math.pow(2, i)));
  }
  throw new Error('Max retries exceeded');
};
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 1501333 and e1a1a77.

📒 Files selected for processing (2)
  • packages/sdk-router/src/rfq/api.ts (2 hunks)
  • packages/synapse-interface/package.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/synapse-interface/package.json
🔇 Additional comments (1)
packages/sdk-router/src/rfq/api.ts (1)

112-124: Consider validating quote_types array

The quote_types array is hardcoded to ['passive'] with a TODO comment about adding active quotes.

Let's verify the supported quote types:

Comment on lines +23 to +36
export type PutRFQRequestAPI = {
user_address?: string
// TODO: make integrator_id required
integrator_id?: string
quote_types: string[]
data: {
origin_chain_id: number
dest_chain_id: number
origin_token_addr: string
dest_token_addr: string
origin_amount_exact: string
expiration_window: number
}
}
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

Address TODO comment regarding integrator_id

The TODO comment indicates that integrator_id should be required, which is important for tracking and security purposes.

Make the field required:

 export type PutRFQRequestAPI = {
   user_address?: string
-  // TODO: make integrator_id required
-  integrator_id?: string
+  integrator_id: string
   quote_types: string[]
   data: {
     // ... rest of the fields
   }
 }
📝 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
export type PutRFQRequestAPI = {
user_address?: string
// TODO: make integrator_id required
integrator_id?: string
quote_types: string[]
data: {
origin_chain_id: number
dest_chain_id: number
origin_token_addr: string
dest_token_addr: string
origin_amount_exact: string
expiration_window: number
}
}
export type PutRFQRequestAPI = {
user_address?: string
integrator_id: string
quote_types: string[]
data: {
origin_chain_id: number
dest_chain_id: number
origin_token_addr: string
dest_token_addr: string
origin_amount_exact: string
expiration_window: number
}
}

Copy link

github-actions bot commented Dec 4, 2024

This PR is stale because it has been open 14 days with no activity. Remove stale label or comment or this will be closed in 5 days.

@github-actions github-actions bot added the Stale label Dec 4, 2024
@ChiTimesChi ChiTimesChi removed the Stale label Dec 4, 2024
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

🧹 Outside diff range and nitpick comments (1)
packages/sdk-router/src/rfq/api.ts (1)

19-47: Add JSDoc documentation for type definitions

The types PutRFQRequestAPI, PutRFQResponseAPI, and RelayerQuote lack documentation. Add JSDoc comments to describe their purpose and field meanings.

Example for PutRFQRequestAPI:

+/**
+ * Request type for the RFQ API PUT endpoint.
+ * @property {string} [user_address] - Optional address of the user requesting the quote
+ * @property {string} [integrator_id] - Identifier for the integrator making the request
+ * @property {string[]} quote_types - Types of quotes to request (e.g., 'passive', 'active')
+ * @property {Object} data - Quote request parameters
+ */
 export type PutRFQRequestAPI = {
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between e1a1a77 and 1d7323a.

📒 Files selected for processing (1)
  • packages/sdk-router/src/rfq/api.ts (3 hunks)
🔇 Additional comments (4)
packages/sdk-router/src/rfq/api.ts (4)

53-62: LGTM! Well-implemented timeout handling

The function correctly implements timeout handling using AbortController and properly merges the init options.


110-111: Address the TODO comment regarding active quotes

The comment indicates that active quotes need to be added. This might affect quote availability and pricing.

Let's check the implementation status:

✅ Verification successful

Active quotes feature is currently disabled by design

The codebase shows that active quotes functionality is intentionally disabled with a TODO comment. This is supported by:

  • The presence of active quotes expiration window configuration
  • Explicit TODO comment indicating active quotes need to be fixed before enabling
  • Current implementation explicitly limiting to passive quotes only

The TODO comment should remain until the active quotes feature is ready to be implemented.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for active quote implementations and tests
rg -A 5 "quote_types.*active" --type ts

Length of output: 41


Script:

#!/bin/bash
# Let's search for any mentions of quote types in the codebase
rg "quote_types" --type ts -B 2 -A 2

# Also search for any mentions of active quotes
rg "active.*quote" --type ts -B 2 -A 2

Length of output: 1447


102-106: ⚠️ Potential issue

Add input parameter validation

The function should validate input parameters before making the API request to fail fast and provide clear error messages.

Add these validations:

 export const getBestRelayerQuote = async (
   ticker: Ticker,
   originAmount: BigNumber,
   originUserAddress?: string
 ): Promise<RelayerQuote> => {
+  // Validate input parameters
+  if (!ticker.originToken?.chainId || !ticker.destToken?.chainId) {
+    console.error('Invalid ticker: missing chain IDs')
+    return ZeroQuote
+  }
+  if (!ticker.originToken?.token || !ticker.destToken?.token) {
+    console.error('Invalid ticker: missing token addresses')
+    return ZeroQuote
+  }
+  if (originAmount.lte(0)) {
+    console.error('Invalid origin amount: must be positive')
+    return ZeroQuote
+  }

Likely invalid or redundant comment.


13-17: ⚠️ Potential issue

Consider increasing the EXPIRATION_WINDOW value

1 second might be too short for relayers to respond with quotes, especially considering network latency and processing time. Consider increasing this value to provide a more reasonable window (e.g., 5-10 seconds).

Let's analyze the typical response times:

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

Successfully merging this pull request may close these issues.

1 participant