Skip to content

riftresearch/fee-comp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

46 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Fee Comp

Headless TypeScript server for cross-chain swap fee comparison across multiple providers.

Setup

pnpm install

Create a .env file:

ETH_PRIVATE_KEY=0x...
BTC_PRIVATE_KEY=K... or L...  # WIF format
ALCHEMY_API_KEY=your-alchemy-api-key
NEAR_INTENTS_JWT=your-jwt-token
GARDEN_API_KEY=your-garden-api-key
BTC_API_BASE=https://your-esplora-node.com

Run

pnpm go                 # Production run (no hot reload)
pnpm go --execute       # Force execute swaps
pnpm go --no-execute    # Quotes only (no execution)

pnpm dev                # Development with hot reload
pnpm quote:near -- --amount 1000  # One-off Near Intents quote (default USDC -> BTC)

Near Intents One-Off Quote

pnpm quote:near -- --amount 1000
pnpm quote:near -- --amount 1000 --input USDC --output BTC --raw

Shows a live countdown to the next swap cycle:

💱 Execute swaps: YES
👀 Settlement watcher started
⏳ Next: EVM → BTC in 1h 59m 45s

Dashboard

Live dashboard at http://localhost:3457 - auto-refreshes every 5 seconds. Click any swap journey to see full details including transaction hashes and explorer links.

Environment Variables

Variable Description
ETH_PRIVATE_KEY EVM private key (0x...) for signing transactions
BTC_PRIVATE_KEY Bitcoin private key in WIF format (starts with K, L, or 5)
ALCHEMY_API_KEY Alchemy API key for Ethereum mainnet
NEAR_INTENTS_JWT JWT token from Near Intents Partners Portal
GARDEN_API_KEY API key for Garden Finance (optional)
BTC_API_BASE Esplora-compatible Bitcoin API base URL (optional, defaults to mempool.space)

Providers

Provider Supported Pairs Notes
Rift BTC ↔ CBBTC, USDC, ETH Native BTC swaps
Relay BTC ↔ CBBTC, USDC, ETH Cross-chain relay
THORChain BTC ↔ USDC, ETH No CBBTC support
Chainflip BTC ↔ USDC, ETH No CBBTC support
Garden BTC ↔ CBBTC CBBTC only
Near Intents BTC ↔ CBBTC, USDC, ETH Via 1Click API

Enable/disable providers in src/constants.ts:

const PROVIDERS = {
  rift: false,
  relay: false,
  thorchain: false,
  chainflip: false,
  garden: false,
  nearintents: true,
}

Swap Schedule

Runs for 7 days, alternating every 2 hours between BTC→EVM and EVM→BTC directions.

Configure swap pairs and USD amounts in src/constants.ts. Amounts are defined in USD and resolved to token amounts at runtime using live prices.

Settlement Tracking

Swaps are executed non-blocking. A background watcher polls for settlement status every 30 seconds:

────────────────────────────────────────────────────────────
🔍 Settlement Check (1 pending)
────────────────────────────────────────────────────────────
  ⏳ [🌐NearIntents] CBBTC→BTC (0.0002) | 5m | PROCESSING
────────────────────────────────────────────────────────────

Settlements timeout after 24 hours if not completed.

CSV Output

All activity is logged to data.csv in the project root with a type column:

  • quote - Quote data (timestamp, provider, tokens, amounts, fees)
  • swap - Executed swaps (swap ID, status)
  • settlement - Settlement results (payout tx hash, actual output amount)

Project Structure

src/
  index.ts              # Entry point & scheduler
  constants.ts          # Timing, swap definitions, config
  account.ts            # Wallet config, BTC/EVM sending
  csv.ts                # CSV logging
  prices.ts             # Token price fetching
  server.ts             # Dashboard HTTP server
  settlement-tracker.ts # Background settlement watcher
  provider-health.ts    # Per-provider swap health tracking
  providers/
    types.ts            # Common provider interface
    rift.ts             # Rift SDK
    relay.ts            # Relay Protocol
    thorchain.ts        # THORChain
    chainflip.ts        # Chainflip
    garden.ts           # Garden Finance
    nearintents.ts      # Near Intents (1Click API)

Adding Providers

Implement the provider interface in src/providers/:

export const myprovider = {
  name: 'MyProvider',
  supportsSwap(inputToken: string, outputToken: string): boolean,
  getQuote(params: SwapParams): Promise<{ quote: Quote, execute: () => Promise<SwapResult> }>,
  checkSettlementOnce(swapId: string, verbose: boolean): Promise<SettlementResult | null>,
  getStatusString(swapId: string): Promise<string>,
}

Then register in src/settlement-tracker.ts and enable in src/index.ts.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors