mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-02-21 14:34:55 +01:00
REF: prettier: line width 120
This commit is contained in:
parent
8fbd2c6ad1
commit
b369a1b917
40 changed files with 205 additions and 769 deletions
|
@ -9,6 +9,7 @@
|
|||
'warn',
|
||||
{
|
||||
singleQuote: true,
|
||||
printWidth: 120,
|
||||
trailingComma: 'all'
|
||||
}
|
||||
]
|
||||
|
|
10
App.js
10
App.js
|
@ -23,14 +23,8 @@ const appjson = require('./app.json');
|
|||
|
||||
const CustomDrawerContentComponent = props => (
|
||||
<ScrollView>
|
||||
<SafeAreaView
|
||||
style={styles.container}
|
||||
forceInset={{ top: 'always', horizontal: 'never' }}
|
||||
>
|
||||
<Text
|
||||
onPress={() => props.navigation.navigate('About')}
|
||||
style={styles.heading}
|
||||
>
|
||||
<SafeAreaView style={styles.container} forceInset={{ top: 'always', horizontal: 'never' }}>
|
||||
<Text onPress={() => props.navigation.navigate('About')} style={styles.heading}>
|
||||
{' '}
|
||||
{pkg.name} v{pkg.version} (build {appjson.expo.ios.buildNumber})
|
||||
</Text>
|
||||
|
|
10
App.test.js
10
App.test.js
|
@ -164,9 +164,7 @@ it('Appstorage - encryptStorage & load encrypted storage works', async () => {
|
|||
assert.equal(Storage2.wallets[1].getLabel(), 'testlabel2');
|
||||
|
||||
// next, adding new `fake` storage which should be unlocked with `fake` password
|
||||
let createFakeStorageResult = await Storage2.createFakeStorage(
|
||||
'fakePassword',
|
||||
);
|
||||
let createFakeStorageResult = await Storage2.createFakeStorage('fakePassword');
|
||||
assert.ok(createFakeStorageResult);
|
||||
assert.equal(Storage2.wallets.length, 0);
|
||||
assert.equal(Storage2.cachedPassword, 'fakePassword');
|
||||
|
@ -194,8 +192,7 @@ it('bip38 decodes', async () => {
|
|||
const bip38 = require('./bip38');
|
||||
const wif = require('wif');
|
||||
|
||||
let encryptedKey =
|
||||
'6PRVWUbkzq2VVjRuv58jpwVjTeN46MeNmzUHqUjQptBJUHGcBakduhrUNc';
|
||||
let encryptedKey = '6PRVWUbkzq2VVjRuv58jpwVjTeN46MeNmzUHqUjQptBJUHGcBakduhrUNc';
|
||||
let decryptedKey = await bip38.decrypt(
|
||||
encryptedKey,
|
||||
'TestingOneTwoThree',
|
||||
|
@ -218,8 +215,7 @@ it('bip38 decodes slow', async () => {
|
|||
const bip38 = require('bip38');
|
||||
const wif = require('wif');
|
||||
|
||||
let encryptedKey =
|
||||
'6PnU5voARjBBykwSddwCdcn6Eu9EcsK24Gs5zWxbJbPZYW7eiYQP8XgKbN';
|
||||
let encryptedKey = '6PnU5voARjBBykwSddwCdcn6Eu9EcsK24Gs5zWxbJbPZYW7eiYQP8XgKbN';
|
||||
let decryptedKey = await bip38.decrypt(encryptedKey, 'qwerty', status =>
|
||||
process.stdout.write(parseInt(status.percent) + '%\r'),
|
||||
);
|
||||
|
|
10
BlueApp.js
10
BlueApp.js
|
@ -15,10 +15,7 @@ async function startAndDecrypt(retry) {
|
|||
let password = false;
|
||||
if (await BlueApp.storageIsEncrypted()) {
|
||||
do {
|
||||
password = await prompt(
|
||||
(retry && loc._.bad_password) || loc._.enter_password,
|
||||
loc._.storage_is_encrypted,
|
||||
);
|
||||
password = await prompt((retry && loc._.bad_password) || loc._.enter_password, loc._.storage_is_encrypted);
|
||||
} while (!password);
|
||||
}
|
||||
let success = await BlueApp.loadFromDisk(password);
|
||||
|
@ -35,10 +32,7 @@ async function startAndDecrypt(retry) {
|
|||
console.log('time to refresh wallet #0');
|
||||
let oldBalance = wallets[0].getBalance();
|
||||
await wallets[0].fetchBalance();
|
||||
if (
|
||||
oldBalance !== wallets[0].getBalance() ||
|
||||
wallets[0].getUnconfirmedBalance() !== 0
|
||||
) {
|
||||
if (oldBalance !== wallets[0].getBalance() || wallets[0].getUnconfirmedBalance() !== 0) {
|
||||
// balance changed, thus txs too
|
||||
await wallets[0].fetchTransactions();
|
||||
hadToRefresh = true;
|
||||
|
|
|
@ -3,25 +3,8 @@ import React, { Component } from 'react';
|
|||
import { SafeAreaView } from 'react-navigation';
|
||||
import Ionicons from 'react-native-vector-icons/Ionicons';
|
||||
import { LinearGradient } from 'expo';
|
||||
import {
|
||||
Icon,
|
||||
Button,
|
||||
FormLabel,
|
||||
FormInput,
|
||||
Card,
|
||||
Text,
|
||||
Header,
|
||||
List,
|
||||
ListItem,
|
||||
} from 'react-native-elements';
|
||||
import {
|
||||
TouchableOpacity,
|
||||
ActivityIndicator,
|
||||
View,
|
||||
StyleSheet,
|
||||
Dimensions,
|
||||
Image,
|
||||
} from 'react-native';
|
||||
import { Icon, Button, FormLabel, FormInput, Card, Text, Header, List, ListItem } from 'react-native-elements';
|
||||
import { TouchableOpacity, ActivityIndicator, View, StyleSheet, Dimensions, Image } from 'react-native';
|
||||
import Carousel from 'react-native-snap-carousel';
|
||||
let loc = require('./loc/');
|
||||
/** @type {AppStorage} */
|
||||
|
@ -91,12 +74,7 @@ export class BlueCard extends Component {
|
|||
|
||||
export class BlueText extends Component {
|
||||
render() {
|
||||
return (
|
||||
<Text
|
||||
{...this.props}
|
||||
style={{ color: BlueApp.settings.foregroundColor }}
|
||||
/>
|
||||
);
|
||||
return <Text {...this.props} style={{ color: BlueApp.settings.foregroundColor }} />;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -123,12 +101,7 @@ export class BlueListItem extends Component {
|
|||
|
||||
export class BlueFormLabel extends Component {
|
||||
render() {
|
||||
return (
|
||||
<FormLabel
|
||||
{...this.props}
|
||||
labelStyle={{ color: BlueApp.settings.foregroundColor }}
|
||||
/>
|
||||
);
|
||||
return <FormLabel {...this.props} labelStyle={{ color: BlueApp.settings.foregroundColor }} />;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -215,12 +188,7 @@ export class BlueHeaderDefaultSub extends Component {
|
|||
>
|
||||
<View style={stylesBlueIcon.box}>
|
||||
<View style={stylesBlueIcon.ballTransparrent}>
|
||||
<Icon
|
||||
name="times"
|
||||
size={16}
|
||||
type="font-awesome"
|
||||
color={BlueApp.settings.foregroundColor}
|
||||
/>
|
||||
<Icon name="times" size={16} type="font-awesome" color={BlueApp.settings.foregroundColor} />
|
||||
</View>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
|
@ -264,12 +232,7 @@ export class BlueHeaderDefaultMain extends Component {
|
|||
>
|
||||
<View style={stylesBlueIcon.box}>
|
||||
<View style={stylesBlueIcon.ballTransparrent}>
|
||||
<Icon
|
||||
name="kebab-horizontal"
|
||||
size={22}
|
||||
type="octicon"
|
||||
color={BlueApp.settings.foregroundColor}
|
||||
/>
|
||||
<Icon name="kebab-horizontal" size={22} type="octicon" color={BlueApp.settings.foregroundColor} />
|
||||
</View>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
|
@ -281,23 +244,13 @@ export class BlueHeaderDefaultMain extends Component {
|
|||
|
||||
export class BlueSpacing extends Component {
|
||||
render() {
|
||||
return (
|
||||
<View
|
||||
{...this.props}
|
||||
style={{ height: 60, backgroundColor: BlueApp.settings.brandingColor }}
|
||||
/>
|
||||
);
|
||||
return <View {...this.props} style={{ height: 60, backgroundColor: BlueApp.settings.brandingColor }} />;
|
||||
}
|
||||
}
|
||||
|
||||
export class BlueSpacing40 extends Component {
|
||||
render() {
|
||||
return (
|
||||
<View
|
||||
{...this.props}
|
||||
style={{ height: 50, backgroundColor: BlueApp.settings.brandingColor }}
|
||||
/>
|
||||
);
|
||||
return <View {...this.props} style={{ height: 50, backgroundColor: BlueApp.settings.brandingColor }} />;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -773,10 +726,7 @@ export class WalletsCarousel extends Component {
|
|||
}
|
||||
}}
|
||||
>
|
||||
<LinearGradient
|
||||
colors={['#65ceef', '#68bbe1']}
|
||||
style={{ padding: 15, borderRadius: 10, height: 145 }}
|
||||
>
|
||||
<LinearGradient colors={['#65ceef', '#68bbe1']} style={{ padding: 15, borderRadius: 10, height: 145 }}>
|
||||
<Image
|
||||
source={require('./img/btc-shape.png')}
|
||||
style={{
|
||||
|
|
|
@ -1,21 +1,12 @@
|
|||
/* global it, jasmine */
|
||||
import {
|
||||
SegwitP2SHWallet,
|
||||
SegwitBech32Wallet,
|
||||
HDSegwitP2SHWallet,
|
||||
HDLegacyBreadwalletWallet,
|
||||
} from './class';
|
||||
import { SegwitP2SHWallet, SegwitBech32Wallet, HDSegwitP2SHWallet, HDLegacyBreadwalletWallet } from './class';
|
||||
let assert = require('assert');
|
||||
|
||||
it('can convert witness to address', () => {
|
||||
let address = SegwitP2SHWallet.witnessToAddress(
|
||||
'035c618df829af694cb99e664ce1b34f80ad2c3b49bcd0d9c0b1836c66b2d25fd8',
|
||||
);
|
||||
let address = SegwitP2SHWallet.witnessToAddress('035c618df829af694cb99e664ce1b34f80ad2c3b49bcd0d9c0b1836c66b2d25fd8');
|
||||
assert.equal(address, '34ZVGb3gT8xMLT6fpqC6dNVqJtJmvdjbD7');
|
||||
|
||||
address = SegwitBech32Wallet.witnessToAddress(
|
||||
'035c618df829af694cb99e664ce1b34f80ad2c3b49bcd0d9c0b1836c66b2d25fd8',
|
||||
);
|
||||
address = SegwitBech32Wallet.witnessToAddress('035c618df829af694cb99e664ce1b34f80ad2c3b49bcd0d9c0b1836c66b2d25fd8');
|
||||
assert.equal(address, 'bc1quhnve8q4tk3unhmjts7ymxv8cd6w9xv8wy29uv');
|
||||
});
|
||||
|
||||
|
@ -35,10 +26,7 @@ it('can create a BIP49', function() {
|
|||
let scriptSig = bitcoin.script.witnessPubKeyHash.output.encode(keyhash);
|
||||
let addressBytes = bitcoin.crypto.hash160(scriptSig);
|
||||
let outputScript = bitcoin.script.scriptHash.output.encode(addressBytes);
|
||||
let address = bitcoin.address.fromOutputScript(
|
||||
outputScript,
|
||||
bitcoin.networks.bitcoin,
|
||||
);
|
||||
let address = bitcoin.address.fromOutputScript(outputScript, bitcoin.networks.bitcoin);
|
||||
|
||||
assert.equal(address, '3GcKN7q7gZuZ8eHygAhHrvPa5zZbG5Q1rK');
|
||||
|
||||
|
@ -59,19 +47,11 @@ it('can create a BIP49', function() {
|
|||
it('HD breadwallet works', async function() {
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 300 * 1000;
|
||||
let hdBread = new HDLegacyBreadwalletWallet();
|
||||
hdBread.setSecret(
|
||||
'high relief amount witness try remember adult destroy puppy fox giant peace',
|
||||
);
|
||||
hdBread.setSecret('high relief amount witness try remember adult destroy puppy fox giant peace');
|
||||
|
||||
assert.equal(hdBread.validateMnemonic(), true);
|
||||
assert.equal(
|
||||
hdBread._getExternalAddressByIndex(0),
|
||||
'1ARGkNMdsBE36fJhddSwf8PqBXG3s4d2KU',
|
||||
);
|
||||
assert.equal(
|
||||
hdBread._getInternalAddressByIndex(0),
|
||||
'1JLvA5D7RpWgChb4A5sFcLNrfxYbyZdw3V',
|
||||
);
|
||||
assert.equal(hdBread._getExternalAddressByIndex(0), '1ARGkNMdsBE36fJhddSwf8PqBXG3s4d2KU');
|
||||
assert.equal(hdBread._getInternalAddressByIndex(0), '1JLvA5D7RpWgChb4A5sFcLNrfxYbyZdw3V');
|
||||
|
||||
assert.equal(
|
||||
hdBread.getXpub(),
|
||||
|
|
|
@ -14,9 +14,7 @@ export default class MockStorage {
|
|||
|
||||
getItem = jest.fn(key => {
|
||||
return new Promise(resolve => {
|
||||
return this.storageCache.hasOwnProperty(key)
|
||||
? resolve(this.storageCache[key])
|
||||
: resolve(null);
|
||||
return this.storageCache.hasOwnProperty(key) ? resolve(this.storageCache[key]) : resolve(null);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -33,8 +31,6 @@ export default class MockStorage {
|
|||
});
|
||||
|
||||
getAllKeys = jest.fn(key => {
|
||||
return new Promise((resolve, reject) =>
|
||||
resolve(Object.keys(this.storageCache)),
|
||||
);
|
||||
return new Promise((resolve, reject) => resolve(Object.keys(this.storageCache)));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -197,9 +197,7 @@ export class AppStorage {
|
|||
} else {
|
||||
// decrypted ok, this is our bucket
|
||||
// we serialize our object's data, encrypt it, and add it to buckets
|
||||
newData.push(
|
||||
encryption.encrypt(JSON.stringify(data), this.cachedPassword),
|
||||
);
|
||||
newData.push(encryption.encrypt(JSON.stringify(data), this.cachedPassword));
|
||||
await AsyncStorage.setItem(AppStorage.FLAG_ENCRYPTED, '1');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,9 +39,7 @@ export class HDSegwitP2SHWallet extends LegacyWallet {
|
|||
let c;
|
||||
for (c = -1; c < 5; c++) {
|
||||
let Segwit = new SegwitP2SHWallet();
|
||||
Segwit.setSecret(
|
||||
this._getExternalWIFByIndex(this.next_free_address_index + c),
|
||||
);
|
||||
Segwit.setSecret(this._getExternalWIFByIndex(this.next_free_address_index + c));
|
||||
await Segwit.fetchTransactions();
|
||||
if (Segwit.transactions.length === 0) {
|
||||
// found free address
|
||||
|
@ -53,9 +51,7 @@ export class HDSegwitP2SHWallet extends LegacyWallet {
|
|||
|
||||
if (!freeAddress) {
|
||||
// could not find in cycle above, give up
|
||||
freeAddress = this._getExternalAddressByIndex(
|
||||
this.next_free_address_index + c,
|
||||
); // we didnt check this one, maybe its free
|
||||
freeAddress = this._getExternalAddressByIndex(this.next_free_address_index + c); // we didnt check this one, maybe its free
|
||||
this.next_free_address_index += c + 1; // now points to the one _after_
|
||||
}
|
||||
|
||||
|
@ -94,10 +90,7 @@ export class HDSegwitP2SHWallet extends LegacyWallet {
|
|||
let scriptSig = bitcoin.script.witnessPubKeyHash.output.encode(keyhash);
|
||||
let addressBytes = bitcoin.crypto.hash160(scriptSig);
|
||||
let outputScript = bitcoin.script.scriptHash.output.encode(addressBytes);
|
||||
let address = bitcoin.address.fromOutputScript(
|
||||
outputScript,
|
||||
bitcoin.networks.bitcoin,
|
||||
);
|
||||
let address = bitcoin.address.fromOutputScript(outputScript, bitcoin.networks.bitcoin);
|
||||
|
||||
return address;
|
||||
}
|
||||
|
@ -115,10 +108,7 @@ export class HDSegwitP2SHWallet extends LegacyWallet {
|
|||
let scriptSig = bitcoin.script.witnessPubKeyHash.output.encode(keyhash);
|
||||
let addressBytes = bitcoin.crypto.hash160(scriptSig);
|
||||
let outputScript = bitcoin.script.scriptHash.output.encode(addressBytes);
|
||||
return bitcoin.address.fromOutputScript(
|
||||
outputScript,
|
||||
bitcoin.networks.bitcoin,
|
||||
);
|
||||
return bitcoin.address.fromOutputScript(outputScript, bitcoin.networks.bitcoin);
|
||||
}
|
||||
|
||||
async fetchBalance() {
|
||||
|
@ -141,9 +131,7 @@ export class HDSegwitP2SHWallet extends LegacyWallet {
|
|||
let offset = 0;
|
||||
|
||||
while (1) {
|
||||
let response = await api.get(
|
||||
'/multiaddr?active=' + this.getXpub() + '&n=100&offset=' + offset,
|
||||
);
|
||||
let response = await api.get('/multiaddr?active=' + this.getXpub() + '&n=100&offset=' + offset);
|
||||
|
||||
if (response && response.body) {
|
||||
if (response.body.txs && response.body.txs.length === 0) {
|
||||
|
@ -173,10 +161,7 @@ export class HDSegwitP2SHWallet extends LegacyWallet {
|
|||
}
|
||||
if (path[path.length - 2] === '0') {
|
||||
// main (aka external) address
|
||||
this.next_free_address_index = Math.max(
|
||||
path[path.length - 1] * 1 + 1,
|
||||
this.next_free_address_index,
|
||||
);
|
||||
this.next_free_address_index = Math.max(path[path.length - 1] * 1 + 1, this.next_free_address_index);
|
||||
// setting to point to last maximum known main address + 1
|
||||
}
|
||||
// done with cache
|
||||
|
@ -201,10 +186,7 @@ export class HDSegwitP2SHWallet extends LegacyWallet {
|
|||
}
|
||||
if (path[path.length - 2] === '0') {
|
||||
// main (aka external) address
|
||||
this.next_free_address_index = Math.max(
|
||||
path[path.length - 1] * 1 + 1,
|
||||
this.next_free_address_index,
|
||||
);
|
||||
this.next_free_address_index = Math.max(path[path.length - 1] * 1 + 1, this.next_free_address_index);
|
||||
// setting to point to last maximum known main address + 1
|
||||
}
|
||||
// done with cache
|
||||
|
|
|
@ -83,25 +83,17 @@ export class LegacyWallet extends AbstractWallet {
|
|||
});
|
||||
|
||||
let response = await api.get(
|
||||
this.getAddress() +
|
||||
'/balance' +
|
||||
((useBlockcypherTokens &&
|
||||
'&token=' + this.getRandomBlockcypherToken()) ||
|
||||
''),
|
||||
this.getAddress() + '/balance' + ((useBlockcypherTokens && '&token=' + this.getRandomBlockcypherToken()) || ''),
|
||||
);
|
||||
let json = response.body;
|
||||
if (
|
||||
typeof json === 'undefined' ||
|
||||
typeof json.final_balance === 'undefined'
|
||||
) {
|
||||
if (typeof json === 'undefined' || typeof json.final_balance === 'undefined') {
|
||||
throw new Error('Could not fetch UTXO from API' + response.err);
|
||||
}
|
||||
|
||||
this.balance = new BigNumber(json.final_balance);
|
||||
this.balance = this.balance.div(100000000).toString() * 1;
|
||||
this.unconfirmed_balance = new BigNumber(json.unconfirmed_balance);
|
||||
this.unconfirmed_balance =
|
||||
this.unconfirmed_balance.div(100000000).toString() * 1;
|
||||
this.unconfirmed_balance = this.unconfirmed_balance.div(100000000).toString() * 1;
|
||||
this._lastBalanceFetch = +new Date();
|
||||
} catch (err) {
|
||||
console.warn(err);
|
||||
|
@ -129,15 +121,10 @@ export class LegacyWallet extends AbstractWallet {
|
|||
this.getAddress() +
|
||||
'?limit=2000&after=' +
|
||||
maxHeight +
|
||||
((useBlockcypherTokens &&
|
||||
'&token=' + this.getRandomBlockcypherToken()) ||
|
||||
''),
|
||||
((useBlockcypherTokens && '&token=' + this.getRandomBlockcypherToken()) || ''),
|
||||
);
|
||||
json = response.body;
|
||||
if (
|
||||
typeof json === 'undefined' ||
|
||||
typeof json.final_balance === 'undefined'
|
||||
) {
|
||||
if (typeof json === 'undefined' || typeof json.final_balance === 'undefined') {
|
||||
throw new Error('Could not fetch UTXO from API' + response.err);
|
||||
}
|
||||
json.txrefs = json.txrefs || []; // case when source address is empty (or maxheight too high, no txs)
|
||||
|
@ -176,12 +163,7 @@ export class LegacyWallet extends AbstractWallet {
|
|||
this.getRandomBlockcypherToken()),
|
||||
);
|
||||
} else {
|
||||
response = await fetch(
|
||||
(url =
|
||||
'https://api.blockcypher.com/v1/btc/main/addrs/' +
|
||||
this.getAddress() +
|
||||
'/full'),
|
||||
);
|
||||
response = await fetch((url = 'https://api.blockcypher.com/v1/btc/main/addrs/' + this.getAddress() + '/full'));
|
||||
}
|
||||
console.log(url);
|
||||
let json = await response.json();
|
||||
|
@ -380,14 +362,7 @@ export class LegacyWallet extends AbstractWallet {
|
|||
this.getAddress(),
|
||||
);
|
||||
let amountPlusFee = parseFloat(new BigNumber(amount).add(fee).toString(10));
|
||||
return signer.createTransaction(
|
||||
utxos,
|
||||
toAddress,
|
||||
amountPlusFee,
|
||||
fee,
|
||||
this.getSecret(),
|
||||
this.getAddress(),
|
||||
);
|
||||
return signer.createTransaction(utxos, toAddress, amountPlusFee, fee, this.getSecret(), this.getAddress());
|
||||
}
|
||||
|
||||
getLatestTransactionTime() {
|
||||
|
|
|
@ -17,9 +17,7 @@ export class SegwitBech32Wallet extends LegacyWallet {
|
|||
try {
|
||||
let keyPair = bitcoin.ECPair.fromWIF(this.secret);
|
||||
let pubKey = keyPair.getPublicKeyBuffer();
|
||||
let scriptPubKey = bitcoin.script.witnessPubKeyHash.output.encode(
|
||||
bitcoin.crypto.hash160(pubKey),
|
||||
);
|
||||
let scriptPubKey = bitcoin.script.witnessPubKeyHash.output.encode(bitcoin.crypto.hash160(pubKey));
|
||||
address = bitcoin.address.fromOutputScript(scriptPubKey);
|
||||
} catch (err) {
|
||||
return false;
|
||||
|
@ -32,12 +30,7 @@ export class SegwitBech32Wallet extends LegacyWallet {
|
|||
static witnessToAddress(witness) {
|
||||
const pubKey = Buffer.from(witness, 'hex');
|
||||
const pubKeyHash = bitcoin.crypto.hash160(pubKey);
|
||||
const scriptPubKey = bitcoin.script.witnessPubKeyHash.output.encode(
|
||||
pubKeyHash,
|
||||
);
|
||||
return bitcoin.address.fromOutputScript(
|
||||
scriptPubKey,
|
||||
bitcoin.networks.bitcoin,
|
||||
);
|
||||
const scriptPubKey = bitcoin.script.witnessPubKeyHash.output.encode(pubKeyHash);
|
||||
return bitcoin.address.fromOutputScript(scriptPubKey, bitcoin.networks.bitcoin);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,17 +16,10 @@ export class SegwitP2SHWallet extends LegacyWallet {
|
|||
static witnessToAddress(witness) {
|
||||
const pubKey = Buffer.from(witness, 'hex');
|
||||
const pubKeyHash = bitcoin.crypto.hash160(pubKey);
|
||||
const redeemScript = bitcoin.script.witnessPubKeyHash.output.encode(
|
||||
pubKeyHash,
|
||||
);
|
||||
const redeemScript = bitcoin.script.witnessPubKeyHash.output.encode(pubKeyHash);
|
||||
const redeemScriptHash = bitcoin.crypto.hash160(redeemScript);
|
||||
const scriptPubkey = bitcoin.script.scriptHash.output.encode(
|
||||
redeemScriptHash,
|
||||
);
|
||||
return bitcoin.address.fromOutputScript(
|
||||
scriptPubkey,
|
||||
bitcoin.networks.bitcoin,
|
||||
);
|
||||
const scriptPubkey = bitcoin.script.scriptHash.output.encode(redeemScriptHash);
|
||||
return bitcoin.address.fromOutputScript(scriptPubkey, bitcoin.networks.bitcoin);
|
||||
}
|
||||
|
||||
getAddress() {
|
||||
|
@ -35,12 +28,8 @@ export class SegwitP2SHWallet extends LegacyWallet {
|
|||
try {
|
||||
let keyPair = bitcoin.ECPair.fromWIF(this.secret);
|
||||
let pubKey = keyPair.getPublicKeyBuffer();
|
||||
let witnessScript = bitcoin.script.witnessPubKeyHash.output.encode(
|
||||
bitcoin.crypto.hash160(pubKey),
|
||||
);
|
||||
let scriptPubKey = bitcoin.script.scriptHash.output.encode(
|
||||
bitcoin.crypto.hash160(witnessScript),
|
||||
);
|
||||
let witnessScript = bitcoin.script.witnessPubKeyHash.output.encode(bitcoin.crypto.hash160(pubKey));
|
||||
let scriptPubKey = bitcoin.script.scriptHash.output.encode(bitcoin.crypto.hash160(witnessScript));
|
||||
address = bitcoin.address.fromOutputScript(scriptPubKey);
|
||||
} catch (err) {
|
||||
return false;
|
||||
|
|
10
events.js
10
events.js
|
@ -1,11 +1,6 @@
|
|||
function EV(eventName, arg) {
|
||||
if (Object.values(EV.enum).indexOf(eventName) === -1) {
|
||||
return console.warn(
|
||||
'Unregistered event',
|
||||
eventName,
|
||||
'registered events:',
|
||||
EV.enum,
|
||||
);
|
||||
return console.warn('Unregistered event', eventName, 'registered events:', EV.enum);
|
||||
}
|
||||
EV.callbacks = EV.callbacks || {}; // static variable
|
||||
EV.callbacks[eventName] = EV.callbacks[eventName] || [];
|
||||
|
@ -27,8 +22,7 @@ function EV(eventName, arg) {
|
|||
EV.enum = {
|
||||
WALLETS_COUNT_CHANGED: 'WALLETS_COUNT_CHANGED',
|
||||
TRANSACTIONS_COUNT_CHANGED: 'TRANSACTIONS_COUNT_CHANGED',
|
||||
CREATE_TRANSACTION_NEW_DESTINATION_ADDRESS:
|
||||
'CREATE_TRANSACTION_NEW_DESTINATION_ADDRESS',
|
||||
CREATE_TRANSACTION_NEW_DESTINATION_ADDRESS: 'CREATE_TRANSACTION_NEW_DESTINATION_ADDRESS',
|
||||
RECEIVE_ADDRESS_CHANGED: 'RECEIVE_ADDRESS_CHANGED',
|
||||
};
|
||||
|
||||
|
|
16
loc/en.js
16
loc/en.js
|
@ -1,7 +1,6 @@
|
|||
module.exports = {
|
||||
_: {
|
||||
storage_is_encrypted:
|
||||
'Your storage is encrypted. Password is required to decrypt it',
|
||||
storage_is_encrypted: 'Your storage is encrypted. Password is required to decrypt it',
|
||||
enter_password: 'Enter password',
|
||||
bad_password: 'Bad pasword, try again',
|
||||
months_ago: 'months ago',
|
||||
|
@ -14,9 +13,7 @@ module.exports = {
|
|||
tabBarLabel: 'Wallets',
|
||||
app_name: 'Blue Wallet',
|
||||
title: 'wallets',
|
||||
header:
|
||||
'A wallet represents a pair of a secret (private key) and an address' +
|
||||
'you can share to receive coins.',
|
||||
header: 'A wallet represents a pair of a secret (private key) and an address' + 'you can share to receive coins.',
|
||||
add: 'Add Wallet',
|
||||
create_a_wallet: 'Create a wallet',
|
||||
create_a_wallet1: "It's free and you can create",
|
||||
|
@ -98,8 +95,7 @@ module.exports = {
|
|||
title: 'Create Transaction',
|
||||
error: 'Error creating transaction. Invalid address or send amount?',
|
||||
go_back: 'Go Back',
|
||||
this_is_hex:
|
||||
'This is transaction hex, signed and ready to be broadcast to the network. Continue?',
|
||||
this_is_hex: 'This is transaction hex, signed and ready to be broadcast to the network. Continue?',
|
||||
to: 'To',
|
||||
amount: 'Amount',
|
||||
fee: 'Fee',
|
||||
|
@ -147,10 +143,8 @@ module.exports = {
|
|||
create_fake_storage: 'Create fake encrypted storage',
|
||||
go_back: 'Go Back',
|
||||
create_password: 'Create a password',
|
||||
create_password_explanation:
|
||||
'Password for fake storage should not match password for your main storage',
|
||||
password_should_not_match:
|
||||
'Password for fake storage should not match password for your main storage',
|
||||
create_password_explanation: 'Password for fake storage should not match password for your main storage',
|
||||
password_should_not_match: 'Password for fake storage should not match password for your main storage',
|
||||
retype_password: 'Retype password',
|
||||
passwords_do_not_match: 'Passwords do not match, try again',
|
||||
success: 'Success',
|
||||
|
|
|
@ -50,8 +50,7 @@ module.exports = {
|
|||
list: {
|
||||
tabBarLabel: 'Transacciónes',
|
||||
title: 'Mi Transacciónes',
|
||||
description:
|
||||
'Una lista de las transacciones entrantes o salientes de sus monederos',
|
||||
description: 'Una lista de las transacciones entrantes o salientes de sus monederos',
|
||||
conf: 'conf',
|
||||
},
|
||||
details: {
|
||||
|
@ -81,8 +80,7 @@ module.exports = {
|
|||
},
|
||||
create: {
|
||||
title: 'Crear una Transaccion',
|
||||
error:
|
||||
'Error al crear una transacción. ¿Dirección o cantidad estan invalidas?',
|
||||
error: 'Error al crear una transacción. ¿Dirección o cantidad estan invalidas?',
|
||||
go_back: 'Regresar',
|
||||
this_is_hex:
|
||||
'Este es representacion hex de transacción, firmado y listo para ser transmitido a la red. ¿Continuar?',
|
||||
|
@ -110,8 +108,7 @@ module.exports = {
|
|||
plausible_deniability: 'Negación plausible...',
|
||||
storage_not_encrypted: 'Almacenamiento: no esta encriptado',
|
||||
password: 'Contraseña',
|
||||
password_explain:
|
||||
'Crea la contraseña que usarás para descifrar el almacenamiento',
|
||||
password_explain: 'Crea la contraseña que usarás para descifrar el almacenamiento',
|
||||
retype_password: 'Ingresa la contraseña de nuevo',
|
||||
passwords_do_not_match: 'Contraseñas deben ser iguales',
|
||||
encrypt_storage: 'Cifrar almacenamiento',
|
||||
|
|
|
@ -21,13 +21,7 @@ let strings;
|
|||
locale = locale.split('-');
|
||||
locale = locale[0];
|
||||
console.log('current locale:', locale);
|
||||
if (
|
||||
locale === 'en' ||
|
||||
locale === 'ru' ||
|
||||
locale === 'ua' ||
|
||||
locale === 'es' ||
|
||||
locale === 'pt'
|
||||
) {
|
||||
if (locale === 'en' || locale === 'ru' || locale === 'ua' || locale === 'es' || locale === 'pt') {
|
||||
strings.setLanguage(locale);
|
||||
} else {
|
||||
strings.setLanguage('en');
|
||||
|
|
18
loc/pt_BR.js
18
loc/pt_BR.js
|
@ -1,7 +1,6 @@
|
|||
module.exports = {
|
||||
_: {
|
||||
storage_is_encrypted:
|
||||
'O armazenamento está encriptado. Uma password é necessaria para desencriptar',
|
||||
storage_is_encrypted: 'O armazenamento está encriptado. Uma password é necessaria para desencriptar',
|
||||
enter_password: 'Inserir password',
|
||||
bad_password: 'pasword errada, tentar novamente',
|
||||
},
|
||||
|
@ -56,8 +55,7 @@ module.exports = {
|
|||
list: {
|
||||
tabBarLabel: 'Transações',
|
||||
title: 'Minhas Transações',
|
||||
description:
|
||||
'Uma lista de transações feitas ou recebidas nas suas wallets',
|
||||
description: 'Uma lista de transações feitas ou recebidas nas suas wallets',
|
||||
conf: 'conf',
|
||||
},
|
||||
details: {
|
||||
|
@ -89,8 +87,7 @@ module.exports = {
|
|||
title: 'Criar Transacção',
|
||||
error: 'Erro ao criar transação. Endereço inválido ou quantia?',
|
||||
go_back: 'Voltar',
|
||||
this_is_hex:
|
||||
'Este é o hex da transação, assinado e pronto para ser difundido para a network. Continuar?',
|
||||
this_is_hex: 'Este é o hex da transação, assinado e pronto para ser difundido para a network. Continuar?',
|
||||
to: 'Para',
|
||||
amount: 'Quantia',
|
||||
fee: 'Taxa',
|
||||
|
@ -133,15 +130,12 @@ module.exports = {
|
|||
'legítimo a um terceiro, mas que secretamente vai manter o seu armazenamento principal ' +
|
||||
'com as moedas em segurança.',
|
||||
help2:
|
||||
'Este novo armazenamento é completamente funcional, e pode guardar ' +
|
||||
'um valor minímo para parecer mais real.',
|
||||
'Este novo armazenamento é completamente funcional, e pode guardar ' + 'um valor minímo para parecer mais real.',
|
||||
create_fake_storage: 'Criar armazenamento encriptado FALSO',
|
||||
go_back: 'Voltar',
|
||||
create_password: 'Criar password',
|
||||
create_password_explanation:
|
||||
'Password para armazenamento FALSO não deve coincidir com o principal',
|
||||
password_should_not_match:
|
||||
'Password para armazenamento FALSO não deve coincidir com o principal',
|
||||
create_password_explanation: 'Password para armazenamento FALSO não deve coincidir com o principal',
|
||||
password_should_not_match: 'Password para armazenamento FALSO não deve coincidir com o principal',
|
||||
retype_password: 'Inserir password novamente',
|
||||
passwords_do_not_match: 'Passwords não coincidem, tente novamente',
|
||||
success: 'Sucesso',
|
||||
|
|
18
loc/pt_PT.js
18
loc/pt_PT.js
|
@ -1,7 +1,6 @@
|
|||
module.exports = {
|
||||
_: {
|
||||
storage_is_encrypted:
|
||||
'O armazenamento está encriptado. Uma password é necessaria para desencriptar',
|
||||
storage_is_encrypted: 'O armazenamento está encriptado. Uma password é necessaria para desencriptar',
|
||||
enter_password: 'Inserir password',
|
||||
bad_password: 'pasword errada, tente novamente',
|
||||
},
|
||||
|
@ -56,8 +55,7 @@ module.exports = {
|
|||
list: {
|
||||
tabBarLabel: 'Transacções',
|
||||
title: 'Minhas Transacções',
|
||||
description:
|
||||
'Uma lista de transações feitas ou recebidas nas suas wallets',
|
||||
description: 'Uma lista de transações feitas ou recebidas nas suas wallets',
|
||||
conf: 'conf',
|
||||
},
|
||||
details: {
|
||||
|
@ -89,8 +87,7 @@ module.exports = {
|
|||
title: 'Criar Transacção',
|
||||
error: 'Erro ao criar transacção. Endereço inválido ou quantia?',
|
||||
go_back: 'Voltar',
|
||||
this_is_hex:
|
||||
'Este é o hex da transacção, assinado e pronto para ser difundido para a network. Continuar?',
|
||||
this_is_hex: 'Este é o hex da transacção, assinado e pronto para ser difundido para a network. Continuar?',
|
||||
to: 'Para',
|
||||
amount: 'Quantia',
|
||||
fee: 'Taxa',
|
||||
|
@ -133,15 +130,12 @@ module.exports = {
|
|||
'legítimo a um terceiro, mas que secretamente vai manter o seu armazenamento principal ' +
|
||||
'com as moedas em segurança.',
|
||||
help2:
|
||||
'Este novo armazenamento é completamente funcional, e pode guardar ' +
|
||||
'um valor minímo para parecer mais real.',
|
||||
'Este novo armazenamento é completamente funcional, e pode guardar ' + 'um valor minímo para parecer mais real.',
|
||||
create_fake_storage: 'Criar armazenamento encriptado FALSO',
|
||||
go_back: 'Voltar',
|
||||
create_password: 'Criar password',
|
||||
create_password_explanation:
|
||||
'Password para armazenamento FALSO não deve coincidir com o principal',
|
||||
password_should_not_match:
|
||||
'Password para armazenamento FALSO não deve coincidir com o principal',
|
||||
create_password_explanation: 'Password para armazenamento FALSO não deve coincidir com o principal',
|
||||
password_should_not_match: 'Password para armazenamento FALSO não deve coincidir com o principal',
|
||||
retype_password: 'Inserir password novamente',
|
||||
passwords_do_not_match: 'Passwords não coincidem, tente novamente',
|
||||
success: 'Sucesso',
|
||||
|
|
18
loc/ru.js
18
loc/ru.js
|
@ -1,7 +1,6 @@
|
|||
module.exports = {
|
||||
_: {
|
||||
storage_is_encrypted:
|
||||
'Ваше хранилище зашифровано. Введите пароль для расшифровки',
|
||||
storage_is_encrypted: 'Ваше хранилище зашифровано. Введите пароль для расшифровки',
|
||||
enter_password: 'Введите пароль',
|
||||
bad_password: 'Неверный пароль, попробуйте еще раз',
|
||||
months_ago: 'месяцев назад',
|
||||
|
@ -14,8 +13,7 @@ module.exports = {
|
|||
tabBarLabel: 'Кошельки',
|
||||
app_name: 'BlueWallet',
|
||||
title: 'Мои Кошельки',
|
||||
header:
|
||||
'Кошелек это секретный (приватный) ключ, и соответствующий ему адрес на который можно получать биткоины',
|
||||
header: 'Кошелек это секретный (приватный) ключ, и соответствующий ему адрес на который можно получать биткоины',
|
||||
add: 'Добавить Кошелек',
|
||||
create_a_wallet: 'Создать кошелек',
|
||||
create_a_wallet1: 'Это бесплатно и вы можете создать',
|
||||
|
@ -95,11 +93,9 @@ module.exports = {
|
|||
},
|
||||
create: {
|
||||
title: 'Создать Транзакцию',
|
||||
error:
|
||||
'Ошибка при создании транзакции. Неправильный адрес назначения или недостаточно средств?',
|
||||
error: 'Ошибка при создании транзакции. Неправильный адрес назначения или недостаточно средств?',
|
||||
go_back: 'Назад',
|
||||
this_is_hex:
|
||||
'Это данные транзакции. Транзакция подписана и готова быть транслирована в сеть. Продолжить?',
|
||||
this_is_hex: 'Это данные транзакции. Транзакция подписана и готова быть транслирована в сеть. Продолжить?',
|
||||
to: 'Куда',
|
||||
amount: 'Сколько',
|
||||
fee: 'Комиссия',
|
||||
|
@ -147,10 +143,8 @@ module.exports = {
|
|||
create_fake_storage: 'Создать фальшивое хранилище',
|
||||
go_back: 'Назад',
|
||||
create_password: 'Придумайте пароль',
|
||||
create_password_explanation:
|
||||
'Пароль для фальшивого хранилища не должен быть таким же как основной пароль',
|
||||
password_should_not_match:
|
||||
'Пароль для фальшивого хранилища не должен быть таким же как основной пароль',
|
||||
create_password_explanation: 'Пароль для фальшивого хранилища не должен быть таким же как основной пароль',
|
||||
password_should_not_match: 'Пароль для фальшивого хранилища не должен быть таким же как основной пароль',
|
||||
retype_password: 'Наберите пароль повторно',
|
||||
passwords_do_not_match: 'Пароли не совпадают, попробуйте еще раз',
|
||||
success: 'Операция успешна',
|
||||
|
|
18
loc/ua.js
18
loc/ua.js
|
@ -1,7 +1,6 @@
|
|||
module.exports = {
|
||||
_: {
|
||||
storage_is_encrypted:
|
||||
'Ваше сховище зашифроване. Введіть пароль для розшифровки',
|
||||
storage_is_encrypted: 'Ваше сховище зашифроване. Введіть пароль для розшифровки',
|
||||
enter_password: 'Введіть пароль',
|
||||
bad_password: 'Невірний пароль, спробуйте ще раз',
|
||||
},
|
||||
|
@ -10,8 +9,7 @@ module.exports = {
|
|||
tabBarLabel: 'Гаманці',
|
||||
app_name: 'BlueWallet',
|
||||
title: 'Мої Біткоїн Гаманці',
|
||||
header:
|
||||
'Гаманець це секретний (приватний) ключ, і відповідна йому адреса на яку можна отримувати біткоїни',
|
||||
header: 'Гаманець це секретний (приватний) ключ, і відповідна йому адреса на яку можна отримувати біткоїни',
|
||||
add: 'Додати Гаманець',
|
||||
},
|
||||
add: {
|
||||
|
@ -85,11 +83,9 @@ module.exports = {
|
|||
},
|
||||
create: {
|
||||
title: 'Створити Транзакцію',
|
||||
error:
|
||||
'Помилка при створенні транзакції. Невiрна адреса призначення або недостатньо коштiв?',
|
||||
error: 'Помилка при створенні транзакції. Невiрна адреса призначення або недостатньо коштiв?',
|
||||
go_back: 'Назад',
|
||||
this_is_hex:
|
||||
'Це дані транзакції. Транзакція підписана і готова бути трансльована в мережу. Продовжити?',
|
||||
this_is_hex: 'Це дані транзакції. Транзакція підписана і готова бути трансльована в мережу. Продовжити?',
|
||||
to: 'Куди',
|
||||
amount: 'Скільки',
|
||||
fee: 'Комісія',
|
||||
|
@ -137,10 +133,8 @@ module.exports = {
|
|||
create_fake_storage: 'Створити фальшиве сховище',
|
||||
go_back: 'Назад',
|
||||
create_password: 'Придумайте пароль',
|
||||
create_password_explanation:
|
||||
'Пароль для фальшивого сховіща не має буті таким же як основній пароль',
|
||||
password_should_not_match:
|
||||
'Пароль для фальшивого сховища не має бути таким же як основний пароль',
|
||||
create_password_explanation: 'Пароль для фальшивого сховіща не має буті таким же як основній пароль',
|
||||
password_should_not_match: 'Пароль для фальшивого сховища не має бути таким же як основний пароль',
|
||||
retype_password: 'Наберіть пароль ще раз',
|
||||
passwords_do_not_match: 'Паролі не збігаються, спробуйте ще раз',
|
||||
success: 'Операція успішна',
|
||||
|
|
|
@ -9,15 +9,7 @@
|
|||
let bitcoinjs = require('bitcoinjs-lib');
|
||||
const toSatoshi = num => parseInt((num * 100000000).toFixed(0));
|
||||
|
||||
exports.createSegwitTransaction = function(
|
||||
utxos,
|
||||
toAddress,
|
||||
amount,
|
||||
fixedFee,
|
||||
WIF,
|
||||
changeAddress,
|
||||
sequence,
|
||||
) {
|
||||
exports.createSegwitTransaction = function(utxos, toAddress, amount, fixedFee, WIF, changeAddress, sequence) {
|
||||
changeAddress = changeAddress || exports.WIF2segwitAddress(WIF);
|
||||
if (sequence === undefined) {
|
||||
sequence = bitcoinjs.Transaction.DEFAULT_SEQUENCE;
|
||||
|
@ -27,9 +19,7 @@ exports.createSegwitTransaction = function(
|
|||
let keyPair = bitcoinjs.ECPair.fromWIF(WIF);
|
||||
let pubKey = keyPair.getPublicKeyBuffer();
|
||||
let pubKeyHash = bitcoinjs.crypto.hash160(pubKey);
|
||||
let redeemScript = bitcoinjs.script.witnessPubKeyHash.output.encode(
|
||||
pubKeyHash,
|
||||
);
|
||||
let redeemScript = bitcoinjs.script.witnessPubKeyHash.output.encode(pubKeyHash);
|
||||
|
||||
let txb = new bitcoinjs.TransactionBuilder();
|
||||
let unspentAmount = 0;
|
||||
|
@ -45,33 +35,18 @@ exports.createSegwitTransaction = function(
|
|||
txb.addOutput(toAddress, amountToOutput);
|
||||
if (amountToOutput + feeInSatoshis < unspentAmount) {
|
||||
// sending less than we have, so the rest should go back
|
||||
txb.addOutput(
|
||||
changeAddress,
|
||||
unspentAmount - amountToOutput - feeInSatoshis,
|
||||
);
|
||||
txb.addOutput(changeAddress, unspentAmount - amountToOutput - feeInSatoshis);
|
||||
}
|
||||
|
||||
for (let c = 0; c < utxos.length; c++) {
|
||||
txb.sign(
|
||||
c,
|
||||
keyPair,
|
||||
redeemScript,
|
||||
null,
|
||||
parseInt((utxos[c].amount * 100000000).toFixed(0)),
|
||||
);
|
||||
txb.sign(c, keyPair, redeemScript, null, parseInt((utxos[c].amount * 100000000).toFixed(0)));
|
||||
}
|
||||
|
||||
let tx = txb.build();
|
||||
return tx.toHex();
|
||||
};
|
||||
|
||||
exports.createRBFSegwitTransaction = function(
|
||||
txhex,
|
||||
addressReplaceMap,
|
||||
feeDelta,
|
||||
WIF,
|
||||
utxodata,
|
||||
) {
|
||||
exports.createRBFSegwitTransaction = function(txhex, addressReplaceMap, feeDelta, WIF, utxodata) {
|
||||
if (feeDelta < 0) {
|
||||
throw Error('replace-by-fee requires increased fee, not decreased');
|
||||
}
|
||||
|
@ -89,11 +64,7 @@ exports.createRBFSegwitTransaction = function(
|
|||
// creating TX
|
||||
let txb = new bitcoinjs.TransactionBuilder();
|
||||
for (let unspent of tx.ins) {
|
||||
txb.addInput(
|
||||
unspent.hash.reverse().toString('hex'),
|
||||
unspent.index,
|
||||
highestSequence + 1,
|
||||
);
|
||||
txb.addInput(unspent.hash.reverse().toString('hex'), unspent.index, highestSequence + 1);
|
||||
}
|
||||
|
||||
for (let o of tx.outs) {
|
||||
|
@ -113,9 +84,7 @@ exports.createRBFSegwitTransaction = function(
|
|||
let keyPair = bitcoinjs.ECPair.fromWIF(WIF);
|
||||
let pubKey = keyPair.getPublicKeyBuffer();
|
||||
let pubKeyHash = bitcoinjs.crypto.hash160(pubKey);
|
||||
let redeemScript = bitcoinjs.script.witnessPubKeyHash.output.encode(
|
||||
pubKeyHash,
|
||||
);
|
||||
let redeemScript = bitcoinjs.script.witnessPubKeyHash.output.encode(pubKeyHash);
|
||||
for (let c = 0; c < tx.ins.length; c++) {
|
||||
let txid = tx.ins[c].hash.reverse().toString('hex');
|
||||
let index = tx.ins[c].index;
|
||||
|
@ -131,12 +100,8 @@ exports.generateNewSegwitAddress = function() {
|
|||
let keyPair = bitcoinjs.ECPair.makeRandom();
|
||||
let pubKey = keyPair.getPublicKeyBuffer();
|
||||
|
||||
let witnessScript = bitcoinjs.script.witnessPubKeyHash.output.encode(
|
||||
bitcoinjs.crypto.hash160(pubKey),
|
||||
);
|
||||
let scriptPubKey = bitcoinjs.script.scriptHash.output.encode(
|
||||
bitcoinjs.crypto.hash160(witnessScript),
|
||||
);
|
||||
let witnessScript = bitcoinjs.script.witnessPubKeyHash.output.encode(bitcoinjs.crypto.hash160(pubKey));
|
||||
let scriptPubKey = bitcoinjs.script.scriptHash.output.encode(bitcoinjs.crypto.hash160(witnessScript));
|
||||
let address = bitcoinjs.address.fromOutputScript(scriptPubKey);
|
||||
|
||||
return {
|
||||
|
@ -163,23 +128,12 @@ exports.URI = function(paymentInfo) {
|
|||
exports.WIF2segwitAddress = function(WIF) {
|
||||
let keyPair = bitcoinjs.ECPair.fromWIF(WIF);
|
||||
let pubKey = keyPair.getPublicKeyBuffer();
|
||||
let witnessScript = bitcoinjs.script.witnessPubKeyHash.output.encode(
|
||||
bitcoinjs.crypto.hash160(pubKey),
|
||||
);
|
||||
let scriptPubKey = bitcoinjs.script.scriptHash.output.encode(
|
||||
bitcoinjs.crypto.hash160(witnessScript),
|
||||
);
|
||||
let witnessScript = bitcoinjs.script.witnessPubKeyHash.output.encode(bitcoinjs.crypto.hash160(pubKey));
|
||||
let scriptPubKey = bitcoinjs.script.scriptHash.output.encode(bitcoinjs.crypto.hash160(witnessScript));
|
||||
return bitcoinjs.address.fromOutputScript(scriptPubKey);
|
||||
};
|
||||
|
||||
exports.createTransaction = function(
|
||||
utxos,
|
||||
toAddress,
|
||||
_amount,
|
||||
_fixedFee,
|
||||
WIF,
|
||||
fromAddress,
|
||||
) {
|
||||
exports.createTransaction = function(utxos, toAddress, _amount, _fixedFee, WIF, fromAddress) {
|
||||
let fixedFee = toSatoshi(_fixedFee);
|
||||
let amountToOutput = toSatoshi(_amount - _fixedFee);
|
||||
let pk = bitcoinjs.ECPair.fromWIF(WIF); // eslint-disable-line new-cap
|
||||
|
|
|
@ -39,16 +39,11 @@ export default class About extends Component {
|
|||
|
||||
return (
|
||||
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={{ flex: 1 }}>
|
||||
<BlueHeaderDefaultSub
|
||||
leftText={'about'}
|
||||
onClose={() => this.props.navigation.goBack()}
|
||||
/>
|
||||
<BlueHeaderDefaultSub leftText={'about'} onClose={() => this.props.navigation.goBack()} />
|
||||
|
||||
<BlueCard>
|
||||
<ScrollView maxHeight={height - 150}>
|
||||
<BlueText h4>
|
||||
BlueWallet is free and opensource Bitcoin wallet. Licensed MIT.
|
||||
</BlueText>
|
||||
<BlueText h4>BlueWallet is free and opensource Bitcoin wallet. Licensed MIT.</BlueText>
|
||||
|
||||
<BlueButton
|
||||
icon={{
|
||||
|
|
|
@ -2,14 +2,7 @@
|
|||
import React, { Component } from 'react';
|
||||
import { ScrollView } from 'react-native';
|
||||
import Ionicons from 'react-native-vector-icons/Ionicons';
|
||||
import {
|
||||
BlueLoading,
|
||||
BlueButton,
|
||||
SafeBlueArea,
|
||||
BlueCard,
|
||||
BlueText,
|
||||
BlueHeader,
|
||||
} from '../BlueComponents';
|
||||
import { BlueLoading, BlueButton, SafeBlueArea, BlueCard, BlueText, BlueHeader } from '../BlueComponents';
|
||||
import PropTypes from 'prop-types';
|
||||
/** @type {AppStorage} */
|
||||
let BlueApp = require('../BlueApp');
|
||||
|
@ -21,11 +14,7 @@ export default class PlausibleDeniability extends Component {
|
|||
static navigationOptions = {
|
||||
tabBarLabel: loc.plausibledeniability.title,
|
||||
tabBarIcon: ({ tintColor, focused }) => (
|
||||
<Ionicons
|
||||
name={focused ? 'ios-settings' : 'ios-settings-outline'}
|
||||
size={26}
|
||||
style={{ color: tintColor }}
|
||||
/>
|
||||
<Ionicons name={focused ? 'ios-settings' : 'ios-settings-outline'} size={26} style={{ color: tintColor }} />
|
||||
),
|
||||
};
|
||||
|
||||
|
@ -78,9 +67,7 @@ export default class PlausibleDeniability extends Component {
|
|||
loc.plausibledeniability.create_password_explanation,
|
||||
);
|
||||
if (p1 === BlueApp.cachedPassword) {
|
||||
return alert(
|
||||
loc.plausibledeniability.password_should_not_match,
|
||||
);
|
||||
return alert(loc.plausibledeniability.password_should_not_match);
|
||||
}
|
||||
|
||||
if (!p1) {
|
||||
|
|
|
@ -70,10 +70,7 @@ export default class ReceiveDetails extends Component {
|
|||
return <BlueSpacing />;
|
||||
}
|
||||
})()}
|
||||
<BlueHeaderDefaultSub
|
||||
leftText={loc.receive.list.header}
|
||||
onClose={() => this.props.navigation.goBack()}
|
||||
/>
|
||||
<BlueHeaderDefaultSub leftText={loc.receive.list.header} onClose={() => this.props.navigation.goBack()} />
|
||||
|
||||
<View
|
||||
style={{
|
||||
|
|
|
@ -1,13 +1,7 @@
|
|||
import React, { Component } from 'react';
|
||||
import { ListView, Dimensions } from 'react-native';
|
||||
import Ionicons from 'react-native-vector-icons/Ionicons';
|
||||
import {
|
||||
BlueLoading,
|
||||
SafeBlueArea,
|
||||
BlueCard,
|
||||
BlueListItem,
|
||||
BlueHeader,
|
||||
} from '../../BlueComponents';
|
||||
import { BlueLoading, SafeBlueArea, BlueCard, BlueListItem, BlueHeader } from '../../BlueComponents';
|
||||
import PropTypes from 'prop-types';
|
||||
/** @type {AppStorage} */
|
||||
let BlueApp = require('../../BlueApp');
|
||||
|
@ -20,11 +14,7 @@ export default class ReceiveList extends Component {
|
|||
static navigationOptions = {
|
||||
tabBarLabel: loc.receive.list.tabBarLabel,
|
||||
tabBarIcon: ({ tintColor, focused }) => (
|
||||
<Ionicons
|
||||
name={focused ? 'ios-cash' : 'ios-cash-outline'}
|
||||
size={26}
|
||||
style={{ color: tintColor }}
|
||||
/>
|
||||
<Ionicons name={focused ? 'ios-cash' : 'ios-cash-outline'} size={26} style={{ color: tintColor }} />
|
||||
),
|
||||
};
|
||||
|
||||
|
|
|
@ -20,11 +20,7 @@ export default class Selftest extends Component {
|
|||
static navigationOptions = {
|
||||
tabBarLabel: 'Self test',
|
||||
tabBarIcon: ({ tintColor, focused }) => (
|
||||
<Ionicons
|
||||
name={focused ? 'ios-settings' : 'ios-settings-outline'}
|
||||
size={26}
|
||||
style={{ color: tintColor }}
|
||||
/>
|
||||
<Ionicons name={focused ? 'ios-settings' : 'ios-settings-outline'} size={26} style={{ color: tintColor }} />
|
||||
),
|
||||
};
|
||||
|
||||
|
@ -65,8 +61,7 @@ export default class Selftest extends Component {
|
|||
// utxos as received from blockcypher
|
||||
let utxos = [
|
||||
{
|
||||
tx_hash:
|
||||
'2f445cf016fa2772db7d473bff97515355b4e6148e1c980ce351d47cf54c517f',
|
||||
tx_hash: '2f445cf016fa2772db7d473bff97515355b4e6148e1c980ce351d47cf54c517f',
|
||||
block_height: 523186,
|
||||
tx_input_n: -1,
|
||||
tx_output_n: 1,
|
||||
|
@ -101,12 +96,10 @@ export default class Selftest extends Component {
|
|||
double_spend: false,
|
||||
ref_balance: 300000,
|
||||
spent: false,
|
||||
tx_hash:
|
||||
'dc3605040a03724bc584ed43bc22a559f5d32a1b0708ca05b20b9018fdd523ef',
|
||||
tx_hash: 'dc3605040a03724bc584ed43bc22a559f5d32a1b0708ca05b20b9018fdd523ef',
|
||||
tx_input_n: -1,
|
||||
tx_output_n: 0,
|
||||
txid:
|
||||
'dc3605040a03724bc584ed43bc22a559f5d32a1b0708ca05b20b9018fdd523ef',
|
||||
txid: 'dc3605040a03724bc584ed43bc22a559f5d32a1b0708ca05b20b9018fdd523ef',
|
||||
value: 200000,
|
||||
vout: 0,
|
||||
},
|
||||
|
@ -118,12 +111,10 @@ export default class Selftest extends Component {
|
|||
double_spend: false,
|
||||
ref_balance: 100000,
|
||||
spent: false,
|
||||
tx_hash:
|
||||
'c473c104febfe6621804976d1082a1468c1198d0339e35f30a8ba1515d9eb017',
|
||||
tx_hash: 'c473c104febfe6621804976d1082a1468c1198d0339e35f30a8ba1515d9eb017',
|
||||
tx_input_n: -1,
|
||||
tx_output_n: 0,
|
||||
txid:
|
||||
'c473c104febfe6621804976d1082a1468c1198d0339e35f30a8ba1515d9eb017',
|
||||
txid: 'c473c104febfe6621804976d1082a1468c1198d0339e35f30a8ba1515d9eb017',
|
||||
value: 100000,
|
||||
vout: 0,
|
||||
},
|
||||
|
@ -160,8 +151,7 @@ export default class Selftest extends Component {
|
|||
// utxos as received from blockcypher
|
||||
let utxo = [
|
||||
{
|
||||
tx_hash:
|
||||
'0f5eea78fb19e72b55bd119252ff29fc16c503d0e956a9c1b5b2ab0e95e0c323',
|
||||
tx_hash: '0f5eea78fb19e72b55bd119252ff29fc16c503d0e956a9c1b5b2ab0e95e0c323',
|
||||
block_height: 514991,
|
||||
tx_input_n: -1,
|
||||
tx_output_n: 2,
|
||||
|
@ -174,20 +164,12 @@ export default class Selftest extends Component {
|
|||
},
|
||||
];
|
||||
|
||||
let tx = l.createTx(
|
||||
utxo,
|
||||
0.001,
|
||||
0.0001,
|
||||
'1QHf8Gp3wfmFiSdEX4FtrssCGR68diN1cj',
|
||||
);
|
||||
let tx = l.createTx(utxo, 0.001, 0.0001, '1QHf8Gp3wfmFiSdEX4FtrssCGR68diN1cj');
|
||||
let bitcoin = require('bitcoinjs-lib');
|
||||
let txDecoded = bitcoin.Transaction.fromHex(tx);
|
||||
let txid = txDecoded.getId();
|
||||
|
||||
if (
|
||||
txid !==
|
||||
'110f51d28d585e922adbf701cba802e549b8fe3a53fa5d62426ab42549c9b6de'
|
||||
) {
|
||||
if (txid !== '110f51d28d585e922adbf701cba802e549b8fe3a53fa5d62426ab42549c9b6de') {
|
||||
errorMessage += 'created txid doesnt match; ';
|
||||
isOk = false;
|
||||
}
|
||||
|
@ -234,10 +216,7 @@ export default class Selftest extends Component {
|
|||
let scriptSig = bitcoin.script.witnessPubKeyHash.output.encode(keyhash);
|
||||
let addressBytes = bitcoin.crypto.hash160(scriptSig);
|
||||
let outputScript = bitcoin.script.scriptHash.output.encode(addressBytes);
|
||||
let address = bitcoin.address.fromOutputScript(
|
||||
outputScript,
|
||||
bitcoin.networks.bitcoin,
|
||||
);
|
||||
let address = bitcoin.address.fromOutputScript(outputScript, bitcoin.networks.bitcoin);
|
||||
|
||||
if (address !== '3GcKN7q7gZuZ8eHygAhHrvPa5zZbG5Q1rK') {
|
||||
errorMessage += 'bip49 is not ok; ';
|
||||
|
|
|
@ -56,13 +56,7 @@ export default class SendCreate extends Component {
|
|||
utxo = this.state.fromWallet.utxo;
|
||||
let startTime = Date.now();
|
||||
|
||||
tx = this.state.fromWallet.createTx(
|
||||
utxo,
|
||||
this.state.amount,
|
||||
this.state.fee,
|
||||
this.state.address,
|
||||
this.state.memo,
|
||||
);
|
||||
tx = this.state.fromWallet.createTx(utxo, this.state.amount, this.state.fee, this.state.address, this.state.memo);
|
||||
let endTime = Date.now();
|
||||
console.log('create tx ', (endTime - startTime) / 1000, 'sec');
|
||||
|
||||
|
@ -113,8 +107,7 @@ export default class SendCreate extends Component {
|
|||
} else {
|
||||
this.setState({ broadcastErrorMessage: '' });
|
||||
this.setState({
|
||||
broadcastSuccessMessage:
|
||||
'Success! TXID: ' + JSON.stringify(result.result),
|
||||
broadcastSuccessMessage: 'Success! TXID: ' + JSON.stringify(result.result),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -124,19 +117,11 @@ export default class SendCreate extends Component {
|
|||
return (
|
||||
<SafeBlueArea style={{ flex: 1, paddingTop: 20 }}>
|
||||
<BlueSpacing />
|
||||
<BlueCard
|
||||
title={loc.send.create.title}
|
||||
style={{ alignItems: 'center', flex: 1 }}
|
||||
>
|
||||
<BlueCard title={loc.send.create.title} style={{ alignItems: 'center', flex: 1 }}>
|
||||
<BlueText>{loc.send.create.error}</BlueText>
|
||||
<FormValidationMessage>
|
||||
{this.state.errorMessage}
|
||||
</FormValidationMessage>
|
||||
<FormValidationMessage>{this.state.errorMessage}</FormValidationMessage>
|
||||
</BlueCard>
|
||||
<BlueButton
|
||||
onPress={() => this.props.navigation.goBack()}
|
||||
title={loc.send.create.go_back}
|
||||
/>
|
||||
<BlueButton onPress={() => this.props.navigation.goBack()} title={loc.send.create.go_back} />
|
||||
</SafeBlueArea>
|
||||
);
|
||||
}
|
||||
|
@ -148,10 +133,7 @@ export default class SendCreate extends Component {
|
|||
return (
|
||||
<SafeBlueArea style={{ flex: 1, paddingTop: 20 }}>
|
||||
<BlueSpacing />
|
||||
<BlueCard
|
||||
title={loc.send.create.title}
|
||||
style={{ alignItems: 'center', flex: 1 }}
|
||||
>
|
||||
<BlueCard title={loc.send.create.title} style={{ alignItems: 'center', flex: 1 }}>
|
||||
<BlueText>{loc.send.create.this_is_hex}</BlueText>
|
||||
|
||||
<TextInput
|
||||
|
@ -182,8 +164,7 @@ export default class SendCreate extends Component {
|
|||
{loc.send.create.tx_size}: {this.state.size} Bytes
|
||||
</BlueText>
|
||||
<BlueText>
|
||||
{loc.send.create.satoshi_per_byte}: {this.state.satoshiPerByte}{' '}
|
||||
Sat/B
|
||||
{loc.send.create.satoshi_per_byte}: {this.state.satoshiPerByte} Sat/B
|
||||
</BlueText>
|
||||
<BlueText>
|
||||
{loc.send.create.memo}: {this.state.memo}
|
||||
|
@ -210,12 +191,8 @@ export default class SendCreate extends Component {
|
|||
title={loc.send.create.go_back}
|
||||
/>
|
||||
|
||||
<FormValidationMessage>
|
||||
{this.state.broadcastErrorMessage}
|
||||
</FormValidationMessage>
|
||||
<Text style={{ padding: 0, color: '#0f0' }}>
|
||||
{this.state.broadcastSuccessMessage}
|
||||
</Text>
|
||||
<FormValidationMessage>{this.state.broadcastErrorMessage}</FormValidationMessage>
|
||||
<Text style={{ padding: 0, color: '#0f0' }}>{this.state.broadcastSuccessMessage}</Text>
|
||||
</SafeBlueArea>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -38,11 +38,9 @@ export default class SendDetails extends Component {
|
|||
super(props);
|
||||
let startTime = Date.now();
|
||||
let address;
|
||||
if (props.navigation.state.params)
|
||||
address = props.navigation.state.params.address;
|
||||
if (props.navigation.state.params) address = props.navigation.state.params.address;
|
||||
let fromAddress;
|
||||
if (props.navigation.state.params)
|
||||
fromAddress = props.navigation.state.params.fromAddress;
|
||||
if (props.navigation.state.params) fromAddress = props.navigation.state.params.fromAddress;
|
||||
let fromWallet = {};
|
||||
|
||||
let startTime2 = Date.now();
|
||||
|
@ -164,9 +162,7 @@ export default class SendDetails extends Component {
|
|||
if (!this.state.fromWallet.getAddress) {
|
||||
return (
|
||||
<View style={{ flex: 1, paddingTop: 20 }}>
|
||||
<Text>
|
||||
System error: Source wallet not found (this should never happen)
|
||||
</Text>
|
||||
<Text>System error: Source wallet not found (this should never happen)</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
@ -180,10 +176,7 @@ export default class SendDetails extends Component {
|
|||
return <BlueSpacing />;
|
||||
}
|
||||
})()}
|
||||
<BlueCard
|
||||
title={loc.send.details.title}
|
||||
style={{ alignItems: 'center', flex: 1 }}
|
||||
>
|
||||
<BlueCard title={loc.send.details.title} style={{ alignItems: 'center', flex: 1 }}>
|
||||
<BlueFormInputAddress
|
||||
style={{ width: 250 }}
|
||||
onChangeText={text => this.setState({ address: text })}
|
||||
|
@ -192,18 +185,14 @@ export default class SendDetails extends Component {
|
|||
/>
|
||||
|
||||
<BlueFormInput
|
||||
onChangeText={text =>
|
||||
this.setState({ amount: text.replace(',', '.') })
|
||||
}
|
||||
onChangeText={text => this.setState({ amount: text.replace(',', '.') })}
|
||||
keyboardType={'numeric'}
|
||||
placeholder={loc.send.details.amount_placeholder}
|
||||
value={this.state.amount + ''}
|
||||
/>
|
||||
|
||||
<BlueFormInput
|
||||
onChangeText={text =>
|
||||
this.setState({ fee: text.replace(',', '.') })
|
||||
}
|
||||
onChangeText={text => this.setState({ fee: text.replace(',', '.') })}
|
||||
keyboardType={'numeric'}
|
||||
placeholder={loc.send.details.fee_placeholder}
|
||||
value={this.state.fee + ''}
|
||||
|
@ -218,11 +207,7 @@ export default class SendDetails extends Component {
|
|||
<BlueSpacing20 />
|
||||
<BlueText>
|
||||
{loc.send.details.remaining_balance}:{' '}
|
||||
{this.recalculateAvailableBalance(
|
||||
this.state.fromWallet.getBalance(),
|
||||
this.state.amount,
|
||||
this.state.fee,
|
||||
)}{' '}
|
||||
{this.recalculateAvailableBalance(this.state.fromWallet.getBalance(), this.state.amount, this.state.fee)}{' '}
|
||||
BTC
|
||||
</BlueText>
|
||||
</BlueCard>
|
||||
|
@ -231,10 +216,7 @@ export default class SendDetails extends Component {
|
|||
|
||||
<View style={{ flex: 1, flexDirection: 'row' }}>
|
||||
<View style={{ flex: 0.33 }}>
|
||||
<BlueButton
|
||||
onPress={() => this.props.navigation.goBack()}
|
||||
title={loc.send.details.cancel}
|
||||
/>
|
||||
<BlueButton onPress={() => this.props.navigation.goBack()} title={loc.send.details.cancel} />
|
||||
</View>
|
||||
<View style={{ flex: 0.33 }}>
|
||||
<BlueButton
|
||||
|
@ -249,10 +231,7 @@ export default class SendDetails extends Component {
|
|||
/>
|
||||
</View>
|
||||
<View style={{ flex: 0.33 }}>
|
||||
<BlueButton
|
||||
onPress={() => this.createTransaction()}
|
||||
title={loc.send.details.create}
|
||||
/>
|
||||
<BlueButton onPress={() => this.createTransaction()} title={loc.send.details.create} />
|
||||
</View>
|
||||
</View>
|
||||
</SafeBlueArea>
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
import React, { Component } from 'react';
|
||||
import { Dimensions, ActivityIndicator, View, ListView } from 'react-native';
|
||||
import Ionicons from 'react-native-vector-icons/Ionicons';
|
||||
import {
|
||||
SafeBlueArea,
|
||||
BlueCard,
|
||||
BlueListItem,
|
||||
BlueHeader,
|
||||
} from '../../BlueComponents';
|
||||
import { SafeBlueArea, BlueCard, BlueListItem, BlueHeader } from '../../BlueComponents';
|
||||
import PropTypes from 'prop-types';
|
||||
let EV = require('../../events');
|
||||
/** @type {AppStorage} */
|
||||
|
@ -19,11 +14,7 @@ export default class SendList extends Component {
|
|||
static navigationOptions = {
|
||||
tabBarLabel: loc.send.list.tabBarLabel,
|
||||
tabBarIcon: ({ tintColor, focused }) => (
|
||||
<Ionicons
|
||||
name={focused ? 'md-paper-plane' : 'md-paper-plane'}
|
||||
size={26}
|
||||
style={{ color: tintColor }}
|
||||
/>
|
||||
<Ionicons name={focused ? 'md-paper-plane' : 'md-paper-plane'} size={26} style={{ color: tintColor }} />
|
||||
),
|
||||
};
|
||||
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
/* global alert */
|
||||
import React from 'react';
|
||||
import {
|
||||
Text,
|
||||
ActivityIndicator,
|
||||
Button,
|
||||
View,
|
||||
TouchableOpacity,
|
||||
} from 'react-native';
|
||||
import { Text, ActivityIndicator, Button, View, TouchableOpacity } from 'react-native';
|
||||
import { Camera, Permissions } from 'expo';
|
||||
import PropTypes from 'prop-types';
|
||||
let EV = require('../../events');
|
||||
|
@ -61,11 +55,7 @@ export default class CameraExample extends React.Component {
|
|||
} else {
|
||||
return (
|
||||
<View style={{ flex: 1 }}>
|
||||
<Camera
|
||||
style={{ flex: 1 }}
|
||||
type={this.state.type}
|
||||
onBarCodeRead={ret => this.onBarCodeRead(ret)}
|
||||
>
|
||||
<Camera style={{ flex: 1 }} type={this.state.type} onBarCodeRead={ret => this.onBarCodeRead(ret)}>
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
|
|
|
@ -2,14 +2,7 @@
|
|||
import React, { Component } from 'react';
|
||||
import { ScrollView, View, Picker } from 'react-native';
|
||||
import { FormValidationMessage } from 'react-native-elements';
|
||||
import {
|
||||
BlueLoading,
|
||||
BlueButton,
|
||||
SafeBlueArea,
|
||||
BlueCard,
|
||||
BlueText,
|
||||
BlueHeaderDefaultSub,
|
||||
} from '../BlueComponents';
|
||||
import { BlueLoading, BlueButton, SafeBlueArea, BlueCard, BlueText, BlueHeaderDefaultSub } from '../BlueComponents';
|
||||
import PropTypes from 'prop-types';
|
||||
/** @type {AppStorage} */
|
||||
let BlueApp = require('../BlueApp');
|
||||
|
@ -43,10 +36,7 @@ export default class Settings extends Component {
|
|||
|
||||
return (
|
||||
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={{ flex: 1 }}>
|
||||
<BlueHeaderDefaultSub
|
||||
leftText={loc.settings.header}
|
||||
onClose={() => this.props.navigation.goBack()}
|
||||
/>
|
||||
<BlueHeaderDefaultSub leftText={loc.settings.header} onClose={() => this.props.navigation.goBack()} />
|
||||
|
||||
<BlueCard>
|
||||
<ScrollView maxHeight={450}>
|
||||
|
@ -56,9 +46,7 @@ export default class Settings extends Component {
|
|||
<View>
|
||||
<BlueText>{loc.settings.storage_encrypted}</BlueText>
|
||||
<BlueButton
|
||||
onPress={() =>
|
||||
this.props.navigation.navigate('PlausibleDeniability')
|
||||
}
|
||||
onPress={() => this.props.navigation.navigate('PlausibleDeniability')}
|
||||
title={loc.settings.plausible_deniability}
|
||||
/>
|
||||
</View>
|
||||
|
@ -66,9 +54,7 @@ export default class Settings extends Component {
|
|||
} else {
|
||||
return (
|
||||
<View>
|
||||
<FormValidationMessage>
|
||||
{loc.settings.storage_not_encrypted}
|
||||
</FormValidationMessage>
|
||||
<FormValidationMessage>{loc.settings.storage_not_encrypted}</FormValidationMessage>
|
||||
<BlueButton
|
||||
icon={{
|
||||
name: 'shield',
|
||||
|
@ -77,18 +63,12 @@ export default class Settings extends Component {
|
|||
}}
|
||||
onPress={async () => {
|
||||
this.setState({ isLoading: true });
|
||||
let p1 = await prompt(
|
||||
loc.settings.password,
|
||||
loc.settings.password_explain,
|
||||
);
|
||||
let p1 = await prompt(loc.settings.password, loc.settings.password_explain);
|
||||
if (!p1) {
|
||||
this.setState({ isLoading: false });
|
||||
return;
|
||||
}
|
||||
let p2 = await prompt(
|
||||
loc.settings.password,
|
||||
loc.settings.retype_password,
|
||||
);
|
||||
let p2 = await prompt(loc.settings.password, loc.settings.retype_password);
|
||||
if (p1 === p2) {
|
||||
await BlueApp.encryptStorage(p1);
|
||||
this.setState({
|
||||
|
@ -107,10 +87,7 @@ export default class Settings extends Component {
|
|||
}
|
||||
})()}
|
||||
|
||||
<BlueButton
|
||||
onPress={() => this.props.navigation.navigate('About')}
|
||||
title={loc.settings.about}
|
||||
/>
|
||||
<BlueButton onPress={() => this.props.navigation.navigate('About')} title={loc.settings.about} />
|
||||
</ScrollView>
|
||||
|
||||
<Picker
|
||||
|
@ -122,31 +99,11 @@ export default class Settings extends Component {
|
|||
return this.setState({ language: itemValue });
|
||||
}}
|
||||
>
|
||||
<Picker.Item
|
||||
color={BlueApp.settings.foregroundColor}
|
||||
label="English"
|
||||
value="en"
|
||||
/>
|
||||
<Picker.Item
|
||||
color={BlueApp.settings.foregroundColor}
|
||||
label="Русский"
|
||||
value="ru"
|
||||
/>
|
||||
<Picker.Item
|
||||
color={BlueApp.settings.foregroundColor}
|
||||
label="Українська"
|
||||
value="ua"
|
||||
/>
|
||||
<Picker.Item
|
||||
color={BlueApp.settings.foregroundColor}
|
||||
label="Spanish"
|
||||
value="es"
|
||||
/>
|
||||
<Picker.Item
|
||||
color={BlueApp.settings.foregroundColor}
|
||||
label="Portuguese"
|
||||
value="pt"
|
||||
/>
|
||||
<Picker.Item color={BlueApp.settings.foregroundColor} label="English" value="en" />
|
||||
<Picker.Item color={BlueApp.settings.foregroundColor} label="Русский" value="ru" />
|
||||
<Picker.Item color={BlueApp.settings.foregroundColor} label="Українська" value="ua" />
|
||||
<Picker.Item color={BlueApp.settings.foregroundColor} label="Spanish" value="es" />
|
||||
<Picker.Item color={BlueApp.settings.foregroundColor} label="Portuguese" value="pt" />
|
||||
</Picker>
|
||||
</BlueCard>
|
||||
</SafeBlueArea>
|
||||
|
|
|
@ -30,8 +30,7 @@ export default class SendCreate extends Component {
|
|||
this.state = {
|
||||
isLoading: true,
|
||||
feeDelta: props.navigation.state.params.feeDelta,
|
||||
newDestinationAddress:
|
||||
props.navigation.state.params.newDestinationAddress,
|
||||
newDestinationAddress: props.navigation.state.params.newDestinationAddress,
|
||||
txid: props.navigation.state.params.txid,
|
||||
sourceTx: props.navigation.state.params.sourceTx,
|
||||
fromWallet: props.navigation.state.params.sourceWallet,
|
||||
|
@ -90,9 +89,7 @@ export default class SendCreate extends Component {
|
|||
transferAmount = transferAmount.div(100000000).toString(10);
|
||||
}
|
||||
}
|
||||
let oldFee = new BigNumber(
|
||||
totalInputAmountSatoshi - totalOutputAmountSatoshi,
|
||||
);
|
||||
let oldFee = new BigNumber(totalInputAmountSatoshi - totalOutputAmountSatoshi);
|
||||
oldFee = parseFloat(oldFee.div(100000000).toString(10));
|
||||
|
||||
console.log('changeAddress = ', changeAddress);
|
||||
|
@ -132,10 +129,7 @@ export default class SendCreate extends Component {
|
|||
BlueApp.tx_metadata[txid]['txhex'] = tx;
|
||||
//
|
||||
BlueApp.saveToDisk();
|
||||
console.log(
|
||||
'BlueApp.txMetadata[this.state.txid]',
|
||||
BlueApp.tx_metadata[this.state.txid],
|
||||
);
|
||||
console.log('BlueApp.txMetadata[this.state.txid]', BlueApp.tx_metadata[this.state.txid]);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
return this.setState({
|
||||
|
@ -173,8 +167,7 @@ export default class SendCreate extends Component {
|
|||
} else {
|
||||
this.setState({ broadcastErrorMessage: '' });
|
||||
this.setState({
|
||||
broadcastSuccessMessage:
|
||||
'Success! TXID: ' + JSON.stringify(result.result || result.txid),
|
||||
broadcastSuccessMessage: 'Success! TXID: ' + JSON.stringify(result.result || result.txid),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -184,21 +177,11 @@ export default class SendCreate extends Component {
|
|||
return (
|
||||
<SafeBlueArea style={{ flex: 1, paddingTop: 20 }}>
|
||||
<BlueSpacing />
|
||||
<BlueCard
|
||||
title={'Replace Transaction'}
|
||||
style={{ alignItems: 'center', flex: 1 }}
|
||||
>
|
||||
<BlueText>
|
||||
Error creating transaction. Invalid address or send amount?
|
||||
</BlueText>
|
||||
<FormValidationMessage>
|
||||
{this.state.errorMessage}
|
||||
</FormValidationMessage>
|
||||
<BlueCard title={'Replace Transaction'} style={{ alignItems: 'center', flex: 1 }}>
|
||||
<BlueText>Error creating transaction. Invalid address or send amount?</BlueText>
|
||||
<FormValidationMessage>{this.state.errorMessage}</FormValidationMessage>
|
||||
</BlueCard>
|
||||
<BlueButton
|
||||
onPress={() => this.props.navigation.goBack()}
|
||||
title="Go back"
|
||||
/>
|
||||
<BlueButton onPress={() => this.props.navigation.goBack()} title="Go back" />
|
||||
</SafeBlueArea>
|
||||
);
|
||||
}
|
||||
|
@ -218,10 +201,7 @@ export default class SendCreate extends Component {
|
|||
|
||||
<BlueText h4>This transaction is not replaceable</BlueText>
|
||||
|
||||
<BlueButton
|
||||
onPress={() => this.props.navigation.goBack()}
|
||||
title="Back"
|
||||
/>
|
||||
<BlueButton onPress={() => this.props.navigation.goBack()} title="Back" />
|
||||
</SafeBlueArea>
|
||||
);
|
||||
}
|
||||
|
@ -229,14 +209,8 @@ export default class SendCreate extends Component {
|
|||
return (
|
||||
<SafeBlueArea style={{ flex: 1, paddingTop: 20 }}>
|
||||
<BlueSpacing />
|
||||
<BlueCard
|
||||
title={'Replace Transaction'}
|
||||
style={{ alignItems: 'center', flex: 1 }}
|
||||
>
|
||||
<BlueText>
|
||||
This is transaction hex, signed and ready to be broadcast to the
|
||||
network. Continue?
|
||||
</BlueText>
|
||||
<BlueCard title={'Replace Transaction'} style={{ alignItems: 'center', flex: 1 }}>
|
||||
<BlueText>This is transaction hex, signed and ready to be broadcast to the network. Continue?</BlueText>
|
||||
|
||||
<TextInput
|
||||
style={{
|
||||
|
@ -253,20 +227,14 @@ export default class SendCreate extends Component {
|
|||
|
||||
<BlueSpacing20 />
|
||||
|
||||
<BlueText style={{ paddingTop: 20 }}>
|
||||
To: {this.state.newDestinationAddress}
|
||||
</BlueText>
|
||||
<BlueText style={{ paddingTop: 20 }}>To: {this.state.newDestinationAddress}</BlueText>
|
||||
<BlueText>Amount: {this.state.amount} BTC</BlueText>
|
||||
<BlueText>Fee: {this.state.fee} BTC</BlueText>
|
||||
<BlueText>TX size: {this.state.size} Bytes</BlueText>
|
||||
<BlueText>satoshiPerByte: {this.state.satoshiPerByte} Sat/B</BlueText>
|
||||
</BlueCard>
|
||||
|
||||
<BlueButton
|
||||
icon={{ name: 'megaphone', type: 'octicon' }}
|
||||
onPress={() => this.broadcast()}
|
||||
title="Broadcast"
|
||||
/>
|
||||
<BlueButton icon={{ name: 'megaphone', type: 'octicon' }} onPress={() => this.broadcast()} title="Broadcast" />
|
||||
|
||||
<BlueButton
|
||||
icon={{ name: 'arrow-left', type: 'octicon' }}
|
||||
|
@ -274,12 +242,8 @@ export default class SendCreate extends Component {
|
|||
title="Go back"
|
||||
/>
|
||||
|
||||
<FormValidationMessage>
|
||||
{this.state.broadcastErrorMessage}
|
||||
</FormValidationMessage>
|
||||
<Text style={{ padding: 20, color: '#080' }}>
|
||||
{this.state.broadcastSuccessMessage}
|
||||
</Text>
|
||||
<FormValidationMessage>{this.state.broadcastErrorMessage}</FormValidationMessage>
|
||||
<Text style={{ padding: 20, color: '#080' }}>{this.state.broadcastSuccessMessage}</Text>
|
||||
</SafeBlueArea>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -21,8 +21,7 @@ export default class RBF extends Component {
|
|||
constructor(props) {
|
||||
super(props);
|
||||
let txid;
|
||||
if (props.navigation.state.params)
|
||||
txid = props.navigation.state.params.txid;
|
||||
if (props.navigation.state.params) txid = props.navigation.state.params.txid;
|
||||
|
||||
let sourceWallet;
|
||||
let sourceTx;
|
||||
|
@ -108,10 +107,7 @@ export default class RBF extends Component {
|
|||
|
||||
<BlueText h4>This transaction is not replaceable</BlueText>
|
||||
|
||||
<BlueButton
|
||||
onPress={() => this.props.navigation.goBack()}
|
||||
title="Back"
|
||||
/>
|
||||
<BlueButton onPress={() => this.props.navigation.goBack()} title="Back" />
|
||||
</SafeBlueArea>
|
||||
);
|
||||
}
|
||||
|
@ -119,13 +115,8 @@ export default class RBF extends Component {
|
|||
if (!this.state.sourceWallet.getAddress) {
|
||||
return (
|
||||
<SafeBlueArea style={{ flex: 1, paddingTop: 20 }}>
|
||||
<BlueText>
|
||||
System error: Source wallet not found (this should never happen)
|
||||
</BlueText>
|
||||
<BlueButton
|
||||
onPress={() => this.props.navigation.goBack()}
|
||||
title="Back"
|
||||
/>
|
||||
<BlueText>System error: Source wallet not found (this should never happen)</BlueText>
|
||||
<BlueButton onPress={() => this.props.navigation.goBack()} title="Back" />
|
||||
</SafeBlueArea>
|
||||
);
|
||||
}
|
||||
|
@ -133,13 +124,9 @@ export default class RBF extends Component {
|
|||
return (
|
||||
<SafeBlueArea style={{ flex: 1, paddingTop: 20 }}>
|
||||
<BlueSpacing />
|
||||
<BlueCard
|
||||
title={'Replace By Fee'}
|
||||
style={{ alignItems: 'center', flex: 1 }}
|
||||
>
|
||||
<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
|
||||
RBF allows you to increase fee on already sent but not confirmed transaction, thus speeding up mining
|
||||
</BlueText>
|
||||
<BlueSpacing20 />
|
||||
|
||||
|
@ -149,9 +136,7 @@ export default class RBF extends Component {
|
|||
<BlueSpacing20 />
|
||||
|
||||
<BlueFormInput
|
||||
onChangeText={text =>
|
||||
this.setState({ newDestinationAddress: text })
|
||||
}
|
||||
onChangeText={text => this.setState({ newDestinationAddress: text })}
|
||||
placeholder={'receiver address here'}
|
||||
value={this.state.newDestinationAddress}
|
||||
/>
|
||||
|
@ -166,17 +151,11 @@ export default class RBF extends Component {
|
|||
|
||||
<View style={{ flex: 1, flexDirection: 'row', paddingTop: 20 }}>
|
||||
<View style={{ flex: 0.33 }}>
|
||||
<BlueButton
|
||||
onPress={() => this.props.navigation.goBack()}
|
||||
title="Cancel"
|
||||
/>
|
||||
<BlueButton onPress={() => this.props.navigation.goBack()} title="Cancel" />
|
||||
</View>
|
||||
<View style={{ flex: 0.33 }} />
|
||||
<View style={{ flex: 0.33 }}>
|
||||
<BlueButton
|
||||
onPress={() => this.createTransaction()}
|
||||
title="Create"
|
||||
/>
|
||||
<BlueButton onPress={() => this.createTransaction()} title="Create" />
|
||||
</View>
|
||||
</View>
|
||||
</SafeBlueArea>
|
||||
|
|
|
@ -88,9 +88,7 @@ export default class TransactionsDetails extends Component {
|
|||
if (BlueApp.tx_metadata[this.state.tx.hash]['memo']) {
|
||||
return (
|
||||
<View>
|
||||
<BlueText h4>
|
||||
{BlueApp.tx_metadata[this.state.tx.hash]['memo']}
|
||||
</BlueText>
|
||||
<BlueText h4>{BlueApp.tx_metadata[this.state.tx.hash]['memo']}</BlueText>
|
||||
<BlueSpacing20 />
|
||||
</View>
|
||||
);
|
||||
|
@ -99,14 +97,10 @@ export default class TransactionsDetails extends Component {
|
|||
})()}
|
||||
|
||||
<BlueText h4>{loc.transactions.details.from}:</BlueText>
|
||||
<BlueText style={{ marginBottom: 10 }}>
|
||||
{this.state.from.join(', ')}
|
||||
</BlueText>
|
||||
<BlueText style={{ marginBottom: 10 }}>{this.state.from.join(', ')}</BlueText>
|
||||
|
||||
<BlueText h4>{loc.transactions.details.to}:</BlueText>
|
||||
<BlueText style={{ marginBottom: 10 }}>
|
||||
{this.state.to.join(', ')}
|
||||
</BlueText>
|
||||
<BlueText style={{ marginBottom: 10 }}>{this.state.to.join(', ')}</BlueText>
|
||||
|
||||
<BlueText>Txid: {this.state.tx.hash}</BlueText>
|
||||
<BlueText>received: {this.state.tx.received}</BlueText>
|
||||
|
|
|
@ -2,14 +2,7 @@ import React, { Component } from 'react';
|
|||
import { ListView, Dimensions } from 'react-native';
|
||||
import Ionicons from 'react-native-vector-icons/Ionicons';
|
||||
import { Header, Icon } from 'react-native-elements';
|
||||
import {
|
||||
BlueLoading,
|
||||
BlueList,
|
||||
SafeBlueArea,
|
||||
BlueCard,
|
||||
BlueText,
|
||||
BlueListItem,
|
||||
} from '../../BlueComponents';
|
||||
import { BlueLoading, BlueList, SafeBlueArea, BlueCard, BlueText, BlueListItem } from '../../BlueComponents';
|
||||
import PropTypes from 'prop-types';
|
||||
let loc = require('../../loc');
|
||||
let EV = require('../../events');
|
||||
|
@ -23,11 +16,7 @@ export default class TransactionsList extends Component {
|
|||
static navigationOptions = {
|
||||
tabBarLabel: loc.transactions.list.tabBarLabel,
|
||||
tabBarIcon: ({ tintColor, focused }) => (
|
||||
<Ionicons
|
||||
name={focused ? 'ios-list-box' : 'ios-list-box-outline'}
|
||||
size={26}
|
||||
style={{ color: tintColor }}
|
||||
/>
|
||||
<Ionicons name={focused ? 'ios-list-box' : 'ios-list-box-outline'} size={26} style={{ color: tintColor }} />
|
||||
),
|
||||
};
|
||||
|
||||
|
@ -115,17 +104,11 @@ export default class TransactionsList extends Component {
|
|||
style: { color: BlueApp.settings.foregroundColor, fontSize: 25 },
|
||||
}}
|
||||
rightComponent={
|
||||
<Icon
|
||||
name="refresh"
|
||||
color={BlueApp.settings.foregroundColor}
|
||||
onPress={() => this.refresh()}
|
||||
/>
|
||||
<Icon name="refresh" color={BlueApp.settings.foregroundColor} onPress={() => this.refresh()} />
|
||||
}
|
||||
/>
|
||||
<BlueCard title={loc.transactions.list.title}>
|
||||
<BlueText style={{ marginBottom: 10 }}>
|
||||
{loc.transactions.list.description}
|
||||
</BlueText>
|
||||
<BlueText style={{ marginBottom: 10 }}>{loc.transactions.list.description}</BlueText>
|
||||
|
||||
<BlueList>
|
||||
<ListView
|
||||
|
@ -138,25 +121,14 @@ export default class TransactionsList extends Component {
|
|||
avatar={
|
||||
<Icon
|
||||
color={(() => {
|
||||
return (
|
||||
(rowData.confirmations &&
|
||||
((rowData.value < 0 && '#900') || '#080')) ||
|
||||
'#ebebeb'
|
||||
);
|
||||
return (rowData.confirmations && ((rowData.value < 0 && '#900') || '#080')) || '#ebebeb';
|
||||
})()}
|
||||
name={(() => {
|
||||
return (
|
||||
(rowData.value < 0 && 'call-made') ||
|
||||
'call-received'
|
||||
);
|
||||
return (rowData.value < 0 && 'call-made') || 'call-received';
|
||||
})()}
|
||||
/>
|
||||
}
|
||||
title={
|
||||
rowData.value / 100000000 +
|
||||
' BTC' +
|
||||
this.txMemo(rowData.hash)
|
||||
}
|
||||
title={rowData.value / 100000000 + ' BTC' + this.txMemo(rowData.hash)}
|
||||
subtitle={
|
||||
rowData.received
|
||||
.replace(['T'], ' ')
|
||||
|
|
|
@ -53,10 +53,7 @@ export default class WalletsAdd extends Component {
|
|||
}
|
||||
|
||||
return (
|
||||
<SafeBlueArea
|
||||
forceInset={{ horizontal: 'always' }}
|
||||
style={{ flex: 1, paddingTop: 40 }}
|
||||
>
|
||||
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={{ flex: 1, paddingTop: 40 }}>
|
||||
{(() => {
|
||||
if (isIpad) {
|
||||
return <BlueSpacing40 />;
|
||||
|
@ -64,10 +61,7 @@ export default class WalletsAdd extends Component {
|
|||
return <BlueSpacing />;
|
||||
}
|
||||
})()}
|
||||
<BlueHeaderDefaultSub
|
||||
leftText={loc.wallets.add.title}
|
||||
onClose={() => this.props.navigation.goBack()}
|
||||
/>
|
||||
<BlueHeaderDefaultSub leftText={loc.wallets.add.title} onClose={() => this.props.navigation.goBack()} />
|
||||
|
||||
<BlueCard>
|
||||
<BlueText>{loc.wallets.add.description}</BlueText>
|
||||
|
|
|
@ -79,23 +79,14 @@ export default class WalletDetails extends Component {
|
|||
<SafeBlueArea style={{ flex: 1 }}>
|
||||
<BlueSpacingVariable />
|
||||
|
||||
<BlueHeaderDefaultSub
|
||||
leftText={loc.wallets.details.title}
|
||||
onClose={() => this.props.navigation.goBack()}
|
||||
/>
|
||||
<BlueHeaderDefaultSub leftText={loc.wallets.details.title} onClose={() => this.props.navigation.goBack()} />
|
||||
|
||||
<BlueCard style={{ alignItems: 'center', flex: 1 }}>
|
||||
<BlueFormLabel>{loc.wallets.details.address}:</BlueFormLabel>
|
||||
<BlueFormInputAddress
|
||||
value={this.state.wallet.getAddress()}
|
||||
editable
|
||||
/>
|
||||
<BlueFormInputAddress value={this.state.wallet.getAddress()} editable />
|
||||
|
||||
<BlueFormLabel>{loc.wallets.details.type}:</BlueFormLabel>
|
||||
<BlueFormInput
|
||||
value={this.state.wallet.getTypeReadable()}
|
||||
editable={false}
|
||||
/>
|
||||
<BlueFormInput value={this.state.wallet.getTypeReadable()} editable={false} />
|
||||
|
||||
<BlueFormLabel>{loc.wallets.details.label}:</BlueFormLabel>
|
||||
<BlueFormInput
|
||||
|
|
|
@ -80,10 +80,7 @@ export default class WalletExport extends Component {
|
|||
return <BlueSpacing />;
|
||||
}
|
||||
})()}
|
||||
<BlueHeaderDefaultSub
|
||||
leftText={loc.wallets.export.title}
|
||||
onClose={() => this.props.navigation.goBack()}
|
||||
/>
|
||||
<BlueHeaderDefaultSub leftText={loc.wallets.export.title} onClose={() => this.props.navigation.goBack()} />
|
||||
|
||||
<BlueCard style={{ alignItems: 'center', flex: 1 }}>
|
||||
<BlueText>{this.state.wallet.getAddress()}</BlueText>
|
||||
|
@ -93,9 +90,7 @@ export default class WalletExport extends Component {
|
|||
bgColor={BlueApp.settings.foregroundColor}
|
||||
fgColor={BlueApp.settings.brandingColor}
|
||||
/>
|
||||
<BlueText>
|
||||
{this.state.wallet.getSecret()} [Wallet Import Format]
|
||||
</BlueText>
|
||||
<BlueText>{this.state.wallet.getSecret()} [Wallet Import Format]</BlueText>
|
||||
</BlueCard>
|
||||
</SafeBlueArea>
|
||||
);
|
||||
|
|
|
@ -85,9 +85,7 @@ export default class WalletsList extends Component {
|
|||
showReceiveButton: (BlueApp.getWallets().length > 0 && true) || false,
|
||||
showSendButton: (BlueApp.getWallets().length > 0 && true) || false,
|
||||
showRereshButton: (BlueApp.getWallets().length > 0 && true) || false,
|
||||
dataSource: ds.cloneWithRows(
|
||||
BlueApp.getTransactions(this.lastSnappedTo || 0),
|
||||
),
|
||||
dataSource: ds.cloneWithRows(BlueApp.getTransactions(this.lastSnappedTo || 0)),
|
||||
});
|
||||
}, 1);
|
||||
}
|
||||
|
@ -160,10 +158,7 @@ export default class WalletsList extends Component {
|
|||
if (wallets && wallets[index] && wallets[index].timeToRefresh()) {
|
||||
console.log('snapped to, and now its time to refresh wallet #', index);
|
||||
await wallets[index].fetchBalance();
|
||||
if (
|
||||
oldBalance !== wallets[index].getBalance() ||
|
||||
wallets[index].getUnconfirmedBalance() !== 0
|
||||
) {
|
||||
if (oldBalance !== wallets[index].getBalance() || wallets[index].getUnconfirmedBalance() !== 0) {
|
||||
console.log('balance changed, thus txs too');
|
||||
// balance changed, thus txs too
|
||||
await wallets[index].fetchTransactions();
|
||||
|
@ -192,10 +187,7 @@ export default class WalletsList extends Component {
|
|||
|
||||
return (
|
||||
<SafeBlueArea>
|
||||
<BlueHeaderDefaultMain
|
||||
leftText={loc.wallets.list.title}
|
||||
onClose={() => navigate('Settings')}
|
||||
/>
|
||||
<BlueHeaderDefaultMain leftText={loc.wallets.list.title} onClose={() => navigate('Settings')} />
|
||||
|
||||
<WalletsCarousel
|
||||
data={BlueApp.getWallets().concat(false)}
|
||||
|
@ -227,11 +219,7 @@ export default class WalletsList extends Component {
|
|||
</Text>
|
||||
{(() => {
|
||||
if (this.state.showRereshButton) {
|
||||
return (
|
||||
<BlueRefreshIcon
|
||||
onPress={() => this.refreshTransactions()}
|
||||
/>
|
||||
);
|
||||
return <BlueRefreshIcon onPress={() => this.refreshTransactions()} />;
|
||||
}
|
||||
})()}
|
||||
</View>
|
||||
|
@ -244,10 +232,7 @@ export default class WalletsList extends Component {
|
|||
}}
|
||||
>
|
||||
{(() => {
|
||||
if (
|
||||
BlueApp.getTransactions(this.lastSnappedTo || 0)
|
||||
.length === 0
|
||||
) {
|
||||
if (BlueApp.getTransactions(this.lastSnappedTo || 0).length === 0) {
|
||||
return (
|
||||
<View>
|
||||
<Text
|
||||
|
@ -306,15 +291,10 @@ export default class WalletsList extends Component {
|
|||
);
|
||||
}
|
||||
})()}
|
||||
title={loc.transactionTimeToReadable(
|
||||
rowData.received,
|
||||
)}
|
||||
title={loc.transactionTimeToReadable(rowData.received)}
|
||||
subtitle={
|
||||
(rowData.confirmations < 200
|
||||
? loc.transactions.list.conf +
|
||||
': ' +
|
||||
rowData.confirmations +
|
||||
' '
|
||||
? loc.transactions.list.conf + ': ' + rowData.confirmations + ' '
|
||||
: '') + this.txMemo(rowData.hash)
|
||||
}
|
||||
onPress={() => {
|
||||
|
@ -336,10 +316,7 @@ export default class WalletsList extends Component {
|
|||
top: -7,
|
||||
fontWeight: '600',
|
||||
fontSize: 16,
|
||||
color:
|
||||
rowData.value / 100000000 < 0
|
||||
? BlueApp.settings.foregroundColor
|
||||
: '#37c0a1',
|
||||
color: rowData.value / 100000000 < 0 ? BlueApp.settings.foregroundColor : '#37c0a1',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
/* global alert */
|
||||
import React from 'react';
|
||||
import {
|
||||
Text,
|
||||
ActivityIndicator,
|
||||
Button,
|
||||
View,
|
||||
TouchableOpacity,
|
||||
} from 'react-native';
|
||||
import { Text, ActivityIndicator, Button, View, TouchableOpacity } from 'react-native';
|
||||
import { BlueText, SafeBlueArea, BlueButton } from '../../BlueComponents';
|
||||
import { Camera, Permissions } from 'expo';
|
||||
import { SegwitP2SHWallet, LegacyWallet } from '../../class';
|
||||
|
@ -46,31 +40,18 @@ export default class ScanQrWif extends React.Component {
|
|||
message: loc.wallets.scanQrWif.decoding,
|
||||
});
|
||||
shold_stop_bip38 = undefined; // eslint-disable-line
|
||||
let password = await prompt(
|
||||
loc.wallets.scanQrWif.input_password,
|
||||
loc.wallets.scanQrWif.password_explain,
|
||||
);
|
||||
let password = await prompt(loc.wallets.scanQrWif.input_password, loc.wallets.scanQrWif.password_explain);
|
||||
if (!password) {
|
||||
return;
|
||||
}
|
||||
let that = this;
|
||||
try {
|
||||
let decryptedKey = await bip38.decrypt(ret.data, password, function(
|
||||
status,
|
||||
) {
|
||||
let decryptedKey = await bip38.decrypt(ret.data, password, function(status) {
|
||||
that.setState({
|
||||
message:
|
||||
loc.wallets.scanQrWif.decoding +
|
||||
'... ' +
|
||||
status.percent.toString().substr(0, 4) +
|
||||
' %',
|
||||
message: loc.wallets.scanQrWif.decoding + '... ' + status.percent.toString().substr(0, 4) + ' %',
|
||||
});
|
||||
});
|
||||
ret.data = wif.encode(
|
||||
0x80,
|
||||
decryptedKey.privateKey,
|
||||
decryptedKey.compressed,
|
||||
);
|
||||
ret.data = wif.encode(0x80, decryptedKey.privateKey, decryptedKey.compressed);
|
||||
} catch (e) {
|
||||
console.log(e.message);
|
||||
this.setState({ message: false });
|
||||
|
@ -93,10 +74,7 @@ export default class ScanQrWif extends React.Component {
|
|||
let newLegacyWallet = new LegacyWallet();
|
||||
newLegacyWallet.setSecret(ret.data);
|
||||
|
||||
if (
|
||||
newWallet.getAddress() === false ||
|
||||
newLegacyWallet.getAddress() === false
|
||||
) {
|
||||
if (newWallet.getAddress() === false || newLegacyWallet.getAddress() === false) {
|
||||
alert(loc.wallets.scanQrWif.bad_wif);
|
||||
return;
|
||||
}
|
||||
|
@ -120,10 +98,7 @@ export default class ScanQrWif extends React.Component {
|
|||
newWallet.setLabel(loc.wallets.scanQrWif.imported_segwit);
|
||||
BlueApp.wallets.push(newWallet);
|
||||
alert(
|
||||
loc.wallets.scanQrWif.imported_wif +
|
||||
ret.data +
|
||||
loc.wallets.scanQrWif.with_address +
|
||||
newWallet.getAddress(),
|
||||
loc.wallets.scanQrWif.imported_wif + ret.data + loc.wallets.scanQrWif.with_address + newWallet.getAddress(),
|
||||
);
|
||||
}
|
||||
await BlueApp.saveToDisk();
|
||||
|
@ -185,11 +160,7 @@ export default class ScanQrWif extends React.Component {
|
|||
);
|
||||
} else {
|
||||
return (
|
||||
<Camera
|
||||
style={{ flex: 1 }}
|
||||
type={this.state.type}
|
||||
onBarCodeRead={ret => this.onBarCodeRead(ret)}
|
||||
>
|
||||
<Camera style={{ flex: 1 }} type={this.state.type} onBarCodeRead={ret => this.onBarCodeRead(ret)}>
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
|
|
Loading…
Add table
Reference in a new issue