Skip to content

Commit

Permalink
Merge pull request #3 from LN-Zap/recommendations
Browse files Browse the repository at this point in the history
Use Blockstream API for further future estimates
  • Loading branch information
mrfelton authored Dec 24, 2023
2 parents 79aca4b + 3362028 commit d41d9b4
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 13 deletions.
30 changes: 27 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,34 @@
# Lnd Mempool.Space Integration

This project aims to integrate the [Lightning Network Daemon (lnd)](https://github.com/lightningnetwork/lnd) with [mempool.space](https://mempool.space/), a Bitcoin blockchain explorer. The primary feature of this integration is to provide fee estimates to lnd based on the fee estimates from mempool.space.
This project aims to integrate the [Lightning Network Daemon (lnd)](https://github.com/lightningnetwork/lnd) with [mempool.space](https://mempool.space/), a Bitcoin blockchain explorer. The primary feature of this integration is to provide fee estimates to lnd based on a combination of mempool-based estimates (from the mempool.space API) and history-based estimates (from the Blockstream API).

## Features
## Fee Estimates

- Fee Estimates: The integration fetches fee estimates from mempool.space and provides them to lnd.
This application uses two APIs to get fee estimates for Bitcoin transactions:

- [**mempool.space API**](https://mempool.space/docs/api/rest): This API is used to get mempool-based fee estimates for upcoming blocks. The application fetches the fastestFee, halfHourFee, hourFee, economyFee, and minimumFee from the mempool.space API and uses these estimates to calculate the fee for upcoming blocks. The application also multiplies these estimates by a configurable multiplier to ensure that can be used to ensure that the fee estimates are always slightly higher or lower than the mempool.space estimates.

- [**Blockstream API**](https://github.com/Blockstream/esplora/blob/master/API.md): This API is used to get history-based fee estimates for further future blocks. The application fetches the fee estimates from the Blockstream API (which gets its data from bitcoind) and adds them to the fee estimates if they are lower than the lowest fee estimate from the mempool.space API.

Fee estimates are cached for a configurable amount of time (15 seconds by default) to reduce the number of API calls. The cache is automatically cleared after the configured time has elapsed.

## API

This application exposes a single API endpoint at `/v1/fee-estimates.json`. This endpoint returns a JSON object with the following structure, which is compatible with the LND's `feeurl` setting:

```json
{
"current_block_hash": "0000000000000000000044ab897830778c73d33fdeddde1f21e875fae2150378",
"fee_by_block_target": {
"1": 81900,
"2": 78750,
"3": 74550,
"144": 64951,
"504": 53464,
"1008": 28175
}
}
```

## Setup & Usage

Expand Down
30 changes: 20 additions & 10 deletions src/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,31 +55,41 @@ app.get('/v1/fee-estimates.json', async (req, res) => {
// Check if the response is cached.
let data = myCache.get('data');

// If the response is not cached, fetch it from the mempool.space API.
// If the response is not cached, fetch it .
if (!data) {
// Fetch the current block hash.
const { bitcoin: { blocks } } = mempool;
const blocksTipHash = await blocks.getBlocksTipHash();

// Fetch fee estimates.
// Fetch fee estimates from mempool.space API.
const { bitcoin: { fees } } = mempool;
const feeEstimates = await fees.getFeesRecommended();
const mempoolBlocks = await fees.getFeesMempoolBlocks();

const minFee = feeEstimates.minimumFee * feeMultiplier;
// Fetch fee estimates from Blockstream API.
const blockstreamFeeEstimates = await fetch('https://blockstream.info/api/fee-estimates');
const blockstreamFees = await blockstreamFeeEstimates.json();

// Transform the fee estimates to match the desired format.
// Get the minimum fee from mempool.space (we use their economy rate).
const minFee = feeEstimates.economyFee;

// Use mempool.space fee estimates for upcoming blocks.
const feeByBlockTarget = {
1: Math.round(feeEstimates.fastestFee * 1000 * feeMultiplier),
2: Math.round(feeEstimates.halfHourFee * 1000 * feeMultiplier), // usually between first and second block
3: Math.round(feeEstimates.hourFee * 1000 * feeMultiplier), // usually between second and third block
36: Math.max(Math.round(mempoolBlocks[2].medianFee * 1000 * feeMultiplier), minFee), // 6 hours to get 3 blocks deep
72: Math.max(Math.round(mempoolBlocks[4].medianFee * 1000 * feeMultiplier), minFee), // 12 hours to get 5 blocks deep
144: Math.max(Math.round(mempoolBlocks[6].medianFee * 1000 * feeMultiplier), minFee), // 24 hours to get 7 blocks deep
720: Math.round(feeEstimates.economyFee * 1000 * feeMultiplier), // 5 days to get to 2x above economy
1008: Math.round(feeEstimates.minimumFee * 1000 * feeMultiplier) // 7 days to get to the minimum fee
};

// Calculate the minimum fee from the feeByBlockTarget object.
const minMempoolFee = Math.min(...Object.values(feeByBlockTarget));

// Merge Blockstream fee estimates into feeByBlockTarget.
for (const [blockTarget, fee] of Object.entries(blockstreamFees)) {
const adjustedFee = Math.round(fee * 1000);
if (!feeByBlockTarget.hasOwnProperty(blockTarget) && adjustedFee < minMempoolFee) {
feeByBlockTarget[blockTarget] = adjustedFee;
}
}

// Create the response object.
data = {
current_block_hash: blocksTipHash,
Expand Down

0 comments on commit d41d9b4

Please sign in to comment.