mirror of
https://github.com/fullstack-cash/fullstack-gatsby-theme-bch-wallet.git
synced 2026-09-22 17:22:05 -07:00
feat(rate-limits): Display rate limit error to the users
This commit is contained in:
@@ -8,7 +8,7 @@ const { Text } = Inputs
|
||||
|
||||
let _this
|
||||
class Configure extends React.Component {
|
||||
constructor (props) {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
_this = this
|
||||
@@ -21,7 +21,7 @@ class Configure extends React.Component {
|
||||
_this.BchWallet = BchWallet
|
||||
}
|
||||
|
||||
render () {
|
||||
render() {
|
||||
return (
|
||||
<Content>
|
||||
<Row>
|
||||
@@ -113,11 +113,11 @@ class Configure extends React.Component {
|
||||
)
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
componentDidMount() {
|
||||
_this.setJwt()
|
||||
}
|
||||
|
||||
setJwt () {
|
||||
setJwt() {
|
||||
const { JWT } = _this.props.walletInfo
|
||||
if (JWT) {
|
||||
const jwtElem = document.getElementById('jwt')
|
||||
@@ -125,27 +125,26 @@ class Configure extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
handleUpdate (event) {
|
||||
handleUpdate(event) {
|
||||
const value = event.target.value
|
||||
_this.setState({
|
||||
[event.target.name]: value
|
||||
})
|
||||
console.log(_this.state.JWT)
|
||||
}
|
||||
|
||||
async handleUpdateJWT () {
|
||||
async handleUpdateJWT() {
|
||||
try {
|
||||
const { mnemonic, selectedServer } = _this.props.walletInfo
|
||||
const apiToken = _this.state.JWT
|
||||
|
||||
// Update instance with JWT
|
||||
if (mnemonic && apiToken) {
|
||||
if (mnemonic) {
|
||||
const bchjsOptions = { apiToken: apiToken }
|
||||
if (selectedServer) {
|
||||
bchjsOptions.restURL = selectedServer
|
||||
}
|
||||
|
||||
console.log('bchjs options : ', bchjsOptions)
|
||||
//console.log('bchjs options : ', bchjsOptions)
|
||||
const bchWalletLib = new _this.BchWallet(mnemonic, bchjsOptions)
|
||||
|
||||
// Update bchjs instances of minimal-slp-wallet libraries
|
||||
@@ -161,7 +160,6 @@ class Configure extends React.Component {
|
||||
|
||||
_this.props.setWalletInfo(walletInfo)
|
||||
} catch (error) {
|
||||
console.warn(error)
|
||||
_this.setState({
|
||||
errMsg: error.message
|
||||
})
|
||||
@@ -169,7 +167,7 @@ class Configure extends React.Component {
|
||||
}
|
||||
|
||||
// Reset form and component state
|
||||
resetValues () {
|
||||
resetValues() {
|
||||
_this.setState({
|
||||
JWT: '',
|
||||
errMsg: ''
|
||||
|
||||
@@ -18,7 +18,8 @@ class Send extends React.Component {
|
||||
amountSat: '',
|
||||
errMsg: '',
|
||||
txId: '',
|
||||
showScan: false
|
||||
showScan: false,
|
||||
inFetch: false
|
||||
}
|
||||
_this.BchWallet = BchWallet
|
||||
}
|
||||
@@ -30,7 +31,9 @@ class Send extends React.Component {
|
||||
<Row>
|
||||
<Col sm={2} />
|
||||
<Col sm={8}>
|
||||
<Box className='hover-shadow border-none mt-2'>
|
||||
<Box
|
||||
loaded={!_this.state.inFetch}
|
||||
className='hover-shadow border-none mt-2'>
|
||||
<Row>
|
||||
<Col sm={12} className='text-center'>
|
||||
<h1>
|
||||
@@ -102,7 +105,6 @@ class Send extends React.Component {
|
||||
_this.setState({
|
||||
[event.target.name]: value
|
||||
})
|
||||
// console.log(_this.state)
|
||||
}
|
||||
|
||||
async handleSend () {
|
||||
@@ -124,6 +126,9 @@ class Send extends React.Component {
|
||||
if (!bchWalletLib) {
|
||||
throw new Error('Wallet not found')
|
||||
}
|
||||
_this.setState({
|
||||
inFetch:true
|
||||
})
|
||||
|
||||
// Ensure the wallet UTXOs are up-to-date.
|
||||
const walletAddr = bchWalletLib.walletInfo.address
|
||||
@@ -147,19 +152,8 @@ class Send extends React.Component {
|
||||
|
||||
_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: ''
|
||||
}
|
||||
})
|
||||
|
||||
_this.handleError(error)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,7 +162,8 @@ class Send extends React.Component {
|
||||
_this.setState({
|
||||
address: '',
|
||||
amountSat: '',
|
||||
errMsg: ''
|
||||
errMsg: '',
|
||||
inFetch: false
|
||||
})
|
||||
const amountEle = document.getElementById('amountToSend')
|
||||
amountEle.value = ''
|
||||
@@ -180,7 +175,6 @@ class Send extends React.Component {
|
||||
validateInputs () {
|
||||
const { address, amountSat } = _this.state
|
||||
const amountNumber = Number(amountSat)
|
||||
console.log(_this.state)
|
||||
|
||||
if (!address) {
|
||||
throw new Error('Address is required')
|
||||
@@ -255,7 +249,33 @@ class Send extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount () {}
|
||||
handleError(error){
|
||||
//console.error(error)
|
||||
let errMsg = ''
|
||||
if (error.message) {
|
||||
errMsg = error.message
|
||||
}
|
||||
if (error.error) {
|
||||
if (error.error.match('rate limits')) {
|
||||
errMsg = <span>
|
||||
Rate limits exceeded, increase rate limits with a JWT token from
|
||||
<a style={{marginLeft:'5px'}}
|
||||
target="_blank"
|
||||
href="https://fullstack.cash">FullStack.cash</a>
|
||||
</span>
|
||||
} else {
|
||||
errMsg = error.error
|
||||
}
|
||||
}
|
||||
_this.setState(prevState => {
|
||||
return {
|
||||
...prevState,
|
||||
errMsg,
|
||||
txId: '',
|
||||
inFetch:false
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Send.propTypes = {
|
||||
updateBalance: PropTypes.func.isRequired,
|
||||
|
||||
@@ -9,7 +9,7 @@ import SendTokens from './send-tokens'
|
||||
|
||||
let _this
|
||||
class Tokens extends React.Component {
|
||||
constructor (props) {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
_this = this
|
||||
this.state = {
|
||||
@@ -17,13 +17,13 @@ class Tokens extends React.Component {
|
||||
selectedTokenToView: '',
|
||||
showModal: false,
|
||||
inFetch: true,
|
||||
onEmptyTokensMsg: 'No tokens found on this wallet..',
|
||||
errMsg: '',
|
||||
selectedTokenToSend: '',
|
||||
showForm: false
|
||||
}
|
||||
}
|
||||
|
||||
render () {
|
||||
render() {
|
||||
const { JWT } = _this.props.walletInfo
|
||||
|
||||
return (
|
||||
@@ -46,59 +46,59 @@ class Tokens extends React.Component {
|
||||
<img alt='Loading...' src={Spinner} width={100} />
|
||||
</div>
|
||||
) : (
|
||||
<Content>
|
||||
{!JWT && (
|
||||
<Box padding='true' className='container-nofound'>
|
||||
<Row>
|
||||
<Col xs={12}>
|
||||
<FontAwesomeIcon
|
||||
className='icon btn-animation'
|
||||
size='lg'
|
||||
icon='exclamation-triangle'
|
||||
/>
|
||||
</Col>
|
||||
<Content>
|
||||
{!JWT && (
|
||||
<Box padding='true' className='container-nofound'>
|
||||
<Row>
|
||||
<Col xs={12}>
|
||||
<FontAwesomeIcon
|
||||
className='icon btn-animation'
|
||||
size='lg'
|
||||
icon='exclamation-triangle'
|
||||
/>
|
||||
</Col>
|
||||
|
||||
<Col xs={12}>
|
||||
<em>
|
||||
You don't have a registered JWT, you could encounter
|
||||
errors viewing some of your tokens.
|
||||
<Col xs={12}>
|
||||
<em>
|
||||
You don't have a registered JWT, you could encounter
|
||||
errors viewing some of your tokens.
|
||||
</em>
|
||||
</Col>
|
||||
</Row>
|
||||
</Box>
|
||||
)}
|
||||
<br />
|
||||
{!_this.state.tokens.length && (
|
||||
<Box padding='true' className='container-nofound'>
|
||||
<Row>
|
||||
<Col xs={12}>
|
||||
<em>{_this.state.onEmptyTokensMsg}</em>
|
||||
</Col>
|
||||
</Row>
|
||||
</Box>
|
||||
)}
|
||||
</Col>
|
||||
</Row>
|
||||
</Box>
|
||||
)}
|
||||
<br />
|
||||
{_this.state.errMsg && (
|
||||
<Box padding='true' className='container-nofound'>
|
||||
<Row>
|
||||
<Col xs={12}>
|
||||
<em>{_this.state.errMsg}</em>
|
||||
</Col>
|
||||
</Row>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{_this.state.tokens.length > 0 && (
|
||||
<>
|
||||
<Row>
|
||||
{_this.state.tokens.map((val, i) => {
|
||||
return (
|
||||
<Col sm={4} key={`token-${i}`}>
|
||||
<TokenCard
|
||||
key={`token-${i}`}
|
||||
id={`token-${i}`}
|
||||
token={val}
|
||||
showToken={_this.showToken}
|
||||
selectToken={_this.selectToken}
|
||||
/>
|
||||
</Col>
|
||||
)
|
||||
})}
|
||||
</Row>
|
||||
</>
|
||||
)}
|
||||
</Content>
|
||||
)}
|
||||
{_this.state.tokens.length > 0 && (
|
||||
<>
|
||||
<Row>
|
||||
{_this.state.tokens.map((val, i) => {
|
||||
return (
|
||||
<Col sm={4} key={`token-${i}`}>
|
||||
<TokenCard
|
||||
key={`token-${i}`}
|
||||
id={`token-${i}`}
|
||||
token={val}
|
||||
showToken={_this.showToken}
|
||||
selectToken={_this.selectToken}
|
||||
/>
|
||||
</Col>
|
||||
)
|
||||
})}
|
||||
</Row>
|
||||
</>
|
||||
)}
|
||||
</Content>
|
||||
)}
|
||||
<TokenModal
|
||||
token={
|
||||
_this.state.selectedTokenToView
|
||||
@@ -112,58 +112,54 @@ class Tokens extends React.Component {
|
||||
)
|
||||
}
|
||||
|
||||
onHandleForm () {
|
||||
onHandleForm() {
|
||||
_this.setState({
|
||||
showForm: !_this.state.showForm
|
||||
})
|
||||
}
|
||||
|
||||
async getTokens () {
|
||||
async getTokens() {
|
||||
_this.setState({
|
||||
inFetch: true
|
||||
})
|
||||
const { mnemonic } = _this.props.walletInfo
|
||||
const bchWallet = _this.props.bchWallet
|
||||
let tokens = []
|
||||
let { onEmptyTokensMsg } = _this.state
|
||||
|
||||
if (mnemonic && bchWallet) {
|
||||
try {
|
||||
await bchWallet.walletInfoPromise
|
||||
tokens = await bchWallet.listTokens()
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
if (error.error) {
|
||||
if (error.error.match('rate limits')) onEmptyTokensMsg = error.error
|
||||
}
|
||||
if (error.message) {
|
||||
onEmptyTokensMsg = error.message
|
||||
}
|
||||
try {
|
||||
if (!mnemonic || !bchWallet)
|
||||
throw new Error('You need to create or import a wallet first, to view tokens')
|
||||
|
||||
await bchWallet.walletInfoPromise
|
||||
tokens = await bchWallet.listTokens()
|
||||
|
||||
if (!tokens.length) {
|
||||
throw new Error('No tokens found on this wallet.')
|
||||
|
||||
}
|
||||
} else {
|
||||
onEmptyTokensMsg =
|
||||
'You need to create or import a wallet first, to view tokens'
|
||||
_this.setState({
|
||||
tokens,
|
||||
inFetch: false,
|
||||
})
|
||||
} catch (error) {
|
||||
_this.handleError(error)
|
||||
}
|
||||
|
||||
_this.setState({
|
||||
tokens,
|
||||
inFetch: false,
|
||||
onEmptyTokensMsg
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
async componentDidMount () {
|
||||
async componentDidMount() {
|
||||
await _this.getTokens()
|
||||
}
|
||||
|
||||
showToken (selectedTokenToView) {
|
||||
showToken(selectedTokenToView) {
|
||||
_this.setState({
|
||||
selectedTokenToView
|
||||
})
|
||||
_this.onHandleToggleModal()
|
||||
}
|
||||
|
||||
selectToken (selectedTokenToSend) {
|
||||
selectToken(selectedTokenToSend) {
|
||||
_this.setState({
|
||||
selectedTokenToSend
|
||||
})
|
||||
@@ -173,11 +169,38 @@ class Tokens extends React.Component {
|
||||
ele.scrollIntoView({ behavior: 'smooth' })
|
||||
}
|
||||
|
||||
onHandleToggleModal () {
|
||||
onHandleToggleModal() {
|
||||
_this.setState({
|
||||
showModal: !_this.state.showModal
|
||||
})
|
||||
}
|
||||
handleError(error) {
|
||||
let errMsg = ''
|
||||
if (error.message) {
|
||||
errMsg = error.message
|
||||
}
|
||||
if (error.error) {
|
||||
if (error.error.match('rate limits')) {
|
||||
errMsg = <span>
|
||||
Rate limits exceeded, increase rate limits with a JWT token from
|
||||
<a style={{ marginLeft: '5px' }}
|
||||
target="_blank"
|
||||
href="https://fullstack.cash">FullStack.cash</a>
|
||||
</span>
|
||||
} else {
|
||||
errMsg = error.error
|
||||
}
|
||||
}
|
||||
_this.setState(prevState => {
|
||||
return {
|
||||
...prevState,
|
||||
errMsg: errMsg,
|
||||
txId: '',
|
||||
inFetch: false
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
Tokens.propTypes = {
|
||||
walletInfo: PropTypes.object.isRequired, // wallet info
|
||||
|
||||
@@ -173,20 +173,7 @@ class SendTokens extends React.Component {
|
||||
_this.props.handleSend()
|
||||
}, 1000)
|
||||
} catch (error) {
|
||||
let errMsg
|
||||
if (error.message) {
|
||||
errMsg = error.message
|
||||
} else if (error.error) {
|
||||
errMsg = error.error
|
||||
}
|
||||
_this.setState(prevState => {
|
||||
return {
|
||||
...prevState,
|
||||
errMsg,
|
||||
txId: '',
|
||||
inFetch: false
|
||||
}
|
||||
})
|
||||
_this.handleError(error)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,7 +194,6 @@ class SendTokens extends React.Component {
|
||||
validateInputs () {
|
||||
const { address, amountSat } = _this.state
|
||||
const amountNumber = Number(amountSat)
|
||||
console.log(_this.state)
|
||||
|
||||
if (!address) {
|
||||
throw new Error('Address is required')
|
||||
@@ -282,7 +268,33 @@ class SendTokens extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount () {}
|
||||
handleError(error){
|
||||
//console.error(error)
|
||||
let errMsg = ''
|
||||
if (error.message) {
|
||||
errMsg = error.message
|
||||
}
|
||||
if (error.error) {
|
||||
if (error.error.match('rate limits')) {
|
||||
errMsg = <span>
|
||||
Rate limits exceeded, increase rate limits with a JWT token from
|
||||
<a style={{marginLeft:'5px'}}
|
||||
target="_blank"
|
||||
href="https://fullstack.cash">FullStack.cash</a>
|
||||
</span>
|
||||
} else {
|
||||
errMsg = error.error
|
||||
}
|
||||
}
|
||||
_this.setState(prevState => {
|
||||
return {
|
||||
...prevState,
|
||||
errMsg,
|
||||
txId: '',
|
||||
inFetch: false
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
SendTokens.propTypes = {
|
||||
walletInfo: PropTypes.object.isRequired, // wallet info
|
||||
|
||||
@@ -6,7 +6,7 @@ import BchWallet from 'minimal-slp-wallet'
|
||||
|
||||
let _this
|
||||
class NewWallet extends React.Component {
|
||||
constructor (props) {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
_this = this
|
||||
this.state = {
|
||||
@@ -17,7 +17,7 @@ class NewWallet extends React.Component {
|
||||
_this.BchWallet = BchWallet
|
||||
}
|
||||
|
||||
render () {
|
||||
render() {
|
||||
return (
|
||||
<>
|
||||
<Row>
|
||||
@@ -38,11 +38,6 @@ class NewWallet extends React.Component {
|
||||
<span>New Wallet</span>
|
||||
</h1>
|
||||
</Col>
|
||||
<Col sm={12} className='text-center '>
|
||||
{_this.state.errMsg && (
|
||||
<p className='error-color mt-2'>{_this.state.errMsg}</p>
|
||||
)}
|
||||
</Col>
|
||||
<Col sm={12} className='text-center mt-2 mb-2'>
|
||||
<Button
|
||||
text='Create Wallet'
|
||||
@@ -51,6 +46,11 @@ class NewWallet extends React.Component {
|
||||
onClick={_this.handleCreateWallet}
|
||||
/>
|
||||
</Col>
|
||||
<Col sm={12} className='text-center '>
|
||||
{_this.state.errMsg && (
|
||||
<p className='error-color mt-2'>{_this.state.errMsg}</p>
|
||||
)}
|
||||
</Col>
|
||||
</Row>
|
||||
</Box>
|
||||
</Col>
|
||||
@@ -60,7 +60,7 @@ class NewWallet extends React.Component {
|
||||
)
|
||||
}
|
||||
|
||||
async handleCreateWallet () {
|
||||
async handleCreateWallet() {
|
||||
try {
|
||||
const currentWallet = _this.props.walletInfo
|
||||
|
||||
@@ -85,7 +85,6 @@ class NewWallet extends React.Component {
|
||||
if (restURL) {
|
||||
bchjsOptions.restURL = restURL
|
||||
}
|
||||
console.log('bchjs options : ', bchjsOptions)
|
||||
}
|
||||
|
||||
const bchWalletLib = new _this.BchWallet(null, bchjsOptions)
|
||||
@@ -102,7 +101,7 @@ class NewWallet extends React.Component {
|
||||
Object.assign(currentWallet, walletInfo)
|
||||
|
||||
const myBalance = await bchWalletLib.getBalance()
|
||||
|
||||
// console.log("myBalance", myBalance)
|
||||
// Update redux state
|
||||
_this.props.setWalletInfo(currentWallet)
|
||||
_this.props.updateBalance(myBalance)
|
||||
@@ -113,13 +112,32 @@ class NewWallet extends React.Component {
|
||||
errMsg: ''
|
||||
})
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
_this.setState({
|
||||
inFetch: false,
|
||||
errMsg: error.message
|
||||
})
|
||||
_this.handleError(error)
|
||||
}
|
||||
}
|
||||
handleError(error) {
|
||||
//console.error(error)
|
||||
let errMsg = ''
|
||||
if (error.message) {
|
||||
errMsg = error.message
|
||||
}
|
||||
if (error.error) {
|
||||
if (error.error.match('rate limits')) {
|
||||
errMsg = <span>
|
||||
Rate limits exceeded, increase rate limits with a JWT token from
|
||||
<a style={{ marginLeft: '5px' }}
|
||||
target="_blank"
|
||||
href="https://fullstack.cash">FullStack.cash</a>
|
||||
</span>
|
||||
} else {
|
||||
errMsg = error.error
|
||||
}
|
||||
}
|
||||
_this.setState({
|
||||
inFetch: false,
|
||||
errMsg: errMsg
|
||||
})
|
||||
}
|
||||
}
|
||||
NewWallet.propTypes = {
|
||||
walletInfo: PropTypes.object.isRequired,
|
||||
|
||||
@@ -58,13 +58,7 @@ class ImportWallet extends React.Component {
|
||||
</Col>
|
||||
</Row>
|
||||
</Col>
|
||||
<Col sm={12} className='text-center'>
|
||||
{_this.state.errMsg && (
|
||||
<p className='error-color'>{_this.state.errMsg}</p>
|
||||
)}
|
||||
</Col>
|
||||
|
||||
<Col sm={12} className='text-center mt-2 mb-2'>
|
||||
<Col sm={12} className='text-center mb-2'>
|
||||
<Button
|
||||
text='Import'
|
||||
type='primary'
|
||||
@@ -72,6 +66,11 @@ class ImportWallet extends React.Component {
|
||||
onClick={_this.handleImportWallet}
|
||||
/>
|
||||
</Col>
|
||||
<Col sm={12} className='text-center'>
|
||||
{_this.state.errMsg && (
|
||||
<p className='error-color'>{_this.state.errMsg}</p>
|
||||
)}
|
||||
</Col>
|
||||
</Row>
|
||||
</Box>
|
||||
</Col>
|
||||
@@ -155,11 +154,8 @@ class ImportWallet extends React.Component {
|
||||
inFetch: false
|
||||
})
|
||||
} catch (error) {
|
||||
console.warn(error)
|
||||
_this.setState({
|
||||
errMsg: error.message,
|
||||
inFetch: false
|
||||
})
|
||||
_this.handleError(error)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,13 +176,36 @@ class ImportWallet extends React.Component {
|
||||
const spaceCount = mnemonic.split(' ').length // mnemonic.match(/ /g).length
|
||||
|
||||
if (spaceCount !== 12) {
|
||||
console.log('reject')
|
||||
// console.log('reject')
|
||||
throw new Error('mnemonic must contain 12 words')
|
||||
}
|
||||
} else {
|
||||
throw new Error('12 word mnemonic is required')
|
||||
}
|
||||
}
|
||||
handleError(error){
|
||||
//console.error(error)
|
||||
let errMsg = ''
|
||||
if (error.message) {
|
||||
errMsg = error.message
|
||||
}
|
||||
if (error.error) {
|
||||
if (error.error.match('rate limits')) {
|
||||
errMsg = <span>
|
||||
Rate limits exceeded, increase rate limits with a JWT token from
|
||||
<a style={{marginLeft:'5px'}}
|
||||
target="_blank"
|
||||
href="https://fullstack.cash">FullStack.cash</a>
|
||||
</span>
|
||||
} else {
|
||||
errMsg = error.error
|
||||
}
|
||||
}
|
||||
_this.setState({
|
||||
inFetch: false,
|
||||
errMsg: errMsg
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
ImportWallet.propTypes = {
|
||||
|
||||
Reference in New Issue
Block a user