Skip to content

Commit f800f52

Browse files
Merge pull request #136 from liquality/refund_flow
Refund flow for swaps
2 parents d1ee998 + 1b74bae commit f800f52

File tree

14 files changed

+544
-359
lines changed

14 files changed

+544
-359
lines changed

package-lock.json

Lines changed: 297 additions & 331 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,21 @@
44
"private": true,
55
"dependencies": {
66
"@liquality/cryptoassets": "^0.0.7",
7-
"@liquality/bitcoin-bitcoinjs-lib-swap-provider": "^0.2.2",
8-
"@liquality/bitcoin-bitcore-rpc-provider": "^0.2.2",
9-
"@liquality/bitcoin-ledger-provider": "^0.2.2",
10-
"@liquality/bitcoin-networks": "^0.2.2",
11-
"@liquality/bitcoin-swap-provider": "^0.2.2",
12-
"@liquality/client": "^0.2.2",
13-
"@liquality/crypto": "^0.2.2",
14-
"@liquality/errors": "^0.2.2",
15-
"@liquality/ethereum-erc20-provider": "^0.2.2",
16-
"@liquality/ethereum-erc20-swap-provider": "^0.2.2",
17-
"@liquality/ethereum-ledger-provider": "^0.2.2",
18-
"@liquality/ethereum-metamask-provider": "^0.2.2",
19-
"@liquality/ethereum-networks": "^0.2.2",
20-
"@liquality/ethereum-rpc-provider": "^0.2.2",
21-
"@liquality/ethereum-swap-provider": "^0.2.2",
7+
"@liquality/bitcoin-bitcoinjs-lib-swap-provider": "^0.2.7",
8+
"@liquality/bitcoin-bitcore-rpc-provider": "^0.2.7",
9+
"@liquality/bitcoin-ledger-provider": "^0.2.7",
10+
"@liquality/bitcoin-networks": "^0.2.7",
11+
"@liquality/bitcoin-swap-provider": "^0.2.7",
12+
"@liquality/client": "^0.2.7",
13+
"@liquality/crypto": "^0.2.7",
14+
"@liquality/errors": "^0.2.7",
15+
"@liquality/ethereum-erc20-provider": "^0.2.7",
16+
"@liquality/ethereum-erc20-swap-provider": "^0.2.7",
17+
"@liquality/ethereum-ledger-provider": "^0.2.7",
18+
"@liquality/ethereum-metamask-provider": "^0.2.7",
19+
"@liquality/ethereum-networks": "^0.2.7",
20+
"@liquality/ethereum-rpc-provider": "^0.2.7",
21+
"@liquality/ethereum-swap-provider": "^0.2.7",
2222
"@material-ui/core": "^3.5.1",
2323
"bignumber.js": "^8.0.1",
2424
"bootstrap": "^4.1.3",

src/actions/swap.js

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,24 @@ function waitForSwapClaim () {
251251
}
252252
}
253253

254+
function waitForSwapRefund () {
255+
return async (dispatch, getState) => {
256+
const {
257+
assets,
258+
wallets,
259+
transactions,
260+
counterParty,
261+
secretParams,
262+
expiration,
263+
isPartyB
264+
} = getState().swap
265+
const client = getClient(assets.a.currency, wallets.a.type)
266+
const swapExpiration = getFundExpiration(expiration, isPartyB ? 'a' : 'b').time
267+
const refundTransaction = await client.swap.findRefundSwapTransaction(transactions.a.fund.hash, counterParty.a.address, wallets.a.addresses[0], secretParams.secretHash, swapExpiration.unix())
268+
dispatch(transactionActions.setTransaction('a', 'refund', refundTransaction))
269+
}
270+
}
271+
254272
async function unlockFunds (dispatch, getState) {
255273
const {
256274
assets,
@@ -302,14 +320,16 @@ function refundSwap () {
302320

303321
const client = getClient(assets.a.currency, wallets.a.type)
304322
const swapExpiration = getFundExpiration(expiration, isPartyB ? 'b' : 'a').time
323+
const block = await client.chain.getBlockHeight()
305324
await withLoadingMessage('a', dispatch, getState, async () => {
306-
return client.swap.refundSwap(
325+
const refundTxHash = await client.swap.refundSwap(
307326
transactions.a.fund.hash,
308327
counterParty.a.address,
309328
wallets.a.addresses[0],
310329
secretParams.secretHash,
311330
swapExpiration.unix()
312331
)
332+
dispatch(transactionActions.setTransaction('a', 'refund', { hash: refundTxHash, block }))
313333
})
314334
}
315335
}
@@ -328,6 +348,7 @@ const actions = {
328348
verifyInitiateSwapTransaction,
329349
waitForSwapConfirmation,
330350
waitForSwapClaim,
351+
waitForSwapRefund,
331352
redeemSwap,
332353
refundSwap
333354
}

src/actions/transactions.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,19 @@ function setStep (transactions, isPartyB, dispatch) {
4242
}
4343

4444
function setLocation (swap, currentLocation, dispatch) {
45-
const canNavigate = currentLocation.pathname !== '/backupLink' && currentLocation.pathname !== '/refund'
45+
const hasRefunded = swap.transactions.a.refund && swap.transactions.a.refund.hash
46+
const canNavigate = currentLocation.pathname !== '/backupLink' && (hasRefunded || currentLocation.pathname !== '/refund')
4647
if (canNavigate) {
4748
const hasInitiated = swap.transactions.a.fund.hash && swap.transactions.a.fund.confirmations > 0
4849
const canRefund = !swap.transactions.b.claim.hash || swap.transactions.b.claim.confirmations === 0
4950
const swapExpiration = getFundExpiration(swap.expiration, swap.isPartyB ? 'b' : 'a').time
5051
const swapExpired = moment().isAfter(swapExpiration)
5152
if (hasInitiated && canRefund && swapExpired) {
52-
dispatch(replace('/refund'))
53+
if (hasRefunded) {
54+
dispatch(replace('/refunded'))
55+
} else {
56+
dispatch(replace('/refund'))
57+
}
5358
} else if (swap.step === steps.AGREEMENT && currentLocation.pathname !== '/waiting') {
5459
if (swap.isPartyB || swap.transactions.b.fund.hash) {
5560
dispatch(replace('/waiting'))
@@ -72,6 +77,8 @@ async function monitorTransaction (swap, party, kind, tx, dispatch, getState) {
7277
client = getClient(swap.assets[currentParty].currency, swap.wallets[currentParty].type)
7378
} else if (kind === 'fund') {
7479
client = getClient(swap.assets[party].currency, swap.wallets[party].type)
80+
} else if (kind === 'refund') {
81+
client = getClient(swap.assets[party].currency, swap.wallets[party].type)
7582
}
7683
const updatedTransaction = await client.chain.getTransactionByHash(tx.hash)
7784
if (updatedTransaction) {
@@ -126,6 +133,11 @@ function loadTransactions () {
126133
if (swapState.transactions.a.fund.hash && !swapState.transactions.b.claim.hash) {
127134
dispatch(swapActions.waitForSwapClaim())
128135
}
136+
const swapExpiration = getFundExpiration(swapState.expiration, swapState.isPartyB ? 'b' : 'a').time
137+
const swapExpired = moment().isAfter(swapExpiration)
138+
if (swapState.transactions.a.fund.hash && swapExpired) {
139+
dispatch(swapActions.waitForSwapRefund())
140+
}
129141
}
130142
}
131143
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import React, { Component } from 'react'
2+
import { shortenAddress } from '../../utils/address'
3+
4+
import './HexaDisplay.css'
5+
6+
class HexaDisplay extends Component {
7+
onCopyLink () {
8+
const tempInput = document.createElement('input')
9+
tempInput.value = this.props.address
10+
tempInput.style = 'position: absolute; top: -2000px;'
11+
document.body.appendChild(tempInput)
12+
tempInput.select()
13+
document.execCommand('copy')
14+
document.body.removeChild(tempInput)
15+
}
16+
17+
render () {
18+
return <span onClick={() => this.onCopyLink.bind(this)()} className='HexaDisplay'>
19+
{shortenAddress(this.props.address)}
20+
</span>
21+
}
22+
}
23+
24+
export default HexaDisplay
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.HexaDisplay {
2+
color: #8D46E2;
3+
cursor: pointer;
4+
}

src/containers/LiqualitySwap/LiqualitySwap.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import WalletPopups from '../WalletPopups'
1212
import SwapRedemption from '../SwapRedemption'
1313
import SwapCompleted from '../SwapCompleted'
1414
import SwapRefund from '../SwapRefund'
15+
import SwapRefunded from '../SwapRefunded'
1516
import SwapProgressStepper from '../../components/SwapProgressStepper/SwapProgressStepper'
1617
import { generateLink } from '../../utils/app-links'
1718
import config from '../../config'
@@ -85,6 +86,7 @@ class LiqualitySwap extends Component {
8586
<Route path='/redeem' component={SwapRedemption} />
8687
<Route path='/completed' component={SwapCompleted} />
8788
<Route path='/refund' component={SwapRefund} />
89+
<Route path='/refunded' component={SwapRefunded} />
8890
<WalletPopups />
8991
</div>
9092
</div>

src/containers/LiqualitySwap/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export default withRouter(connect(
1515
{
1616
waitForSwapConfirmation: swapActions.waitForSwapConfirmation,
1717
waitForSwapClaim: swapActions.waitForSwapClaim,
18+
waitForSwapRefund: swapActions.waitForSwapRefund,
1819
clearError: errorActions.clearError,
1920
waitForWallet: walletsActions.waitForWallet,
2021
waitForWalletInitialization: walletsActions.waitForWalletInitialization,

src/containers/SwapRefund/SwapRefund.js

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,37 @@ import './SwapRefund.css'
66

77
class SwapRedemption extends Component {
88
render () {
9-
return <BrandCard className='SwapRefund' title='Refund'>
10-
<div className='SwapRefund_confirmation'>
11-
<p className='SwapRefund_terms'>
12-
{this.props.assets.a.value} {cryptoassets[this.props.assets.a.currency].code}
13-
</p>
14-
<p>Your funds are ready for a refund.</p>
9+
return <div>
10+
<BrandCard className='SwapRefund' title='RECLAIM YOUR ASSETS'>
11+
<div className='SwapRefund_confirmation'>
12+
Refund amount:
13+
<p className='SwapRefund_terms'>
14+
{this.props.assets.a.value} {cryptoassets[this.props.assets.a.currency].code}
15+
</p>
16+
<p>To process this refund, press the reclaim button.</p>
17+
</div>
18+
<p><Button wide primary loadingMessage={this.props.loadingMessage} onClick={this.props.refundSwap}>Reclaim</Button></p>
19+
</BrandCard>
20+
<div className='SwapRefund_expiredFrame'>
21+
<div className='SwapRefund_expiredFrame_content'>
22+
23+
<p className='SwapRefund_expiredFrame_content_title'>
24+
Expired Swap offer
25+
</p>
26+
<hr />
27+
<p>
28+
Receive: <span className='SwapRefund_expiredFrame_content_value'>{this.props.assets.b.value} {cryptoassets[this.props.assets.b.currency].code}</span>
29+
</p>
30+
<p>
31+
For: <span className='SwapRefund_expiredFrame_content_value'>{this.props.assets.a.value} {cryptoassets[this.props.assets.a.currency].code}</span>
32+
</p>
33+
<p>
34+
Expired: <span className='SwapRefund_expiredFrame_content_value'>{this.props.expiration.format('DD/MM/YYYY h:mm a')}</span>
35+
</p>
36+
<hr />
37+
</div>
1538
</div>
16-
<p><Button wide primary loadingMessage={this.props.loadingMessage} onClick={this.props.refundSwap}>Get Refund</Button></p>
17-
</BrandCard>
39+
</div>
1840
}
1941
}
2042

src/containers/SwapRefund/SwapRefund.scss

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,32 @@
66
&_terms {
77
font-size: $h1-font-size;
88
}
9+
10+
&_expiredFrame {
11+
text-align: center;
12+
width: 100%;
13+
background-color: #F7F8FA;
14+
color: #A4AAB6;
15+
margin-top: -20px;
16+
border-radius: 0px 0px 22px 22px;
17+
padding: 50px;
18+
19+
&_content {
20+
margin-left: 30%;
21+
width: 40%;
22+
text-align: left;
23+
24+
&_title {
25+
text-align: center;
26+
color: #494949;
27+
}
28+
29+
&_value {
30+
color: #5F5F5F;
31+
}
32+
}
33+
34+
}
35+
36+
937
}

0 commit comments

Comments
 (0)