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

Commit df0076d

Browse files
committed
Unpolished but working desktop zero value payments.
1 parent 736870b commit df0076d

File tree

3 files changed

+92
-41
lines changed

3 files changed

+92
-41
lines changed

src/action/payment.js

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,26 @@ class PaymentAction {
206206
}
207207
}
208208

209+
/**
210+
* Estimate the lightning transaction fee using the queryRoutes grpc api
211+
* after which the fee is set in the store.
212+
* @param {number} options.satAmt The amount to be payed in satoshis
213+
* @return {Promise<undefined>}
214+
*/
215+
async estimateLightningFeeForAmount({ amount }) {
216+
try {
217+
const request = await this._grpc.sendCommand('decodePayReq', {
218+
payReq: this._store.payment.address,
219+
});
220+
this.estimateLightningFee({
221+
destination: request.destination,
222+
satAmt: toSatoshis(amount, this._store.settings),
223+
});
224+
} catch (err) {
225+
log.info(`Estimating lightning fee failed!`, err);
226+
}
227+
}
228+
209229
/**
210230
* Estimate the lightning transaction fee using the queryRoutes grpc api
211231
* after which the fee is set in the store.
@@ -328,7 +348,8 @@ class PaymentAction {
328348
}
329349

330350
/**
331-
* Send the amount specified in the invoice as a lightning transaction and
351+
* Send the amount specified in the payment.amount. If zero use the amount
352+
* specified in the invoice as a lightning transaction and
332353
* display the wait screen while the payment confirms.
333354
* This action can be called from a view event handler as does all
334355
* the necessary error handling and notification display.
@@ -343,6 +364,8 @@ class PaymentAction {
343364
try {
344365
this._nav.goWait();
345366
const invoice = this._store.payment.address;
367+
const { settings } = this._store;
368+
const satAmt = toSatoshis(this._store.payment.amount, settings);
346369
const stream = this._grpc.sendStreamCommand('sendPayment');
347370
await new Promise((resolve, reject) => {
348371
stream.on('data', data => {
@@ -353,7 +376,13 @@ class PaymentAction {
353376
}
354377
});
355378
stream.on('error', reject);
356-
stream.write(JSON.stringify({ paymentRequest: invoice }), 'utf8');
379+
stream.write(
380+
JSON.stringify({
381+
paymentRequest: invoice,
382+
amt: satAmt,
383+
}),
384+
'utf8'
385+
);
357386
});
358387
if (failed) return;
359388
this._nav.goPayLightningDone();

src/view/pay-lightning-supply-amount.js

Lines changed: 41 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,78 +4,82 @@ import { observer } from 'mobx-react';
44
import PropTypes from 'prop-types';
55
import Background from '../component/background';
66
import MainContent from '../component/main-content';
7-
import { NamedField } from '../component/field';
7+
import { NamedField, AmountInputField } from '../component/field';
88
import { Header, Title } from '../component/header';
9-
import { CancelButton, BackButton, PillButton } from '../component/button';
9+
import {
10+
MaxButton,
11+
CancelButton,
12+
BackButton,
13+
PillButton,
14+
} from '../component/button';
1015
import Card from '../component/card';
1116
import LightningBoltIcon from '../asset/icon/lightning-bolt';
12-
import { FormStretcher } from '../component/form';
13-
import {
14-
BalanceLabel,
15-
BalanceLabelNumeral,
16-
BalanceLabelUnit,
17-
} from '../component/label';
17+
import { FormStretcher, FormText } from '../component/form';
18+
import { BalanceLabel, BalanceLabelUnit } from '../component/label';
1819
import { color } from '../component/style';
1920

2021
const styles = StyleSheet.create({
21-
balance: {
22-
marginBottom: 10,
23-
},
24-
numeral: {
25-
color: color.blackText,
22+
description: {
23+
paddingLeft: 20,
24+
paddingRight: 20,
2625
},
2726
unit: {
2827
color: color.blackText,
2928
},
30-
totalLbl: {
31-
marginTop: 5,
32-
},
33-
note: {
34-
marginTop: 5,
35-
borderBottomWidth: 0,
29+
maxBtn: {
30+
marginTop: 10,
31+
marginBottom: 20,
3632
},
37-
confirmBtn: {
33+
nextBtn: {
3834
marginTop: 20,
35+
backgroundColor: color.purple,
3936
},
4037
});
4138

4239
const PayLightningSupplyAmountView = ({ store, nav, payment }) => (
43-
<Background image="purple-gradient-bg">
44-
<Header shadow color={color.purple}>
45-
<BackButton onPress={() => nav.goPay()} />
46-
<Title title="Supply Lightning Amount">
40+
<Background color={color.purple}>
41+
<Header color={color.purple}>
42+
<BackButton onPress={() => nav.goHome()} />
43+
<Title title="Specify Amount to Send">
4744
<LightningBoltIcon height={12} width={6.1} />
4845
</Title>
4946
<CancelButton onPress={() => nav.goHome()} />
5047
</Header>
5148
<MainContent>
5249
<Card>
50+
<FormText style={styles.description}>
51+
The invoice did not specify an amount.
52+
</FormText>
5353
<FormStretcher>
5454
<BalanceLabel style={styles.balance}>
55-
<BalanceLabelNumeral style={styles.numeral}>
56-
{store.paymentAmountLabel}
57-
</BalanceLabelNumeral>
55+
<AmountInputField
56+
autoFocus={true}
57+
value={store.payment.amount}
58+
onChangeText={amount => payment.setAmount({ amount })}
59+
onSubmitEditing={() =>
60+
payment.estimateLightningFeeForAmount(payment.amount)
61+
}
62+
/>
5863
<BalanceLabelUnit style={styles.unit}>
59-
{store.unitLabel}
64+
{store.unitFiatLabel}
6065
</BalanceLabelUnit>
6166
</BalanceLabel>
62-
<NamedField name="Fee">
63-
{store.paymentFeeLabel} {store.unitLabel}
64-
</NamedField>
65-
<NamedField name="Total" style={styles.totalLbl}>
66-
{store.paymentTotalLabel} {store.unitLabel}
67-
</NamedField>
67+
<MaxButton
68+
style={styles.maxBtn}
69+
active={store.payment.sendAll}
70+
onPress={() => payment.toggleMax()}
71+
/>
6872
{store.payment.note ? (
6973
<NamedField name="Note" style={styles.note}>
7074
{store.payment.note}
7175
</NamedField>
7276
) : null}
7377
</FormStretcher>
7478
<PillButton
75-
style={styles.confirmBtn}
76-
onPress={() => payment.payLightning()}
79+
style={styles.nextBtn}
80+
onPress={() => nav.goPayLightningConfirm()}
7781
>
78-
Confirm
82+
Pay
7983
</PillButton>
8084
</Card>
8185
</MainContent>

test/unit/action/payment.spec.js

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -469,15 +469,33 @@ describe('Action Payments Unit Tests', () => {
469469
});
470470
});
471471

472-
it('should send lightning payment', async () => {
472+
it('should send lightning payment with amount 0 if not specified.', async () => {
473473
paymentsOnStub.withArgs('data').yields({ paymentError: '' });
474474
payment.setAddress({ address: 'lightning:some-invoice' });
475475
await payment.payLightning();
476476
expect(grpc.sendStreamCommand, 'was called with', 'sendPayment');
477477
expect(
478478
paymentsWriteStub,
479479
'was called with',
480-
JSON.stringify({ paymentRequest: 'some-invoice' }),
480+
JSON.stringify({ paymentRequest: 'some-invoice', amt: 0 }),
481+
'utf8'
482+
);
483+
expect(nav.goWait, 'was called once');
484+
expect(nav.goPayLightningDone, 'was called once');
485+
expect(notification.display, 'was not called');
486+
});
487+
488+
it('should send lightning payment with amount.', async () => {
489+
paymentsOnStub.withArgs('data').yields({ paymentError: '' });
490+
payment.setAddress({ address: 'lightning:some-invoice' });
491+
store.settings.unit = 'btc';
492+
payment.setAmount({ amount: '0.0001' });
493+
await payment.payLightning();
494+
expect(grpc.sendStreamCommand, 'was called with', 'sendPayment');
495+
expect(
496+
paymentsWriteStub,
497+
'was called with',
498+
JSON.stringify({ paymentRequest: 'some-invoice', amt: 10000 }),
481499
'utf8'
482500
);
483501
expect(nav.goWait, 'was called once');

0 commit comments

Comments
 (0)