Skip to content

BitGet solver#4249

Merged
squadgazzz merged 4 commits intomainfrom
bitget-solver
Mar 11, 2026
Merged

BitGet solver#4249
squadgazzz merged 4 commits intomainfrom
bitget-solver

Conversation

@squadgazzz
Copy link
Copy Markdown
Contributor

This effectively replicates gnosis/solvers#203

Summary

  • Add a new solver that integrates with the https://web3.bitget.com/en/docs/swap/ API to find swap routes, following existing patterns
  • The Bitget API uses a two-step POST flow: quote (to get the optimal routing market and output amount) followed by swap (to get the on-chain calldata) The BitGet team suggested using the request_mod="rich" param in the /swap API, which makes the response contain much more data, including the outAmount.
  • To mitigate the race condition between quote and swap calls, slippage is applied to the quoted output and passed as toMinAmount to the swap endpoint, ensuring consistency between what the calldata enforces on-chain and what the solver reports Not needed anymore because of the previous point
  • Only sell orders are supported - the Bitget API has no exactOut mode

Changes

  • Bitget API client and DTOs with HMAC-SHA256 request signing, base64 calldata decoding, typed ChainName enum, and serialize::U256 for amount fields
  • TOML config loading (endpoint, chain-id, api-key, api-secret)
  • E2E tests: market sell order, buy order rejection, insufficient liquidity, and out-of-price limit order
  • config/example.bitget.toml - Example configuration

How to test

New unit and manual e2e tests (ignored by default).

@squadgazzz squadgazzz marked this pull request as ready for review March 10, 2026 18:12
@squadgazzz squadgazzz requested a review from a team as a code owner March 10, 2026 18:12
Copy link
Copy Markdown
Contributor

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

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a new solver for Bitget, including configuration, API client, and tests. The implementation is well-structured and follows existing patterns in the codebase. The test coverage is good, including happy path, error cases, and edge cases like out-of-price swaps. I have identified one high-severity finding regarding the mapping of API error codes, which appears to be incorrect and could lead to miscategorization of errors from the Bitget API. This comment has been retained as it does not conflict with any existing rules.

Comment thread crates/solvers/src/infra/dex/bitget/mod.rs
@squadgazzz
Copy link
Copy Markdown
Contributor Author

@AryanGodara
Copy link
Copy Markdown
Member

Tested on base staging: https://barn.explorer.cow.fi/base/orders/0x6dcb5fec6bdb4091c89a7f758368fff28d5ed2c85ff0ee245bd891333475f9fbd16f39990092033ee2fab400bf3364379c616c4e69b0814c

image

How did you get only 1 solver to participate in auction on base staging?
(Was it suspending flux, and then commenting out all other solvers? 🤔 )

@squadgazzz
Copy link
Copy Markdown
Contributor Author

Was it suspending flux, and then commenting out all other solvers?

Exactly

Comment thread crates/solvers/src/infra/dex/bitget/dto.rs
@squadgazzz squadgazzz enabled auto-merge March 11, 2026 11:09
@squadgazzz squadgazzz disabled auto-merge March 11, 2026 11:14
@squadgazzz squadgazzz enabled auto-merge March 11, 2026 11:14
Copy link
Copy Markdown
Contributor

@jmg-duarte jmg-duarte left a comment

Choose a reason for hiding this comment

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

Some questions but not worth blocking the PR for

Comment thread crates/solvers/src/run.rs
)))
}
cli::Command::Bitget { config: path } => {
let config = config::dex::bitget::file::load(&path).await;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: Given you're using expect right after, IMO load could return the result instead

Comment on lines +17 to +18
#[serde_as(as = "serde_with::DisplayFromStr")]
endpoint: reqwest::Url,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Isn't this available with the serde feature?

Comment on lines +141 to +144
pub fn decode_calldata(&self) -> Result<Vec<u8>, hex::FromHexError> {
let hex_str = self.data.strip_prefix("0x").unwrap_or(&self.data);
hex::decode(hex_str)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why not use the const_hex, which handles this by default?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It will be addressed in a follow-up PR.

@squadgazzz squadgazzz added this pull request to the merge queue Mar 11, 2026
Merged via the queue into main with commit b7643dd Mar 11, 2026
19 checks passed
@squadgazzz squadgazzz deleted the bitget-solver branch March 11, 2026 11:29
@github-actions github-actions bot locked and limited conversation to collaborators Mar 11, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants