on d6291a2 help sign in
bridge/src/components/Transaction.js
191 lines 5.3 kB history raw
1import Maybe from 'folktale/maybe'
2import Result from 'folktale/result'
3import React from 'react'
4import { Row, Col, Code, H3 } from './Base'
5import { Button } from './Base'
6import { CheckboxButton } from './Base'
8import Signer from './Transaction/Signer'
9import { ROUTE_NAMES } from '../lib/router'
10import { renderTxnPurpose } from '../lib/txn'
11import { addHexPrefix } from '../lib/wallet'
12import { BRIDGE_ERROR } from '../lib/error'
14const hexify = val =>
15 addHexPrefix(val.toString('hex'))
17const renderSignedTx = stx => ({
18 messageHash: hexify(stx.hash()),
19 v: hexify(stx.v),
20 s: hexify(stx.s),
21 r: hexify(stx.r),
22 rawTransaction: hexify(stx.serialize())
23})
25class Transaction extends React.Component {
26 constructor(props) {
27 super(props)
29 this.state = {
30 purposeConfirmed: false,
31 looksGood: false,
32 isSigned: false,
33 txn: Maybe.Nothing(),
34 stx: Maybe.Nothing()
35 }
37 this.handlePurposeConfirmation = this.handlePurposeConfirmation.bind(this)
38 this.handleLooksGood = this.handleLooksGood.bind(this)
39 this.setSignedTransaction = this.setSignedTransaction.bind(this)
40 this.sendSignedTransaction = this.sendSignedTransaction.bind(this)
41 }
43 // createUnsignedTxn() {
44 // const { props, state } = this
45 // const txn = props.createUnsignedTxn()
46 // this.setState({ txn })
47 // }
49 setSignedTransaction(stx) {
51 this.setState({
52 isSigned: true,
53 stx: Maybe.Just(stx)
54 })
55 }
57 handlePurposeConfirmation() {
58 this.setState({ purposeConfirmed: !this.state.purposeConfirmed })
59 }
61 handleLooksGood() {
62 this.setState({ looksGood: !this.state.looksGood })
63 }
65 async sendSignedTransaction(web3, stx) {
66 const txn = stx.matchWith({
67 Just: (tx) => tx.value,
68 Nothing: () => {
69 throw BRIDGE_ERROR.MISSING_TXN
70 }
71 })
73 const serializedTx = addHexPrefix(txn.serialize().toString('hex'))
75 return new Promise((resolve, _) => {
76 web3.eth.sendSignedTransaction(serializedTx)
77 .on('receipt', txn =>
78 resolve(Maybe.Just(Result.Ok(txn)))
79 )
80 .on('error', err => {
81 resolve(Maybe.Just(Result.Error(err.message)))
82 })
83 })
84 }
86 render() {
87 const { state, props } = this
89 const { web3, wallet, walletType, purpose, setTxnCursor } = this.props
90 const { pushRoute, popRoute } = this.props
91 const { className } = this.props
92 const { purposeConfirmed, looksGood, stx, isSigned, txn } = this.state
94 return (
95 <Row className={`${className}`}>
96 <Col>
99 <Button
100 prop-size={'lg wide'}
101 className={'mt-8'}
102 disabled={ props.disabled }
103 onClick={ () => this.createUnsignedTxn()}
104 >
105 { 'Generate Transaction' }
106 </Button>
108 {
109 // <CheckboxButton
110 // className={'mt-8'}
111 // disabled={ Maybe.Nothing.hasInstance(txn) }
112 // onClick={ this.handlePurposeConfirmation }
113 // state={purposeConfirmed}>
114 // <div>
115 // { `Yes, I am sure I want to ${renderTxnPurpose(purpose)}.` }
116 // </div>
117 // </CheckboxButton>
118 }
121 <Signer
122 className={'mt-8'}
123 web3={ web3 }
124 wallet={ wallet }
125 walletType={ walletType }
126 txn={ txn }
127 setSignedTransaction={ this.setSignedTransaction }
128 disabled={ Maybe.Nothing.hasInstance(txn) } />
132 { stx.matchWith({
133 Nothing: () => '',
134 Just: (tx) => {
135 const rendered = renderSignedTx(tx.value)
136 return (
137 <div>
138 <H3 className={'mt-8'}>{'Signed Transaction'}</H3>
139 <Code> {JSON.stringify(rendered, null, 2)} </Code>
140 </div>
141 )
142 }
143 }) }
145 {
146 web3.matchWith({
147 Nothing: () => <div />,
148 Just: () =>
149 <CheckboxButton
150 className={'mt-8 mb-4'}
151 disabled={ !(!Maybe.Nothing.hasInstance(stx) && isSigned && purposeConfirmed)}
152 onClick={ this.handleLooksGood }
153 state={looksGood}>
154 <div>
155 { `I approve this transaction and wish to send.` }
156 </div>
157 </CheckboxButton>
158 })
159 }
163 { web3.matchWith({
164 Nothing: _ => <div />,
165 Just: w3 =>
166 <Button
167 prop-size={'xl wide'}
168 className={'mt-8'}
169 disabled={ !looksGood }
170 onClick={ () => {
171 this.sendSignedTransaction(w3.value, stx)
172 .then(sent => {
173 setTxnCursor(sent)
174 popRoute()
175 pushRoute(ROUTE_NAMES.SENT_TRANSACTION)
176 })
177 }}
178 >
179 { 'Send Transaction' }
180 </Button>
181 })
182 }
183 </Col>
184 </Row>
185 )
186 }
191export default Transaction