DataSourceManager

The DataSourceManager is a core component of LaserEyes that abstracts away the complexities of interacting with different Bitcoin data providers. It provides a unified interface for fetching blockchain data, regardless of the underlying provider.

Overview

The DataSourceManager handles:

  • Provider selection based on availability and capability
  • Fallback mechanisms when a provider fails
  • Caching to improve performance
  • Error handling and retry logic
  • Data normalization across different providers

Accessing the DataSourceManager

You can access the DataSourceManager through the LaserEyesClient:

accessing-datasource-manager.ts
import { 
  LaserEyesClient, 
  createStores, 
  createConfig, 
  MAINNET 
} from '@omnisat/lasereyes-core'

// Create and initialize the client
const stores = createStores()
const config = createConfig({ network: MAINNET })
const client = new LaserEyesClient(stores, config)
client.initialize()

// Get the DataSourceManager
const dataSourceManager = client.getDataSourceManager()

// Now you can use the DataSourceManager
const balance = await dataSourceManager.getBalance('bc1q...')

Key Methods

The DataSourceManager provides methods for interacting with the Bitcoin blockchain:

Basic Bitcoin Operations

basic-operations.ts
// Get balance for an address
const balance = await dataSourceManager.getBalance('bc1q...')

// Get UTXOs for an address
const utxos = await dataSourceManager.getUtxos('bc1q...')

// Get transaction details
const tx = await dataSourceManager.getTransaction('txid...')

// Broadcast a transaction
const txid = await dataSourceManager.broadcastTransaction(txHex)

// Estimate fee rate
const feeRate = await dataSourceManager.estimateFee(1) // For next block

// Get current block height
const blockHeight = await dataSourceManager.getBlockHeight()

// Get address transaction history
const history = await dataSourceManager.getAddressHistory('bc1q...')

Ordinals and Inscriptions

inscriptions.ts
// Get inscriptions for an address
const inscriptions = await dataSourceManager.getInscriptions('bc1q...')

// Get inscription content
const content = await dataSourceManager.getInscriptionContent('inscriptionId...')

// Get inscription details
const inscription = await dataSourceManager.getInscriptionById('inscriptionId...')

// Get inscription UTXO
const utxo = await dataSourceManager.getInscriptionUtxo('inscriptionId...')

Tokens (BRC-20 and Runes)

tokens.ts
// Get BRC-20 token balances
const brc20Tokens = await dataSourceManager.getMetaBalances('bc1q...', 'brc20')

// Get Rune balances
const runes = await dataSourceManager.getMetaBalances('bc1q...', 'runes')

// Get token info
const tokenInfo = await dataSourceManager.getTokenInfo('ORDI', 'brc20')

// Get token transfers
const transfers = await dataSourceManager.getTokenTransfers('bc1q...', 'ORDI', 'brc20')

Configuration

You can configure the DataSourceManager through the LaserEyesClient configuration:

configuration.ts
const config = createConfig({
  network: MAINNET,
  dataSources: {
    // Maestro configuration
    maestro: {
      apiKey: 'your-maestro-api-key', // Optional for development
    },
    // Sandshrew configuration
    sandshrew: {
      url: 'https://api.sandshrew.io', // Optional, defaults to this
      apiKey: 'your-sandshrew-api-key', // Optional for development
    },
    // Mempool.space configuration
    mempool: {
      url: 'https://mempool.space/api', // Optional, defaults to this
    },
    // Esplora configuration (URL string)
    esplora: 'https://blockstream.info/api',
  }
})

Custom Data Sources

You can register custom data sources with the DataSourceManager:

custom-datasource.ts
import { DataSource } from '@omnisat/lasereyes-core'

// Implement the DataSource interface
class CustomDataSource implements DataSource {
  constructor(private apiKey: string, private network: NetworkType) {
    // Initialize your data source
  }

  // Implement required methods
  async getBalance(address: string): Promise<string> {
    // Implement balance fetching logic
    const response = await fetch(`https://your-api.com/balance/${address}?apiKey=${this.apiKey}`)
    const data = await response.json()
    return data.balance
  }

  // Implement other required methods...
}

// Register your custom data source
const customDataSource = new CustomDataSource('your-api-key', MAINNET)
dataSourceManager.registerDataSource('custom', customDataSource)

Provider Selection

The DataSourceManager automatically selects the appropriate provider based on:

  • The operation being performed
  • Provider availability
  • Provider capabilities
  • Previous success/failure with each provider

You can also manually specify which provider to use for a specific operation:

provider-selection.ts
// Use Maestro specifically for this operation
const balance = await dataSourceManager.getBalance('bc1q...', { provider: 'maestro' })

// Use Sandshrew specifically for this operation
const utxos = await dataSourceManager.getUtxos('bc1q...', { provider: 'sandshrew' })

Error Handling

The DataSourceManager includes built-in error handling and retry logic:

error-handling.ts
try {
  const balance = await dataSourceManager.getBalance('bc1q...')
} catch (error) {
  if (error.code === 'PROVIDER_ERROR') {
    console.error('All providers failed:', error.message)
  } else if (error.code === 'INVALID_ADDRESS') {
    console.error('Invalid Bitcoin address')
  } else {
    console.error('Operation failed:', error.message)
  }
}

Caching

The DataSourceManager includes built-in caching to improve performance:

caching.ts
// Configure cache options
const config = createConfig({
  network: MAINNET,
  cacheOptions: {
    ttl: 60000, // Cache time-to-live in milliseconds
    maxSize: 100, // Maximum number of items to cache
  }
})

// The DataSourceManager will automatically cache results
// You can bypass the cache for specific operations
const balance = await dataSourceManager.getBalance('bc1q...', { bypassCache: true })

Provider Capabilities

Different data providers have different capabilities:

FeatureMaestroSandshrewMempool.spaceEsplora
Basic Bitcoin Operations
Ordinals & Inscriptions
BRC-20 Tokens
Runes
Fee Estimation
Transaction History

Next Steps

Now that you understand the DataSourceManager, you can explore related topics: