Skip to content

feat(fee-engine): add history tracking, testnet support, USD helper &… - #29

Open
RiH-137 wants to merge 1 commit into
Swapso-App:dev-branchfrom
RiH-137:feat/fee-engine
Open

feat(fee-engine): add history tracking, testnet support, USD helper &…#29
RiH-137 wants to merge 1 commit into
Swapso-App:dev-branchfrom
RiH-137:feat/fee-engine

Conversation

@RiH-137

@RiH-137 RiH-137 commented Mar 13, 2026

Copy link
Copy Markdown

Summary

Completes Week 7 of Phase 2 — Fee Engine. Adds four new capabilities to
the FeeEstimator class and covers them with a full unit-test suite.

Changes

src/helper/feeEstimator.ts

  • Fee rate history tracking — every successful fetchRates() call
    appends a FeeRateEntry (rates, network, timestamp) to an internal
    ring buffer capped at 10 entries. Exposed via getHistory() and
    clearHistory().
  • Testnet fee estimationfetchRates('TESTNET') now routes to
    https://mempool.space/testnet/api/v1/fees/recommended, fully
    independent of the mainnet cache.
  • sat/vByte → USD fee comparison helper
    • getBtcPriceUsd() — live BTC/USD price from mempool.space; returns
      null gracefully when the price API is unavailable.
    • getSatVByteToUsd(satPerVByte, vBytes) — converts a fee rate +
      transaction size into total sats, BTC, and USD.
    • compareTiers(vBytes, network) — side-by-side breakdown of all four
      tiers (slow / normal / fast / urgent) with sat, BTC, and USD columns.

src/helper/index.ts

  • Exports FeeEstimator class and feeEstimator singleton.

test/feeEstimator.js (new file)

  • 36 unit tests using nock to mock the mempool.space API.
  • Covers: mainnet & testnet rate fetching, static fallback on error,
    30-second cache (per network), history overflow capping, timestamp
    correctness, USD calculation accuracy, null price fallback, and
    compareTiers invariants.

Test results

Related planning

Days 31–34, Week 7, Phase 2 — Fee Engine (planning_tracker.csv)

Copilot AI review requested due to automatic review settings March 13, 2026 11:21

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds a new FeeEstimator helper to the btc-controller “fee-engine” layer, expanding fee estimation capabilities (testnet support, history tracking, and USD comparison utilities) and introducing a dedicated unit test suite.

Changes:

  • Introduces FeeEstimator with per-network fee fetching + caching, history tracking, and BTC/USD conversion helpers.
  • Updates helper barrel exports to include FeeEstimator and a feeEstimator singleton.
  • Adds a comprehensive mocha/nock unit test suite for the new estimator.

Reviewed changes

Copilot reviewed 3 out of 5 changed files in this pull request and generated 6 comments.

File Description
btc-controller/src/helper/feeEstimator.ts New fee estimation helper with caching/retry, history ring buffer, and USD comparison utilities.
btc-controller/src/helper/index.ts Exposes FeeEstimator and feeEstimator from the helper barrel.
btc-controller/test/feeEstimator.js New unit tests covering fee fetching (mainnet/testnet), caching, history behavior, and USD calculations.
btc-controller/coverage/tmp/coverage-980-1773166164780-0.json Generated coverage temp artifact added to the PR (should not be committed).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +107 to +110
const cached = this.cache.get(network);
if (cached && Date.now() < cached.expiresAt) {
return cached.rates;
}
* Capped at 10 entries; only successful fetches are recorded.
*/
getHistory(): FeeRateEntry[] {
return [...this.history];
Comment on lines +112 to +115
try {
const url = MEMPOOL_FEE_URL[network];
const data = await this.fetchWithRetry(url);

Comment on lines +210 to +222
for (const tier of tiers) {
const satPerVByte = rates[tier];
const totalSats = satPerVByte * vBytes;
const totalBtc = totalSats / 1e8;

result[tier] = {
satPerVByte,
totalSats,
totalBtc,
totalUSD: btcPrice !== null
? parseFloat((totalBtc * btcPrice).toFixed(6))
: null,
};
Comment on lines +4 to +7
import { FeeEstimator, feeEstimator } from "./feeEstimator";
import * as utils from "./utils/index";

export { signTransaction, utils, getFeeAndInput, getTransactionSize, TransactionVisualizer };
export { signTransaction, utils, getFeeAndInput, getTransactionSize, TransactionVisualizer, FeeEstimator, feeEstimator };
Comment on lines +107 to +110
const cached = this.cache.get(network);
if (cached && Date.now() < cached.expiresAt) {
return cached.rates;
}
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.

2 participants