Browse Source

Merge branch 'master' into settingsui

settingsui
Marcos Rodriguez 5 years ago
parent
commit
4b36c5f69a
  1. 4
      App.js
  2. 16
      WatchConnectivity.ios.js
  3. 1
      android/app/src/main/AndroidManifest.xml
  4. 2
      class/app-storage.js
  5. 1
      class/hd-segwit-bech32-wallet.js
  6. 4
      class/quickActions.js
  7. 42
      screen/lnd/lndCreateInvoice.js
  8. 85
      screen/send/details.js
  9. 16
      screen/wallets/scanQrWif.js

4
App.js

@ -38,7 +38,7 @@ export default class App extends React.Component {
clipboardContent: '',
};
async componentDidMount() {
componentDidMount() {
Linking.addEventListener('url', this.handleOpenURL);
AppState.addEventListener('change', this._handleAppStateChange);
QuickActions.popInitialAction().then(this.popInitialAction);
@ -110,7 +110,7 @@ export default class App extends React.Component {
_handleAppStateChange = async nextAppState => {
if (BlueApp.getWallets().length > 0) {
if (this.state.appState.match(/inactive|background/) && nextAppState === 'active') {
if (this.state.appState.match(/background/) && nextAppState === 'active') {
setTimeout(() => A(A.ENUM.APP_UNSUSPENDED), 2000);
const clipboard = await Clipboard.getString();
const isAddressFromStoredWallet = BlueApp.getWallets().some(wallet =>

16
WatchConnectivity.ios.js

@ -32,7 +32,7 @@ export default class WatchConnectivity {
);
reply({ invoicePaymentRequest: createInvoiceRequest });
} else if (message.message === 'sendApplicationContext') {
await WatchConnectivity.shared.sendWalletsToWatch(WatchConnectivity.shared.wallets);
await WatchConnectivity.shared.sendWalletsToWatch();
} else if (message.message === 'fetchTransactions') {
await WatchConnectivity.shared.fetchTransactionsFunction();
}
@ -56,14 +56,16 @@ export default class WatchConnectivity {
}
}
async sendWalletsToWatch(allWallets) {
if (allWallets === undefined && WatchConnectivity.shared.wallets !== undefined) {
allWallets = WatchConnectivity.shared.wallets;
}
if (allWallets && allWallets.length === 0) {
async sendWalletsToWatch() {
const allWallets = WatchConnectivity.shared.wallets;
if (!Array.isArray(allWallets)) {
console.log('No Wallets set to sync with Watch app. Exiting...');
return;
} else if (allWallets.length === 0) {
console.log('Wallets array is set. No Wallets set to sync with Watch app. Exiting...');
return;
}
console.log('Wallets set to sync with Watch app. Continuing...');
return InteractionManager.runAfterInteractions(async () => {
if (WatchConnectivity.shared.isAppInstalled) {
let wallets = [];

1
android/app/src/main/AndroidManifest.xml

@ -16,6 +16,7 @@
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:launchMode="singleInstance"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:windowSoftInputMode="adjustResize">
<intent-filter>

2
class/app-storage.js

@ -295,7 +295,7 @@ export class AppStorage {
await this.fetchWalletTransactions();
await this.saveToDisk();
};
await WatchConnectivity.shared.sendWalletsToWatch(this.wallets);
await WatchConnectivity.shared.sendWalletsToWatch();
DeviceQuickActions.setWallets(this.wallets);
DeviceQuickActions.setQuickActions();
return true;

1
class/hd-segwit-bech32-wallet.js

@ -20,6 +20,7 @@ export class HDSegwitBech32Wallet extends AbstractHDWallet {
static type = 'HDsegwitBech32';
static typeReadable = 'HD SegWit (BIP84 Bech32 Native)';
static defaultRBFSequence = 2147483648; // 1 << 31, minimum for replaceable transactions as per BIP68
static finalRBFSequence = 4294967295; // 0xFFFFFFFF
constructor() {
super();

4
class/quickActions.js

@ -17,8 +17,8 @@ export default class DeviceQuickActions {
if (DeviceQuickActions.shared.wallets === undefined) {
return;
}
QuickActions.isSupported((error, supported) => {
if (supported && error === null) {
QuickActions.isSupported((error, _supported) => {
if (error === null) {
let shortcutItems = [];
const loc = require('../loc/');
for (const wallet of DeviceQuickActions.shared.wallets) {

42
screen/lnd/lndCreateInvoice.js

@ -1,7 +1,6 @@
/* global alert */
import React, { Component } from 'react';
import {
Dimensions,
ActivityIndicator,
View,
TextInput,
@ -18,10 +17,10 @@ import bech32 from 'bech32';
import { BitcoinUnit } from '../../models/bitcoinUnits';
import NavigationService from '../../NavigationService';
import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
import { Icon } from 'react-native-elements';
let BlueApp = require('../../BlueApp');
let EV = require('../../events');
let loc = require('../../loc');
const { width } = Dimensions.get('window');
export default class LNDCreateInvoice extends Component {
static navigationOptions = ({ navigation }) => ({
@ -167,20 +166,27 @@ export default class LNDCreateInvoice extends Component {
renderScanClickable = () => {
return (
<View style={{ marginHorizontal: 0, marginVertical: 16, minHeight: 25, alignContent: 'center' }}>
<TouchableOpacity
onPress={() => NavigationService.navigate('ScanQrAddress', { onBarScanned: this.processLnurl })}
style={{
flex: 1,
flexDirection: 'row',
minWidth: width,
justifyContent: 'center',
alignItems: 'center',
}}
>
<Text style={{ color: BlueApp.settings.buttonTextColor, textAlign: 'center' }}>{loc.receive.scan_lnurl}</Text>
</TouchableOpacity>
</View>
<TouchableOpacity
disabled={this.state.isLoading}
onPress={() => {
NavigationService.navigate('ScanQrAddress', { onBarScanned: this.processLnurl });
Keyboard.dismiss();
}}
style={{
height: 36,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
backgroundColor: '#9AA0AA',
borderRadius: 4,
paddingVertical: 4,
paddingHorizontal: 8,
marginHorizontal: 4,
}}
>
<Icon name="qrcode" size={22} type="font-awesome" color={BlueApp.settings.inverseForegroundColor} />
<Text style={{ marginLeft: 4, color: BlueApp.settings.inverseForegroundColor }}>{loc.send.details.scan}</Text>
</TouchableOpacity>
);
};
@ -245,12 +251,12 @@ export default class LNDCreateInvoice extends Component {
onSubmitEditing={Keyboard.dismiss}
inputAccessoryViewID={BlueDismissKeyboardInputAccessory.InputAccessoryViewID}
/>
{this.state.lnurlParams ? null : this.renderScanClickable()}
</View>
<BlueDismissKeyboardInputAccessory />
{this.renderCreateButton()}
</KeyboardAvoidingView>
</View>
{this.state.lnurlParams ? null : this.renderScanClickable()}
</View>
</TouchableWithoutFeedback>
);
@ -265,7 +271,7 @@ LNDCreateInvoice.propTypes = {
state: PropTypes.shape({
params: PropTypes.shape({
uri: PropTypes.string,
fromWallet: PropTypes.string,
fromWallet: PropTypes.shape({}),
}),
}),
}),

85
screen/send/details.js

@ -84,6 +84,7 @@ export default class SendDetails extends Component {
showSendMax: false,
isFeeSelectionModalVisible: false,
isAdvancedTransactionOptionsVisible: false,
isTransactionReplaceable: fromWallet.type === HDSegwitBech32Wallet.type,
recipientsScrollIndex: 0,
fromAddress,
fromWallet,
@ -495,22 +496,20 @@ export default class SendDetails extends Component {
this.setState({ isLoading: false });
return;
}
this.setState({ isLoading: false }, () =>
this.props.navigation.navigate('Confirm', {
recipients: [firstTransaction],
// HD wallet's utxo is in sats, classic segwit wallet utxos are in btc
fee: this.calculateFee(
utxo,
tx,
this.state.fromWallet.type === HDSegwitP2SHWallet.type || this.state.fromWallet.type === HDLegacyP2PKHWallet.type,
),
memo: this.state.memo,
fromWallet: this.state.fromWallet,
tx: tx,
satoshiPerByte: actualSatoshiPerByte.toFixed(2),
}),
);
this.props.navigation.navigate('Confirm', {
recipients: [firstTransaction],
// HD wallet's utxo is in sats, classic segwit wallet utxos are in btc
fee: this.calculateFee(
utxo,
tx,
this.state.fromWallet.type === HDSegwitP2SHWallet.type || this.state.fromWallet.type === HDLegacyP2PKHWallet.type,
),
memo: this.state.memo,
fromWallet: this.state.fromWallet,
tx: tx,
satoshiPerByte: actualSatoshiPerByte.toFixed(2),
});
this.setState({ isLoading: false });
});
}
@ -537,20 +536,24 @@ export default class SendDetails extends Component {
targets = [{ address: firstTransaction.address, amount: BitcoinUnit.MAX }];
}
let { tx, fee, psbt } = wallet.createTransaction(wallet.getUtxo(), targets, requestedSatPerByte, changeAddress);
let { tx, fee, psbt } = wallet.createTransaction(
wallet.getUtxo(),
targets,
requestedSatPerByte,
changeAddress,
this.state.isTransactionReplaceable ? HDSegwitBech32Wallet.defaultRBFSequence : HDSegwitBech32Wallet.finalRBFSequence,
);
if (wallet.type === WatchOnlyWallet.type) {
// watch-only wallets with enabled HW wallet support have different flow. we have to show PSBT to user as QR code
// so he can scan it and sign it. then we have to scan it back from user (via camera and QR code), and ask
// user whether he wants to broadcast it
this.setState({ isLoading: false }, () =>
this.props.navigation.navigate('PsbtWithHardwareWallet', {
memo: this.state.memo,
fromWallet: wallet,
psbt,
}),
);
this.props.navigation.navigate('PsbtWithHardwareWallet', {
memo: this.state.memo,
fromWallet: wallet,
psbt,
});
this.setState({ isLoading: false });
return;
}
@ -560,16 +563,15 @@ export default class SendDetails extends Component {
memo: this.state.memo,
};
await BlueApp.saveToDisk();
this.setState({ isLoading: false }, () =>
this.props.navigation.navigate('Confirm', {
fee: new BigNumber(fee).dividedBy(100000000).toNumber(),
memo: this.state.memo,
fromWallet: wallet,
tx: tx.toHex(),
recipients: targets,
satoshiPerByte: requestedSatPerByte,
}),
);
this.props.navigation.navigate('Confirm', {
fee: new BigNumber(fee).dividedBy(100000000).toNumber(),
memo: this.state.memo,
fromWallet: wallet,
tx: tx.toHex(),
recipients: targets,
satoshiPerByte: requestedSatPerByte,
});
this.setState({ isLoading: false });
}
onWalletSelect = wallet => {
@ -725,6 +727,15 @@ export default class SendDetails extends Component {
onPress={this.onUseAllPressed}
/>
)}
{this.state.fromWallet.type === HDSegwitBech32Wallet.type && (
<BlueListItem
title="Allow Fee Bump"
hideChevron
switchButton
switched={this.state.isTransactionReplaceable}
onSwitch={this.onReplaceableFeeSwitchValueChanged}
/>
)}
{this.state.fromWallet.allowBatchSend() && (
<>
<BlueListItem
@ -775,6 +786,10 @@ export default class SendDetails extends Component {
);
};
onReplaceableFeeSwitchValueChanged = value => {
this.setState({ isTransactionReplaceable: value });
};
renderCreateButton = () => {
return (
<View style={{ marginHorizontal: 56, marginVertical: 16, alignContent: 'center', backgroundColor: '#FFFFFF', minHeight: 44 }}>

16
screen/wallets/scanQrWif.js

@ -90,9 +90,9 @@ export default class ScanQrWif extends React.Component {
BlueApp.wallets.push(hd);
await BlueApp.saveToDisk();
alert(loc.wallets.import.success);
this.props.navigation.popToTop();
setTimeout(() => EV(EV.enum.WALLETS_COUNT_CHANGED), 500);
this.setState({ isLoading: false });
this.props.navigation.dismiss();
return;
}
}
@ -117,9 +117,9 @@ export default class ScanQrWif extends React.Component {
BlueApp.wallets.push(hd);
await BlueApp.saveToDisk();
alert(loc.wallets.import.success);
this.props.navigation.popToTop();
setTimeout(() => EV(EV.enum.WALLETS_COUNT_CHANGED), 500);
this.setState({ isLoading: false });
this.props.navigation.dismiss();
return;
}
}
@ -144,9 +144,9 @@ export default class ScanQrWif extends React.Component {
await hd.fetchTransactions();
await BlueApp.saveToDisk();
alert(loc.wallets.import.success);
this.props.navigation.popToTop();
setTimeout(() => EV(EV.enum.WALLETS_COUNT_CHANGED), 500);
this.setState({ isLoading: false });
this.props.navigation.dismiss();
return;
}
// nope
@ -179,11 +179,11 @@ export default class ScanQrWif extends React.Component {
BlueApp.wallets.push(lnd);
lnd.setLabel(loc.wallets.import.imported + ' ' + lnd.typeReadable);
this.props.navigation.popToTop();
alert(loc.wallets.import.success);
await BlueApp.saveToDisk();
setTimeout(() => EV(EV.enum.WALLETS_COUNT_CHANGED), 500);
this.setState({ isLoading: false });
this.props.navigation.dismiss();
return;
}
// nope
@ -208,9 +208,9 @@ export default class ScanQrWif extends React.Component {
await watchOnly.fetchBalance();
await watchOnly.fetchTransactions();
await BlueApp.saveToDisk();
this.props.navigation.popToTop();
setTimeout(() => EV(EV.enum.WALLETS_COUNT_CHANGED), 500);
this.setState({ isLoading: false });
this.props.navigation.dismiss();
return;
}
// nope
@ -235,8 +235,8 @@ export default class ScanQrWif extends React.Component {
await newLegacyWallet.fetchBalance();
await newLegacyWallet.fetchTransactions();
await BlueApp.saveToDisk();
this.props.navigation.popToTop();
setTimeout(() => EV(EV.enum.WALLETS_COUNT_CHANGED), 500);
this.props.navigation.dismiss();
return;
}
@ -257,7 +257,7 @@ export default class ScanQrWif extends React.Component {
alert(loc.wallets.scanQrWif.imported_wif + ret.data + loc.wallets.scanQrWif.with_address + newWallet.getAddress());
}
await BlueApp.saveToDisk();
this.props.navigation.popToTop();
this.props.navigation.dismiss();
setTimeout(() => EV(EV.enum.WALLETS_COUNT_CHANGED), 500);
}; // end
@ -337,8 +337,8 @@ export default class ScanQrWif extends React.Component {
ScanQrWif.propTypes = {
navigation: PropTypes.shape({
dismiss: PropTypes.func,
goBack: PropTypes.func,
popToTop: PropTypes.func,
navigate: PropTypes.func,
}),
};

Loading…
Cancel
Save