mirror of
https://github.com/Permissionless-Software-Foundation/bch-dex-taker-v2.git
synced 2026-09-21 16:52:01 -07:00
Merge pull request #11 from Permissionless-Software-Foundation/dh-sweep-view
feat(sweep): Ported the Sweep view
This commit is contained in:
Generated
+27
-1
@@ -15,6 +15,7 @@
|
||||
"@fortawesome/react-fontawesome": "0.2.2",
|
||||
"axios": "0.27.2",
|
||||
"bch-message-lib": "2.2.1",
|
||||
"bch-token-sweep": "^2.2.1",
|
||||
"bootstrap": "5.2.0",
|
||||
"qrcode.react": "4.2.0",
|
||||
"query-string": "7.1.1",
|
||||
@@ -5126,6 +5127,19 @@
|
||||
"minimal-slp-wallet": ">= 4"
|
||||
}
|
||||
},
|
||||
"node_modules/bch-token-sweep": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/bch-token-sweep/-/bch-token-sweep-2.2.1.tgz",
|
||||
"integrity": "sha512-f4UGEpPXzea7HQMRSEb6h/amXiwrlsMBAjl1dVYg5//26IDWeG+e3qVNtMJhm00NMZ0BS+LasUa2xlz0UVziZA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"bch-donation": "1.1.2",
|
||||
"bignumber.js": "9.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"minimal-slp-wallet": ">= 4"
|
||||
}
|
||||
},
|
||||
"node_modules/bchaddrjs-slp": {
|
||||
"version": "0.2.5",
|
||||
"license": "MIT",
|
||||
@@ -13302,6 +13316,8 @@
|
||||
"node_modules/node-fetch": {
|
||||
"name": "@achingbrain/node-fetch",
|
||||
"version": "2.6.7",
|
||||
"resolved": "https://registry.npmjs.org/@achingbrain/node-fetch/-/node-fetch-2.6.7.tgz",
|
||||
"integrity": "sha512-iTASGs+HTFK5E4ZqcMsHmeJ4zodyq8L38lZV33jwqcBJYoUt3HjN4+ot+O9/0b+ke8ddE7UgOtVuZN/OkV19/g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
@@ -22429,6 +22445,15 @@
|
||||
"version": "2.2.1",
|
||||
"requires": {}
|
||||
},
|
||||
"bch-token-sweep": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/bch-token-sweep/-/bch-token-sweep-2.2.1.tgz",
|
||||
"integrity": "sha512-f4UGEpPXzea7HQMRSEb6h/amXiwrlsMBAjl1dVYg5//26IDWeG+e3qVNtMJhm00NMZ0BS+LasUa2xlz0UVziZA==",
|
||||
"requires": {
|
||||
"bch-donation": "1.1.2",
|
||||
"bignumber.js": "9.0.0"
|
||||
}
|
||||
},
|
||||
"bchaddrjs-slp": {
|
||||
"version": "0.2.5",
|
||||
"requires": {
|
||||
@@ -27457,7 +27482,8 @@
|
||||
"version": "2.0.2"
|
||||
},
|
||||
"node-fetch": {
|
||||
"version": "npm:@achingbrain/node-fetch@2.6.7",
|
||||
"version": "https://registry.npmjs.org/@achingbrain/node-fetch/-/node-fetch-2.6.7.tgz",
|
||||
"integrity": "sha512-iTASGs+HTFK5E4ZqcMsHmeJ4zodyq8L38lZV33jwqcBJYoUt3HjN4+ot+O9/0b+ke8ddE7UgOtVuZN/OkV19/g==",
|
||||
"dev": true
|
||||
},
|
||||
"node-forge": {
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
"@fortawesome/react-fontawesome": "0.2.2",
|
||||
"axios": "0.27.2",
|
||||
"bch-message-lib": "2.2.1",
|
||||
"bch-token-sweep": "2.2.1",
|
||||
"bootstrap": "5.2.0",
|
||||
"qrcode.react": "4.2.0",
|
||||
"query-string": "7.1.1",
|
||||
|
||||
@@ -19,6 +19,7 @@ import ServerSelectView from './servers/select-server-view'
|
||||
import SelectServerButton from './servers/select-server-button'
|
||||
import BchSend from './bch-send'
|
||||
import SlpTokens from './slp-tokens'
|
||||
import SweepWif from './sweep/index.js'
|
||||
|
||||
function AppBody (props) {
|
||||
// Dependency injection through props
|
||||
@@ -35,6 +36,7 @@ function AppBody (props) {
|
||||
<Route path='/placeholder2' element={<Placeholder2 />} />
|
||||
<Route path='/placeholder3' element={<Placeholder3 />} />
|
||||
<Route path='/servers' element={<ServerSelectView appData={appData} />} />
|
||||
<Route path='/sweep' element={<SweepWif appData={appData} />} />
|
||||
</Routes>
|
||||
{/** Show in all paths except the servers view */}
|
||||
{appData.currentPath !== '/servers' && <SelectServerButton linkTo='/servers' appData={appData} />}
|
||||
|
||||
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
This Sweep component allows users to sweep a private key and transfer any
|
||||
BCH or SLP tokens into their wallet.
|
||||
*/
|
||||
|
||||
// Global npm libraries
|
||||
import React from 'react'
|
||||
import { Container, Row, Col, Form, Button, Modal, Spinner } from 'react-bootstrap'
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||
import { faCircleQuestion } from '@fortawesome/free-solid-svg-icons'
|
||||
import Sweeper from 'bch-token-sweep'
|
||||
|
||||
// let _this
|
||||
|
||||
const SweepWif = (props) => {
|
||||
const { appData } = props
|
||||
console.log('appData', appData)
|
||||
const [wifToSweep, setWifToSweep] = React.useState('')
|
||||
const [showModal, setShowModal] = React.useState(false)
|
||||
const [statusMsg, setStatusMsg] = React.useState('')
|
||||
const [hideSpinner, setHideSpinner] = React.useState(false)
|
||||
|
||||
// shouldRefreshOnModalClose: false
|
||||
|
||||
// Helper function to validate WIF
|
||||
const validateWIF = (WIF) => {
|
||||
if (typeof WIF !== 'string') return false
|
||||
if (WIF.length !== 52) return false
|
||||
if (WIF[0] !== 'L' && WIF[0] !== 'K') return false
|
||||
return true
|
||||
}
|
||||
|
||||
// Update wallet state function
|
||||
const updateWalletState = async () => {
|
||||
const wallet = appData.wallet
|
||||
const bchBalance = await wallet.getBalance({ bchAddress: wallet.walletInfo.cashAddress })
|
||||
await wallet.initialize()
|
||||
const slpTokens = await wallet.listTokens(wallet.walletInfo.cashAddress)
|
||||
appData.updateBchWalletState({ walletObj: { bchBalance, slpTokens }, appData })
|
||||
}
|
||||
|
||||
// Handle sweep function
|
||||
const handleSweep = async () => {
|
||||
try {
|
||||
console.log(`Sweeping this WIF: ${wifToSweep}`)
|
||||
|
||||
// Set modal initial state
|
||||
setShowModal(true)
|
||||
setHideSpinner(false)
|
||||
setStatusMsg('')
|
||||
|
||||
// Input validation
|
||||
const isWIF = validateWIF(wifToSweep)
|
||||
if (!isWIF) {
|
||||
setHideSpinner(true)
|
||||
setStatusMsg(<b style={{ color: 'red' }}>Input is not a WIF private key.</b>)
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const walletWif = appData.wallet.walletInfo.privateKey
|
||||
const toAddr = appData.wallet.slpAddress
|
||||
|
||||
// Instance the Sweep library
|
||||
const sweep = new Sweeper(wifToSweep, walletWif, appData.wallet)
|
||||
await sweep.populateObjectFromNetwork()
|
||||
|
||||
// Constructing the sweep transaction
|
||||
const hex = await sweep.sweepTo(toAddr)
|
||||
const txid = await appData.wallet.ar.sendTx(hex)
|
||||
|
||||
// Generate status message
|
||||
const newStatusMsg = (
|
||||
<>
|
||||
<p>Sweep succeeded!</p>
|
||||
<p>Transaction ID: {txid}</p>
|
||||
<p>
|
||||
<a href={`https://blockchair.com/bitcoin-cash/transaction/${txid}`} target='_blank' rel='noreferrer'>
|
||||
TX on Blockchair BCH Block Explorer
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
<a href={`https://token.fullstack.cash/transactions/?txid=${txid}`} target='_blank' rel='noreferrer'>
|
||||
TX on token explorer
|
||||
</a>
|
||||
</p>
|
||||
</>
|
||||
)
|
||||
|
||||
setHideSpinner(true)
|
||||
setStatusMsg(newStatusMsg)
|
||||
setWifToSweep('')
|
||||
|
||||
await updateWalletState()
|
||||
} catch (err) {
|
||||
setHideSpinner(true)
|
||||
setStatusMsg(<b style={{ color: 'red' }}>{`Error: ${err.message}`}</b>)
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Error in handleSweep(): ', err)
|
||||
}
|
||||
}
|
||||
|
||||
// Modal component
|
||||
const getModal = () => (
|
||||
<Modal show={showModal} size='lg' onHide={() => setShowModal(false)}>
|
||||
<Modal.Header closeButton>
|
||||
<Modal.Title>Sweeping...</Modal.Title>
|
||||
</Modal.Header>
|
||||
<Modal.Body>
|
||||
<Container>
|
||||
<Row>
|
||||
{!hideSpinner && (
|
||||
<Col style={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
|
||||
<span style={{ marginRight: '10px' }}>Sweeping private key...</span> <Spinner animation='border' />
|
||||
</Col>
|
||||
)}
|
||||
</Row>
|
||||
<br />
|
||||
{statusMsg && (
|
||||
<Row>
|
||||
<Col style={{ textAlign: 'center' }}>{statusMsg}</Col>
|
||||
</Row>
|
||||
)}
|
||||
</Container>
|
||||
</Modal.Body>
|
||||
<Modal.Footer />
|
||||
</Modal>
|
||||
)
|
||||
|
||||
return (
|
||||
<>
|
||||
<Container>
|
||||
<Row>
|
||||
<Col style={{ textAlign: 'right' }}>
|
||||
<a href='https://youtu.be/QW9xixHaEJE' target='_blank' rel='noreferrer'>
|
||||
<FontAwesomeIcon icon={faCircleQuestion} size='lg' />
|
||||
</a>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Row>
|
||||
<Col>
|
||||
<p>
|
||||
This View is used to 'sweep' a private key. This will transfer
|
||||
any BCH or SLP tokens from a paper wallet to your web wallet.
|
||||
Paper wallets are used to store BCH and tokens. You
|
||||
can <a href='https://paperwallet.fullstack.cash/' target='_blank' rel='noreferrer'>generate paper wallets here</a>.
|
||||
</p>
|
||||
<p>
|
||||
Paste the private key of a paper wallet below and click the button
|
||||
to sweep the funds. The private key must be in WIF format. It will
|
||||
start with the letter 'K' or 'L'.
|
||||
</p>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Row>
|
||||
<Col>
|
||||
<Form>
|
||||
<Form.Group controlId='formWif' style={{ textAlign: 'center' }}>
|
||||
<Form.Control
|
||||
type='text'
|
||||
placeholder='KzJqZxi5XSo36woCy7MFVNRPDpfp8x8FpkhRvrErKBBrDXRVY9Ft'
|
||||
onChange={(e) => setWifToSweep(e.target.value)}
|
||||
value={wifToSweep}
|
||||
/>
|
||||
</Form.Group>
|
||||
</Form>
|
||||
</Col>
|
||||
</Row>
|
||||
<br />
|
||||
|
||||
<Row style={{ textAlign: 'center' }}>
|
||||
<Col>
|
||||
<Button variant='info' onClick={handleSweep}>
|
||||
Sweep
|
||||
</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
</Container>
|
||||
{showModal && getModal()}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default SweepWif
|
||||
@@ -70,6 +70,13 @@ function NavMenu (props) {
|
||||
>
|
||||
Check Balance
|
||||
</NavLink>
|
||||
<NavLink
|
||||
className={(currentPath === '/sweep') ? 'nav-link-active' : 'nav-link-inactive'}
|
||||
to='/sweep'
|
||||
onClick={handleClickEvent}
|
||||
>
|
||||
Sweep
|
||||
</NavLink>
|
||||
</Nav>
|
||||
</Navbar.Collapse>
|
||||
</Navbar>
|
||||
|
||||
Reference in New Issue
Block a user