on 2ee2847 help sign in
bridge/src/components/StatelessTransaction.js
197 lines 4.6 kB history raw
1import { Nothing } from 'folktale/maybe'
2import React from 'react'
4import { Code, H3 } from './Base'
5import { Button } from './Base'
6import { CheckboxButton, Input, InnerLabel } from './Base'
8import { renderSignedTx, signTransaction } from '../lib/txn'
10const StatelessTransaction = props => {
11 const { web3, gasPrice, gasLimit, nonce, chainId } = props
12 const { setNonce, setChainId, setGasLimit, setGasPrice } = props
13 const { txn, stx, createUnsignedTxn } = props
14 const { canSign, canGenerate, canApprove } = props
15 const { setUserApproval, userApproval } = props
16 const { canSend, handleSubmit } = props
18 // setState doesn't seem to work in SetProxy/handleSubmit, so just
19 // modifying the DOM manually here. (https://imgur.com/a/i0Qsyq1)
21 const sendTxn = (e) => {
22 e.target.setAttribute("disabled", true);
23 let spinner = e.target.querySelectorAll('.btn-spinner')[0];
24 spinner.classList.remove('hide');
25 handleSubmit()
26 }
28 const generateButtonColor =
29 Nothing.hasInstance(txn)
30 ? 'blue'
31 : 'green'
33 const signerButtonColor =
34 Nothing.hasInstance(stx)
35 ? 'blue'
36 : 'green'
38 const generateTxnButton =
39 <Button
40 className={ 'mt-8' }
41 disabled={ !canGenerate }
42 prop-color={ generateButtonColor }
43 prop-size={ 'lg wide' }
44 onClick={ createUnsignedTxn }
45 >
46 { 'Generate Transaction' }
47 </Button>
49 const unsignedTxnDisplay = txn.matchWith({
50 Nothing: _ => '',
51 Just: tx =>
52 <React.Fragment>
53 <H3 className={ 'mt-8' }>
54 { 'Unsigned Transaction' }
55 </H3>
56 <Code>
57 { JSON.stringify(tx.value, null, 2) }
58 </Code>
59 </React.Fragment>
60 })
62 const gasPriceDialogue =
63 <Input
64 className={ 'mono mt-4' }
65 prop-size={ 'md' }
66 prop-format={ 'innerLabel' }
67 value={ gasPrice }
68 onChange={ setGasPrice }
69 >
70 <InnerLabel>
71 { 'Gas Price (gwei)' }
72 </InnerLabel>
73 </Input>
75 const gasLimitDialogue =
76 <Input
77 className={ 'mono mt-4' }
78 prop-size={ 'md' }
79 prop-format={ 'innerLabel' }
80 value={ gasLimit }
81 onChange={ setGasLimit }>
82 <InnerLabel>
83 { 'Gas Limit' }
84 </InnerLabel>
85 </Input>
87 const nonceDialogue =
88 <Input
89 className={ 'mono mt-4' }
90 prop-size={ 'md' }
91 prop-format={ 'innerLabel' }
92 value={ nonce }
93 onChange={ setNonce }
94 >
95 <InnerLabel>
96 { 'Nonce' }
97 </InnerLabel>
98 </Input>
100 const chainDialogue =
101 <Input
102 className={ 'mono mt-4 mb-8' }
103 prop-size={ 'md' }
104 prop-format={ 'innerLabel' }
105 value={ chainId }
106 onChange={ setChainId }
107 >
108 <InnerLabel>
109 { 'Chain ID' }
110 </InnerLabel>
111 </Input>
113 const onlineParamsDialogue = web3.matchWith({
114 Just: _ => <div />,
115 Nothing: _ =>
116 <React.Fragment>
117 { nonceDialogue }
118 { chainDialogue }
119 </React.Fragment>
120 })
122 const signTxnButton =
123 <Button
124 disabled={ !canSign }
125 className={ 'mt-8' }
126 prop-size={ 'lg wide' }
127 prop-color={ signerButtonColor }
128 onClick={ () => signTransaction(props) }
129 >
130 { 'Sign Transaction' }
131 </Button>
133 const signedTxnDisplay = stx.matchWith({
134 Nothing: _ => '',
135 Just: tx =>
136 <React.Fragment>
137 <H3 className={ 'mt-8' }>
138 { 'Signed Transaction' }
139 </H3>
140 <Code>
141 { JSON.stringify(renderSignedTx(tx.value), null, 2) }
142 </Code>
143 </React.Fragment>
144 })
146 const confirmButton =
147 <CheckboxButton
148 className={ 'mt-8' }
149 disabled={ !canApprove }
150 onClick={ setUserApproval }
151 state={ userApproval }
152 >
153 <div>
154 { `I approve this transaction and wish to send.` }
155 </div>
156 </CheckboxButton>
158 const sendTxnButton =
159 <Button
160 prop-size={ 'xl wide' }
161 className={ 'mt-8' }
162 disabled={ !canSend }
163 onClick={ sendTxn }
164 >
165 <span className="relative">
166 <span className="btn-spinner hide"></span>
167 { 'Send Transaction' }
168 </span>
169 </Button>
171 const sendDialogue = web3.matchWith({
172 Nothing: _ => '',
173 Just: _ =>
174 <React.Fragment>
175 { confirmButton }
176 { sendTxnButton }
177 </React.Fragment>
178 })
180 return (
181 <React.Fragment>
182 { generateTxnButton }
183 { unsignedTxnDisplay }
185 { gasPriceDialogue }
186 { gasLimitDialogue }
187 { onlineParamsDialogue }
189 { signTxnButton }
191 { signedTxnDisplay }
192 { sendDialogue }
193 </React.Fragment>
194 )
197export default StatelessTransaction