Skip to content
This repository was archived by the owner on Feb 23, 2021. It is now read-only.
Merged
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
4 changes: 4 additions & 0 deletions src/action/nav.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ class NavAction {
this._store.route = 'PayLightningDone';
}

goPaymentFailed() {
this._store.route = 'PaymentFailed';
}

goPayBitcoin() {
this._store.route = 'PayBitcoin';
}
Expand Down
11 changes: 10 additions & 1 deletion src/action/payment.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* call the corresponding GRPC apis for payment management.
*/

import { PREFIX_URI } from '../config';
import { PREFIX_URI, PAYMENT_TIMEOUT } from '../config';
import {
toSatoshis,
toAmount,
Expand Down Expand Up @@ -170,6 +170,11 @@ class PaymentAction {
* @return {Promise<undefined>}
*/
async payLightning() {
let failed = false;
const timeout = setTimeout(() => {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How can I test this block manually? In my local simnet environment I'm always getting an error from the stream data.payment_error and it just shows the notification.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested by manually putting a sleep before the failed check, forcing a timeout. Not the most robust 😬

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@valentinewallace well, that's one way of doing it :D.

failed = true;
this._nav.goPaymentFailed();
}, PAYMENT_TIMEOUT);
try {
this._nav.goWait();
const invoice = this._store.payment.address.replace(PREFIX_URI, '');
Expand All @@ -185,10 +190,14 @@ class PaymentAction {
stream.on('error', reject);
stream.write(JSON.stringify({ payment_request: invoice }), 'utf8');
});
if (failed) return;
this._nav.goPayLightningDone();
} catch (err) {
if (failed) return;
this._nav.goPayLightningConfirm();
this._notification.display({ msg: 'Lightning payment failed!', err });
} finally {
clearTimeout(timeout);
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module.exports.RETRY_DELAY = 1000;
module.exports.LND_INIT_DELAY = 5000;
module.exports.NOTIFICATION_DELAY = 5000;
module.exports.RATE_DELAY = 15 * 60 * 1000;
module.exports.PAYMENT_TIMEOUT = 60 * 1000;

module.exports.LND_PORT = 10006;
module.exports.LND_PEER_PORT = 10016;
Expand Down
4 changes: 4 additions & 0 deletions src/view/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import Home from './home';
import Payment from './payment';
import PayLightningConfirm from './pay-lightning-confirm';
import PayLightningDone from './pay-lightning-done';
import PaymentFailed from './payment-failed';
import PayBitcoin from './pay-bitcoin';
import PayBitcoinConfirm from './pay-bitcoin-confirm';
import PayBitcoinDone from './pay-bitcoin-done';
Expand Down Expand Up @@ -111,6 +112,9 @@ class MainView extends Component {
{route === 'PayLightningDone' && (
<PayLightningDone store={store} payment={payment} nav={nav} />
)}
{route === 'PaymentFailed' && (
<PaymentFailed channel={channel} nav={nav} />
)}
{route === 'PayBitcoin' && (
<PayBitcoin store={store} payment={payment} nav={nav} />
)}
Expand Down
17 changes: 10 additions & 7 deletions src/view/no-route.js → src/view/payment-failed.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,29 +28,32 @@ const styles = StyleSheet.create({
},
});

const NoRouteView = ({ channel, payment }) => (
const PaymentFailedView = ({ channel, nav }) => (
<Background color={color.blackDark}>
<MainContent>
<FormStretcher>
<LightningErrorIcon height={115 * 0.8} width={60 * 0.8} />
<H1Text style={styles.h1Txt}>No route found</H1Text>
<H1Text style={styles.h1Txt}>Payment Failed</H1Text>
<CopyText style={styles.copyTxt}>
{"You'll need to manually create a channel"}
{'You may need to manually create a channel.'}
</CopyText>
</FormStretcher>
<PillButton style={styles.createBtn} onPress={() => channel.initCreate()}>
Create channel
</PillButton>
<Button style={styles.retryBtn} onPress={() => payment.init()}>
<Button
style={styles.retryBtn}
onPress={() => nav.goPayLightningConfirm()}
>
<ButtonText>Try again</ButtonText>
</Button>
</MainContent>
</Background>
);

NoRouteView.propTypes = {
PaymentFailedView.propTypes = {
channel: PropTypes.object.isRequired,
payment: PropTypes.object.isRequired,
nav: PropTypes.object.isRequired,
};

export default observer(NoRouteView);
export default observer(PaymentFailedView);
4 changes: 2 additions & 2 deletions stories/screen-story.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import PayLightningDone from '../src/view/pay-lightning-done';
import PayBitcoin from '../src/view/pay-bitcoin';
import PayBitcoinConfirm from '../src/view/pay-bitcoin-confirm';
import PayBitcoinDone from '../src/view/pay-bitcoin-done';
import NoRoute from '../src/view/no-route';
import PaymentFailed from '../src/view/payment-failed';
import Loader from '../src/view/loader';
import LoaderSyncing from '../src/view/loader-syncing';
import SelectSeed from '../src/view/select-seed';
Expand Down Expand Up @@ -149,7 +149,7 @@ storiesOf('Screens', module)
.add('Pay Lightning Done', () => (
<PayLightningDone store={store} payment={payment} nav={nav} />
))
.add('No Route Found', () => <NoRoute channel={channel} payment={payment} />)
.add('Payment Failed', () => <PaymentFailed channel={channel} nav={nav} />)
.add('Pay Bitcoin', () => (
<PayBitcoin store={store} payment={payment} nav={nav} />
))
Expand Down
7 changes: 7 additions & 0 deletions test/unit/action/nav.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,13 @@ describe('Action Nav Unit Tests', () => {
});
});

describe('goPaymentFailed()', () => {
it('should set correct route', () => {
nav.goPaymentFailed();
expect(store.route, 'to equal', 'PaymentFailed');
});
});

describe('goPayBitcoin()', () => {
it('should set correct route', () => {
nav.goPayBitcoin();
Expand Down
8 changes: 8 additions & 0 deletions test/unit/action/payment.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ describe('Action Payments Unit Tests', () => {
store = new Store();
store.settings.displayFiat = false;
require('../../../src/config').RETRY_DELAY = 1;
require('../../../src/config').PAYMENT_TIMEOUT = 10;
grpc = sinon.createStubInstance(GrpcAction);
notification = sinon.createStubInstance(NotificationAction);
nav = sinon.createStubInstance(NavAction);
Expand Down Expand Up @@ -240,5 +241,12 @@ describe('Action Payments Unit Tests', () => {
expect(nav.goPayLightningConfirm, 'was called once');
expect(notification.display, 'was called once');
});

it('should go to error page on timeout', async () => {
payment.payLightning({ invoice: 'some-invoice' });
await nap(100);
expect(nav.goPaymentFailed, 'was called once');
expect(nav.goPayLightningDone, 'was not called');
});
});
});