npm package: @mixerx/oracles
Description: Complete oracle library for MixerX - gas prices (EIP-1559 + Legacy), token prices, and Tornado fee calculations
Author: MixerX Team
Latest version: 1.0.0

# MixerX Oracles

Oracle library for MixerX Relayer - fee calculation and token pricing for Tornado Cash operations.

## Requirements

- Node.js >= 24.12.0
- Yarn 4.12.0 (nodeLinker: node-modules)

Create `./.yarnrc.yml` (repository-root relative path, works on Linux/macOS/Windows):

```yaml
nodeLinker: node-modules
```

## Installation

```bash
yarn add @mixerx/oracles
```

## Quick Start

```typescript
import { createMixerxOraclesModule } from '@mixerx/oracles';

// Create module
const oracles = createMixerxOraclesModule({
  chainId: 1, // Mainnet
  rpcUrl: 'https://mainnet.infura.io/v3/YOUR_KEY',
  relayerFeePercent: 0.004, // 0.4%
  priceRepository: yourRedisRepository, // Implementation of ITokenPriceRepository
  multicallAddress: '0xeefBa1e63905eF1D7ACbA5a8513c70307C1cE441', // optional
  // offchainOracleAddress is optional:
  // if omitted, it is resolved from @mixerx/config by chainId
  fallbackGasPrices: {
    legacy: { instant: 25, fast: 20, standard: 18, low: 15 },
    eip1559: { baseFee: 10, maxFeePerGas: 20, maxPriorityFeePerGas: 2 },
  },
});

// Fetch token prices
const prices = await oracles.fetchPrices();
console.log(prices); // { dai: '603108348359886', usdc: '601311723569085', ... }

// Calculate withdrawal fee
const fee = await oracles.tornadoFeeOracle.calculateWithdrawalFee({
  currency: 'dai',
  amount: BigInt('100000000000000000000'), // 100 DAI
  decimals: 18,
  refund: '0x0',
  txType: 'relayer_withdrawal',
});

console.log(`Total fee: ${fee.totalFee.toString()}`);
```

## Architecture

This library follows Domain-Driven Design (DDD) principles:

- **Domain**: Value objects and entities for fees, gas, and tokens
- **Application**: Services and use cases for fee calculation and price fetching
- **Infrastructure**: Adapters for blockchain interaction (ethers)

## Features

### Fee Calculation (V5)

- Smart gas limit bumping (10% for relayer, 30% for user)
- On-chain gas estimation with fallback to defaults
- Support for ETH and ERC-20 tokens
- Automatic conversion between ETH and token units
- EIP-1559 and Legacy gas price support

### Token Price Fetching

- Fetches prices from on-chain OffchainOracle
- Uses Multicall for efficient batch requests
- Fallback to default prices if fetching fails
- Token list is resolved from `@mixerx/config` by `chainId`

### Mining Fee Support

- Anonymity Mining reward calculations
- Anonymity Mining withdrawal calculations
- Automatic conversion between points and TORN

## API Reference

### `createMixerxOraclesModule(config)`

Factory function to create the oracles module.

**Config:**
- `chainId`: Chain ID (1 for Mainnet)
- `rpcUrl`: RPC endpoint URL
- `relayerFeePercent`: Fee percentage (e.g., 0.004 for 0.4%)
- `priceRepository`: Implementation of `ITokenPriceRepository`
- `multicallAddress?`: Multicall contract address
- `offchainOracleAddress?`: OffchainOracle contract address (fallback to `@mixerx/config` by `chainId`)
- `fallbackGasPrices?`: Optional fallback gas prices

### Use Cases

#### `tornadoFeeOracle.calculateWithdrawalFee(input)`

Calculate and validate fees for Tornado Cash withdrawals.

**Input:**
- `currency`: Token symbol (eth, dai, usdc, etc.)
- `amount`: Withdrawal amount in base units (`bigint`)
- `decimals`: Token decimals
- `refund?`: Optional refund amount (hex string)
- `txType?`: `'relayer_withdrawal' | 'user_withdrawal' | 'relayer_withdrawal_check_v4'`

**Output:**
- `gasCost`: bigint
- `relayerFee`: bigint
- `refundAmount`: bigint
- `totalFee`: bigint
- `currency`: string

#### `fetchTokenPrices.execute(input?)`

Fetch current token prices from on-chain oracle.

**Input (optional):**
- `tokens?`: Specific tokens to fetch
- `useDefaults?`: Use default prices as fallback

**Output:**
- `prices`: TokenPrices map
- `failedTokens`: Tokens that failed to fetch
- `usedDefaults`: Whether defaults were used

## License

MIT