mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-01-19 05:45:15 +01:00
ADD: Provide fee bump suggestions.
This commit is contained in:
parent
7638407d43
commit
db8f53c67f
@ -33,6 +33,7 @@ import WalletGradient from './class/walletGradient';
|
||||
import ToolTip from 'react-native-tooltip';
|
||||
import { BlurView } from '@react-native-community/blur';
|
||||
import showPopupMenu from 'react-native-popup-menu-android';
|
||||
import NetworkTransactionFees, { NetworkTransactionFeeType } from './models/networkTransactionFees';
|
||||
const LocalQRCode = require('@remobile/react-native-qrcode-local-image');
|
||||
let loc = require('./loc/');
|
||||
/** @type {AppStorage} */
|
||||
@ -850,7 +851,7 @@ export class BlueDismissKeyboardInputAccessory extends Component {
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<BlueButtonLink title="Done" onPress={Keyboard.dismiss} />
|
||||
<BlueButtonLink title="Done" onPress={() => Keyboard.dismiss()} />
|
||||
</View>
|
||||
</InputAccessoryView>
|
||||
);
|
||||
@ -1956,6 +1957,118 @@ export class BlueAddressInput extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
export class BlueReplaceFeeSuggestions extends Component {
|
||||
static propTypes = {
|
||||
onFeeSelected: PropTypes.func.isRequired,
|
||||
transactionMinimum: PropTypes.number.isRequired,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
onFeeSelected: undefined,
|
||||
transactionMinimum: 1,
|
||||
};
|
||||
|
||||
state = { networkFees: undefined, selectedFeeType: NetworkTransactionFeeType.FAST, customFeeValue: 0 };
|
||||
|
||||
async componentDidMount() {
|
||||
const networkFees = await NetworkTransactionFees.recommendedFees();
|
||||
this.setState({ networkFees });
|
||||
}
|
||||
|
||||
onFeeSelected = selectedFeeType => {
|
||||
if (selectedFeeType !== NetworkTransactionFeeType.CUSTOM) {
|
||||
Keyboard.dismiss();
|
||||
}
|
||||
if (selectedFeeType === NetworkTransactionFeeType.FAST) {
|
||||
this.props.onFeeSelected(this.state.networkFees.fastestFee);
|
||||
this.setState({ selectedFeeType }, () => this.props.onFeeSelected(this.state.networkFees.fastestFee));
|
||||
} else if (selectedFeeType === NetworkTransactionFeeType.MEDIUM) {
|
||||
this.setState({ selectedFeeType }, () => this.props.onFeeSelected(this.state.networkFees.halfHourFee));
|
||||
} else if (selectedFeeType === NetworkTransactionFeeType.SLOW) {
|
||||
this.setState({ selectedFeeType }, () => this.props.onFeeSelected(this.state.networkFees.hourFee));
|
||||
} else if (selectedFeeType === NetworkTransactionFeeType.CUSTOM) {
|
||||
this.props.onFeeSelected(this.state.customFeeValue);
|
||||
}
|
||||
};
|
||||
|
||||
onCustomFeeTextChange = customFee => {
|
||||
this.setState({ customFeeValue: Number(customFee), selectedFeeType: NetworkTransactionFeeType.CUSTOM }, () => {
|
||||
this.onFeeSelected(NetworkTransactionFeeType.CUSTOM);
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View>
|
||||
{this.state.networkFees && (
|
||||
<>
|
||||
<BlueText>Suggestions</BlueText>
|
||||
<TouchableOpacity onPress={() => this.onFeeSelected(NetworkTransactionFeeType.FAST)}>
|
||||
<BlueListItem
|
||||
title={'Fast'}
|
||||
rightTitle={`${this.state.networkFees.fastestFee} sat/b`}
|
||||
{...(this.state.selectedFeeType === NetworkTransactionFeeType.FAST
|
||||
? { rightIcon: <Icon name="check" type="font-awesome" color="#0c2550" /> }
|
||||
: { hideChevron: true })}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity onPress={() => this.onFeeSelected(NetworkTransactionFeeType.MEDIUM)}>
|
||||
<BlueListItem
|
||||
title={'Medium'}
|
||||
rightTitle={`${this.state.networkFees.halfHourFee} sat/b`}
|
||||
{...(this.state.selectedFeeType === NetworkTransactionFeeType.MEDIUM
|
||||
? { rightIcon: <Icon name="check" type="font-awesome" color="#0c2550" /> }
|
||||
: { hideChevron: true })}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity onPress={() => this.onFeeSelected(NetworkTransactionFeeType.SLOW)}>
|
||||
<BlueListItem
|
||||
title={'Slow'}
|
||||
rightTitle={`${this.state.networkFees.hourFee} sat/b`}
|
||||
{...(this.state.selectedFeeType === NetworkTransactionFeeType.SLOW
|
||||
? { rightIcon: <Icon name="check" type="font-awesome" color="#0c2550" /> }
|
||||
: { hideChevron: true })}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
</>
|
||||
)}
|
||||
<BlueSpacing20 />
|
||||
<BlueText>Custom</BlueText>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
borderColor: '#d2d2d2',
|
||||
borderBottomColor: '#d2d2d2',
|
||||
borderWidth: 1.0,
|
||||
borderBottomWidth: 0.5,
|
||||
backgroundColor: '#f5f5f5',
|
||||
minHeight: 44,
|
||||
height: 44,
|
||||
alignItems: 'center',
|
||||
marginVertical: 8,
|
||||
borderRadius: 4,
|
||||
}}
|
||||
>
|
||||
<TextInput
|
||||
onChangeText={this.onCustomFeeTextChange}
|
||||
keyboardType={'numeric'}
|
||||
value={this.state.customFeeValue}
|
||||
style={{ flex: 1, minHeight: 33, marginHorizontal: 8 }}
|
||||
onFocus={() => this.onCustomFeeTextChange(this.state.customFeeValue)}
|
||||
defaultValue={`${this.props.transactionMinimum}`}
|
||||
placeholder="Custom sat/b"
|
||||
inputAccessoryViewID={BlueDismissKeyboardInputAccessory.InputAccessoryViewID}
|
||||
/>
|
||||
<BlueDismissKeyboardInputAccessory />
|
||||
</View>
|
||||
<BlueText>
|
||||
The total fee rate (satoshi per byte) you want to pay should be higher than {this.props.transactionMinimum} sat/byte
|
||||
</BlueText>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export class BlueBitcoinAmount extends Component {
|
||||
static propTypes = {
|
||||
isLoading: PropTypes.bool,
|
||||
|
@ -3,6 +3,14 @@ import BigNumber from 'bignumber.js';
|
||||
let loc = require('../loc');
|
||||
|
||||
const BlueElectrum = require('../BlueElectrum');
|
||||
|
||||
export const NetworkTransactionFeeType = Object.freeze({
|
||||
FAST: 'Fast',
|
||||
MEDIUM: 'MEDIUM',
|
||||
SLOW: 'SLOW',
|
||||
CUSTOM: 'CUSTOM',
|
||||
});
|
||||
|
||||
export class NetworkTransactionFee {
|
||||
static StorageKey = 'NetworkTransactionFee';
|
||||
|
||||
|
@ -1,7 +1,16 @@
|
||||
/* global alert */
|
||||
import React, { Component } from 'react';
|
||||
import { ActivityIndicator, View, TextInput, TouchableOpacity, Linking, Clipboard } from 'react-native';
|
||||
import { BlueSpacing20, BlueButton, SafeBlueArea, BlueCard, BlueText, BlueSpacing, BlueNavigationStyle } from '../../BlueComponents';
|
||||
import {
|
||||
BlueSpacing20,
|
||||
BlueReplaceFeeSuggestions,
|
||||
BlueButton,
|
||||
SafeBlueArea,
|
||||
BlueCard,
|
||||
BlueText,
|
||||
BlueSpacing,
|
||||
BlueNavigationStyle,
|
||||
} from '../../BlueComponents';
|
||||
import PropTypes from 'prop-types';
|
||||
import { HDSegwitBech32Transaction, HDSegwitBech32Wallet } from '../../class';
|
||||
import { Icon, Text } from 'react-native-elements';
|
||||
@ -216,34 +225,9 @@ export default class CPFP extends Component {
|
||||
<BlueCard style={{ alignItems: 'center', flex: 1 }}>
|
||||
<BlueText>{text}</BlueText>
|
||||
<BlueSpacing20 />
|
||||
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
borderColor: '#d2d2d2',
|
||||
borderBottomColor: '#d2d2d2',
|
||||
borderWidth: 1.0,
|
||||
borderBottomWidth: 0.5,
|
||||
backgroundColor: '#f5f5f5',
|
||||
minHeight: 44,
|
||||
height: 44,
|
||||
alignItems: 'center',
|
||||
marginVertical: 8,
|
||||
borderRadius: 4,
|
||||
}}
|
||||
>
|
||||
<TextInput
|
||||
onChangeText={text => this.setState({ newFeeRate: text })}
|
||||
keyboardType={'numeric'}
|
||||
placeholder={'total fee rate (satoshi per byte) you want to pay'}
|
||||
value={this.state.newFeeRate + ''}
|
||||
style={{ flex: 1, minHeight: 33, marginHorizontal: 8 }}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<BlueText>Should be higher than {this.state.feeRate} sat/byte</BlueText>
|
||||
<BlueReplaceFeeSuggestions onFeeSelected={fee => this.setState({ newFeeRate: fee })} transactionMinimum={this.state.feeRate} />
|
||||
<BlueSpacing />
|
||||
<BlueButton onPress={() => this.createTransaction()} title="Create" />
|
||||
<BlueButton disabled={this.state.newFeeRate <= this.state.feeRate} onPress={() => this.createTransaction()} title="Create" />
|
||||
</BlueCard>
|
||||
</SafeBlueArea>
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user