diff --git a/BlueComponents.js b/BlueComponents.js index 1469bb5c6..427d9f089 100644 --- a/BlueComponents.js +++ b/BlueComponents.js @@ -190,7 +190,7 @@ export const BitcoinButton = props => { flex: 1, }} > - + {loc.wallets.add_bitcoin} { flex: 1, }} > - + {loc.wallets.add_lightning} { export const BlueFormLabel = props => { const { colors } = useTheme(); - return ; + return ; }; export class BlueFormInput extends Component { diff --git a/android/app/build.gradle b/android/app/build.gradle index 7fc0455e8..1d02819d1 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -132,7 +132,7 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion versionCode 1 - versionName "5.6.0" + versionName "5.6.1" multiDexEnabled true missingDimensionStrategy 'react-native-camera', 'general' testBuildType System.getProperty('testBuildType', 'debug') // This will later be used to control the test apk build type diff --git a/class/wallets/abstract-hd-electrum-wallet.js b/class/wallets/abstract-hd-electrum-wallet.js index 3525a0da4..1bf299a20 100644 --- a/class/wallets/abstract-hd-electrum-wallet.js +++ b/class/wallets/abstract-hd-electrum-wallet.js @@ -553,27 +553,33 @@ export class AbstractHDElectrumWallet extends AbstractHDWallet { async _fetchBalance() { // probing future addressess in hierarchy whether they have any transactions, in case // our 'next free addr' pointers are lagging behind - let tryAgain = false; - let txs = await BlueElectrum.getTransactionsByAddress( - this._getExternalAddressByIndex(this.next_free_address_index + this.gap_limit - 1), - ); - if (txs.length > 0) { - // whoa, someone uses our wallet outside! better catch up - this.next_free_address_index += this.gap_limit; - tryAgain = true; + // for that we are gona batch fetch history for all addresses between last used and last used + gap_limit + + const lagAddressesToFetch = []; + for (let c = this.next_free_address_index; c < this.next_free_address_index + this.gap_limit; c++) { + lagAddressesToFetch.push(this._getExternalAddressByIndex(c)); + } + for (let c = this.next_free_change_address_index; c < this.next_free_change_address_index + this.gap_limit; c++) { + lagAddressesToFetch.push(this._getInternalAddressByIndex(c)); } - txs = await BlueElectrum.getTransactionsByAddress( - this._getInternalAddressByIndex(this.next_free_change_address_index + this.gap_limit - 1), - ); - if (txs.length > 0) { - this.next_free_change_address_index += this.gap_limit; - tryAgain = true; + const txs = await BlueElectrum.multiGetHistoryByAddress(lagAddressesToFetch); // <------ electrum call + + for (let c = this.next_free_address_index; c < this.next_free_address_index + this.gap_limit; c++) { + const address = this._getExternalAddressByIndex(c); + if (txs[address] && Array.isArray(txs[address]) && txs[address].length > 0) { + // whoa, someone uses our wallet outside! better catch up + this.next_free_address_index = c + 1; + } } - // FIXME: refactor me ^^^ can be batched in single call. plus not just couple of addresses, but all between [ next_free .. (next_free + gap_limit) ] - - if (tryAgain) return this._fetchBalance(); + for (let c = this.next_free_change_address_index; c < this.next_free_change_address_index + this.gap_limit; c++) { + const address = this._getInternalAddressByIndex(c); + if (txs[address] && Array.isArray(txs[address]) && txs[address].length > 0) { + // whoa, someone uses our wallet outside! better catch up + this.next_free_change_address_index = c + 1; + } + } // next, business as usuall. fetch balances diff --git a/ios/BlueWalletWatch Extension/Info.plist b/ios/BlueWalletWatch Extension/Info.plist index 5a7736ebf..6d3e00906 100644 --- a/ios/BlueWalletWatch Extension/Info.plist +++ b/ios/BlueWalletWatch Extension/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType XPC! CFBundleShortVersionString - 5.6.0 + 5.6.1 CFBundleVersion 239 CLKComplicationPrincipalClass diff --git a/ios/BlueWalletWatch/Info.plist b/ios/BlueWalletWatch/Info.plist index 507f38e7d..30cc3636c 100644 --- a/ios/BlueWalletWatch/Info.plist +++ b/ios/BlueWalletWatch/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 5.6.0 + 5.6.1 CFBundleVersion 239 UISupportedInterfaceOrientations diff --git a/ios/TodayExtension/Info.plist b/ios/TodayExtension/Info.plist index 032183a29..062d3250c 100644 --- a/ios/TodayExtension/Info.plist +++ b/ios/TodayExtension/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString - 5.6.0 + 5.6.1 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSExtension diff --git a/ios/fastlane/metadata/en-US/release_notes.txt b/ios/fastlane/metadata/en-US/release_notes.txt index 403fa8d99..27040a507 100644 --- a/ios/fastlane/metadata/en-US/release_notes.txt +++ b/ios/fastlane/metadata/en-US/release_notes.txt @@ -1,3 +1,12 @@ +v.5.6.0 +======= + +* FIX: some transactions displayed with 0 value +* FIX: PSBT with HW wallets flow +* FIX: rare crash on watch-only receive button +* FIX: RBF cancel style +* REF: updated languages sl_SI, de_DE, fi_FI, es_ES + v5.5.9 ======= @@ -80,20 +89,3 @@ v5.5.5 ====== * FIX: scan Cobo vault signed transaction QR - -v5.5.4 -====== - -* ADD: handling push notification open -* ADD: View Wallet xPub (Apple Watch) -* ADD: COP Fiat -* FIX: Invoice were not being sent (Apple Watch) -* FIX: Disable some Watch app elements when app is not reachable -* FIX: Show loading indicator when processing file or qrcode image -* FIX: Button size for large devices -* FIX: better handling of electrum disconnect -* FIX: disable push notifications in settings -* FIX: Font-Color in Bump-Fee Input Field "Custom" is not adapted for dark mode -* FIX: QRCode border in LND Backup screen -* FIX: Animated QRCode border. Change save path to Downloads folder -* FIX: sk_SK language updates diff --git a/package-lock.json b/package-lock.json index b18c075ad..1934a05e5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "bluewallet", - "version": "5.6.0", + "version": "5.6.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index f644f2759..f8558ea79 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bluewallet", - "version": "5.6.0", + "version": "5.6.1", "license": "MIT", "devDependencies": { "@babel/core": "^7.9.6", diff --git a/screen/wallets/details.js b/screen/wallets/details.js index 8205ff532..036c1b5f3 100644 --- a/screen/wallets/details.js +++ b/screen/wallets/details.js @@ -14,6 +14,7 @@ import { Linking, StyleSheet, StatusBar, + PermissionsAndroid, } from 'react-native'; import { SecondButton, SafeBlueArea, BlueCard, BlueSpacing20, BlueNavigationStyle, BlueText, BlueLoadingHook } from '../../BlueComponents'; import { LightningCustodianWallet } from '../../class/wallets/lightning-custodian-wallet'; @@ -26,10 +27,14 @@ import { HDSegwitBech32Wallet, SegwitP2SHWallet, LegacyWallet, SegwitBech32Walle import { ScrollView } from 'react-native-gesture-handler'; import loc from '../../loc'; import { useTheme, useRoute, useNavigation } from '@react-navigation/native'; +import RNFS from 'react-native-fs'; +import Share from 'react-native-share'; +import { getSystemName } from 'react-native-device-info'; const EV = require('../../blue_modules/events'); const prompt = require('../../blue_modules/prompt'); const BlueApp = require('../../BlueApp'); const notifications = require('../../blue_modules/notifications'); +const isDesktop = getSystemName() === 'Mac OS X'; const styles = StyleSheet.create({ root: { @@ -94,6 +99,7 @@ const styles = StyleSheet.create({ const WalletDetails = () => { const { wallet } = useRoute().params; const [isLoading, setIsLoading] = useState(true); + const [backdoorPressed, setBackdoorPressed] = useState(0); const [walletName, setWalletName] = useState(wallet.getLabel()); const [useWithHardwareWallet, setUseWithHardwareWallet] = useState(wallet.useWithHardwareWalletEnabled()); const [hideTransactionsInWalletsList, setHideTransactionsInWalletsList] = useState(!wallet.getHideTransactionsInWalletsList()); @@ -204,6 +210,65 @@ const WalletDetails = () => { }); }; + const exportInternals = async () => { + if (backdoorPressed < 10) return setBackdoorPressed(backdoorPressed + 1); + setBackdoorPressed(0); + if (wallet.type !== HDSegwitBech32Wallet.type) return; + const fileName = 'wallet-externals.json'; + const contents = JSON.stringify( + { + _balances_by_external_index: wallet._balances_by_external_index, + _balances_by_internal_index: wallet._balances_by_internal_index, + _txs_by_external_index: wallet._txs_by_external_index, + _txs_by_internal_index: wallet._txs_by_internal_index, + _utxo: wallet._utxo, + next_free_address_index: wallet.next_free_address_index, + next_free_change_address_index: wallet.next_free_change_address_index, + internal_addresses_cache: wallet.internal_addresses_cache, + external_addresses_cache: wallet.external_addresses_cache, + _xpub: wallet._xpub, + gap_limit: wallet.gap_limit, + label: wallet.label, + _lastTxFetch: wallet._lastTxFetch, + _lastBalanceFetch: wallet._lastBalanceFetch, + }, + null, + 2, + ); + if (Platform.OS === 'ios') { + const filePath = RNFS.TemporaryDirectoryPath + `/${fileName}`; + await RNFS.writeFile(filePath, contents); + Share.open({ + url: 'file://' + filePath, + saveToFiles: isDesktop, + }) + .catch(error => { + console.log(error); + alert(error.message); + }) + .finally(() => { + RNFS.unlink(filePath); + }); + } else if (Platform.OS === 'android') { + const granted = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE, { + title: loc.send.permission_storage_title, + message: loc.send.permission_storage_message, + buttonNeutral: loc.send.permission_storage_later, + buttonNegative: loc._.cancel, + buttonPositive: loc._.ok, + }); + + if (granted === PermissionsAndroid.RESULTS.GRANTED) { + console.log('Storage Permission: Granted'); + const filePath = RNFS.DownloadDirectoryPath + `/${fileName}`; + await RNFS.writeFile(filePath, contents); + alert(loc.formatString(loc.send.txSaved, { filePath: fileName })); + } else { + console.log('Storage Permission: Denied'); + } + } + }; + const navigateToBroadcast = () => { navigate('Broadcast'); }; @@ -302,7 +367,9 @@ const WalletDetails = () => { )} <> - {loc.transactions.list_title.toLowerCase()} + + {loc.transactions.list_title.toLowerCase()} + {loc.wallets.details_display}