1import { Just, Nothing } from 'folktale/maybe'
2import React from 'react'
3import { Row, Col, H1, H3, P, Warning } from '../components/Base'
4import { InnerLabel, AddressInput, ShowBlockie, Anchor } from '../components/Base'
5import * as azimuth from 'azimuth-js'
6import * as ob from 'urbit-ob'
8import StatelessTransaction from '../components/StatelessTransaction'
9import { BRIDGE_ERROR } from '../lib/error'
10import { NETWORK_NAMES } from '../lib/network'
11import { ROUTE_NAMES } from '../lib/router'
14 sendSignedTransaction,
20 addressFromSecp256k1Public,
24class AcceptTransfer extends React.Component {
28 const receivingAddress = props.wallet.matchWith({
29 Just: (wal) => addressFromSecp256k1Public(wal.value.publicKey),
31 throw BRIDGE_ERROR.MISSING_WALLET
35 const incomingPoint = props.pointCursor.matchWith({
36 Just: (shp) => shp.value,
38 throw BRIDGE_ERROR.MISSING_POINT
43 receivingAddress: receivingAddress,
46 incomingPoint: incomingPoint,
54 this.handleAddressInput = this.handleAddressInput.bind(this)
56 this.handleCreateUnsignedTxn = this.handleCreateUnsignedTxn.bind(this)
57 this.handleSubmit = this.handleSubmit.bind(this)
58 this.handleSetUserApproval = this.handleSetUserApproval.bind(this)
59 this.handleSetTxn = this.handleSetTxn.bind(this)
60 this.handleSetStx = this.handleSetStx.bind(this)
61 this.handleSetNonce = this.handleSetNonce.bind(this)
62 this.handleSetChainId = this.handleSetChainId.bind(this)
63 this.handleSetGasPrice = this.handleSetGasPrice.bind(this)
64 this.handleSetGasLimit = this.handleSetGasLimit.bind(this)
68 const { props } = this
70 const addr = props.wallet.matchWith({
71 Just: wal => addressFromSecp256k1Public(wal.value.publicKey),
73 throw BRIDGE_ERROR.MISSING_WALLET
77 props.web3.matchWith({
80 const validWeb3 = w3.value
82 const getTxMetadata = [
83 validWeb3.eth.getTransactionCount(addr),
84 validWeb3.eth.net.getId(),
85 validWeb3.eth.getGasPrice()
88 Promise.all(getTxMetadata).then(r => {
92 gasPrice: fromWei(r[2], 'gwei'),
95 this.setState({...txMetadata})
104 handleAddressInput(proxyAddress) {
105 this.setState({ proxyAddress })
106 this.handleClearTxn()
110 handleCreateUnsignedTxn() {
111 const txn = this.createUnsignedTxn()
112 this.setState({ txn })
116 handleSetUserApproval(){
118 this.setState({ userApproval: !state.userApproval })
124 this.setState({ txn })
138 handleSetNonce(nonce){
139 this.setState({ nonce })
140 this.handleClearStx()
145 handleSetChainId(chainId){
146 this.setState({ chainId })
147 this.handleClearStx()
152 handleSetGasPrice(gasPrice){
153 this.setState({ gasPrice })
154 this.handleClearStx()
159 handleSetGasLimit(gasLimit){
160 this.setState({ gasLimit })
161 this.handleClearStx()
185 handleClearTransaction() {
196 const { props, state } = this
197 sendSignedTransaction(props.web3.value, state.stx)
199 props.setTxnCursor(sent)
201 props.pushRoute(ROUTE_NAMES.SENT_TRANSACTION)
204 this.setState({ txError: err.map(val => val.merge()) })
208 createUnsignedTxn() {
209 const { state, props } = this
211 const validContracts = props.contracts.matchWith({
212 Just: (cs) => cs.value,
214 throw BRIDGE_ERROR.MISSING_CONTRACTS
218 const validPoint = props.pointCursor.matchWith({
219 Just: (shp) => shp.value,
221 throw BRIDGE_ERROR.MISSING_POINT
225 const owner = props.pointCache[validPoint].owner
227 return Just(azimuth.ecliptic.transferFrom(
230 state.receivingAddress,
237 const { state, props } = this
238 const validAddress = isValidAddress(state.receivingAddress)
239 const canGenerate = validAddress === true
240 const canSign = Just.hasInstance(state.txn)
241 const canApprove = Just.hasInstance(state.stx)
243 Just.hasInstance(state.stx)
244 && state.userApproval === true
247 props.networkType === NETWORK_NAMES.ROPSTEN ||
248 props.networkType === NETWORK_NAMES.MAINNET
251 props.networkType === NETWORK_NAMES.ROPSTEN
252 ? "ropsten.etherscan.io"
259 { 'Accept Transfer of '} <code>{ ` ${ob.patp(state.incomingPoint)} ` }</code>
264 "By default, the recipient is the address you're logged in " +
265 "as. But you can transfer to any address you like."
269 className='mono mt-8'
271 prop-format='innerLabel'
272 value={ state.receivingAddress }
273 onChange={ v => this.handleAddressInput(v) }>
274 <InnerLabel>{ 'Receiving Address' }</InnerLabel>
275 <ShowBlockie className={'mt-1'} address={state.receivingAddress} />
279 className={'mt-1 sm'}
281 prop-disabled={!isValidAddress(state.receivingAddress) || !esvisible}
283 href={`https://${esdomain}/address/${state.receivingAddress}`}>
284 {'View on Etherscan ↗'}
287 <StatelessTransaction
290 contracts={props.contracts}
291 wallet={props.wallet}
292 walletType={props.walletType}
293 walletHdPath={props.walletHdPath}
294 networkType={props.networkType}
300 gasPrice={state.gasPrice}
301 chainId={state.chainId}
302 gasLimit={state.gasLimit}
304 userApproval={state.userApproval}
305 canGenerate={ canGenerate }
307 canApprove={ canApprove }
310 createUnsignedTxn={this.handleCreateUnsignedTxn}
311 setUserApproval={this.handleSetUserApproval}
312 setTxn={this.handleSetTxn}
313 setStx={this.handleSetStx}
314 setNonce={this.handleSetNonce}
315 setChainId={this.handleSetChainId}
316 setGasPrice={this.handleSetGasPrice}
317 setGasLimit={this.handleSetGasLimit}
318 handleSubmit={this.handleSubmit} />
321 Nothing.hasInstance(state.txError)
323 : <Warning className={'mt-8'}>
324 <H3 style={{marginTop: 0, paddingTop: 0}}>
326 'There was an error sending your transaction.'
329 { state.txError.value }
338export default AcceptTransfer
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list