aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/scripts/lib/config-manager.js34
-rw-r--r--app/scripts/lib/controllers/shapeshift.js104
-rw-r--r--app/scripts/lib/idStore.js1
-rw-r--r--app/scripts/metamask-controller.js15
-rw-r--r--app/scripts/migrations/010.js36
-rw-r--r--app/scripts/migrations/index.js3
-rw-r--r--ui/app/actions.js3
7 files changed, 156 insertions, 40 deletions
diff --git a/app/scripts/lib/config-manager.js b/app/scripts/lib/config-manager.js
index a9b86ca8c..7ae2d4400 100644
--- a/app/scripts/lib/config-manager.js
+++ b/app/scripts/lib/config-manager.js
@@ -250,40 +250,6 @@ ConfigManager.prototype.getTOSHash = function () {
return data.TOSHash
}
-ConfigManager.prototype.getShapeShiftTxList = function () {
- var data = this.getData()
- var shapeShiftTxList = data.shapeShiftTxList ? data.shapeShiftTxList : []
- shapeShiftTxList.forEach((tx) => {
- if (tx.response.status !== 'complete') {
- var requestListner = function (request) {
- tx.response = JSON.parse(this.responseText)
- if (tx.response.status === 'complete') {
- tx.time = new Date().getTime()
- }
- }
-
- var shapShiftReq = new XMLHttpRequest()
- shapShiftReq.addEventListener('load', requestListner)
- shapShiftReq.open('GET', `https://shapeshift.io/txStat/${tx.depositAddress}`, true)
- shapShiftReq.send()
- }
- })
- this.setData(data)
- return shapeShiftTxList
-}
-
-ConfigManager.prototype.createShapeShiftTx = function (depositAddress, depositType) {
- var data = this.getData()
-
- var shapeShiftTx = {depositAddress, depositType, key: 'shapeshift', time: new Date().getTime(), response: {}}
- if (!data.shapeShiftTxList) {
- data.shapeShiftTxList = [shapeShiftTx]
- } else {
- data.shapeShiftTxList.push(shapeShiftTx)
- }
- this.setData(data)
-}
-
ConfigManager.prototype.getGasMultiplier = function () {
var data = this.getData()
return data.gasMultiplier
diff --git a/app/scripts/lib/controllers/shapeshift.js b/app/scripts/lib/controllers/shapeshift.js
new file mode 100644
index 000000000..3d955c01f
--- /dev/null
+++ b/app/scripts/lib/controllers/shapeshift.js
@@ -0,0 +1,104 @@
+const ObservableStore = require('obs-store')
+const extend = require('xtend')
+
+// every three seconds when an incomplete tx is waiting
+const POLLING_INTERVAL = 3000
+
+class ShapeshiftController {
+
+ constructor (opts = {}) {
+ const initState = extend({
+ shapeShiftTxList: [],
+ }, opts.initState)
+ this.store = new ObservableStore(initState)
+ this.pollForUpdates()
+ }
+
+ //
+ // PUBLIC METHODS
+ //
+
+ getShapeShiftTxList () {
+ const shapeShiftTxList = this.store.getState().shapeShiftTxList
+ return shapeShiftTxList
+ }
+
+ getPendingTxs () {
+ const txs = this.getShapeShiftTxList()
+ const pending = txs.filter(tx => tx.response && tx.response.status !== 'complete')
+ return pending
+ }
+
+ pollForUpdates () {
+ const pendingTxs = this.getPendingTxs()
+
+ if (pendingTxs.length === 0) {
+ return
+ }
+
+ Promise.all(pendingTxs.map((tx) => {
+ return this.updateTx(tx)
+ }))
+ .then((results) => {
+ results.forEach(tx => this.saveTx(tx))
+ this.timeout = setTimeout(this.pollForUpdates.bind(this), POLLING_INTERVAL)
+ })
+ }
+
+ updateTx (tx) {
+ const url = `https://shapeshift.io/txStat/${tx.depositAddress}`
+ return fetch(url)
+ .then((response) => {
+ return response.json()
+ }).then((json) => {
+ tx.response = json
+ if (tx.response.status === 'complete') {
+ tx.time = new Date().getTime()
+ }
+ return tx
+ })
+ }
+
+ saveTx (tx) {
+ const { shapeShiftTxList } = this.store.getState()
+ const index = shapeShiftTxList.indexOf(tx)
+ if (index !== -1) {
+ shapeShiftTxList[index] = tx
+ this.store.updateState({ shapeShiftTxList })
+ }
+ }
+
+ removeShapeShiftTx (tx) {
+ const { shapeShiftTxList } = this.store.getState()
+ const index = shapeShiftTxList.indexOf(index)
+ if (index !== -1) {
+ shapeShiftTxList.splice(index, 1)
+ }
+ this.updateState({ shapeShiftTxList })
+ }
+
+ createShapeShiftTx (depositAddress, depositType) {
+ const state = this.store.getState()
+ let { shapeShiftTxList } = state
+
+ var shapeShiftTx = {
+ depositAddress,
+ depositType,
+ key: 'shapeshift',
+ time: new Date().getTime(),
+ response: {},
+ }
+
+ if (!shapeShiftTxList) {
+ shapeShiftTxList = [shapeShiftTx]
+ } else {
+ shapeShiftTxList.push(shapeShiftTx)
+ }
+
+ this.store.updateState({ shapeShiftTxList })
+ this.pollForUpdates()
+ }
+
+}
+
+module.exports = ShapeshiftController
diff --git a/app/scripts/lib/idStore.js b/app/scripts/lib/idStore.js
index ac395440d..1afe5f651 100644
--- a/app/scripts/lib/idStore.js
+++ b/app/scripts/lib/idStore.js
@@ -96,7 +96,6 @@ IdentityStore.prototype.getState = function () {
seedWords: seedWords,
isDisclaimerConfirmed: configManager.getConfirmedDisclaimer(),
selectedAddress: configManager.getSelectedAccount(),
- shapeShiftTxList: configManager.getShapeShiftTxList(),
gasMultiplier: configManager.getGasMultiplier(),
}))
}
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index 066e389e2..fb2040c63 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -14,6 +14,7 @@ const KeyringController = require('./keyring-controller')
const PreferencesController = require('./lib/controllers/preferences')
const CurrencyController = require('./lib/controllers/currency')
const NoticeController = require('./notice-controller')
+const ShapeShiftController = require('./lib/controllers/shapeshift')
const MessageManager = require('./lib/message-manager')
const TxManager = require('./transaction-manager')
const ConfigManager = require('./lib/config-manager')
@@ -98,6 +99,10 @@ module.exports = class MetamaskController extends EventEmitter {
// to be uncommented when retrieving notices from a remote server.
// this.noticeController.startPolling()
+ this.shapeshiftController = new ShapeShiftController({
+ initState: initState.ShapeShiftController,
+ })
+
this.lookupNetwork()
this.messageManager = new MessageManager()
this.publicConfigStore = this.initPublicConfigStore()
@@ -125,6 +130,9 @@ module.exports = class MetamaskController extends EventEmitter {
this.noticeController.store.subscribe((state) => {
this.store.updateState({ NoticeController: state })
})
+ this.shapeshiftController.store.subscribe((state) => {
+ this.store.updateState({ ShapeShiftController: state })
+ })
// manual mem state subscriptions
this.networkStore.subscribe(this.sendUpdate.bind(this))
@@ -135,6 +143,7 @@ module.exports = class MetamaskController extends EventEmitter {
this.preferencesController.store.subscribe(this.sendUpdate.bind(this))
this.currencyController.store.subscribe(this.sendUpdate.bind(this))
this.noticeController.memStore.subscribe(this.sendUpdate.bind(this))
+ this.shapeshiftController.store.subscribe(this.sendUpdate.bind(this))
}
//
@@ -207,8 +216,8 @@ module.exports = class MetamaskController extends EventEmitter {
this.noticeController.memStore.getState(),
// config manager
this.configManager.getConfig(),
+ this.shapeshiftController.store.getState(),
{
- shapeShiftTxList: this.configManager.getShapeShiftTxList(),
lostAccounts: this.configManager.getLostAccounts(),
isDisclaimerConfirmed: this.configManager.getConfirmedDisclaimer(),
seedWords: this.configManager.getSeedWords(),
@@ -327,7 +336,7 @@ module.exports = class MetamaskController extends EventEmitter {
)
}
- sendUpdate () {
+ sendUpdate () {
this.emit('update', this.getState())
}
@@ -597,7 +606,7 @@ module.exports = class MetamaskController extends EventEmitter {
}
createShapeShiftTx (depositAddress, depositType) {
- this.configManager.createShapeShiftTx(depositAddress, depositType)
+ this.shapeshiftController.createShapeShiftTx(depositAddress, depositType)
}
setGasMultiplier (gasMultiplier, cb) {
diff --git a/app/scripts/migrations/010.js b/app/scripts/migrations/010.js
new file mode 100644
index 000000000..d41c63fcd
--- /dev/null
+++ b/app/scripts/migrations/010.js
@@ -0,0 +1,36 @@
+const version = 10
+
+/*
+
+This migration breaks out the CurrencyController substate
+
+*/
+
+const merge = require('deep-extend')
+
+module.exports = {
+ version,
+
+ migrate: function (versionedData) {
+ versionedData.meta.version = version
+ try {
+ const state = versionedData.data
+ const newState = transformState(state)
+ versionedData.data = newState
+ } catch (err) {
+ console.warn(`MetaMask Migration #${version}` + err.stack)
+ }
+ return Promise.resolve(versionedData)
+ },
+}
+
+function transformState (state) {
+ const newState = merge({}, state, {
+ ShapeShiftController: {
+ shapeShiftTxList: state.shapeShiftTxList || [],
+ },
+ })
+ delete newState.shapeShiftTxList
+
+ return newState
+}
diff --git a/app/scripts/migrations/index.js b/app/scripts/migrations/index.js
index 22bf008ba..2db8646b0 100644
--- a/app/scripts/migrations/index.js
+++ b/app/scripts/migrations/index.js
@@ -1,5 +1,5 @@
/* The migrator has two methods the user should be concerned with:
- *
+ *
* getData(), which returns the app-consumable data object
* saveData(), which persists the app-consumable data object.
*/
@@ -20,4 +20,5 @@ module.exports = [
require('./007'),
require('./008'),
require('./009'),
+ require('./010'),
]
diff --git a/ui/app/actions.js b/ui/app/actions.js
index c153a55a6..0c6e40552 100644
--- a/ui/app/actions.js
+++ b/ui/app/actions.js
@@ -843,6 +843,7 @@ function coinShiftRquest (data, marketData) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
shapeShiftRequest('shift', { method: 'POST', data}, (response) => {
+ dispatch(actions.hideLoadingIndication())
if (response.error) return dispatch(actions.displayWarning(response.error))
var message = `
Deposit your ${response.depositType} to the address bellow:`
@@ -933,4 +934,4 @@ function forceUpdateMetamaskState(dispatch){
}
dispatch(actions.updateMetamaskState(newState))
})
-} \ No newline at end of file
+}