Skip to main content

Frequently Asked Questions

General Questions

Link Quote is a digital asset pricing and rate aggregation microservice for the LedgerLink platform. It provides real-time market rates for cryptocurrencies and other digital assets by aggregating data from multiple trusted providers.

Technology Stack:

  • NestJS backend with TypeScript
  • PostgreSQL database with TypeORM
  • CoinMarketCap and Pyth Network integrations
  • ActiveMQ for real-time event streaming
  • RESTful API with Swagger documentation

Currently, Link Quote integrates with:

  1. CoinMarketCap: Professional cryptocurrency market data with extensive coverage
  2. Pyth Network (Hermes): Decentralized oracle network with sub-second updates

Provider selection is configurable per asset or category, with automatic failover support.

How accurate are the rates?

Link Quote aggregates rates from multiple providers to ensure accuracy:

  • Fetches from 2+ providers simultaneously
  • Calculates weighted average from valid responses
  • Filters outliers and invalid data
  • Typical accuracy within 0.1% of market rates
  • Sub-second latency for price updates

How often are rates updated?

  • Real-time requests: Fetched on-demand when you call POST /rates
  • Provider latency: CoinMarketCap (10-60s), Pyth (<1s)
  • Historical storage: Each rate is timestamped and stored in PostgreSQL
  • Event publishing: Real-time valuation events via ActiveMQ

Which digital assets are supported?

Link Quote supports any digital asset you configure:

Pre-configured assets include:

  • Major cryptocurrencies: BTC, ETH, SOL, AVAX
  • Stablecoins: USDC, USDT, DAI, PYUSD
  • ERC-20 tokens
  • Custom tokens via Asset Management API

You can add new assets using POST /assets endpoint.

Technical Questions

How does provider selection work?

Link Quote uses a priority-based provider selection:

  1. Asset-Level Providers (highest priority)

    • Check if asset has specific providers configured
    • Use those if available
  2. Category-Level Providers (fallback)

    • If no asset providers, use category's providers
    • All assets in category inherit these providers
  3. All Available Providers (default)

    • If no asset or category providers configured
    • Query all active providers

Example:

BTC asset → has CoinMarketCap configured → only queries CoinMarketCap
ETH asset → no providers → uses category providers → queries Pyth + CoinMarketCap

What happens if a provider fails?

Link Quote has built-in redundancy:

  1. Multiple Providers: Queries 2+ providers in parallel
  2. Graceful Degradation: If one fails, uses others
  3. Error Handling: Returns 503 only if ALL providers fail
  4. Retry Logic: Implements exponential backoff for transient errors
  5. Event Logging: Publishes ERROR events to ActiveMQ for monitoring

Best Practice: Configure multiple providers per asset/category for maximum uptime.

Can I add custom price providers?

Yes! Use the Provider Management API:

POST /providers
{
"name": "MyCustomProvider",
"description": "Custom price feed",
"isActive": true
}

However, you'll need to extend the Link Quote service code to implement the actual provider integration. Built-in providers (CoinMarketCap, Pyth) are ready to use out-of-the-box.

How do I configure providers for an asset?

Map providers to assets or categories:

Asset-specific provider:

POST /asset-providers
{
"assetId": "550e8400-e29b-41d4-a716-446655440000",
"providerId": "123e4567-e89b-12d3-a456-426614174000"
}

Category-wide provider:

POST /category-providers
{
"categoryId": "789e4567-e89b-12d3-a456-426614174000",
"providerId": "123e4567-e89b-12d3-a456-426614174000"
}

Server-side:

  • No automatic caching
  • Each request fetches fresh data from providers
  • Historical rates stored in PostgreSQL for later retrieval

Client-side (recommended):

  • Implement your own caching strategy
  • Cache rates for 30-60 seconds
  • Reduces API calls and improves performance

See Error Handling - Caching for implementation examples.

Can I get historical rate data?

Yes! Use the GET /rates endpoint:

GET /rates?name=bitcoin&fromTime=2025-11-01T00:00:00Z&toTime=2025-11-20T23:59:59Z&limit=100

Returns all stored rates for the asset within the date range, including:

  • Rate value
  • Timestamp
  • Currency
  • Provider details (in metadata)

What's the difference between POST /rates and GET /rates?

  • POST /rates: Creates a NEW rate by fetching from providers (on-demand pricing)
  • GET /rates: Retrieves HISTORICAL rates from database (stored data)

Use POST for real-time pricing, GET for historical analysis.

How do I filter rates by asset?

Use the name parameter (asset name, case-insensitive):

GET /rates?name=bitcoin
GET /rates?name=ethereum

You can also combine with date filters, sorting, and pagination:

GET /rates?name=usdc&fromTime=2025-11-20T00:00:00Z&sortBy=timestamp&sortOrder=desc&limit=50

What currency formats are supported?

Currently, Link Quote primarily supports:

  • USD (default)
  • Other fiat currencies supported by providers

The currency parameter in POST /rates specifies the target currency.

Integration Questions

The Dashboard proxies requests through the Auth Server (BFF):

// From dashboard (Next.js API route)
const response = await fetch('/api/link-quote/v1/rates', {
method: 'POST',
body: JSON.stringify({ assetCode: 'BTC' }),
credentials: 'include', // Includes session cookies
});

The Auth Server forwards to Link Quote with proper authentication.

Can I subscribe to real-time rate updates?

Yes, via ActiveMQ event streaming:

  1. Connect to ActiveMQ with STOMP protocol
  2. Subscribe to /queue/valuation-events
  3. Filter events by asset ID or event type
  4. Receive real-time valuation events

Events include:

  • VALUATION_REQUESTED: Rate request received
  • VALUATION_PROCESSED: Rate successfully calculated
  • ERROR: Valuation failed

What permissions do I need?

For Dashboard Users:

  • Authentication Required: Must be logged into Link Dashboard
  • No RBAC: Role-based access control is not currently implemented

Current Access Pattern:

  • If logged in → Full access to all operations (GET, POST, PUT, DELETE, PATCH)
  • If not logged in → 401 error from Auth Server

For Direct Service Access (Internal Services):

  • No authentication required at Link Quote service level
  • Network-level security should be implemented
  • Service-to-service calls within secure VPC/network

How do I test my integration?

  1. Local Development:

    # Run Link Quote locally
    yarn dev:server:start
    # Access Swagger docs at http://localhost:3000/api
  2. Sandbox Environment:

    # Use sandbox URL
    https://sandbox-api.ledgerlink.ai/v1
  3. Mock Data: Create test assets and categories to experiment without affecting production

Can I batch fetch multiple rates?

Make parallel requests for multiple assets:

const assetCodes = ['BTC', 'ETH', 'SOL', 'USDC'];

const rates = await Promise.all(
assetCodes.map(code =>
fetch('/api/link-quote/v1/rates', {
method: 'POST',
body: JSON.stringify({ assetCode: code }),
}).then(r => r.json())
)
);

Troubleshooting

Why am I getting 503 errors?

Possible causes:

  1. No providers configured for asset/category

    • Solution: Configure providers via /asset-providers or /category-providers
  2. All providers failed (network, API limits, invalid keys)

    • Solution: Check provider API keys, monitor provider status, implement retry logic
  3. Provider API rate limits exceeded

    • Solution: Implement caching, upgrade provider plan, add more providers

Why are my rates different from exchange prices?

Small discrepancies are normal:

  • Aggregation: Average of multiple providers
  • Timing: Slight delay from providers
  • Exchange variance: Different exchanges have different prices
  • Network latency: 1-2 second delay possible

Typical variance: ±0.1% from spot price

How do I debug provider issues?

Enable debug logging in local development:

# server/.env
LOG_LEVEL=debug

Check logs for:

  • Provider API requests/responses
  • Error messages from providers
  • Rate calculation details
  • Failed provider attempts

Yes, but with limitations:

  • CoinMarketCap provider won't work
  • Pyth Network will still function
  • Reduced redundancy (only 1 provider)
  • Higher risk of 503 errors

Recommendation: Get a CoinMarketCap API key for production use.

Performance

What are the typical response times?

  • POST /rates: 200-500ms (depends on providers)

    • CoinMarketCap: 100-300ms
    • Pyth Network: 50-150ms
    • Parallel fetching minimizes total time
  • GET /rates: 10-50ms (database query)

  • Asset/Category CRUD: 5-20ms

What are the rate limits?

Link Dashboard (Auth Server): Rate limiting is implemented at the Dashboard/Auth Server level to protect the entire platform.

Link Quote Service: No rate limiting at the service level (relies on Dashboard protection).

External Provider Limits:

  • CoinMarketCap: 333 calls/day (free tier), higher with paid plans
  • Pyth Network: No rate limits (decentralized)

Best Practices:

  • Dashboard rate limiting protects against excessive requests
  • Implement client-side caching (30-60s minimum) to reduce load
  • Use GET /rates for historical data instead of re-fetching
  • Batch requests when possible
  • Monitor provider API usage to avoid hitting CoinMarketCap limits
  • Consider upgrading CoinMarketCap plan for high-volume use
  • Database: PostgreSQL with indexing on common query fields
  • Horizontal scaling: Stateless service, can run multiple instances
  • Provider failover: Multiple providers for redundancy
  • Caching strategy: Implement Redis for production high-volume use

Still have questions? Contact helpdesk@ledgerlink.ai or create an issue in the GitHub repository.