Skip to content
This repository was archived by the owner on Apr 28, 2023. It is now read-only.

Commit

Permalink
feat: show error if invoice could not be paid (#126)
Browse files Browse the repository at this point in the history
  • Loading branch information
michael1011 authored Mar 10, 2019
1 parent 3c1d1f6 commit 7b38103
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 64 deletions.
8 changes: 4 additions & 4 deletions src/components/controls/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React from 'react';
import injectSheet from 'react-jss';
import PropTypes from 'prop-types';
import View from '../view';
import injectSheet from 'react-jss';
import { MdArrowForward } from 'react-icons/md';
import View from '../view';

const styles = theme => ({
wrapper: {
Expand Down Expand Up @@ -85,14 +85,14 @@ Controls.propTypes = {
classes: PropTypes.object.isRequired,
text: PropTypes.string,
error: PropTypes.bool,
errorText: PropTypes.string,
errorAction: PropTypes.func,
errorText: PropTypes.string,
onPress: PropTypes.func,
loading: PropTypes.bool,
loadingText: PropTypes.string,
loadingStyle: PropTypes.string,
loadingRender: PropTypes.func,
errorRender: PropTypes.func,
errorRender: PropTypes.node,
};

export default injectSheet(styles)(Controls);
13 changes: 13 additions & 0 deletions src/constants/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,19 @@ const capitalizeFirstLetter = input => {
return input.charAt(0).toUpperCase() + input.slice(1);
};

export const SwapUpdateEvent = {
InvoicePaid: 'invoice.paid',
InvoiceSettled: 'invoice.settled',
InvoiceFailedToPay: 'invoice.failedToPay',

TransactionRefunded: 'transaction.refunded',
TransactionConfirmed: 'transaction.confirmed',
};

/**
* Values from the environment
*/

// API endpoint
export const boltzApi = process.env.REACT_APP_BOLTZ_API;

Expand Down
88 changes: 53 additions & 35 deletions src/views/reverse/reverseActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@ import axios from 'axios';
import EventSource from 'eventsource';
import { Transaction, ECPair, address } from 'bitcoinjs-lib';
import { detectSwap, constructClaimTransaction } from 'boltz-core';
import { boltzApi } from '../../constants';
import * as actionTypes from '../../constants/actions';
import { boltzApi, SwapUpdateEvent } from '../../constants';
import {
toSatoshi,
getHexBuffer,
getNetwork,
getHexBuffer,
getFeeEstimation,
} from '../../scripts/utils';

let latestSwapStatus = '';
let latestSwapEvent = '';

export const initReverseSwap = state => ({
type: actionTypes.INIT_REVERSE_SWAP,
Expand Down Expand Up @@ -94,7 +94,7 @@ export const startReverseSwap = (swapInfo, nextStage, timelockExpired) => {
};
};

const claimTransaction = (swapInfo, response, preimage, feeEstimation) => {
const getClaimTransaction = (swapInfo, response, preimage, feeEstimation) => {
const redeemScript = getHexBuffer(response.redeemScript);
const lockupTransaction = Transaction.fromHex(response.lockupTransaction);

Expand All @@ -114,7 +114,7 @@ const claimTransaction = (swapInfo, response, preimage, feeEstimation) => {
);
};

const handleSwapStatus = (
const handleReverseSwapStatus = (
data,
source,
dispatch,
Expand All @@ -123,38 +123,56 @@ const handleSwapStatus = (
swapInfo,
response
) => {
const message = data.message;
const event = data.event;

if (message === latestSwapStatus) {
// If this function is called with the data from the GET endpoint "/swapstatus"
// it could be that the received event has already been handled
if (event === latestSwapEvent) {
return;
} else {
latestSwapStatus = message;
latestSwapEvent = event;
}

if (message.startsWith('Transaction confirmed')) {
dispatch(setReverseSwapStatus('Waiting for invoice to be paid...'));
nextStage();
} else if (data.message.startsWith('Refunded lockup transaction')) {
source.close();
dispatch(timelockExpired());
} else if (!message.startsWith('Could not find swap with id')) {
source.close();
dispatch(
getFeeEstimation(feeEstimation => {
const claimTx = claimTransaction(
swapInfo,
response,
data.preimage,
feeEstimation
);
dispatch(
broadcastClaim(swapInfo.quote, claimTx.toHex(), () => {
dispatch(reverseSwapResponse(true, response));
nextStage();
})
);
})
);
switch (event) {
case SwapUpdateEvent.TransactionConfirmed:
dispatch(setReverseSwapStatus('Waiting for invoice to be paid...'));
nextStage();
break;

case SwapUpdateEvent.TransactionRefunded:
source.close();
dispatch(timelockExpired());
break;

case SwapUpdateEvent.InvoiceSettled:
source.close();

dispatch(
getFeeEstimation(feeEstimation => {
const claimTransaction = getClaimTransaction(
swapInfo,
response,
data.preimage,
feeEstimation
);

dispatch(
broadcastClaimTransaction(
swapInfo.quote,
claimTransaction.toHex(),
() => {
dispatch(reverseSwapResponse(true, response));
nextStage();
}
)
);
})
);
break;

default:
console.log(`Unknown swap status: ${data}`);
break;
}
};

Expand Down Expand Up @@ -196,7 +214,7 @@ const startListening = (
timelockExpired
);

handleSwapStatus(
handleReverseSwapStatus(
statusReponse.data,
source,
dispatch,
Expand All @@ -210,7 +228,7 @@ const startListening = (
};

source.onmessage = event => {
handleSwapStatus(
handleReverseSwapStatus(
JSON.parse(event.data),
source,
dispatch,
Expand All @@ -222,7 +240,7 @@ const startListening = (
};
};

const broadcastClaim = (currency, claimTransaction, cb) => {
const broadcastClaimTransaction = (currency, claimTransaction, cb) => {
const url = `${boltzApi}/broadcasttransaction`;
return dispatch => {
axios
Expand Down
2 changes: 1 addition & 1 deletion src/views/swap/swap.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ const Swap = ({
loading={swapStatus.pending}
error={swapStatus.error}
errorText={swapStatus.message}
errorAction={() => startSwap(swapInfo, props.nextStage)}
errorRender={() => {}}
loadingRender={() => <Loading />}
onPress={() => {
props.nextStage();
Expand Down
67 changes: 43 additions & 24 deletions src/views/swap/swapActions.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import axios from 'axios';
import EventSource from 'eventsource';
import { boltzApi } from '../../constants';
import { boltzApi, SwapUpdateEvent } from '../../constants';
import * as actionTypes from '../../constants/actions';

export const completeSwap = () => {
Expand Down Expand Up @@ -74,35 +74,54 @@ export const startSwap = (swapInfo, cb) => {
};
};

const handleSwapStatus = (data, source, dispatch, callback) => {
const event = data.event;

switch (event) {
case SwapUpdateEvent.TransactionConfirmed:
dispatch(
setSwapStatus({
pending: true,
message: 'Waiting for invoice to be paid...',
})
);
break;

case SwapUpdateEvent.InvoiceFailedToPay:
source.close();
dispatch(
setSwapStatus({
error: true,
pending: false,
message: 'Could not pay invoice. Please refund your coins.',
})
);
break;

case SwapUpdateEvent.InvoicePaid:
source.close();
callback();
break;

default:
console.log(`Unknown swap status: ${data}`);
break;
}
};

export const startListening = (dispatch, swapId, callback) => {
const source = new EventSource(`${boltzApi}/streamswapstatus?id=${swapId}`);

let message = {
pending: true,
message: 'Waiting for one confirmation...',
};

dispatch(setSwapStatus(message));
dispatch(
setSwapStatus({
pending: true,
message: 'Waiting for one confirmation...',
})
);

source.onmessage = event => {
const data = JSON.parse(event.data);

if (data.message.startsWith('Invoice paid:')) {
source.close();
callback();
} else if (data.message.startsWith('Transaction confirmed:')) {
message = {
pending: true,
message: 'Waiting for invoice to be paid...',
};
} else {
message = {
error: true,
pending: true,
message: 'Boltz could not find the transaction',
};
}

dispatch(setSwapStatus(message));
handleSwapStatus(data, source, dispatch, callback);
};
};

0 comments on commit 7b38103

Please sign in to comment.