on master help sign in
Add transaction status indicator to SentTransaction
58ac642pkova
src/bridge/Bridge.js+13−2
@@ -80,7 +80,8 @@ class Bridge extends React.Component {
80 pointCursor: Maybe.Nothing(),
80 pointCursor: Maybe.Nothing(),
81 pointCache: {},
81 pointCache: {},
82 // txn
82 // txn
83− txnHashCursor: Maybe.Nothing()
83+ txnHashCursor: Maybe.Nothing(),
84+ txnConfirmations: {}
84 }
85 }
85
86
86 this.pushRoute = this.pushRoute.bind(this)
87 this.pushRoute = this.pushRoute.bind(this)
@@ -95,6 +96,7 @@ class Bridge extends React.Component {
95 this.setAuthMnemonic = this.setAuthMnemonic.bind(this)
96 this.setAuthMnemonic = this.setAuthMnemonic.bind(this)
96 this.setPointCursor = this.setPointCursor.bind(this)
97 this.setPointCursor = this.setPointCursor.bind(this)
97 this.setTxnHashCursor = this.setTxnHashCursor.bind(this)
98 this.setTxnHashCursor = this.setTxnHashCursor.bind(this)
99+ this.setTxnConfirmations = this.setTxnConfirmations.bind(this)
98 this.setNetworkSeedCache = this.setNetworkSeedCache.bind(this)
100 this.setNetworkSeedCache = this.setNetworkSeedCache.bind(this)
99 this.addToPointCache = this.addToPointCache.bind(this)
101 this.addToPointCache = this.addToPointCache.bind(this)
100 }
102 }
@@ -234,6 +236,12 @@ class Bridge extends React.Component {
234 this.setState({ txnHashCursor })
236 this.setState({ txnHashCursor })
235 }
237 }
236
238
239+ setTxnConfirmations(txnHash, txnConfirmations) {
240+ this.setState((prevState, _) =>
241+ ({txnConfirmations: { ...prevState.txnConfirmations,
242+ [txnHash]: txnConfirmations}}))
243+ }
244+
237 render() {
245 render() {
238 const {
246 const {
239 routeCrumbs,
247 routeCrumbs,
@@ -248,6 +256,7 @@ class Bridge extends React.Component {
248 pointCursor,
256 pointCursor,
249 pointCache,
257 pointCache,
250 txnHashCursor,
258 txnHashCursor,
259+ txnConfirmations,
251 web3,
260 web3,
252 contracts
261 contracts
253 } = this.state
262 } = this.state
@@ -300,7 +309,9 @@ class Bridge extends React.Component {
300 setNetworkSeedCache= { this.setNetworkSeedCache }
309 setNetworkSeedCache= { this.setNetworkSeedCache }
301 // txn
310 // txn
302 setTxnHashCursor={ this.setTxnHashCursor }
311 setTxnHashCursor={ this.setTxnHashCursor }
303− txnHashCursor={ txnHashCursor } />
312+ txnHashCursor={ txnHashCursor }
313+ setTxnConfirmations={ this.setTxnConfirmations }
314+ txnConfirmations={ txnConfirmations } />
304
315
305 <div className={'push'} />
316 <div className={'push'} />
306
317
src/bridge/components/StatelessTransaction.js+1−1
@@ -85,7 +85,7 @@ class StatelessTransaction extends React.Component {
85
85
86 submit(){
86 submit(){
87 const { props, state } = this
87 const { props, state } = this
88− sendSignedTransaction(props.web3.value, state.stx)
88+ sendSignedTransaction(props.web3.value, state.stx, props.setTxnConfirmations)
89 .then(sent => {
89 .then(sent => {
90 props.setTxnHashCursor(sent)
90 props.setTxnHashCursor(sent)
91 props.popRoute()
91 props.popRoute()
src/bridge/lib/txn.js+5−1
@@ -137,7 +137,7 @@ const signTransaction = async config => {
137 setStx(Just(stx))
137 setStx(Just(stx))
138}
138}
139
139
140−const sendSignedTransaction = (web3, stx) => {
140+const sendSignedTransaction = (web3, stx, confirmationCb) => {
141 const txn = stx.matchWith({
141 const txn = stx.matchWith({
142 Just: (tx) => tx.value,
142 Just: (tx) => tx.value,
143 Nothing: () => {
143 Nothing: () => {
@@ -155,6 +155,10 @@ const sendSignedTransaction = (web3, stx) => {
155 .on('receipt', txn => {
155 .on('receipt', txn => {
156 resolve(Just(Ok(txn.transactionHash)))
156 resolve(Just(Ok(txn.transactionHash)))
157 })
157 })
158+ .on('confirmation', (confirmationNum, txn) => {
159+ confirmationCb(txn.transactionHash, confirmationNum + 1)
160+ resolve(Just(Ok(txn.transactionHash)))
161+ })
158 .on('error', err => {
162 .on('error', err => {
159 reject(Just(Error(err.message)))
163 reject(Just(Error(err.message)))
160 })
164 })
src/bridge/views/AcceptTransfer.js+1
@@ -126,6 +126,7 @@ class AcceptTransfer extends React.Component {
126 walletHdPath={props.walletHdPath}
126 walletHdPath={props.walletHdPath}
127 networkType={props.networkType}
127 networkType={props.networkType}
128 setTxnHashCursor={props.setTxnHashCursor}
128 setTxnHashCursor={props.setTxnHashCursor}
129+ setTxnConfirmations={props.setTxnConfirmations}
129 popRoute={props.popRoute}
130 popRoute={props.popRoute}
130 pushRoute={props.pushRoute}
131 pushRoute={props.pushRoute}
131 // Other
132 // Other
src/bridge/views/CancelTransfer.js+1
@@ -87,6 +87,7 @@ class CancelTransfer extends React.Component {
87 walletHdPath={props.walletHdPath}
87 walletHdPath={props.walletHdPath}
88 networkType={props.networkType}
88 networkType={props.networkType}
89 setTxnHashCursor={props.setTxnHashCursor}
89 setTxnHashCursor={props.setTxnHashCursor}
90+ setTxnConfirmations={props.setTxnConfirmations}
90 popRoute={props.popRoute}
91 popRoute={props.popRoute}
91 pushRoute={props.pushRoute}
92 pushRoute={props.pushRoute}
92 // Other
93 // Other
src/bridge/views/CreateGalaxy.js+1
@@ -212,6 +212,7 @@ class CreateGalaxy extends React.Component {
212 walletHdPath={props.walletHdPath}
212 walletHdPath={props.walletHdPath}
213 networkType={props.networkType}
213 networkType={props.networkType}
214 setTxnHashCursor={props.setTxnHashCursor}
214 setTxnHashCursor={props.setTxnHashCursor}
215+ setTxnConfirmations={props.setTxnConfirmations}
215 popRoute={props.popRoute}
216 popRoute={props.popRoute}
216 pushRoute={props.pushRoute}
217 pushRoute={props.pushRoute}
217 // Other
218 // Other
src/bridge/views/IssueChild.js+1
@@ -303,6 +303,7 @@ class IssueChild extends React.Component {
303 walletHdPath={props.walletHdPath}
303 walletHdPath={props.walletHdPath}
304 networkType={props.networkType}
304 networkType={props.networkType}
305 setTxnHashCursor={props.setTxnHashCursor}
305 setTxnHashCursor={props.setTxnHashCursor}
306+ setTxnConfirmations={props.setTxnConfirmations}
306 popRoute={props.popRoute}
307 popRoute={props.popRoute}
307 pushRoute={props.pushRoute}
308 pushRoute={props.pushRoute}
308 // Other
309 // Other
src/bridge/views/SentTransaction.js+25−7
@@ -1,3 +1,4 @@
1+import Maybe from 'folktale/maybe'
1import React from 'react'
2import React from 'react'
2import { Row, Col, H1, H3, P, Warning, Anchor } from '../components/Base'
3import { Row, Col, H1, H3, P, Warning, Anchor } from '../components/Base'
3import { Button } from '../components/Base'
4import { Button } from '../components/Base'
@@ -6,14 +7,17 @@ import { ROUTE_NAMES } from '../lib/router'
6import { BRIDGE_ERROR, renderTxnError } from '../lib/error'
7import { BRIDGE_ERROR, renderTxnError } from '../lib/error'
7import { NETWORK_NAMES } from '../lib/network'
8import { NETWORK_NAMES } from '../lib/network'
8
9
10+
9const Success = (props) => {
11const Success = (props) => {
10
12
13+ const { networkType, hash, txnConfirmations } = props
14+
11 const esvisible =
15 const esvisible =
12− props.networkType === NETWORK_NAMES.ROPSTEN ||
16+ networkType === NETWORK_NAMES.ROPSTEN ||
13− props.networkType === NETWORK_NAMES.MAINNET
17+ networkType === NETWORK_NAMES.MAINNET
14
18
15 const esdomain =
19 const esdomain =
16− props.networkType === NETWORK_NAMES.ROPSTEN
20+ networkType === NETWORK_NAMES.ROPSTEN
17 ? "ropsten.etherscan.io"
21 ? "ropsten.etherscan.io"
18 : "etherscan.io"
22 : "etherscan.io"
19
23
@@ -29,10 +33,16 @@ const Success = (props) => {
29 className={'mb-4 mt-1'}
33 className={'mb-4 mt-1'}
30 prop-size={'sm'}
34 prop-size={'sm'}
31 target={'_blank'}
35 target={'_blank'}
32− href={`https://${esdomain}/tx/${props.hash}`}>
36+ href={`https://${esdomain}/tx/${hash}`}>
33 {'View on Etherscan ↗'}
37 {'View on Etherscan ↗'}
34 </Anchor>
38 </Anchor>
35
39
40+ const confirmations = Maybe.fromNullable(txnConfirmations[hash]).getOrElse(0)
41+
42+ const requiredConfirmations = 1
43+
44+ const status = confirmations < requiredConfirmations ? 'Pending...' : `Confirmed x${confirmations}!`
45+
36 return (
46 return (
37 <Row>
47 <Row>
38 <Col>
48 <Col>
@@ -47,10 +57,17 @@ const Success = (props) => {
47
57
48 <H3>{ 'Transaction Hash' }</H3>
58 <H3>{ 'Transaction Hash' }</H3>
49 <P>
59 <P>
50− { props.hash }
60+ { hash }
61+ </P>
62+
63+ <H3>{ 'Transaction Status' }</H3>
64+ <P>
65+ <div>{ status }</div>
66+ <div>{ esanchor }</div>
67+ </P>
68+ <P>
51 </P>
69 </P>
52
70
53− { esanchor }
54
71
55 </Col>
72 </Col>
56 </Row>
73 </Row>
@@ -76,7 +93,7 @@ const Failure = (props) =>
76 </Row>
93 </Row>
77
94
78const SentTransaction = (props) => {
95const SentTransaction = (props) => {
79− const { web3, txnHashCursor, networkType, popRoute, pushRoute } = props
96+ const { web3, txnHashCursor, networkType, popRoute, pushRoute, txnConfirmations} = props
80 const { setPointCursor, pointCursor } = props
97 const { setPointCursor, pointCursor } = props
81
98
82 const promptKeyfile = props.routeData && props.routeData.promptKeyfile
99 const promptKeyfile = props.routeData && props.routeData.promptKeyfile
@@ -97,6 +114,7 @@ const SentTransaction = (props) => {
97 <Success
114 <Success
98 hash={ hash.value }
115 hash={ hash.value }
99 networkType={ networkType }
116 networkType={ networkType }
117+ txnConfirmations={ txnConfirmations }
100 />
118 />
101 })
119 })
102
120
src/bridge/views/SetKeys.js+1
@@ -194,6 +194,7 @@ class SetKeys extends React.Component {
194 walletHdPath={props.walletHdPath}
194 walletHdPath={props.walletHdPath}
195 networkType={props.networkType}
195 networkType={props.networkType}
196 setTxnHashCursor={props.setTxnHashCursor}
196 setTxnHashCursor={props.setTxnHashCursor}
197+ setTxnConfirmations={props.setTxnConfirmations}
197 popRoute={props.popRoute}
198 popRoute={props.popRoute}
198 pushRoute={props.pushRoute}
199 pushRoute={props.pushRoute}
199 // Tx
200 // Tx
src/bridge/views/SetProxy.js+1
@@ -162,6 +162,7 @@ class SetProxy extends React.Component {
162 walletHdPath={props.walletHdPath}
162 walletHdPath={props.walletHdPath}
163 networkType={props.networkType}
163 networkType={props.networkType}
164 setTxnHashCursor={props.setTxnHashCursor}
164 setTxnHashCursor={props.setTxnHashCursor}
165+ setTxnConfirmations={props.setTxnConfirmations}
165 popRoute={props.popRoute}
166 popRoute={props.popRoute}
166 pushRoute={props.pushRoute}
167 pushRoute={props.pushRoute}
167 // Other
168 // Other
src/bridge/views/Transfer.js+1
@@ -132,6 +132,7 @@ class Transfer extends React.Component {
132 walletHdPath={props.walletHdPath}
132 walletHdPath={props.walletHdPath}
133 networkType={props.networkType}
133 networkType={props.networkType}
134 setTxnHashCursor={props.setTxnHashCursor}
134 setTxnHashCursor={props.setTxnHashCursor}
135+ setTxnConfirmations={props.setTxnConfirmations}
135 popRoute={props.popRoute}
136 popRoute={props.popRoute}
136 pushRoute={props.pushRoute}
137 pushRoute={props.pushRoute}
137 // Checks
138 // Checks