Skip to main content

BumpFee

BumpFee is an endpoint that allows users to interact with lnd's sweeper directly. It takes an outpoint from an unconfirmed transaction and sends it to the sweeper for potential fee bumping. Depending on whether the outpoint has been registered in the sweeper (an existing input, e.g., an anchor output) or not (a new input, e.g., an unconfirmed wallet utxo), this will either be an RBF or CPFP attempt.

When receiving an input, lnd’s sweeper needs to understand its time sensitivity to make economical fee bumps - internally a fee function is created using the deadline and budget to guide the process. When the deadline is approaching, the fee function will increase the fee rate and perform an RBF.

When a force close happens, all the outputs from the force closing transaction will be registered in the sweeper. The sweeper will then handle the creation, publish, and fee bumping of the sweeping transactions. Everytime a new block comes in, unless the sweeping transaction is confirmed, an RBF is attempted. To interfere with this automatic process, users can use BumpFee to specify customized fee rate, budget, deadline, and whether the sweep should happen immediately. It's recommended to call ListSweeps to understand the shape of the existing sweeping transaction first - depending on the number of inputs in this transaction, the RBF requirements can be quite different.

This RPC also serves useful when wanting to perform a Child-Pays-For-Parent (CPFP), where the child transaction pays for its parent's fee. This can be done by specifying an outpoint within the low fee transaction that is under the control of the wallet.

Source: walletrpc/walletkit.proto

gRPC

rpc BumpFee (BumpFeeRequest) returns (BumpFeeResponse);

REST

HTTP MethodPath
POST /v2/wallet/bumpfee

Code Samples

const fs = require('fs');
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');

const GRPC_HOST = 'localhost:10009'
const MACAROON_PATH = 'LND_DIR/data/chain/bitcoin/regtest/admin.macaroon'
const TLS_PATH = 'LND_DIR/tls.cert'

const loaderOptions = {
keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true,
};
const packageDefinition = protoLoader.loadSync(['lightning.proto', 'walletrpc/walletkit.proto'], loaderOptions);
const walletrpc = grpc.loadPackageDefinition(packageDefinition).walletrpc;
process.env.GRPC_SSL_CIPHER_SUITES = 'HIGH+ECDSA';
const tlsCert = fs.readFileSync(TLS_PATH);
const sslCreds = grpc.credentials.createSsl(tlsCert);
const macaroon = fs.readFileSync(MACAROON_PATH).toString('hex');
const macaroonCreds = grpc.credentials.createFromMetadataGenerator(function(args, callback) {
let metadata = new grpc.Metadata();
metadata.add('macaroon', macaroon);
callback(null, metadata);
});
let creds = grpc.credentials.combineChannelCredentials(sslCreds, macaroonCreds);
let client = new walletrpc.WalletKit(GRPC_HOST, creds);
let request = {
outpoint: <OutPoint>,
target_conf: <uint32>,
sat_per_byte: <uint32>,
force: <bool>,
sat_per_vbyte: <uint64>,
immediate: <bool>,
budget: <uint64>,
};
client.bumpFee(request, function(err, response) {
console.log(response);
});
// Console output:
// {
// "status": <string>,
// }

Messages

walletrpc.BumpFeeRequest

Source: walletrpc/walletkit.proto

FieldgRPC TypeREST TypeREST Placement
outpoint
OutPointobjectbody
target_conf
uint32integerbody
sat_per_bytedeprecated
uint32integerbody
forcedeprecated
boolbooleanbody
sat_per_vbyte
uint64stringbody
immediate
boolbooleanbody
budget
uint64stringbody

walletrpc.BumpFeeResponse

Source: walletrpc/walletkit.proto

FieldgRPC TypeREST Type
status
stringstring

Nested Messages

lnrpc.OutPoint

FieldgRPC TypeREST Type
txid_bytes
bytesstring
txid_str
stringstring
output_index
uint32integer