Skip to content

feat: Integrate Bitget for Rate Fetching & Median Calculation Across Multiple Providers #441

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

Open
wants to merge 57 commits into
base: main
Choose a base branch
from

Conversation

sundayonah
Copy link
Collaborator

Description

This PR integrates Bitget as a source for fetching rates for all supported currencies (e.g., NGN, KES, GHS). It enhances the rate calculation system by retrieving data from multiple providers (Quidax, Binance, and Bitget) and computing the median rate for improved accuracy and reliability.

References

Closes #423
Bitget API Documentation

Testing

  • Fetching exchange rates from Bitget, Binance, and Quidax.
  • Median calculation logic across multiple price sources.
  • Handling API failures and missing data scenarios.

Checklist

  • I have added documentation and tests for new/changed functionality in this PR
  • All active GitHub checks for tests, formatting, and security are passing
  • The correct base branch is being used, if not main

By submitting a PR, I agree to Paycrest's Contributor Code of Conduct and Contribution Guide.

@sundayonah sundayonah requested review from chibie and 5ran6 as code owners March 20, 2025 11:46
@onahprosper
Copy link
Collaborator

@sundayonah there are conflicts

Copy link
Collaborator

@onahprosper onahprosper left a comment

Choose a reason for hiding this comment

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

Please can you share the direct link to the query advList, when i test the endpoint i am getting:

{
    "status": "error",
    "message": "Failed to fetch rates",
    "data": "FetchBitgetRates: failed to parse response: invalid character '<' looking for beginning of value"
}

var prices []decimal.Decimal

// Fetch rates based on currency
if currency == "NGN" {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This check is not enough.
The first check should includes what we have here

if currency == "NGN" || currency == "KES" || currency == "GHS"
// get market price from each Bitget, Binance, and Quidax
// calculate the median

Copy link
Collaborator Author

@sundayonah sundayonah Apr 28, 2025

Choose a reason for hiding this comment

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

This check is not enough. The first check should includes what we have here

if currency == "NGN" || currency == "KES" || currency == "GHS"
// get market price from each Bitget, Binance, and Quidax
// calculate the median

based on this part:

GIVEN the currency is NGN
WHEN fetching rates for USDT/NGN
THEN the system should fetch rates from Quidax and Bitget

GIVEN the currency is not NGN
WHEN fetching rates for USDT/
THEN the system should fetch rates from Binance and Bitget

if currency == NGN use FetchQuidaxRates and FetchBitgetRates
else if currency is ... use FetchBinanceRates and FetchBitgetRates

         if currency == "NGN" {
		quidaxRate, err := FetchQuidaxRates(currency)
		if err == nil {
			prices = append(prices, quidaxRate)
		}
	} else {
		binanceRates, err := FetchBinanceRates(currency)
		if err == nil {
			prices = append(prices, binanceRates...)
		}
	}

	// Fetch Bitget rates for all supported currencies
	bitgetRates, err := FetchBitgetRates(currency)
	if err == nil {
		prices = append(prices, bitgetRates...)
	}
	```

@sundayonah
Copy link
Collaborator Author

Please can you share the direct link to the query advList, when i test the endpoint i am getting:

{
    "status": "error",
    "message": "Failed to fetch rates",
    "data": "FetchBitgetRates: failed to parse response: invalid character '<' looking for beginning of value"
}

https://www.bitget.com/v1/p2p/pub/adv/queryAdvList

body Params
{ "side": 2, "pageNo": 1, "pageSize": 10, "coinCode": "USDT", "fiatCode": "NGN", "languageType": 0 }

@onahprosper
Copy link
Collaborator

Please can you share the direct link to the query advList, when i test the endpoint i am getting:

{
    "status": "error",
    "message": "Failed to fetch rates",
    "data": "FetchBitgetRates: failed to parse response: invalid character '<' looking for beginning of value"
}

https://www.bitget.com/v1/p2p/pub/adv/queryAdvList

body Params { "side": 2, "pageNo": 1, "pageSize": 10, "coinCode": "USDT", "fiatCode": "NGN", "languageType": 0 }

What are the inputs?

@sundayonah
Copy link
Collaborator Author

Please can you share the direct link to the query advList, when i test the endpoint i am getting:

{
    "status": "error",
    "message": "Failed to fetch rates",
    "data": "FetchBitgetRates: failed to parse response: invalid character '<' looking for beginning of value"
}

https://www.bitget.com/v1/p2p/pub/adv/queryAdvList
body Params { "side": 2, "pageNo": 1, "pageSize": 10, "coinCode": "USDT", "fiatCode": "NGN", "languageType": 0 }

What are the inputs?

body Params

{
 "side": 2, 
 "pageNo": 1,
 "pageSize": 10, 
 "coinCode": "USDT", 
 "fiatCode": "NGN", 
 "languageType": 0 
 }

@onahprosper
Copy link
Collaborator

in your controller/index.go file, kindly add this after running the aggregator locally to reproduce

// GetBitgetRates fetches USDT exchange rates from Bitget P2P listings
func (ctrl *Controller) GetBitgetRates(ctx *gin.Context) {
    currency := ctx.Param("currency")
    if currency == "" {
        u.APIResponse(ctx, http.StatusBadRequest, "error", "Currency code is required", nil)
        return
    }

    rates, err := u.FetchBitgetRates(currency)
    if err != nil {
        fmt.Println("Bitget rates error:")
        u.APIResponse(ctx, http.StatusInternalServerError, "error", "Failed to fetch rates", err.Error())
        return
    }

    u.APIResponse(ctx, http.StatusOK, "success", "Rates fetched successfully", rates)
}

and you can register the route in your router file

v1.GET("bitget/:currency", ctrl.GetBitgetRates)

test with postman
Screenshot 2025-04-29 at 13 50 14

chibie and others added 30 commits May 13, 2025 10:15
* feat: Add rate slippage configuration for provider tokens

* fix: correct slippageThreshold assignment to avoid variable shadowing

* test: add test cases for rate slippage with minor modifications

* test: add token-specific slippage validation and default slippage behavior

* fix: resolve undefined FieldSymbol and syntax error in ClearedFields

* fix: resolve undefined providerordertoken.SymbolEQ in priority_queue.go

* fix: updated baseTokenPayload to match ProviderOrderTokenPayload struct

* fix: update rate slippage validation and error messages in profile handling

* feat: implement rate slippage validation for provider order tokens and update related tests

* chore: update go.sum to remove deprecated cobra version 1.7.0

* fix(profile): update rate slippage validation and error handling in provider profile updates

* chore: update go.sum and atlas.sum to include new cobra version and add rate slippage migration

---------

Co-authored-by: Chibuotu Amadi <[email protected]>
* Enhance logging with contextual information across services

- Updated logging in `priority_queue.go` to include additional context such as Redis keys, provider IDs, and error details for better traceability.
- Improved error handling in `tasks.go` by adding more descriptive logging for RPC client connections, order operations, and refund processes.
- Enhanced the logger utility in `logger.go` to automatically include caller information (file, line, function) in log entries for easier debugging.
- Refined error logging in `utils.go` to provide more context when invalid provider data is encountered, including token and currency details.

* fix(logger): enhance logging with caller information and improve error context for indexer

* Refactor error logging to use fmt.Sprintf for consistent error formatting

- Updated error logging across multiple services to use fmt.Sprintf for better error message formatting.
- Ensured all error messages include detailed context for easier debugging.
- Adjusted tests to accommodate changes in error handling.

* fix(auth): update logging to use UserID instead of Email for errors logging

* fix(logger): update log field keys to use PascalCase for consistency

* fix(logger): update OrderID logging to use hex encoding for consistency
…xt in profile and indexer services

- Updated error logging in  to ensure consistent formatting and improved contextual information for various failure scenarios.
- Enhanced error messages in  to reflect the correct event types (settled, refunded) for better traceability.
- Adjusted validation rules in  for  to enforce stricter requirements on conversion rates and order amounts.
…d priority queue services

- Updated error logging in  to ensure consistent formatting and improved contextual information for various failure scenarios.
- Enhanced error messages to include relevant details such as token addresses, order IDs, and provider IDs for better traceability.
- Refactored logging in  to align with the new formatting standards, ensuring clarity in error reporting.
- Improved error handling in  by adding more descriptive logging for RPC client connections and order operations.
…roviderController

- Updated the Stats method to separately aggregate USD and local stablecoin volumes.
- Enhanced error handling to log errors and return appropriate API responses when fetching provider stats fails.
- Adjusted total fiat volume calculation to account for different token currencies.
- Combined USD and local stablecoin volumes for the final response.
…clarity

- Enhanced the profile test to include additional token properties and commented out a test case for future restoration.
- Simplified error messages in the UpdateSenderProfile method for better readability.
- Replaced utility function calls with direct references to improve code clarity.
* Add JSON schema for smile ID types configuration

This commit introduces a new JSON schema file that defines the structure for smile ID types, including continents, countries, and their respective ID types. The schema enforces validation rules such as required fields, string patterns for country codes, and minimum item requirements for arrays.

* feat: add JSON schema for smile ID types configuration

This commit introduces a new JSON schema file that defines the structure for smile ID types, including continents, countries, and their respective ID types. The schema enforces validation rules such as required fields, string patterns for country codes, and minimum item requirements for arrays.

* test: add test to smileID implementation

* chore: rename 'document_image' to 'doc_verification' in smile_id_types.json

* chore: fix conflicts

* fix: close LoadSmileIDConfig function and clean up IsValidHttpsUrl

* feat: initialize aggregator with base structure

* feat: load SmileID configuration dynamically and refactor ID types generation

* fix: update country name reference to use country code in ID types generation

* refactor: improve SmileID configuration loading and flattening logic

* fix: reorganize Smile ID files according to new structure

* fix: implement robust file path resolution for Smile ID configuration

* fix: remove Kosovo (XK) and its ID types from countries verification configuration

* refactor(kyc): update identity verification request handling and signature verification

- Replaced the deprecated  with  across the codebase.
- Implemented a new method  for Ethereum signature validation.
- Enhanced error handling in the identity verification process by introducing specific error types for better clarity.
- Removed the  file as its functionality has been integrated into the new structure.

---------

Co-authored-by: Prosper <[email protected]>
Co-authored-by: Chibuotu Amadi <[email protected]>
- Changed the environment configuration to use SERVER_URL instead of HOST_DOMAIN.
- Updated the KYC verification request structure to use types from the new shared types package.
- Removed the old KYC types and configuration files, streamlining the KYC service implementation.
- Adjusted tests to reflect the new structure and ensure compatibility with the updated KYC provider interface.
* feat: add metadata field to payment order and recipient models

- Introduced a new  field in the  and  entities to store additional information.
- Updated related functions and methods to handle the new  field, including setting, clearing, and querying its values.
- Refactored the server configuration to replace  with  for consistency.
- Adjusted various services and tests to accommodate the new metadata functionality.

* refactor: remove invalid signature format test from SmileID service

- Eliminated the test case for invalid signature format in the SmileID service tests to streamline the test suite.
- This change helps focus on relevant test scenarios and improves overall test clarity.

* feat: add metadata field to LinkedAddress entity and related functionality
* feat(ci): add Atlas database migrations workflow

- Add GitHub Actions workflow for automated database migrations
- Configure environment-specific database URLs for staging and production
- Run migrations on push to main and stable branches

* refactor(ci): remove pull request trigger from Atlas migration workflow
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.

Add Bitget as a Source for Rates and Refactor External Market Logic
4 participants