diff --git a/CHANGELOG.md b/CHANGELOG.md
index 85dc9ce81..60c6a6f44 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,14 @@
 
 - Now when switching networks the extension does not restart
 
+## 3.7.0 2017-5-23
+
+- Add Transaction Number (nonce) to transaction list.
+- Label the pending tx icon with a tooltip.
+- Fix bug where website filters would pile up and not deallocate when leaving a site.
+- Continually resubmit pending txs for a period of time to ensure successful broadcast.
+- ENS names will no longer resolve to their owner if no resolver is set. Resolvers must be explicitly set and configured.
+
 ## 3.6.5 2017-5-17
 
 - Fix bug where edited gas parameters would not take effect.
diff --git a/app/manifest.json b/app/manifest.json
index 31e4598c7..5fd4420be 100644
--- a/app/manifest.json
+++ b/app/manifest.json
@@ -1,7 +1,7 @@
 {
   "name": "MetaMask",
   "short_name": "Metamask",
-  "version": "3.6.5",
+  "version": "3.7.0",
   "manifest_version": 2,
   "author": "https://metamask.io",
   "description": "Ethereum Browser Extension",
diff --git a/app/scripts/controllers/transactions.js b/app/scripts/controllers/transactions.js
index 2ebeed3ab..faccf1ab1 100644
--- a/app/scripts/controllers/transactions.js
+++ b/app/scripts/controllers/transactions.js
@@ -6,8 +6,12 @@ const ObservableStore = require('obs-store')
 const ethUtil = require('ethereumjs-util')
 const TxProviderUtil = require('../lib/tx-utils')
 const createId = require('../lib/random-id')
+const denodeify = require('denodeify')
 
-module.exports = class TransactionManager extends EventEmitter {
+const RETRY_LIMIT = 200
+const RESUBMIT_INTERVAL = 10000 // Ten seconds
+
+module.exports = class TransactionController extends EventEmitter {
   constructor (opts) {
     super()
     this.store = new ObservableStore(extend({
@@ -30,6 +34,8 @@ module.exports = class TransactionManager extends EventEmitter {
     this.store.subscribe(() => this._updateMemstore())
     this.networkStore.subscribe(() => this._updateMemstore())
     this.preferencesStore.subscribe(() => this._updateMemstore())
+
+    this.continuallyResubmitPendingTxs()
   }
 
   getState () {
@@ -229,7 +235,11 @@ module.exports = class TransactionManager extends EventEmitter {
     })
   }
 
-  publishTransaction (txId, rawTx, cb) {
+  publishTransaction (txId, rawTx, cb = warn) {
+    const txMeta = this.getTx(txId)
+    txMeta.rawTx = rawTx
+    this.updateTx(txMeta)
+
     this.txProviderUtils.publishTransaction(rawTx, (err, txHash) => {
       if (err) return cb(err)
       this.setTxHash(txId, txHash)
@@ -352,7 +362,7 @@ module.exports = class TransactionManager extends EventEmitter {
             message: 'There was a problem loading this transaction.',
           }
           this.updateTx(txMeta)
-          return console.error(err)
+          return log.error(err)
         }
         if (txParams.blockNumber) {
           this.setTxStatusConfirmed(txId)
@@ -378,6 +388,7 @@ module.exports = class TransactionManager extends EventEmitter {
     this.emit(`${txMeta.id}:${status}`, txId)
     if (status === 'submitted' || status === 'rejected') {
       this.emit(`${txMeta.id}:finished`, txMeta)
+
     }
     this.updateTx(txMeta)
     this.emit('updateBadge')
@@ -397,7 +408,47 @@ module.exports = class TransactionManager extends EventEmitter {
     })
     this.memStore.updateState({ unapprovedTxs, selectedAddressTxList })
   }
+
+  continuallyResubmitPendingTxs () {
+    const pending = this.getTxsByMetaData('status', 'submitted')
+    const resubmit = denodeify(this.resubmitTx.bind(this))
+    Promise.all(pending.map(txMeta => resubmit(txMeta)))
+    .catch((reason) => {
+      log.info('Problem resubmitting tx', reason)
+    })
+    .then(() => {
+      global.setTimeout(() => {
+        this.continuallyResubmitPendingTxs()
+      }, RESUBMIT_INTERVAL)
+    })
+  }
+
+  resubmitTx (txMeta, cb) {
+    // Increment a try counter.
+    if (!('retryCount' in txMeta)) {
+      txMeta.retryCount = 0
+    }
+
+    // Only auto-submit already-signed txs:
+    if (!('rawTx' in txMeta)) {
+      return cb()
+    }
+
+    if (txMeta.retryCount > RETRY_LIMIT) {
+      txMeta.err = {
+        isWarning: true,
+        message: 'Gave up submitting tx.',
+      }
+      this.updateTx(txMeta)
+      return log.error(txMeta.err.message)
+    }
+
+    txMeta.retryCount++
+    const rawTx = txMeta.rawTx
+    this.txProviderUtils.publishTransaction(rawTx, cb)
+  }
+
 }
 
 
-const warn = () => console.warn('warn was used no cb provided')
+const warn = () => log.warn('warn was used no cb provided')
diff --git a/app/scripts/lib/inpage-provider.js b/app/scripts/lib/inpage-provider.js
index e5e398e24..e54f547bd 100644
--- a/app/scripts/lib/inpage-provider.js
+++ b/app/scripts/lib/inpage-provider.js
@@ -1,5 +1,7 @@
 const pipe = require('pump')
-const StreamProvider = require('web3-stream-provider')
+const ProviderEngine = require('web3-provider-engine')
+const FilterSubprovider = require('web3-provider-engine/subproviders/filters')
+const StreamSubprovider = require('web3-provider-engine/subproviders/stream')
 const LocalStorageStore = require('obs-store')
 const ObjectMultiplex = require('./obj-multiplex')
 const createRandomId = require('./random-id')
@@ -27,14 +29,24 @@ function MetamaskInpageProvider (connectionStream) {
   )
 
   // connect to async provider
-  const asyncProvider = self.asyncProvider = new StreamProvider()
+  const engine = new ProviderEngine()
+
+  const filterSubprovider = new FilterSubprovider()
+  engine.addProvider(filterSubprovider)
+
+  const streamSubprovider = new StreamSubprovider()
+  engine.addProvider(streamSubprovider)
+
   pipe(
-    asyncProvider,
+    streamSubprovider,
     multiStream.createStream('provider'),
-    asyncProvider,
+    streamSubprovider,
     (err) => logStreamDisconnectWarning('MetaMask RpcProvider', err)
   )
 
+  // start polling
+  engine.start()
+
   self.idMap = {}
   // handle sendAsync requests via asyncProvider
   self.sendAsync = function (payload, cb) {
@@ -46,7 +58,7 @@ function MetamaskInpageProvider (connectionStream) {
       return message
     })
     // forward to asyncProvider
-    asyncProvider.sendAsync(request, function (err, res) {
+    engine.sendAsync(request, function (err, res) {
       if (err) return cb(err)
       // transform messages to original ids
       eachJsonMessage(res, (message) => {
diff --git a/package.json b/package.json
index 14ddd2886..6b6996d9d 100644
--- a/package.json
+++ b/package.json
@@ -69,7 +69,7 @@
     "ethereumjs-tx": "^1.3.0",
     "ethereumjs-util": "ethereumjs/ethereumjs-util#ac5d0908536b447083ea422b435da27f26615de9",
     "ethereumjs-wallet": "^0.6.0",
-    "ethjs-ens": "^1.0.2",
+    "ethjs-ens": "^2.0.0",
     "express": "^4.14.0",
     "extension-link-enabler": "^1.0.0",
     "extensionizer": "^1.0.0",
@@ -87,6 +87,7 @@
     "mississippi": "^1.2.0",
     "mkdirp": "^0.5.1",
     "multiplex": "^6.7.0",
+    "number-to-bn": "^1.7.0",
     "obs-store": "^2.3.1",
     "once": "^1.3.3",
     "ping-pong-stream": "^1.0.0",
@@ -121,7 +122,7 @@
     "valid-url": "^1.0.9",
     "vreme": "^3.0.2",
     "web3": "0.18.2",
-    "web3-provider-engine": "^12.0.6",
+    "web3-provider-engine": "^12.1.0",
     "web3-stream-provider": "^2.0.6",
     "xtend": "^4.0.1"
   },
diff --git a/ui/app/components/transaction-list-item-icon.js b/ui/app/components/transaction-list-item-icon.js
index d63cae259..431054340 100644
--- a/ui/app/components/transaction-list-item-icon.js
+++ b/ui/app/components/transaction-list-item-icon.js
@@ -1,6 +1,7 @@
 const Component = require('react').Component
 const h = require('react-hyperscript')
 const inherits = require('util').inherits
+const Tooltip = require('./tooltip')
 
 const Identicon = require('./identicon')
 
@@ -32,11 +33,16 @@ TransactionIcon.prototype.render = function () {
       })
 
     case 'submitted':
-      return h('i.fa.fa-ellipsis-h', {
-        style: {
-          fontSize: '27px',
-        },
-      })
+      return h(Tooltip, {
+        title: 'Pending',
+        position: 'bottom',
+      }, [
+        h('i.fa.fa-ellipsis-h', {
+          style: {
+            fontSize: '27px',
+          },
+        }),
+      ])
   }
 
   if (isMsg) {
diff --git a/ui/app/components/transaction-list-item.js b/ui/app/components/transaction-list-item.js
index c2a585003..dbda66a31 100644
--- a/ui/app/components/transaction-list-item.js
+++ b/ui/app/components/transaction-list-item.js
@@ -8,6 +8,7 @@ const explorerLink = require('../../lib/explorer-link')
 const CopyButton = require('./copyButton')
 const vreme = new (require('vreme'))
 const Tooltip = require('./tooltip')
+const numberToBN = require('number-to-bn')
 
 const TransactionIcon = require('./transaction-list-item-icon')
 const ShiftListItem = require('./shift-list-item')
@@ -39,6 +40,8 @@ TransactionListItem.prototype.render = function () {
     txParams = transaction.msgParams
   }
 
+  const nonce = txParams.nonce ? numberToBN(txParams.nonce).toString(10) : ''
+
   const isClickable = ('hash' in transaction && isLinkable) || isPending
   return (
     h(`.transaction-list-item.flex-row.flex-space-between${isClickable ? '.pointer' : ''}`, {
@@ -69,6 +72,22 @@ TransactionListItem.prototype.render = function () {
         ]),
       ]),
 
+      h(Tooltip, {
+        title: 'Transaction Number',
+        position: 'bottom',
+      }, [
+        h('span', {
+          style: {
+            display: 'flex',
+            cursor: 'normal',
+            flexDirection: 'column',
+            alignItems: 'center',
+            justifyContent: 'center',
+            padding: '10px',
+          },
+        }, nonce),
+      ]),
+
       h('.flex-column', {style: {width: '200px', overflow: 'hidden'}}, [
         domainField(txParams),
         h('div', date),