diff --git a/browser/index.html b/browser/index.html
index 89fa039f..4915fd27 100644
--- a/browser/index.html
+++ b/browser/index.html
@@ -121,47 +121,50 @@ more bitcoin magic).
floating.style.display = 'block';
}
- logger = {
- debug: function(args) {
- if (++scrollback > 1000) {
- log.innerHTML = '';
- scrollback = 1;
- }
- var msg = utils.format(args, false);
- log.innerHTML += '' + utils.now() + ' ';
- log.innerHTML += escape(msg) + '\n';
- log.scrollTop = log.scrollHeight;
- },
- error: function(err) {
- if (++scrollback > 1000) {
- log.innerHTML = '';
- scrollback = 1;
- }
- var msg = (err.message + '').replace(/^ *Error: */, '');
- log.innerHTML += '' + utils.now() + ' ';
- log.innerHTML += '[Error] ';
- log.innerHTML += escape(msg) + '\n';
- log.scrollTop = log.scrollHeight;
+ logger = new bcoin.logger({ level: 'debug' });
+ logger.writeConsole = function(level, args) {
+ var msg = utils.format(args, false);
+ if (++scrollback > 1000) {
+ log.innerHTML = '';
+ scrollback = 1;
}
+ log.innerHTML += '' + utils.now() + ' ';
+ if (level === 'error')
+ log.innerHTML += '[' + level + '] ';
+ else
+ log.innerHTML += '[' + level + '] ';
+ log.innerHTML += escape(msg) + '\n';
+ log.scrollTop = log.scrollHeight;
};
send.onsubmit = function(ev) {
var value = document.getElementById('amount').value;
var address = document.getElementById('address').value;
- value = utils.satoshi(value);
- node.wallet.createTX({}, [{address: address,value:value}], function(err, tx) {
+
+ var options = {
+ outputs: [{
+ address: address,
+ value: utils.satoshi(value)
+ }]
+ };
+
+ node.wallet.createTX(options, function(err, tx) {
if (err)
- return bcoin.error(err);
+ return node.logger.error(err);
+
node.wallet.sign(tx, function(err) {
if (err)
- return bcoin.error(err);
+ return node.logger.error(err);
+
node.sendTX(tx, function(err) {
if (err)
- return bcoin.error(err);
+ return node.logger.error(err);
+
show(tx);
});
});
});
+
ev.preventDefault();
ev.stopPropagation();
return false;
@@ -220,16 +223,16 @@ more bitcoin magic).
function formatWallet(wallet) {
var html = '';
- var key = wallet.master.toJSON();
+ var key = wallet.master.toJSON().key;
html += 'Wallet
';
- if (bcoin.networkType === 'segnet4') {
+ if (bcoin.network.get().type === 'segnet4') {
html += 'Current Address (p2wpkh): ' + wallet.getAddress() + '
';
html += 'Current Address (p2wpkh behind p2sh): ' + wallet.getProgramAddress() + '
';
} else {
html += 'Current Address: ' + wallet.getAddress() + '
';
}
html += 'Extended Private Key: ' + key.xprivkey + '
';
- html += 'Mnemonic: ' + key.phrase + '
';
+ html += 'Mnemonic: ' + key.mnemonic.phrase + '
';
wallet.getBalance(function(err, balance) {
if (balance) {
html += 'Confirmed Balance: ' + utils.btc(balance.confirmed) + '
';
@@ -271,21 +274,21 @@ more bitcoin magic).
bcoin.set({
network: query.network || 'segnet4',
- debug: true,
- db: query.db || null,
- logger: logger,
useWorkers: true
});
node = new bcoin.fullnode({
- prune: query.prune === 'true' || query.prune === '1'
+ prune: query.prune === 'true' || query.prune === '1',
+ logger: logger,
+ db: query.db || 'leveldb',
+ coinCache: true
});
node.on('error', function(err) {
- bcoin.error(err);
+ ;
});
- node.on('block', addItem);
+ node.chain.on('block', addItem);
node.mempool.on('tx', addItem);
node.open(function(err) {
diff --git a/browser/ldb.js b/browser/ldb.js
new file mode 100644
index 00000000..81dd82f2
--- /dev/null
+++ b/browser/ldb.js
@@ -0,0 +1,120 @@
+var level = require('level-js');
+
+function DB(file) {
+ this.level = new level(file);
+ this.bufferKeys = false;
+}
+
+DB.prototype.open = function open(options, callback) {
+ this.level.open(options, callback);
+};
+
+DB.prototype.close = function close(callback) {
+ this.level.close(callback);
+};
+
+DB.prototype.get = function get(key, options, callback) {
+ if (this.bufferKeys && Buffer.isBuffer(key))
+ key = key.toString('hex');
+ this.level.get(key, options, callback);
+};
+
+DB.prototype.put = function get(key, value, options, callback) {
+ if (this.bufferKeys && Buffer.isBuffer(key))
+ key = key.toString('hex');
+ this.level.put(key, value, options, callback);
+};
+
+DB.prototype.del = function del(key, options, callback) {
+ if (this.bufferKeys && Buffer.isBuffer(key))
+ key = key.toString('hex');
+ this.level.del(key, options, callback);
+};
+
+DB.prototype.batch = function batch(ops, options, callback) {
+ if (!ops)
+ return new Batch(this);
+ return this.level.batch(ops, options, callback);
+};
+
+DB.prototype.iterator = function iterator(options) {
+ options.keyAsBuffer = false;
+ return new Iterator(this, options);
+};
+
+DB.prototype.approximateSize = function approximateSize(start, end, callback) {
+ return this.level.approximateSize(start, end, callback);
+};
+
+DB.prototype.getProperty = function getProperty(name) {
+ return this.level.getProperty(name);
+};
+
+function Batch(db) {
+ this.db = db;
+ this.batch = db.level.batch();
+}
+
+Batch.prototype.put = function(key, value) {
+ if (this.db.bufferKeys && Buffer.isBuffer(key))
+ key = key.toString('hex');
+ this.batch.put(key, value);
+ return this;
+};
+
+Batch.prototype.del = function del(key) {
+ if (this.db.bufferKeys && Buffer.isBuffer(key))
+ key = key.toString('hex');
+ this.batch.del(key);
+ return this;
+};
+
+Batch.prototype.write = function write(callback) {
+ this.batch.write(callback);
+ return this;
+};
+
+Batch.prototype.clear = function clear() {
+ this.batch.clear();
+ return this;
+};
+
+function Iterator(db, options) {
+ this.db = db;
+ this.iter = db.level.iterator(options);
+}
+
+Iterator.prototype.next = function(callback) {
+ var self = this;
+ this.iter.next(function(err, key, value) {
+ if (err) {
+ callback(err);
+ return;
+ }
+
+ if (key === undefined) {
+ callback(err, key, value);
+ return;
+ }
+
+ if (self.db.bufferKeys)
+ key = new Buffer(key, 'hex');
+
+ if (!Buffer.isBuffer(value))
+ value = new Buffer(value.buffer);
+
+ callback(err, key, value);
+ });
+};
+
+Iterator.prototype.seek = function seek(key) {
+ if (this.db.bufferKeys && Buffer.isBuffer(key))
+ key = key.toString('hex');
+ this.iter.seek(key);
+};
+
+Iterator.prototype.end = function end(callback) {
+ this.iter.end(callback);
+};
+
+module.exports = DB;
diff --git a/lib/bcoin/chaindb.js b/lib/bcoin/chaindb.js
index 9ffe5be8..e9479699 100644
--- a/lib/bcoin/chaindb.js
+++ b/lib/bcoin/chaindb.js
@@ -35,9 +35,7 @@ var BufferReader = require('./reader');
*/
var layout = {
- R: !utils.isBrowser
- ? new Buffer([0x52])
- : '52',
+ R: new Buffer([0x52]),
e: function e(hash) {
return pair(0x65, hash);
},
@@ -84,9 +82,6 @@ var layout = {
write(key, hash, 21);
}
- if (utils.isBrowser)
- key = key.toString('hex');
-
return key;
},
C: function C(address, hash, index) {
@@ -110,17 +105,11 @@ var layout = {
key.writeUInt32LE(index, 53, true);
}
- if (utils.isBrowser)
- key = key.toString('hex');
-
return key;
},
Cc: function Cc(key) {
var hash, index;
- if (utils.isBrowser)
- key = new Buffer(key, 'hex');
-
if (key.length === 69) {
hash = key.slice(33, 65).toString('hex');
index = key.readUInt32LE(65, 0);
@@ -132,9 +121,6 @@ var layout = {
return [hash, index];
},
Tt: function Tt(key) {
- if (utils.isBrowser)
- key = new Buffer(key, 'hex');
-
return key.length === 65
? key.slice(33).toString('hex')
: key.slice(21).toString('hex');
@@ -182,7 +168,8 @@ function ChainDB(chain, options) {
db: this.options.db,
compression: true,
cacheSize: 16 << 20,
- writeBufferSize: 8 << 20
+ writeBufferSize: 8 << 20,
+ bufferKeys: true
});
this.keepBlocks = options.keepBlocks || 288;
@@ -1255,7 +1242,7 @@ ChainDB.prototype.getCoinsByAddress = function getCoinsByAddress(addresses, call
self.db.iterate({
gte: layout.C(address, constants.ZERO_HASH, 0),
lte: layout.C(address, constants.MAX_HASH, 0xffffffff),
- keyAsBuffer: !utils.isBrowser,
+ keyAsBuffer: true,
transform: layout.Cc
}, function(err, keys) {
if (err)
@@ -1303,7 +1290,7 @@ ChainDB.prototype.getTXByAddress = function getTXByAddress(addresses, callback)
self.db.lookup({
gte: layout.T(address, constants.ZERO_HASH),
lte: layout.T(address, constants.MAX_HASH),
- keyAsBuffer: !utils.isBrowser,
+ keyAsBuffer: true,
transform: function(key) {
var hash = layout.Tt(key);
@@ -1561,8 +1548,6 @@ function pair(prefix, hash) {
var key = new Buffer(33);
key[0] = prefix;
write(key, hash, 1);
- if (utils.isBrowser)
- key = key.toString('hex');
return key;
}
@@ -1570,8 +1555,6 @@ function ipair(prefix, num) {
var key = new Buffer(5);
key[0] = prefix;
key.writeUInt32LE(num, 1, true);
- if (utils.isBrowser)
- key = key.toString('hex');
return key;
}
diff --git a/lib/bcoin/ldb.js b/lib/bcoin/ldb.js
index a4cf0705..61eb310e 100644
--- a/lib/bcoin/ldb.js
+++ b/lib/bcoin/ldb.js
@@ -51,6 +51,9 @@ function ldb(options) {
mapSize: options.mapSize || 300 * (1024 << 20),
writeMap: options.writeMap || false,
+ // For browser buffer keys
+ bufferKeys: options.bufferKeys,
+
db: options.db
});
}
@@ -113,7 +116,7 @@ ldb.parseOptions = function parseOptions(options) {
if (backend.name === 'rbt')
db = require('./rbt');
else if (utils.isBrowser)
- db = require('level-js');
+ db = require('../../browser/ldb');
else
db = require(backend.name);
diff --git a/lib/bcoin/lowlevelup.js b/lib/bcoin/lowlevelup.js
index 3f6a9d56..d8c0e9e4 100644
--- a/lib/bcoin/lowlevelup.js
+++ b/lib/bcoin/lowlevelup.js
@@ -40,6 +40,9 @@ function LowlevelUp(file, options) {
this.db = new options.db(file);
+ if (utils.isBrowser)
+ this.db.bufferKeys = options.bufferKeys;
+
// Stay as close to the metal as possible.
// We want to make calls to C++ directly.
while (this.db.db && this.db.db.put && this.db.db !== this.db)
@@ -268,6 +271,7 @@ LowlevelUp.prototype.iterate = function iterate(options, callback) {
values: options.values || false,
fillCache: options.fillCache || false,
keyAsBuffer: options.keyAsBuffer || false,
+ valueAsBuffer: true,
reverse: options.reverse || false
};
diff --git a/lib/bcoin/pool.js b/lib/bcoin/pool.js
index 9b8815be..39a10e18 100644
--- a/lib/bcoin/pool.js
+++ b/lib/bcoin/pool.js
@@ -132,7 +132,7 @@ function Pool(options) {
: this.network.port;
this.address = new NetworkAddress({
- ts: utils.now() - (process.uptime() | 0),
+ ts: utils.now(),
services: this.services,
host: '0.0.0.0',
port: this.port