diff --git a/Makefile b/Makefile
index caee01cc..27e9635d 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,9 @@
all:
@npm run webpack
+app:
+ @npm run webpack-app
+
browser:
@npm run webpack-browser
@@ -22,4 +25,4 @@ lint:
test:
@npm test
-.PHONY: all browser compat node clean docs lint test
+.PHONY: all app browser compat node clean docs lint test
diff --git a/browser/index.html b/browser/index.html
index 3e147a00..fc5a054e 100644
--- a/browser/index.html
+++ b/browser/index.html
@@ -1,106 +1,110 @@
-
-
-bcoin
-
-
-
-
-Bcoin, the browser full node
-Welcome. Your machine is currently validating the blockchain.
-The blocks and wallet are stored on your local disk with indexed DB. You are
-connecting to the actual bitcoin P2P network via a websocket->tcp proxy.
-Enjoy. (See the bcoin repo for
-more bitcoin magic).
-
-
Chain State:
-
Last 20 Blocks/TXs:
-
-
-
-
-
-
-
-
-
-
+
+
+ bcoin
+
+
+
+
+
+ Bcoin, the browser full node
+
+ Welcome. Your machine is currently validating the blockchain. The blocks
+ and wallet are stored on your local disk with indexed DB. You are
+ connecting to the actual bitcoin P2P network via a websocket->tcp
+ proxy. Enjoy. (See the
+ bcoin repo
+ for more bitcoin magic).
+
+
+
Chain State:
+
Last 20 Blocks/TXs:
+
+
+
+
+
+
+
+
+
diff --git a/browser/index.js b/browser/index.js
deleted file mode 100644
index 400970ff..00000000
--- a/browser/index.js
+++ /dev/null
@@ -1,262 +0,0 @@
-;(function() {
-
-'use strict';
-
-var util = bcoin.util;
-var body = document.getElementsByTagName('body')[0];
-var log = document.getElementById('log');
-var wdiv = document.getElementById('wallet');
-var tdiv = document.getElementById('tx');
-var floating = document.getElementById('floating');
-var send = document.getElementById('send');
-var newaddr = document.getElementById('newaddr');
-var chainState = document.getElementById('state');
-var rpc = document.getElementById('rpc');
-var cmd = document.getElementById('cmd');
-var items = [];
-var scrollback = 0;
-var logger, node, wdb;
-
-window.onunhandledrejection = function(event) {
- throw event.reason;
-};
-
-body.onmouseup = function() {
- floating.style.display = 'none';
-};
-
-floating.onmouseup = function(ev) {
- ev.stopPropagation();
- return false;
-};
-
-function show(obj) {
- const json = obj && obj.toJSON ? obj.toJSON() : null;
- floating.innerHTML = escape(JSON.stringify(json, null, 2));
- floating.style.display = 'block';
-}
-
-logger = new bcoin.logger({ level: 'debug', console: true });
-logger.writeConsole = function(level, module, args) {
- var name = bcoin.logger.levelsByVal[level];
- var msg = this.fmt(args, false);
- if (++scrollback > 1000) {
- log.innerHTML = '';
- scrollback = 1;
- }
- log.innerHTML += '' + util.now() + ' ';
- if (name === 'error') {
- log.innerHTML += '';
- log.innerHTML += '[';
- log.innerHTML += name
- log.innerHTML += '] ';
- if (module)
- log.innerHTML += '(' + module + ') ';
- log.innerHTML += ' ';
- } else {
- log.innerHTML += '[';
- log.innerHTML += name
- log.innerHTML += '] ';
- if (module)
- log.innerHTML += '(' + module + ') ';
- }
- log.innerHTML += escape(msg) + '\n';
- log.scrollTop = log.scrollHeight;
-};
-
-rpc.onsubmit = function(ev) {
- var text = cmd.value || '';
- var argv = text.trim().split(/\s+/);
- var method = argv.shift();
- var params = [];
- var i, arg, param;
-
- cmd.value = '';
-
- for (i = 0; i < argv.length; i++) {
- arg = argv[i];
- try {
- param = JSON.parse(arg);
- } catch (e) {
- param = arg;
- }
- params.push(param);
- }
-
- node.rpc.execute({ method: method, params: params }).then(show, show);
-
- ev.preventDefault();
- ev.stopPropagation();
-
- return false;
-};
-
-send.onsubmit = function(ev) {
- var value = document.getElementById('amount').value;
- var address = document.getElementById('address').value;
- var tx, options;
-
- options = {
- outputs: [{
- address: address,
- value: bcoin.amount.value(value)
- }]
- };
-
- wdb.primary.createTX(options).then(function(mtx) {
- tx = mtx;
- return wdb.primary.sign(tx);
- }).then(function() {
- return node.sendTX(tx);
- }).then(function() {
- show(tx);
- });
-
- ev.preventDefault();
- ev.stopPropagation();
-
- return false;
-};
-
-newaddr.onmouseup = function() {
- wdb.primary.createReceive().then(function() {
- formatWallet(wdb.primary);
- });
-};
-
-function kb(size) {
- size /= 1000;
- return size.toFixed(2) + 'kb';
-}
-
-function create(html) {
- var el = document.createElement('div');
- el.innerHTML = html;
- return el.firstChild;
-}
-
-function escape(html, encode) {
- return html
- .replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&')
- .replace(//g, '>')
- .replace(/"/g, '"')
- .replace(/'/g, ''');
-}
-
-function addItem(item, entry) {
- var height = entry ? entry.height : -1;
- var el;
-
- if (items.length === 20) {
- el = items.shift();
- tdiv.removeChild(el);
- el.onmouseup = null;
- }
-
- el = create('' + item.rhash() + ' (' + height
- + ' - ' + kb(item.getSize()) + ') ');
- tdiv.appendChild(el);
-
- setMouseup(el, item);
-
- items.push(el);
-
- chainState.innerHTML = ''
- + 'tx=' + node.chain.db.state.tx
- + ' coin=' + node.chain.db.state.coin
- + ' value=' + bcoin.amount.btc(node.chain.db.state.value);
-}
-
-function setMouseup(el, obj) {
- el.onmouseup = function(ev) {
- show(obj);
- ev.stopPropagation();
- return false;
- };
-}
-
-function formatWallet(wallet) {
- var html = '';
- var json = wallet.master.toJSON(true);
- var i, tx, el;
-
- html += 'Wallet ';
-
- if (wallet.account.witness) {
- html += 'Current Address (p2wpkh): '
- + wallet.getAddress()
- + ' ';
- html += 'Current Address (p2wpkh behind p2sh): '
- + wallet.getNestedAddress()
- + ' ';
- } else {
- html += 'Current Address: ' + wallet.getAddress() + ' ';
- }
-
- html += 'Extended Private Key: ' + json.key.xprivkey + ' ';
- html += 'Mnemonic: ' + json.mnemonic.phrase + ' ';
-
- wallet.getBalance().then(function(balance) {
- html += 'Confirmed Balance: '
- + bcoin.amount.btc(balance.confirmed)
- + ' ';
-
- html += 'Unconfirmed Balance: '
- + bcoin.amount.btc(balance.unconfirmed)
- + ' ';
-
- return wallet.getHistory();
- }).then(function(txs) {
- return wallet.toDetails(txs);
- }).then(function(txs) {
- html += 'TXs:\n';
- wdiv.innerHTML = html;
-
- for (i = 0; i < txs.length; i++) {
- tx = txs[i];
-
- el = create(
- ''
- + tx.hash + ' ');
-
- wdiv.appendChild(el);
- setMouseup(el, tx.toJSON());
- }
- });
-}
-
-node = new bcoin.fullnode({
- hash: true,
- query: true,
- prune: true,
- network: 'main',
- db: 'leveldb',
- coinCache: 30000000,
- logConsole: true,
- workers: true,
- workerFile: '/bcoin-worker.js',
- logger: logger
-});
-
-wdb = node.use(bcoin.wallet.plugin);
-
-node.chain.on('block', addItem);
-node.mempool.on('tx', addItem);
-
-node.open().then(function() {
- return node.connect();
-}).then(function() {
- node.startSync();
-
- wdb.primary.on('balance', function() {
- formatWallet(wdb.primary);
- });
-
- formatWallet(wdb.primary);
-}).catch(function(err) {
- throw err;
-});
-
-})();
diff --git a/browser/server.js b/browser/server.js
index 3322d878..79dcc009 100644
--- a/browser/server.js
+++ b/browser/server.js
@@ -5,13 +5,10 @@ const fs = require('bfile');
const WSProxy = require('./wsproxy');
const index = fs.readFileSync(`${__dirname}/index.html`);
-const indexjs = fs.readFileSync(`${__dirname}/index.js`);
-const debug = fs.readFileSync(`${__dirname}/debug.html`);
-const bcoin = fs.readFileSync(`${__dirname}/bcoin.js`);
-const worker = fs.readFileSync(`${__dirname}/bcoin-worker.js`);
+const app = fs.readFileSync(`${__dirname}/app.js`);
+const worker = fs.readFileSync(`${__dirname}/worker.js`);
const proxy = new WSProxy({
- pow: process.argv.indexOf('--pow') !== -1,
ports: [8333, 18333, 18444, 28333, 28901]
});
@@ -20,6 +17,8 @@ const server = bweb.server({
sockets: false
});
+server.use(server.router());
+
proxy.on('error', (err) => {
console.error(err.stack);
});
@@ -28,27 +27,15 @@ server.on('error', (err) => {
console.error(err.stack);
});
-server.get('/favicon.ico', (req, res) => {
- res.send(404, '', 'txt');
-});
-
server.get('/', (req, res) => {
res.send(200, index, 'html');
});
-server.get('/index.js', (req, res) => {
- res.send(200, indexjs, 'js');
+server.get('/app.js', (req, res) => {
+ res.send(200, app, 'js');
});
-server.get('/debug', (req, res) => {
- res.send(200, debug, 'html');
-});
-
-server.get('/bcoin.js', (req, res) => {
- res.send(200, bcoin, 'js');
-});
-
-server.get('/bcoin-worker.js', (req, res) => {
+server.get('/worker.js', (req, res) => {
res.send(200, worker, 'js');
});
diff --git a/browser/src/app.js b/browser/src/app.js
new file mode 100644
index 00000000..77cc3eec
--- /dev/null
+++ b/browser/src/app.js
@@ -0,0 +1,284 @@
+'use strict';
+
+const Logger = require('blgr');
+const FullNode = require('../../lib/node/fullnode');
+const Amount = require('../../lib/btc/amount');
+const plugin = require('../../lib/wallet/plugin');
+const ProxySocket = require('./proxysocket');
+
+const body = document.getElementsByTagName('body')[0];
+const log = document.getElementById('log');
+const wdiv = document.getElementById('wallet');
+const tdiv = document.getElementById('tx');
+const floating = document.getElementById('floating');
+const send = document.getElementById('send');
+const newaddr = document.getElementById('newaddr');
+const chainState = document.getElementById('state');
+const rpc = document.getElementById('rpc');
+const cmd = document.getElementById('cmd');
+const items = [];
+
+let scrollback = 0;
+
+const logger = new Logger({
+ level: 'debug',
+ console: true
+});
+
+if (0)
+logger.writeConsole = function writeConsole(level, module, args) {
+ const name = Logger.levelsByVal[level];
+ const msg = this.fmt(args, false);
+
+ if (++scrollback > 1000) {
+ log.innerHTML = '';
+ scrollback = 1;
+ }
+
+ const now = Math.floor(Date.now() / 1000);
+
+ log.innerHTML += `${now} `;
+
+ if (name === 'error') {
+ log.innerHTML += `[${name}] `;
+ if (module)
+ log.innerHTML += `(${module}) `;
+ log.innerHTML += ' ';
+ } else {
+ log.innerHTML += `[${name}] `;
+ if (module)
+ log.innerHTML += `(${module}) `;
+ }
+
+ log.innerHTML += escape(msg) + '\n';
+ log.scrollTop = log.scrollHeight;
+};
+
+const node = new FullNode({
+ hash: true,
+ query: true,
+ prune: true,
+ network: 'main',
+ memory: false,
+ coinCache: 30,
+ logConsole: true,
+ workers: true,
+ workerFile: '/worker.js',
+ createSocket: (port, host) => {
+ return ProxySocket.connect('ws://127.0.0.1:8080', port, host);
+ },
+ logger: logger,
+ plugins: [plugin]
+});
+
+const {wdb} = node.require('walletdb');
+
+window.onunhandledrejection = function onunhandledrejection(event) {
+ throw event.reason;
+};
+
+body.onmouseup = function onmouseup() {
+ floating.style.display = 'none';
+};
+
+floating.onmouseup = function onmouseup(ev) {
+ ev.stopPropagation();
+ return false;
+};
+
+function show(obj) {
+ const json = obj && obj.toJSON ? obj.toJSON() : null;
+ floating.innerHTML = escape(JSON.stringify(json, null, 2));
+ floating.style.display = 'block';
+}
+
+rpc.onsubmit = function onsubmit(ev) {
+ const text = cmd.value || '';
+ const argv = text.trim().split(/\s+/);
+ const method = argv.shift();
+ const params = [];
+
+ cmd.value = '';
+
+ for (const arg of argv) {
+ let param;
+ try {
+ param = JSON.parse(arg);
+ } catch (e) {
+ param = arg;
+ }
+ params.push(param);
+ }
+
+ (async () => {
+ try {
+ const result = await node.rpc.execute({ method, params });
+ show(result);
+ } catch (e) {
+ show(e);
+ }
+ })();
+
+ ev.preventDefault();
+ ev.stopPropagation();
+
+ return false;
+};
+
+send.onsubmit = function onsubmit(ev) {
+ const value = document.getElementById('amount').value;
+ const address = document.getElementById('address').value;
+
+ const options = {
+ outputs: [{
+ address: address,
+ value: Amount.value(value)
+ }]
+ };
+
+ (async () => {
+ try {
+ const mtx = await wdb.primary.createTX(options);
+ await wdb.primary.sign(mtx);
+ await node.relay(mtx.toTX());
+ show(mtx);
+ } catch (e) {
+ show(e);
+ }
+ })();
+
+ ev.preventDefault();
+ ev.stopPropagation();
+
+ return false;
+};
+
+newaddr.onmouseup = function onmouseup() {
+ (async () => {
+ try {
+ await wdb.primary.createReceive();
+ formatWallet(wdb.primary);
+ } catch (e) {
+ show(e);
+ }
+ })();
+};
+
+function kb(size) {
+ size /= 1000;
+ return size.toFixed(2) + 'kb';
+}
+
+function create(html) {
+ const el = document.createElement('div');
+ el.innerHTML = html;
+ return el.firstChild;
+}
+
+function escape(html, encode) {
+ return html
+ .replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&')
+ .replace(//g, '>')
+ .replace(/"/g, '"')
+ .replace(/'/g, ''');
+}
+
+function addItem(item, entry) {
+ const height = entry ? entry.height : -1;
+
+ if (items.length === 20) {
+ const el = items.shift();
+ tdiv.removeChild(el);
+ el.onmouseup = null;
+ }
+
+ const el = create(''
+ + ``
+ + `${item.rhash()} (${height} - ${kb(item.getSize())})`
+ + ' '
+ );
+
+ tdiv.appendChild(el);
+
+ setMouseup(el, item);
+
+ items.push(el);
+
+ chainState.innerHTML = ''
+ + `tx=${node.chain.db.state.tx} `
+ + `coin=${node.chain.db.state.coin} `
+ + `value=${Amount.btc(node.chain.db.state.value)}`;
+}
+
+function setMouseup(el, obj) {
+ el.onmouseup = function onmouseup(ev) {
+ show(obj);
+ ev.stopPropagation();
+ return false;
+ };
+}
+
+async function formatWallet(wallet) {
+ try {
+ await _formatWallet(wallet);
+ } catch (e) {
+ show(e);
+ }
+}
+
+async function _formatWallet(wallet) {
+ const {key, mnemonic} = wallet.master.toJSON(node.network, true);
+ const account = await wallet.getAccount('default');
+ const receive = account.receiveAddress();
+ const nested = account.nestedAddress();
+ const raddr = receive.toString(node.network);
+ const naddr = nested ? nested.toString(node.network) : null;
+
+ let html = '';
+
+ html += 'Wallet ';
+
+ if (naddr) {
+ html += `Current Address (p2wpkh): ${raddr} `;
+ html += `Current Address (p2wpkh behind p2sh): ${naddr} `;
+ } else {
+ html += `Current Address: ${raddr} `;
+ }
+
+ html += `Extended Private Key: ${key.xprivkey} `;
+ html += `Mnemonic: ${mnemonic.phrase} `;
+
+ const balance = await wallet.getBalance();
+
+ html += `Confirmed Balance: ${Amount.btc(balance.confirmed)} `;
+ html += `Unconfirmed Balance: ${Amount.btc(balance.unconfirmed)} `;
+
+ const txs = await wallet.getHistory();
+ const det = await wallet.toDetails(txs);
+
+ html += 'TXs:\n';
+ wdiv.innerHTML = html;
+
+ for (const tx of det) {
+ const el = create(
+ `${tx.hash} `);
+ wdiv.appendChild(el);
+ setMouseup(el, tx.toJSON());
+ }
+}
+
+node.chain.on('block', addItem);
+node.mempool.on('tx', addItem);
+
+(async () => {
+ await node.open();
+ await node.connect();
+ node.startSync();
+ wdb.primary.on('balance', () => {
+ formatWallet(wdb.primary);
+ });
+ formatWallet(wdb.primary);
+})().catch((err) => {
+ throw err;
+});
diff --git a/browser/proxysocket.js b/browser/src/proxysocket.js
similarity index 67%
rename from browser/proxysocket.js
rename to browser/src/proxysocket.js
index 8267f3f8..80f07177 100644
--- a/browser/proxysocket.js
+++ b/browser/src/proxysocket.js
@@ -9,20 +9,18 @@
const assert = require('assert');
const EventEmitter = require('events');
const bsock = require('bsock');
-const hash256 = require('bcrypto/lib/hash256');
-const bio = require('bufio');
class ProxySocket extends EventEmitter {
constructor(uri) {
super();
- this.info = null;
+ this.socket = bsock.socket();
+ this.socket.reconnection = false;
+ this.socket.connect(uri);
- this.socket = bsock.connect(uri);
this.sendBuffer = [];
this.recvBuffer = [];
this.paused = false;
- this.snonce = null;
this.bytesWritten = 0;
this.bytesRead = 0;
this.remoteAddress = null;
@@ -34,20 +32,6 @@ class ProxySocket extends EventEmitter {
}
init() {
- this.socket.bind('info', (info) => {
- if (this.closed)
- return;
-
- this.info = info;
-
- if (info.pow) {
- this.snonce = Buffer.from(info.snonce, 'hex');
- this.target = Buffer.from(info.target, 'hex');
- }
-
- this.emit('info', info);
- });
-
this.socket.on('error', (err) => {
console.error(err);
});
@@ -87,7 +71,7 @@ class ProxySocket extends EventEmitter {
this.emit('timeout');
});
- this.socket.bind('disconnect', () => {
+ this.socket.on('disconnect', () => {
if (this.closed)
return;
this.closed = true;
@@ -104,37 +88,7 @@ class ProxySocket extends EventEmitter {
return;
}
- if (!this.info) {
- this.once('info', connect.bind(this, port, host));
- return;
- }
-
- let nonce = 0;
-
- if (this.info.pow) {
- const bw = bio.write();
-
- bw.writeU32(nonce);
- bw.writeBytes(this.snonce);
- bw.writeU32(port);
- bw.writeString(host, 'ascii');
-
- const pow = bw.render();
-
- console.log(
- 'Solving proof of work to create socket (%d, %s) -- please wait.',
- port, host);
-
- do {
- nonce += 1;
- assert(nonce <= 0xffffffff, 'Could not create socket.');
- pow.writeUInt32LE(nonce, 0, true);
- } while (hash256.digest(pow).compare(this.target) > 0);
-
- console.log('Solved proof of work: %d', nonce);
- }
-
- this.socket.fire('tcp connect', port, host, nonce);
+ this.socket.fire('tcp connect', port, host);
for (const chunk of this.sendBuffer)
this.write(chunk);
@@ -157,15 +111,6 @@ class ProxySocket extends EventEmitter {
}
write(data, callback) {
- if (!this.info) {
- this.sendBuffer.push(data);
-
- if (callback)
- callback();
-
- return true;
- }
-
this.bytesWritten += data.length;
this.socket.fire('tcp data', data.toString('hex'));
diff --git a/browser/wsproxy.js b/browser/wsproxy.js
index d6b5748b..3b219dd5 100644
--- a/browser/wsproxy.js
+++ b/browser/wsproxy.js
@@ -4,13 +4,7 @@ const assert = require('assert');
const net = require('net');
const EventEmitter = require('events');
const bsock = require('bsock');
-const hash256 = require('bcrypto/lib/hash256');
const IP = require('binet');
-const bio = require('bufio');
-
-const TARGET = Buffer.from(
- '0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
- 'hex');
class WSProxy extends EventEmitter {
constructor(options) {
@@ -20,8 +14,6 @@ class WSProxy extends EventEmitter {
options = {};
this.options = options;
- this.target = options.target || TARGET;
- this.pow = options.pow === true;
this.ports = new Set();
this.io = bsock.server();
this.sockets = new WeakMap();
@@ -51,18 +43,16 @@ class WSProxy extends EventEmitter {
// mutating the websocket object.
this.sockets.set(ws, state);
- ws.fire('info', state.toInfo());
-
ws.on('error', (err) => {
this.emit('error', err);
});
- ws.bind('tcp connect', (port, host, nonce) => {
- this.handleConnect(ws, port, host, nonce);
+ ws.bind('tcp connect', (port, host) => {
+ this.handleConnect(ws, port, host);
});
}
- handleConnect(ws, port, host, nonce) {
+ handleConnect(ws, port, host) {
const state = this.sockets.get(ws);
assert(state);
@@ -80,30 +70,6 @@ class WSProxy extends EventEmitter {
return;
}
- if (this.pow) {
- if ((nonce >>> 0) !== nonce) {
- this.log('Client did not solve proof of work (%s).', state.host);
- ws.fire('tcp close');
- ws.destroy();
- return;
- }
-
- const bw = bio.write();
- bw.writeU32(nonce);
- bw.writeBytes(state.snonce);
- bw.writeU32(port);
- bw.writeString(host, 'ascii');
-
- const pow = bw.render();
-
- if (hash256.digest(pow).compare(this.target) > 0) {
- this.log('Client did not solve proof of work (%s).', state.host);
- ws.fire('tcp close');
- ws.destroy();
- return;
- }
- }
-
let raw, addr;
try {
raw = IP.toBuffer(host);
@@ -206,7 +172,7 @@ class WSProxy extends EventEmitter {
socket.resume();
});
- ws.bind('disconnect', () => {
+ ws.on('disconnect', () => {
socket.destroy();
});
}
@@ -223,22 +189,11 @@ class WSProxy extends EventEmitter {
class SocketState {
constructor(server, socket) {
- this.pow = server.pow;
- this.target = server.target;
- this.snonce = nonce();
this.socket = null;
this.host = socket.host;
this.remoteHost = null;
}
- toInfo() {
- return {
- pow: this.pow,
- target: this.target.toString('hex'),
- snonce: this.snonce.toString('hex')
- };
- }
-
connect(port, host) {
this.socket = net.connect(port, host);
this.remoteHost = IP.toHostname(host, port);
@@ -246,11 +201,4 @@ class SocketState {
}
}
-function nonce() {
- const buf = Buffer.allocUnsafe(8);
- buf.writeUInt32LE(Math.random() * 0x100000000, 0, true);
- buf.writeUInt32LE(Math.random() * 0x100000000, 4, true);
- return buf;
-}
-
module.exports = WSProxy;
diff --git a/lib/bcoin-browser.js b/lib/bcoin-browser.js
index bcdae54e..9240c28d 100644
--- a/lib/bcoin-browser.js
+++ b/lib/bcoin-browser.js
@@ -33,12 +33,10 @@ bcoin.set = function set(network) {
* Expose
*/
-/*
// Blockchain
bcoin.blockchain = require('./blockchain');
bcoin.Chain = require('./blockchain/chain');
bcoin.ChainEntry = require('./blockchain/chainentry');
-*/
// BTC
bcoin.btc = require('./btc');
@@ -57,7 +55,6 @@ bcoin.HDPrivateKey = require('./hd/private');
bcoin.HDPublicKey = require('./hd/public');
bcoin.Mnemonic = require('./hd/mnemonic');
-/*
// Mempool
bcoin.mempool = require('./mempool');
bcoin.Fees = require('./mempool/fees');
@@ -79,7 +76,6 @@ bcoin.node = require('./node');
bcoin.Node = require('./node/node');
bcoin.FullNode = require('./node/fullnode');
bcoin.SPVNode = require('./node/spvnode');
-*/
// Primitives
bcoin.primitives = require('./primitives');
@@ -117,7 +113,6 @@ bcoin.Witness = require('./script/witness');
bcoin.utils = require('./utils');
bcoin.util = require('./utils/util');
-/*
// Wallet
bcoin.wallet = require('./wallet');
bcoin.WalletDB = require('./wallet/walletdb');
@@ -125,7 +120,6 @@ bcoin.WalletDB = require('./wallet/walletdb');
// Workers
bcoin.workers = require('./workers');
bcoin.WorkerPool = require('./workers/workerpool');
-*/
// Package Info
bcoin.pkg = require('./pkg');
diff --git a/package.json b/package.json
index 1ce27766..418efebb 100644
--- a/package.json
+++ b/package.json
@@ -69,7 +69,7 @@
"bcoin-spvnode": "./bin/spvnode"
},
"scripts": {
- "clean": "rm -f {browser/,}{bcoin.js,bcoin-worker.js}",
+ "clean": "rm -f {browser/,}{bcoin.js,bcoin-worker.js,app.js,worker.js}",
"docs": "jsdoc -c jsdoc.json",
"lint": "eslint $(cat .eslintfiles) || exit 0",
"lint-file": "eslint",
@@ -82,6 +82,6 @@
"webpack": "webpack --config webpack.browser.js",
"webpack-browser": "webpack --config webpack.browser.js",
"webpack-compat": "webpack --config webpack.compat.js",
- "webpack-node": "webpack --config webpack.node.js"
+ "webpack-app": "webpack --config webpack.app.js"
}
}
diff --git a/webpack.app.js b/webpack.app.js
new file mode 100644
index 00000000..db860174
--- /dev/null
+++ b/webpack.app.js
@@ -0,0 +1,32 @@
+'use strict';
+
+const Path = require('path');
+const webpack = require('webpack');
+const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
+const str = JSON.stringify;
+const env = process.env;
+
+module.exports = {
+ target: 'web',
+ entry: {
+ 'app': './browser/src/app',
+ 'worker': './lib/workers/worker'
+ },
+ output: {
+ path: Path.join(__dirname, 'browser'),
+ filename: '[name].js'
+ },
+ resolve: {
+ modules: ['node_modules'],
+ extensions: ['-browser.js', '.js', '.json']
+ },
+ plugins: [
+ new webpack.DefinePlugin({
+ 'process.env.BCOIN_NETWORK':
+ str(env.BCOIN_NETWORK || 'main'),
+ 'process.env.BCOIN_WORKER_FILE':
+ str(env.BCOIN_WORKER_FILE || '/bcoin-worker.js')
+ }),
+ new UglifyJsPlugin()
+ ]
+};
diff --git a/webpack.browser.js b/webpack.browser.js
index 7579f870..5a8eeb11 100644
--- a/webpack.browser.js
+++ b/webpack.browser.js
@@ -1,7 +1,7 @@
'use strict';
+const Path = require('path');
const webpack = require('webpack');
-const path = require('path');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const str = JSON.stringify;
const env = process.env;
@@ -9,11 +9,13 @@ const env = process.env;
module.exports = {
target: 'web',
entry: {
- 'bcoin': './lib/bcoin-browser',
+ 'bcoin': './lib/bcoin',
'bcoin-worker': './lib/workers/worker'
},
output: {
- path: path.join(__dirname, 'browser'),
+ library: 'bcoin',
+ libraryTarget: 'umd',
+ path: Path.join(__dirname, 'browser'),
filename: '[name].js'
},
resolve: {
@@ -27,10 +29,6 @@ module.exports = {
'process.env.BCOIN_WORKER_FILE':
str(env.BCOIN_WORKER_FILE || '/bcoin-worker.js')
}),
- new UglifyJsPlugin({
- compress: {
- warnings: true
- }
- })
+ new UglifyJsPlugin()
]
};
diff --git a/webpack.compat.js b/webpack.compat.js
index 26a35267..4a1cef80 100644
--- a/webpack.compat.js
+++ b/webpack.compat.js
@@ -1,7 +1,7 @@
'use strict';
+const Path = require('path');
const webpack = require('webpack');
-const path = require('path');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const str = JSON.stringify;
const env = process.env;
@@ -9,11 +9,13 @@ const env = process.env;
module.exports = {
target: 'web',
entry: {
- 'bcoin': './lib/bcoin-browser',
+ 'bcoin': './lib/bcoin',
'bcoin-worker': './lib/workers/worker'
},
output: {
- path: path.join(__dirname, 'browser'),
+ library: 'bcoin',
+ libraryTarget: 'umd',
+ path: Path.join(__dirname, 'browser'),
filename: '[name].js'
},
resolve: {
@@ -23,7 +25,6 @@ module.exports = {
module: {
rules: [{
test: /\.js$/,
- exclude: /node_modules\/(?!bcoin|elliptic|bn\.js|n64)/,
loader: 'babel-loader'
}]
},
@@ -34,10 +35,6 @@ module.exports = {
'process.env.BCOIN_WORKER_FILE':
str(env.BCOIN_WORKER_FILE || '/bcoin-worker.js')
}),
- new UglifyJsPlugin({
- compress: {
- warnings: false
- }
- })
+ new UglifyJsPlugin()
]
};
diff --git a/webpack.node.js b/webpack.node.js
deleted file mode 100644
index 110ce723..00000000
--- a/webpack.node.js
+++ /dev/null
@@ -1,49 +0,0 @@
-'use strict';
-
-const webpack = require('webpack');
-const path = require('path');
-const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
-const str = JSON.stringify;
-const env = process.env;
-
-module.exports = {
- target: 'node',
- entry: {
- 'bcoin': './lib/bcoin-browser',
- 'bcoin-worker': './lib/workers/worker'
- },
- output: {
- path: __dirname,
- filename: '[name].js',
- libraryTarget: 'commonjs2'
- },
- resolve: {
- modules: ['node_modules'],
- extensions: ['.node', '.js', '.json'],
- alias: {
- 'bindings': path.resolve(__dirname, 'webpack', 'bindings.js')
- }
- },
- node: {
- __dirname: false,
- __filename: false
- },
- module: {
- rules: [{
- test: /\.node$/,
- loader: 'node-loader'
- }]
- },
- plugins: [
- new webpack.DefinePlugin({
- 'process.env.BCOIN_WORKER_FILE':
- str(env.BCOIN_WORKER_FILE || 'bcoin-worker.js')
- }),
- new webpack.IgnorePlugin(/^utf-8-validate|bufferutil$/),
- new UglifyJsPlugin({
- compress: {
- warnings: true
- }
- })
- ]
-};
diff --git a/webpack/bindings.js b/webpack/bindings.js
deleted file mode 100644
index b8ed4ff1..00000000
--- a/webpack/bindings.js
+++ /dev/null
@@ -1,13 +0,0 @@
-'use strict';
-
-module.exports = function bindings(name) {
- switch (name) {
- case 'leveldown':
- return require('leveldown/build/Release/leveldown.node');
- case 'bcoin-native':
- return require('bcoin-native/build/Release/bcoin-native.node');
- case 'secp256k1':
- return require('secp256k1/build/Release/secp256k1.node');
- }
- throw new Error(`Cannot find module "${name}".`);
-};