on 5fa3fd0 help sign in
bridge/src/components/StatelessTransaction.js
199 lines 4.7 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 // TODO: Investigate
19 // setState doesn't seem to work in SetProxy/handleSubmit;
20 // - TypeError: Cannot read property 'updater' of undefined
21 // so just modifying the DOM manually here. (https://imgur.com/a/i0Qsyq1)
23 const sendTxn = (e) => {
24 e.target.setAttribute("disabled", true);
25 let spinner = e.target.querySelectorAll('.btn-spinner')[0];
26 spinner.classList.remove('hide');
27 handleSubmit()
28 }
30 const generateButtonColor =
31 Nothing.hasInstance(txn)
32 ? 'blue'
33 : 'green'
35 const signerButtonColor =
36 Nothing.hasInstance(stx)
37 ? 'blue'
38 : 'green'
40 const generateTxnButton =
41 <Button
42 className={ 'mt-8' }
43 disabled={ !canGenerate }
44 prop-color={ generateButtonColor }
45 prop-size={ 'lg wide' }
46 onClick={ createUnsignedTxn }
47 >
48 { 'Generate Transaction' }
49 </Button>
51 const unsignedTxnDisplay = txn.matchWith({
52 Nothing: _ => '',
53 Just: tx =>
54 <React.Fragment>
55 <H3 className={ 'mt-8' }>
56 { 'Unsigned Transaction' }
57 </H3>
58 <Code>
59 { JSON.stringify(tx.value, null, 2) }
60 </Code>
61 </React.Fragment>
62 })
64 const gasPriceDialogue =
65 <Input
66 className={ 'mono mt-4' }
67 prop-size={ 'md' }
68 prop-format={ 'innerLabel' }
69 value={ gasPrice }
70 onChange={ setGasPrice }
71 >
72 <InnerLabel>
73 { 'Gas Price (gwei)' }
74 </InnerLabel>
75 </Input>
77 const gasLimitDialogue =
78 <Input
79 className={ 'mono mt-4' }
80 prop-size={ 'md' }
81 prop-format={ 'innerLabel' }
82 value={ gasLimit }
83 onChange={ setGasLimit }>
84 <InnerLabel>
85 { 'Gas Limit' }
86 </InnerLabel>
87 </Input>
89 const nonceDialogue =
90 <Input
91 className={ 'mono mt-4' }
92 prop-size={ 'md' }
93 prop-format={ 'innerLabel' }
94 value={ nonce }
95 onChange={ setNonce }
96 >
97 <InnerLabel>
98 { 'Nonce' }
99 </InnerLabel>
100 </Input>
102 const chainDialogue =
103 <Input
104 className={ 'mono mt-4 mb-8' }
105 prop-size={ 'md' }
106 prop-format={ 'innerLabel' }
107 value={ chainId }
108 onChange={ setChainId }
109 >
110 <InnerLabel>
111 { 'Chain ID' }
112 </InnerLabel>
113 </Input>
115 const onlineParamsDialogue = web3.matchWith({
116 Just: _ => <div />,
117 Nothing: _ =>
118 <React.Fragment>
119 { nonceDialogue }
120 { chainDialogue }
121 </React.Fragment>
122 })
124 const signTxnButton =
125 <Button
126 disabled={ !canSign }
127 className={ 'mt-8' }
128 prop-size={ 'lg wide' }
129 prop-color={ signerButtonColor }
130 onClick={ () => signTransaction(props) }
131 >
132 { 'Sign Transaction' }
133 </Button>
135 const signedTxnDisplay = stx.matchWith({
136 Nothing: _ => '',
137 Just: tx =>
138 <React.Fragment>
139 <H3 className={ 'mt-8' }>
140 { 'Signed Transaction' }
141 </H3>
142 <Code>
143 { JSON.stringify(renderSignedTx(tx.value), null, 2) }
144 </Code>
145 </React.Fragment>
146 })
148 const confirmButton =
149 <CheckboxButton
150 className={ 'mt-8' }
151 disabled={ !canApprove }
152 onClick={ setUserApproval }
153 state={ userApproval }
154 >
155 <div>
156 { `I approve this transaction and wish to send.` }
157 </div>
158 </CheckboxButton>
160 const sendTxnButton =
161 <Button
162 prop-size={ 'xl wide' }
163 className={ 'mt-8' }
164 disabled={ !canSend }
165 onClick={ sendTxn }
166 >
167 <span className="relative">
168 <span className="btn-spinner hide"></span>
169 { 'Send Transaction' }
170 </span>
171 </Button>
173 const sendDialogue = web3.matchWith({
174 Nothing: _ => '',
175 Just: _ =>
176 <React.Fragment>
177 { confirmButton }
178 { sendTxnButton }
179 </React.Fragment>
180 })
182 return (
183 <React.Fragment>
184 { generateTxnButton }
185 { unsignedTxnDisplay }
187 { gasPriceDialogue }
188 { gasLimitDialogue }
189 { onlineParamsDialogue }
191 { signTxnButton }
193 { signedTxnDisplay }
194 { sendDialogue }
195 </React.Fragment>
196 )
199export default StatelessTransaction