Format files

This commit is contained in:
Dennis Reimann 2021-11-03 22:00:57 +01:00
parent ca009e01b3
commit fadf91ef7a
No known key found for this signature in database
GPG key ID: 5009E1797F03F8D0
23 changed files with 1083 additions and 1287 deletions

View file

@ -1,476 +1,399 @@
import './App.css';
import '@ibunker/bitcoin-react/dist/index.css';
import './App.css'
import '@ibunker/bitcoin-react/dist/index.css'
import {useState,useEffect} from 'react'
import Wallets from './components/Wallets';
import Payment from './components/Payment';
import CreateWallet from './components/CreateWallet';
import Homepage from './components/homepage';
import Maker from './components/Maker';
import Receive from './components/Receive';
import Wallets from './components/Wallets'
import Payment from './components/Payment'
import CreateWallet from './components/CreateWallet'
import Homepage from './components/homepage'
import Maker from './components/Maker'
import Receive from './components/Receive'
import DisplayWallet from './components/DisplayWallet'
import * as rb from 'react-bootstrap';
import * as rb from 'react-bootstrap'
import github_logo from './github.svg'
import twitter_logo from './twitter.svg'
import useInterval from './components/utils'
import { BrowserRouter as Router, Route ,Switch} from 'react-router-dom';
import { useGlobal } from 'reactn';
import { BrowserRouter as Router, Route ,Switch} from 'react-router-dom'
import { useGlobal } from 'reactn'
function App() {
const [walletList,setWalletList] = useState([])
const [makerStarted, setmakerStarted] = useGlobal("makerStarted");
const [walletName, setWalletName] = useGlobal("walletName");
const [coinjoinInProcess, setCoinjoinInProcess] = useGlobal("coinjoinInProcess");
const [, setCurrentStatusMessage] = useGlobal("currentStatusMessage");
const [walletList, setWalletList] = useState([])
const [makerStarted, setmakerStarted] = useGlobal('makerStarted')
const [walletName, setWalletName] = useGlobal('walletName')
const [coinjoinInProcess, setCoinjoinInProcess] = useGlobal('coinjoinInProcess')
const [, setCurrentStatusMessage] = useGlobal('currentStatusMessage')
const listWallets = async () =>{
const res = await fetch('/api/v1/wallet/all');
const data = await res.json();
const walletList = data.wallets;
return walletList;
const res = await fetch('/api/v1/wallet/all')
const data = await res.json()
return data.wallets
}
const resetWalletSessionStorage = async () =>{
sessionStorage.clear();
setWalletName("No wallet loaded");
setmakerStarted(false);
setCoinjoinInProcess(false);
sessionStorage.clear()
setWalletName('No wallet loaded')
setmakerStarted(false)
setCoinjoinInProcess(false)
}
const getCurrentStatusMessage = () =>
`Wallet: ${walletName}, YG ${makerStarted ? 'started' : 'not running'}, Coinjoin in process: ${coinjoinInProcess}`;
`Wallet: ${walletName}, YG ${makerStarted ? 'started' : 'not running'}, Coinjoin in process: ${coinjoinInProcess}`
useInterval(() => {
const sessionClear = async () =>{
const sessionClear = async () => {
try {
const res = await fetch('/api/v1/session');
const { session, maker_running, wallet_name, coinjoin_in_process } = await res.json();
const res = await fetch('/api/v1/session')
const { session, maker_running, wallet_name, coinjoin_in_process } = await res.json()
if (session === false) {
console.log("no wallet in backend");
console.log('no wallet in backend')
// This status requires us to clear, especially
// the auth state, so we just reset everything:
return resetWalletSessionStorage();
return resetWalletSessionStorage()
}
setmakerStarted(maker_running);
setWalletName(wallet_name);
setCoinjoinInProcess(coinjoin_in_process);
setCurrentStatusMessage(getCurrentStatusMessage());
setmakerStarted(maker_running)
setWalletName(wallet_name)
setCoinjoinInProcess(coinjoin_in_process)
setCurrentStatusMessage(getCurrentStatusMessage())
} catch(e) {
console.error(e);
alert("Lost connection to backend! Please restart the backend server.");
sessionStorage.clear();
console.error(e)
alert('Lost connection to backend! Please restart the backend server.')
sessionStorage.clear()
}
}
sessionClear();
sessionClear()
}, 8*1000)
}, 8*1000);
useEffect(()=>{
const getWallets = async()=>{
const wallets = await listWallets();
setWalletList(wallets);
useEffect(() => {
const getWallets = async () => {
const wallets = await listWallets()
setWalletList(wallets)
}
getWallets();
},[])
getWallets()
}, [])
const unlockWallet = async (name) => {
const authData = JSON.parse(sessionStorage.getItem('auth'));
const authData = JSON.parse(sessionStorage.getItem('auth'))
if (authData && authData.login) {
return alert(authData.name === name
// unlocking same wallet
? `${name} is already unlocked`
// unlocking another wallet while one is already unlocked
: `${authData.name} is currently in use, please lock it first`);
: `${authData.name} is currently in use, please lock it first`)
} else {
try {
const password = prompt(`Enter the passphrase for ${name}`);
const password = prompt(`Enter the passphrase for ${name}`)
const res = await fetch(`/api/v1/wallet/${name}/unlock`,{
method: 'POST',
headers: { 'Content-type': 'application/json' },
body: JSON.stringify({ password }),
})
const data = await res.json();
const data = await res.json()
console.log(data)
const token = data.token;
sessionStorage.setItem('auth', JSON.stringify({ login: true, token, name }));
const token = data.token
sessionStorage.setItem('auth', JSON.stringify({ login: true, token, name }))
} catch (e) {
console.error(e);
alert('Something went wrong, please try again!');
console.error(e)
alert('Something went wrong, please try again!')
}
}
}
const lockWallet = async(name)=>{
let authData =JSON.parse(sessionStorage.getItem('auth'));
if(!authData || authData.login===false || authData.name!==name){
alert("Please unlock "+name+" first")
return;
}
const lockWallet = async (name) => {
const authData = JSON.parse(sessionStorage.getItem('auth'))
if (!authData || !authData.login || authData.name !== name) {
return alert(`Please unlock ${name} first`)
}
try{
let token = "Bearer "+authData.token
const res = await fetch(`/api/v1/wallet/${name}/lock`,{
method:"GET",
headers:{
'Authorization':token
try {
const res = await fetch(`/api/v1/wallet/${name}/lock`, {
headers: {
'Authorization': `Bearer ${authData.token}`
}
});
sessionStorage.setItem('auth',JSON.stringify({
login:false,
token:'',
name:''
})
sessionStorage.setItem('auth', JSON.stringify({
login: false,
token: '',
name: ''
}))
const data = await res.json();
console.log(data);
alert("locked wallet succesfully")
}
catch(e){
alert("Error while locking.")
const data = await res.json()
console.log(data)
alert('Wallet locked succesfully')
} catch (e) {
console.error(e)
alert('Error while locking.')
}
}
const listWalletInfo = async (name) => {
const authData = JSON.parse(sessionStorage.getItem('auth'))
const res = await fetch(`/api/v1/wallet/${name}/display`, {
headers:{
'Authorization': `Bearer ${authData.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]
}
const displayWallet = async (name) => {
const authData = JSON.parse(sessionStorage.getItem('auth'))
if (!authData || !authData.login || authData.name !== name) {
return alert(`Please unlock ${name} first`)
}
const listWalletInfo = async(name)=>{
let authData =JSON.parse(sessionStorage.getItem('auth'));
let token = "Bearer "+authData.token
const res = await fetch(`/api/v1/wallet/${name}/display`,{
method:"GET",
headers:{
'Authorization':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
const res = await fetch(`/api/v1/wallet/${name}/display`, {
headers:{
'Authorization': `Bearer ${authData.token}`
}
})
return [walletinfo];
const { walletinfo } = await res.json()
const balance = walletinfo.total_balance
const mix_depths = walletinfo.accounts
const wallet_info={}
wallet_info['balance'] = 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
console.log(wallet_info)
return wallet_info
}
const createWallet = async (walletname, password) => {
const authData = JSON.parse(sessionStorage.getItem('auth'))
if (!authData || !authData.login) {
try {
const wallettype = 'sw'
const res = await fetch(`/api/v1/wallet/create`, {
method: 'POST',
headers: { 'Content-type': 'application/json', },
body: JSON.stringify({
password,
walletname,
wallettype
}),
})
const { seedphrase, token } = await res.json()
alert('Wallet created succesfully')
// TODO: figure out a safer way to show the seedphrase
alert(seedphrase)
sessionStorage.setItem('auth', JSON.stringify({ login: true, token, name: walletname }))
} catch (e) {
console.error(e)
//some other error occurs where wallet is not created
alert('Unexpected error! Please try again')
}
} else {
alert(`${authData.name} is in use! Please lock it first.`)
}
}
const displayWallet = async(name)=>{
let authData =JSON.parse(sessionStorage.getItem('auth'));
if(authData.login===false || authData.name!==name){
alert("Please unlock "+name+" first")
return;
const makePayment = async (name, mixdepth, amount_sats,destination) => {
const authData = JSON.parse(sessionStorage.getItem('auth'))
if (authData && authData.login === true){
try {
const res = await fetch(`/api/v1/wallet/${name}/taker/direct-send`, {
method:'POST',
headers: {
'Content-type': 'application/json',
'Authorization': `Bearer ${authData.token}`
},
body: JSON.stringify({
mixdepth,
amount_sats,
destination
}),
})
const data = await res.json()
console.log(data)
alert('Payment Succesful!')
} catch(e) {
alert('Error while processing payment!')
}
let token = "Bearer "+authData.token
const res = await fetch(`/api/v1/wallet/${name}/display`,{
method:"GET",
headers:{
'Authorization':token
}
});
const { walletinfo } = await res.json();
const balance = walletinfo.total_balance;
const mix_depths = walletinfo.accounts;
const wallet_info={}
wallet_info['balance'] = 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
console.log(wallet_info)
return wallet_info;
} else {
alert('please unlock wallet first')
}
}
const createWallet = async(name,password)=>{
const authData = JSON.parse(sessionStorage.getItem('auth'));
if (!authData || !authData.login) {
try {
const res = await fetch(`/api/v1/wallet/create`,{
method:'POST',
headers: { 'Content-type': 'application/json', },
body: JSON.stringify({ password, "walletname": name, "wallettype":"sw" }),
})
const { seedphrase, token } = await res.json();
alert("Wallet created succesfully")
//figure out a safer way to show the seedphrase
alert(seedphrase)
sessionStorage.setItem('auth', JSON.stringify({ login: true, token, name }))
} catch (e) {
console.error(e);
//some other error occurs where wallet is not created
alert('Unexpected error! Please try again')
}
} else{
alert(`${authData.name} is in use! Please lock it first.`)
//route for frontend
const doCoinjoin = async (mixdepth, amount, counterparties, destination) => {
try {
const authData = JSON.parse(sessionStorage.getItem('auth'))
if (!authData || !authData.login || authData.name === '') {
return
}
}
const makePayment = async(name,mixdepth,amountSats,destination)=>{
let authData =JSON.parse(sessionStorage.getItem('auth'));
if(authData!=null && authData.login===true){
try{
let token = "Bearer "+authData.token
const res = await fetch(`/api/v1/wallet/${name}/taker/direct-send`,{
method:'POST',
headers: {
'Content-type': 'application/json',
'Authorization':token
},
body: JSON.stringify({
"mixdepth": mixdepth,
"amount_sats": amountSats,
"destination": destination
}
),
})
const data = await res.json();
console.log(data);
alert("Payment Succesful!")
}
catch(e){
alert("Error while processing payment!")
}
}
else{
alert("please unlock wallet first")
}
}
//route for frontend
const doCoinjoin = async(mixdepth,amount,counterparties,destination)=>{
try{
console.log("hellooo")
let authData = JSON.parse(sessionStorage.getItem('auth'));
if(!authData|| authData.login===false || authData.name===''){
return;
}
let token = "Bearer "+authData.token;
let name = authData.name;
const res = await fetch(`/api/v1/wallet/${name}/taker/coinjoin`,{
method:'POST',
headers: {
'Content-type': 'application/json',
'Authorization':token
},
body: JSON.stringify({
"mixdepth": mixdepth,
"amount": amount,
"counterparties": counterparties,
"destination":destination
}
),
})
const data = await res.json();
console.log(data);
alert("Coinjoin in Progress!")
}
catch(e){
return;
}
}
const startMakerService = async(txfee,cjfee_a,cjfee_r,ordertype,minsize)=>{
let authData =JSON.parse(sessionStorage.getItem('auth'));
if(!authData|| authData.login===false || authData.name===''){
alert("Please unlock a wallet first")
return;
}
let name = authData.name
try{
let token = "Bearer "+authData.token
const res = await fetch(`/api/v1/wallet/${name}/maker/start`,{
method:"POST",
headers:{
'Authorization':token
const res = await fetch(`/api/v1/wallet/${authData.name}/taker/coinjoin`, {
method:'POST',
headers: {
'Content-type': 'application/json',
'Authorization': `Bearer ${authData.token}`
},
body: JSON.stringify({
"txfee":txfee,
"cjfee_a":cjfee_a,
"cjfee_r":cjfee_r,
"ordertype":ordertype,
"minsize":minsize
}
),
});
const data = await res.json();
console.log(data);
}
catch(e){
alert("Error while starting service!")
}
mixdepth,
amount,
counterparties,
destination
}),
})
const data = await res.json()
console.log(data)
alert('Coinjoin in Progress!')
} catch (e) {
console.error(e)
}
}
const startMakerService = async (txfee, cjfee_a, cjfee_r, ordertype, minsize) => {
const authData =JSON.parse(sessionStorage.getItem('auth'))
if (!authData || !authData.login || authData.name === ''){
return alert('Please unlock a wallet first')
}
const stopMakerService= async()=>{
let authData =JSON.parse(sessionStorage.getItem('auth'));
if(authData===null ||authData.login===false || authData.name===''){
alert('Wallet needs to be unlocked')
return;
}
try{
let name = authData.name
let token = "Bearer "+authData.token
const res = await fetch(`/api/v1/wallet/${name}/maker/stop`,{
method:"GET",
headers:{
'Authorization':token
},
try {
const res = await fetch(`/api/v1/wallet/${authData.name}/maker/start`, {
method: 'POST',
headers:{
'Authorization': `Bearer ${authData.token}`
},
body: JSON.stringify({
txfee,
cjfee_a,
cjfee_r,
ordertype,
minsize
})
const data = await res.json();
console.log(data);
alert("Maker service stopped")
}
})
catch(e){
alert("Error while stopping service!")
}
const data = await res.json()
console.log(data)
} catch (e) {
console.error(e)
alert('Error while starting service!')
}
}
const stopMakerService = async () => {
const authData = JSON.parse(sessionStorage.getItem('auth'))
if (!authData || !authData.login || authData.name === '') {
return alert('Wallet needs to be unlocked')
}
const getUTXOs = async()=>{
try{
let authData =JSON.parse(sessionStorage.getItem('auth'));
let token = "Bearer "+authData.token
if(!authData|| authData.login===false || authData.name===''){
return;
}
let name = authData.name;
const res = await fetch(`/api/v1/wallet/${name}/utxos`, {
headers: { 'Authorization':token }
});
const { utxos } = await res.json();
return utxos;
} catch(e){
return console.error(e);
}
try {
const res = await fetch(`/api/v1/wallet/${authData.name}/maker/stop`, {
headers:{
'Authorization': `Bearer ${authData.token}`
},
})
const data = await res.json()
console.log(data)
alert('Maker service stopped')
} catch (e) {
console.error(e)
alert('Error while stopping service!')
}
}
const getUTXOs = async () => {
try {
const authData = JSON.parse(sessionStorage.getItem('auth'))
if (!authData || !authData.login || authData.name === '') {
return
}
const res = await fetch(`/api/v1/wallet/${authData.name}/utxos`, {
headers: {
'Authorization': `Bearer ${authData.token}`
}
})
const { utxos } = await res.json()
return utxos
} catch (e) {
console.error(e)
}
}
return (
<Router>
<div className="App">
<rb.Navbar sticky="top" collapseOnSelect expand="lg" bg="dark" variant="dark">
<rb.Container>
<rb.Navbar.Brand href='/'>Joinmarket</rb.Navbar.Brand>
<rb.Navbar.Toggle aria-controls="responsive-rb.Navbar-rb.Nav" />
<rb.Navbar.Collapse id="responsive-rb.Navbar-rb.Nav">
<rb.Nav className="me-auto">
<rb.Nav.Link href="https://github.com/JoinMarket-Org/joinmarket-clientserver/tree/master/docs">Docs</rb.Nav.Link>
<rb.Nav.Link href="https://github.com/JoinMarket-Org/joinmarket-clientserver#wallet-features">Features</rb.Nav.Link>
<rb.Nav.Link href="https://github.com/JoinMarket-Org/joinmarket-clientserver#joinmarket-clientserver">About</rb.Nav.Link>
</rb.Nav>
<rb.Nav>
<rb.Navbar.Brand href="https://github.com/JoinMarket-Org/joinmarket-clientserver">
<img
src={github_logo}
width="50"
height="50"
className="github"
alt="github logo"
/>
</rb.Navbar.Brand>
<rb.Navbar.Brand href="https://twitter.com/joinmarket">
<img
src={twitter_logo}
width="50"
height="50"
className="twitter"
alt="twitter logo"
/>
</rb.Navbar.Brand>
</rb.Nav>
</rb.Navbar.Collapse>
</rb.Container>
<rb.Container>
<rb.Navbar.Text>{getCurrentStatusMessage()}</rb.Navbar.Text>
</rb.Container>
</rb.Navbar>
<div className="App">
<rb.Navbar sticky="top" collapseOnSelect expand="lg" bg="dark" variant="dark">
<rb.Container>
<rb.Navbar.Brand href='/'>Joinmarket</rb.Navbar.Brand>
<rb.Navbar.Toggle aria-controls="responsive-rb.Navbar-rb.Nav" />
<rb.Navbar.Collapse id="responsive-rb.Navbar-rb.Nav">
<rb.Nav className="me-auto">
<rb.Nav.Link href="https://github.com/JoinMarket-Org/joinmarket-clientserver/tree/master/docs">Docs</rb.Nav.Link>
<rb.Nav.Link href="https://github.com/JoinMarket-Org/joinmarket-clientserver#wallet-features">Features</rb.Nav.Link>
<rb.Nav.Link href="https://github.com/JoinMarket-Org/joinmarket-clientserver#joinmarket-clientserver">About</rb.Nav.Link>
</rb.Nav>
<rb.Nav>
<rb.Navbar.Brand href="https://github.com/JoinMarket-Org/joinmarket-clientserver">
<img
src={github_logo}
width="50"
height="50"
className="github"
alt="github logo"
/>
</rb.Navbar.Brand>
<rb.Navbar.Brand href="https://twitter.com/joinmarket">
<img
src={twitter_logo}
width="50"
height="50"
className="twitter"
alt="twitter logo"
/>
</rb.Navbar.Brand>
</rb.Nav>
</rb.Navbar.Collapse>
</rb.Container>
<rb.Container>
<rb.Navbar.Text>
{getCurrentStatusMessage()}
</rb.Navbar.Text>
</rb.Container>
</rb.Navbar>
<p></p>
<Switch>
<Route
path='/'
exact
render={(props) => (
<>
<Homepage></Homepage>
</>
)}
/>
<Route
path='/showWallets'
exact
render={(props) => (
<>
<Wallets walletList = {walletList} onUnlock = {unlockWallet} onLock = {lockWallet} onDisplay = {displayWallet}></Wallets>
</>
)}
/>
<Route path='/payment' exact render={(props) => (
<>
<Payment onPayment = {makePayment} onCoinjoin = {doCoinjoin}></Payment>
</>
)}
/>
<Route path='/create' exact render={(props) => (
<>
<CreateWallet onCreate={createWallet}></CreateWallet>
</>
)}
/>
<Route path='/maker' exact render={(props) => (
<>
<Maker onStart = {startMakerService} onStop = {stopMakerService}></Maker>
</>
)}
/>
<Route path='/receive' exact render={(props) => (
<>
<Receive></Receive>
</>
)}
/>
<Route path='/display' exact render={(props) => (
<>
<DisplayWallet listWalletInfo = {listWalletInfo} onSend = {makePayment} listUTXOs={getUTXOs}></DisplayWallet>
</>
)}
/>
</Switch>{" "}
</div>
<Route path='/' exact render={props => (
<Homepage />
)} />
<Route path='/showWallets' exact render={props => (
<Wallets walletList={walletList} currentWallet={walletName} onUnlock={unlockWallet} onLock={lockWallet} onDisplay={displayWallet} />
)} />
<Route path='/payment' exact render={props => (
<Payment onPayment={makePayment} onCoinjoin={doCoinjoin} />
)} />
<Route path='/create' exact render={props => (
<CreateWallet onCreate={createWallet} />
)} />
<Route path='/maker' exact render={props => (
<Maker onStart={startMakerService} onStop={stopMakerService} />
)} />
<Route path='/receive' exact render={props => (
<Receive />
)} />
<Route path='/display' exact render={props => (
<DisplayWallet listWalletInfo={listWalletInfo} onSend={makePayment} listUTXOs={getUTXOs} />
)} />
</Switch>
</div>
</Router>
);
)
}
export default App;
export default App

View file

@ -1,8 +0,0 @@
import { render, screen } from '@testing-library/react';
import App from './App';
test('renders learn react link', () => {
render(<App />);
const linkElement = screen.getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
});

View file

@ -1,11 +1,8 @@
import React from "react";
import "./button.css";
export const Button = ({name,children, type, onClick, buttonStyle, buttonSize}) => {
return (
<button onClick = {()=>onClick(name)} type = {type}>
{children}
</button>
)
}
import React from 'react'
import './button.css'
export const Button = ({ name, children, type, onClick }) => (
<button onClick={() => onClick(name)} type={type}>
{children}
</button>
)

View file

@ -3,82 +3,60 @@ import { useState } from 'react'
import './createWallet.css'
import * as rb from 'react-bootstrap'
const CreateWallet = ({onCreate}) => {
const CreateWallet = ({ onCreate }) => {
const [wallet, setWallet] = useState('')
const [password, setPassword] = useState('')
const [wallet,setWallet] = useState('')
const [password,setPassword]=useState('')
const onSubmit = (e) => {
e.preventDefault()
const onSubmit = (e) => {
e.preventDefault()
if (!wallet || !password) {
alert('Please add details')
return;
}
onCreate(wallet,password)
setWallet('')
setPassword('')
}
return (
<div>
<br></br>
<div className = "heading">
Create Wallet
</div>
if (!wallet || !password) {
alert('Please add details')
return;
}
<form method="POST" onSubmit={onSubmit}>
<rb.Container className = "center">
<rb.Container fluid = "false" className = "form1">
<rb.Row>
<rb.Col className="label">
Wallet Name
</rb.Col>
<rb.Col>
<input style = {{width: "220px"}} classname = "field-border" type="text" name="wallet" value = {wallet} onChange={(e) => setWallet(e.target.value)}/>
</rb.Col>
</rb.Row>
<rb.Row className = "field">
<rb.Col className="label">
Password
</rb.Col>
<rb.Col>
<input type="password" style = {{width: "220px"}} name="password" value = {password} onChange={(e) => setPassword(e.target.value)} />
</rb.Col>
</rb.Row>
<rb.Row className = "btn-field">
<button className="btncr" type="submit" value="Submit" ><span>Submit</span></button>
</rb.Row>
</rb.Container>
</rb.Container>
</form>
{/* <form method="POST" onSubmit={onSubmit}>
<label>
Wallet Name
<input className = "test" type="text" name="wallet" value = {wallet} onChange={(e) => setWallet(e.target.value)}/>
</label>
<p></p>
<label>
Password
<input type="password" name="password" value = {password} onChange={(e) => setPassword(e.target.value)} />
</label>
<p></p>
<input className = "submit" type="submit" value="Submit" />
onCreate(wallet, password)
setWallet('')
setPassword('')
}
</form> */}
</div>
)
return (
<div>
<div className="heading">
Create Wallet
</div>
<form method="POST" onSubmit={onSubmit}>
<rb.Container className="center">
<rb.Container fluid="false" className="form1">
<rb.Row>
<rb.Col className="label">
Wallet Name
</rb.Col>
<rb.Col>
<input style={{ width: "220px" }} classname="field-border" type="text" name="wallet" value={wallet} onChange={(e) => setWallet(e.target.value)} />
</rb.Col>
</rb.Row>
<rb.Row className="field">
<rb.Col className="label">
Password
</rb.Col>
<rb.Col>
<input type="password" style={{ width: "220px" }} name="password" value={password} onChange={(e) => setPassword(e.target.value)} />
</rb.Col>
</rb.Row>
<rb.Row className="btn-field">
<button className="btncr" type="submit" value="Submit"><span>Submit</span></button>
</rb.Row>
</rb.Container>
</rb.Container>
</form>
</div>
)
}
export default CreateWallet

View file

@ -1,110 +1,99 @@
import React from 'react'
import './displayMixdepth.css'
import { Link } from 'react-router-dom';
import { Link } from 'react-router-dom'
import * as rb from 'react-bootstrap'
const DisplayMixdepth = ({walletInfo}) => {
const DisplayMixdepth = ({ walletInfo }) => {
const accounts = []
const accounts = []
for (const account_info of walletInfo.accounts) {
accounts.push(account_info)
}
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>
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

View file

@ -1,22 +1,19 @@
import React from 'react'
const DisplayUTXOs = ({utxoID,utxo}) => {
return (
<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>
)
}
export default DisplayUTXOs;
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>
)
export default DisplayUTXOs

View file

@ -1,75 +1,73 @@
import React from 'react'
import {useState,useEffect} from 'react'
import { useState, useEffect } from 'react'
import { Button } from './Button'
import DisplayMixdepth from './DisplayMixdepth'
import DisplayUTXOs from './DisplayUTXOs'
const DisplayWallet = ({listWalletInfo,onSend,listUTXOs}) => {
const [wallet_info,setWalletInfo] = useState([])
const [UTXOHistory,setUTXOHistory] = useState({})
const [showUTXO,setShowUTXO] = useState(false);
// Websocket object with scope of DisplayWallet - we don't initialize
// yet because it auto-opens, and we can only open once
// we have authenticated:
var ws;
useEffect(()=>{
const name = JSON.parse(sessionStorage.getItem('auth')).name;
const token = JSON.parse(sessionStorage.getItem('auth')).token;
ws = new WebSocket(`ws://${window.location.hostname}:${window.location.port}`);
ws.onopen = (event) => {
console.log("connected to websocket");
ws.send(token);
}
ws.onmessage = (event) => {
// For now we only have one message type,
// namely the transaction notification:
// For now, note that since the `getUtxos` function
// is called on every render of the display page,
// we don't need to somehow use this data other
// than as some kind of popup/status bar notifier.
// In future it might be possible to use the detailed
// transaction deserialization passed in this notification,
// for something.
var wsdata = JSON.parse(event.data);
alert("Websocket sent: " + wsdata.txid);
}
const getWalletInfo = async()=>{
const wallet_info = await listWalletInfo(name);
console.log(wallet_info);
setWalletInfo(wallet_info);
}
const DisplayWallet = ({ listWalletInfo, onSend, listUTXOs }) => {
const [wallet_info, setWalletInfo] = useState([])
const [UTXOHistory, setUTXOHistory] = useState({})
const [showUTXO, setShowUTXO] = useState(false)
const getUTXOs = async()=>{
const utxos = await listUTXOs();
setUTXOHistory(utxos)
console.log(utxos)
}
// Websocket object with scope of DisplayWallet - we don't initialize
// yet because it auto-opens, and we can only open once
// we have authenticated:
var ws
useEffect(() => {
const name = JSON.parse(sessionStorage.getItem('auth')).name;
const token = JSON.parse(sessionStorage.getItem('auth')).token;
ws = new WebSocket(`ws://${window.location.hostname}:${window.location.port}`);
ws.onopen = (event) => {
console.log("connected to websocket");
ws.send(token);
}
ws.onmessage = (event) => {
// For now we only have one message type,
// namely the transaction notification:
// For now, note that since the `getUtxos` function
// is called on every render of the display page,
// we don't need to somehow use this data other
// than as some kind of popup/status bar notifier.
// In future it might be possible to use the detailed
// transaction deserialization passed in this notification,
// for something.
var wsdata = JSON.parse(event.data);
alert("Websocket sent: " + wsdata.txid);
}
const getWalletInfo = async () => {
const wallet_info = await listWalletInfo(name);
console.log(wallet_info);
setWalletInfo(wallet_info);
}
getWalletInfo();
getUTXOs();
},[])
const getUTXOs = async () => {
const utxos = await listUTXOs();
setUTXOHistory(utxos)
console.log(utxos)
}
return (
<div>
Wallet Details
<p></p>
{wallet_info.map((walletInfo,index)=>{
return <DisplayMixdepth key={index} walletInfo = {walletInfo}></DisplayMixdepth>
})}
<p></p>
<Button onClick={()=>{setShowUTXO(!showUTXO)}}>{showUTXO?"Hide UTXOs":"Show UTXOs"}</Button>
<p></p>
getWalletInfo();
getUTXOs();
}, [])
{
showUTXO?
Object.entries(UTXOHistory).map(([key, val])=>
<DisplayUTXOs key={key} utxoID={key} utxo={val}> </DisplayUTXOs>
)
: ""
}
</div>
)
return (
<div>
Wallet Details
<p></p>
{wallet_info.map((walletInfo, index) => {
return <DisplayMixdepth key={index} walletInfo={walletInfo}></DisplayMixdepth>
})}
<p></p>
<Button onClick={() => { setShowUTXO(!showUTXO) }}>{showUTXO ? "Hide UTXOs" : "Show UTXOs"}</Button>
<p></p>
{ showUTXO
? Object.entries(UTXOHistory).map(([key, val]) =>
<DisplayUTXOs key={key} utxoID={key} utxo={val}> </DisplayUTXOs>
)
: null
}
</div>
)
}
export default DisplayWallet

View file

@ -1,6 +1,4 @@
.container1{
height: 100vh;
padding-top: 100px;
.container1 {
height: 100vh;
padding-top: 100px;
}

View file

@ -1,67 +1,51 @@
import React from 'react'
import { useHistory } from 'react-router-dom';
import { useHistory } from 'react-router-dom'
import { useState } from 'react'
import { useGlobal } from 'reactn';
import { useGlobal } from 'reactn'
const Maker = ({onStart,onStop}) => {
const Maker = ({ onStart, onStop }) => {
const [cjfeeRel, setCjfeerel] = useState('')
const [makerStarted] = useGlobal('makerStarted')
const [setSubmitVal] = useState('Start Maker Service')
const history = useHistory()
const [cjfeeRel,setCjfeerel] = useState('')
const [makerStarted] = useGlobal("makerStarted");
const [setSubmitVal] = useState('Start Maker Service')
const history = useHistory();
const onSubmit = (e) => {
e.preventDefault()
if(makerStarted === false){
console.log('b')
if (!cjfeeRel) {
alert('Please add details')
return;
}
onStart(0,0,cjfeeRel,'sw0reloffer',1000);
setCjfeerel('')
alert("Attempting to start the yield generator. Check the status bar for updates.");
setSubmitVal('Stop Maker Service')
}
else{
console.log('c')
onStop();
setSubmitVal('Start Maker Service')
}
let path = `/display`;
history.push(path);
const onSubmit = (e) => {
e.preventDefault()
if (makerStarted === false) {
if (!cjfeeRel) {
return alert('Please add details')
}
onStart(0, 0, cjfeeRel, 'sw0reloffer', 1000)
setCjfeerel('')
alert("Attempting to start the yield generator. Check the status bar for updates.")
setSubmitVal('Stop Maker Service')
} else {
onStop()
setSubmitVal('Start Maker Service')
}
return (
<div>
<h3>Maker Service</h3>
<form method="POST" onSubmit={onSubmit}>
let path = `/display`;
history.push(path);
}
return (
<div>
<h3>Maker Service</h3>
<form method="POST" onSubmit={onSubmit}>
<p></p>
{
makerStarted === false ?
<label>
Relative Coinjoin Fee
<input type="text" name="cjfee_r" value = {cjfeeRel} onChange={(e) => setCjfeerel(e.target.value)}/>
</label>
:''
{ makerStarted === false
? <label>
Relative Coinjoin Fee
<input type="text" name="cjfee_r" value={cjfeeRel} onChange={(e) => setCjfeerel(e.target.value)} />
</label>
: null
}
<p></p>
<input type="submit" value={makerStarted ==='true'?'Stop Maker Service':'Start Maker Service'} />
</form>
</div>
)
<input type="submit" value={makerStarted === 'true' ? 'Stop Maker Service' : 'Start Maker Service'} />
</form>
</div>
)
}
export default Maker

View file

@ -4,132 +4,108 @@ import { useLocation } from "react-router-dom"
import './payment.css'
import * as rb from 'react-bootstrap'
const Payment = ({onPayment,onCoinjoin}) => {
const location = useLocation()
const [destination, setDestination] = useState('')
const [amount, setAmount] = useState('')
const [mixdepth, setMixdepth] = useState(location.state.account_no)
const [counterparties,setcounterparties] = useState('');
const [isCoinjoin,setisCoinjoin] = useState(false);
const Payment = ({ onPayment, onCoinjoin }) => {
const location = useLocation()
const [destination, setDestination] = useState('')
const [amount, setAmount] = useState('')
const [mixdepth, setMixdepth] = useState(location.state.account_no)
const [counterparties, setcounterparties] = useState('')
const [isCoinjoin, setisCoinjoin] = useState(false)
const onSubmit = (e) => {
e.preventDefault()
if (!amount || !mixdepth || !destination) {
alert('Please add details')
return
}
//maybe add await here
//if normal payment
if(isCoinjoin===false){
let wallet =JSON.parse(sessionStorage.getItem('auth')).name;
onPayment(wallet,mixdepth,amount,destination);
}
//coinjoin
else{
if(!counterparties){
alert("Please set counterparties to a non zero number");
return;
}
else{
onCoinjoin(mixdepth,amount,counterparties,destination);
alert("Coinjoin in progress");
}
const onSubmit = (e) => {
e.preventDefault()
}
setcounterparties('');
setMixdepth('');
setAmount('');
setDestination('');
setisCoinjoin(false);
if (!amount || !mixdepth || !destination) {
return alert('Please add details')
}
//maybe add await here
if (!isCoinjoin) { //if normal payment
let wallet = JSON.parse(sessionStorage.getItem('auth')).name
onPayment(wallet, mixdepth, amount, destination)
} else { //coinjoin
if (!counterparties) {
return alert('Please set counterparties to a non zero number')
} else {
onCoinjoin(mixdepth, amount, counterparties, destination)
alert('Coinjoin in progress')
}
}
return (
<div>
setcounterparties('')
setMixdepth('')
setAmount('')
setDestination('')
setisCoinjoin(false)
}
<br></br>
<div className = "heading">
Send Payment
</div>
return (
<div>
<div className="heading">
Send Payment
</div>
<form method="POST" onSubmit={onSubmit}>
<rb.Container className = "center">
<rb.Container fluid = "false" className = "form1">
<rb.Row>
<rb.Col className="label">
Receiver address:
</rb.Col>
<rb.Col>
<input type="text" name="destination" value = {destination }onChange={(e) => setDestination(e.target.value)}/>
</rb.Col>
</rb.Row>
<rb.Row className = "field">
<rb.Col className="label">
Account
</rb.Col>
<rb.Col>
<input type="text" name="mixdepth" value = {mixdepth} onChange={(e) => setMixdepth(e.target.value)} readOnly={true}/>
</rb.Col>
</rb.Row>
<rb.Row className = "field">
<rb.Col className="label">
Amount(SATS)
</rb.Col>
<rb.Col>
<input type="text" name="amount_sats" value = {amount} onChange={(e) => setAmount(e.target.value)}/>
</rb.Col>
</rb.Row>
<p></p>
<br></br>
<div className = "coinjoin">
Do you want to do a coinjoin?
<p></p>
Yes<input type="radio" name="coinjoin" onChange={(e) => setisCoinjoin(true)} />
<p></p>
No<input type="radio" name="coinjoin" onChange={(e) => setisCoinjoin(false)}/>
<p></p>
</div>
{
isCoinjoin?
<div>
<rb.Row className = "field">
<rb.Col className="label">
Counterparties
</rb.Col>
<rb.Col>
<input type="text" name="counterparties" value = {counterparties} onChange={(e)=>setcounterparties(e.target.value)}/>
</rb.Col>
<form method="POST" onSubmit={onSubmit}>
<rb.Container className="center">
<rb.Container fluid="false" className="form1">
<rb.Row>
<rb.Col className="label">
Receiver address:
</rb.Col>
<rb.Col>
<input type="text" name="destination" value={destination} onChange={(e) => setDestination(e.target.value)} />
</rb.Col>
</rb.Row>
<rb.Row className="field">
<rb.Col className="label">
Account
</rb.Col>
<rb.Col>
<input type="text" name="mixdepth" value={mixdepth} onChange={(e) => setMixdepth(e.target.value)} readOnly={true} />
</rb.Col>
</rb.Row>
<rb.Row className="field">
<rb.Col className="label">
Amount(SATS)
</rb.Col>
<rb.Col>
<input type="text" name="amount_sats" value={amount} onChange={(e) => setAmount(e.target.value)} />
</rb.Col>
</rb.Row>
</div>
:
""
}
<rb.Row className = "btn-field">
<button className="btncr" type="submit" value="Submit" ><span>Submit</span></button>
<p></p>
<br></br>
<div className="coinjoin">
Do you want to do a coinjoin?
<p></p>
Yes<input type="radio" name="coinjoin" onChange={(e) => setisCoinjoin(true)} />
<p></p>
No<input type="radio" name="coinjoin" onChange={(e) => setisCoinjoin(false)} />
<p></p>
</div>
{isCoinjoin
? <div>
<rb.Row className="field">
<rb.Col className="label">
Counterparties
</rb.Col>
<rb.Col>
<input type="text" name="counterparties" value={counterparties} onChange={(e) => setcounterparties(e.target.value)} />
</rb.Col>
</rb.Row>
</rb.Container>
</rb.Container>
</form>
</div>
)
</div>
: null
}
<rb.Row className="btn-field">
<button className="btncr" type="submit" value="Submit" ><span>Submit</span></button>
</rb.Row>
</rb.Container>
</rb.Container>
</form>
</div>
)
}
export default Payment

View file

@ -6,105 +6,92 @@ import { useLocation } from "react-router-dom";
import * as rb from 'react-bootstrap'
import './receive.css'
const Receive = ({onReceive}) => {
const location = useLocation()
const [new_address, setNewAddress] = useState('')
const Receive = ({ onReceive }) => {
const location = useLocation()
const [new_address, setNewAddress] = useState('')
const getAddress = async (mixdepth) =>{
//update request with token if backend updated
let authData = JSON.parse(sessionStorage.getItem('auth'));
let token = "Bearer "+authData.token;
let name = authData.name;
const res = await fetch(`/api/v1/wallet/${name}/address/new/${mixdepth}`,{
method:'GET',
headers: {
'Content-type': 'application/json',
'Authorization':token
},
});
const { address } = await res.json();
return address;
const getAddress = async (mixdepth) => {
//update request with token if backend updated
let authData = JSON.parse(sessionStorage.getItem('auth'));
let token = "Bearer " + authData.token;
let name = authData.name;
const res = await fetch(`/api/v1/wallet/${name}/address/new/${mixdepth}`, {
method: 'GET',
headers: {
'Content-type': 'application/json',
'Authorization': token
},
});
const { address } = await res.json();
return address;
}
useEffect(() => {
const getNewAddress = async (account) => {
const temp1 = parseInt(account, 10)
const temp = await getAddress(temp1)
setNewAddress(temp)
return
}
useEffect(()=>{
getNewAddress(location.state.account_no);
}, [location.state.account_no])
const getNewAddress = async(account) => {
const temp1 = parseInt(account,10)
const temp = await getAddress(temp1)
//window.alert(temp1)
setNewAddress(temp)
return
}
const [temp_address, setTempAddress] = useState('')
const [amount, setAmount] = useState('')
getNewAddress(location.state.account_no);
}, [location.state.account_no])
const onSubmit = (e) => {
e.preventDefault()
const [temp_address, setTempAddress] = useState('')
const [amount, setAmount] = useState('')
if (!new_address) {
return alert('Please add the address')
}
const onSubmit = (e) => {
e.preventDefault()
setTempAddress(new_address)
}
if (!new_address) {
alert('Please add the address')
return
}
setTempAddress(new_address)
}
return (
<div>
<br></br>
<div className = "heading">
Receive Funds
</div>
<form method="POST" onSubmit={onSubmit}>
<rb.Container className = "center">
<rb.Container fluid = "false" className = "form1">
<rb.Row>
<rb.Col className="label">
Address
</rb.Col>
<rb.Col>
<input type="text" name="address" value = {new_address } style = {{width: "415px"}} readOnly = {true} onChange={(e) => setNewAddress(e.target.value)}/>
</rb.Col>
</rb.Row>
<rb.Row className = "field">
<rb.Col className="label">
Amount(BTC)
</rb.Col>
<rb.Col>
<input type="text" name="amount_sats" value = {amount} style = {{width: "415px"}} onChange={(e) => setAmount(e.target.value)}/>
</rb.Col>
</rb.Row>
<rb.Row className = "btn-field">
<button className="btncr" type="submit" value="Submit" ><span>Get QR Code</span></button>
</rb.Row>
{temp_address.length > 0? (
<BitcoinQR
bitcoinAddress={temp_address}
message = ""
amount ={amount}
time = ""
exp = ""
/>):("")}
</rb.Container>
</rb.Container>
</form>
</div>
)
return (
<div>
<div className="heading">
Receive Funds
</div>
<form method="POST" onSubmit={onSubmit}>
<rb.Container className="center">
<rb.Container fluid="false" className="form1">
<rb.Row>
<rb.Col className="label">
Address
</rb.Col>
<rb.Col>
<input type="text" name="address" value={new_address} style={{ width: "415px" }} readOnly={true} onChange={(e) => setNewAddress(e.target.value)} />
</rb.Col>
</rb.Row>
<rb.Row className="field">
<rb.Col className="label">
Amount(BTC)
</rb.Col>
<rb.Col>
<input type="text" name="amount_sats" value={amount} style={{ width: "415px" }} onChange={(e) => setAmount(e.target.value)} />
</rb.Col>
</rb.Row>
<rb.Row className="btn-field">
<button className="btncr" type="submit" value="Submit" ><span>Get QR Code</span></button>
</rb.Row>
{temp_address.length > 0
? <BitcoinQR
bitcoinAddress={temp_address}
message=""
amount={amount}
time=""
exp=""
/>
: null
}
</rb.Container>
</rb.Container>
</form>
</div>
)
}
export default Receive

View file

@ -1,20 +1,20 @@
import React from 'react'
import * as rb from 'react-bootstrap'
import './wallet.css'
const Wallet = ({name,onUnlock,onLock,onDisplay}) => {
return (
<div>
<br></br>
<rb.Card style={{ width: '18rem' }} className = "wallet_cards">
<rb.Card.Body>
<rb.Card.Title>{name}</rb.Card.Title>
<rb.Button className="btn btn-primary" onClick={()=>onUnlock(name)}>Unlock</rb.Button>{' '}
<rb.Button href="/display">Open</rb.Button>{' '}
<rb.Button onClick = {()=>onLock(name)}>Lock</rb.Button>
</rb.Card.Body>
</rb.Card>
</div>
)
}
const Wallet = ({ name, isCurrent, onUnlock, onLock }) => (
<rb.Card style={{ width: '18rem' }} className="wallet_cards mb-3">
<rb.Card.Body>
<rb.Card.Title>{name}</rb.Card.Title>
{ isCurrent
? <>
<rb.Button className="btn btn-primary me-2" href="/display">Open</rb.Button>
<rb.Button className="btn btn-secondary" onClick={() => onLock(name)}>Lock</rb.Button>
</>
: <rb.Button className="btn btn-primary" onClick={() => onUnlock(name)}>Unlock</rb.Button>
}
</rb.Card.Body>
</rb.Card>
)
export default Wallet

View file

@ -1,15 +1,9 @@
import React from 'react'
import Wallet from './Wallet'
const Wallets = ({walletList,onUnlock,onLock,onDisplay}) => {
return (
<>
<p></p>
{walletList.map((wallet,index)=>{
return <Wallet key = {index} name={wallet} onUnlock = {onUnlock} onLock = {onLock} onDisplay = {onDisplay}></Wallet>
})}
</>
)
}
const Wallets = ({ walletList, currentWallet, onUnlock, onLock, onDisplay }) =>
walletList.map((wallet, index)=>
<Wallet key={index} name={wallet} isCurrent={wallet === currentWallet} onUnlock={onUnlock} onLock={onLock} onDisplay={onDisplay} />
)
export default Wallets

View file

@ -1,10 +1,10 @@
.heading{
color:rgb(15, 3, 58);
.heading {
color: rgb(15, 3, 58);
font-size: 40px;
font-weight: 450;
}
.form1{
.form1 {
margin: 0 auto;
background-color: rgb(244, 247, 253);
width: 40%;
@ -16,24 +16,23 @@
border-width: 3px;
border-style: dashed;
border-color: #e0e3f0;
}
.center{
.center {
padding: 40px;
}
.label{
.label {
text-align: left;
font-size: 20px;
color:rgb(15, 3, 58)
color: rgb(15, 3, 58)
}
.field{
.field {
padding-top: 20px;
}
.field-border{
.field-border {
border-radius: 10px;
border-width: 2px;
border-style: dashed;
@ -62,7 +61,7 @@
}
.btncr span {
position: relative;
position: relative;
z-index: 1;
color:rgb(15, 3, 58)
}
@ -84,4 +83,4 @@
.btncr:hover:after {
-webkit-transform: translateX(-9%) translateY(-25%) rotate(45deg);
transform: translateX(-9%) translateY(-25%) rotate(45deg);
}
}

View file

@ -1,18 +1,18 @@
.head{
font-size: small;
.head {
font-size: small;
}
.address_label{
text-align: right;
padding-right: 7%;
color: rgb(10, 192, 10);
.address_label {
text-align: right;
padding-right: 7%;
color: rgb(10, 192, 10);
}
.xpub{
text-align: left;
padding-left: 20px;
.xpub {
text-align: left;
padding-left: 20px;
}
.branch_body{
text-align: left;
}
text-align: left;
}

View file

@ -1,33 +1,21 @@
import React from 'react'
import * as rb from 'react-bootstrap'
import './Homepage.css'
import { Link } from 'react-router-dom';
import { Link } from 'react-router-dom'
const Homepage = () => {
return (
<>
<div className="showcase-container">
<h1 className="main-title" id="home">Joinmarket</h1>
</div>
<rb.Container className = "container1">
<rb.Row>
<rb.Col className = "column">
<div className="text-center">
<Link to="/create" className="btn btn-primary">Create Wallet</Link>
</div>
</rb.Col>
<rb.Col className = "column">
<Link to="/showWallets" className="btn btn-primary">Show Wallets</Link>
</rb.Col>
</rb.Row>
</rb.Container>
</>
)
}
const Homepage = () => (
<rb.Container className="container1">
<rb.Row>
<rb.Col className="column">
<div className="text-center">
<Link to="/create" className="btn btn-primary">Create Wallet</Link>
</div>
</rb.Col>
<rb.Col className="column">
<Link to="/showWallets" className="btn btn-primary">Show Wallets</Link>
</rb.Col>
</rb.Row>
</rb.Container>
)
export default Homepage

View file

@ -1,91 +1,91 @@
.heading{
color:rgb(15, 3, 58);
font-size: 40px;
font-weight: 450;
}
.form1{
margin: 0 auto;
background-color: rgb(244, 247, 253);
width: 50%;
padding-top: 40px;
padding-bottom: 40px;
padding-left: 40px;
padding-right: 40px;
border-radius: 10px;
border-width: 3px;
border-style: dashed;
border-color: #e0e3f0;
}
.coinjoin{
font-size: 20px;
.heading {
color:rgb(15, 3, 58);
font-size: 40px;
font-weight: 450;
}
.center{
padding: 40px;
}
.label{
text-align: left;
font-size: 20px;
color:rgb(15, 3, 58)
}
.field{
padding-top: 20px;
}
.field-border{
border-radius: 10px;
border-width: 2px;
border-style: dashed;
border-color: #e0e3f0;
}
.btn-field{
padding-top: 50px;
}
.btncr {
border: none;
border-radius: 2px;
display: block;
text-align: center;
cursor: pointer;
outline: none;
overflow: hidden;
position: relative;
font-weight: 500;
font-size: 20px;
background-color: rgb(244, 247, 253);
padding: 10px 60px;
margin: 0 auto;
box-shadow: 0 5px 15px rgba(0,0,0,0.20);
}
.btncr span {
position: relative;
z-index: 1;
color:rgb(15, 3, 58)
}
.btncr:after {
content: "";
position: absolute;
left: 0;
top: 0;
height: 300%;
width: 130%;
background: #e0e3f0;
-webkit-transition: all .5s ease-in-out;
transition: all .5s ease-in-out;
-webkit-transform: translateX(-98%) translateY(-25%) rotate(45deg);
transform: translateX(-98%) translateY(-25%) rotate(45deg);
}
.btncr:hover:after {
-webkit-transform: translateX(-9%) translateY(-25%) rotate(45deg);
transform: translateX(-9%) translateY(-25%) rotate(45deg);
}
.form1 {
margin: 0 auto;
background-color: rgb(244, 247, 253);
width: 50%;
padding-top: 40px;
padding-bottom: 40px;
padding-left: 40px;
padding-right: 40px;
border-radius: 10px;
border-width: 3px;
border-style: dashed;
border-color: #e0e3f0;
}
.coinjoin{
font-size: 20px;
}
.center{
padding: 40px;
}
.label{
text-align: left;
font-size: 20px;
color: rgb(15, 3, 58)
}
.field{
padding-top: 20px;
}
.field-border{
border-radius: 10px;
border-width: 2px;
border-style: dashed;
border-color: #e0e3f0;
}
.btn-field{
padding-top: 50px;
}
.btncr {
border: none;
border-radius: 2px;
display: block;
text-align: center;
cursor: pointer;
outline: none;
overflow: hidden;
position: relative;
font-weight: 500;
font-size: 20px;
background-color: rgb(244, 247, 253);
padding: 10px 60px;
margin: 0 auto;
box-shadow: 0 5px 15px rgba(0,0,0,0.20);
}
.btncr span {
position: relative;
z-index: 1;
color:rgb(15, 3, 58)
}
.btncr:after {
content: "";
position: absolute;
left: 0;
top: 0;
height: 300%;
width: 130%;
background: #e0e3f0;
-webkit-transition: all .5s ease-in-out;
transition: all .5s ease-in-out;
-webkit-transform: translateX(-98%) translateY(-25%) rotate(45deg);
transform: translateX(-98%) translateY(-25%) rotate(45deg);
}
.btncr:hover:after {
-webkit-transform: translateX(-9%) translateY(-25%) rotate(45deg);
transform: translateX(-9%) translateY(-25%) rotate(45deg);
}

View file

@ -1,91 +1,90 @@
.heading{
color:rgb(15, 3, 58);
font-size: 40px;
font-weight: 450;
}
.form1{
margin: 0 auto;
background-color: rgb(244, 247, 253);
width: 50%;
padding-top: 40px;
padding-bottom: 40px;
padding-left: 40px;
padding-right: 40px;
border-radius: 10px;
border-width: 3px;
border-style: dashed;
border-color: #e0e3f0;
}
.coinjoin{
font-size: 20px;
.heading {
color:rgb(15, 3, 58);
font-size: 40px;
font-weight: 450;
}
.center{
padding: 40px;
}
.label{
text-align: left;
font-size: 20px;
color:rgb(15, 3, 58)
}
.field{
padding-top: 20px;
}
.field-border{
border-radius: 10px;
border-width: 2px;
border-style: dashed;
border-color: #e0e3f0;
}
.btn-field{
padding-top: 50px;
}
.btncr {
border: none;
border-radius: 2px;
display: block;
text-align: center;
cursor: pointer;
outline: none;
overflow: hidden;
position: relative;
font-weight: 500;
font-size: 20px;
background-color: rgb(244, 247, 253);
padding: 10px 60px;
margin: 0 auto;
box-shadow: 0 5px 15px rgba(0,0,0,0.20);
}
.btncr span {
position: relative;
z-index: 1;
color:rgb(15, 3, 58)
}
.btncr:after {
content: "";
position: absolute;
left: 0;
top: 0;
height: 300%;
width: 130%;
background: #e0e3f0;
-webkit-transition: all .5s ease-in-out;
transition: all .5s ease-in-out;
-webkit-transform: translateX(-98%) translateY(-25%) rotate(45deg);
transform: translateX(-98%) translateY(-25%) rotate(45deg);
}
.btncr:hover:after {
-webkit-transform: translateX(-9%) translateY(-25%) rotate(45deg);
transform: translateX(-9%) translateY(-25%) rotate(45deg);
}
.form1 {
margin: 0 auto;
background-color: rgb(244, 247, 253);
width: 50%;
padding-top: 40px;
padding-bottom: 40px;
padding-left: 40px;
padding-right: 40px;
border-radius: 10px;
border-width: 3px;
border-style: dashed;
border-color: #e0e3f0;
}
.coinjoin{
font-size: 20px;
}
.center {
padding: 40px;
}
.label {
text-align: left;
font-size: 20px;
color:rgb(15, 3, 58)
}
.field {
padding-top: 20px;
}
.field-border {
border-radius: 10px;
border-width: 2px;
border-style: dashed;
border-color: #e0e3f0;
}
.btn-field {
padding-top: 50px;
}
.btncr {
border: none;
border-radius: 2px;
display: block;
text-align: center;
cursor: pointer;
outline: none;
overflow: hidden;
position: relative;
font-weight: 500;
font-size: 20px;
background-color: rgb(244, 247, 253);
padding: 10px 60px;
margin: 0 auto;
box-shadow: 0 5px 15px rgba(0,0,0,0.20);
}
.btncr span {
position: relative;
z-index: 1;
color: rgb(15, 3, 58)
}
.btncr:after {
content: "";
position: absolute;
left: 0;
top: 0;
height: 300%;
width: 130%;
background: #e0e3f0;
-webkit-transition: all .5s ease-in-out;
transition: all .5s ease-in-out;
-webkit-transform: translateX(-98%) translateY(-25%) rotate(45deg);
transform: translateX(-98%) translateY(-25%) rotate(45deg);
}
.btncr:hover:after {
-webkit-transform: translateX(-9%) translateY(-25%) rotate(45deg);
transform: translateX(-9%) translateY(-25%) rotate(45deg);
}

View file

@ -1,87 +1,87 @@
.heading{
color:rgb(15, 3, 58);
font-size: 40px;
font-weight: 450;
}
.form1{
margin: 0 auto;
background-color: rgb(244, 247, 253);
width: 60%;
padding-top: 40px;
padding-bottom: 40px;
padding-left: 40px;
padding-right: 40px;
border-radius: 10px;
border-width: 3px;
border-style: dashed;
border-color: #e0e3f0;
}
.center{
padding: 40px;
}
.label{
text-align: left;
font-size: 20px;
color:rgb(15, 3, 58)
}
.field{
padding-top: 20px;
}
.field-border{
border-radius: 10px;
border-width: 2px;
border-style: dashed;
border-color: #e0e3f0;
}
.btn-field{
padding-top: 50px;
}
.btncr {
border: none;
border-radius: 2px;
display: block;
text-align: center;
cursor: pointer;
outline: none;
overflow: hidden;
position: relative;
font-weight: 500;
font-size: 20px;
background-color: rgb(244, 247, 253);
padding: 10px 60px;
margin: 0 auto;
box-shadow: 0 5px 15px rgba(0,0,0,0.20);
}
.btncr span {
position: relative;
z-index: 1;
color:rgb(15, 3, 58)
}
.btncr:after {
content: "";
position: absolute;
left: 0;
top: 0;
height: 300%;
width: 130%;
background: #e0e3f0;
-webkit-transition: all .5s ease-in-out;
transition: all .5s ease-in-out;
-webkit-transform: translateX(-98%) translateY(-25%) rotate(45deg);
transform: translateX(-98%) translateY(-25%) rotate(45deg);
}
.btncr:hover:after {
-webkit-transform: translateX(-9%) translateY(-25%) rotate(45deg);
transform: translateX(-9%) translateY(-25%) rotate(45deg);
}
.heading {
color: rgb(15, 3, 58);
font-size: 40px;
font-weight: 450;
}
.form1{
margin: 0 auto;
background-color: rgb(244, 247, 253);
width: 60%;
padding-top: 40px;
padding-bottom: 40px;
padding-left: 40px;
padding-right: 40px;
border-radius: 10px;
border-width: 3px;
border-style: dashed;
border-color: #e0e3f0;
}
.center {
padding: 40px;
}
.label {
text-align: left;
font-size: 20px;
color:rgb(15, 3, 58)
}
.field {
padding-top: 20px;
}
.field-border {
border-radius: 10px;
border-width: 2px;
border-style: dashed;
border-color: #e0e3f0;
}
.btn-field {
padding-top: 50px;
}
.btncr {
border: none;
border-radius: 2px;
display: block;
text-align: center;
cursor: pointer;
outline: none;
overflow: hidden;
position: relative;
font-weight: 500;
font-size: 20px;
background-color: rgb(244, 247, 253);
padding: 10px 60px;
margin: 0 auto;
box-shadow: 0 5px 15px rgba(0,0,0,0.20);
}
.btncr span {
position: relative;
z-index: 1;
color:rgb(15, 3, 58)
}
.btncr:after {
content: "";
position: absolute;
left: 0;
top: 0;
height: 300%;
width: 130%;
background: #e0e3f0;
-webkit-transition: all .5s ease-in-out;
transition: all .5s ease-in-out;
-webkit-transform: translateX(-98%) translateY(-25%) rotate(45deg);
transform: translateX(-98%) translateY(-25%) rotate(45deg);
}
.btncr:hover:after {
-webkit-transform: translateX(-9%) translateY(-25%) rotate(45deg);
transform: translateX(-9%) translateY(-25%) rotate(45deg);
}

View file

@ -1,22 +1,21 @@
import { useEffect, useRef } from 'react';
import { useEffect, useRef } from 'react'
const useInterval = (callback, delay) => {
const savedCallback = useRef();
useEffect(() => {
savedCallback.current = callback;
savedCallback.current = callback
}, [callback]);
useEffect(() => {
function tick() {
savedCallback.current();
savedCallback.current()
}
if (delay !== null) {
const id = setInterval(tick, delay);
return () => clearInterval(id);
const id = setInterval(tick, delay)
return () => clearInterval(id)
}
}, [delay]);
}, [delay])
}
export default useInterval;
export default useInterval

View file

@ -1,3 +1,3 @@
.wallet_cards{
margin: 0 auto;
}
.wallet_cards {
margin: 0 auto;
}

View file

@ -1,13 +1,10 @@
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
}

View file

@ -5,6 +5,7 @@ import App from './App';
import reportWebVitals from './reportWebVitals';
import 'bootstrap/dist/css/bootstrap.min.css';
import { setGlobal } from 'reactn';
// Set an initial global state directly:
setGlobal({
currentStatusMessage: "loading",
@ -14,7 +15,7 @@ setGlobal({
});
ReactDOM.render(
<App />
,
document.getElementById('root')