mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-02-23 23:27:26 +01:00
Merge branch 'master' into ccfix
This commit is contained in:
commit
5652915881
5 changed files with 88 additions and 9 deletions
|
@ -1,9 +1,10 @@
|
|||
import PushNotificationIOS from '@react-native-community/push-notification-ios';
|
||||
import { Alert } from 'react-native';
|
||||
import { Alert, Platform } from 'react-native';
|
||||
import Frisbee from 'frisbee';
|
||||
import { getApplicationName, getVersion, getSystemName, getSystemVersion } from 'react-native-device-info';
|
||||
import { getApplicationName, getVersion, getSystemName, getSystemVersion, hasGmsSync, hasHmsSync } from 'react-native-device-info';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
import loc from '../loc';
|
||||
|
||||
const PushNotification = require('react-native-push-notification');
|
||||
const constants = require('./constants');
|
||||
const PUSH_TOKEN = 'PUSH_TOKEN';
|
||||
|
@ -28,6 +29,7 @@ function Notifications(props) {
|
|||
return false;
|
||||
};
|
||||
|
||||
Notifications.isNotificationsCapable = hasGmsSync() || hasHmsSync() || Platform.OS !== 'android';
|
||||
/**
|
||||
* Calls `configure`, which tries to obtain push token, save it, and registers all associated with
|
||||
* notifications callbacks
|
||||
|
@ -120,6 +122,7 @@ function Notifications(props) {
|
|||
* @returns {Promise<boolean>} TRUE if permissions were obtained, FALSE otherwise
|
||||
*/
|
||||
Notifications.tryToObtainPermissions = async function () {
|
||||
if (!Notifications.isNotificationsCapable) return false;
|
||||
if (await Notifications.getPushToken()) {
|
||||
// we already have a token, no sense asking again, just configure pushes to register callbacks and we are done
|
||||
if (!alreadyConfigured) configureNotifications(); // no await so it executes in background while we return TRUE and use token
|
||||
|
@ -127,7 +130,7 @@ function Notifications(props) {
|
|||
}
|
||||
|
||||
if (await AsyncStorage.getItem(NOTIFICATIONS_NO_AND_DONT_ASK_FLAG)) {
|
||||
// user doesnt want them
|
||||
// user doesn't want them
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { randomBytes } from '../rng';
|
||||
import { AbstractWallet } from './abstract-wallet';
|
||||
import { HDSegwitBech32Wallet } from '..';
|
||||
import BigNumber from 'bignumber.js';
|
||||
const bitcoin = require('bitcoinjs-lib');
|
||||
const BlueElectrum = require('../../blue_modules/BlueElectrum');
|
||||
const coinSelectAccumulative = require('coinselect/accumulative');
|
||||
|
@ -161,12 +162,72 @@ export class LegacyWallet extends AbstractWallet {
|
|||
if (!u.confirmations && u.height) u.confirmations = BlueElectrum.estimateCurrentBlockheight() - u.height;
|
||||
ret.push(u);
|
||||
}
|
||||
|
||||
if (ret.length === 0) {
|
||||
ret = this.getDerivedUtxoFromOurTransaction(); // oy vey, no stored utxo. lets attempt to derive it from stored transactions
|
||||
}
|
||||
|
||||
if (!respectFrozen) {
|
||||
ret = ret.filter(({ txid, vout }) => !this.getUTXOMetadata(txid, vout).frozen);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
getDerivedUtxoFromOurTransaction(returnSpentUtxoAsWell = false) {
|
||||
const utxos = [];
|
||||
|
||||
const ownedAddressesHashmap = {};
|
||||
ownedAddressesHashmap[this.getAddress()] = true;
|
||||
|
||||
/**
|
||||
* below copypasted from
|
||||
* @see AbstractHDElectrumWallet.getDerivedUtxoFromOurTransaction
|
||||
*/
|
||||
|
||||
for (const tx of this.getTransactions()) {
|
||||
for (const output of tx.outputs) {
|
||||
let address = false;
|
||||
if (output.scriptPubKey && output.scriptPubKey.addresses && output.scriptPubKey.addresses[0]) {
|
||||
address = output.scriptPubKey.addresses[0];
|
||||
}
|
||||
if (ownedAddressesHashmap[address]) {
|
||||
const value = new BigNumber(output.value).multipliedBy(100000000).toNumber();
|
||||
utxos.push({
|
||||
txid: tx.txid,
|
||||
txId: tx.txid,
|
||||
vout: output.n,
|
||||
address,
|
||||
value,
|
||||
amount: value,
|
||||
confirmations: tx.confirmations,
|
||||
wif: false,
|
||||
height: BlueElectrum.estimateCurrentBlockheight() - tx.confirmations,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (returnSpentUtxoAsWell) return utxos;
|
||||
|
||||
// got all utxos we ever had. lets filter out the ones that are spent:
|
||||
const ret = [];
|
||||
for (const utxo of utxos) {
|
||||
let spent = false;
|
||||
for (const tx of this.getTransactions()) {
|
||||
for (const input of tx.inputs) {
|
||||
if (input.txid === utxo.txid && input.vout === utxo.vout) spent = true;
|
||||
// utxo we got previously was actually spent right here ^^
|
||||
}
|
||||
}
|
||||
|
||||
if (!spent) {
|
||||
ret.push(utxo);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches transactions via Electrum. Returns VOID.
|
||||
* Use getter to get the actual list. *
|
||||
|
|
|
@ -6,6 +6,7 @@ import navigationStyle from '../../components/navigationStyle';
|
|||
import { BlueListItem, BlueHeaderDefaultSub } from '../../BlueComponents';
|
||||
import loc from '../../loc';
|
||||
import { BlueStorageContext } from '../../blue_modules/storage-context';
|
||||
import Notifications from '../../blue_modules/notifications';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
root: {
|
||||
|
@ -28,7 +29,9 @@ const Settings = () => {
|
|||
<BlueListItem title={loc.settings.language} onPress={() => navigate('Language')} chevron />
|
||||
<BlueListItem title={loc.settings.encrypt_title} onPress={() => navigate('EncryptStorage')} testID="SecurityButton" chevron />
|
||||
<BlueListItem title={loc.settings.network} onPress={() => navigate('NetworkSettings')} chevron />
|
||||
<BlueListItem title={loc.settings.notifications} onPress={() => navigate('NotificationSettings')} chevron />
|
||||
{Notifications.isNotificationsCapable && (
|
||||
<BlueListItem title={loc.settings.notifications} onPress={() => navigate('NotificationSettings')} chevron />
|
||||
)}
|
||||
<BlueListItem title={loc.settings.privacy} onPress={() => navigate('SettingsPrivacy')} chevron />
|
||||
<BlueListItem title={loc.settings.about} onPress={() => navigate('About')} testID="AboutButton" chevron />
|
||||
</ScrollView>
|
||||
|
|
|
@ -54,11 +54,11 @@ describe('LegacyWallet', function () {
|
|||
assert.ok(w._lastBalanceFetch > 0);
|
||||
});
|
||||
|
||||
it('can fetch TXs', async () => {
|
||||
it('can fetch TXs and derive UTXO from them', async () => {
|
||||
const w = new LegacyWallet();
|
||||
w._address = '12eQ9m4sgAwTSQoNXkRABKhCXCsjm2jdVG';
|
||||
w._address = '3GCvDBAktgQQtsbN6x5DYiQCMmgZ9Yk8BK';
|
||||
await w.fetchTransactions();
|
||||
assert.strictEqual(w.getTransactions().length, 2);
|
||||
assert.strictEqual(w.getTransactions().length, 1);
|
||||
|
||||
for (const tx of w.getTransactions()) {
|
||||
assert.ok(tx.hash);
|
||||
|
@ -67,9 +67,19 @@ describe('LegacyWallet', function () {
|
|||
assert.ok(tx.confirmations > 1);
|
||||
}
|
||||
|
||||
assert.ok(w.weOwnTransaction('4924f3a29acdee007ebcf6084d2c9e1752c4eb7f26f7d1a06ef808780bf5fe6d'));
|
||||
assert.ok(w.weOwnTransaction('d0432027a86119c63a0be8fa453275c2333b59067f1e559389cd3e0e377c8b96'));
|
||||
assert.ok(w.weOwnTransaction('b2ac59bc282083498d1e87805d89bef9d3f3bc216c1d2c4dfaa2e2911b547100'));
|
||||
assert.ok(!w.weOwnTransaction('825c12f277d1f84911ac15ad1f41a3de28e9d906868a930b0a7bca61b17c8881'));
|
||||
|
||||
assert.strictEqual(w.getUtxo().length, 1);
|
||||
|
||||
for (const tx of w.getUtxo()) {
|
||||
assert.strictEqual(tx.txid, 'b2ac59bc282083498d1e87805d89bef9d3f3bc216c1d2c4dfaa2e2911b547100');
|
||||
assert.strictEqual(tx.vout, 0);
|
||||
assert.strictEqual(tx.address, '3GCvDBAktgQQtsbN6x5DYiQCMmgZ9Yk8BK');
|
||||
assert.strictEqual(tx.value, 51432);
|
||||
assert.strictEqual(tx.value, tx.amount);
|
||||
assert.ok(tx.confirmations > 0);
|
||||
}
|
||||
});
|
||||
|
||||
it.each([
|
||||
|
|
|
@ -21,6 +21,8 @@ jest.mock('@react-native-community/push-notification-ios', () => {
|
|||
jest.mock('react-native-device-info', () => {
|
||||
return {
|
||||
getSystemName: jest.fn(),
|
||||
hasGmsSync: jest.fn().mockReturnValue(true),
|
||||
hasHmsSync: jest.fn().mockReturnValue(false),
|
||||
};
|
||||
});
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue