Skip to content
This repository was archived by the owner on Feb 23, 2021. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions assets/rpc.proto
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,16 @@ service Lightning {
};
}

/** lncli: `estimatefee`
EstimateFee asks the chain backend to estimate the fee rate and total fees
for a transaction that pays to multiple specified outputs.
*/
rpc EstimateFee (EstimateFeeRequest) returns (EstimateFeeResponse) {
option (google.api.http) = {
get: "/v1/transactions/fee"
};
}

/** lncli: `sendcoins`
SendCoins executes a request to send coins to a particular address. Unlike
SendMany, this RPC call only allows creating a single output at a time. If
Expand Down Expand Up @@ -654,6 +664,27 @@ message LightningAddress {
string host = 2 [json_name = "host"];
}

message FeeEstimate {
/// The total fee in satoshis.
int64 fee_sat = 1;

/// The fee rate in satoshi/byte.
int64 feerate_sat_per_byte = 2;
}

message EstimateFeeRequest {
/// The map from addresses to amounts for the transaction.
map<string, int64> AddrToAmount = 1;

/// The target number of blocks that this transaction should be confirmed by.
int32 target_conf = 2;
}

message EstimateFeeResponse {
/// A fee estimate for the specified confirmation target.
FeeEstimate estimate = 1;
}

message SendManyRequest {
/// The map from addresses to amounts
map<string, int64> AddrToAmount = 1;
Expand Down
14 changes: 14 additions & 0 deletions src/action/payment.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,20 @@ class PaymentAction {
}
}

async estimateFee() {
try {
const { payment, settings } = this._store;
const AddrToAmount = {};
AddrToAmount[payment.address] = toSatoshis(payment.amount, settings.unit);
const { estimate } = await this._grpc.sendCommand('estimateFee', {
AddrToAmount,
});
payment.fee = toAmount(parseSat(estimate.fee_sat), settings.unit);
} catch (err) {
this._notification.display({ msg: 'Estimating fee failed!', err });
}
}

async payBitcoin() {
try {
const { payment, settings } = this._store;
Expand Down
7 changes: 6 additions & 1 deletion test/integration/action/action-integration.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -245,9 +245,14 @@ describe('Action Integration Tests', function() {
transactions2.subscribeTransactions();
});

it('should send some on-chain funds to node2', async () => {
it('should estimate on-chain fees', async () => {
store1.payment.address = store2.walletAddress;
store1.payment.amount = '10';
await payments1.estimateFee();
expect(store1.payment.fee, 'to be ok');
});

it('should send some on-chain funds to node2', async () => {
await payments1.payBitcoin();
});

Expand Down
26 changes: 26 additions & 0 deletions test/unit/action/payment.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ describe('Action Payments Unit Tests', () => {
payment.init();
expect(store.payment.address, 'to equal', '');
expect(store.payment.amount, 'to equal', '');
expect(store.payment.fee, 'to equal', '');
expect(store.payment.note, 'to equal', '');
expect(nav.goPay, 'was called once');
});
Expand Down Expand Up @@ -80,6 +81,31 @@ describe('Action Payments Unit Tests', () => {
});
});

describe('estimateFee()', () => {
it('should get fee estimate to display', async () => {
store.payment.amount = '0.00001';
store.payment.address = 'some-address';
grpc.sendCommand.withArgs('estimateFee').resolves({
estimate: {
fee_sat: '8250',
feerate_sat_per_byte: '50',
},
});
await payment.estimateFee();
expect(grpc.sendCommand, 'was called with', 'estimateFee', {
AddrToAmount: { 'some-address': 1000 },
});
expect(store.payment.fee, 'to equal', '0.0000825');
});

it('should display notification on error', async () => {
grpc.sendCommand.withArgs('estimateFee').rejects();
await payment.estimateFee();
expect(notification.display, 'was called once');
expect(store.payment.fee, 'to equal', '');
});
});

describe('payBitcoin()', () => {
it('should send on-chain transaction', async () => {
store.payment.amount = '0.00001';
Expand Down