mirror of
https://github.com/joinmarket-webui/jam.git
synced 2026-08-20 13:28:21 +02:00
Improve current wallet display
This commit is contained in:
parent
eb561570b6
commit
c35926e92e
9 changed files with 217 additions and 216 deletions
|
|
@ -227,55 +227,55 @@ export default function App() {
|
|||
<rb.Navbar.Toggle aria-controls="responsive-rb.Navbar-rb.Nav" className="ms-auto border-0" />
|
||||
<rb.Navbar.Collapse id="responsive-rb.Navbar-rb.Nav">
|
||||
<rb.Nav className="text-start">
|
||||
{currentWallet
|
||||
? <>
|
||||
<Link to="/wallets/current" className="nav-link">Wallet</Link>
|
||||
<Link to="/payment" className="nav-link">Payment</Link>
|
||||
<Link to="/receive" className="nav-link">Receive</Link>
|
||||
<Link to="/maker" className="nav-link">Maker</Link>
|
||||
</>
|
||||
: null}
|
||||
{connection === true
|
||||
? <Link to="/wallets/create" className="nav-link">Create Wallet</Link>
|
||||
: null}
|
||||
{currentWallet &&
|
||||
<>
|
||||
<Link to="/wallets/current" className="nav-link">Wallet</Link>
|
||||
<Link to="/payment" className="nav-link">Payment</Link>
|
||||
<Link to="/receive" className="nav-link">Receive</Link>
|
||||
<Link to="/maker" className="nav-link">Maker</Link>
|
||||
</>}
|
||||
{connection === true &&
|
||||
<Link to="/wallets/create" className="nav-link">Create Wallet</Link>}
|
||||
<Link to="/about" className="nav-link">About</Link>
|
||||
</rb.Nav>
|
||||
</rb.Navbar.Collapse>
|
||||
<div className="justify-content-start justify-content-md-end">
|
||||
<rb.Nav className="flex-row">
|
||||
<Link to="/" className="nav-link">{walletLoadStatus} ({activeWallet || 'None'} active)</Link> }
|
||||
<Link to="/" className="nav-link">{walletLoadStatus} ({activeWallet || 'None'} active)</Link>
|
||||
<rb.Navbar.Text>
|
||||
{connection === true
|
||||
? ` · YG ${makerStarted ? 'on' : 'off'}${coinjoinInProcess ? ', Coinjoining' : ''}`
|
||||
: null}
|
||||
{connection === true &&
|
||||
` · YG ${makerStarted ? 'on' : 'off'}${coinjoinInProcess ? ', Coinjoining' : ''}`}
|
||||
</rb.Navbar.Text>
|
||||
</rb.Nav>
|
||||
</div>
|
||||
</rb.Container>
|
||||
</rb.Navbar>
|
||||
<rb.Container as="main" className="py-4">
|
||||
{connection === false
|
||||
? <rb.Alert variant="danger">No connection to backend server.</rb.Alert>
|
||||
: null }
|
||||
{connection === false &&
|
||||
<rb.Alert variant="danger">No connection to backend server.</rb.Alert>}
|
||||
<Switch>
|
||||
<Route path='/' exact render={props => (
|
||||
<Wallets currentWallet={currentWallet} activeWallet={activeWallet} walletList={walletList} onDisplay={displayWallet} />
|
||||
)} />
|
||||
<Route path='/wallets/current' exact render={props => (
|
||||
<CurrentWallet currentWallet={currentWallet} activeWallet={activeWallet} onSend={makePayment} listUTXOs={getUTXOs} />
|
||||
)} />
|
||||
<Route path='/wallets/create' exact render={props => (
|
||||
<CreateWallet currentWallet={currentWallet} activeWallet={activeWallet} />
|
||||
)} />
|
||||
<Route path='/payment' exact render={props => (
|
||||
<Payment currentWallet={currentWallet} onPayment={makePayment} onCoinjoin={doCoinjoin} />
|
||||
)} />
|
||||
<Route path='/maker' exact render={props => (
|
||||
<Maker onStart={startMakerService} onStop={stopMakerService} />
|
||||
)} />
|
||||
<Route path='/receive' exact render={props => (
|
||||
<Receive />
|
||||
)} />
|
||||
{currentWallet &&
|
||||
<>
|
||||
<Route path='/wallets/current' exact render={props => (
|
||||
<CurrentWallet currentWallet={currentWallet} activeWallet={activeWallet} onSend={makePayment} listUTXOs={getUTXOs} />
|
||||
)} />
|
||||
<Route path='/wallets/create' exact render={props => (
|
||||
<CreateWallet currentWallet={currentWallet} activeWallet={activeWallet} />
|
||||
)} />
|
||||
<Route path='/payment' exact render={props => (
|
||||
<Payment currentWallet={currentWallet} onPayment={makePayment} onCoinjoin={doCoinjoin} />
|
||||
)} />
|
||||
<Route path='/maker' exact render={props => (
|
||||
<Maker onStart={startMakerService} onStop={stopMakerService} />
|
||||
)} />
|
||||
<Route path='/receive' exact render={props => (
|
||||
<Receive />
|
||||
)} />
|
||||
</>
|
||||
}
|
||||
<Route path='/about' exact render={props => (
|
||||
<About />
|
||||
)} />
|
||||
|
|
|
|||
|
|
@ -80,9 +80,7 @@ export default function CreateWallet({ currentWallet, activeWallet }) {
|
|||
return canCreate
|
||||
? <rb.Form onSubmit={onSubmit} validated={validated} noValidate>
|
||||
<h1>Create Wallet</h1>
|
||||
{alert
|
||||
? <rb.Alert variant={alert.variant}>{alert.message}</rb.Alert>
|
||||
: null}
|
||||
{alert && <rb.Alert variant={alert.variant}>{alert.message}</rb.Alert>}
|
||||
<rb.Form.Group className="mb-3" controlId="walletName">
|
||||
<rb.Form.Label>Wallet Name</rb.Form.Label>
|
||||
<rb.Form.Control name="wallet" style={{ maxWidth: '20em' }} required />
|
||||
|
|
|
|||
|
|
@ -1,13 +1,15 @@
|
|||
import React from 'react'
|
||||
import { useState, useEffect } from 'react'
|
||||
import { Button } from './Button'
|
||||
import DisplayMixdepth from './DisplayMixdepth'
|
||||
import * as rb from 'react-bootstrap'
|
||||
import DisplayMixdepths from './DisplayMixdepths'
|
||||
import DisplayUTXOs from './DisplayUTXOs'
|
||||
|
||||
const CurrentWallet = ({ currentWallet, activeWallet, onSend, listUTXOs }) => {
|
||||
const [wallet_info, setWalletInfo] = useState([])
|
||||
const [UTXOHistory, setUTXOHistory] = useState({})
|
||||
export default function CurrentWallet ({ currentWallet, activeWallet, onSend, listUTXOs }) {
|
||||
const [wallet_info, setWalletInfo] = useState(null)
|
||||
const [UTXOHistory, setUTXOHistory] = useState(null)
|
||||
const [showUTXO, setShowUTXO] = useState(false)
|
||||
const [alert, setAlert] = useState(null)
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
|
||||
const listWalletInfo = async () => {
|
||||
const { name, token } = currentWallet
|
||||
|
|
@ -16,26 +18,35 @@ const CurrentWallet = ({ currentWallet, activeWallet, onSend, listUTXOs }) => {
|
|||
return alert(`Please unlock ${name} first`)
|
||||
}
|
||||
|
||||
setAlert(null)
|
||||
setIsLoading(true)
|
||||
try {
|
||||
const res = await fetch(`/api/v1/wallet/${name}/display`, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`
|
||||
}
|
||||
})
|
||||
const { walletinfo } = await res.json()
|
||||
const balance = walletinfo.total_balance
|
||||
const mix_depths = walletinfo.accounts
|
||||
const wallet_info = { balance }
|
||||
wallet_info[mix_depths[0].account] = mix_depths[0].account_balance
|
||||
wallet_info[mix_depths[1].account] = mix_depths[1].account_balance
|
||||
wallet_info[mix_depths[2].account] = mix_depths[2].account_balance
|
||||
wallet_info[mix_depths[3].account] = mix_depths[3].account_balance
|
||||
wallet_info[mix_depths[4].account] = mix_depths[4].account_balance
|
||||
|
||||
return [walletinfo]
|
||||
if (res.ok) {
|
||||
const { walletinfo } = await res.json()
|
||||
const balance = walletinfo.total_balance
|
||||
const mix_depths = walletinfo.accounts
|
||||
const wallet_info = { balance }
|
||||
wallet_info[mix_depths[0].account] = mix_depths[0].account_balance
|
||||
wallet_info[mix_depths[1].account] = mix_depths[1].account_balance
|
||||
wallet_info[mix_depths[2].account] = mix_depths[2].account_balance
|
||||
wallet_info[mix_depths[3].account] = mix_depths[3].account_balance
|
||||
wallet_info[mix_depths[4].account] = mix_depths[4].account_balance
|
||||
|
||||
return [walletinfo]
|
||||
} else {
|
||||
const { message } = await res.json()
|
||||
setAlert({ variant: 'danger', message })
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
alert('Error while loading.')
|
||||
setAlert({ variant: 'danger', message: e.message })
|
||||
} finally {
|
||||
setIsLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -65,14 +76,12 @@ const CurrentWallet = ({ currentWallet, activeWallet, onSend, listUTXOs }) => {
|
|||
}
|
||||
const getWalletInfo = async () => {
|
||||
const wallet_info = await listWalletInfo()
|
||||
console.log(wallet_info)
|
||||
setWalletInfo(wallet_info)
|
||||
}
|
||||
|
||||
const getUTXOs = async () => {
|
||||
const utxos = await listUTXOs()
|
||||
setUTXOHistory(utxos)
|
||||
console.log(utxos)
|
||||
}
|
||||
|
||||
getWalletInfo()
|
||||
|
|
@ -82,20 +91,17 @@ const CurrentWallet = ({ currentWallet, activeWallet, onSend, listUTXOs }) => {
|
|||
return (
|
||||
<div>
|
||||
<h1>{activeWallet}</h1>
|
||||
{wallet_info?.map((walletInfo, index) => {
|
||||
return <DisplayMixdepth key={index} walletInfo={walletInfo}></DisplayMixdepth>
|
||||
})}
|
||||
{alert && <rb.Alert variant={alert.variant}>{alert.message}</rb.Alert>}
|
||||
{isLoading &&
|
||||
<>
|
||||
<rb.Spinner as="span" animation="border" size="sm" role="status" aria-hidden="true" className="me-2" />
|
||||
Loading
|
||||
</>}
|
||||
{wallet_info?.map((walletInfo) => <DisplayMixdepths walletInfo={walletInfo} />)}
|
||||
<p></p>
|
||||
<Button onClick={() => { setShowUTXO(!showUTXO) }}>{showUTXO ? 'Hide UTXOs' : 'Show UTXOs'}</Button>
|
||||
{UTXOHistory && <rb.Button onClick={() => { setShowUTXO(!showUTXO) }}>{showUTXO ? 'Hide UTXOs' : 'Show UTXOs'}</rb.Button>}
|
||||
<p></p>
|
||||
{ showUTXO
|
||||
? Object.entries(UTXOHistory).map(([key, val]) =>
|
||||
<DisplayUTXOs key={key} utxoID={key} utxo={val}> </DisplayUTXOs>
|
||||
)
|
||||
: null
|
||||
}
|
||||
{UTXOHistory && showUTXO && <DisplayUTXOs utxos={UTXOHistory} />}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default CurrentWallet
|
||||
|
|
|
|||
|
|
@ -1,18 +0,0 @@
|
|||
.head {
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
.address_label {
|
||||
text-align: right;
|
||||
padding-right: 7%;
|
||||
color: rgb(10, 192, 10);
|
||||
}
|
||||
|
||||
.xpub {
|
||||
text-align: left;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.branch_body{
|
||||
text-align: left;
|
||||
}
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
import React from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
import * as rb from 'react-bootstrap'
|
||||
import './DisplayMixdepth.css'
|
||||
|
||||
const DisplayMixdepth = ({ walletInfo }) => {
|
||||
const accounts = []
|
||||
|
||||
for (const account_info of walletInfo.accounts) {
|
||||
accounts.push(account_info)
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
Total Balance: {walletInfo.total_balance} BTC
|
||||
<p></p>
|
||||
<rb.Button href="/maker">Maker Service</rb.Button>
|
||||
<p></p>
|
||||
{accounts.map((account, index) => (
|
||||
<div key={index}>
|
||||
<rb.Accordion>
|
||||
<rb.Accordion.Item eventKey={index}>
|
||||
<rb.Accordion.Header className="head">
|
||||
<div className="links">
|
||||
<rb.Container>
|
||||
<rb.Row>
|
||||
<rb.Col>
|
||||
Account {accounts[index].account}
|
||||
</rb.Col>
|
||||
<rb.Col>
|
||||
Balance: {accounts[index].account_balance} BTC
|
||||
</rb.Col>
|
||||
<rb.Col>
|
||||
<Link to={{ pathname: "/payment", state: { account_no: accounts[index].account } }} className="btn btn-primary">Send </Link>{' '}
|
||||
</rb.Col>
|
||||
<rb.Col>
|
||||
<Link to={{ pathname: "/receive", state: { account_no: accounts[index].account } }} className="btn btn-primary">Receive </Link>
|
||||
</rb.Col>
|
||||
</rb.Row>
|
||||
</rb.Container>
|
||||
</div>
|
||||
</rb.Accordion.Header>
|
||||
<rb.Accordion.Body>
|
||||
<rb.Accordion>
|
||||
<rb.Accordion.Item eventKey="0">
|
||||
<rb.Accordion.Header>External Addresses Balance: {accounts[index].branches[0].balance} BTC </rb.Accordion.Header>
|
||||
<div className="xpub">
|
||||
Extended Pubkey : {accounts[index].branches[0].branch.split("\t").pop()}
|
||||
</div>
|
||||
<rb.Accordion.Body>
|
||||
{accounts[index].branches[0].entries.map((user, i) => (
|
||||
<div key={i}>
|
||||
<rb.Accordion>
|
||||
<rb.Accordion.Item eventKey="0">
|
||||
<div className="address_label">
|
||||
<b>{accounts[index].branches[0].entries[i].labels}</b>
|
||||
</div>
|
||||
<rb.Accordion.Header>{accounts[index].branches[0].entries[i].address} {' '} </rb.Accordion.Header>
|
||||
<rb.Accordion.Body>
|
||||
<div className="branch-body">
|
||||
amount: {accounts[index].branches[0].entries[i].amount}
|
||||
</div>
|
||||
</rb.Accordion.Body>
|
||||
</rb.Accordion.Item>
|
||||
</rb.Accordion>
|
||||
</div>
|
||||
))}
|
||||
</rb.Accordion.Body>
|
||||
</rb.Accordion.Item>
|
||||
<rb.Accordion.Item eventKey="1">
|
||||
<rb.Accordion.Header>Internal Addresses Balance: {accounts[index].branches[1].balance} BTC</rb.Accordion.Header>
|
||||
<rb.Accordion.Body>
|
||||
{accounts[index].branches[1].entries.map((user, j) => (
|
||||
<div key={j}>
|
||||
<rb.Accordion>
|
||||
<rb.Accordion.Item eventKey="0">
|
||||
<rb.Accordion.Header>{accounts[index].branches[0].entries[j].address} {' '} {accounts[index].branches[0].entries[j].labels} </rb.Accordion.Header>
|
||||
<rb.Accordion.Body>
|
||||
<div className="branch_body">
|
||||
amount: {accounts[index].branches[0].entries[j].amount}
|
||||
</div>
|
||||
</rb.Accordion.Body>
|
||||
</rb.Accordion.Item>
|
||||
</rb.Accordion>
|
||||
</div>
|
||||
))}
|
||||
</rb.Accordion.Body>
|
||||
</rb.Accordion.Item>
|
||||
</rb.Accordion>
|
||||
</rb.Accordion.Body>
|
||||
</rb.Accordion.Item>
|
||||
</rb.Accordion>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default DisplayMixdepth
|
||||
94
src/components/DisplayMixdepths.jsx
Normal file
94
src/components/DisplayMixdepths.jsx
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
import React from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
import * as rb from 'react-bootstrap'
|
||||
|
||||
export default function DisplayMixdepths({ walletInfo }) {
|
||||
const accounts = []
|
||||
|
||||
for (const account_info of walletInfo.accounts) {
|
||||
accounts.push(account_info)
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
Total Balance: {walletInfo.total_balance} BTC
|
||||
<p></p>
|
||||
<rb.Button href="/maker">Maker Service</rb.Button>
|
||||
<p></p>
|
||||
<rb.Accordion>
|
||||
{accounts.map((account, index) => (
|
||||
<rb.Accordion.Item key={index} eventKey={index}>
|
||||
<rb.Accordion.Header className="head">
|
||||
<div className="links">
|
||||
<rb.Container>
|
||||
<rb.Row>
|
||||
<rb.Col>
|
||||
Account {accounts[index].account}
|
||||
</rb.Col>
|
||||
<rb.Col>
|
||||
Balance: {accounts[index].account_balance} BTC
|
||||
</rb.Col>
|
||||
<rb.Col>
|
||||
<Link to={{ pathname: "/payment", state: { account_no: accounts[index].account } }} className="btn btn-primary">Send </Link>{' '}
|
||||
</rb.Col>
|
||||
<rb.Col>
|
||||
<Link to={{ pathname: "/receive", state: { account_no: accounts[index].account } }} className="btn btn-primary">Receive </Link>
|
||||
</rb.Col>
|
||||
</rb.Row>
|
||||
</rb.Container>
|
||||
</div>
|
||||
</rb.Accordion.Header>
|
||||
<rb.Accordion.Body>
|
||||
<rb.Accordion>
|
||||
<rb.Accordion.Item eventKey="0">
|
||||
<rb.Accordion.Header>External Addresses Balance: {accounts[index].branches[0].balance} BTC </rb.Accordion.Header>
|
||||
<div className="xpub">
|
||||
Extended Pubkey : {accounts[index].branches[0].branch.split("\t").pop()}
|
||||
</div>
|
||||
<rb.Accordion.Body>
|
||||
{accounts[index].branches[0].entries.map((user, i) => (
|
||||
<div key={i}>
|
||||
<rb.Accordion>
|
||||
<rb.Accordion.Item eventKey="0">
|
||||
<div className="address_label">
|
||||
<b>{accounts[index].branches[0].entries[i].labels}</b>
|
||||
</div>
|
||||
<rb.Accordion.Header>{accounts[index].branches[0].entries[i].address} {' '} </rb.Accordion.Header>
|
||||
<rb.Accordion.Body>
|
||||
<div className="branch-body">
|
||||
amount: {accounts[index].branches[0].entries[i].amount}
|
||||
</div>
|
||||
</rb.Accordion.Body>
|
||||
</rb.Accordion.Item>
|
||||
</rb.Accordion>
|
||||
</div>
|
||||
))}
|
||||
</rb.Accordion.Body>
|
||||
</rb.Accordion.Item>
|
||||
<rb.Accordion.Item eventKey="1">
|
||||
<rb.Accordion.Header>Internal Addresses Balance: {accounts[index].branches[1].balance} BTC</rb.Accordion.Header>
|
||||
<rb.Accordion.Body>
|
||||
{accounts[index].branches[1].entries.map((user, j) => (
|
||||
<div key={j}>
|
||||
<rb.Accordion>
|
||||
<rb.Accordion.Item eventKey="0">
|
||||
<rb.Accordion.Header>{accounts[index].branches[0].entries[j].address} {' '} {accounts[index].branches[0].entries[j].labels} </rb.Accordion.Header>
|
||||
<rb.Accordion.Body>
|
||||
<div className="branch_body">
|
||||
amount: {accounts[index].branches[0].entries[j].amount}
|
||||
</div>
|
||||
</rb.Accordion.Body>
|
||||
</rb.Accordion.Item>
|
||||
</rb.Accordion>
|
||||
</div>
|
||||
))}
|
||||
</rb.Accordion.Body>
|
||||
</rb.Accordion.Item>
|
||||
</rb.Accordion>
|
||||
</rb.Accordion.Body>
|
||||
</rb.Accordion.Item>
|
||||
))}
|
||||
</rb.Accordion>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,19 +1,42 @@
|
|||
import React from 'react'
|
||||
import * as rb from 'react-bootstrap'
|
||||
|
||||
const DisplayUTXOs = ({ utxoID, utxo }) => (
|
||||
<div>
|
||||
<p></p>
|
||||
<p></p>
|
||||
<br></br>
|
||||
<span>Address: {utxo.address}</span>
|
||||
<br></br>
|
||||
<span>Value(Sats): {utxo.value}</span>
|
||||
<br></br>
|
||||
<span>Confirmations: {utxo.confirmations}</span>
|
||||
<br></br>
|
||||
<span>Mixdepth: {utxo.mixdepth}</span>
|
||||
<p></p>
|
||||
</div>
|
||||
const byMixdepth = utxos => {
|
||||
const ret = utxos.reduce((res, utxo) => {
|
||||
const { mixdepth } = utxo
|
||||
res[mixdepth] = res[mixdepth] || []
|
||||
res[mixdepth].push(utxo)
|
||||
return res
|
||||
}, {})
|
||||
console.log(ret)
|
||||
return ret
|
||||
}
|
||||
|
||||
|
||||
const DisplayUTXOs = ({ utxos }) => (
|
||||
<rb.Accordion>
|
||||
{Object.entries(byMixdepth(utxos)).map(([mixdepth, utxos]) => (
|
||||
<rb.Accordion.Item key={mixdepth} eventKey={mixdepth}>
|
||||
<rb.Accordion.Header className="head">
|
||||
Mixdepth {mixdepth}
|
||||
</rb.Accordion.Header>
|
||||
<rb.Accordion.Body>
|
||||
<ul class="list-group list-group-flush">
|
||||
{utxos.map(utxo => (
|
||||
<li class="list-group-item">
|
||||
<span>Address: {utxo.address}</span>
|
||||
<br></br>
|
||||
<span>Sats: {utxo.value}</span>
|
||||
<br></br>
|
||||
<span>{utxo.confirmations} Confirmations</span>
|
||||
<pre>{JSON.stringify(utxo, null, 2)}</pre>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</rb.Accordion.Body>
|
||||
</rb.Accordion.Item>
|
||||
))}
|
||||
</rb.Accordion>
|
||||
)
|
||||
|
||||
export default DisplayUTXOs
|
||||
|
|
|
|||
|
|
@ -133,21 +133,20 @@ export default function Wallet({ name, currentWallet, activeWallet, setAlert })
|
|||
Please remove the lock file on the server.
|
||||
</rb.Alert>
|
||||
)
|
||||
: (noneActive
|
||||
? <rb.InputGroup>
|
||||
<rb.FormControl type="password" placeholder="Password" name="password" disabled={isUnlocking} required />
|
||||
<rb.FormControl type="hidden" name="action" value="unlock" />
|
||||
<rb.Button variant="primary" type="submit" disabled={isUnlocking}>
|
||||
{isUnlocking
|
||||
? <>
|
||||
<rb.Spinner as="span" animation="border" size="sm" role="status" aria-hidden="true" className="me-2" />
|
||||
Unlocking
|
||||
</>
|
||||
: 'Unlock'}
|
||||
</rb.Button>
|
||||
<rb.Form.Control.Feedback type="invalid">Please set the wallet's password.</rb.Form.Control.Feedback>
|
||||
</rb.InputGroup>
|
||||
: null)
|
||||
: (noneActive &&
|
||||
<rb.InputGroup>
|
||||
<rb.FormControl type="password" placeholder="Password" name="password" disabled={isUnlocking} required />
|
||||
<rb.FormControl type="hidden" name="action" value="unlock" />
|
||||
<rb.Button variant="primary" type="submit" disabled={isUnlocking}>
|
||||
{isUnlocking
|
||||
? <>
|
||||
<rb.Spinner as="span" animation="border" size="sm" role="status" aria-hidden="true" className="me-2" />
|
||||
Unlocking
|
||||
</>
|
||||
: 'Unlock'}
|
||||
</rb.Button>
|
||||
<rb.Form.Control.Feedback type="invalid">Please set the wallet's password.</rb.Form.Control.Feedback>
|
||||
</rb.InputGroup>)
|
||||
}
|
||||
</rb.Form>
|
||||
</rb.Card.Body>
|
||||
|
|
|
|||
|
|
@ -14,9 +14,7 @@ export default function Wallets({ currentWallet, activeWallet, walletList, onDis
|
|||
return (
|
||||
<>
|
||||
<h1>Wallets</h1>
|
||||
{alert
|
||||
? <Alert {...alert} />
|
||||
: null}
|
||||
{alert && <Alert {...alert} />}
|
||||
{walletList.map(wallet =>
|
||||
<Wallet key={wallet} name={wallet} currentWallet={currentWallet} activeWallet={activeWallet} setAlert={setAlert} onDisplay={onDisplay} />)}
|
||||
</>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue