mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2024-11-19 09:50:15 +01:00
REF: hd wallet classes
This commit is contained in:
parent
afae64a32c
commit
777c9e6de7
@ -2,6 +2,8 @@ import { LegacyWallet } from './legacy-wallet';
|
||||
import Frisbee from 'frisbee';
|
||||
import { WatchOnlyWallet } from './watch-only-wallet';
|
||||
const bip39 = require('bip39');
|
||||
const BigNumber = require('bignumber.js');
|
||||
const bitcoin = require('bitcoinjs-lib');
|
||||
|
||||
export class AbstractHDWallet extends LegacyWallet {
|
||||
constructor() {
|
||||
@ -195,28 +197,6 @@ export class AbstractHDWallet extends LegacyWallet {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
async fetchBalance() {
|
||||
try {
|
||||
const api = new Frisbee({ baseURI: 'https://blockchain.info' });
|
||||
|
||||
let response = await api.get('/balance?active=' + this.getXpub());
|
||||
|
||||
if (response && response.body) {
|
||||
for (let xpub of Object.keys(response.body)) {
|
||||
this.balance = response.body[xpub].final_balance / 100000000;
|
||||
}
|
||||
this._lastBalanceFetch = +new Date();
|
||||
} else {
|
||||
throw new Error('Could not fetch balance from API: ' + response.err);
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn(err);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Async function to fetch all transactions. Use getter to get actual txs.
|
||||
* Also, sets internals:
|
||||
@ -365,4 +345,84 @@ export class AbstractHDWallet extends LegacyWallet {
|
||||
createTx() {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
|
||||
async fetchBalance() {
|
||||
try {
|
||||
const api = new Frisbee({ baseURI: 'https://www.blockonomics.co' });
|
||||
let response = await api.post('/api/balance', { body: JSON.stringify({ addr: this.getXpub() }) });
|
||||
|
||||
if (response && response.body && response.body.response) {
|
||||
this.balance = 0;
|
||||
this.unconfirmed_balance = 0;
|
||||
this.usedAddresses = [];
|
||||
for (let addr of response.body.response) {
|
||||
this.balance += addr.confirmed;
|
||||
this.unconfirmed_balance += addr.unconfirmed;
|
||||
this.usedAddresses.push(addr.addr);
|
||||
}
|
||||
this.balance = new BigNumber(this.balance).dividedBy(100000000).toString() * 1;
|
||||
this.unconfirmed_balance = new BigNumber(this.unconfirmed_balance).dividedBy(100000000).toString() * 1;
|
||||
this._lastBalanceFetch = +new Date();
|
||||
} else {
|
||||
throw new Error('Could not fetch balance from API: ' + response.err);
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn(err);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
async fetchUtxo() {
|
||||
const api = new Frisbee({
|
||||
baseURI: 'https://blockchain.info',
|
||||
});
|
||||
|
||||
if (this.usedAddresses.length === 0) {
|
||||
// just for any case, refresh balance (it refreshes internal `this.usedAddresses`)
|
||||
await this.fetchBalance();
|
||||
}
|
||||
|
||||
let addresses = this.usedAddresses.join('|');
|
||||
addresses += '|' + this._getExternalAddressByIndex(this.next_free_address_index);
|
||||
addresses += '|' + this._getInternalAddressByIndex(this.next_free_change_address_index);
|
||||
|
||||
let utxos = [];
|
||||
|
||||
let response;
|
||||
try {
|
||||
response = await api.get('/unspent?active=' + addresses + '&limit=1000');
|
||||
// this endpoint does not support offset of some kind o_O
|
||||
// so doing only one call
|
||||
let json = response.body;
|
||||
if (typeof json === 'undefined' || typeof json.unspent_outputs === 'undefined') {
|
||||
throw new Error('Could not fetch UTXO from API ' + response.err);
|
||||
}
|
||||
|
||||
for (let unspent of json.unspent_outputs) {
|
||||
// a lil transform for signer module
|
||||
unspent.txid = unspent.tx_hash_big_endian;
|
||||
unspent.vout = unspent.tx_output_n;
|
||||
unspent.amount = unspent.value;
|
||||
|
||||
let chunksIn = bitcoin.script.decompile(Buffer.from(unspent.script, 'hex'));
|
||||
unspent.address = bitcoin.address.fromOutputScript(chunksIn);
|
||||
utxos.push(unspent);
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn(err);
|
||||
}
|
||||
|
||||
this.utxo = utxos;
|
||||
}
|
||||
|
||||
weOwnAddress(addr) {
|
||||
let hashmap = {};
|
||||
for (let a of this.usedAddresses) {
|
||||
hashmap[a] = 1;
|
||||
}
|
||||
|
||||
return hashmap[addr] === 1;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { AbstractHDWallet } from './abstract-hd-wallet';
|
||||
import Frisbee from 'frisbee';
|
||||
const bitcoin = require('bitcoinjs-lib');
|
||||
const bip39 = require('bip39');
|
||||
|
||||
@ -80,4 +81,26 @@ export class HDLegacyBreadwalletWallet extends AbstractHDWallet {
|
||||
let child = root.derivePath(path);
|
||||
return child.keyPair.toWIF();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
async fetchBalance() {
|
||||
try {
|
||||
const api = new Frisbee({ baseURI: 'https://blockchain.info' });
|
||||
|
||||
let response = await api.get('/balance?active=' + this.getXpub());
|
||||
|
||||
if (response && response.body) {
|
||||
for (let xpub of Object.keys(response.body)) {
|
||||
this.balance = response.body[xpub].final_balance / 100000000;
|
||||
}
|
||||
this._lastBalanceFetch = +new Date();
|
||||
} else {
|
||||
throw new Error('Could not fetch balance from API: ' + response.err);
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { LegacyWallet } from './';
|
||||
import { AbstractHDWallet } from './abstract-hd-wallet';
|
||||
import Frisbee from 'frisbee';
|
||||
const bitcoin = require('bitcoinjs-lib');
|
||||
const bip39 = require('bip39');
|
||||
const BigNumber = require('bignumber.js');
|
||||
@ -107,87 +106,6 @@ export class HDLegacyP2PKHWallet extends AbstractHDWallet {
|
||||
}
|
||||
}
|
||||
|
||||
async fetchBalance() {
|
||||
try {
|
||||
const api = new Frisbee({ baseURI: 'https://www.blockonomics.co' });
|
||||
let response = await api.post('/api/balance', { body: JSON.stringify({ addr: this.getXpub() }) });
|
||||
// console.log(response);
|
||||
|
||||
if (response && response.body && response.body.response) {
|
||||
this.balance = 0;
|
||||
this.unconfirmed_balance = 0;
|
||||
this.usedAddresses = [];
|
||||
for (let addr of response.body.response) {
|
||||
this.balance += addr.confirmed;
|
||||
this.unconfirmed_balance += addr.unconfirmed;
|
||||
this.usedAddresses.push(addr.addr);
|
||||
}
|
||||
this.balance = new BigNumber(this.balance).dividedBy(100000000).toString() * 1;
|
||||
this.unconfirmed_balance = new BigNumber(this.unconfirmed_balance).dividedBy(100000000).toString() * 1;
|
||||
this._lastBalanceFetch = +new Date();
|
||||
} else {
|
||||
throw new Error('Could not fetch balance from API: ' + response.err);
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn(err);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
async fetchUtxo() {
|
||||
const api = new Frisbee({
|
||||
baseURI: 'https://blockchain.info',
|
||||
});
|
||||
|
||||
if (this.usedAddresses.length === 0) {
|
||||
// just for any case, refresh balance (it refreshes internal `this.usedAddresses`)
|
||||
await this.fetchBalance();
|
||||
}
|
||||
|
||||
let addresses = this.usedAddresses.join('|');
|
||||
addresses += '|' + this._getExternalAddressByIndex(this.next_free_address_index);
|
||||
addresses += '|' + this._getInternalAddressByIndex(this.next_free_change_address_index);
|
||||
|
||||
let utxos = [];
|
||||
|
||||
let response;
|
||||
try {
|
||||
response = await api.get('/unspent?active=' + addresses + '&limit=1000');
|
||||
// this endpoint does not support offset of some kind o_O
|
||||
// so doing only one call
|
||||
let json = response.body;
|
||||
if (typeof json === 'undefined' || typeof json.unspent_outputs === 'undefined') {
|
||||
throw new Error('Could not fetch UTXO from API ' + response.err);
|
||||
}
|
||||
|
||||
for (let unspent of json.unspent_outputs) {
|
||||
// a lil transform for signer module
|
||||
unspent.txid = unspent.tx_hash_big_endian;
|
||||
unspent.vout = unspent.tx_output_n;
|
||||
unspent.amount = unspent.value;
|
||||
|
||||
let chunksIn = bitcoin.script.decompile(Buffer.from(unspent.script, 'hex'));
|
||||
unspent.address = bitcoin.address.fromOutputScript(chunksIn);
|
||||
utxos.push(unspent);
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn(err);
|
||||
}
|
||||
|
||||
this.utxo = utxos;
|
||||
}
|
||||
|
||||
weOwnAddress(addr) {
|
||||
let hashmap = {};
|
||||
for (let a of this.usedAddresses) {
|
||||
hashmap[a] = 1;
|
||||
}
|
||||
|
||||
return hashmap[addr] === 1;
|
||||
}
|
||||
|
||||
createTx(utxos, amount, fee, address) {
|
||||
for (let utxo of utxos) {
|
||||
utxo.wif = this._getWifForAddress(utxo.address);
|
||||
|
@ -50,32 +50,6 @@ export class HDSegwitP2SHWallet extends AbstractHDWallet {
|
||||
});
|
||||
}
|
||||
|
||||
async fetchBalance() {
|
||||
try {
|
||||
const api = new Frisbee({ baseURI: 'https://www.blockonomics.co' });
|
||||
let response = await api.post('/api/balance', { body: JSON.stringify({ addr: this.getXpub() }) });
|
||||
// console.log(response);
|
||||
|
||||
if (response && response.body && response.body.response) {
|
||||
this.balance = 0;
|
||||
this.unconfirmed_balance = 0;
|
||||
this.usedAddresses = [];
|
||||
for (let addr of response.body.response) {
|
||||
this.balance += addr.confirmed;
|
||||
this.unconfirmed_balance += addr.unconfirmed;
|
||||
this.usedAddresses.push(addr.addr);
|
||||
}
|
||||
this.balance = new BigNumber(this.balance).dividedBy(100000000).toString() * 1;
|
||||
this.unconfirmed_balance = new BigNumber(this.unconfirmed_balance).dividedBy(100000000).toString() * 1;
|
||||
this._lastBalanceFetch = +new Date();
|
||||
} else {
|
||||
throw new Error('Could not fetch balance from API: ' + response.err);
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn(err);
|
||||
}
|
||||
}
|
||||
|
||||
_getExternalWIFByIndex(index) {
|
||||
index = index * 1; // cast to int
|
||||
let mnemonic = this.secret;
|
||||
@ -290,61 +264,6 @@ export class HDSegwitP2SHWallet extends AbstractHDWallet {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
async fetchUtxo() {
|
||||
const api = new Frisbee({
|
||||
baseURI: 'https://blockchain.info',
|
||||
});
|
||||
|
||||
if (this.usedAddresses.length === 0) {
|
||||
// just for any case, refresh balance (it refreshes internal `this.usedAddresses`)
|
||||
await this.fetchBalance();
|
||||
}
|
||||
|
||||
let addresses = this.usedAddresses.join('|');
|
||||
addresses += '|' + this._getExternalAddressByIndex(this.next_free_address_index);
|
||||
addresses += '|' + this._getInternalAddressByIndex(this.next_free_change_address_index);
|
||||
|
||||
let utxos = [];
|
||||
|
||||
let response;
|
||||
try {
|
||||
response = await api.get('/unspent?active=' + addresses + '&limit=1000');
|
||||
// this endpoint does not support offset of some kind o_O
|
||||
// so doing only one call
|
||||
let json = response.body;
|
||||
if (typeof json === 'undefined' || typeof json.unspent_outputs === 'undefined') {
|
||||
throw new Error('Could not fetch UTXO from API ' + response.err);
|
||||
}
|
||||
|
||||
for (let unspent of json.unspent_outputs) {
|
||||
// a lil transform for signer module
|
||||
unspent.txid = unspent.tx_hash_big_endian;
|
||||
unspent.vout = unspent.tx_output_n;
|
||||
unspent.amount = unspent.value;
|
||||
|
||||
let chunksIn = bitcoin.script.decompile(Buffer.from(unspent.script, 'hex'));
|
||||
unspent.address = bitcoin.address.fromOutputScript(chunksIn);
|
||||
utxos.push(unspent);
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn(err);
|
||||
}
|
||||
|
||||
this.utxo = utxos;
|
||||
}
|
||||
|
||||
weOwnAddress(addr) {
|
||||
let hashmap = {};
|
||||
for (let a of this.usedAddresses) {
|
||||
hashmap[a] = 1;
|
||||
}
|
||||
|
||||
return hashmap[addr] === 1;
|
||||
}
|
||||
|
||||
createTx(utxos, amount, fee, address) {
|
||||
for (let utxo of utxos) {
|
||||
utxo.wif = this._getWifForAddress(utxo.address);
|
||||
|
@ -19,7 +19,7 @@ import Modal from 'react-native-modal';
|
||||
import NetworkTransactionFees, { NetworkTransactionFee } from '../../models/networkTransactionFees';
|
||||
import BitcoinBIP70TransactionDecode from '../../bip70/bip70';
|
||||
import { BitcoinUnit } from '../../models/bitcoinUnits';
|
||||
import { HDSegwitP2SHWallet } from '../../class';
|
||||
import { HDLegacyP2PKHWallet, HDSegwitP2SHWallet } from '../../class';
|
||||
import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
|
||||
const bip21 = require('bip21');
|
||||
let EV = require('../../events');
|
||||
@ -304,7 +304,11 @@ export default class SendDetails extends Component {
|
||||
this.props.navigation.navigate('Confirm', {
|
||||
amount: this.state.amount,
|
||||
// HD wallet's utxo is in sats, classic segwit wallet utxos are in btc
|
||||
fee: this.calculateFee(utxo, tx, this.state.fromWallet.type === new HDSegwitP2SHWallet().type),
|
||||
fee: this.calculateFee(
|
||||
utxo,
|
||||
tx,
|
||||
this.state.fromWallet.type === new HDSegwitP2SHWallet().type || this.state.fromWallet.type === new HDLegacyP2PKHWallet().type,
|
||||
),
|
||||
address: this.state.address,
|
||||
memo: this.state.memo,
|
||||
fromWallet: this.state.fromWallet,
|
||||
|
Loading…
Reference in New Issue
Block a user