mirror of
https://github.com/fullstack-cash/fullstack-gatsby-theme-bch-wallet.git
synced 2026-09-22 09:12:06 -07:00
Merge pull request #36 from Permissionless-Software-Foundation/dh-back-ends
feat(backends): Started the implementation of select multiple backends
This commit is contained in:
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types'
|
||||
import { Content, Row, Col, Box, Inputs, Button } from 'adminlte-2-react'
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||
import BchWallet from 'minimal-slp-wallet'
|
||||
|
||||
import Servers from './servers'
|
||||
const { Text } = Inputs
|
||||
|
||||
let _this
|
||||
@@ -104,6 +104,11 @@ class Configure extends React.Component {
|
||||
</Box>
|
||||
</Col>
|
||||
</Row>
|
||||
<Servers
|
||||
setWalletInfo={_this.props.setWalletInfo}
|
||||
walletInfo={_this.props.walletInfo}
|
||||
setBchWallet={_this.props.setBchWallet}
|
||||
/>
|
||||
</Content>
|
||||
)
|
||||
}
|
||||
@@ -130,13 +135,19 @@ class Configure extends React.Component {
|
||||
|
||||
async handleUpdateJWT () {
|
||||
try {
|
||||
const { mnemonic } = _this.props.walletInfo
|
||||
const { mnemonic, selectedServer } = _this.props.walletInfo
|
||||
const apiToken = _this.state.JWT
|
||||
|
||||
// Update instance with JWT
|
||||
if (mnemonic && apiToken) {
|
||||
const bchjsOptions = { apiToken: apiToken }
|
||||
if (selectedServer) {
|
||||
bchjsOptions.restURL = selectedServer
|
||||
}
|
||||
|
||||
console.log('bchjs options : ', bchjsOptions)
|
||||
const bchWalletLib = new _this.BchWallet(mnemonic)
|
||||
bchWalletLib.bchjs = new bchWalletLib.BCHJS({ apiToken: apiToken })
|
||||
bchWalletLib.bchjs = new bchWalletLib.BCHJS(bchjsOptions)
|
||||
_this.props.setBchWallet(bchWalletLib)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,271 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { Row, Col, Box, Inputs, Button } from 'adminlte-2-react'
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||
import BchWallet from 'minimal-slp-wallet'
|
||||
|
||||
const { Text, Select } = Inputs
|
||||
|
||||
let _this
|
||||
class Servers extends React.Component {
|
||||
constructor (props) {
|
||||
super(props)
|
||||
|
||||
_this = this
|
||||
|
||||
this.state = {
|
||||
selectOptions: [],
|
||||
errMsg: '',
|
||||
selectedServer: '',
|
||||
showAddField: false,
|
||||
newServer: ''
|
||||
}
|
||||
_this.BchWallet = BchWallet
|
||||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
<Row>
|
||||
<Col sm={12}>
|
||||
<Box className='hover-shadow border-none mt-2'>
|
||||
<Row>
|
||||
<Col sm={12} className='text-center'>
|
||||
<h1>
|
||||
<FontAwesomeIcon
|
||||
className='title-icon'
|
||||
size='xs'
|
||||
icon='server'
|
||||
/>
|
||||
<span>Back End Server</span>
|
||||
</h1>
|
||||
<Box className='border-none'>
|
||||
<Row>
|
||||
<Col xs={12}>
|
||||
{_this.state.showAddField ? (
|
||||
<Text
|
||||
id='newServer'
|
||||
name='newServer'
|
||||
placeholder='Add New Server url'
|
||||
label='Add New Server Url'
|
||||
labelPosition='above'
|
||||
onChange={_this.handleUpdate}
|
||||
value={_this.state.newServer}
|
||||
buttonRight={
|
||||
<Button
|
||||
text={_this.state.newServer ? ' ADD ' : 'CLOSE'}
|
||||
type='primary'
|
||||
onClick={_this.handleNewServerUrl}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
<Select
|
||||
name='selectedServer'
|
||||
label='Select Server Url'
|
||||
labelPosition='above'
|
||||
options={_this.state.selectOptions}
|
||||
value={_this.state.selectedServer}
|
||||
onChange={_this.handleUpdate}
|
||||
buttonRight={
|
||||
<Button
|
||||
icon='fa-plus'
|
||||
onClick={_this.handleTextField}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</Col>
|
||||
<Col sm={12} />
|
||||
</Row>
|
||||
|
||||
<Button
|
||||
text='Update'
|
||||
type='primary'
|
||||
className='btn-lg'
|
||||
onClick={_this.handleUpdateServer}
|
||||
/>
|
||||
</Box>
|
||||
</Col>
|
||||
<Col sm={12} className='text-center'>
|
||||
{_this.state.errMsg && (
|
||||
<p className='error-color'>{_this.state.errMsg}</p>
|
||||
)}
|
||||
</Col>
|
||||
</Row>
|
||||
</Box>
|
||||
</Col>
|
||||
</Row>
|
||||
)
|
||||
}
|
||||
|
||||
// turn on / off text field
|
||||
handleTextField () {
|
||||
_this.setState({
|
||||
showAddField: !_this.state.showAddField
|
||||
})
|
||||
}
|
||||
|
||||
// Add the new server value to the select field
|
||||
handleNewServerUrl () {
|
||||
_this.setState({
|
||||
errMsg: ''
|
||||
})
|
||||
const { newServer, selectOptions } = _this.state
|
||||
try {
|
||||
if (newServer) {
|
||||
if (newServer.match(' ')) {
|
||||
throw new Error('backend url must have no spaces')
|
||||
}
|
||||
|
||||
const alreadyExist = selectOptions.find(val => {
|
||||
return val.value === newServer
|
||||
})
|
||||
|
||||
// Prevent duplicate options
|
||||
if (alreadyExist) {
|
||||
_this.setState({
|
||||
showAddField: false,
|
||||
selectedServer: newServer
|
||||
})
|
||||
_this.resetForm()
|
||||
|
||||
return
|
||||
}
|
||||
const option = {
|
||||
value: newServer,
|
||||
text: newServer
|
||||
}
|
||||
|
||||
// add the new select option
|
||||
selectOptions.push(option)
|
||||
}
|
||||
|
||||
_this.setState({
|
||||
selectOptions,
|
||||
showAddField: false,
|
||||
selectedServer: newServer || _this.state.selectedServer
|
||||
})
|
||||
_this.resetForm()
|
||||
} catch (error) {
|
||||
_this.setState({
|
||||
errMsg: error.message
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// populate select field with select options from localstorage
|
||||
populateSelect () {
|
||||
try {
|
||||
const walletInfo = _this.props.walletInfo
|
||||
|
||||
const selectOptions = []
|
||||
|
||||
// populate select field with data from localstorage
|
||||
for (let i = 0; i < walletInfo.servers.length; i++) {
|
||||
const option = {
|
||||
value: walletInfo.servers[i],
|
||||
text: walletInfo.servers[i]
|
||||
}
|
||||
selectOptions.push(option)
|
||||
}
|
||||
_this.setState({
|
||||
selectOptions,
|
||||
selectedServer: walletInfo.selectedServer
|
||||
})
|
||||
} catch (error) {
|
||||
console.warn(error)
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
_this.populateSelect()
|
||||
}
|
||||
|
||||
handleUpdate (event) {
|
||||
const value = event.target.value
|
||||
_this.setState({
|
||||
[event.target.name]: value
|
||||
})
|
||||
}
|
||||
|
||||
handleUpdateServer () {
|
||||
_this.handleNewServerUrl()
|
||||
// await for state update delay
|
||||
setTimeout(() => {
|
||||
_this.updateWalletInstance()
|
||||
}, 500)
|
||||
}
|
||||
|
||||
// Update the wallet instance state
|
||||
updateWalletInstance () {
|
||||
try {
|
||||
const { mnemonic, JWT } = _this.props.walletInfo
|
||||
const apiToken = JWT
|
||||
const restURL = _this.state.selectedServer
|
||||
|
||||
// Update instance with the selected url
|
||||
if (mnemonic) {
|
||||
const bchjsOptions = {}
|
||||
if (apiToken) {
|
||||
bchjsOptions.apiToken = apiToken
|
||||
}
|
||||
|
||||
bchjsOptions.restURL = restURL
|
||||
|
||||
console.log('bchjs options : ', bchjsOptions)
|
||||
const bchWalletLib = new _this.BchWallet(mnemonic)
|
||||
bchWalletLib.bchjs = new bchWalletLib.BCHJS(bchjsOptions)
|
||||
_this.props.setBchWallet(bchWalletLib)
|
||||
}
|
||||
_this.saveServer()
|
||||
} catch (error) {
|
||||
console.warn(error)
|
||||
_this.setState({
|
||||
errMsg: error.message
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// store servers in the localstorage
|
||||
saveServer () {
|
||||
try {
|
||||
// store the new server in the localstorage if it does not exist
|
||||
|
||||
const walletInfo = _this.props.walletInfo
|
||||
const { servers } = walletInfo
|
||||
|
||||
const selectedValue = _this.state.selectedServer
|
||||
if (!selectedValue) {
|
||||
return
|
||||
}
|
||||
|
||||
const alreadyExist = servers.find(val => {
|
||||
return val === selectedValue
|
||||
})
|
||||
// Prevent duplicate values
|
||||
if (!alreadyExist) {
|
||||
servers.push(selectedValue)
|
||||
}
|
||||
|
||||
walletInfo.servers = servers
|
||||
walletInfo.selectedServer = selectedValue
|
||||
_this.props.setWalletInfo(walletInfo)
|
||||
} catch (error) {
|
||||
console.warn(error)
|
||||
}
|
||||
}
|
||||
|
||||
// clean the text form field
|
||||
resetForm () {
|
||||
_this.setState({
|
||||
newServer: ''
|
||||
})
|
||||
}
|
||||
}
|
||||
Servers.propTypes = {
|
||||
setWalletInfo: PropTypes.func.isRequired,
|
||||
walletInfo: PropTypes.object.isRequired,
|
||||
setBchWallet: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
export default Servers
|
||||
@@ -4,7 +4,6 @@ import Configure from './configure'
|
||||
import Tokens from './tokens'
|
||||
import Wallet from './wallet'
|
||||
import siteConfig from '../site-config'
|
||||
|
||||
// import Audit from "./audit"
|
||||
|
||||
import AdminLTE, { Sidebar, Navbar } from 'adminlte-2-react'
|
||||
@@ -52,7 +51,11 @@ class AdminLTEPage extends React.Component {
|
||||
render () {
|
||||
return (
|
||||
<>
|
||||
<AdminLTE title={[siteConfig.title]} titleShort={[siteConfig.titleShort]} theme='blue'>
|
||||
<AdminLTE
|
||||
title={[siteConfig.title]}
|
||||
titleShort={[siteConfig.titleShort]}
|
||||
theme='blue'
|
||||
>
|
||||
<Sidebar.Core>
|
||||
<Item key='Balance' text='Balance' icon={siteConfig.balanceIcon}>
|
||||
<div className='sidebar-balance'>
|
||||
@@ -146,6 +149,8 @@ class AdminLTEPage extends React.Component {
|
||||
|
||||
_this.activeItemById('Wallet')
|
||||
|
||||
_this.setDefaultServers()
|
||||
|
||||
await _this.updateState()
|
||||
setTimeout(() => {
|
||||
_this.dropDownBalance()
|
||||
@@ -306,6 +311,37 @@ class AdminLTEPage extends React.Component {
|
||||
</li>
|
||||
)
|
||||
}
|
||||
|
||||
// Define backends servers configuration by default
|
||||
setDefaultServers () {
|
||||
try {
|
||||
const walletInfo = _this.props.walletInfo
|
||||
const accessLocation = window.location.hostname
|
||||
console.log('accessLocation', accessLocation)
|
||||
|
||||
// return if servers configurations exist
|
||||
if (walletInfo.selectedServer) return null
|
||||
|
||||
const server1 = 'https://api.fullstack.cash/v3/'
|
||||
const server2 = 'https://free-api.fullstack.cash/v3/'
|
||||
|
||||
const servers = [server1, server2]
|
||||
|
||||
let selectedServer = server1
|
||||
// Assign the second server if the url path
|
||||
// is different of 'wallet.fullstack.cash'
|
||||
if (accessLocation !== 'wallet.fullstack.cash') {
|
||||
selectedServer = server2
|
||||
}
|
||||
|
||||
walletInfo.selectedServer = selectedServer
|
||||
walletInfo.servers = servers
|
||||
|
||||
_this.props.setWalletInfo(walletInfo)
|
||||
} catch (error) {
|
||||
console.warn(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Props prvided by redux
|
||||
AdminLTEPage.propTypes = {
|
||||
|
||||
@@ -9,7 +9,9 @@ class NewWallet extends React.Component {
|
||||
constructor (props) {
|
||||
super(props)
|
||||
_this = this
|
||||
this.state = {}
|
||||
this.state = {
|
||||
inFetch: false
|
||||
}
|
||||
|
||||
_this.BchWallet = BchWallet
|
||||
}
|
||||
@@ -20,7 +22,10 @@ class NewWallet extends React.Component {
|
||||
<Row>
|
||||
<Col sm={2} />
|
||||
<Col sm={8}>
|
||||
<Box className='hover-shadow border-none mt-2'>
|
||||
<Box
|
||||
className='hover-shadow border-none mt-2'
|
||||
loaded={!_this.state.inFetch}
|
||||
>
|
||||
<Row>
|
||||
<Col sm={12} className='text-center'>
|
||||
<h1>
|
||||
@@ -60,12 +65,23 @@ class NewWallet extends React.Component {
|
||||
* it will get overwritten
|
||||
*/
|
||||
}
|
||||
|
||||
_this.setState({
|
||||
inFetch: true
|
||||
})
|
||||
const bchWalletLib = new _this.BchWallet()
|
||||
const apiToken = currentWallet.JWT
|
||||
const restURL = currentWallet.selectedServer
|
||||
|
||||
if (apiToken) {
|
||||
bchWalletLib.bchjs = new bchWalletLib.BCHJS({ apiToken: apiToken })
|
||||
if (apiToken || restURL) {
|
||||
const bchjsOptions = {}
|
||||
if (apiToken) {
|
||||
bchjsOptions.apiToken = apiToken
|
||||
}
|
||||
if (restURL) {
|
||||
bchjsOptions.restURL = restURL
|
||||
}
|
||||
console.log('bchjs options : ', bchjsOptions)
|
||||
bchWalletLib.bchjs = new bchWalletLib.BCHJS(bchjsOptions)
|
||||
}
|
||||
|
||||
await bchWalletLib.walletInfoPromise // Wait for wallet to be created.
|
||||
@@ -73,14 +89,23 @@ class NewWallet extends React.Component {
|
||||
const walletInfo = bchWalletLib.walletInfo
|
||||
walletInfo.from = 'created'
|
||||
|
||||
Object.assign(currentWallet, walletInfo)
|
||||
|
||||
const myBalance = await bchWalletLib.getBalance()
|
||||
|
||||
// Update redux state
|
||||
_this.props.setWalletInfo(walletInfo)
|
||||
_this.props.setWalletInfo(currentWallet)
|
||||
_this.props.updateBalance(myBalance)
|
||||
_this.props.setBchWallet(bchWalletLib)
|
||||
|
||||
_this.setState({
|
||||
inFetch: false
|
||||
})
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
_this.setState({
|
||||
inFetch: false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,9 @@ class ImportWallet extends React.Component {
|
||||
this.state = {
|
||||
mnemonic: '',
|
||||
privateKey: '',
|
||||
errMsg: ''
|
||||
errMsg: '',
|
||||
inFetch: false
|
||||
|
||||
}
|
||||
_this.BchWallet = BchWallet
|
||||
}
|
||||
@@ -26,7 +28,10 @@ class ImportWallet extends React.Component {
|
||||
<Row className=''>
|
||||
<Col sm={2} />
|
||||
<Col sm={8}>
|
||||
<Box className='hover-shadow border-none mt-2'>
|
||||
<Box
|
||||
className='hover-shadow border-none mt-2'
|
||||
loaded={!_this.state.inFetch}
|
||||
>
|
||||
<Row>
|
||||
<Col sm={12} className='text-center'>
|
||||
<h1>
|
||||
@@ -112,32 +117,49 @@ class ImportWallet extends React.Component {
|
||||
* and it will get overwritten
|
||||
*/
|
||||
}
|
||||
_this.setState({
|
||||
inFetch: true
|
||||
})
|
||||
|
||||
const bchWalletLib = new _this.BchWallet(_this.state.mnemonic)
|
||||
const apiToken = currentWallet.JWT
|
||||
const restURL = currentWallet.selectedServer
|
||||
|
||||
if (apiToken) {
|
||||
bchWalletLib.bchjs = new bchWalletLib.BCHJS({ apiToken: apiToken })
|
||||
if (apiToken || restURL) {
|
||||
const bchjsOptions = {}
|
||||
if (apiToken) {
|
||||
bchjsOptions.apiToken = apiToken
|
||||
}
|
||||
if (restURL) {
|
||||
bchjsOptions.restURL = restURL
|
||||
}
|
||||
console.log('bchjs options : ', bchjsOptions)
|
||||
bchWalletLib.bchjs = new bchWalletLib.BCHJS(bchjsOptions)
|
||||
}
|
||||
|
||||
await bchWalletLib.walletInfoPromise // Wait for wallet to be created.
|
||||
|
||||
const walletInfo = bchWalletLib.walletInfo
|
||||
walletInfo.from = 'imported'
|
||||
|
||||
Object.assign(currentWallet, walletInfo)
|
||||
|
||||
const myBalance = await bchWalletLib.getBalance()
|
||||
|
||||
// Update redux state
|
||||
_this.props.setWalletInfo(walletInfo)
|
||||
_this.props.setWalletInfo(currentWallet)
|
||||
_this.props.updateBalance(myBalance)
|
||||
_this.props.setBchWallet(bchWalletLib)
|
||||
|
||||
// Reset form and component state
|
||||
_this.resetValues()
|
||||
_this.setState({
|
||||
inFetch: false
|
||||
})
|
||||
} catch (error) {
|
||||
console.warn(error)
|
||||
_this.setState({
|
||||
errMsg: error.message
|
||||
errMsg: error.message,
|
||||
inFetch: false
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,28 +41,37 @@ const reducer = (state, action) => {
|
||||
}
|
||||
|
||||
// Wallet info from local storage
|
||||
const localWallet = getWalletInfo()
|
||||
const localStorageInfo = getWalletInfo()
|
||||
|
||||
// Creates an instance of minimal-slp-wallet, with
|
||||
// the local storage information if it exists
|
||||
const instanceWallet = () => {
|
||||
try {
|
||||
if (!localWallet.mnemonic) return null
|
||||
if (!localStorageInfo.mnemonic) return null
|
||||
|
||||
const bchWalletLib = new BchWallet(localWallet.mnemonic)
|
||||
const bchWalletLib = new BchWallet(localStorageInfo.mnemonic)
|
||||
|
||||
const jwtToken = localStorageInfo.JWT
|
||||
const restURL = localStorageInfo.selectedServer
|
||||
const bchjsOptions = {}
|
||||
|
||||
const jwtToken = localWallet.JWT
|
||||
if (jwtToken) {
|
||||
bchWalletLib.bchjs = new bchWalletLib.BCHJS({ apiToken: jwtToken })
|
||||
bchjsOptions.apiToken = jwtToken
|
||||
}
|
||||
if (restURL) {
|
||||
bchjsOptions.restURL = restURL
|
||||
}
|
||||
bchWalletLib.bchjs = new bchWalletLib.BCHJS(bchjsOptions)
|
||||
|
||||
return bchWalletLib
|
||||
} catch (error) {
|
||||
console.warn(error)
|
||||
}
|
||||
}
|
||||
|
||||
// initial state
|
||||
const initialState = {
|
||||
walletInfo: localWallet.mnemonic ? localWallet : {}, // Object wallet info
|
||||
walletInfo: localStorageInfo, // Object wallet info
|
||||
bchBalance: 0, // Wallet Balance
|
||||
bchWallet: instanceWallet() // minimal-slp-wallet instance
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user