Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3box integration 2.0 #6972

Merged
merged 61 commits into from
Sep 16, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
936b21b
Adds threebox controller
danjm Jun 19, 2019
de1a418
Adds threebox approval modal
danjm Jun 19, 2019
521681b
Fix unit tests and lint after addition of threebox
danjm Jun 24, 2019
04676e4
Correct threebox behaviour after rejecting request for backup; fixes …
danjm Jun 24, 2019
c60eab8
Update threebox controller for automatic syncing
danjm Jul 18, 2019
e18a659
Ensure frontend locale updates when preferences are changed via direc…
danjm Jul 18, 2019
c618cc3
Add toggle in settings for 3box syncing
danjm Jul 18, 2019
a69819d
Update threebox controller for latest 3box version
danjm Jul 26, 2019
8766e7c
Delete unnecessary frontend changes for threebox integration
danjm Jul 26, 2019
6ccee35
Backing up address book contacts with threebox
danjm Jul 26, 2019
3c0dab8
Update unit tests for 3box-integration additions
danjm Jul 26, 2019
a5635e3
Only enable threebox by default for new wallets
danjm Aug 1, 2019
a4d2910
Mock globals for correct unit tests
danjm Aug 1, 2019
249a732
3box '1.10.2' -> '^1.10.2'
danjm Aug 1, 2019
000b42c
Correct capilalization on 3Box
danjm Aug 1, 2019
988581b
Use log.debug instead of console.log in threebox controller
danjm Aug 1, 2019
05eaa9d
Update yarn.lock
danjm Aug 1, 2019
d605674
Remove edge build
whymarrh Aug 2, 2019
8e12be9
Split 3box module into background deps js file
whymarrh Aug 2, 2019
6289526
extra bundle opts for bg-libs
whymarrh Aug 2, 2019
079306d
sync yarn.lock
whymarrh Aug 2, 2019
92d471c
new3Box logic
whymarrh Aug 2, 2019
49c7dd0
Remove bg-libs.js from manifest file for dev builds
danjm Aug 5, 2019
535ab01
Show confirm threebox restore after import
danjm Aug 2, 2019
b9f8de6
Switch 3Box controller to using the spaces api (instead of the profil…
danjm Aug 6, 2019
fd0ccdb
Finalize switching to spaces api and only restoring from 3box after i…
danjm Aug 7, 2019
20fda39
Update metamask-controller-test.js for threebox controller changes
danjm Aug 7, 2019
61460b0
Make threebox modal style consistent with others and update success b…
danjm Aug 13, 2019
45833e8
Use mock 3box when in test
danjm Aug 13, 2019
e3c4171
Correct 3box modal header
danjm Aug 13, 2019
0ea5868
Remove unnecessary property of threebox controller provider
danjm Aug 16, 2019
049b885
Remove unnecessary method calls after restoration from 3box in the th…
danjm Aug 16, 2019
538ce93
Replace setThreeBoxSyncingPermission calls in routes/index.js with tu…
danjm Aug 16, 2019
f3f1930
Replace erroneous use of with
danjm Aug 16, 2019
3bc3ba2
Replace erroneous use of threeboxSyncing with threeBoxSyncingAllowed …
danjm Aug 16, 2019
d2702ef
Lint fixes for 3box changes
danjm Aug 16, 2019
eceb3bc
Log errors encountered when updating 3Box
Gudahtt Aug 16, 2019
2a5fc53
Remove unnecessary parameter from state update
Gudahtt Aug 19, 2019
606ee9a
Add timeout to initial 3Box sync
Gudahtt Aug 19, 2019
f260617
Use non-minified 3Box module
Gudahtt Aug 20, 2019
1314c63
Use app key addresses for threebox
danjm Aug 21, 2019
696d56b
Replace use of modal for confirming 3box restoration with a home noti…
danjm Aug 22, 2019
fad7b8b
Adds e2e tests for restoring from threebox
danjm Aug 22, 2019
8762465
Update eth-keyring-controller to 5.1.0
danjm Sep 3, 2019
7f39afd
Correct parameters passed to getAppKeyAddress in threebox.js
danjm Sep 4, 2019
b2375e0
Add prefix to origin passed to getAppKeyAddress in threebox.js
danjm Sep 4, 2019
d1519b0
Remove unused locale message.
danjm Sep 4, 2019
46d9465
Prevent CORS errors in firefox e2e tests
danjm Sep 4, 2019
e994151
Ensure extraneous scripts are excluded from the local test dev build
danjm Sep 4, 2019
c2b678b
Move threeBoxLastUpdate state from home.component to redux
danjm Sep 9, 2019
d0909c6
Threebox PR code cleanup
danjm Sep 9, 2019
557df40
Always use first address when initializing threebox
danjm Sep 9, 2019
3fd1cc1
Replace setRestoredFromThreeBox api with setRestoredFromThreeBoxToFal…
danjm Sep 9, 2019
ef4c74e
Update development/metamaskbot-build-announce.js to include ui-libs a…
danjm Sep 11, 2019
9fbf587
Update test/e2e/threebox.spec.js to use new helpers added with pull #…
danjm Sep 11, 2019
26d6a7a
Make setFeatureFlag available on the ui window during testing
danjm Sep 11, 2019
70c8004
Hide threebox feature behind a feature flag that can only be activate…
danjm Sep 11, 2019
255a0c0
Remove unnecessary migration of threebox feature flag
danjm Sep 12, 2019
a203d58
Prevent this.init() call in threebox constructor if feature flag is n…
danjm Sep 12, 2019
4fcc18a
Prevent threebox notification from showing if feature flag is falsy
danjm Sep 12, 2019
3d81850
http://localhost/8889 -> http://localhost/* in gulp manifest:testing …
danjm Sep 12, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions app/_locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,9 @@
"customRPC": {
"message": "Custom RPC"
},
"dataBackupFoundInfo": {
"message": "Some of your account data was backed up during a previous installation of MetaMask. This could include your settings, contacts and tokens. Would you like to restore this data now?"
},
"decimalsMustZerotoTen": {
"message": "Decimals must be at least 0, and not over 36."
},
Expand Down Expand Up @@ -1148,6 +1151,9 @@
"noTransactions": {
"message": "You have no transactions"
},
"noThanks": {
"message": "No Thanks"
},
"notEnoughGas": {
"message": "Not Enough Gas"
},
Expand Down Expand Up @@ -1337,6 +1343,10 @@
"restoreAccountWithSeed": {
"message": "Restore your Account with Seed Phrase"
},
"restoreWalletPreferences": {
"message": "A backup of your data from $1 has been found. Would you like to restore your wallet preferences?",
"description": "$1 is the date at which the data was backed up"
},
"requestsAwaitingAcknowledgement": {
"message": "requests waiting to be acknowledged"
},
Expand Down Expand Up @@ -1642,6 +1652,15 @@
"symbolBetweenZeroTwelve": {
"message": "Symbol must be between 0 and 12 characters."
},
"syncWithThreeBox": {
"message": "Sync data with 3Box"
},
"syncWithThreeBoxDescription": {
"message": "Turn on to have your settings backed up with 3Box"
},
"syncWithThreeBoxDisabled": {
"message": "3Box has been disabled due to an error during the initial sync"
},
"syncWithMobile": {
"message": "Sync with mobile"
},
Expand Down
2 changes: 1 addition & 1 deletion app/home.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
</head>
<body>
<div id="app-content"></div>
<script src="./libs.js" type="text/javascript" charset="utf-8"></script>
<script src="./ui-libs.js" type="text/javascript" charset="utf-8"></script>
<script src="./ui.js" type="text/javascript" charset="utf-8"></script>
</body>
</html>
1 change: 1 addition & 0 deletions app/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"background": {
"scripts": [
"chromereload.js",
"bg-libs.js",
"background.js"
],
"persistent": true
Expand Down
2 changes: 1 addition & 1 deletion app/notification.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
<img id="loading__logo" src="./images/logo/metamask-fox.svg" />
<img id="loading__spinner" src="./images/spinner.gif" />
</div>
<script src="./libs.js" type="text/javascript" charset="utf-8"></script>
<script src="./ui-libs.js" type="text/javascript" charset="utf-8"></script>
<script src="./ui.js" type="text/javascript" charset="utf-8"></script>
</body>
</html>
2 changes: 1 addition & 1 deletion app/popup.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
</head>
<body style="width:357px; height:600px;">
<div id="app-content"></div>
<script src="./libs.js" type="text/javascript" charset="utf-8"></script>
<script src="./ui-libs.js" type="text/javascript" charset="utf-8"></script>
<script src="./ui.js" type="text/javascript" charset="utf-8"></script>
</body>
</html>
1 change: 1 addition & 0 deletions app/scripts/controllers/preferences.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class PreferencesController {
// perform sensitive operations.
featureFlags: {
showIncomingTransactions: true,
threeBox: false,
},
knownMethodData: {},
participateInMetaMetrics: null,
Expand Down
213 changes: 213 additions & 0 deletions app/scripts/controllers/threebox.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
const ObservableStore = require('obs-store')
const Box = process.env.IN_TEST
? require('../../../development/mock-3box')
: require('3box')
// const Box = require(process.env.IN_TEST ? '../lib/mock-3box' : '3box/dist/3box.min')
const log = require('loglevel')

const JsonRpcEngine = require('json-rpc-engine')
const providerFromEngine = require('eth-json-rpc-middleware/providerFromEngine')
const createMetamaskMiddleware = require('./network/createMetamaskMiddleware')
const createOriginMiddleware = require('../lib/createOriginMiddleware')

const SYNC_TIMEOUT = 60 * 1000 // one minute

class ThreeBoxController {
constructor (opts = {}) {
const {
preferencesController,
keyringController,
addressBookController,
version,
getKeyringControllerState,
getSelectedAddress,
} = opts

this.preferencesController = preferencesController
this.addressBookController = addressBookController
this.keyringController = keyringController
this.provider = this._createProvider({
version,
getAccounts: async ({ origin }) => {
if (origin !== '3Box') { return [] }
const isUnlocked = getKeyringControllerState().isUnlocked

const selectedAddress = getSelectedAddress()

if (isUnlocked && selectedAddress) {
return [selectedAddress]
} else {
return []
}
},
processPersonalMessage: (msgParams) => {
return Promise.resolve(keyringController.signPersonalMessage(msgParams, {
withAppKeyOrigin: 'wallet://3box.metamask.io',
}))
},
})

const initState = {
threeBoxSyncingAllowed: true,
restoredFromThreeBox: null,
...opts.initState,
threeBoxAddress: null,
threeBoxSynced: false,
threeBoxDisabled: false,
}
this.store = new ObservableStore(initState)
this.registeringUpdates = false

const threeBoxFeatureFlagTurnedOn = this.preferencesController.getFeatureFlags().threeBox

if (threeBoxFeatureFlagTurnedOn) {
this.init()
}
}

async init () {
const accounts = await this.keyringController.getAccounts()
this.address = accounts[0]
if (this.address && !(this.box && this.store.getState().threeBoxSynced)) {
await this.new3Box()
}
}

async _update3Box ({ type }, newState) {
try {
const { threeBoxSyncingAllowed, threeBoxSynced } = this.store.getState()
if (threeBoxSyncingAllowed && threeBoxSynced) {
await this.space.private.set('lastUpdated', Date.now())
await this.space.private.set(type, JSON.stringify(newState))
}
} catch (error) {
console.error(error)
}
}

_createProvider (providerOpts) {
const metamaskMiddleware = createMetamaskMiddleware(providerOpts)
const engine = new JsonRpcEngine()
engine.push(createOriginMiddleware({ origin: '3Box' }))
engine.push(metamaskMiddleware)
const provider = providerFromEngine(engine)
return provider
}

_waitForOnSyncDone () {
return new Promise((resolve) => {
this.box.onSyncDone(() => {
log.debug('3Box box sync done')
return resolve()
})
})
}

async new3Box () {
const accounts = await this.keyringController.getAccounts()
const address = accounts[0]

if (this.getThreeBoxSyncingState()) {
this.store.updateState({ threeBoxSynced: false })
this.address = await this.keyringController.getAppKeyAddress(address, 'wallet://3box.metamask.io')

let timedOut = false
const syncTimeout = setTimeout(() => {
log.error(`3Box sync timed out after ${SYNC_TIMEOUT} ms`)
timedOut = true
this.store.updateState({
threeBoxDisabled: true,
threeBoxSyncingAllowed: false,
})
}, SYNC_TIMEOUT)
try {
this.box = await Box.openBox(address, this.provider)
await this._waitForOnSyncDone()
Gudahtt marked this conversation as resolved.
Show resolved Hide resolved
this.space = await this.box.openSpace('metamask', {
onSyncDone: async () => {
const stateUpdate = {
threeBoxSynced: true,
threeBoxAddress: address,
}
if (timedOut) {
log.info(`3Box sync completed after timeout; no longer disabled`)
stateUpdate.threeBoxDisabled = false
}

clearTimeout(syncTimeout)
this.store.updateState(stateUpdate)
log.debug('3Box space sync done')
},
})
} catch (e) {
console.error(e)
throw e
}
}
}

async getLastUpdated () {
return await this.space.private.get('lastUpdated')
}

async restoreFromThreeBox () {
this.setRestoredFromThreeBoxToTrue()
const backedUpPreferences = await this.space.private.get('preferences')
backedUpPreferences && this.preferencesController.store.updateState(JSON.parse(backedUpPreferences))
const backedUpAddressBook = await this.space.private.get('addressBook')
backedUpAddressBook && this.addressBookController.update(JSON.parse(backedUpAddressBook), true)
}

turnThreeBoxSyncingOn () {
this._registerUpdates()
}

turnThreeBoxSyncingOff () {
this.box.logout()
}

setRestoredFromThreeBoxToTrue () {
this.store.updateState({ restoredFromThreeBox: true })
}

setRestoredFromThreeBoxToFalse () {
this.store.updateState({ restoredFromThreeBox: false })
}

setThreeBoxSyncingPermission (newThreeboxSyncingState) {
if (this.store.getState().threeBoxDisabled) {
return
}
this.store.updateState({
threeBoxSyncingAllowed: newThreeboxSyncingState,
})

if (newThreeboxSyncingState && this.box) {
this.turnThreeBoxSyncingOn()
}

if (!newThreeboxSyncingState && this.box) {
this.turnThreeBoxSyncingOff()
}
}

getThreeBoxSyncingState () {
return this.store.getState().threeBoxSyncingAllowed
}

getThreeBoxAddress () {
return this.store.getState().threeBoxAddress
}

_registerUpdates () {
if (!this.registeringUpdates) {
const updatePreferences = this._update3Box.bind(this, { type: 'preferences' })
this.preferencesController.store.subscribe(updatePreferences)
const updateAddressBook = this._update3Box.bind(this, { type: 'addressBook' })
this.addressBookController.subscribe(updateAddressBook)
this.registeringUpdates = true
}
}
}

module.exports = ThreeBoxController
2 changes: 1 addition & 1 deletion app/scripts/lib/personal-message-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ module.exports = class PersonalMessageManager extends EventEmitter {
*/
_setMsgStatus (msgId, status) {
const msg = this.getMsg(msgId)
if (!msg) throw new Error('PersonalMessageManager - Message not found for id: "${msgId}".')
if (!msg) throw new Error(`PersonalMessageManager - Message not found for id: "${msgId}".`)
msg.status = status
this._updateMsg(msg)
this.emit(`${msgId}:${status}`, msg)
Expand Down
Loading