Merge branch 'master' into feature/packaged-theme

This commit is contained in:
Chris Troutner
2020-07-01 19:16:02 -07:00
committed by GitHub
8 changed files with 399 additions and 0 deletions
+15
View File
@@ -28844,6 +28844,11 @@
"resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
"integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc="
},
"qr.js": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/qr.js/-/qr.js-0.0.0.tgz",
"integrity": "sha1-ys6GOG9ZoNuAUPqQ2baw6IoeNk8="
},
"qrcode": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.4.4.tgz",
@@ -28977,6 +28982,16 @@
}
}
},
"qrcode.react": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/qrcode.react/-/qrcode.react-1.0.0.tgz",
"integrity": "sha512-jBXleohRTwvGBe1ngV+62QvEZ/9IZqQivdwzo9pJM4LQMoCM2VnvNBnKdjvGnKyDZ/l0nCDgsPod19RzlPvm/Q==",
"requires": {
"loose-envify": "^1.4.0",
"prop-types": "^15.6.0",
"qr.js": "0.0.0"
}
},
"qs": {
"version": "6.7.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
+1
View File
@@ -17,6 +17,7 @@
"gatsby-transformer-sharp": "^2.5.3",
"minimal-slp-wallet": "1.3.4",
"prop-types": "^15.7.2",
"qrcode.react": "^1.0.0",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-helmet": "^6.0.0",
+6
View File
@@ -12,9 +12,12 @@ import "./admin-lte.css"
import BchWallet from "minimal-slp-wallet"
import VersionStatus from "../version-status"
import { BrowserRouter as Router } from "react-router-dom"
import { StaticQuery, graphql } from "gatsby"
import loadable from "@loadable/component"
import SendReceive from "./send-receive"
const { Item } = Sidebar
// Screen width to hide the side menu on click
@@ -45,6 +48,8 @@ class AdminLTEPage extends React.Component {
<Item icon="fas-coins" key="Tokens" text="Tokens" />,
<Item icon="fa-qrcode" key="qrReader" text="Qr Scanner" />,
<Item icon="fas-cog" key="Configure" text="Configure" />,
<Item icon="fa-exchange-alt" key="SendReceive" text="Send/Receive" />,
]
render() {
@@ -117,6 +122,7 @@ class AdminLTEPage extends React.Component {
</Router>
</>
}/>
)
}
// Get wallet balance
@@ -0,0 +1,41 @@
import React from "react"
import PropTypes from "prop-types"
import { Content } from "adminlte-2-react"
import Receive from "./receive"
import Send from "./send"
import './send-receive.css'
let _this
class SendReceive extends React.Component {
constructor(props) {
super(props)
_this = this
this.state = {}
}
render() {
return (
<>
<Content>
<Receive
walletInfo={_this.props.walletInfo}
/>
<Send
updateBalance={_this.props.updateBalance}
bchWallet={_this.props.bchWallet}
/>
</Content>
</>
)
}
}
SendReceive.propTypes = {
setWalletInfo: PropTypes.func.isRequired,
walletInfo: PropTypes.object.isRequired,
updateBalance: PropTypes.func.isRequired,
setBchWallet: PropTypes.func.isRequired,
bchWallet:PropTypes.object,
}
export default SendReceive
@@ -0,0 +1,85 @@
import React from "react"
import PropTypes from "prop-types"
import { Content } from "adminlte-2-react"
import { Row, Col, Box } from "adminlte-2-react"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
var QRCode = require("qrcode.react")
let _this
class Receive extends React.Component {
constructor(props) {
super(props)
_this = this
this.state = {
addr: _this.props.walletInfo.cashAddress,
}
}
render() {
return (
<>
<Content>
<>
<Row>
<Col sm={2} />
<Col sm={8}>
<Box className=" border-none mt-2">
<Row>
<Col sm={12} className="text-center">
<h1>
<FontAwesomeIcon
className="title-icon"
size="xs"
icon={"wallet"}
/>
<span>Receive</span>
</h1>
</Col>
<Col sm={12} className="text-center mt-2 mb-2">
<QRCode
value={_this.state.addr}
size={256}
includeMargin={true}
fgColor={"#333"}
/>
<p>{_this.state.addr}</p>
<label className="switch-address" htmlFor="address-checkbox">
<input
id="address-checkbox"
type="checkbox"
onChange={_this.changeAddr}
/>
<span className="slider round"></span>
</label>
</Col>
</Row>
</Box>
</Col>
<Col sm={2} />
</Row>
</>
</Content>
</>
)
}
changeAddr() {
const checkbox = document.getElementById("address-checkbox")
const { cashAddress, slpAddress } = _this.props.walletInfo
let addr
if (checkbox.checked) {
addr = slpAddress
} else {
addr = cashAddress
}
_this.setState({
addr,
})
}
}
Receive.propTypes = {
walletInfo: PropTypes.object.isRequired,
}
export default Receive
@@ -0,0 +1,59 @@
.switch-address {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}
.switch-address input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: var(--main-color);
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
input:checked + .slider {
background-color: var(--main-color);
}
input:focus + .slider {
box-shadow: 0 0 1px var(--main-color);
}
input:checked + .slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
@@ -0,0 +1,189 @@
import React from "react"
import PropTypes from "prop-types"
import { Content, Row, Col, Box, Inputs, Button } from "adminlte-2-react"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import BchWallet from "minimal-slp-wallet"
const { Text } = Inputs
let _this
class Configure extends React.Component {
constructor(props) {
super(props)
_this = this
this.state = {
address: "",
amountSat: "",
errMsg: "",
txId: "",
}
_this.BchWallet = BchWallet
}
render() {
return (
<Content>
<Row>
<Col sm={2} />
<Col sm={8}>
<Box className="hover-shadow border-none mt-2">
<Row>
<Col sm={12} className="text-center">
<h1>
<FontAwesomeIcon
className="title-icon"
size="xs"
icon={"paper-plane"}
/>
<span>Send</span>
</h1>
<Box className="border-none">
<Text
id="addressToSend"
name="address"
placeholder="Enter bch address to send"
label="BCH Address"
labelPosition="above"
onChange={_this.handleUpdate}
/>
<Text
id="amountToSend"
name="amountSat"
placeholder="Enter amount to send"
label="Amount"
labelPosition="above"
onChange={_this.handleUpdate}
/>
<Button
text="Send"
type="primary"
className="btn-lg"
onClick={_this.send}
/>
</Box>
</Col>
<Col sm={12} className="text-center">
{_this.state.errMsg && (
<p className="error-color">{_this.state.errMsg}</p>
)}
{_this.state.txId && (
<p className="">Transaction ID: {_this.state.txId}</p>
)}
</Col>
</Row>
</Box>
</Col>
<Col sm={2} />
</Row>
</Content>
)
}
componentDidMount() {}
handleUpdate(event) {
let value = event.target.value
_this.setState({
[event.target.name]: value,
})
//console.log(_this.state)
}
async send() {
try {
_this.validateInputs()
const bchWalletLib = _this.props.bchWallet
const { address, amountSat } = _this.state
const receivers = [
{
address,
// amount in satoshis, 1 satoshi = 0.00000001 Bitcoin
amountSat: Math.floor(Number(amountSat) * 100000000),
},
]
// console.log("receivers", receivers)
if (!bchWalletLib) {
throw new Error("Wallet not found")
}
// Ensure the wallet UTXOs are up-to-date.
const walletAddr = bchWalletLib.walletInfo.address
bchWalletLib.utxos.bchUtxos = await bchWalletLib.utxos.initUtxoStore(walletAddr)
// Send the BCH.
const result = await bchWalletLib.send(receivers)
// console.log('result',result)
_this.setState({
txId: result,
})
// update balance
setTimeout(async () => {
const myBalance = await bchWalletLib.getBalance()
_this.props.updateBalance(myBalance)
}, 1000)
_this.resetValues()
} catch (error) {
let errMsg
if (error.message) {
errMsg = error.message
} else if (error.error) {
errMsg = error.error
}
_this.setState(prevState => {
return {
...prevState,
errMsg,
txId: "",
}
})
}
}
// Reset form and component state
resetValues() {
_this.setState({
address: "",
amountSat: "",
errMsg: "",
})
const amountEle = document.getElementById("amountToSend")
amountEle.value = ""
const addressEle = document.getElementById("addressToSend")
addressEle.value = ""
}
validateInputs() {
try {
const { address, amountSat } = _this.state
const amountNumber = Number(amountSat)
console.log(_this.state)
if (!address) {
throw new Error("Address is required")
}
if (!amountSat) {
throw new Error("Amount is required")
}
if (!amountNumber) {
throw new Error("Amount must be a number")
}
if (amountNumber < 0) {
throw new Error("Amount must be greater than zero")
}
} catch (error) {
throw error
}
}
}
Configure.propTypes = {
updateBalance: PropTypes.func.isRequired,
bchWallet: PropTypes.object,
}
export default Configure
+3
View File
@@ -30,3 +30,6 @@
.box{
border-color: var(--main-color)!important;
}
.error-color{
color: red;
}