mirror of
https://github.com/fullstack-cash/fullstack-gatsby-theme-bch-wallet.git
synced 2026-09-21 16:52:06 -07:00
Merge branch 'master' into feature/packaged-theme
This commit is contained in:
Generated
+15
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
@@ -30,3 +30,6 @@
|
||||
.box{
|
||||
border-color: var(--main-color)!important;
|
||||
}
|
||||
.error-color{
|
||||
color: red;
|
||||
}
|
||||
Reference in New Issue
Block a user