BlueWallet/screen/transactions/RBF.js

167 lines
4.7 KiB
JavaScript
Raw Normal View History

2018-01-30 23:42:38 +01:00
import React, { Component } from 'react';
2018-03-18 03:48:23 +01:00
import { ActivityIndicator, View } from 'react-native';
import { BlueSpacing20, BlueButton, SafeBlueArea, BlueCard, BlueText, BlueFormInput, BlueSpacing } from '../../BlueComponents';
2018-03-18 03:48:23 +01:00
import PropTypes from 'prop-types';
/** @type {AppStorage} */
let BlueApp = require('../../BlueApp');
2018-01-30 23:42:38 +01:00
export default class RBF extends Component {
static navigationOptions = {
2018-06-28 03:43:28 +02:00
tabBarVisible: false,
2018-03-17 21:39:21 +01:00
};
2018-01-30 23:42:38 +01:00
constructor(props) {
super(props);
2018-03-17 21:39:21 +01:00
let txid;
2018-07-07 15:04:32 +02:00
if (props.navigation.state.params) txid = props.navigation.state.params.txid;
2018-01-30 23:42:38 +01:00
2018-03-17 21:39:21 +01:00
let sourceWallet;
let sourceTx;
2018-01-30 23:42:38 +01:00
for (let w of BlueApp.getWallets()) {
for (let t of w.getTransactions()) {
if (t.hash === txid) {
// found our source wallet
2018-03-17 21:39:21 +01:00
sourceWallet = w;
sourceTx = t;
console.log(t);
2018-01-30 23:42:38 +01:00
}
}
}
2018-03-17 21:39:21 +01:00
let destinationAddress;
2018-01-30 23:42:38 +01:00
for (let o of sourceTx.outputs) {
2018-03-17 21:39:21 +01:00
if (o.addresses[0] === sourceWallet.getAddress()) {
// change
2018-01-30 23:42:38 +01:00
// nop
2018-03-17 21:39:21 +01:00
} else {
// DESTINATION address
destinationAddress = o.addresses[0];
console.log('dest = ', destinationAddress);
2018-01-30 23:42:38 +01:00
}
}
if (!destinationAddress || sourceWallet.type === 'legacy') {
// for now I'm too lazy to add RBF support for legacy addresses
2018-01-30 23:42:38 +01:00
this.state = {
isLoading: false,
nonReplaceable: true,
2018-03-17 21:39:21 +01:00
};
return;
2018-01-30 23:42:38 +01:00
}
this.state = {
isLoading: true,
txid,
sourceTx,
sourceWallet,
2018-03-17 21:39:21 +01:00
newDestinationAddress: destinationAddress,
feeDelta: '',
};
2018-01-30 23:42:38 +01:00
}
async componentDidMount() {
2018-03-17 21:39:21 +01:00
let startTime = Date.now();
console.log('transactions/RBF - componentDidMount');
2018-01-30 23:42:38 +01:00
this.setState({
isLoading: false,
2018-03-17 21:39:21 +01:00
});
let endTime = Date.now();
console.log('componentDidMount took', (endTime - startTime) / 1000, 'sec');
2018-01-30 23:42:38 +01:00
}
createTransaction() {
this.props.navigation.navigate('CreateRBF', {
feeDelta: this.state.feeDelta,
newDestinationAddress: this.state.newDestinationAddress,
txid: this.state.txid,
sourceTx: this.state.sourceTx,
sourceWallet: this.state.sourceWallet,
2018-03-17 21:39:21 +01:00
});
2018-01-30 23:42:38 +01:00
}
render() {
if (this.state.isLoading) {
return (
2018-03-17 21:39:21 +01:00
<View style={{ flex: 1, paddingTop: 20 }}>
2018-01-30 23:42:38 +01:00
<ActivityIndicator />
</View>
);
}
if (this.state.nonReplaceable) {
return (
2018-03-17 21:39:21 +01:00
<SafeBlueArea style={{ flex: 1, paddingTop: 20 }}>
<BlueSpacing20 />
<BlueSpacing20 />
<BlueSpacing20 />
<BlueSpacing20 />
<BlueSpacing20 />
2018-01-30 23:42:38 +01:00
<BlueText h4>This transaction is not replaceable</BlueText>
2018-07-07 15:04:32 +02:00
<BlueButton onPress={() => this.props.navigation.goBack()} title="Back" />
2018-01-30 23:42:38 +01:00
</SafeBlueArea>
);
}
if (!this.state.sourceWallet.getAddress) {
return (
2018-03-17 21:39:21 +01:00
<SafeBlueArea style={{ flex: 1, paddingTop: 20 }}>
2018-07-07 15:04:32 +02:00
<BlueText>System error: Source wallet not found (this should never happen)</BlueText>
<BlueButton onPress={() => this.props.navigation.goBack()} title="Back" />
2018-01-30 23:42:38 +01:00
</SafeBlueArea>
);
}
return (
2018-03-17 21:39:21 +01:00
<SafeBlueArea style={{ flex: 1, paddingTop: 20 }}>
<BlueSpacing />
2018-07-07 15:04:32 +02:00
<BlueCard title={'Replace By Fee'} style={{ alignItems: 'center', flex: 1 }}>
<BlueText>RBF allows you to increase fee on already sent but not confirmed transaction, thus speeding up mining</BlueText>
2018-03-17 21:39:21 +01:00
<BlueSpacing20 />
<BlueText>
From wallet '{this.state.sourceWallet.getLabel()}' ({this.state.sourceWallet.getAddress()})
</BlueText>
<BlueSpacing20 />
2018-01-30 23:42:38 +01:00
<BlueFormInput
2018-07-07 15:04:32 +02:00
onChangeText={text => this.setState({ newDestinationAddress: text })}
2018-03-17 21:39:21 +01:00
placeholder={'receiver address here'}
value={this.state.newDestinationAddress}
2018-01-30 23:42:38 +01:00
/>
2018-03-17 21:39:21 +01:00
<BlueFormInput
onChangeText={text => this.setState({ feeDelta: text })}
keyboardType={'numeric'}
placeholder={'fee to add (in BTC)'}
value={this.state.feeDelta + ''}
2018-01-30 23:42:38 +01:00
/>
</BlueCard>
2018-03-17 21:39:21 +01:00
<View style={{ flex: 1, flexDirection: 'row', paddingTop: 20 }}>
<View style={{ flex: 0.33 }}>
2018-07-07 15:04:32 +02:00
<BlueButton onPress={() => this.props.navigation.goBack()} title="Cancel" />
2018-01-30 23:42:38 +01:00
</View>
2018-03-17 21:39:21 +01:00
<View style={{ flex: 0.33 }} />
<View style={{ flex: 0.33 }}>
2018-07-07 15:04:32 +02:00
<BlueButton onPress={() => this.createTransaction()} title="Create" />
2018-01-30 23:42:38 +01:00
</View>
</View>
</SafeBlueArea>
);
}
}
2018-03-18 03:48:23 +01:00
RBF.propTypes = {
navigation: PropTypes.shape({
goBack: PropTypes.function,
navigate: PropTypes.func,
state: PropTypes.shape({
params: PropTypes.shape({
txid: PropTypes.string,
}),
}),
}),
};