├── joinmarket
├── src
│ ├── components
│ │ ├── button.css
│ │ ├── wallet.css
│ │ ├── Homepage.css
│ │ ├── Button.jsx
│ │ ├── displayMixdepth.css
│ │ ├── Wallets.jsx
│ │ ├── utils.jsx
│ │ ├── DisplayUTXOs.jsx
│ │ ├── Wallet.jsx
│ │ ├── homepage.jsx
│ │ ├── createWallet.css
│ │ ├── receive.css
│ │ ├── maker.css
│ │ ├── payment.css
│ │ ├── Maker.jsx
│ │ ├── CreateWallet.jsx
│ │ ├── DisplayWallet.jsx
│ │ ├── Receive.jsx
│ │ ├── Payment.jsx
│ │ └── DisplayMixdepth.jsx
│ ├── setupTests.js
│ ├── App.test.js
│ ├── index.css
│ ├── reportWebVitals.js
│ ├── App.css
│ ├── index.js
│ ├── twitter.svg
│ ├── github.svg
│ ├── logo.svg
│ └── App.js
├── public
│ ├── robots.txt
│ ├── favicon.ico
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── index.html
├── .gitignore
├── package.json
└── README.md
└── README.md
/joinmarket/src/components/button.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/joinmarket/src/components/wallet.css:
--------------------------------------------------------------------------------
1 | .wallet_cards{
2 | margin: 0 auto;
3 | }
--------------------------------------------------------------------------------
/joinmarket/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/joinmarket/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JoinMarket-Org/jm-web-client/HEAD/joinmarket/public/favicon.ico
--------------------------------------------------------------------------------
/joinmarket/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JoinMarket-Org/jm-web-client/HEAD/joinmarket/public/logo192.png
--------------------------------------------------------------------------------
/joinmarket/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JoinMarket-Org/jm-web-client/HEAD/joinmarket/public/logo512.png
--------------------------------------------------------------------------------
/joinmarket/src/components/Homepage.css:
--------------------------------------------------------------------------------
1 | .container1{
2 | height: 100vh;
3 | padding-top: 100px;
4 | }
5 |
6 |
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Web client for joinmarket
2 |
3 | This project was an earlier proof-of-concept, please go to: https://github.com/joinmarket-webui/joinmarket-webui
4 |
--------------------------------------------------------------------------------
/joinmarket/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/joinmarket/src/App.test.js:
--------------------------------------------------------------------------------
1 | import { render, screen } from '@testing-library/react';
2 | import App from './App';
3 |
4 | test('renders learn react link', () => {
5 | render( );
6 | const linkElement = screen.getByText(/learn react/i);
7 | expect(linkElement).toBeInTheDocument();
8 | });
9 |
--------------------------------------------------------------------------------
/joinmarket/src/components/Button.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import "./button.css";
3 |
4 | export const Button = ({name,children, type, onClick, buttonStyle, buttonSize}) => {
5 | return (
6 | onClick(name)} type = {type}>
7 | {children}
8 |
9 | )
10 | }
11 |
12 |
--------------------------------------------------------------------------------
/joinmarket/src/components/displayMixdepth.css:
--------------------------------------------------------------------------------
1 | .head{
2 | font-size: small;
3 | }
4 |
5 | .address_label{
6 | text-align: right;
7 | padding-right: 7%;
8 | color: rgb(10, 192, 10);
9 | }
10 |
11 | .xpub{
12 | text-align: left;
13 | padding-left: 20px;
14 | }
15 |
16 | .branch_body{
17 | text-align: left;
18 | }
--------------------------------------------------------------------------------
/joinmarket/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/joinmarket/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/joinmarket/src/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = onPerfEntry => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------
/joinmarket/src/components/Wallets.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import Wallet from './Wallet'
3 | const Wallets = ({walletList,onUnlock,onLock,onDisplay}) => {
4 |
5 | return (
6 | <>
7 |
8 | {walletList.map((wallet,index)=>{
9 | return
10 | })}
11 | >
12 | )
13 | }
14 |
15 | export default Wallets
16 |
--------------------------------------------------------------------------------
/joinmarket/src/components/utils.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect, useRef } from 'react';
2 |
3 | const useInterval = (callback, delay) => {
4 |
5 | const savedCallback = useRef();
6 |
7 | useEffect(() => {
8 | savedCallback.current = callback;
9 | }, [callback]);
10 |
11 |
12 | useEffect(() => {
13 | function tick() {
14 | savedCallback.current();
15 | }
16 | if (delay !== null) {
17 | const id = setInterval(tick, delay);
18 | return () => clearInterval(id);
19 | }
20 | }, [delay]);
21 | }
22 |
23 | export default useInterval;
--------------------------------------------------------------------------------
/joinmarket/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/joinmarket/src/components/DisplayUTXOs.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | const DisplayUTXOs = ({utxoID,utxo}) => {
4 | return (
5 |
6 |
7 |
8 |
9 |
Address: {utxo.address}
10 |
11 |
Value(Sats): {utxo.value}
12 |
13 |
Confirmations: {utxo.confirmations}
14 |
15 |
Mixdepth: {utxo.mixdepth}
16 |
17 |
18 | )
19 | }
20 |
21 | export default DisplayUTXOs;
22 |
23 |
--------------------------------------------------------------------------------
/joinmarket/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/joinmarket/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import reportWebVitals from './reportWebVitals';
6 | import 'bootstrap/dist/css/bootstrap.min.css';
7 | import { setGlobal } from 'reactn';
8 | // Set an initial global state directly:
9 | setGlobal({
10 | currentStatusMessage: "loading",
11 | makerStarted: false,
12 | walletName: "(waiting..)",
13 | coinjoinInProcess: false
14 | });
15 |
16 | ReactDOM.render(
17 |
18 |
19 | ,
20 | document.getElementById('root')
21 | );
22 |
23 | // If you want to start measuring performance in your app, pass a function
24 | // to log results (for example: reportWebVitals(console.log))
25 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
26 | reportWebVitals();
27 |
--------------------------------------------------------------------------------
/joinmarket/src/components/Wallet.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Button } from './Button'
3 | import {Link} from 'react-router-dom'
4 | import * as rb from 'react-bootstrap'
5 | import './wallet.css'
6 | const Wallet = ({name,onUnlock,onLock,onDisplay}) => {
7 | return (
8 |
9 |
10 |
11 |
12 | {name}
13 | onUnlock(name)}>Unlock {' '}
14 | Open {' '}
15 | onLock(name)}>Lock
16 |
17 |
18 |
19 | )
20 | }
21 |
22 | export default Wallet
23 |
--------------------------------------------------------------------------------
/joinmarket/src/twitter.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/joinmarket/src/components/homepage.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import * as rb from 'react-bootstrap'
3 | import './Homepage.css'
4 | import { BrowserRouter as Router, Link, Route ,Switch} from 'react-router-dom';
5 |
6 | const Homepage = () => {
7 |
8 | return (
9 | <>
10 |
11 |
12 |
Joinmarket
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | Create Wallet
23 |
24 |
25 |
26 |
27 | Show Wallets
28 |
29 |
30 |
31 |
32 | >
33 | )
34 | }
35 |
36 | export default Homepage
37 |
--------------------------------------------------------------------------------
/joinmarket/src/github.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/joinmarket/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "joinmarket",
3 | "version": "0.1.0",
4 | "private": true,
5 | "proxy": "https://localhost:28183",
6 | "dependencies": {
7 | "@ibunker/bitcoin-react": "^0.1.13-cd",
8 | "@testing-library/jest-dom": "^5.11.4",
9 | "@testing-library/react": "^11.1.0",
10 | "@testing-library/user-event": "^12.1.10",
11 | "bootstrap": "^5.1.0",
12 | "moving-letters": "^1.0.1",
13 | "react": "^17.0.2",
14 | "react-bootstrap": "^2.0.0-beta.6",
15 | "react-dom": "^17.0.2",
16 | "react-router-dom": "^5.2.0",
17 | "react-scripts": "4.0.3",
18 | "reactn": "^2.2.7",
19 | "web-vitals": "^1.0.1"
20 | },
21 | "scripts": {
22 | "start": "react-scripts start",
23 | "build": "react-scripts build",
24 | "test": "react-scripts test",
25 | "eject": "react-scripts eject"
26 | },
27 | "eslintConfig": {
28 | "extends": [
29 | "react-app",
30 | "react-app/jest"
31 | ]
32 | },
33 | "browserslist": {
34 | "production": [
35 | ">0.2%",
36 | "not dead",
37 | "not op_mini all"
38 | ],
39 | "development": [
40 | "last 1 chrome version",
41 | "last 1 firefox version",
42 | "last 1 safari version"
43 | ]
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/joinmarket/src/components/createWallet.css:
--------------------------------------------------------------------------------
1 | .heading{
2 | color:rgb(15, 3, 58);
3 | font-size: 40px;
4 | font-weight: 450;
5 | }
6 |
7 | .form1{
8 | margin: 0 auto;
9 | background-color: rgb(244, 247, 253);
10 | width: 40%;
11 | padding-top: 40px;
12 | padding-bottom: 40px;
13 | padding-left: 40px;
14 | padding-right: 40px;
15 | border-radius: 10px;
16 | border-width: 3px;
17 | border-style: dashed;
18 | border-color: #e0e3f0;
19 |
20 | }
21 |
22 | .center{
23 | padding: 40px;
24 | }
25 |
26 | .label{
27 | text-align: left;
28 | font-size: 20px;
29 | color:rgb(15, 3, 58)
30 | }
31 |
32 | .field{
33 | padding-top: 20px;
34 | }
35 |
36 | .field-border{
37 | border-radius: 10px;
38 | border-width: 2px;
39 | border-style: dashed;
40 | border-color: #e0e3f0;
41 | }
42 |
43 | .btn-field{
44 | padding-top: 50px;
45 | }
46 |
47 | .btncr {
48 | border: none;
49 | border-radius: 2px;
50 | display: block;
51 | text-align: center;
52 | cursor: pointer;
53 | outline: none;
54 | overflow: hidden;
55 | position: relative;
56 | font-weight: 500;
57 | font-size: 20px;
58 | background-color: rgb(244, 247, 253);
59 | padding: 10px 60px;
60 | margin: 0 auto;
61 | box-shadow: 0 5px 15px rgba(0,0,0,0.20);
62 | }
63 |
64 | .btncr span {
65 | position: relative;
66 | z-index: 1;
67 | color:rgb(15, 3, 58)
68 | }
69 |
70 | .btncr:after {
71 | content: "";
72 | position: absolute;
73 | left: 0;
74 | top: 0;
75 | height: 300%;
76 | width: 130%;
77 | background: #e0e3f0;
78 | -webkit-transition: all .5s ease-in-out;
79 | transition: all .5s ease-in-out;
80 | -webkit-transform: translateX(-98%) translateY(-25%) rotate(45deg);
81 | transform: translateX(-98%) translateY(-25%) rotate(45deg);
82 | }
83 |
84 | .btncr:hover:after {
85 | -webkit-transform: translateX(-9%) translateY(-25%) rotate(45deg);
86 | transform: translateX(-9%) translateY(-25%) rotate(45deg);
87 | }
--------------------------------------------------------------------------------
/joinmarket/src/components/receive.css:
--------------------------------------------------------------------------------
1 | .heading{
2 | color:rgb(15, 3, 58);
3 | font-size: 40px;
4 | font-weight: 450;
5 | }
6 |
7 | .form1{
8 | margin: 0 auto;
9 | background-color: rgb(244, 247, 253);
10 | width: 60%;
11 | padding-top: 40px;
12 | padding-bottom: 40px;
13 | padding-left: 40px;
14 | padding-right: 40px;
15 | border-radius: 10px;
16 | border-width: 3px;
17 | border-style: dashed;
18 | border-color: #e0e3f0;
19 |
20 | }
21 |
22 | .center{
23 | padding: 40px;
24 | }
25 |
26 | .label{
27 | text-align: left;
28 | font-size: 20px;
29 | color:rgb(15, 3, 58)
30 | }
31 |
32 | .field{
33 | padding-top: 20px;
34 | }
35 |
36 | .field-border{
37 | border-radius: 10px;
38 | border-width: 2px;
39 | border-style: dashed;
40 | border-color: #e0e3f0;
41 | }
42 |
43 | .btn-field{
44 | padding-top: 50px;
45 | }
46 |
47 | .btncr {
48 | border: none;
49 | border-radius: 2px;
50 | display: block;
51 | text-align: center;
52 | cursor: pointer;
53 | outline: none;
54 | overflow: hidden;
55 | position: relative;
56 | font-weight: 500;
57 | font-size: 20px;
58 | background-color: rgb(244, 247, 253);
59 | padding: 10px 60px;
60 | margin: 0 auto;
61 | box-shadow: 0 5px 15px rgba(0,0,0,0.20);
62 | }
63 |
64 | .btncr span {
65 | position: relative;
66 | z-index: 1;
67 | color:rgb(15, 3, 58)
68 | }
69 |
70 | .btncr:after {
71 | content: "";
72 | position: absolute;
73 | left: 0;
74 | top: 0;
75 | height: 300%;
76 | width: 130%;
77 | background: #e0e3f0;
78 | -webkit-transition: all .5s ease-in-out;
79 | transition: all .5s ease-in-out;
80 | -webkit-transform: translateX(-98%) translateY(-25%) rotate(45deg);
81 | transform: translateX(-98%) translateY(-25%) rotate(45deg);
82 | }
83 |
84 | .btncr:hover:after {
85 | -webkit-transform: translateX(-9%) translateY(-25%) rotate(45deg);
86 | transform: translateX(-9%) translateY(-25%) rotate(45deg);
87 | }
--------------------------------------------------------------------------------
/joinmarket/src/components/maker.css:
--------------------------------------------------------------------------------
1 | .heading{
2 | color:rgb(15, 3, 58);
3 | font-size: 40px;
4 | font-weight: 450;
5 | }
6 |
7 | .form1{
8 | margin: 0 auto;
9 | background-color: rgb(244, 247, 253);
10 | width: 50%;
11 | padding-top: 40px;
12 | padding-bottom: 40px;
13 | padding-left: 40px;
14 | padding-right: 40px;
15 | border-radius: 10px;
16 | border-width: 3px;
17 | border-style: dashed;
18 | border-color: #e0e3f0;
19 |
20 | }
21 |
22 | .coinjoin{
23 | font-size: 20px;
24 | }
25 |
26 | .center{
27 | padding: 40px;
28 | }
29 |
30 | .label{
31 | text-align: left;
32 | font-size: 20px;
33 | color:rgb(15, 3, 58)
34 | }
35 |
36 | .field{
37 | padding-top: 20px;
38 | }
39 |
40 | .field-border{
41 | border-radius: 10px;
42 | border-width: 2px;
43 | border-style: dashed;
44 | border-color: #e0e3f0;
45 | }
46 |
47 | .btn-field{
48 | padding-top: 50px;
49 | }
50 |
51 | .btncr {
52 | border: none;
53 | border-radius: 2px;
54 | display: block;
55 | text-align: center;
56 | cursor: pointer;
57 | outline: none;
58 | overflow: hidden;
59 | position: relative;
60 | font-weight: 500;
61 | font-size: 20px;
62 | background-color: rgb(244, 247, 253);
63 | padding: 10px 60px;
64 | margin: 0 auto;
65 | box-shadow: 0 5px 15px rgba(0,0,0,0.20);
66 | }
67 |
68 | .btncr span {
69 | position: relative;
70 | z-index: 1;
71 | color:rgb(15, 3, 58)
72 | }
73 |
74 | .btncr:after {
75 | content: "";
76 | position: absolute;
77 | left: 0;
78 | top: 0;
79 | height: 300%;
80 | width: 130%;
81 | background: #e0e3f0;
82 | -webkit-transition: all .5s ease-in-out;
83 | transition: all .5s ease-in-out;
84 | -webkit-transform: translateX(-98%) translateY(-25%) rotate(45deg);
85 | transform: translateX(-98%) translateY(-25%) rotate(45deg);
86 | }
87 |
88 | .btncr:hover:after {
89 | -webkit-transform: translateX(-9%) translateY(-25%) rotate(45deg);
90 | transform: translateX(-9%) translateY(-25%) rotate(45deg);
91 | }
--------------------------------------------------------------------------------
/joinmarket/src/components/payment.css:
--------------------------------------------------------------------------------
1 | .heading{
2 | color:rgb(15, 3, 58);
3 | font-size: 40px;
4 | font-weight: 450;
5 | }
6 |
7 | .form1{
8 | margin: 0 auto;
9 | background-color: rgb(244, 247, 253);
10 | width: 50%;
11 | padding-top: 40px;
12 | padding-bottom: 40px;
13 | padding-left: 40px;
14 | padding-right: 40px;
15 | border-radius: 10px;
16 | border-width: 3px;
17 | border-style: dashed;
18 | border-color: #e0e3f0;
19 |
20 | }
21 |
22 | .coinjoin{
23 | font-size: 20px;
24 | }
25 |
26 | .center{
27 | padding: 40px;
28 | }
29 |
30 | .label{
31 | text-align: left;
32 | font-size: 20px;
33 | color:rgb(15, 3, 58)
34 | }
35 |
36 | .field{
37 | padding-top: 20px;
38 | }
39 |
40 | .field-border{
41 | border-radius: 10px;
42 | border-width: 2px;
43 | border-style: dashed;
44 | border-color: #e0e3f0;
45 | }
46 |
47 | .btn-field{
48 | padding-top: 50px;
49 | }
50 |
51 | .btncr {
52 | border: none;
53 | border-radius: 2px;
54 | display: block;
55 | text-align: center;
56 | cursor: pointer;
57 | outline: none;
58 | overflow: hidden;
59 | position: relative;
60 | font-weight: 500;
61 | font-size: 20px;
62 | background-color: rgb(244, 247, 253);
63 | padding: 10px 60px;
64 | margin: 0 auto;
65 | box-shadow: 0 5px 15px rgba(0,0,0,0.20);
66 | }
67 |
68 | .btncr span {
69 | position: relative;
70 | z-index: 1;
71 | color:rgb(15, 3, 58)
72 | }
73 |
74 | .btncr:after {
75 | content: "";
76 | position: absolute;
77 | left: 0;
78 | top: 0;
79 | height: 300%;
80 | width: 130%;
81 | background: #e0e3f0;
82 | -webkit-transition: all .5s ease-in-out;
83 | transition: all .5s ease-in-out;
84 | -webkit-transform: translateX(-98%) translateY(-25%) rotate(45deg);
85 | transform: translateX(-98%) translateY(-25%) rotate(45deg);
86 | }
87 |
88 | .btncr:hover:after {
89 | -webkit-transform: translateX(-9%) translateY(-25%) rotate(45deg);
90 | transform: translateX(-9%) translateY(-25%) rotate(45deg);
91 | }
--------------------------------------------------------------------------------
/joinmarket/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
18 |
19 |
23 |
24 |
33 | React App
34 |
35 |
36 | You need to enable JavaScript to run this app.
37 |
38 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/joinmarket/src/components/Maker.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { useHistory } from 'react-router-dom';
3 | import { useState } from 'react'
4 | import { useGlobal } from 'reactn';
5 |
6 | const Maker = ({onStart,onStop}) => {
7 |
8 | const [txFee,setTxFee] = useState('')
9 | const [cjfeeAbs,setCjfeeabs] = useState('')
10 | const [cjfeeRel,setCjfeerel] = useState('')
11 | const [orderType,setOrdertype] = useState('')
12 | const [minsize,setMinsize] = useState('')
13 |
14 |
15 | const [makerStarted, setmakerStarted] = useGlobal("makerStarted");
16 |
17 | const [submitVal,setSubmitVal] = useState('Start Maker Service')
18 |
19 | const history = useHistory();
20 |
21 | const onSubmit = (e) => {
22 | e.preventDefault()
23 |
24 |
25 |
26 | if(makerStarted === false){
27 | console.log('b')
28 | if (!cjfeeRel) {
29 | alert('Please add details')
30 | return;
31 | }
32 | onStart(0,0,cjfeeRel,'sw0reloffer',1000);
33 | setCjfeerel('')
34 | alert("Attempting to start the yield generator. Check the status bar for updates.");
35 | setSubmitVal('Stop Maker Service')
36 |
37 | }
38 | else{
39 | console.log('c')
40 | onStop();
41 | setSubmitVal('Start Maker Service')
42 |
43 | }
44 | let path = `/display`;
45 | history.push(path);
46 |
47 |
48 | }
49 | return (
50 |
51 |
Maker Service
52 |
70 |
71 | )
72 | }
73 |
74 | export default Maker
75 |
--------------------------------------------------------------------------------
/joinmarket/src/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/joinmarket/src/components/CreateWallet.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { useState } from 'react'
3 | import './createWallet.css'
4 | import * as rb from 'react-bootstrap'
5 |
6 | const CreateWallet = ({onCreate}) => {
7 |
8 | const [wallet,setWallet] = useState('')
9 | const [password,setPassword]=useState('')
10 |
11 | const onSubmit = (e) => {
12 | e.preventDefault()
13 |
14 | if (!wallet || !password) {
15 | alert('Please add details')
16 | return;
17 | }
18 |
19 | onCreate(wallet,password)
20 | setWallet('')
21 | setPassword('')
22 | }
23 | return (
24 |
25 |
26 |
27 |
28 |
29 | Create Wallet
30 |
31 |
32 |
61 |
62 | {/*
*/}
80 |
81 | )
82 | }
83 |
84 | export default CreateWallet
85 |
--------------------------------------------------------------------------------
/joinmarket/src/components/DisplayWallet.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {useState,useEffect} from 'react'
3 | import { Button } from './Button'
4 | import DisplayMixdepth from './DisplayMixdepth'
5 | import DisplayUTXOs from './DisplayUTXOs'
6 |
7 | const DisplayWallet = ({listWalletInfo,onSend,listUTXOs}) => {
8 | const [wallet_info,setWalletInfo] = useState([])
9 | const [UTXOHistory,setUTXOHistory] = useState({})
10 | const [showUTXO,setShowUTXO] = useState(false);
11 | // Websocket object with scope of DisplayWallet - we don't initialize
12 | // yet because it auto-opens, and we can only open once
13 | // we have authenticated:
14 | var ws;
15 | useEffect(()=>{
16 | const name = JSON.parse(sessionStorage.getItem('auth')).name;
17 | const token = JSON.parse(sessionStorage.getItem('auth')).token;
18 | ws = new WebSocket("wss://127.0.0.1:28283");
19 | ws.onopen = (event) => {
20 | console.log("connected to websocket");
21 | ws.send(token);
22 | }
23 | ws.onmessage = (event) => {
24 | // For now we only have one message type,
25 | // namely the transaction notification:
26 | // For now, note that since the `getUtxos` function
27 | // is called on every render of the display page,
28 | // we don't need to somehow use this data other
29 | // than as some kind of popup/status bar notifier.
30 | // In future it might be possible to use the detailed
31 | // transaction deserialization passed in this notification,
32 | // for something.
33 | var wsdata = JSON.parse(event.data);
34 | alert("Websocket sent: " + wsdata.txid);
35 | }
36 | const getWalletInfo = async()=>{
37 | const wallet_info = await listWalletInfo(name);
38 | console.log(wallet_info);
39 | setWalletInfo(wallet_info);
40 | }
41 |
42 | const getUTXOs = async()=>{
43 | const utxos = await listUTXOs();
44 | setUTXOHistory(utxos)
45 | console.log(utxos)
46 | }
47 |
48 | getWalletInfo();
49 | getUTXOs();
50 | },[])
51 |
52 | return (
53 |
54 | Wallet Details
55 |
56 | {wallet_info.map((walletInfo,index)=>{
57 | return
58 | })}
59 |
60 |
{setShowUTXO(!showUTXO)}}>{showUTXO?"Hide UTXOs":"Show UTXOs"}
61 |
62 |
63 | {
64 | showUTXO?
65 | Object.entries(UTXOHistory).map(([key, val])=>
66 |
67 | )
68 |
69 | : ""
70 | }
71 |
72 | )
73 | }
74 |
75 | export default DisplayWallet
76 |
--------------------------------------------------------------------------------
/joinmarket/README.md:
--------------------------------------------------------------------------------
1 | # Getting Started with Create React App
2 |
3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
4 |
5 | ## Available Scripts
6 |
7 | In the project directory, you can run:
8 |
9 | ### `yarn start`
10 |
11 | Runs the app in the development mode.\
12 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
13 |
14 | The page will reload if you make edits.\
15 | You will also see any lint errors in the console.
16 |
17 | ### `yarn test`
18 |
19 | Launches the test runner in the interactive watch mode.\
20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
21 |
22 | ### `yarn build`
23 |
24 | Builds the app for production to the `build` folder.\
25 | It correctly bundles React in production mode and optimizes the build for the best performance.
26 |
27 | The build is minified and the filenames include the hashes.\
28 | Your app is ready to be deployed!
29 |
30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
31 |
32 | ### `yarn eject`
33 |
34 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!**
35 |
36 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
37 |
38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
39 |
40 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
41 |
42 | ## Learn More
43 |
44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
45 |
46 | To learn React, check out the [React documentation](https://reactjs.org/).
47 |
48 | ### Code Splitting
49 |
50 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
51 |
52 | ### Analyzing the Bundle Size
53 |
54 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
55 |
56 | ### Making a Progressive Web App
57 |
58 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
59 |
60 | ### Advanced Configuration
61 |
62 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
63 |
64 | ### Deployment
65 |
66 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
67 |
68 | ### `yarn build` fails to minify
69 |
70 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
71 |
--------------------------------------------------------------------------------
/joinmarket/src/components/Receive.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { useState, useEffect } from 'react'
3 | import { BitcoinQR } from '@ibunker/bitcoin-react';
4 | import '@ibunker/bitcoin-react/dist/index.css';
5 | import { useLocation } from "react-router-dom";
6 | import * as rb from 'react-bootstrap'
7 | import './receive.css'
8 |
9 | const Receive = ({onReceive}) => {
10 | const location = useLocation()
11 | const [new_address, setNewAddress] = useState('')
12 |
13 | const getAddress = async(mixdepth)=>{
14 | //update request with token if backend updated
15 | let authData = JSON.parse(sessionStorage.getItem('auth'));
16 | let token = "Bearer "+authData.token;
17 | let name = authData.name;
18 | const res = await fetch(`/api/v1/wallet/${name}/address/new/${mixdepth}`,{
19 | method:'GET',
20 | headers: {
21 | 'Content-type': 'application/json',
22 | 'Authorization':token
23 | },
24 | });
25 | const data = await res.json();
26 | console.log(data)
27 | return (data[0].address);
28 |
29 | }
30 |
31 | useEffect(()=>{
32 |
33 | const getNewAddress = async(account) => {
34 | const temp1 = parseInt(account,10)
35 | const temp = await getAddress(temp1)
36 | //window.alert(temp1)
37 | setNewAddress(temp)
38 | return
39 | }
40 |
41 | getNewAddress(location.state.account_no);
42 | },[])
43 |
44 | const [temp_address, setTempAddress] = useState('')
45 | const [amount, setAmount] = useState('')
46 |
47 | const onSubmit = (e) => {
48 | e.preventDefault()
49 |
50 | if (!new_address) {
51 | alert('Please add the address')
52 | return
53 | }
54 |
55 | setTempAddress(new_address)
56 |
57 | }
58 |
59 | return (
60 |
61 |
62 |
63 |
64 | Recieve Funds
65 |
66 |
67 |
108 |
109 | )
110 | }
111 |
112 | export default Receive
113 |
--------------------------------------------------------------------------------
/joinmarket/src/components/Payment.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { useState } from 'react'
3 | import { useLocation } from "react-router-dom"
4 | import './payment.css'
5 | import * as rb from 'react-bootstrap'
6 |
7 | const Payment = ({onPayment,onCoinjoin}) => {
8 | const location = useLocation()
9 | const [destination, setDestination] = useState('')
10 | const [amount, setAmount] = useState('')
11 | const [mixdepth, setMixdepth] = useState(location.state.account_no)
12 | const [counterparties,setcounterparties] = useState('');
13 | const [isCoinjoin,setisCoinjoin] = useState(false);
14 |
15 | const onSubmit = (e) => {
16 | e.preventDefault()
17 |
18 | if (!amount || !mixdepth || !destination) {
19 | alert('Please add details')
20 | return
21 | }
22 | //maybe add await here
23 | //if normal payment
24 | if(isCoinjoin===false){
25 | let wallet =JSON.parse(sessionStorage.getItem('auth')).name;
26 | onPayment(wallet,mixdepth,amount,destination);
27 | }
28 | //coinjoin
29 | else{
30 | if(!counterparties){
31 | alert("Please set counterparties to a non zero number");
32 |
33 | return;
34 | }
35 | else{
36 | onCoinjoin(mixdepth,amount,counterparties,destination);
37 | alert("Coinjoin in progress");
38 | }
39 |
40 | }
41 |
42 | setcounterparties('');
43 | setMixdepth('');
44 | setAmount('');
45 | setDestination('');
46 | setisCoinjoin(false);
47 |
48 |
49 |
50 |
51 | }
52 |
53 | return (
54 |
55 |
56 |
57 |
58 | Send Payment
59 |
60 |
61 |
131 |
132 | )
133 | }
134 |
135 | export default Payment
136 |
--------------------------------------------------------------------------------
/joinmarket/src/components/DisplayMixdepth.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Button } from './Button'
3 | import './displayMixdepth.css'
4 | import { BrowserRouter as Router, Link, Route ,Switch} from 'react-router-dom';
5 | import * as rb from 'react-bootstrap'
6 |
7 | const DisplayMixdepth = ({walletInfo}) => {
8 |
9 | const accounts = []
10 |
11 | for (const account_info of walletInfo.accounts){
12 | accounts.push(account_info)
13 | }
14 |
15 | return (
16 |
17 | Total Balance: {walletInfo.total_balance} BTC
18 |
19 |
Maker Service
20 |
21 | {accounts.map((account, index) => (
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | Account {accounts[index].account}
34 |
35 |
36 |
37 | Balance: {accounts[index].account_balance} BTC
38 |
39 |
40 |
41 |
42 | Send {' '}
43 |
44 |
45 | Receive
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | External Addresses Balance: {accounts[index].branches[0].balance} BTC
58 |
59 | Extended Pubkey : {accounts[index].branches[0].branch.split("\t").pop()}
60 |
61 |
62 | {accounts[index].branches[0].entries.map((user, i) => (
63 |
64 |
65 |
66 |
67 | {accounts[index].branches[0].entries[i].labels}
68 |
69 |
70 | {accounts[index].branches[0].entries[i].address} {' '}
71 |
72 |
73 | amount: {accounts[index].branches[0].entries[i].amount}
74 |
75 |
76 |
77 |
78 |
79 | ))}
80 |
81 |
82 |
83 | Internal Addresses Balance: {accounts[index].branches[1].balance} BTC
84 |
85 | {accounts[index].branches[1].entries.map((user, j) => (
86 |
87 |
88 |
89 | {accounts[index].branches[0].entries[j].address} {' '} {accounts[index].branches[0].entries[j].labels}
90 |
91 |
92 | amount: {accounts[index].branches[0].entries[j].amount}
93 |
94 |
95 |
96 |
97 |
98 | ))}
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | ))}
107 |
108 | )
109 | }
110 |
111 | export default DisplayMixdepth
112 |
--------------------------------------------------------------------------------
/joinmarket/src/App.js:
--------------------------------------------------------------------------------
1 | import './App.css';
2 | import '@ibunker/bitcoin-react/dist/index.css';
3 | import {useState,useEffect} from 'react'
4 | import Wallets from './components/Wallets';
5 | import Payment from './components/Payment';
6 | import CreateWallet from './components/CreateWallet';
7 | import Homepage from './components/homepage';
8 | import Maker from './components/Maker';
9 | import Receive from './components/Receive';
10 | import DisplayWallet from './components/DisplayWallet'
11 | import * as rb from 'react-bootstrap';
12 | import github_logo from './github.svg'
13 | import twitter_logo from './twitter.svg'
14 | import useInterval from './components/utils'
15 | import { BrowserRouter as Router, Route ,Switch} from 'react-router-dom';
16 | import { useGlobal } from 'reactn';
17 |
18 | function App() {
19 |
20 | const [walletList,setWalletList] = useState([])
21 |
22 | const [makerStarted, setmakerStarted] = useGlobal("makerStarted");
23 | const [walletName, setWalletName] = useGlobal("walletName");
24 | const [coinjoinInProcess, setCoinjoinInProcess] = useGlobal("coinjoinInProcess");
25 | const [currentStatusMessage, setCurrentStatusMessage] = useGlobal("currentStatusMessage");
26 |
27 | const listWallets = async()=>{
28 | const res = await fetch('/api/v1/wallet/all');
29 | const data = await res.json();
30 | const walletList = data[0].wallets;
31 | return walletList;
32 | }
33 | const resetWalletSessionStorage = async()=>{
34 | sessionStorage.clear();
35 | setWalletName("No wallet loaded");
36 | setmakerStarted(false);
37 | setCoinjoinInProcess(false);
38 | }
39 |
40 | function getCurrentStatusMessage(){
41 | return "Wallet: " + walletName + ", Yg started: " + makerStarted + ", Coinjoin in process: " + coinjoinInProcess;
42 | }
43 |
44 | useInterval(() => {
45 | const sessionClear = async()=>{
46 |
47 | try{
48 | const res = await fetch('/api/v1/session',{
49 | method:"GET",
50 | });
51 |
52 | const data = await res.json();
53 | if(data[0].session===false){
54 | console.log("no wallet in backend");
55 | // This status requires us to clear, especially
56 | // the auth state, so we just reset everything:
57 | resetWalletSessionStorage();
58 | return;
59 | }
60 | console.log("backend alive and wallet loaded");
61 | console.log("maker status: " + data[0].maker_running);
62 | if (data[0].maker_running === true) {
63 | setmakerStarted(true);
64 | }
65 | else {
66 | setmakerStarted(false);
67 | }
68 | setWalletName(data[0].wallet_name);
69 |
70 | if (data[0].coinjoin_in_process === true){
71 | setCoinjoinInProcess(true);
72 | }
73 | else {
74 | setCoinjoinInProcess(false);
75 | }
76 | setCurrentStatusMessage(getCurrentStatusMessage());
77 | }
78 |
79 | catch(e){
80 | console.log("test")
81 | alert("Lost connection to backend! Please restart the backend server.");
82 | sessionStorage.clear();
83 | }
84 | }
85 | sessionClear();
86 |
87 | }, 8*1000);
88 |
89 | useEffect(()=>{
90 |
91 | const getWallets = async()=>{
92 | const wallets = await listWallets();
93 | console.log(wallets);
94 | setWalletList(wallets);
95 | }
96 |
97 | getWallets();
98 |
99 | },[])
100 |
101 |
102 | const unlockWallet = async (name)=>{
103 |
104 | let authData =JSON.parse(sessionStorage.getItem('auth'));
105 | console.log(authData)
106 | //if unlocking same wallet
107 | if(authData && authData.login===true && authData.name===name){
108 | alert(name+" is already unlocked")
109 | return;
110 | }
111 | //if unlocking another wallet while one is already unlocked
112 | else if(authData && authData.login===true && authData.name!==name){
113 | alert(authData.name+" is currently in use, please lock it first");
114 | return;
115 | }
116 |
117 | else{
118 | try{
119 | var passphrase = prompt("Enter the passphrase for " + name);
120 | const res = await fetch(`/api/v1/wallet/${name}/unlock`,{
121 | method:'POST',
122 | headers: {
123 | 'Content-type': 'application/json',
124 | },
125 | body: JSON.stringify({"password": passphrase}),
126 | })
127 | const data = await res.json();
128 | const token = data[0].token;
129 | sessionStorage.setItem('auth',JSON.stringify({
130 | login:true,
131 | token:token,
132 | name:name
133 | }))
134 |
135 | }
136 |
137 | catch(e){
138 | alert("Something went wrong,please try again!")
139 | }
140 |
141 | }
142 | }
143 |
144 | const lockWallet = async(name)=>{
145 | let authData =JSON.parse(sessionStorage.getItem('auth'));
146 | if(!authData || authData.login===false || authData.name!==name){
147 | alert("Please unlock "+name+" first")
148 | return;
149 | }
150 |
151 | try{
152 | let token = "Bearer "+authData.token
153 | const res = await fetch(`/api/v1/wallet/${name}/lock`,{
154 | method:"GET",
155 | headers:{
156 | 'Authorization':token
157 | }
158 | });
159 | sessionStorage.setItem('auth',JSON.stringify({
160 | login:false,
161 | token:'',
162 | name:''
163 |
164 | }))
165 | const data = await res.json();
166 | console.log(data);
167 | alert("locked wallet succesfully")
168 | }
169 | catch(e){
170 | alert("Error while locking.")
171 | }
172 |
173 | }
174 |
175 | const listWalletInfo = async(name)=>{
176 | let authData =JSON.parse(sessionStorage.getItem('auth'));
177 | let token = "Bearer "+authData.token
178 | const res = await fetch(`/api/v1/wallet/${name}/display`,{
179 | method:"GET",
180 | headers:{
181 | 'Authorization':token
182 | }
183 | });
184 | const data = await res.json();
185 | const balance = data[0].walletinfo.total_balance;
186 | const mix_depths = data[0].walletinfo.accounts;
187 | const wallet_info={}
188 | wallet_info['balance'] = balance;
189 | wallet_info[mix_depths[0].account] = mix_depths[0].account_balance
190 | wallet_info[mix_depths[1].account] = mix_depths[1].account_balance
191 | wallet_info[mix_depths[2].account] = mix_depths[2].account_balance
192 | wallet_info[mix_depths[3].account] = mix_depths[3].account_balance
193 | wallet_info[mix_depths[4].account] = mix_depths[4].account_balance
194 |
195 | return [data[0].walletinfo];
196 | }
197 |
198 | const displayWallet = async(name)=>{
199 |
200 | let authData =JSON.parse(sessionStorage.getItem('auth'));
201 | if(authData.login===false || authData.name!==name){
202 | alert("Please unlock "+name+" first")
203 | return;
204 | }
205 | let token = "Bearer "+authData.token
206 | const res = await fetch(`/api/v1/wallet/${name}/display`,{
207 | method:"GET",
208 | headers:{
209 | 'Authorization':token
210 | }
211 | });
212 | const data = await res.json();
213 | console.log(data[0].walletinfo);
214 | const wallet_name = name
215 | const balance = data[0].walletinfo.total_balance;
216 | const mix_depths = data[0].walletinfo.accounts;
217 | const wallet_info={}
218 | wallet_info['balance'] = balance;
219 | wallet_info[mix_depths[0].account] = mix_depths[0].account_balance
220 | wallet_info[mix_depths[1].account] = mix_depths[1].account_balance
221 | wallet_info[mix_depths[2].account] = mix_depths[2].account_balance
222 | wallet_info[mix_depths[3].account] = mix_depths[3].account_balance
223 | wallet_info[mix_depths[4].account] = mix_depths[4].account_balance
224 | console.log(wallet_info)
225 | return wallet_info;
226 | }
227 |
228 | const createWallet = async(name,password)=>{
229 | let authData =JSON.parse(sessionStorage.getItem('auth'));
230 | if(authData===null || authData.login===false){
231 | try{
232 | const res = await fetch(`/api/v1/wallet/create`,{
233 | method:'POST',
234 | headers: {
235 | 'Content-type': 'application/json',
236 | },
237 | body: JSON.stringify({"password":password,"walletname":name,"wallettype":"sw"}),
238 | })
239 |
240 | const data = await res.json();
241 |
242 | alert("Wallet created succesfully")
243 | //figure out a safer way to show the seedphrase
244 | alert(data[0].seedphrase)
245 | const token = data[0].token;
246 | sessionStorage.setItem('auth',JSON.stringify({
247 | login:true,
248 | token:token,
249 | name:name
250 | }))
251 | }
252 | catch(e){
253 | //some other error occurs where wallet is not created
254 | alert("Unexpected error! PLease try again")
255 | }
256 | }
257 | else{
258 | alert(authData.name +" is in use! Please lock it first.")
259 | }
260 |
261 | }
262 |
263 |
264 | const makePayment = async(name,mixdepth,amountSats,destination)=>{
265 | let authData =JSON.parse(sessionStorage.getItem('auth'));
266 | if(authData!=null && authData.login===true){
267 | try{
268 | let token = "Bearer "+authData.token
269 | const res = await fetch(`/api/v1/wallet/${name}/taker/direct-send`,{
270 | method:'POST',
271 | headers: {
272 | 'Content-type': 'application/json',
273 | 'Authorization':token
274 | },
275 | body: JSON.stringify({
276 | "mixdepth": mixdepth,
277 | "amount_sats": amountSats,
278 | "destination": destination
279 | }
280 |
281 | ),
282 | })
283 | const data = await res.json();
284 | console.log(data);
285 | alert("Payment Succesful!")
286 | }
287 | catch(e){
288 | alert("Error while processing payment!")
289 | }
290 |
291 |
292 | }
293 | else{
294 | alert("please unlock wallet first")
295 | }
296 | }
297 |
298 | //route for frontend
299 |
300 | const doCoinjoin = async(mixdepth,amount,counterparties,destination)=>{
301 | try{
302 | console.log("hellooo")
303 | let authData = JSON.parse(sessionStorage.getItem('auth'));
304 |
305 | if(!authData|| authData.login===false || authData.name===''){
306 | return;
307 | }
308 |
309 | let token = "Bearer "+authData.token;
310 | let name = authData.name;
311 | const res = await fetch(`/api/v1/wallet/${name}/taker/coinjoin`,{
312 | method:'POST',
313 | headers: {
314 | 'Content-type': 'application/json',
315 | 'Authorization':token
316 | },
317 | body: JSON.stringify({
318 |
319 | "mixdepth": mixdepth,
320 | "amount": amount,
321 | "counterparties": counterparties,
322 | "destination":destination
323 | }
324 |
325 | ),
326 | })
327 | const data = await res.json();
328 | console.log(data);
329 | alert("Coinjoin in Progress!")
330 |
331 | }
332 | catch(e){
333 | return;
334 | }
335 | }
336 |
337 | const startMakerService = async(txfee,cjfee_a,cjfee_r,ordertype,minsize)=>{
338 | let authData =JSON.parse(sessionStorage.getItem('auth'));
339 |
340 | if(!authData|| authData.login===false || authData.name===''){
341 | alert("Please unlock a wallet first")
342 | return;
343 | }
344 | let name = authData.name
345 | try{
346 | let token = "Bearer "+authData.token
347 | const res = await fetch(`/api/v1/wallet/${name}/maker/start`,{
348 | method:"POST",
349 | headers:{
350 | 'Authorization':token
351 | },
352 | body: JSON.stringify({
353 | "txfee":txfee,
354 | "cjfee_a":cjfee_a,
355 | "cjfee_r":cjfee_r,
356 | "ordertype":ordertype,
357 | "minsize":minsize
358 | }
359 |
360 | ),
361 | });
362 |
363 | const data = await res.json();
364 | console.log(data);
365 | }
366 |
367 | catch(e){
368 | alert("Error while starting service!")
369 | }
370 |
371 | }
372 |
373 | const stopMakerService= async()=>{
374 | let authData =JSON.parse(sessionStorage.getItem('auth'));
375 | if(authData===null ||authData.login===false || authData.name===''){
376 | alert('Wallet needs to be unlocked')
377 | return;
378 | }
379 | try{
380 | let name = authData.name
381 | let token = "Bearer "+authData.token
382 | const res = await fetch(`/api/v1/wallet/${name}/maker/stop`,{
383 | method:"GET",
384 | headers:{
385 | 'Authorization':token
386 | },
387 | })
388 | const data = await res.json();
389 | console.log(data);
390 | alert("Maker service stopped")
391 | }
392 |
393 | catch(e){
394 | alert("Error while stopping service!")
395 | }
396 | }
397 |
398 | const getUTXOs = async()=>{
399 | try{
400 | let authData =JSON.parse(sessionStorage.getItem('auth'));
401 | let token = "Bearer "+authData.token
402 | if(!authData|| authData.login===false || authData.name===''){
403 | return;
404 | }
405 | let name = authData.name;
406 | const res = await fetch(`/api/v1/wallet/${name}/utxos`,{
407 | method:"GET",
408 | headers:{
409 | 'Authorization':token
410 | },
411 | });
412 | const data = await res.json();
413 | return data[0].utxos;
414 | }
415 | catch(e){
416 | return;
417 | }
418 | }
419 |
420 |
421 | return (
422 |
423 |
424 |
425 |
426 |
427 |
428 | Joinmarket
429 |
430 |
431 |
432 | Docs
433 | Features
434 | About
435 |
436 |
437 |
438 |
445 |
446 |
447 |
454 |
455 |
456 |
457 |
458 |
459 | {getCurrentStatusMessage()}
460 |
461 |
462 |
463 |
464 |
465 |
466 | (
470 | <>
471 |
472 | >
473 | )}
474 | />
475 |
476 | (
480 | <>
481 |
482 | >
483 | )}
484 | />
485 |
486 |
487 | (
488 | <>
489 |
490 | >
491 | )}
492 | />
493 |
494 | (
495 | <>
496 |
497 | >
498 | )}
499 | />
500 |
501 | (
502 | <>
503 |
504 | >
505 | )}
506 | />
507 | (
508 | <>
509 |
510 | >
511 | )}
512 | />
513 | (
514 | <>
515 |
516 | >
517 | )}
518 | />
519 |
520 | {" "}
521 |
522 |
523 |
524 |
525 |
526 | );
527 | }
528 |
529 | export default App;
--------------------------------------------------------------------------------