Skip to content
This repository was archived by the owner on Feb 23, 2021. It is now read-only.

Commit ec6555e

Browse files
valentinewallacetanx
authored andcommitted
Add setMax method to payment action for max on-chain withdrawal.
1 parent 4e64148 commit ec6555e

File tree

2 files changed

+61
-2
lines changed

2 files changed

+61
-2
lines changed

src/action/payment.js

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,37 @@ class PaymentAction {
125125
this._store.payment.sendAll = false;
126126
}
127127

128+
/**
129+
* Set the payment amount to the max amount that can be sent. This
130+
* is useful for people to move their coins off of the app.
131+
* @return {Promise<undefined>}
132+
*/
133+
async setMax() {
134+
const timeout = setTimeout(() => {
135+
return this._notification.display({
136+
type: 'error',
137+
msg: 'Setting max payment amount timed out!',
138+
});
139+
}, PAYMENT_TIMEOUT);
140+
const { payment, balanceSatoshis, settings } = this._store;
141+
let feeSat;
142+
let amtSat = Math.floor(0.99 * balanceSatoshis);
143+
while (!feeSat) {
144+
try {
145+
feeSat = await this._getFeeEstimateSat({
146+
addr: payment.address,
147+
amtSat,
148+
});
149+
} catch (err) {
150+
amtSat = Math.floor(0.99 * amtSat);
151+
} finally {
152+
clearTimeout(timeout);
153+
}
154+
}
155+
payment.amount = toAmount(amtSat, settings);
156+
payment.sendAll = true;
157+
}
158+
128159
/**
129160
* Check if the address input provided by the user is either an on-chain
130161
* bitcoin address or a lightning invoice. Depending on which type it is
@@ -201,12 +232,21 @@ class PaymentAction {
201232
*/
202233
async estimateFee() {
203234
const { payment, settings } = this._store;
235+
const amtSat = toSatoshis(payment.amount, settings);
236+
const feeSat = await this._getFeeEstimateSat({
237+
addr: payment.address,
238+
amtSat,
239+
});
240+
payment.fee = toAmount(feeSat, settings);
241+
}
242+
243+
async _getFeeEstimateSat({ addr, amtSat }) {
204244
const AddrToAmount = {};
205-
AddrToAmount[payment.address] = toSatoshis(payment.amount, settings);
245+
AddrToAmount[addr] = amtSat;
206246
const { feeSat } = await this._grpc.sendCommand('estimateFee', {
207247
AddrToAmount,
208248
});
209-
payment.fee = toAmount(feeSat, settings);
249+
return feeSat;
210250
}
211251

212252
/**

test/unit/action/payment.spec.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,25 @@ describe('Action Payments Unit Tests', () => {
302302
});
303303
});
304304

305+
describe('setMax()', () => {
306+
it('should set the payment amount to ~99% of the wallet balance', async () => {
307+
store.payment.address = 'some-address';
308+
store.balanceSatoshis = 100000;
309+
grpc.sendCommand.onSecondCall().resolves({ feeSat: 100 });
310+
await payment.setMax();
311+
expect(store.payment.amount, 'to match', /^0[,.]0{3}9{1}8{1}0{1}1{1}$/);
312+
expect(store.payment.sendAll, 'to be true');
313+
});
314+
315+
it('should display error notification on timeout', async () => {
316+
grpc.sendCommand.callsFake(() => nap(50));
317+
payment.setMax();
318+
await nap(10);
319+
expect(store.payment.amount, 'to be', '');
320+
expect(store.payment.sendAll, 'to be false');
321+
});
322+
});
323+
305324
describe('payBitcoin()', () => {
306325
it('should send on-chain transaction', async () => {
307326
store.payment.amount = '0.00001';

0 commit comments

Comments
 (0)