From 84b36a71939cfc6c673f0fd3fec079ca7e23df6c Mon Sep 17 00:00:00 2001
From: Marek Kotewicz <marek.kotewicz@gmail.com>
Date: Tue, 11 Nov 2014 11:46:46 +0100
Subject: [PATCH 1/2] retabed files

---
 lib/httprpc.js   | 107 ++++---
 lib/main.js      | 732 +++++++++++++++++++++++------------------------
 lib/qt.js        |  33 +--
 lib/websocket.js |  78 ++---
 4 files changed, 476 insertions(+), 474 deletions(-)

diff --git a/lib/httprpc.js b/lib/httprpc.js
index 99f02b532..8141a6bae 100644
--- a/lib/httprpc.js
+++ b/lib/httprpc.js
@@ -21,74 +21,73 @@
  * @date 2014
  */
 
-if(process.env.NODE_ENV !== "build") {
+if (process.env.NODE_ENV !== "build") {
     var XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; // jshint ignore:line
 }
 
+var HttpRpcProvider = function (host) {
+    this.handlers = [];
+    this.host = host;
+};
 
-    var HttpRpcProvider = function (host) {
-        this.handlers = [];
-        this.host = host;
+function formatJsonRpcObject(object) {
+    return {
+        jsonrpc: '2.0',
+        method: object.call,
+        params: object.args,
+        id: object._id
     };
+}
 
-    function formatJsonRpcObject(object) {
-        return {
-            jsonrpc: '2.0',
-            method: object.call,
-            params: object.args,
-            id: object._id
-        };
-    }
-
-    function formatJsonRpcMessage(message) {
-        var object = JSON.parse(message);
-
-        return {
-            _id: object.id,
-            data: object.result,
-            error: object.error
-        };
-    }
-
-    HttpRpcProvider.prototype.sendRequest = function (payload, cb) {
-        var data = formatJsonRpcObject(payload);
+function formatJsonRpcMessage(message) {
+    var object = JSON.parse(message);
 
-        var request = new XMLHttpRequest();
-        request.open("POST", this.host, true);
-        request.send(JSON.stringify(data));
-        request.onreadystatechange = function () {
-            if (request.readyState === 4 && cb) {
-                cb(request);
-            }
-        };
+    return {
+        _id: object.id,
+        data: object.result,
+        error: object.error
     };
+}
 
-    HttpRpcProvider.prototype.send = function (payload) {
-        var self = this;
-        this.sendRequest(payload, function (request) {
-            self.handlers.forEach(function (handler) {
-                handler.call(self, formatJsonRpcMessage(request.responseText));
-            });
-        });
+HttpRpcProvider.prototype.sendRequest = function (payload, cb) {
+    var data = formatJsonRpcObject(payload);
+
+    var request = new XMLHttpRequest();
+    request.open("POST", this.host, true);
+    request.send(JSON.stringify(data));
+    request.onreadystatechange = function () {
+        if (request.readyState === 4 && cb) {
+            cb(request);
+        }
     };
+};
 
-    HttpRpcProvider.prototype.poll = function (payload, id) {
-        var self = this;
-        this.sendRequest(payload, function (request) {
-            var parsed = JSON.parse(request.responseText);
-            if (parsed.error || (parsed.result instanceof Array ? parsed.result.length === 0 : !parsed.result)) {
-                return;
-            }
-            self.handlers.forEach(function (handler) {
-                handler.call(self, {_event: payload.call, _id: id, data: parsed.result});
-            });
+HttpRpcProvider.prototype.send = function (payload) {
+    var self = this;
+    this.sendRequest(payload, function (request) {
+        self.handlers.forEach(function (handler) {
+            handler.call(self, formatJsonRpcMessage(request.responseText));
         });
-    };
+    });
+};
 
-    Object.defineProperty(HttpRpcProvider.prototype, "onmessage", {
-        set: function (handler) {
-            this.handlers.push(handler);
+HttpRpcProvider.prototype.poll = function (payload, id) {
+    var self = this;
+    this.sendRequest(payload, function (request) {
+        var parsed = JSON.parse(request.responseText);
+        if (parsed.error || (parsed.result instanceof Array ? parsed.result.length === 0 : !parsed.result)) {
+            return;
         }
+        self.handlers.forEach(function (handler) {
+            handler.call(self, {_event: payload.call, _id: id, data: parsed.result});
+        });
     });
+};
+
+Object.defineProperty(HttpRpcProvider.prototype, "onmessage", {
+    set: function (handler) {
+        this.handlers.push(handler);
+    }
+});
 
 module.exports = HttpRpcProvider;
diff --git a/lib/main.js b/lib/main.js
index 52fa790b4..d751f8527 100644
--- a/lib/main.js
+++ b/lib/main.js
@@ -22,136 +22,169 @@
  * @date 2014
  */
 
-    function flattenPromise (obj) {
-        if (obj instanceof Promise) {
-            return Promise.resolve(obj);
-        }
-
-        if (obj instanceof Array) {
-            return new Promise(function (resolve) {
-                var promises = obj.map(function (o) {
-                    return flattenPromise(o);
-                });
+function flattenPromise (obj) {
+    if (obj instanceof Promise) {
+        return Promise.resolve(obj);
+    }
 
-                return Promise.all(promises).then(function (res) {
-                    for (var i = 0; i < obj.length; i++) {
-                        obj[i] = res[i];
-                    }
-                    resolve(obj);
-                });
+    if (obj instanceof Array) {
+        return new Promise(function (resolve) {
+            var promises = obj.map(function (o) {
+                return flattenPromise(o);
             });
-        }
- 
-        if (obj instanceof Object) {
-            return new Promise(function (resolve) {
-                var keys = Object.keys(obj);
-                var promises = keys.map(function (key) {
-                    return flattenPromise(obj[key]);
-                });
 
-                return Promise.all(promises).then(function (res) {
-                    for (var i = 0; i < keys.length; i++) {
-                        obj[keys[i]] = res[i];
-                    }
-                    resolve(obj);
-                });
+            return Promise.all(promises).then(function (res) {
+                for (var i = 0; i < obj.length; i++) {
+                    obj[i] = res[i];
+                }
+                resolve(obj);
             });
-        }
-
-        return Promise.resolve(obj);
+        });
     }
 
-    var ethMethods = function () {
-        var blockCall = function (args) {
-            return typeof args[0] === "string" ? "eth_blockByHash" : "eth_blockByNumber";
-        };
+    if (obj instanceof Object) {
+        return new Promise(function (resolve) {
+            var keys = Object.keys(obj);
+            var promises = keys.map(function (key) {
+                return flattenPromise(obj[key]);
+            });
 
-        var transactionCall = function (args) {
-            return typeof args[0] === "string" ? 'eth_transactionByHash' : 'eth_transactionByNumber';   
-        };
+            return Promise.all(promises).then(function (res) {
+                for (var i = 0; i < keys.length; i++) {
+                    obj[keys[i]] = res[i];
+                }
+                resolve(obj);
+            });
+        });
+    }
 
-        var uncleCall = function (args) {
-            return typeof args[0] === "string" ? 'eth_uncleByHash' : 'eth_uncleByNumber';       
-        };
+    return Promise.resolve(obj);
+}
 
-        var methods = [
-        { name: 'balanceAt', call: 'eth_balanceAt' },
-        { name: 'stateAt', call: 'eth_stateAt' },
-        { name: 'countAt', call: 'eth_countAt'},
-        { name: 'codeAt', call: 'eth_codeAt' },
-        { name: 'transact', call: 'eth_transact' },
-        { name: 'call', call: 'eth_call' },
-        { name: 'block', call: blockCall },
-        { name: 'transaction', call: transactionCall },
-        { name: 'uncle', call: uncleCall },
-        { name: 'compile', call: 'eth_compile' },
-        { name: 'lll', call: 'eth_lll' }
-        ];
-        return methods;
+var ethMethods = function () {
+    var blockCall = function (args) {
+        return typeof args[0] === "string" ? "eth_blockByHash" : "eth_blockByNumber";
     };
 
-    var ethProperties = function () {
-        return [
-        { name: 'coinbase', getter: 'eth_coinbase', setter: 'eth_setCoinbase' },
-        { name: 'listening', getter: 'eth_listening', setter: 'eth_setListening' },
-        { name: 'mining', getter: 'eth_mining', setter: 'eth_setMining' },
-        { name: 'gasPrice', getter: 'eth_gasPrice' },
-        { name: 'account', getter: 'eth_account' },
-        { name: 'accounts', getter: 'eth_accounts' },
-        { name: 'peerCount', getter: 'eth_peerCount' },
-        { name: 'defaultBlock', getter: 'eth_defaultBlock', setter: 'eth_setDefaultBlock' },
-        { name: 'number', getter: 'eth_number'}
-        ];
+    var transactionCall = function (args) {
+        return typeof args[0] === "string" ? 'eth_transactionByHash' : 'eth_transactionByNumber';   
     };
 
-    var dbMethods = function () {
-        return [
-        { name: 'put', call: 'db_put' },
-        { name: 'get', call: 'db_get' },
-        { name: 'putString', call: 'db_putString' },
-        { name: 'getString', call: 'db_getString' }
-        ];
+    var uncleCall = function (args) {
+        return typeof args[0] === "string" ? 'eth_uncleByHash' : 'eth_uncleByNumber';       
     };
 
-    var shhMethods = function () {
-        return [
-        { name: 'post', call: 'shh_post' },
-        { name: 'newIdentity', call: 'shh_newIdentity' },
-        { name: 'haveIdentity', call: 'shh_haveIdentity' },
-        { name: 'newGroup', call: 'shh_newGroup' },
-        { name: 'addToGroup', call: 'shh_addToGroup' }
-        ];
+    var methods = [
+    { name: 'balanceAt', call: 'eth_balanceAt' },
+    { name: 'stateAt', call: 'eth_stateAt' },
+    { name: 'countAt', call: 'eth_countAt'},
+    { name: 'codeAt', call: 'eth_codeAt' },
+    { name: 'transact', call: 'eth_transact' },
+    { name: 'call', call: 'eth_call' },
+    { name: 'block', call: blockCall },
+    { name: 'transaction', call: transactionCall },
+    { name: 'uncle', call: uncleCall },
+    { name: 'compile', call: 'eth_compile' },
+    { name: 'lll', call: 'eth_lll' }
+    ];
+    return methods;
+};
+
+var ethProperties = function () {
+    return [
+    { name: 'coinbase', getter: 'eth_coinbase', setter: 'eth_setCoinbase' },
+    { name: 'listening', getter: 'eth_listening', setter: 'eth_setListening' },
+    { name: 'mining', getter: 'eth_mining', setter: 'eth_setMining' },
+    { name: 'gasPrice', getter: 'eth_gasPrice' },
+    { name: 'account', getter: 'eth_account' },
+    { name: 'accounts', getter: 'eth_accounts' },
+    { name: 'peerCount', getter: 'eth_peerCount' },
+    { name: 'defaultBlock', getter: 'eth_defaultBlock', setter: 'eth_setDefaultBlock' },
+    { name: 'number', getter: 'eth_number'}
+    ];
+};
+
+var dbMethods = function () {
+    return [
+    { name: 'put', call: 'db_put' },
+    { name: 'get', call: 'db_get' },
+    { name: 'putString', call: 'db_putString' },
+    { name: 'getString', call: 'db_getString' }
+    ];
+};
+
+var shhMethods = function () {
+    return [
+    { name: 'post', call: 'shh_post' },
+    { name: 'newIdentity', call: 'shh_newIdentity' },
+    { name: 'haveIdentity', call: 'shh_haveIdentity' },
+    { name: 'newGroup', call: 'shh_newGroup' },
+    { name: 'addToGroup', call: 'shh_addToGroup' }
+    ];
+};
+
+var ethWatchMethods = function () {
+    var newFilter = function (args) {
+        return typeof args[0] === 'string' ? 'eth_newFilterString' : 'eth_newFilter';
     };
 
-    var ethWatchMethods = function () {
-        var newFilter = function (args) {
-            return typeof args[0] === 'string' ? 'eth_newFilterString' : 'eth_newFilter';
+    return [
+    { name: 'newFilter', call: newFilter },
+    { name: 'uninstallFilter', call: 'eth_uninstallFilter' },
+    { name: 'getMessages', call: 'eth_getMessages' }
+    ];
+};
+
+var shhWatchMethods = function () {
+    return [
+    { name: 'newFilter', call: 'shh_newFilter' },
+    { name: 'uninstallFilter', call: 'shh_uninstallFilter' },
+    { name: 'getMessage', call: 'shh_getMessages' }
+    ];
+};
+
+var setupMethods = function (obj, methods) {
+    methods.forEach(function (method) {
+        obj[method.name] = function () {
+            return flattenPromise(Array.prototype.slice.call(arguments)).then(function (args) {
+                var call = typeof method.call === "function" ? method.call(args) : method.call;
+                return {call: call, args: args};
+            }).then(function (request) {
+                return new Promise(function (resolve, reject) {
+                    web3.provider.send(request, function (err, result) {
+                        if (!err) {
+                            resolve(result);
+                            return;
+                        }
+                        reject(err);
+                    });
+                });
+            }).catch(function(err) {
+                console.error(err);
+            });
         };
-
-        return [
-        { name: 'newFilter', call: newFilter },
-        { name: 'uninstallFilter', call: 'eth_uninstallFilter' },
-        { name: 'getMessages', call: 'eth_getMessages' }
-        ];
-    };
-
-    var shhWatchMethods = function () {
-        return [
-        { name: 'newFilter', call: 'shh_newFilter' },
-        { name: 'uninstallFilter', call: 'shh_uninstallFilter' },
-        { name: 'getMessage', call: 'shh_getMessages' }
-        ];
-    };
-
-    var setupMethods = function (obj, methods) {
-        methods.forEach(function (method) {
-            obj[method.name] = function () {
-                return flattenPromise(Array.prototype.slice.call(arguments)).then(function (args) {
-                    var call = typeof method.call === "function" ? method.call(args) : method.call;
-                    return {call: call, args: args};
-                }).then(function (request) {
-                    return new Promise(function (resolve, reject) {
-                        web3.provider.send(request, function (err, result) {
+    });
+};
+
+var setupProperties = function (obj, properties) {
+    properties.forEach(function (property) {
+        var proto = {};
+        proto.get = function () {
+            return new Promise(function(resolve, reject) {
+                web3.provider.send({call: property.getter}, function(err, result) {
+                    if (!err) {
+                        resolve(result);
+                        return;
+                    }
+                    reject(err);
+                });
+            });
+        };
+        if (property.setter) {
+            proto.set = function (val) {
+                return flattenPromise([val]).then(function (args) {
+                    return new Promise(function (resolve) {
+                        web3.provider.send({call: property.setter, args: args}, function (err, result) {
                             if (!err) {
                                 resolve(result);
                                 return;
@@ -159,294 +192,261 @@
                             reject(err);
                         });
                     });
-                }).catch(function(err) {
+                }).catch(function (err) {
                     console.error(err);
                 });
             };
-        });
-    };
-
-    var setupProperties = function (obj, properties) {
-        properties.forEach(function (property) {
-            var proto = {};
-            proto.get = function () {
-                return new Promise(function(resolve, reject) {
-                    web3.provider.send({call: property.getter}, function(err, result) {
-                        if (!err) {
-                            resolve(result);
-                            return;
-                        }
-                        reject(err);
-                    });
-                });
-            };
-            if (property.setter) {
-                proto.set = function (val) {
-                    return flattenPromise([val]).then(function (args) {
-                        return new Promise(function (resolve) {
-                            web3.provider.send({call: property.setter, args: args}, function (err, result) {
-                                if (!err) {
-                                    resolve(result);
-                                    return;
-                                }
-                                reject(err);
-                            });
-                        });
-                    }).catch(function (err) {
-                        console.error(err);
-                    });
-                };
-            }
-            Object.defineProperty(obj, property.name, proto);
-        });
-    };
- 
-    var web3 = {
-        _callbacks: {},
-        _events: {},
-        providers: {},
-        toHex: function(str) {
-            var hex = "";
-            for(var i = 0; i < str.length; i++) {
-                var n = str.charCodeAt(i).toString(16);
-                hex += n.length < 2 ? '0' + n : n;
-            }
-
-            return hex;
-        },
-
-        toAscii: function(hex) {
-            // Find termination
-            var str = "";
-            var i = 0, l = hex.length;
-            if (hex.substring(0, 2) === '0x')
-                i = 2;
-            for(; i < l; i+=2) {
-                var code = hex.charCodeAt(i);
-                if(code === 0) {
-                    break;
-                }
-
-                str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
-            }
-
-            return str;
-        },
-
-        toDecimal: function (val) {
-            return parseInt(val, 16);
-        },
-
-        fromAscii: function(str, pad) {
-            pad = pad === undefined ? 32 : pad;
-            var hex = this.toHex(str);
-            while(hex.length < pad*2)
-                hex += "00";
-            return "0x" + hex;
-        },
-
-        eth: {
-            prototype: Object(), // jshint ignore:line
-            watch: function (params) {
-                return new Filter(params, ethWatch);
-            }
-        },
-
-        db: {
-            prototype: Object() // jshint ignore:line
-        },
-
-        shh: {
-            prototype: Object(), // jshint ignore:line
-            watch: function (params) {
-                return new Filter(params, shhWatch);
-            }
-        },
-
-        on: function(event, id, cb) {
-            if(web3._events[event] === undefined) {
-                web3._events[event] = {};
-            }
-
-            web3._events[event][id] = cb;
-            return this;
-        },
+        }
+        Object.defineProperty(obj, property.name, proto);
+    });
+};
+
+var web3 = {
+    _callbacks: {},
+    _events: {},
+    providers: {},
+    toHex: function(str) {
+        var hex = "";
+        for(var i = 0; i < str.length; i++) {
+            var n = str.charCodeAt(i).toString(16);
+            hex += n.length < 2 ? '0' + n : n;
+        }
 
-        off: function(event, id) {
-            if(web3._events[event] !== undefined) {
-                delete web3._events[event][id];
+        return hex;
+    },
+
+    toAscii: function(hex) {
+        // Find termination
+        var str = "";
+        var i = 0, l = hex.length;
+        if (hex.substring(0, 2) === '0x')
+            i = 2;
+        for(; i < l; i+=2) {
+            var code = hex.charCodeAt(i);
+            if(code === 0) {
+                break;
             }
 
-            return this;
-        },
-
-        trigger: function(event, id, data) {
-            var callbacks = web3._events[event];
-            if (!callbacks || !callbacks[id]) {
-                return;
-            }
-            var cb = callbacks[id];
-            cb(data);
+            str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
         }
-    };
-
-    var eth = web3.eth;
-    setupMethods(eth, ethMethods());
-    setupProperties(eth, ethProperties());
-    setupMethods(web3.db, dbMethods());
-    setupMethods(web3.shh, shhMethods());
 
-    var ethWatch = {
-        changed: 'eth_changed'
-    };
-    setupMethods(ethWatch, ethWatchMethods());
-    var shhWatch = {
-        changed: 'shh_changed'
-    };
-    setupMethods(shhWatch, shhWatchMethods());
-
-    var ProviderManager = function() {
-        this.queued = [];
-        this.polls = [];
-        this.ready = false;
-        this.provider = undefined;
-        this.id = 1;
-
-        var self = this;
-        var poll = function () {
-            if (self.provider && self.provider.poll) {
-                self.polls.forEach(function (data) {
-                    data.data._id = self.id;
-                    self.id++;
-                    self.provider.poll(data.data, data.id);
-                });
-            }
-            setTimeout(poll, 12000);
-        };
-        poll();
-    };
-
-    ProviderManager.prototype.send = function(data, cb) {
-        data._id = this.id;
-        if (cb) {
-            web3._callbacks[data._id] = cb;
+        return str;
+    },
+
+    toDecimal: function (val) {
+        return parseInt(val, 16);
+    },
+
+    fromAscii: function(str, pad) {
+        pad = pad === undefined ? 32 : pad;
+        var hex = this.toHex(str);
+        while(hex.length < pad*2)
+            hex += "00";
+        return "0x" + hex;
+    },
+
+    eth: {
+        prototype: Object(), // jshint ignore:line
+        watch: function (params) {
+            return new Filter(params, ethWatch);
         }
+    },
 
-        data.args = data.args || [];
-        this.id++;
+    db: {
+        prototype: Object() // jshint ignore:line
+    },
 
-        if(this.provider !== undefined) {
-            this.provider.send(data);
-        } else {
-            console.warn("provider is not set");
-            this.queued.push(data);
+    shh: {
+        prototype: Object(), // jshint ignore:line
+        watch: function (params) {
+            return new Filter(params, shhWatch);
         }
-    };
+    },
 
-    ProviderManager.prototype.set = function(provider) {
-        if(this.provider !== undefined && this.provider.unload !== undefined) {
-            this.provider.unload();
+    on: function(event, id, cb) {
+        if(web3._events[event] === undefined) {
+            web3._events[event] = {};
         }
 
-        this.provider = provider;
-        this.ready = true;
-    };
+        web3._events[event][id] = cb;
+        return this;
+    },
 
-    ProviderManager.prototype.sendQueued = function() {
-        for(var i = 0; this.queued.length; i++) {
-            // Resend
-            this.send(this.queued[i]);
+    off: function(event, id) {
+        if(web3._events[event] !== undefined) {
+            delete web3._events[event][id];
         }
-    };
 
-    ProviderManager.prototype.installed = function() {
-        return this.provider !== undefined;
-    };
+        return this;
+    },
 
-    ProviderManager.prototype.startPolling = function (data, pollId) {
-        if (!this.provider || !this.provider.poll) {
+    trigger: function(event, id, data) {
+        var callbacks = web3._events[event];
+        if (!callbacks || !callbacks[id]) {
             return;
         }
-        this.polls.push({data: data, id: pollId});
-    };
-
-    ProviderManager.prototype.stopPolling = function (pollId) {
-        for (var i = this.polls.length; i--;) {
-            var poll = this.polls[i];
-            if (poll.id === pollId) {
-                this.polls.splice(i, 1);
-            }
+        var cb = callbacks[id];
+        cb(data);
+    }
+};
+
+var eth = web3.eth;
+setupMethods(eth, ethMethods());
+setupProperties(eth, ethProperties());
+setupMethods(web3.db, dbMethods());
+setupMethods(web3.shh, shhMethods());
+
+var ethWatch = {
+    changed: 'eth_changed'
+};
+setupMethods(ethWatch, ethWatchMethods());
+var shhWatch = {
+    changed: 'shh_changed'
+};
+setupMethods(shhWatch, shhWatchMethods());
+
+var ProviderManager = function() {
+    this.queued = [];
+    this.polls = [];
+    this.ready = false;
+    this.provider = undefined;
+    this.id = 1;
+
+    var self = this;
+    var poll = function () {
+        if (self.provider && self.provider.poll) {
+            self.polls.forEach(function (data) {
+                data.data._id = self.id;
+                self.id++;
+                self.provider.poll(data.data, data.id);
+            });
         }
+        setTimeout(poll, 12000);
     };
+    poll();
+};
 
-    web3.provider = new ProviderManager();
-
-    web3.setProvider = function(provider) {
-        provider.onmessage = messageHandler;
-        web3.provider.set(provider);
-        web3.provider.sendQueued();
-    };
+ProviderManager.prototype.send = function(data, cb) {
+    data._id = this.id;
+    if (cb) {
+        web3._callbacks[data._id] = cb;
+    }
 
-    var Filter = function(options, impl) {
-        this.impl = impl;
-        this.callbacks = [];
+    data.args = data.args || [];
+    this.id++;
 
-        var self = this;
-        this.promise = impl.newFilter(options);
-        this.promise.then(function (id) {
-            self.id = id;
-            web3.on(impl.changed, id, self.trigger.bind(self));
-            web3.provider.startPolling({call: impl.changed, args: [id]}, id);
-        });
-    };
+    if(this.provider !== undefined) {
+        this.provider.send(data);
+    } else {
+        console.warn("provider is not set");
+        this.queued.push(data);
+    }
+};
 
-    Filter.prototype.arrived = function(callback) {
-        this.changed(callback);
-    };
+ProviderManager.prototype.set = function(provider) {
+    if(this.provider !== undefined && this.provider.unload !== undefined) {
+        this.provider.unload();
+    }
 
-    Filter.prototype.changed = function(callback) {
-        var self = this;
-        this.promise.then(function(id) {
-            self.callbacks.push(callback);
-        });
-    };
+    this.provider = provider;
+    this.ready = true;
+};
 
-    Filter.prototype.trigger = function(messages) {
-        for(var i = 0; i < this.callbacks.length; i++) {
-            this.callbacks[i].call(this, messages);
-        }
-    };
-
-    Filter.prototype.uninstall = function() {
-        var self = this;
-        this.promise.then(function (id) {
-            self.impl.uninstallFilter(id);
-            web3.provider.stopPolling(id);
-            web3.off(impl.changed, id);
-        });
-    };
+ProviderManager.prototype.sendQueued = function() {
+    for(var i = 0; this.queued.length; i++) {
+        // Resend
+        this.send(this.queued[i]);
+    }
+};
 
-    Filter.prototype.messages = function() {
-        var self = this;
-        return this.promise.then(function (id) {
-            return self.impl.getMessages(id);
-        });
-    };
+ProviderManager.prototype.installed = function() {
+    return this.provider !== undefined;
+};
 
-    function messageHandler(data) {
-        if(data._event !== undefined) {
-            web3.trigger(data._event, data._id, data.data);
-            return;
+ProviderManager.prototype.startPolling = function (data, pollId) {
+    if (!this.provider || !this.provider.poll) {
+        return;
+    }
+    this.polls.push({data: data, id: pollId});
+};
+
+ProviderManager.prototype.stopPolling = function (pollId) {
+    for (var i = this.polls.length; i--;) {
+        var poll = this.polls[i];
+        if (poll.id === pollId) {
+            this.polls.splice(i, 1);
         }
+    }
+};
+
+web3.provider = new ProviderManager();
+
+web3.setProvider = function(provider) {
+    provider.onmessage = messageHandler;
+    web3.provider.set(provider);
+    web3.provider.sendQueued();
+};
+
+var Filter = function(options, impl) {
+    this.impl = impl;
+    this.callbacks = [];
+
+    var self = this;
+    this.promise = impl.newFilter(options);
+    this.promise.then(function (id) {
+        self.id = id;
+        web3.on(impl.changed, id, self.trigger.bind(self));
+        web3.provider.startPolling({call: impl.changed, args: [id]}, id);
+    });
+};
+
+Filter.prototype.arrived = function(callback) {
+    this.changed(callback);
+};
+
+Filter.prototype.changed = function(callback) {
+    var self = this;
+    this.promise.then(function(id) {
+        self.callbacks.push(callback);
+    });
+};
+
+Filter.prototype.trigger = function(messages) {
+    for(var i = 0; i < this.callbacks.length; i++) {
+        this.callbacks[i].call(this, messages);
+    }
+};
+
+Filter.prototype.uninstall = function() {
+    var self = this;
+    this.promise.then(function (id) {
+        self.impl.uninstallFilter(id);
+        web3.provider.stopPolling(id);
+        web3.off(impl.changed, id);
+    });
+};
+
+Filter.prototype.messages = function() {
+    var self = this;
+    return this.promise.then(function (id) {
+        return self.impl.getMessages(id);
+    });
+};
+
+function messageHandler(data) {
+    if(data._event !== undefined) {
+        web3.trigger(data._event, data._id, data.data);
+        return;
+    }
 
-        if(data._id) {
-            var cb = web3._callbacks[data._id];
-            if (cb) {
-                cb.call(this, data.error, data.data);
-                delete web3._callbacks[data._id];
-            }
+    if(data._id) {
+        var cb = web3._callbacks[data._id];
+        if (cb) {
+            cb.call(this, data.error, data.data);
+            delete web3._callbacks[data._id];
         }
     }
+}
 
-    module.exports = web3;
+module.exports = web3;
 
diff --git a/lib/qt.js b/lib/qt.js
index 7ec548c8c..f02239547 100644
--- a/lib/qt.js
+++ b/lib/qt.js
@@ -16,29 +16,30 @@
 */
 /** @file qt.js
  * @authors:
+ *   Jeffrey Wilcke <jeff@ethdev.com>
  *   Marek Kotewicz <marek@ethdev.com>
  * @date 2014
  */
 
-    var QtProvider = function() {
-        this.handlers = [];
+var QtProvider = function() {
+    this.handlers = [];
 
-        var self = this;
-        navigator.qt.onmessage = function (message) {
-            self.handlers.forEach(function (handler) {
-                handler.call(self, JSON.parse(message.data));
-            });
-        };
+    var self = this;
+    navigator.qt.onmessage = function (message) {
+        self.handlers.forEach(function (handler) {
+            handler.call(self, JSON.parse(message.data));
+        });
     };
+};
 
-    QtProvider.prototype.send = function(payload) {
-        navigator.qt.postMessage(JSON.stringify(payload));
-    };
+QtProvider.prototype.send = function(payload) {
+    navigator.qt.postMessage(JSON.stringify(payload));
+};
 
-    Object.defineProperty(QtProvider.prototype, "onmessage", {
-        set: function(handler) {
-            this.handlers.push(handler);
-        }
-    });
+Object.defineProperty(QtProvider.prototype, "onmessage", {
+    set: function(handler) {
+        this.handlers.push(handler);
+    }
+});
 
 module.exports = QtProvider;
diff --git a/lib/websocket.js b/lib/websocket.js
index 93d58aeba..0c7563062 100644
--- a/lib/websocket.js
+++ b/lib/websocket.js
@@ -16,59 +16,61 @@
 */
 /** @file websocket.js
  * @authors:
+ *   Jeffrey Wilcke <jeff@ethdev.com>
  *   Marek Kotewicz <marek@ethdev.com>
  *   Marian Oancea <marian@ethdev.com>
  * @date 2014
  */
 
-if(process.env.NODE_ENV !== "build") {
+if (process.env.NODE_ENV !== "build") {
     var WebSocket = require('ws'); // jshint ignore:line
 }
 
-    var WebSocketProvider = function(host) {
-        // onmessage handlers
-        this.handlers = [];
-        // queue will be filled with messages if send is invoked before the ws is ready
-        this.queued = [];
-        this.ready = false;
+var WebSocketProvider = function(host) {
+    // onmessage handlers
+    this.handlers = [];
+    // queue will be filled with messages if send is invoked before the ws is ready
+    this.queued = [];
+    this.ready = false;
 
-        this.ws = new WebSocket(host);
+    this.ws = new WebSocket(host);
 
-        var self = this;
-        this.ws.onmessage = function(event) {
-            for(var i = 0; i < self.handlers.length; i++) {
-                self.handlers[i].call(self, JSON.parse(event.data), event);
-            }
-        };
-
-        this.ws.onopen = function() {
-            self.ready = true;
-
-            for(var i = 0; i < self.queued.length; i++) {
-                // Resend
-                self.send(self.queued[i]);
-            }
-        };
+    var self = this;
+    this.ws.onmessage = function(event) {
+        for(var i = 0; i < self.handlers.length; i++) {
+            self.handlers[i].call(self, JSON.parse(event.data), event);
+        }
     };
-    WebSocketProvider.prototype.send = function(payload) {
-        if(this.ready) {
-            var data = JSON.stringify(payload);
 
-            this.ws.send(data);
-        } else {
-            this.queued.push(payload);
+    this.ws.onopen = function() {
+        self.ready = true;
+
+        for(var i = 0; i < self.queued.length; i++) {
+            // Resend
+            self.send(self.queued[i]);
         }
     };
+};
 
-    WebSocketProvider.prototype.onMessage = function(handler) {
-        this.handlers.push(handler);
-    };
+WebSocketProvider.prototype.send = function(payload) {
+    if(this.ready) {
+        var data = JSON.stringify(payload);
 
-    WebSocketProvider.prototype.unload = function() {
-        this.ws.close();
-    };
-    Object.defineProperty(WebSocketProvider.prototype, "onmessage", {
-        set: function(provider) { this.onMessage(provider); }
-    });
+        this.ws.send(data);
+    } else {
+        this.queued.push(payload);
+    }
+};
+
+WebSocketProvider.prototype.onMessage = function(handler) {
+    this.handlers.push(handler);
+};
+
+WebSocketProvider.prototype.unload = function() {
+    this.ws.close();
+};
+Object.defineProperty(WebSocketProvider.prototype, "onmessage", {
+    set: function(provider) { this.onMessage(provider); }
+});
 
 module.exports = WebSocketProvider;

From 838ca2fd9393e5b3cd4423934de78f1b8f9fd13f Mon Sep 17 00:00:00 2001
From: Marek Kotewicz <marek.kotewicz@gmail.com>
Date: Tue, 11 Nov 2014 15:47:58 +0100
Subject: [PATCH 2/2] autoprovider, buildQt not builds only necessery files,
 fixed gulpfile

---
 dist/ethereum.js     |  12 ++---
 dist/ethereum.js.map |   8 ++--
 dist/ethereum.min.js |   2 +-
 example/index.html   |   5 ++-
 gulpfile.js          |  31 +++++++++++--
 index.js             |   3 +-
 lib/autoprovider.js  | 103 +++++++++++++++++++++++++++++++++++++++++++
 lib/main.js          |   4 ++
 8 files changed, 153 insertions(+), 15 deletions(-)
 create mode 100644 lib/autoprovider.js

diff --git a/dist/ethereum.js b/dist/ethereum.js
index 3bb15bcf8..eed53675a 100644
--- a/dist/ethereum.js
+++ b/dist/ethereum.js
@@ -1,14 +1,16 @@
 require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
-function formatJsonRpcObject(object){return{jsonrpc:"2.0",method:object.call,params:object.args,id:object._id}}function formatJsonRpcMessage(message){var object=JSON.parse(message);return{_id:object.id,data:object.result,error:object.error}}var HttpRpcProvider=function(host){this.handlers=[],this.host=host};HttpRpcProvider.prototype.sendRequest=function(payload,cb){var data=formatJsonRpcObject(payload),request=new XMLHttpRequest;request.open("POST",this.host,!0),request.send(JSON.stringify(data)),request.onreadystatechange=function(){4===request.readyState&&cb&&cb(request)}},HttpRpcProvider.prototype.send=function(payload){var self=this;this.sendRequest(payload,function(request){self.handlers.forEach(function(handler){handler.call(self,formatJsonRpcMessage(request.responseText))})})},HttpRpcProvider.prototype.poll=function(payload,id){var self=this;this.sendRequest(payload,function(request){var parsed=JSON.parse(request.responseText);!parsed.error&&(parsed.result instanceof Array?0!==parsed.result.length:parsed.result)&&self.handlers.forEach(function(handler){handler.call(self,{_event:payload.call,_id:id,data:parsed.result})})})},Object.defineProperty(HttpRpcProvider.prototype,"onmessage",{set:function(handler){this.handlers.push(handler)}}),module.exports=HttpRpcProvider;
+var AutoProvider=function(userOptions){var options,self,closeWithSuccess,ws;if(!web3.haveProvider()){if(this.sendQueue=[],this.onmessageQueue=[],navigator.qt)return void(this.provider=new web3.providers.QtProvider);userOptions=userOptions||{},options={httprpc:userOptions.httprpc||"http://localhost:8080",websockets:userOptions.websockets||"ws://localhost:40404/eth"},self=this,closeWithSuccess=function(success){return ws.close(),success?void(self.provider=new web3.providers.WebSocketProvider(options.websockets)):(self.provider=new web3.providers.HttpRpcProvider(options.httprpc),self.poll=self.provider.poll.bind(self.provider),self.sendQueue.forEach(function(payload){self.provider(payload)}),void self.onmessageQueue.forEach(function(handler){self.provider.onmessage=handler}))},ws=new WebSocket(options.websockets),ws.onopen=function(){closeWithSuccess(!0)},ws.onerror=function(){closeWithSuccess(!1)}}};AutoProvider.prototype.send=function(payload){return this.provider?void this.provider.send(payload):void this.sendQueue.push(payload)},Object.defineProperty(AutoProvider.prototype,"onmessage",{set:function(handler){return this.provider?void(this.provider.onmessage=handler):void this.onmessageQueue.push(handler)}}),module.exports=AutoProvider;
 },{}],2:[function(require,module,exports){
-function flattenPromise(obj){return obj instanceof Promise?Promise.resolve(obj):obj instanceof Array?new Promise(function(resolve){var promises=obj.map(function(o){return flattenPromise(o)});return Promise.all(promises).then(function(res){for(var i=0;i<obj.length;i++)obj[i]=res[i];resolve(obj)})}):obj instanceof Object?new Promise(function(resolve){var keys=Object.keys(obj),promises=keys.map(function(key){return flattenPromise(obj[key])});return Promise.all(promises).then(function(res){for(var i=0;i<keys.length;i++)obj[keys[i]]=res[i];resolve(obj)})}):Promise.resolve(obj)}function messageHandler(data){if(void 0!==data._event)return void web3.trigger(data._event,data._id,data.data);if(data._id){var cb=web3._callbacks[data._id];cb&&(cb.call(this,data.error,data.data),delete web3._callbacks[data._id])}}var ethWatch,shhWatch,ProviderManager,Filter,ethMethods=function(){var blockCall=function(args){return"string"==typeof args[0]?"eth_blockByHash":"eth_blockByNumber"},transactionCall=function(args){return"string"==typeof args[0]?"eth_transactionByHash":"eth_transactionByNumber"},uncleCall=function(args){return"string"==typeof args[0]?"eth_uncleByHash":"eth_uncleByNumber"},methods=[{name:"balanceAt",call:"eth_balanceAt"},{name:"stateAt",call:"eth_stateAt"},{name:"countAt",call:"eth_countAt"},{name:"codeAt",call:"eth_codeAt"},{name:"transact",call:"eth_transact"},{name:"call",call:"eth_call"},{name:"block",call:blockCall},{name:"transaction",call:transactionCall},{name:"uncle",call:uncleCall},{name:"compile",call:"eth_compile"},{name:"lll",call:"eth_lll"}];return methods},ethProperties=function(){return[{name:"coinbase",getter:"eth_coinbase",setter:"eth_setCoinbase"},{name:"listening",getter:"eth_listening",setter:"eth_setListening"},{name:"mining",getter:"eth_mining",setter:"eth_setMining"},{name:"gasPrice",getter:"eth_gasPrice"},{name:"account",getter:"eth_account"},{name:"accounts",getter:"eth_accounts"},{name:"peerCount",getter:"eth_peerCount"},{name:"defaultBlock",getter:"eth_defaultBlock",setter:"eth_setDefaultBlock"},{name:"number",getter:"eth_number"}]},dbMethods=function(){return[{name:"put",call:"db_put"},{name:"get",call:"db_get"},{name:"putString",call:"db_putString"},{name:"getString",call:"db_getString"}]},shhMethods=function(){return[{name:"post",call:"shh_post"},{name:"newIdentity",call:"shh_newIdentity"},{name:"haveIdentity",call:"shh_haveIdentity"},{name:"newGroup",call:"shh_newGroup"},{name:"addToGroup",call:"shh_addToGroup"}]},ethWatchMethods=function(){var newFilter=function(args){return"string"==typeof args[0]?"eth_newFilterString":"eth_newFilter"};return[{name:"newFilter",call:newFilter},{name:"uninstallFilter",call:"eth_uninstallFilter"},{name:"getMessages",call:"eth_getMessages"}]},shhWatchMethods=function(){return[{name:"newFilter",call:"shh_newFilter"},{name:"uninstallFilter",call:"shh_uninstallFilter"},{name:"getMessage",call:"shh_getMessages"}]},setupMethods=function(obj,methods){methods.forEach(function(method){obj[method.name]=function(){return flattenPromise(Array.prototype.slice.call(arguments)).then(function(args){var call="function"==typeof method.call?method.call(args):method.call;return{call:call,args:args}}).then(function(request){return new Promise(function(resolve,reject){web3.provider.send(request,function(err,result){return err?void reject(err):void resolve(result)})})}).catch(function(err){console.error(err)})}})},setupProperties=function(obj,properties){properties.forEach(function(property){var proto={};proto.get=function(){return new Promise(function(resolve,reject){web3.provider.send({call:property.getter},function(err,result){return err?void reject(err):void resolve(result)})})},property.setter&&(proto.set=function(val){return flattenPromise([val]).then(function(args){return new Promise(function(resolve){web3.provider.send({call:property.setter,args:args},function(err,result){return err?void reject(err):void resolve(result)})})}).catch(function(err){console.error(err)})}),Object.defineProperty(obj,property.name,proto)})},web3={_callbacks:{},_events:{},providers:{},toHex:function(str){var i,n,hex="";for(i=0;i<str.length;i++)n=str.charCodeAt(i).toString(16),hex+=n.length<2?"0"+n:n;return hex},toAscii:function(hex){var code,str="",i=0,l=hex.length;for("0x"===hex.substring(0,2)&&(i=2);l>i&&(code=hex.charCodeAt(i),0!==code);i+=2)str+=String.fromCharCode(parseInt(hex.substr(i,2),16));return str},toDecimal:function(val){return parseInt(val,16)},fromAscii:function(str,pad){pad=void 0===pad?32:pad;for(var hex=this.toHex(str);hex.length<2*pad;)hex+="00";return"0x"+hex},eth:{prototype:Object(),watch:function(params){return new Filter(params,ethWatch)}},db:{prototype:Object()},shh:{prototype:Object(),watch:function(params){return new Filter(params,shhWatch)}},on:function(event,id,cb){return void 0===web3._events[event]&&(web3._events[event]={}),web3._events[event][id]=cb,this},off:function(event,id){return void 0!==web3._events[event]&&delete web3._events[event][id],this},trigger:function(event,id,data){var cb,callbacks=web3._events[event];callbacks&&callbacks[id]&&(cb=callbacks[id])(data)}},eth=web3.eth;setupMethods(eth,ethMethods()),setupProperties(eth,ethProperties()),setupMethods(web3.db,dbMethods()),setupMethods(web3.shh,shhMethods()),ethWatch={changed:"eth_changed"},setupMethods(ethWatch,ethWatchMethods()),shhWatch={changed:"shh_changed"},setupMethods(shhWatch,shhWatchMethods()),ProviderManager=function(){var self,poll;this.queued=[],this.polls=[],this.ready=!1,this.provider=void 0,this.id=1,self=this,(poll=function(){self.provider&&self.provider.poll&&self.polls.forEach(function(data){data.data._id=self.id,self.id++,self.provider.poll(data.data,data.id)}),setTimeout(poll,12e3)})()},ProviderManager.prototype.send=function(data,cb){data._id=this.id,cb&&(web3._callbacks[data._id]=cb),data.args=data.args||[],this.id++,void 0!==this.provider?this.provider.send(data):(console.warn("provider is not set"),this.queued.push(data))},ProviderManager.prototype.set=function(provider){void 0!==this.provider&&void 0!==this.provider.unload&&this.provider.unload(),this.provider=provider,this.ready=!0},ProviderManager.prototype.sendQueued=function(){for(var i=0;this.queued.length;i++)this.send(this.queued[i])},ProviderManager.prototype.installed=function(){return void 0!==this.provider},ProviderManager.prototype.startPolling=function(data,pollId){this.provider&&this.provider.poll&&this.polls.push({data:data,id:pollId})},ProviderManager.prototype.stopPolling=function(pollId){var i,poll;for(i=this.polls.length;i--;)poll=this.polls[i],poll.id===pollId&&this.polls.splice(i,1)},web3.provider=new ProviderManager,web3.setProvider=function(provider){provider.onmessage=messageHandler,web3.provider.set(provider),web3.provider.sendQueued()},Filter=function(options,impl){this.impl=impl,this.callbacks=[];var self=this;this.promise=impl.newFilter(options),this.promise.then(function(id){self.id=id,web3.on(impl.changed,id,self.trigger.bind(self)),web3.provider.startPolling({call:impl.changed,args:[id]},id)})},Filter.prototype.arrived=function(callback){this.changed(callback)},Filter.prototype.changed=function(callback){var self=this;this.promise.then(function(id){self.callbacks.push(callback)})},Filter.prototype.trigger=function(messages){for(var i=0;i<this.callbacks.length;i++)this.callbacks[i].call(this,messages)},Filter.prototype.uninstall=function(){var self=this;this.promise.then(function(id){self.impl.uninstallFilter(id),web3.provider.stopPolling(id),web3.off(impl.changed,id)})},Filter.prototype.messages=function(){var self=this;return this.promise.then(function(id){return self.impl.getMessages(id)})},module.exports=web3;
+function formatJsonRpcObject(object){return{jsonrpc:"2.0",method:object.call,params:object.args,id:object._id}}function formatJsonRpcMessage(message){var object=JSON.parse(message);return{_id:object.id,data:object.result,error:object.error}}var HttpRpcProvider=function(host){this.handlers=[],this.host=host};HttpRpcProvider.prototype.sendRequest=function(payload,cb){var data=formatJsonRpcObject(payload),request=new XMLHttpRequest;request.open("POST",this.host,!0),request.send(JSON.stringify(data)),request.onreadystatechange=function(){4===request.readyState&&cb&&cb(request)}},HttpRpcProvider.prototype.send=function(payload){var self=this;this.sendRequest(payload,function(request){self.handlers.forEach(function(handler){handler.call(self,formatJsonRpcMessage(request.responseText))})})},HttpRpcProvider.prototype.poll=function(payload,id){var self=this;this.sendRequest(payload,function(request){var parsed=JSON.parse(request.responseText);!parsed.error&&(parsed.result instanceof Array?0!==parsed.result.length:parsed.result)&&self.handlers.forEach(function(handler){handler.call(self,{_event:payload.call,_id:id,data:parsed.result})})})},Object.defineProperty(HttpRpcProvider.prototype,"onmessage",{set:function(handler){this.handlers.push(handler)}}),module.exports=HttpRpcProvider;
 },{}],3:[function(require,module,exports){
-var QtProvider=function(){this.handlers=[];var self=this;navigator.qt.onmessage=function(message){self.handlers.forEach(function(handler){handler.call(self,JSON.parse(message.data))})}};QtProvider.prototype.send=function(payload){navigator.qt.postMessage(JSON.stringify(payload))},Object.defineProperty(QtProvider.prototype,"onmessage",{set:function(handler){this.handlers.push(handler)}}),module.exports=QtProvider;
+function flattenPromise(obj){return obj instanceof Promise?Promise.resolve(obj):obj instanceof Array?new Promise(function(resolve){var promises=obj.map(function(o){return flattenPromise(o)});return Promise.all(promises).then(function(res){for(var i=0;i<obj.length;i++)obj[i]=res[i];resolve(obj)})}):obj instanceof Object?new Promise(function(resolve){var keys=Object.keys(obj),promises=keys.map(function(key){return flattenPromise(obj[key])});return Promise.all(promises).then(function(res){for(var i=0;i<keys.length;i++)obj[keys[i]]=res[i];resolve(obj)})}):Promise.resolve(obj)}function messageHandler(data){if(void 0!==data._event)return void web3.trigger(data._event,data._id,data.data);if(data._id){var cb=web3._callbacks[data._id];cb&&(cb.call(this,data.error,data.data),delete web3._callbacks[data._id])}}var ethWatch,shhWatch,ProviderManager,Filter,ethMethods=function(){var blockCall=function(args){return"string"==typeof args[0]?"eth_blockByHash":"eth_blockByNumber"},transactionCall=function(args){return"string"==typeof args[0]?"eth_transactionByHash":"eth_transactionByNumber"},uncleCall=function(args){return"string"==typeof args[0]?"eth_uncleByHash":"eth_uncleByNumber"},methods=[{name:"balanceAt",call:"eth_balanceAt"},{name:"stateAt",call:"eth_stateAt"},{name:"countAt",call:"eth_countAt"},{name:"codeAt",call:"eth_codeAt"},{name:"transact",call:"eth_transact"},{name:"call",call:"eth_call"},{name:"block",call:blockCall},{name:"transaction",call:transactionCall},{name:"uncle",call:uncleCall},{name:"compile",call:"eth_compile"},{name:"lll",call:"eth_lll"}];return methods},ethProperties=function(){return[{name:"coinbase",getter:"eth_coinbase",setter:"eth_setCoinbase"},{name:"listening",getter:"eth_listening",setter:"eth_setListening"},{name:"mining",getter:"eth_mining",setter:"eth_setMining"},{name:"gasPrice",getter:"eth_gasPrice"},{name:"account",getter:"eth_account"},{name:"accounts",getter:"eth_accounts"},{name:"peerCount",getter:"eth_peerCount"},{name:"defaultBlock",getter:"eth_defaultBlock",setter:"eth_setDefaultBlock"},{name:"number",getter:"eth_number"}]},dbMethods=function(){return[{name:"put",call:"db_put"},{name:"get",call:"db_get"},{name:"putString",call:"db_putString"},{name:"getString",call:"db_getString"}]},shhMethods=function(){return[{name:"post",call:"shh_post"},{name:"newIdentity",call:"shh_newIdentity"},{name:"haveIdentity",call:"shh_haveIdentity"},{name:"newGroup",call:"shh_newGroup"},{name:"addToGroup",call:"shh_addToGroup"}]},ethWatchMethods=function(){var newFilter=function(args){return"string"==typeof args[0]?"eth_newFilterString":"eth_newFilter"};return[{name:"newFilter",call:newFilter},{name:"uninstallFilter",call:"eth_uninstallFilter"},{name:"getMessages",call:"eth_getMessages"}]},shhWatchMethods=function(){return[{name:"newFilter",call:"shh_newFilter"},{name:"uninstallFilter",call:"shh_uninstallFilter"},{name:"getMessage",call:"shh_getMessages"}]},setupMethods=function(obj,methods){methods.forEach(function(method){obj[method.name]=function(){return flattenPromise(Array.prototype.slice.call(arguments)).then(function(args){var call="function"==typeof method.call?method.call(args):method.call;return{call:call,args:args}}).then(function(request){return new Promise(function(resolve,reject){web3.provider.send(request,function(err,result){return err?void reject(err):void resolve(result)})})}).catch(function(err){console.error(err)})}})},setupProperties=function(obj,properties){properties.forEach(function(property){var proto={};proto.get=function(){return new Promise(function(resolve,reject){web3.provider.send({call:property.getter},function(err,result){return err?void reject(err):void resolve(result)})})},property.setter&&(proto.set=function(val){return flattenPromise([val]).then(function(args){return new Promise(function(resolve){web3.provider.send({call:property.setter,args:args},function(err,result){return err?void reject(err):void resolve(result)})})}).catch(function(err){console.error(err)})}),Object.defineProperty(obj,property.name,proto)})},web3={_callbacks:{},_events:{},providers:{},toHex:function(str){var i,n,hex="";for(i=0;i<str.length;i++)n=str.charCodeAt(i).toString(16),hex+=n.length<2?"0"+n:n;return hex},toAscii:function(hex){var code,str="",i=0,l=hex.length;for("0x"===hex.substring(0,2)&&(i=2);l>i&&(code=hex.charCodeAt(i),0!==code);i+=2)str+=String.fromCharCode(parseInt(hex.substr(i,2),16));return str},toDecimal:function(val){return parseInt(val,16)},fromAscii:function(str,pad){pad=void 0===pad?32:pad;for(var hex=this.toHex(str);hex.length<2*pad;)hex+="00";return"0x"+hex},eth:{prototype:Object(),watch:function(params){return new Filter(params,ethWatch)}},db:{prototype:Object()},shh:{prototype:Object(),watch:function(params){return new Filter(params,shhWatch)}},on:function(event,id,cb){return void 0===web3._events[event]&&(web3._events[event]={}),web3._events[event][id]=cb,this},off:function(event,id){return void 0!==web3._events[event]&&delete web3._events[event][id],this},trigger:function(event,id,data){var cb,callbacks=web3._events[event];callbacks&&callbacks[id]&&(cb=callbacks[id])(data)}},eth=web3.eth;setupMethods(eth,ethMethods()),setupProperties(eth,ethProperties()),setupMethods(web3.db,dbMethods()),setupMethods(web3.shh,shhMethods()),ethWatch={changed:"eth_changed"},setupMethods(ethWatch,ethWatchMethods()),shhWatch={changed:"shh_changed"},setupMethods(shhWatch,shhWatchMethods()),ProviderManager=function(){var self,poll;this.queued=[],this.polls=[],this.ready=!1,this.provider=void 0,this.id=1,self=this,(poll=function(){self.provider&&self.provider.poll&&self.polls.forEach(function(data){data.data._id=self.id,self.id++,self.provider.poll(data.data,data.id)}),setTimeout(poll,12e3)})()},ProviderManager.prototype.send=function(data,cb){data._id=this.id,cb&&(web3._callbacks[data._id]=cb),data.args=data.args||[],this.id++,void 0!==this.provider?this.provider.send(data):(console.warn("provider is not set"),this.queued.push(data))},ProviderManager.prototype.set=function(provider){void 0!==this.provider&&void 0!==this.provider.unload&&this.provider.unload(),this.provider=provider,this.ready=!0},ProviderManager.prototype.sendQueued=function(){for(var i=0;this.queued.length;i++)this.send(this.queued[i])},ProviderManager.prototype.installed=function(){return void 0!==this.provider},ProviderManager.prototype.startPolling=function(data,pollId){this.provider&&this.provider.poll&&this.polls.push({data:data,id:pollId})},ProviderManager.prototype.stopPolling=function(pollId){var i,poll;for(i=this.polls.length;i--;)poll=this.polls[i],poll.id===pollId&&this.polls.splice(i,1)},web3.provider=new ProviderManager,web3.setProvider=function(provider){provider.onmessage=messageHandler,web3.provider.set(provider),web3.provider.sendQueued()},web3.haveProvider=function(){return!!web3.provider.provider},Filter=function(options,impl){this.impl=impl,this.callbacks=[];var self=this;this.promise=impl.newFilter(options),this.promise.then(function(id){self.id=id,web3.on(impl.changed,id,self.trigger.bind(self)),web3.provider.startPolling({call:impl.changed,args:[id]},id)})},Filter.prototype.arrived=function(callback){this.changed(callback)},Filter.prototype.changed=function(callback){var self=this;this.promise.then(function(id){self.callbacks.push(callback)})},Filter.prototype.trigger=function(messages){for(var i=0;i<this.callbacks.length;i++)this.callbacks[i].call(this,messages)},Filter.prototype.uninstall=function(){var self=this;this.promise.then(function(id){self.impl.uninstallFilter(id),web3.provider.stopPolling(id),web3.off(impl.changed,id)})},Filter.prototype.messages=function(){var self=this;return this.promise.then(function(id){return self.impl.getMessages(id)})},module.exports=web3;
 },{}],4:[function(require,module,exports){
+var QtProvider=function(){this.handlers=[];var self=this;navigator.qt.onmessage=function(message){self.handlers.forEach(function(handler){handler.call(self,JSON.parse(message.data))})}};QtProvider.prototype.send=function(payload){navigator.qt.postMessage(JSON.stringify(payload))},Object.defineProperty(QtProvider.prototype,"onmessage",{set:function(handler){this.handlers.push(handler)}}),module.exports=QtProvider;
+},{}],5:[function(require,module,exports){
 var WebSocketProvider=function(host){this.handlers=[],this.queued=[],this.ready=!1,this.ws=new WebSocket(host);var self=this;this.ws.onmessage=function(event){for(var i=0;i<self.handlers.length;i++)self.handlers[i].call(self,JSON.parse(event.data),event)},this.ws.onopen=function(){self.ready=!0;for(var i=0;i<self.queued.length;i++)self.send(self.queued[i])}};WebSocketProvider.prototype.send=function(payload){if(this.ready){var data=JSON.stringify(payload);this.ws.send(data)}else this.queued.push(payload)},WebSocketProvider.prototype.onMessage=function(handler){this.handlers.push(handler)},WebSocketProvider.prototype.unload=function(){this.ws.close()},Object.defineProperty(WebSocketProvider.prototype,"onmessage",{set:function(provider){this.onMessage(provider)}}),module.exports=WebSocketProvider;
 },{}],"web3":[function(require,module,exports){
-var web3=require("./lib/main");web3.providers.WebSocketProvider=require("./lib/websocket"),web3.providers.HttpRpcProvider=require("./lib/httprpc"),web3.providers.QtProvider=require("./lib/qt"),module.exports=web3;
-},{"./lib/httprpc":1,"./lib/main":2,"./lib/qt":3,"./lib/websocket":4}]},{},[])
+var web3=require("./lib/main");web3.providers.WebSocketProvider=require("./lib/websocket"),web3.providers.HttpRpcProvider=require("./lib/httprpc"),web3.providers.QtProvider=require("./lib/qt"),web3.providers.AutoProvider=require("./lib/autoprovider"),module.exports=web3;
+},{"./lib/autoprovider":1,"./lib/httprpc":2,"./lib/main":3,"./lib/qt":4,"./lib/websocket":5}]},{},[])
 
 
 //# sourceMappingURL=ethereum.js.map
\ No newline at end of file
diff --git a/dist/ethereum.js.map b/dist/ethereum.js.map
index 733b956f6..7fb672b8c 100644
--- a/dist/ethereum.js.map
+++ b/dist/ethereum.js.map
@@ -2,6 +2,7 @@
   "version": 3,
   "sources": [
     "node_modules/browserify/node_modules/browser-pack/_prelude.js",
+    "lib/autoprovider.js",
     "lib/httprpc.js",
     "lib/main.js",
     "lib/qt.js",
@@ -9,15 +10,16 @@
     "index.js"
   ],
   "names": [],
-  "mappings": "AAAA;ACAA;;ACAA;;ACAA;;ACAA;;ACAA",
+  "mappings": "AAAA;ACAA;;ACAA;;ACAA;;ACAA;;ACAA;;ACAA",
   "file": "generated.js",
   "sourceRoot": "",
   "sourcesContent": [
     "(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})",
+    "var AutoProvider=function(userOptions){var options,self,closeWithSuccess,ws;if(!web3.haveProvider()){if(this.sendQueue=[],this.onmessageQueue=[],navigator.qt)return void(this.provider=new web3.providers.QtProvider);userOptions=userOptions||{},options={httprpc:userOptions.httprpc||\"http://localhost:8080\",websockets:userOptions.websockets||\"ws://localhost:40404/eth\"},self=this,closeWithSuccess=function(success){return ws.close(),success?void(self.provider=new web3.providers.WebSocketProvider(options.websockets)):(self.provider=new web3.providers.HttpRpcProvider(options.httprpc),self.poll=self.provider.poll.bind(self.provider),self.sendQueue.forEach(function(payload){self.provider(payload)}),void self.onmessageQueue.forEach(function(handler){self.provider.onmessage=handler}))},ws=new WebSocket(options.websockets),ws.onopen=function(){closeWithSuccess(!0)},ws.onerror=function(){closeWithSuccess(!1)}}};AutoProvider.prototype.send=function(payload){return this.provider?void this.provider.send(payload):void this.sendQueue.push(payload)},Object.defineProperty(AutoProvider.prototype,\"onmessage\",{set:function(handler){return this.provider?void(this.provider.onmessage=handler):void this.onmessageQueue.push(handler)}}),module.exports=AutoProvider;",
     "function formatJsonRpcObject(object){return{jsonrpc:\"2.0\",method:object.call,params:object.args,id:object._id}}function formatJsonRpcMessage(message){var object=JSON.parse(message);return{_id:object.id,data:object.result,error:object.error}}var HttpRpcProvider=function(host){this.handlers=[],this.host=host};HttpRpcProvider.prototype.sendRequest=function(payload,cb){var data=formatJsonRpcObject(payload),request=new XMLHttpRequest;request.open(\"POST\",this.host,!0),request.send(JSON.stringify(data)),request.onreadystatechange=function(){4===request.readyState&&cb&&cb(request)}},HttpRpcProvider.prototype.send=function(payload){var self=this;this.sendRequest(payload,function(request){self.handlers.forEach(function(handler){handler.call(self,formatJsonRpcMessage(request.responseText))})})},HttpRpcProvider.prototype.poll=function(payload,id){var self=this;this.sendRequest(payload,function(request){var parsed=JSON.parse(request.responseText);!parsed.error&&(parsed.result instanceof Array?0!==parsed.result.length:parsed.result)&&self.handlers.forEach(function(handler){handler.call(self,{_event:payload.call,_id:id,data:parsed.result})})})},Object.defineProperty(HttpRpcProvider.prototype,\"onmessage\",{set:function(handler){this.handlers.push(handler)}}),module.exports=HttpRpcProvider;",
-    "function flattenPromise(obj){return obj instanceof Promise?Promise.resolve(obj):obj instanceof Array?new Promise(function(resolve){var promises=obj.map(function(o){return flattenPromise(o)});return Promise.all(promises).then(function(res){for(var i=0;i<obj.length;i++)obj[i]=res[i];resolve(obj)})}):obj instanceof Object?new Promise(function(resolve){var keys=Object.keys(obj),promises=keys.map(function(key){return flattenPromise(obj[key])});return Promise.all(promises).then(function(res){for(var i=0;i<keys.length;i++)obj[keys[i]]=res[i];resolve(obj)})}):Promise.resolve(obj)}function messageHandler(data){if(void 0!==data._event)return void web3.trigger(data._event,data._id,data.data);if(data._id){var cb=web3._callbacks[data._id];cb&&(cb.call(this,data.error,data.data),delete web3._callbacks[data._id])}}var ethWatch,shhWatch,ProviderManager,Filter,ethMethods=function(){var blockCall=function(args){return\"string\"==typeof args[0]?\"eth_blockByHash\":\"eth_blockByNumber\"},transactionCall=function(args){return\"string\"==typeof args[0]?\"eth_transactionByHash\":\"eth_transactionByNumber\"},uncleCall=function(args){return\"string\"==typeof args[0]?\"eth_uncleByHash\":\"eth_uncleByNumber\"},methods=[{name:\"balanceAt\",call:\"eth_balanceAt\"},{name:\"stateAt\",call:\"eth_stateAt\"},{name:\"countAt\",call:\"eth_countAt\"},{name:\"codeAt\",call:\"eth_codeAt\"},{name:\"transact\",call:\"eth_transact\"},{name:\"call\",call:\"eth_call\"},{name:\"block\",call:blockCall},{name:\"transaction\",call:transactionCall},{name:\"uncle\",call:uncleCall},{name:\"compile\",call:\"eth_compile\"},{name:\"lll\",call:\"eth_lll\"}];return methods},ethProperties=function(){return[{name:\"coinbase\",getter:\"eth_coinbase\",setter:\"eth_setCoinbase\"},{name:\"listening\",getter:\"eth_listening\",setter:\"eth_setListening\"},{name:\"mining\",getter:\"eth_mining\",setter:\"eth_setMining\"},{name:\"gasPrice\",getter:\"eth_gasPrice\"},{name:\"account\",getter:\"eth_account\"},{name:\"accounts\",getter:\"eth_accounts\"},{name:\"peerCount\",getter:\"eth_peerCount\"},{name:\"defaultBlock\",getter:\"eth_defaultBlock\",setter:\"eth_setDefaultBlock\"},{name:\"number\",getter:\"eth_number\"}]},dbMethods=function(){return[{name:\"put\",call:\"db_put\"},{name:\"get\",call:\"db_get\"},{name:\"putString\",call:\"db_putString\"},{name:\"getString\",call:\"db_getString\"}]},shhMethods=function(){return[{name:\"post\",call:\"shh_post\"},{name:\"newIdentity\",call:\"shh_newIdentity\"},{name:\"haveIdentity\",call:\"shh_haveIdentity\"},{name:\"newGroup\",call:\"shh_newGroup\"},{name:\"addToGroup\",call:\"shh_addToGroup\"}]},ethWatchMethods=function(){var newFilter=function(args){return\"string\"==typeof args[0]?\"eth_newFilterString\":\"eth_newFilter\"};return[{name:\"newFilter\",call:newFilter},{name:\"uninstallFilter\",call:\"eth_uninstallFilter\"},{name:\"getMessages\",call:\"eth_getMessages\"}]},shhWatchMethods=function(){return[{name:\"newFilter\",call:\"shh_newFilter\"},{name:\"uninstallFilter\",call:\"shh_uninstallFilter\"},{name:\"getMessage\",call:\"shh_getMessages\"}]},setupMethods=function(obj,methods){methods.forEach(function(method){obj[method.name]=function(){return flattenPromise(Array.prototype.slice.call(arguments)).then(function(args){var call=\"function\"==typeof method.call?method.call(args):method.call;return{call:call,args:args}}).then(function(request){return new Promise(function(resolve,reject){web3.provider.send(request,function(err,result){return err?void reject(err):void resolve(result)})})}).catch(function(err){console.error(err)})}})},setupProperties=function(obj,properties){properties.forEach(function(property){var proto={};proto.get=function(){return new Promise(function(resolve,reject){web3.provider.send({call:property.getter},function(err,result){return err?void reject(err):void resolve(result)})})},property.setter&&(proto.set=function(val){return flattenPromise([val]).then(function(args){return new Promise(function(resolve){web3.provider.send({call:property.setter,args:args},function(err,result){return err?void reject(err):void resolve(result)})})}).catch(function(err){console.error(err)})}),Object.defineProperty(obj,property.name,proto)})},web3={_callbacks:{},_events:{},providers:{},toHex:function(str){var i,n,hex=\"\";for(i=0;i<str.length;i++)n=str.charCodeAt(i).toString(16),hex+=n.length<2?\"0\"+n:n;return hex},toAscii:function(hex){var code,str=\"\",i=0,l=hex.length;for(\"0x\"===hex.substring(0,2)&&(i=2);l>i&&(code=hex.charCodeAt(i),0!==code);i+=2)str+=String.fromCharCode(parseInt(hex.substr(i,2),16));return str},toDecimal:function(val){return parseInt(val,16)},fromAscii:function(str,pad){pad=void 0===pad?32:pad;for(var hex=this.toHex(str);hex.length<2*pad;)hex+=\"00\";return\"0x\"+hex},eth:{prototype:Object(),watch:function(params){return new Filter(params,ethWatch)}},db:{prototype:Object()},shh:{prototype:Object(),watch:function(params){return new Filter(params,shhWatch)}},on:function(event,id,cb){return void 0===web3._events[event]&&(web3._events[event]={}),web3._events[event][id]=cb,this},off:function(event,id){return void 0!==web3._events[event]&&delete web3._events[event][id],this},trigger:function(event,id,data){var cb,callbacks=web3._events[event];callbacks&&callbacks[id]&&(cb=callbacks[id])(data)}},eth=web3.eth;setupMethods(eth,ethMethods()),setupProperties(eth,ethProperties()),setupMethods(web3.db,dbMethods()),setupMethods(web3.shh,shhMethods()),ethWatch={changed:\"eth_changed\"},setupMethods(ethWatch,ethWatchMethods()),shhWatch={changed:\"shh_changed\"},setupMethods(shhWatch,shhWatchMethods()),ProviderManager=function(){var self,poll;this.queued=[],this.polls=[],this.ready=!1,this.provider=void 0,this.id=1,self=this,(poll=function(){self.provider&&self.provider.poll&&self.polls.forEach(function(data){data.data._id=self.id,self.id++,self.provider.poll(data.data,data.id)}),setTimeout(poll,12e3)})()},ProviderManager.prototype.send=function(data,cb){data._id=this.id,cb&&(web3._callbacks[data._id]=cb),data.args=data.args||[],this.id++,void 0!==this.provider?this.provider.send(data):(console.warn(\"provider is not set\"),this.queued.push(data))},ProviderManager.prototype.set=function(provider){void 0!==this.provider&&void 0!==this.provider.unload&&this.provider.unload(),this.provider=provider,this.ready=!0},ProviderManager.prototype.sendQueued=function(){for(var i=0;this.queued.length;i++)this.send(this.queued[i])},ProviderManager.prototype.installed=function(){return void 0!==this.provider},ProviderManager.prototype.startPolling=function(data,pollId){this.provider&&this.provider.poll&&this.polls.push({data:data,id:pollId})},ProviderManager.prototype.stopPolling=function(pollId){var i,poll;for(i=this.polls.length;i--;)poll=this.polls[i],poll.id===pollId&&this.polls.splice(i,1)},web3.provider=new ProviderManager,web3.setProvider=function(provider){provider.onmessage=messageHandler,web3.provider.set(provider),web3.provider.sendQueued()},Filter=function(options,impl){this.impl=impl,this.callbacks=[];var self=this;this.promise=impl.newFilter(options),this.promise.then(function(id){self.id=id,web3.on(impl.changed,id,self.trigger.bind(self)),web3.provider.startPolling({call:impl.changed,args:[id]},id)})},Filter.prototype.arrived=function(callback){this.changed(callback)},Filter.prototype.changed=function(callback){var self=this;this.promise.then(function(id){self.callbacks.push(callback)})},Filter.prototype.trigger=function(messages){for(var i=0;i<this.callbacks.length;i++)this.callbacks[i].call(this,messages)},Filter.prototype.uninstall=function(){var self=this;this.promise.then(function(id){self.impl.uninstallFilter(id),web3.provider.stopPolling(id),web3.off(impl.changed,id)})},Filter.prototype.messages=function(){var self=this;return this.promise.then(function(id){return self.impl.getMessages(id)})},module.exports=web3;",
+    "function flattenPromise(obj){return obj instanceof Promise?Promise.resolve(obj):obj instanceof Array?new Promise(function(resolve){var promises=obj.map(function(o){return flattenPromise(o)});return Promise.all(promises).then(function(res){for(var i=0;i<obj.length;i++)obj[i]=res[i];resolve(obj)})}):obj instanceof Object?new Promise(function(resolve){var keys=Object.keys(obj),promises=keys.map(function(key){return flattenPromise(obj[key])});return Promise.all(promises).then(function(res){for(var i=0;i<keys.length;i++)obj[keys[i]]=res[i];resolve(obj)})}):Promise.resolve(obj)}function messageHandler(data){if(void 0!==data._event)return void web3.trigger(data._event,data._id,data.data);if(data._id){var cb=web3._callbacks[data._id];cb&&(cb.call(this,data.error,data.data),delete web3._callbacks[data._id])}}var ethWatch,shhWatch,ProviderManager,Filter,ethMethods=function(){var blockCall=function(args){return\"string\"==typeof args[0]?\"eth_blockByHash\":\"eth_blockByNumber\"},transactionCall=function(args){return\"string\"==typeof args[0]?\"eth_transactionByHash\":\"eth_transactionByNumber\"},uncleCall=function(args){return\"string\"==typeof args[0]?\"eth_uncleByHash\":\"eth_uncleByNumber\"},methods=[{name:\"balanceAt\",call:\"eth_balanceAt\"},{name:\"stateAt\",call:\"eth_stateAt\"},{name:\"countAt\",call:\"eth_countAt\"},{name:\"codeAt\",call:\"eth_codeAt\"},{name:\"transact\",call:\"eth_transact\"},{name:\"call\",call:\"eth_call\"},{name:\"block\",call:blockCall},{name:\"transaction\",call:transactionCall},{name:\"uncle\",call:uncleCall},{name:\"compile\",call:\"eth_compile\"},{name:\"lll\",call:\"eth_lll\"}];return methods},ethProperties=function(){return[{name:\"coinbase\",getter:\"eth_coinbase\",setter:\"eth_setCoinbase\"},{name:\"listening\",getter:\"eth_listening\",setter:\"eth_setListening\"},{name:\"mining\",getter:\"eth_mining\",setter:\"eth_setMining\"},{name:\"gasPrice\",getter:\"eth_gasPrice\"},{name:\"account\",getter:\"eth_account\"},{name:\"accounts\",getter:\"eth_accounts\"},{name:\"peerCount\",getter:\"eth_peerCount\"},{name:\"defaultBlock\",getter:\"eth_defaultBlock\",setter:\"eth_setDefaultBlock\"},{name:\"number\",getter:\"eth_number\"}]},dbMethods=function(){return[{name:\"put\",call:\"db_put\"},{name:\"get\",call:\"db_get\"},{name:\"putString\",call:\"db_putString\"},{name:\"getString\",call:\"db_getString\"}]},shhMethods=function(){return[{name:\"post\",call:\"shh_post\"},{name:\"newIdentity\",call:\"shh_newIdentity\"},{name:\"haveIdentity\",call:\"shh_haveIdentity\"},{name:\"newGroup\",call:\"shh_newGroup\"},{name:\"addToGroup\",call:\"shh_addToGroup\"}]},ethWatchMethods=function(){var newFilter=function(args){return\"string\"==typeof args[0]?\"eth_newFilterString\":\"eth_newFilter\"};return[{name:\"newFilter\",call:newFilter},{name:\"uninstallFilter\",call:\"eth_uninstallFilter\"},{name:\"getMessages\",call:\"eth_getMessages\"}]},shhWatchMethods=function(){return[{name:\"newFilter\",call:\"shh_newFilter\"},{name:\"uninstallFilter\",call:\"shh_uninstallFilter\"},{name:\"getMessage\",call:\"shh_getMessages\"}]},setupMethods=function(obj,methods){methods.forEach(function(method){obj[method.name]=function(){return flattenPromise(Array.prototype.slice.call(arguments)).then(function(args){var call=\"function\"==typeof method.call?method.call(args):method.call;return{call:call,args:args}}).then(function(request){return new Promise(function(resolve,reject){web3.provider.send(request,function(err,result){return err?void reject(err):void resolve(result)})})}).catch(function(err){console.error(err)})}})},setupProperties=function(obj,properties){properties.forEach(function(property){var proto={};proto.get=function(){return new Promise(function(resolve,reject){web3.provider.send({call:property.getter},function(err,result){return err?void reject(err):void resolve(result)})})},property.setter&&(proto.set=function(val){return flattenPromise([val]).then(function(args){return new Promise(function(resolve){web3.provider.send({call:property.setter,args:args},function(err,result){return err?void reject(err):void resolve(result)})})}).catch(function(err){console.error(err)})}),Object.defineProperty(obj,property.name,proto)})},web3={_callbacks:{},_events:{},providers:{},toHex:function(str){var i,n,hex=\"\";for(i=0;i<str.length;i++)n=str.charCodeAt(i).toString(16),hex+=n.length<2?\"0\"+n:n;return hex},toAscii:function(hex){var code,str=\"\",i=0,l=hex.length;for(\"0x\"===hex.substring(0,2)&&(i=2);l>i&&(code=hex.charCodeAt(i),0!==code);i+=2)str+=String.fromCharCode(parseInt(hex.substr(i,2),16));return str},toDecimal:function(val){return parseInt(val,16)},fromAscii:function(str,pad){pad=void 0===pad?32:pad;for(var hex=this.toHex(str);hex.length<2*pad;)hex+=\"00\";return\"0x\"+hex},eth:{prototype:Object(),watch:function(params){return new Filter(params,ethWatch)}},db:{prototype:Object()},shh:{prototype:Object(),watch:function(params){return new Filter(params,shhWatch)}},on:function(event,id,cb){return void 0===web3._events[event]&&(web3._events[event]={}),web3._events[event][id]=cb,this},off:function(event,id){return void 0!==web3._events[event]&&delete web3._events[event][id],this},trigger:function(event,id,data){var cb,callbacks=web3._events[event];callbacks&&callbacks[id]&&(cb=callbacks[id])(data)}},eth=web3.eth;setupMethods(eth,ethMethods()),setupProperties(eth,ethProperties()),setupMethods(web3.db,dbMethods()),setupMethods(web3.shh,shhMethods()),ethWatch={changed:\"eth_changed\"},setupMethods(ethWatch,ethWatchMethods()),shhWatch={changed:\"shh_changed\"},setupMethods(shhWatch,shhWatchMethods()),ProviderManager=function(){var self,poll;this.queued=[],this.polls=[],this.ready=!1,this.provider=void 0,this.id=1,self=this,(poll=function(){self.provider&&self.provider.poll&&self.polls.forEach(function(data){data.data._id=self.id,self.id++,self.provider.poll(data.data,data.id)}),setTimeout(poll,12e3)})()},ProviderManager.prototype.send=function(data,cb){data._id=this.id,cb&&(web3._callbacks[data._id]=cb),data.args=data.args||[],this.id++,void 0!==this.provider?this.provider.send(data):(console.warn(\"provider is not set\"),this.queued.push(data))},ProviderManager.prototype.set=function(provider){void 0!==this.provider&&void 0!==this.provider.unload&&this.provider.unload(),this.provider=provider,this.ready=!0},ProviderManager.prototype.sendQueued=function(){for(var i=0;this.queued.length;i++)this.send(this.queued[i])},ProviderManager.prototype.installed=function(){return void 0!==this.provider},ProviderManager.prototype.startPolling=function(data,pollId){this.provider&&this.provider.poll&&this.polls.push({data:data,id:pollId})},ProviderManager.prototype.stopPolling=function(pollId){var i,poll;for(i=this.polls.length;i--;)poll=this.polls[i],poll.id===pollId&&this.polls.splice(i,1)},web3.provider=new ProviderManager,web3.setProvider=function(provider){provider.onmessage=messageHandler,web3.provider.set(provider),web3.provider.sendQueued()},web3.haveProvider=function(){return!!web3.provider.provider},Filter=function(options,impl){this.impl=impl,this.callbacks=[];var self=this;this.promise=impl.newFilter(options),this.promise.then(function(id){self.id=id,web3.on(impl.changed,id,self.trigger.bind(self)),web3.provider.startPolling({call:impl.changed,args:[id]},id)})},Filter.prototype.arrived=function(callback){this.changed(callback)},Filter.prototype.changed=function(callback){var self=this;this.promise.then(function(id){self.callbacks.push(callback)})},Filter.prototype.trigger=function(messages){for(var i=0;i<this.callbacks.length;i++)this.callbacks[i].call(this,messages)},Filter.prototype.uninstall=function(){var self=this;this.promise.then(function(id){self.impl.uninstallFilter(id),web3.provider.stopPolling(id),web3.off(impl.changed,id)})},Filter.prototype.messages=function(){var self=this;return this.promise.then(function(id){return self.impl.getMessages(id)})},module.exports=web3;",
     "var QtProvider=function(){this.handlers=[];var self=this;navigator.qt.onmessage=function(message){self.handlers.forEach(function(handler){handler.call(self,JSON.parse(message.data))})}};QtProvider.prototype.send=function(payload){navigator.qt.postMessage(JSON.stringify(payload))},Object.defineProperty(QtProvider.prototype,\"onmessage\",{set:function(handler){this.handlers.push(handler)}}),module.exports=QtProvider;",
     "var WebSocketProvider=function(host){this.handlers=[],this.queued=[],this.ready=!1,this.ws=new WebSocket(host);var self=this;this.ws.onmessage=function(event){for(var i=0;i<self.handlers.length;i++)self.handlers[i].call(self,JSON.parse(event.data),event)},this.ws.onopen=function(){self.ready=!0;for(var i=0;i<self.queued.length;i++)self.send(self.queued[i])}};WebSocketProvider.prototype.send=function(payload){if(this.ready){var data=JSON.stringify(payload);this.ws.send(data)}else this.queued.push(payload)},WebSocketProvider.prototype.onMessage=function(handler){this.handlers.push(handler)},WebSocketProvider.prototype.unload=function(){this.ws.close()},Object.defineProperty(WebSocketProvider.prototype,\"onmessage\",{set:function(provider){this.onMessage(provider)}}),module.exports=WebSocketProvider;",
-    "var web3=require(\"./lib/main\");web3.providers.WebSocketProvider=require(\"./lib/websocket\"),web3.providers.HttpRpcProvider=require(\"./lib/httprpc\"),web3.providers.QtProvider=require(\"./lib/qt\"),module.exports=web3;"
+    "var web3=require(\"./lib/main\");web3.providers.WebSocketProvider=require(\"./lib/websocket\"),web3.providers.HttpRpcProvider=require(\"./lib/httprpc\"),web3.providers.QtProvider=require(\"./lib/qt\"),web3.providers.AutoProvider=require(\"./lib/autoprovider\"),module.exports=web3;"
   ]
 }
\ No newline at end of file
diff --git a/dist/ethereum.min.js b/dist/ethereum.min.js
index 390b60e28..f11406dfc 100644
--- a/dist/ethereum.min.js
+++ b/dist/ethereum.min.js
@@ -1 +1 @@
-require=function e(t,n,r){function i(s,a){if(!n[s]){if(!t[s]){var c="function"==typeof require&&require;if(!a&&c)return c(s,!0);if(o)return o(s,!0);var l=new Error("Cannot find module '"+s+"'");throw l.code="MODULE_NOT_FOUND",l}var u=n[s]={exports:{}};t[s][0].call(u.exports,function(e){var n=t[s][1][e];return i(n?n:e)},u,u.exports,e,t,n,r)}return n[s].exports}for(var o="function"==typeof require&&require,s=0;s<r.length;s++)i(r[s]);return i}({1:[function(e,t){function n(e){return{jsonrpc:"2.0",method:e.call,params:e.args,id:e._id}}function r(e){var t=JSON.parse(e);return{_id:t.id,data:t.result,error:t.error}}var i=function(e){this.handlers=[],this.host=e};i.prototype.sendRequest=function(e,t){var r=n(e),i=new XMLHttpRequest;i.open("POST",this.host,!0),i.send(JSON.stringify(r)),i.onreadystatechange=function(){4===i.readyState&&t&&t(i)}},i.prototype.send=function(e){var t=this;this.sendRequest(e,function(e){t.handlers.forEach(function(n){n.call(t,r(e.responseText))})})},i.prototype.poll=function(e,t){var n=this;this.sendRequest(e,function(r){var i=JSON.parse(r.responseText);!i.error&&(i.result instanceof Array?0!==i.result.length:i.result)&&n.handlers.forEach(function(r){r.call(n,{_event:e.call,_id:t,data:i.result})})})},Object.defineProperty(i.prototype,"onmessage",{set:function(e){this.handlers.push(e)}}),t.exports=i},{}],2:[function(e,t){function n(e){return e instanceof Promise?Promise.resolve(e):e instanceof Array?new Promise(function(t){var r=e.map(function(e){return n(e)});return Promise.all(r).then(function(n){for(var r=0;r<e.length;r++)e[r]=n[r];t(e)})}):e instanceof Object?new Promise(function(t){var r=Object.keys(e),i=r.map(function(t){return n(e[t])});return Promise.all(i).then(function(n){for(var i=0;i<r.length;i++)e[r[i]]=n[i];t(e)})}):Promise.resolve(e)}function r(e){if(void 0!==e._event)return void g.trigger(e._event,e._id,e.data);if(e._id){var t=g._callbacks[e._id];t&&(t.call(this,e.error,e.data),delete g._callbacks[e._id])}}var i,o,s,a,c=function(){var e=function(e){return"string"==typeof e[0]?"eth_blockByHash":"eth_blockByNumber"},t=function(e){return"string"==typeof e[0]?"eth_transactionByHash":"eth_transactionByNumber"},n=function(e){return"string"==typeof e[0]?"eth_uncleByHash":"eth_uncleByNumber"},r=[{name:"balanceAt",call:"eth_balanceAt"},{name:"stateAt",call:"eth_stateAt"},{name:"countAt",call:"eth_countAt"},{name:"codeAt",call:"eth_codeAt"},{name:"transact",call:"eth_transact"},{name:"call",call:"eth_call"},{name:"block",call:e},{name:"transaction",call:t},{name:"uncle",call:n},{name:"compile",call:"eth_compile"},{name:"lll",call:"eth_lll"}];return r},l=function(){return[{name:"coinbase",getter:"eth_coinbase",setter:"eth_setCoinbase"},{name:"listening",getter:"eth_listening",setter:"eth_setListening"},{name:"mining",getter:"eth_mining",setter:"eth_setMining"},{name:"gasPrice",getter:"eth_gasPrice"},{name:"account",getter:"eth_account"},{name:"accounts",getter:"eth_accounts"},{name:"peerCount",getter:"eth_peerCount"},{name:"defaultBlock",getter:"eth_defaultBlock",setter:"eth_setDefaultBlock"},{name:"number",getter:"eth_number"}]},u=function(){return[{name:"put",call:"db_put"},{name:"get",call:"db_get"},{name:"putString",call:"db_putString"},{name:"getString",call:"db_getString"}]},h=function(){return[{name:"post",call:"shh_post"},{name:"newIdentity",call:"shh_newIdentity"},{name:"haveIdentity",call:"shh_haveIdentity"},{name:"newGroup",call:"shh_newGroup"},{name:"addToGroup",call:"shh_addToGroup"}]},d=function(){var e=function(e){return"string"==typeof e[0]?"eth_newFilterString":"eth_newFilter"};return[{name:"newFilter",call:e},{name:"uninstallFilter",call:"eth_uninstallFilter"},{name:"getMessages",call:"eth_getMessages"}]},p=function(){return[{name:"newFilter",call:"shh_newFilter"},{name:"uninstallFilter",call:"shh_uninstallFilter"},{name:"getMessage",call:"shh_getMessages"}]},f=function(e,t){t.forEach(function(t){e[t.name]=function(){return n(Array.prototype.slice.call(arguments)).then(function(e){var n="function"==typeof t.call?t.call(e):t.call;return{call:n,args:e}}).then(function(e){return new Promise(function(t,n){g.provider.send(e,function(e,r){return e?void n(e):void t(r)})})}).catch(function(e){console.error(e)})}})},v=function(e,t){t.forEach(function(t){var r={};r.get=function(){return new Promise(function(e,n){g.provider.send({call:t.getter},function(t,r){return t?void n(t):void e(r)})})},t.setter&&(r.set=function(e){return n([e]).then(function(e){return new Promise(function(n){g.provider.send({call:t.setter,args:e},function(e,t){return e?void reject(e):void n(t)})})}).catch(function(e){console.error(e)})}),Object.defineProperty(e,t.name,r)})},g={_callbacks:{},_events:{},providers:{},toHex:function(e){var t,n,r="";for(t=0;t<e.length;t++)n=e.charCodeAt(t).toString(16),r+=n.length<2?"0"+n:n;return r},toAscii:function(e){var t,n="",r=0,i=e.length;for("0x"===e.substring(0,2)&&(r=2);i>r&&(t=e.charCodeAt(r),0!==t);r+=2)n+=String.fromCharCode(parseInt(e.substr(r,2),16));return n},toDecimal:function(e){return parseInt(e,16)},fromAscii:function(e,t){t=void 0===t?32:t;for(var n=this.toHex(e);n.length<2*t;)n+="00";return"0x"+n},eth:{prototype:Object(),watch:function(e){return new a(e,i)}},db:{prototype:Object()},shh:{prototype:Object(),watch:function(e){return new a(e,o)}},on:function(e,t,n){return void 0===g._events[e]&&(g._events[e]={}),g._events[e][t]=n,this},off:function(e,t){return void 0!==g._events[e]&&delete g._events[e][t],this},trigger:function(e,t,n){var r,i=g._events[e];i&&i[t]&&(r=i[t])(n)}},m=g.eth;f(m,c()),v(m,l()),f(g.db,u()),f(g.shh,h()),i={changed:"eth_changed"},f(i,d()),o={changed:"shh_changed"},f(o,p()),s=function(){var e,t;this.queued=[],this.polls=[],this.ready=!1,this.provider=void 0,this.id=1,e=this,(t=function(){e.provider&&e.provider.poll&&e.polls.forEach(function(t){t.data._id=e.id,e.id++,e.provider.poll(t.data,t.id)}),setTimeout(t,12e3)})()},s.prototype.send=function(e,t){e._id=this.id,t&&(g._callbacks[e._id]=t),e.args=e.args||[],this.id++,void 0!==this.provider?this.provider.send(e):(console.warn("provider is not set"),this.queued.push(e))},s.prototype.set=function(e){void 0!==this.provider&&void 0!==this.provider.unload&&this.provider.unload(),this.provider=e,this.ready=!0},s.prototype.sendQueued=function(){for(var e=0;this.queued.length;e++)this.send(this.queued[e])},s.prototype.installed=function(){return void 0!==this.provider},s.prototype.startPolling=function(e,t){this.provider&&this.provider.poll&&this.polls.push({data:e,id:t})},s.prototype.stopPolling=function(e){var t,n;for(t=this.polls.length;t--;)n=this.polls[t],n.id===e&&this.polls.splice(t,1)},g.provider=new s,g.setProvider=function(e){e.onmessage=r,g.provider.set(e),g.provider.sendQueued()},a=function(e,t){this.impl=t,this.callbacks=[];var n=this;this.promise=t.newFilter(e),this.promise.then(function(e){n.id=e,g.on(t.changed,e,n.trigger.bind(n)),g.provider.startPolling({call:t.changed,args:[e]},e)})},a.prototype.arrived=function(e){this.changed(e)},a.prototype.changed=function(e){var t=this;this.promise.then(function(){t.callbacks.push(e)})},a.prototype.trigger=function(e){for(var t=0;t<this.callbacks.length;t++)this.callbacks[t].call(this,e)},a.prototype.uninstall=function(){var e=this;this.promise.then(function(t){e.impl.uninstallFilter(t),g.provider.stopPolling(t),g.off(impl.changed,t)})},a.prototype.messages=function(){var e=this;return this.promise.then(function(t){return e.impl.getMessages(t)})},t.exports=g},{}],3:[function(e,t){var n=function(){this.handlers=[];var e=this;navigator.qt.onmessage=function(t){e.handlers.forEach(function(n){n.call(e,JSON.parse(t.data))})}};n.prototype.send=function(e){navigator.qt.postMessage(JSON.stringify(e))},Object.defineProperty(n.prototype,"onmessage",{set:function(e){this.handlers.push(e)}}),t.exports=n},{}],4:[function(e,t){var n=function(e){this.handlers=[],this.queued=[],this.ready=!1,this.ws=new WebSocket(e);var t=this;this.ws.onmessage=function(e){for(var n=0;n<t.handlers.length;n++)t.handlers[n].call(t,JSON.parse(e.data),e)},this.ws.onopen=function(){t.ready=!0;for(var e=0;e<t.queued.length;e++)t.send(t.queued[e])}};n.prototype.send=function(e){if(this.ready){var t=JSON.stringify(e);this.ws.send(t)}else this.queued.push(e)},n.prototype.onMessage=function(e){this.handlers.push(e)},n.prototype.unload=function(){this.ws.close()},Object.defineProperty(n.prototype,"onmessage",{set:function(e){this.onMessage(e)}}),t.exports=n},{}],web3:[function(e,t){var n=e("./lib/main");n.providers.WebSocketProvider=e("./lib/websocket"),n.providers.HttpRpcProvider=e("./lib/httprpc"),n.providers.QtProvider=e("./lib/qt"),t.exports=n},{"./lib/httprpc":1,"./lib/main":2,"./lib/qt":3,"./lib/websocket":4}]},{},[]);
\ No newline at end of file
+require=function e(t,n,r){function o(s,a){if(!n[s]){if(!t[s]){var c="function"==typeof require&&require;if(!a&&c)return c(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var l=n[s]={exports:{}};t[s][0].call(l.exports,function(e){var n=t[s][1][e];return o(n?n:e)},l,l.exports,e,t,n,r)}return n[s].exports}for(var i="function"==typeof require&&require,s=0;s<r.length;s++)o(r[s]);return o}({1:[function(e,t){var n=function(e){var t,n,r,o;if(!web3.haveProvider()){if(this.sendQueue=[],this.onmessageQueue=[],navigator.qt)return void(this.provider=new web3.providers.QtProvider);e=e||{},t={httprpc:e.httprpc||"http://localhost:8080",websockets:e.websockets||"ws://localhost:40404/eth"},n=this,r=function(e){return o.close(),e?void(n.provider=new web3.providers.WebSocketProvider(t.websockets)):(n.provider=new web3.providers.HttpRpcProvider(t.httprpc),n.poll=n.provider.poll.bind(n.provider),n.sendQueue.forEach(function(e){n.provider(e)}),void n.onmessageQueue.forEach(function(e){n.provider.onmessage=e}))},o=new WebSocket(t.websockets),o.onopen=function(){r(!0)},o.onerror=function(){r(!1)}}};n.prototype.send=function(e){return this.provider?void this.provider.send(e):void this.sendQueue.push(e)},Object.defineProperty(n.prototype,"onmessage",{set:function(e){return this.provider?void(this.provider.onmessage=e):void this.onmessageQueue.push(e)}}),t.exports=n},{}],2:[function(e,t){function n(e){return{jsonrpc:"2.0",method:e.call,params:e.args,id:e._id}}function r(e){var t=JSON.parse(e);return{_id:t.id,data:t.result,error:t.error}}var o=function(e){this.handlers=[],this.host=e};o.prototype.sendRequest=function(e,t){var r=n(e),o=new XMLHttpRequest;o.open("POST",this.host,!0),o.send(JSON.stringify(r)),o.onreadystatechange=function(){4===o.readyState&&t&&t(o)}},o.prototype.send=function(e){var t=this;this.sendRequest(e,function(e){t.handlers.forEach(function(n){n.call(t,r(e.responseText))})})},o.prototype.poll=function(e,t){var n=this;this.sendRequest(e,function(r){var o=JSON.parse(r.responseText);!o.error&&(o.result instanceof Array?0!==o.result.length:o.result)&&n.handlers.forEach(function(r){r.call(n,{_event:e.call,_id:t,data:o.result})})})},Object.defineProperty(o.prototype,"onmessage",{set:function(e){this.handlers.push(e)}}),t.exports=o},{}],3:[function(e,t){function n(e){return e instanceof Promise?Promise.resolve(e):e instanceof Array?new Promise(function(t){var r=e.map(function(e){return n(e)});return Promise.all(r).then(function(n){for(var r=0;r<e.length;r++)e[r]=n[r];t(e)})}):e instanceof Object?new Promise(function(t){var r=Object.keys(e),o=r.map(function(t){return n(e[t])});return Promise.all(o).then(function(n){for(var o=0;o<r.length;o++)e[r[o]]=n[o];t(e)})}):Promise.resolve(e)}function r(e){if(void 0!==e._event)return void g.trigger(e._event,e._id,e.data);if(e._id){var t=g._callbacks[e._id];t&&(t.call(this,e.error,e.data),delete g._callbacks[e._id])}}var o,i,s,a,c=function(){var e=function(e){return"string"==typeof e[0]?"eth_blockByHash":"eth_blockByNumber"},t=function(e){return"string"==typeof e[0]?"eth_transactionByHash":"eth_transactionByNumber"},n=function(e){return"string"==typeof e[0]?"eth_uncleByHash":"eth_uncleByNumber"},r=[{name:"balanceAt",call:"eth_balanceAt"},{name:"stateAt",call:"eth_stateAt"},{name:"countAt",call:"eth_countAt"},{name:"codeAt",call:"eth_codeAt"},{name:"transact",call:"eth_transact"},{name:"call",call:"eth_call"},{name:"block",call:e},{name:"transaction",call:t},{name:"uncle",call:n},{name:"compile",call:"eth_compile"},{name:"lll",call:"eth_lll"}];return r},u=function(){return[{name:"coinbase",getter:"eth_coinbase",setter:"eth_setCoinbase"},{name:"listening",getter:"eth_listening",setter:"eth_setListening"},{name:"mining",getter:"eth_mining",setter:"eth_setMining"},{name:"gasPrice",getter:"eth_gasPrice"},{name:"account",getter:"eth_account"},{name:"accounts",getter:"eth_accounts"},{name:"peerCount",getter:"eth_peerCount"},{name:"defaultBlock",getter:"eth_defaultBlock",setter:"eth_setDefaultBlock"},{name:"number",getter:"eth_number"}]},l=function(){return[{name:"put",call:"db_put"},{name:"get",call:"db_get"},{name:"putString",call:"db_putString"},{name:"getString",call:"db_getString"}]},h=function(){return[{name:"post",call:"shh_post"},{name:"newIdentity",call:"shh_newIdentity"},{name:"haveIdentity",call:"shh_haveIdentity"},{name:"newGroup",call:"shh_newGroup"},{name:"addToGroup",call:"shh_addToGroup"}]},d=function(){var e=function(e){return"string"==typeof e[0]?"eth_newFilterString":"eth_newFilter"};return[{name:"newFilter",call:e},{name:"uninstallFilter",call:"eth_uninstallFilter"},{name:"getMessages",call:"eth_getMessages"}]},p=function(){return[{name:"newFilter",call:"shh_newFilter"},{name:"uninstallFilter",call:"shh_uninstallFilter"},{name:"getMessage",call:"shh_getMessages"}]},f=function(e,t){t.forEach(function(t){e[t.name]=function(){return n(Array.prototype.slice.call(arguments)).then(function(e){var n="function"==typeof t.call?t.call(e):t.call;return{call:n,args:e}}).then(function(e){return new Promise(function(t,n){g.provider.send(e,function(e,r){return e?void n(e):void t(r)})})}).catch(function(e){console.error(e)})}})},v=function(e,t){t.forEach(function(t){var r={};r.get=function(){return new Promise(function(e,n){g.provider.send({call:t.getter},function(t,r){return t?void n(t):void e(r)})})},t.setter&&(r.set=function(e){return n([e]).then(function(e){return new Promise(function(n){g.provider.send({call:t.setter,args:e},function(e,t){return e?void reject(e):void n(t)})})}).catch(function(e){console.error(e)})}),Object.defineProperty(e,t.name,r)})},g={_callbacks:{},_events:{},providers:{},toHex:function(e){var t,n,r="";for(t=0;t<e.length;t++)n=e.charCodeAt(t).toString(16),r+=n.length<2?"0"+n:n;return r},toAscii:function(e){var t,n="",r=0,o=e.length;for("0x"===e.substring(0,2)&&(r=2);o>r&&(t=e.charCodeAt(r),0!==t);r+=2)n+=String.fromCharCode(parseInt(e.substr(r,2),16));return n},toDecimal:function(e){return parseInt(e,16)},fromAscii:function(e,t){t=void 0===t?32:t;for(var n=this.toHex(e);n.length<2*t;)n+="00";return"0x"+n},eth:{prototype:Object(),watch:function(e){return new a(e,o)}},db:{prototype:Object()},shh:{prototype:Object(),watch:function(e){return new a(e,i)}},on:function(e,t,n){return void 0===g._events[e]&&(g._events[e]={}),g._events[e][t]=n,this},off:function(e,t){return void 0!==g._events[e]&&delete g._events[e][t],this},trigger:function(e,t,n){var r,o=g._events[e];o&&o[t]&&(r=o[t])(n)}},m=g.eth;f(m,c()),v(m,u()),f(g.db,l()),f(g.shh,h()),o={changed:"eth_changed"},f(o,d()),i={changed:"shh_changed"},f(i,p()),s=function(){var e,t;this.queued=[],this.polls=[],this.ready=!1,this.provider=void 0,this.id=1,e=this,(t=function(){e.provider&&e.provider.poll&&e.polls.forEach(function(t){t.data._id=e.id,e.id++,e.provider.poll(t.data,t.id)}),setTimeout(t,12e3)})()},s.prototype.send=function(e,t){e._id=this.id,t&&(g._callbacks[e._id]=t),e.args=e.args||[],this.id++,void 0!==this.provider?this.provider.send(e):(console.warn("provider is not set"),this.queued.push(e))},s.prototype.set=function(e){void 0!==this.provider&&void 0!==this.provider.unload&&this.provider.unload(),this.provider=e,this.ready=!0},s.prototype.sendQueued=function(){for(var e=0;this.queued.length;e++)this.send(this.queued[e])},s.prototype.installed=function(){return void 0!==this.provider},s.prototype.startPolling=function(e,t){this.provider&&this.provider.poll&&this.polls.push({data:e,id:t})},s.prototype.stopPolling=function(e){var t,n;for(t=this.polls.length;t--;)n=this.polls[t],n.id===e&&this.polls.splice(t,1)},g.provider=new s,g.setProvider=function(e){e.onmessage=r,g.provider.set(e),g.provider.sendQueued()},g.haveProvider=function(){return!!g.provider.provider},a=function(e,t){this.impl=t,this.callbacks=[];var n=this;this.promise=t.newFilter(e),this.promise.then(function(e){n.id=e,g.on(t.changed,e,n.trigger.bind(n)),g.provider.startPolling({call:t.changed,args:[e]},e)})},a.prototype.arrived=function(e){this.changed(e)},a.prototype.changed=function(e){var t=this;this.promise.then(function(){t.callbacks.push(e)})},a.prototype.trigger=function(e){for(var t=0;t<this.callbacks.length;t++)this.callbacks[t].call(this,e)},a.prototype.uninstall=function(){var e=this;this.promise.then(function(t){e.impl.uninstallFilter(t),g.provider.stopPolling(t),g.off(impl.changed,t)})},a.prototype.messages=function(){var e=this;return this.promise.then(function(t){return e.impl.getMessages(t)})},t.exports=g},{}],4:[function(e,t){var n=function(){this.handlers=[];var e=this;navigator.qt.onmessage=function(t){e.handlers.forEach(function(n){n.call(e,JSON.parse(t.data))})}};n.prototype.send=function(e){navigator.qt.postMessage(JSON.stringify(e))},Object.defineProperty(n.prototype,"onmessage",{set:function(e){this.handlers.push(e)}}),t.exports=n},{}],5:[function(e,t){var n=function(e){this.handlers=[],this.queued=[],this.ready=!1,this.ws=new WebSocket(e);var t=this;this.ws.onmessage=function(e){for(var n=0;n<t.handlers.length;n++)t.handlers[n].call(t,JSON.parse(e.data),e)},this.ws.onopen=function(){t.ready=!0;for(var e=0;e<t.queued.length;e++)t.send(t.queued[e])}};n.prototype.send=function(e){if(this.ready){var t=JSON.stringify(e);this.ws.send(t)}else this.queued.push(e)},n.prototype.onMessage=function(e){this.handlers.push(e)},n.prototype.unload=function(){this.ws.close()},Object.defineProperty(n.prototype,"onmessage",{set:function(e){this.onMessage(e)}}),t.exports=n},{}],web3:[function(e,t){var n=e("./lib/main");n.providers.WebSocketProvider=e("./lib/websocket"),n.providers.HttpRpcProvider=e("./lib/httprpc"),n.providers.QtProvider=e("./lib/qt"),n.providers.AutoProvider=e("./lib/autoprovider"),t.exports=n},{"./lib/autoprovider":1,"./lib/httprpc":2,"./lib/main":3,"./lib/qt":4,"./lib/websocket":5}]},{},[]);
\ No newline at end of file
diff --git a/example/index.html b/example/index.html
index 202ae70a9..17694cbf6 100644
--- a/example/index.html
+++ b/example/index.html
@@ -3,7 +3,7 @@
 
 <head>
 <script type="text/javascript" src="js/es6-promise/promise.min.js"></script>
-<script type="text/javascript" src="../dist/ethereum.min.js"></script>
+<script type="text/javascript" src="../dist/ethereum.js"></script>
 
 <script type="text/javascript">
 if (window.Promise === undefined) {
@@ -13,8 +13,9 @@ if (window.Promise === undefined) {
 var web3 = require('web3');
 
 //web3.setProvider(new web3.providers.QtProvider());
-web3.setProvider(new web3.providers.HttpRpcProvider("http://localhost:8080"));
+//web3.setProvider(new web3.providers.HttpRpcProvider("http://localhost:8080"));
 // web3.setProvider(new web3.providers.WebSocketProvider("ws://localhost:40404/eth"));
+web3.setProvider(new web3.providers.AutoProvider());
 
 function testSnippet() {
     web3.eth.watch({altered: web3.eth.coinbase}).changed(function() {
diff --git a/gulpfile.js b/gulpfile.js
index 7758a38e0..9e0717d8b 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -25,8 +25,8 @@ var build = function(src, dst) {
       detectGlobals: false,
       bundleExternal: false
     })
-    .add('./')
     .require('./' + src + '.js', {expose: 'web3'})
+    .add('./' + src + '.js')
     .transform('envify', {
       NODE_ENV: 'build'
     })
@@ -50,6 +50,25 @@ var build = function(src, dst) {
     .pipe(gulp.dest( DEST ));
 };
 
+var buildDev = function(src, dst) {
+  return browserify({
+      debug: true,
+      insert_global_vars: false,
+      detectGlobals: false,
+      bundleExternal: false
+    })
+    .require('./' + src + '.js', {expose: 'web3'})
+    .add('./' + src + '.js')
+    .transform('envify', {
+      NODE_ENV: 'build'
+    })
+    .transform('unreachable-branch-transform')
+    .bundle()
+    .pipe(exorcist(path.join( DEST, dst + '.js.map')))
+    .pipe(source(dst + '.js'))
+    .pipe(gulp.dest( DEST ));
+};
+
 var uglifyFile = function(file) {
   return gulp.src( DEST + file + '.js')
     .pipe(uglify())
@@ -79,7 +98,11 @@ gulp.task('build', ['clean'], function () {
 });
 
 gulp.task('buildQt', ['clean'], function () {
-    return build('index_qt', 'ethereum_qt');
+    return build('index_qt', 'ethereum');
+});
+
+gulp.task('buildDev', ['clean'], function () {
+    return buildDev('index', 'ethereum');
 });
 
 gulp.task('uglify', ['build'], function(){
@@ -87,7 +110,7 @@ gulp.task('uglify', ['build'], function(){
 });
 
 gulp.task('uglifyQt', ['buildQt'], function () {
-    return uglifyFile('ethereum_qt');
+    return uglifyFile('ethereum');
 });
 
 gulp.task('watch', function() {
@@ -96,3 +119,5 @@ gulp.task('watch', function() {
 
 gulp.task('default', ['bower', 'lint', 'build', 'uglify']);
 gulp.task('qt', ['bower', 'lint', 'buildQt', 'uglifyQt']);
+gulp.task('dev', ['bower', 'lint', 'buildDev']);
+
diff --git a/index.js b/index.js
index 11e444187..4cf36348f 100644
--- a/index.js
+++ b/index.js
@@ -2,5 +2,6 @@ var web3 = require('./lib/main');
 web3.providers.WebSocketProvider = require('./lib/websocket');
 web3.providers.HttpRpcProvider = require('./lib/httprpc');
 web3.providers.QtProvider = require('./lib/qt');
+web3.providers.AutoProvider = require('./lib/autoprovider');
 
-module.exports = web3;
\ No newline at end of file
+module.exports = web3;
diff --git a/lib/autoprovider.js b/lib/autoprovider.js
new file mode 100644
index 000000000..b05d4190a
--- /dev/null
+++ b/lib/autoprovider.js
@@ -0,0 +1,103 @@
+/*
+    This file is part of ethereum.js.
+
+    ethereum.js is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    ethereum.js is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with ethereum.js.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/** @file websocket.js
+ * @authors:
+ *   Marek Kotewicz <marek@ethdev.com>
+ *   Marian Oancea <marian@ethdev.com>
+ * @date 2014
+ */
+
+/*
+ * @brief if qt object is available, uses QtProvider,
+ * if not tries to connect over websockets
+ * if it fails, it uses HttpRpcProvider
+ */
+if (process.env.NODE_ENV !== 'build') {
+    var WebSocket = require('ws'); // jshint ignore:line
+}
+
+if (process.env.NODE_ENV !== 'build') {
+    var web3 = require('./web3'); // jshint ignore:line
+}
+
+var AutoProvider = function (userOptions) {
+    if (web3.haveProvider()) {
+        return;
+    }
+
+    // before we determine what provider we are, we have to cache request
+    this.sendQueue = [];
+    this.onmessageQueue = [];
+
+    if (navigator.qt) {
+        this.provider = new web3.providers.QtProvider();
+        return;
+    }
+   
+    userOptions = userOptions || {};
+    var options = {
+        httprpc: userOptions.httprpc || 'http://localhost:8080',
+        websockets: userOptions.websockets || 'ws://localhost:40404/eth'
+    };
+    
+    var self = this;
+    var closeWithSuccess = function (success) {
+        ws.close();
+        if (success) {
+            self.provider = new web3.providers.WebSocketProvider(options.websockets);
+            return;
+        }
+        self.provider = new web3.providers.HttpRpcProvider(options.httprpc);
+        self.poll = self.provider.poll.bind(self.provider);
+        self.sendQueue.forEach(function (payload) {
+            self.provider(payload);
+        });
+        self.onmessageQueue.forEach(function (handler) {
+            self.provider.onmessage = handler;
+        });
+    };
+
+    var ws = new WebSocket(options.websockets);
+
+    ws.onopen = function() {
+        closeWithSuccess(true);    
+    };
+
+    ws.onerror = function() {
+        closeWithSuccess(false);
+    };
+};
+
+AutoProvider.prototype.send = function (payload) {
+    if (this.provider) {
+        this.provider.send(payload);
+        return;
+    }
+    this.sendQueue.push(payload);
+};
+
+Object.defineProperty(AutoProvider.prototype, 'onmessage', {
+    set: function (handler) {
+        if (this.provider) {
+            this.provider.onmessage = handler;
+            return;
+        }
+        this.onmessageQueue.push(handler);
+    }
+});
+
+module.exports = AutoProvider;
diff --git a/lib/main.js b/lib/main.js
index d751f8527..c3ed22f8b 100644
--- a/lib/main.js
+++ b/lib/main.js
@@ -387,6 +387,10 @@ web3.setProvider = function(provider) {
     web3.provider.sendQueued();
 };
 
+web3.haveProvider = function() {
+    return !!web3.provider.provider;
+};
+
 var Filter = function(options, impl) {
     this.impl = impl;
     this.callbacks = [];