From 9f3445252c766053b7a773d75dceb1c1bbfdc6f5 Mon Sep 17 00:00:00 2001 From: frankiebee Date: Thu, 9 Mar 2017 18:24:41 -0800 Subject: put background in service worker --- library/controller.js | 22 ++++ library/controllers/index-db-controller.js | 96 ++++++++++++++ library/index.js | 2 +- library/popup.js | 2 +- library/server.js | 6 + library/sw-controller.js | 49 +++++++ library/sw-core.js | 203 +++++++++++++++++++++++++++++ 7 files changed, 378 insertions(+), 2 deletions(-) create mode 100644 library/controllers/index-db-controller.js create mode 100644 library/sw-controller.js create mode 100644 library/sw-core.js diff --git a/library/controller.js b/library/controller.js index 5823287cc..ba97da93c 100644 --- a/library/controller.js +++ b/library/controller.js @@ -1,3 +1,4 @@ +/* const urlUtil = require('url') const extend = require('xtend') const Dnode = require('dnode') @@ -157,3 +158,24 @@ function initializeZeroClient() { } } + +*/ +const SWcontroller = require('./sw-controller') +console.log('outside:open') +const background = new SWcontroller({ + fileName: 'sw-build.js', + registerOpts: { + scope: './', + } +}) + +background.startWorker() +.then(registerdWorker => { + return background.sendMessage('connect') +}) +.then((port) => { + debugger +}) +.catch(err => { + console.error(`SW Controller: ${err}`) +}) diff --git a/library/controllers/index-db-controller.js b/library/controllers/index-db-controller.js new file mode 100644 index 000000000..8b90db066 --- /dev/null +++ b/library/controllers/index-db-controller.js @@ -0,0 +1,96 @@ +const EventEmitter = require('events') +module.exports = class IndexDbController extends EventEmitter { + + constructor (opts) { + super() + this.migrations = opts.migrations + this.key = opts.key + this.dbObject = opts.global.indexedDB + this.IDBTransaction = opts.global.IDBTransaction || opts.global.webkitIDBTransaction || opts.global.msIDBTransaction || {READ_WRITE: "readwrite"}; // This line should only be needed if it is needed to support the object's constants for older browsers + this.IDBKeyRange = opts.global.IDBKeyRange || opts.global.webkitIDBKeyRange || opts.global.msIDBKeyRange; + this.version = opts.version + this.logging = opts.logging + this.initialState = opts.initialState + if (this.logging) this.on('log', logger) + } + + // Opens the database connection and returns a promise + open (version = this.version) { + return new Promise((resolve, reject) => { + const dbOpenRequest = this.dbObject.open(this.key, version) + dbOpenRequest.onerror = (event) => { + return reject(event) + } + dbOpenRequest.onsuccess = (event) => { + this.db = dbOpenRequest.result + if (!this.db.objectStoreNames.length) { + Object.keys(this.initialState).forEach((key) => { + this._add(key, this.initialState[key]) + }) + } + this.emit('success') + resolve(this.db) + } + dbOpenRequest.onupgradeneeded = (event) => { + // if (this.migrators) + this.db = event.target.result + this.migrate() + } + }) + } + + requestObjectStore (key, type = 'readonly') { + return new Promise((resolve, reject) => { + const dbReadWrite = this.db.transaction(key, type) + const dataStore = dbReadWrite.objectStore(key) + resolve(dataStore) + }) + } + + get (key) { + return this.requestObjectStore(key) + .then((dataObject)=> { + return new Promise((resolve, reject) => { + const getRequest = dataObject.get(key) + getRequest.onsuccess = (event) => resolve(event.currentTarget.result) + getRequest.onerror = (event) => reject(event) + }) + }) + } + + put (key, store) { + return this.requestObjectStore(key, 'readwrite') + .then((dataObject)=> { + const putRequest = dataObject.put(store) + putRequest.onsuccess = (event) => Promise.resolve(event.currentTarget.result) + putRequest.onerror = (event) => Promise.reject(event) + }) + } + + update (key, value) { + + } + + migrate () { + // this.migrations + + // Place holder for future migrations eg: + this.db.deleteObjectStore('meta') + this.db.deleteObjectStore('data') + this.db.createObjectStore('dataStore') + } + + _add (key, objStore, cb = logger) { + return this.requestObjectStore(key, 'readwrite') + .then((dataObject)=> { + const addRequest = dataObject.add(objStore, key) + addRequest.onsuccess = (event) => Promise.resolve(event.currentTarget.result) + addRequest.onerror = (event) => Promise.reject(event) + }) + } + +} + +function logger (err, ress) { + err ? console.error(`Logger says: ${err}`) : console.dir(`Logger says: ${ress}`) +} diff --git a/library/index.js b/library/index.js index b5f4f6637..af82c6546 100644 --- a/library/index.js +++ b/library/index.js @@ -26,7 +26,7 @@ var shouldPop = false window.addEventListener('click', function(){ if (!shouldPop) return shouldPop = false - window.open('http://127.0.0.1:9001/popup/popup.html', '', 'width=360 height=500') + window.open('http://localhost:9001/popup/popup.html', '', 'width=360 height=500') console.log('opening window...') }) diff --git a/library/popup.js b/library/popup.js index 667b13371..59b70edbb 100644 --- a/library/popup.js +++ b/library/popup.js @@ -11,7 +11,7 @@ var name = 'popup' window.METAMASK_UI_TYPE = name var iframeStream = setupIframe({ - zeroClientProvider: 'http://127.0.0.1:9001', + zeroClientProvider: 'http://localhost:9001', sandboxAttributes: ['allow-scripts', 'allow-popups', 'allow-same-origin'], container: document.body, }) diff --git a/library/server.js b/library/server.js index 797ad8a77..b9f59c2a1 100644 --- a/library/server.js +++ b/library/server.js @@ -7,6 +7,7 @@ const zeroBundle = createBundle('./index.js') const controllerBundle = createBundle('./controller.js') const popupBundle = createBundle('./popup.js') const appBundle = createBundle('./example/index.js') +const swBuild = createBundle('./sw-core.js') // // Iframe Server @@ -24,6 +25,11 @@ iframeServer.use('/popup', express.static('../dist/chrome')) iframeServer.get('/controller.js', function(req, res){ res.send(controllerBundle.latest) }) +iframeServer.get('/sw-build.js', function(req, res){ + console.log('/sw-build.js') + res.setHeader('Content-Type', 'application/javascript') + res.send(swBuild.latest) +}) // serve background controller iframeServer.use(express.static('./server')) diff --git a/library/sw-controller.js b/library/sw-controller.js new file mode 100644 index 000000000..d5065a933 --- /dev/null +++ b/library/sw-controller.js @@ -0,0 +1,49 @@ +const EventEmitter = require('events') + +module.exports = class serviceWorkerController extends EventEmitter{ + constructor (opts) { + super() + this.fileName = opts.fileName + this.registerOpts = opts.registerOpts + this.serviceWorker = navigator.serviceWorker + } + + + startWorker () { + // check to see if their is a preregistered service worker + if (!this.serviceWorker.controller) { + return Promise.resolve(this.registerWorker()) + } else { + return Promise.resolve(this.serviceWorker.ready) + } + } + + registerWorker () { + return this.serviceWorker.register(this.fileName, this.registerOpts) + .then(sw => { + return sw + }) + } + + syncSW (registeredSW) { + return registeredSW.sync.register('sync') + .then(() => { + console.log('sync') + }) + } + + sendMessage (message) { + const self = this + return new Promise((resolve, reject) => { + var messageChannel = new MessageChannel() + messageChannel.port1.onmessage = (event) => { + if (event.data.err) { + reject(event.data.error) + } else { + resolve(event.data.data) + } + } + self.serviceWorker.controller.postMessage(message, [messageChannel.port2]) + }) + } +} diff --git a/library/sw-core.js b/library/sw-core.js new file mode 100644 index 000000000..e018dff0f --- /dev/null +++ b/library/sw-core.js @@ -0,0 +1,203 @@ +global.window = global +const SWGlobal = self +const urlUtil = require('url') +const endOfStream = require('end-of-stream') +const asyncQ = require('async-q') +const pipe = require('pump') +// const ParentStream = require('iframe-stream').ParentStream +const setupMultiplex = require('../app/scripts/lib/stream-utils.js').setupMultiplex +const PortStream = require('../app/scripts/lib/port-stream.js') +// const notification = require('../app/scripts/lib/notifications.js') + +const DbController = require('./controllers/index-db-controller') + +// // all this will go in service worker +const MetamaskController = require('../app/scripts/metamask-controller') +// const extension = require('../app/scripts/lib/extension') +// const LocalStorageStore = require('obs-store/lib/localStorage') +const storeTransform = require('obs-store/lib/transform') +const Migrator = require('../app/scripts/lib/migrator/') +const migrations = require('../app/scripts/migrations/') +const firstTimeState = require('../app/scripts/first-time-state') + +const STORAGE_KEY = 'metamask-config' +const METAMASK_DEBUG = 'GULP_METAMASK_DEBUG' +let popupIsOpen = false + +self.addEventListener('install', function(event) { + event.waitUntil(self.skipWaiting()) +}) +self.addEventListener('activate', function(event) { + event.waitUntil(self.clients.claim()) +}) + +self.onsync = function (syncEvent) { +// What is done when a sync even is fired + console.log('inside:sync') + var focused + self.clients.matchAll() + .then(clients => { + clients.forEach(function(client) { + + }) + }) +} + + + +console.log('inside:open') + + +// // state persistence +let diskStore +const dbController = new DbController({ + key: STORAGE_KEY, + global: self, + version: 6, + initialState: { + dataStore: { + meta: 2, + data: firstTimeState, + }, + }, +}) +asyncQ.waterfall([ + () => loadStateFromPersistence(), + (initState) => setupController(initState), +]) +.then(() => console.log('MetaMask initialization complete.')) +.catch((err) => { + console.log('WHILE SETTING UP:') + console.error(err) +}) + +// initialization flow + +// +// State and Persistence +// +function loadStateFromPersistence() { + // migrations + let migrator = new Migrator({ migrations }) + const initialState = migrator.generateInitialState(firstTimeState) + dbController.initialState = initialState + return dbController.open() + .then((stuff) => { + return dbController.get('dataStore') + }) + .then((data) => { + if (!data) { + return dbController._add('dataStore', initialState) + .then(() => dbController.get('dataStore')) + .then((versionedData) => Promise.resolve(versionedData.data)) + } + + return Promise.resolve(data.data) + }) + .catch((err) => console.error(err)) + + // return asyncQ.waterfall([ + // // read from disk + // () => Promise.resolve(diskStore || initialState), + // // migrate data + // (versionedData) => migrator.migrateData(versionedData), + // // write to disk + // (versionedData) => { + // diskStore.put(versionedData) + // return Promise.resolve(versionedData) + // }, + // // resolve to just data + // (versionedData) => Promise.resolve(versionedData.data), + // ]) +} + +function setupController (initState, client) { + + // + // MetaMask Controller + // + + const controller = new MetamaskController({ + // User confirmation callbacks: + showUnconfirmedMessage: triggerUi, + unlockAccountMessage: triggerUi, + showUnapprovedTx: triggerUi, + // initial state + initState, + }) + global.metamaskController = controller + + // setup state persistence + pipe( + controller.store, + storeTransform(versionifyData), + diskStore + ) + + function versionifyData(state) { + let versionedData = diskStore.getState() + versionedData.data = state + return versionedData + } + + // + // connect to other contexts + // + var connectionStream //= new ParentStream() + SWGlobal.onmessage = (message) => { + + debugger + connectRemote(connectionStream, message.origin) + } + + connectRemote(connectionStream, client.origin) + + function connectRemote (connectionStream, originDomain) { + var isMetaMaskInternalProcess = (originDomain === 'http://localhost:9001') + if (isMetaMaskInternalProcess) { + // communication with popup + controller.setupTrustedCommunication(connectionStream, 'MetaMask') + } else { + // communication with page + setupUntrustedCommunication(connectionStream, originDomain) + } + } + + function setupUntrustedCommunication (connectionStream, originDomain) { + // setup multiplexing + var mx = setupMultiplex(connectionStream) + // connect features + controller.setupProviderConnection(mx.createStream('provider'), originDomain) + controller.setupPublicConfig(mx.createStream('publicConfig')) + } + + function setupTrustedCommunication (connectionStream, originDomain) { + // setup multiplexing + var mx = setupMultiplex(connectionStream) + // connect features + controller.setupProviderConnection(mx.createStream('provider'), originDomain) + } + // + // User Interface setup + // + return Promise.resolve() + +} + +// // // +// // // Etc... +// // // + +// // // popup trigger +function triggerUi () { + if (!popupIsOpen) notification.show() +} + +// function getParentHref(){ +// try { +// var parentLocation = window.parent.location +// return parentLocation.hostname + ':' + parentLocation.port +// } catch (err) { +// return 'unknown' +// } +// } -- cgit From 60f00a950cbe90edda4d9de4a67c3e0c528f6638 Mon Sep 17 00:00:00 2001 From: frankiebee Date: Thu, 9 Mar 2017 21:53:49 -0800 Subject: notes and clean up --- library/controller.js | 162 ----------------------------- library/controllers/index-db-controller.js | 4 - library/sw-core.js | 20 ++-- 3 files changed, 7 insertions(+), 179 deletions(-) diff --git a/library/controller.js b/library/controller.js index ba97da93c..bad8d33cd 100644 --- a/library/controller.js +++ b/library/controller.js @@ -1,165 +1,3 @@ -/* -const urlUtil = require('url') -const extend = require('xtend') -const Dnode = require('dnode') -const eos = require('end-of-stream') -const ParentStream = require('iframe-stream').ParentStream -const PortStream = require('../app/scripts/lib/port-stream.js') -const notification = require('../app/scripts/lib/notifications.js') -const messageManager = require('../app/scripts/lib/message-manager') -const setupMultiplex = require('../app/scripts/lib/stream-utils.js').setupMultiplex -const MetamaskController = require('../app/scripts/metamask-controller') -const extension = require('../app/scripts/lib/extension') - -const STORAGE_KEY = 'metamask-config' - - -initializeZeroClient() - -function initializeZeroClient() { - - const controller = new MetamaskController({ - // User confirmation callbacks: - showUnconfirmedMessage, - unlockAccountMessage, - showUnapprovedTx, - // Persistence Methods: - setData, - loadData, - }) - const idStore = controller.idStore - - function unlockAccountMessage () { - console.log('notif stub - unlockAccountMessage') - } - - function showUnconfirmedMessage (msgParams, msgId) { - console.log('notif stub - showUnconfirmedMessage') - } - - function showUnapprovedTx (txParams, txData, onTxDoneCb) { - console.log('notif stub - showUnapprovedTx') - } - - // - // connect to other contexts - // - - var connectionStream = new ParentStream() - - connectRemote(connectionStream, getParentHref()) - - function connectRemote (connectionStream, originDomain) { - var isMetaMaskInternalProcess = (originDomain === '127.0.0.1:9001') - if (isMetaMaskInternalProcess) { - // communication with popup - setupTrustedCommunication(connectionStream, 'MetaMask') - } else { - // communication with page - setupUntrustedCommunication(connectionStream, originDomain) - } - } - - function setupUntrustedCommunication (connectionStream, originDomain) { - // setup multiplexing - var mx = setupMultiplex(connectionStream) - // connect features - controller.setupProviderConnection(mx.createStream('provider'), originDomain) - controller.setupPublicConfig(mx.createStream('publicConfig')) - } - - function setupTrustedCommunication (connectionStream, originDomain) { - // setup multiplexing - var mx = setupMultiplex(connectionStream) - // connect features - setupControllerConnection(mx.createStream('controller')) - controller.setupProviderConnection(mx.createStream('provider'), originDomain) - } - - // - // remote features - // - - function setupControllerConnection (stream) { - controller.stream = stream - var api = controller.getApi() - var dnode = Dnode(api) - stream.pipe(dnode).pipe(stream) - dnode.on('remote', (remote) => { - // push updates to popup - controller.ethStore.on('update', controller.sendUpdate.bind(controller)) - controller.listeners.push(remote) - idStore.on('update', controller.sendUpdate.bind(controller)) - - // teardown on disconnect - eos(stream, () => { - controller.ethStore.removeListener('update', controller.sendUpdate.bind(controller)) - }) - }) - } - - function loadData () { - var oldData = getOldStyleData() - var newData - try { - newData = JSON.parse(window.localStorage[STORAGE_KEY]) - } catch (e) {} - - var data = extend({ - meta: { - version: 0, - }, - data: { - config: { - provider: { - type: 'testnet', - }, - }, - }, - }, oldData || null, newData || null) - return data - } - - function getOldStyleData () { - var config, wallet, seedWords - - var result = { - meta: { version: 0 }, - data: {}, - } - - try { - config = JSON.parse(window.localStorage['config']) - result.data.config = config - } catch (e) {} - try { - wallet = JSON.parse(window.localStorage['lightwallet']) - result.data.wallet = wallet - } catch (e) {} - try { - seedWords = window.localStorage['seedWords'] - result.data.seedWords = seedWords - } catch (e) {} - - return result - } - - function setData (data) { - window.localStorage[STORAGE_KEY] = JSON.stringify(data) - } - - function getParentHref(){ - try { - var parentLocation = window.parent.location - return parentLocation.hostname + ':' + parentLocation.port - } catch (err) { - return 'unknown' - } - } - -} - -*/ const SWcontroller = require('./sw-controller') console.log('outside:open') const background = new SWcontroller({ diff --git a/library/controllers/index-db-controller.js b/library/controllers/index-db-controller.js index 8b90db066..4c53e1094 100644 --- a/library/controllers/index-db-controller.js +++ b/library/controllers/index-db-controller.js @@ -72,11 +72,7 @@ module.exports = class IndexDbController extends EventEmitter { } migrate () { - // this.migrations - // Place holder for future migrations eg: - this.db.deleteObjectStore('meta') - this.db.deleteObjectStore('data') this.db.createObjectStore('dataStore') } diff --git a/library/sw-core.js b/library/sw-core.js index e018dff0f..1afcc3cff 100644 --- a/library/sw-core.js +++ b/library/sw-core.js @@ -11,7 +11,6 @@ const PortStream = require('../app/scripts/lib/port-stream.js') const DbController = require('./controllers/index-db-controller') -// // all this will go in service worker const MetamaskController = require('../app/scripts/metamask-controller') // const extension = require('../app/scripts/lib/extension') // const LocalStorageStore = require('obs-store/lib/localStorage') @@ -53,7 +52,7 @@ let diskStore const dbController = new DbController({ key: STORAGE_KEY, global: self, - version: 6, + version: 2, initialState: { dataStore: { meta: 2, @@ -95,6 +94,9 @@ function loadStateFromPersistence() { return Promise.resolve(data.data) }) .catch((err) => console.error(err)) + /* + need to get migrations working + */ // return asyncQ.waterfall([ // // read from disk @@ -143,10 +145,11 @@ function setupController (initState, client) { // // connect to other contexts // + /* + need to write a service worker stream for this + */ var connectionStream //= new ParentStream() SWGlobal.onmessage = (message) => { - - debugger connectRemote(connectionStream, message.origin) } @@ -192,12 +195,3 @@ function setupController (initState, client) { function triggerUi () { if (!popupIsOpen) notification.show() } - -// function getParentHref(){ -// try { -// var parentLocation = window.parent.location -// return parentLocation.hostname + ':' + parentLocation.port -// } catch (err) { -// return 'unknown' -// } -// } -- cgit From d4e8ff188bc82a974fd0a767c2676d4a4b9747b4 Mon Sep 17 00:00:00 2001 From: frankiebee Date: Tue, 21 Mar 2017 15:35:01 -0700 Subject: WIP:stream --- library/controllers/index-db-controller.js | 9 ++++----- library/sw-core.js | 15 ++++++++------- package.json | 1 + 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/library/controllers/index-db-controller.js b/library/controllers/index-db-controller.js index 4c53e1094..3373de113 100644 --- a/library/controllers/index-db-controller.js +++ b/library/controllers/index-db-controller.js @@ -5,9 +5,9 @@ module.exports = class IndexDbController extends EventEmitter { super() this.migrations = opts.migrations this.key = opts.key - this.dbObject = opts.global.indexedDB - this.IDBTransaction = opts.global.IDBTransaction || opts.global.webkitIDBTransaction || opts.global.msIDBTransaction || {READ_WRITE: "readwrite"}; // This line should only be needed if it is needed to support the object's constants for older browsers - this.IDBKeyRange = opts.global.IDBKeyRange || opts.global.webkitIDBKeyRange || opts.global.msIDBKeyRange; + this.dbObject = global.indexedDB + this.IDBTransaction = global.IDBTransaction || global.webkitIDBTransaction || global.msIDBTransaction || {READ_WRITE: "readwrite"}; // This line should only be needed if it is needed to support the object's constants for older browsers + this.IDBKeyRange = global.IDBKeyRange || global.webkitIDBKeyRange || global.msIDBKeyRange; this.version = opts.version this.logging = opts.logging this.initialState = opts.initialState @@ -72,8 +72,7 @@ module.exports = class IndexDbController extends EventEmitter { } migrate () { - // Place holder for future migrations eg: - this.db.createObjectStore('dataStore') + this.db.createObjectStore(this.name) } _add (key, objStore, cb = logger) { diff --git a/library/sw-core.js b/library/sw-core.js index 1afcc3cff..41fce637f 100644 --- a/library/sw-core.js +++ b/library/sw-core.js @@ -4,7 +4,9 @@ const urlUtil = require('url') const endOfStream = require('end-of-stream') const asyncQ = require('async-q') const pipe = require('pump') -// const ParentStream = require('iframe-stream').ParentStream + +const SwGlobalListener = require('sw-stream/lib/sw-global-listener.js') +const connectionListener = new SwGlobalListener(self) const setupMultiplex = require('../app/scripts/lib/stream-utils.js').setupMultiplex const PortStream = require('../app/scripts/lib/port-stream.js') // const notification = require('../app/scripts/lib/notifications.js') @@ -148,12 +150,11 @@ function setupController (initState, client) { /* need to write a service worker stream for this */ - var connectionStream //= new ParentStream() - SWGlobal.onmessage = (message) => { - connectRemote(connectionStream, message.origin) - } - - connectRemote(connectionStream, client.origin) + // var connectionStream = new ParentStream() + connectionListener.on('remote', (portStream, messageEvent) => { + debugger + connectRemote(connectionStream, messageEvent.origin) + }) function connectRemote (connectionStream, originDomain) { var isMetaMaskInternalProcess = (originDomain === 'http://localhost:9001') diff --git a/package.json b/package.json index 96d58fa1b..30e89356f 100644 --- a/package.json +++ b/package.json @@ -104,6 +104,7 @@ "request-promise": "^4.1.1", "sandwich-expando": "^1.0.5", "semaphore": "^1.0.5", + "sw-stream": "^1.0.1", "textarea-caret": "^3.0.1", "three.js": "^0.73.2", "through2": "^2.0.1", -- cgit From 45ab81fb45ec1043d617f66c308e2e7911c8e0ad Mon Sep 17 00:00:00 2001 From: frankiebee Date: Thu, 23 Mar 2017 11:06:38 -0700 Subject: WIP: streams->indexdb --- app/scripts/metamask-controller.js | 1 - app/scripts/popup-core.js | 1 + library/controller.js | 30 +++++++---------- library/lib/setup-iframe.js | 1 + library/popup.js | 18 ++++++++-- library/server.js | 2 +- library/sw-controller.js | 67 +++++++++++++++++++++++++++----------- library/sw-core.js | 24 +++++++++----- package.json | 4 +-- ui/index.js | 2 +- 10 files changed, 96 insertions(+), 54 deletions(-) diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 536891dc6..a26c0e45d 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -204,7 +204,6 @@ module.exports = class MetamaskController extends EventEmitter { // getState () { - const wallet = this.configManager.getWallet() const vault = this.keyringController.store.getState().vault const isInitialized = (!!wallet || !!vault) diff --git a/app/scripts/popup-core.js b/app/scripts/popup-core.js index b1e521a7a..7ade66922 100644 --- a/app/scripts/popup-core.js +++ b/app/scripts/popup-core.js @@ -11,6 +11,7 @@ module.exports = initializePopup function initializePopup (connectionStream) { // setup app + debugger connectToAccountManager(connectionStream, setupApp) } diff --git a/library/controller.js b/library/controller.js index bad8d33cd..f0aa7172c 100644 --- a/library/controller.js +++ b/library/controller.js @@ -1,19 +1,13 @@ -const SWcontroller = require('./sw-controller') -console.log('outside:open') -const background = new SWcontroller({ - fileName: 'sw-build.js', - registerOpts: { - scope: './', - } -}) +// const SWcontroller = require('./sw-controller') +// const SwStream = require('sw-stream/lib/sw-stream.js') +// const startPopup = require('../app/scripts/popup-core') -background.startWorker() -.then(registerdWorker => { - return background.sendMessage('connect') -}) -.then((port) => { - debugger -}) -.catch(err => { - console.error(`SW Controller: ${err}`) -}) +// console.log('outside:open') +// const background = new SWcontroller({ +// fileName: 'sw-build.js', +// }) +// background.on('ready', (readSw) => { +// startPopup(SwStream(background.controller)) +// }) +// background.startWorker() +console.log('hello from controller') diff --git a/library/lib/setup-iframe.js b/library/lib/setup-iframe.js index db67163df..0aa001dcf 100644 --- a/library/lib/setup-iframe.js +++ b/library/lib/setup-iframe.js @@ -5,6 +5,7 @@ module.exports = setupIframe function setupIframe(opts) { + debugger opts = opts || {} var frame = Iframe({ src: opts.zeroClientProvider || 'https://zero.metamask.io/', diff --git a/library/popup.js b/library/popup.js index 59b70edbb..3825661cf 100644 --- a/library/popup.js +++ b/library/popup.js @@ -1,7 +1,10 @@ const injectCss = require('inject-css') const MetaMaskUiCss = require('../ui/css') -const startPopup = require('../app/scripts/popup-core') const setupIframe = require('./lib/setup-iframe.js') +const MetamaskInpageProvider = require('../app/scripts/lib/inpage-provider.js') +const SWcontroller = require('./sw-controller') +const SwStream = require('sw-stream/lib/sw-stream.js') +const startPopup = require('../app/scripts/popup-core') var css = MetaMaskUiCss() @@ -15,5 +18,14 @@ var iframeStream = setupIframe({ sandboxAttributes: ['allow-scripts', 'allow-popups', 'allow-same-origin'], container: document.body, }) - -startPopup(iframeStream) +console.log('outside:open') +const background = new SWcontroller({ + fileName: '/popup/sw-build.js', +}) +background.on('ready', (readSw) => { + // var inpageProvider = new MetamaskInpageProvider(SwStream(background.controller)) + // startPopup(inpageProvider) + startPopup(SwStream(background.controller)) +}) +background.startWorker() +console.log('hello from /library/popup.js') diff --git a/library/server.js b/library/server.js index b9f59c2a1..a284d3e05 100644 --- a/library/server.js +++ b/library/server.js @@ -25,7 +25,7 @@ iframeServer.use('/popup', express.static('../dist/chrome')) iframeServer.get('/controller.js', function(req, res){ res.send(controllerBundle.latest) }) -iframeServer.get('/sw-build.js', function(req, res){ +iframeServer.get('/popup/sw-build.js', function(req, res){ console.log('/sw-build.js') res.setHeader('Content-Type', 'application/javascript') res.send(swBuild.latest) diff --git a/library/sw-controller.js b/library/sw-controller.js index d5065a933..23d67026e 100644 --- a/library/sw-controller.js +++ b/library/sw-controller.js @@ -1,34 +1,63 @@ const EventEmitter = require('events') -module.exports = class serviceWorkerController extends EventEmitter{ +module.exports = class ClientSideServiceWorker extends EventEmitter{ constructor (opts) { super() this.fileName = opts.fileName - this.registerOpts = opts.registerOpts - this.serviceWorker = navigator.serviceWorker - } + this.startDelay = opts.startDelay + this.serviceWorkerApi = navigator.serviceWorker + this.serviceWorkerApi.onmessage = (event) => this.emit('message', event) + this.serviceWorkerApi.onerror = (event) => this.emit('error') - startWorker () { - // check to see if their is a preregistered service worker - if (!this.serviceWorker.controller) { - return Promise.resolve(this.registerWorker()) - } else { - return Promise.resolve(this.serviceWorker.ready) + // temporary function + this.askForId = (message) => { + this.sendMessage('check-in') + .then((data) => console.log(`${message}----${data}`)) } + + // if (!!this.serviceWorkerApi) this.askForId('before') + + if (opts.initStart) this.startWorker() + + this.on('ready', (sw) => { + this.askForId('ready') + }) } - registerWorker () { - return this.serviceWorker.register(this.fileName, this.registerOpts) - .then(sw => { - return sw + get controller () { + return this.sw || this.serviceWorkerApi.controller + } + + + startWorker () { + return this.registerWorker() + .then((sw) => { + this.sw = sw + this.askForId('after register:') + this.sw.onerror = (err) => this.emit('error', err) + this.sw = sw + this.emit('ready', this.sw) }) + .catch((err) => this.emit('error', err)) } - syncSW (registeredSW) { - return registeredSW.sync.register('sync') - .then(() => { - console.log('sync') + registerWorker () { + return this.serviceWorkerApi.register(this.fileName) + .then((registerdWorker) => { + return new Promise((resolve, reject) => { + this.askForId('after') + let timeOutId = setTimeout(() => { + if (this.serviceWorkerApi.controller) return resolve(this.serviceWorkerApi.controller) + if (registerdWorker.active) return resolve(registerdWorker.active) + return reject(new Error('ClientSideServiceWorker: No controller found and onupdatefound timed out')) + }, this.startDelay || 1000 ) + + registerdWorker.onupdatefound = (event) => { + this.emit('updatefound') + registerdWorker.update() + } + }) }) } @@ -43,7 +72,7 @@ module.exports = class serviceWorkerController extends EventEmitter{ resolve(event.data.data) } } - self.serviceWorker.controller.postMessage(message, [messageChannel.port2]) + this.controller.postMessage(message, [messageChannel.port2]) }) } } diff --git a/library/sw-core.js b/library/sw-core.js index 41fce637f..9ceaf1dc5 100644 --- a/library/sw-core.js +++ b/library/sw-core.js @@ -25,6 +25,10 @@ const STORAGE_KEY = 'metamask-config' const METAMASK_DEBUG = 'GULP_METAMASK_DEBUG' let popupIsOpen = false +const log = require('loglevel') +global.log = log +log.setDefaultLevel(METAMASK_DEBUG ? 'debug' : 'warn') + self.addEventListener('install', function(event) { event.waitUntil(self.skipWaiting()) }) @@ -132,12 +136,16 @@ function setupController (initState, client) { global.metamaskController = controller // setup state persistence - pipe( - controller.store, - storeTransform(versionifyData), - diskStore - ) - + // pipe( + // controller.store, + // storeTransform(versionifyData), + // diskStore + // ) + controller.store.subscribe((store) => { + dbController.put('dataStore', store) + // .then((event) => {debugger}) + // .catch((err) => {debugger}) + }) function versionifyData(state) { let versionedData = diskStore.getState() versionedData.data = state @@ -150,10 +158,8 @@ function setupController (initState, client) { /* need to write a service worker stream for this */ - // var connectionStream = new ParentStream() connectionListener.on('remote', (portStream, messageEvent) => { - debugger - connectRemote(connectionStream, messageEvent.origin) + connectRemote(portStream, messageEvent.origin) }) function connectRemote (connectionStream, originDomain) { diff --git a/package.json b/package.json index 30e89356f..1d19d5e75 100644 --- a/package.json +++ b/package.json @@ -104,14 +104,14 @@ "request-promise": "^4.1.1", "sandwich-expando": "^1.0.5", "semaphore": "^1.0.5", - "sw-stream": "^1.0.1", + "sw-stream": "^1.0.2", "textarea-caret": "^3.0.1", "three.js": "^0.73.2", "through2": "^2.0.1", "valid-url": "^1.0.9", "vreme": "^3.0.2", "web3": "0.18.2", - "web3-provider-engine": "^10.0.1", + "web3-provider-engine": "^11.0.0", "web3-stream-provider": "^2.0.6", "xtend": "^4.0.1" }, diff --git a/ui/index.js b/ui/index.js index 1a65f813c..932054027 100644 --- a/ui/index.js +++ b/ui/index.js @@ -14,7 +14,7 @@ log.setLevel(debugMode ? 'debug' : 'warn') function launchApp (opts) { var accountManager = opts.accountManager actions._setBackgroundConnection(accountManager) - + debugger // check if we are unlocked first accountManager.getState(function (err, metamaskState) { if (err) throw err -- cgit From 197e6e0b77868b0bec76cef303b2eeffda5797bf Mon Sep 17 00:00:00 2001 From: frankiebee Date: Thu, 23 Mar 2017 11:41:32 -0700 Subject: WIP: indexdb is at an err state "provider is undefined" --- app/scripts/popup-core.js | 1 - library/controllers/index-db-controller.js | 32 ++++++++++++++++++++++-------- library/lib/setup-iframe.js | 1 - library/sw-core.js | 4 ++-- ui/index.js | 1 - 5 files changed, 26 insertions(+), 13 deletions(-) diff --git a/app/scripts/popup-core.js b/app/scripts/popup-core.js index 7ade66922..b1e521a7a 100644 --- a/app/scripts/popup-core.js +++ b/app/scripts/popup-core.js @@ -11,7 +11,6 @@ module.exports = initializePopup function initializePopup (connectionStream) { // setup app - debugger connectToAccountManager(connectionStream, setupApp) } diff --git a/library/controllers/index-db-controller.js b/library/controllers/index-db-controller.js index 3373de113..f7225c00b 100644 --- a/library/controllers/index-db-controller.js +++ b/library/controllers/index-db-controller.js @@ -51,19 +51,35 @@ module.exports = class IndexDbController extends EventEmitter { return this.requestObjectStore(key) .then((dataObject)=> { return new Promise((resolve, reject) => { - const getRequest = dataObject.get(key) - getRequest.onsuccess = (event) => resolve(event.currentTarget.result) - getRequest.onerror = (event) => reject(event) + const getRequest = dataObject.get(key) + getRequest.onsuccess = (event) => { + const serialized = event.currentTarget.result + try { + console.log('serialized:',serialized) + const state = serialized ? JSON.parse(serialized) : {} + resolve(state) + } catch (err) { + reject(err) + } + } + getRequest.onerror = (event) => reject(event) + }) }) - }) } - put (key, store) { + put (key, state) { return this.requestObjectStore(key, 'readwrite') .then((dataObject)=> { - const putRequest = dataObject.put(store) - putRequest.onsuccess = (event) => Promise.resolve(event.currentTarget.result) - putRequest.onerror = (event) => Promise.reject(event) + return new Promise((resolve, reject) => { + try { + const serialized = JSON.stringify(state) + const putRequest = dataObject.put(serialized) + putRequest.onsuccess = (event) => resolve(event.currentTarget.result) + putRequest.onerror = (event) => reject(event) + } catch (err) { + reject(err) + } + }) }) } diff --git a/library/lib/setup-iframe.js b/library/lib/setup-iframe.js index 0aa001dcf..db67163df 100644 --- a/library/lib/setup-iframe.js +++ b/library/lib/setup-iframe.js @@ -5,7 +5,6 @@ module.exports = setupIframe function setupIframe(opts) { - debugger opts = opts || {} var frame = Iframe({ src: opts.zeroClientProvider || 'https://zero.metamask.io/', diff --git a/library/sw-core.js b/library/sw-core.js index 9ceaf1dc5..60fc88039 100644 --- a/library/sw-core.js +++ b/library/sw-core.js @@ -141,8 +141,8 @@ function setupController (initState, client) { // storeTransform(versionifyData), // diskStore // ) - controller.store.subscribe((store) => { - dbController.put('dataStore', store) + controller.store.subscribe((state) => { + dbController.put('dataStore', state) // .then((event) => {debugger}) // .catch((err) => {debugger}) }) diff --git a/ui/index.js b/ui/index.js index 932054027..16875fce4 100644 --- a/ui/index.js +++ b/ui/index.js @@ -14,7 +14,6 @@ log.setLevel(debugMode ? 'debug' : 'warn') function launchApp (opts) { var accountManager = opts.accountManager actions._setBackgroundConnection(accountManager) - debugger // check if we are unlocked first accountManager.getState(function (err, metamaskState) { if (err) throw err -- cgit From 412cc2394a89a3ba1c0ca82cecf03c29254b7381 Mon Sep 17 00:00:00 2001 From: frankiebee Date: Thu, 23 Mar 2017 14:22:05 -0700 Subject: Get mascara to send a transaction in the ui --- app/scripts/popup-core.js | 1 - library/controllers/index-db-controller.js | 12 ++++-------- library/lib/setup-iframe.js | 1 - library/sw-core.js | 14 +++++++------- ui/index.js | 1 - 5 files changed, 11 insertions(+), 18 deletions(-) diff --git a/app/scripts/popup-core.js b/app/scripts/popup-core.js index 7ade66922..b1e521a7a 100644 --- a/app/scripts/popup-core.js +++ b/app/scripts/popup-core.js @@ -11,7 +11,6 @@ module.exports = initializePopup function initializePopup (connectionStream) { // setup app - debugger connectToAccountManager(connectionStream, setupApp) } diff --git a/library/controllers/index-db-controller.js b/library/controllers/index-db-controller.js index 3373de113..bf840b98a 100644 --- a/library/controllers/index-db-controller.js +++ b/library/controllers/index-db-controller.js @@ -58,21 +58,17 @@ module.exports = class IndexDbController extends EventEmitter { }) } - put (key, store) { - return this.requestObjectStore(key, 'readwrite') + put (state) { + return this.requestObjectStore('dataStore', 'readwrite') .then((dataObject)=> { - const putRequest = dataObject.put(store) + const putRequest = dataObject.put(state, 'dataStore') putRequest.onsuccess = (event) => Promise.resolve(event.currentTarget.result) putRequest.onerror = (event) => Promise.reject(event) }) } - update (key, value) { - - } - migrate () { - this.db.createObjectStore(this.name) + this.db.createObjectStore('dataStore') } _add (key, objStore, cb = logger) { diff --git a/library/lib/setup-iframe.js b/library/lib/setup-iframe.js index 0aa001dcf..db67163df 100644 --- a/library/lib/setup-iframe.js +++ b/library/lib/setup-iframe.js @@ -5,7 +5,6 @@ module.exports = setupIframe function setupIframe(opts) { - debugger opts = opts || {} var frame = Iframe({ src: opts.zeroClientProvider || 'https://zero.metamask.io/', diff --git a/library/sw-core.js b/library/sw-core.js index 9ceaf1dc5..3972e361b 100644 --- a/library/sw-core.js +++ b/library/sw-core.js @@ -87,7 +87,7 @@ function loadStateFromPersistence() { const initialState = migrator.generateInitialState(firstTimeState) dbController.initialState = initialState return dbController.open() - .then((stuff) => { + .then((openRequest) => { return dbController.get('dataStore') }) .then((data) => { @@ -141,14 +141,14 @@ function setupController (initState, client) { // storeTransform(versionifyData), // diskStore // ) - controller.store.subscribe((store) => { - dbController.put('dataStore', store) - // .then((event) => {debugger}) - // .catch((err) => {debugger}) + controller.store.subscribe((state) => { + dbController.put(versionifyData(controller.store)) + .catch((err) => {console.error(err)}) }) function versionifyData(state) { - let versionedData = diskStore.getState() - versionedData.data = state + // let versionedData = diskStore.getState() + // versionedData.data = state + let versionedData = {data: state} return versionedData } diff --git a/ui/index.js b/ui/index.js index 932054027..16875fce4 100644 --- a/ui/index.js +++ b/ui/index.js @@ -14,7 +14,6 @@ log.setLevel(debugMode ? 'debug' : 'warn') function launchApp (opts) { var accountManager = opts.accountManager actions._setBackgroundConnection(accountManager) - debugger // check if we are unlocked first accountManager.getState(function (err, metamaskState) { if (err) throw err -- cgit From 445159386798579f3ed449b8bc4efa00f52a26ac Mon Sep 17 00:00:00 2001 From: frankiebee Date: Thu, 23 Mar 2017 14:35:01 -0700 Subject: Clean up messy merge --- library/controllers/index-db-controller.js | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/library/controllers/index-db-controller.js b/library/controllers/index-db-controller.js index 4c03eca46..6bcae9845 100644 --- a/library/controllers/index-db-controller.js +++ b/library/controllers/index-db-controller.js @@ -50,18 +50,9 @@ module.exports = class IndexDbController extends EventEmitter { get (key) { return this.requestObjectStore(key) .then((dataObject)=> { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { const getRequest = dataObject.get(key) - getRequest.onsuccess = (event) => { - const serialized = event.currentTarget.result - try { - console.log('serialized:',serialized) - const state = serialized ? JSON.parse(serialized) : {} - resolve(state) - } catch (err) { - reject(err) - } - } + getRequest.onsuccess = (event) => resolve(event.currentTarget.result) getRequest.onerror = (event) => reject(event) }) }) -- cgit From c8540261c1c9b60c98845bdd19095efc064fdde8 Mon Sep 17 00:00:00 2001 From: frankiebee Date: Thu, 23 Mar 2017 15:12:39 -0700 Subject: Fix state persistence --- library/sw-core.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/sw-core.js b/library/sw-core.js index 3972e361b..8c7de2c32 100644 --- a/library/sw-core.js +++ b/library/sw-core.js @@ -142,7 +142,7 @@ function setupController (initState, client) { // diskStore // ) controller.store.subscribe((state) => { - dbController.put(versionifyData(controller.store)) + dbController.put(versionifyData(state)) .catch((err) => {console.error(err)}) }) function versionifyData(state) { -- cgit From 282775c52f558bbd90d4d0a1706a835dde6c3202 Mon Sep 17 00:00:00 2001 From: frankiebee Date: Thu, 23 Mar 2017 19:14:08 -0700 Subject: add versioning and migrateing data --- library/controllers/index-db-controller.js | 25 +++++++------- library/sw-core.js | 54 +++++++++--------------------- 2 files changed, 28 insertions(+), 51 deletions(-) diff --git a/library/controllers/index-db-controller.js b/library/controllers/index-db-controller.js index 6bcae9845..041ddae2e 100644 --- a/library/controllers/index-db-controller.js +++ b/library/controllers/index-db-controller.js @@ -23,20 +23,25 @@ module.exports = class IndexDbController extends EventEmitter { } dbOpenRequest.onsuccess = (event) => { this.db = dbOpenRequest.result - if (!this.db.objectStoreNames.length) { - Object.keys(this.initialState).forEach((key) => { - this._add(key, this.initialState[key]) - }) - } this.emit('success') resolve(this.db) } dbOpenRequest.onupgradeneeded = (event) => { - // if (this.migrators) this.db = event.target.result - this.migrate() + this.db.createObjectStore('dataStore') } }) + .then((openRequest) => { + return this.get('dataStore') + }) + .then((data) => { + if (!data) { + return this._add('dataStore', this.initialState) + .then(() => this.get('dataStore')) + .then((versionedData) => Promise.resolve(versionedData.data)) + } + return Promise.resolve(data) + }) } requestObjectStore (key, type = 'readonly') { @@ -47,7 +52,7 @@ module.exports = class IndexDbController extends EventEmitter { }) } - get (key) { + get (key = 'dataStore') { return this.requestObjectStore(key) .then((dataObject)=> { return new Promise((resolve, reject) => { @@ -67,10 +72,6 @@ module.exports = class IndexDbController extends EventEmitter { }) } - migrate () { - this.db.createObjectStore('dataStore') - } - _add (key, objStore, cb = logger) { return this.requestObjectStore(key, 'readwrite') .then((dataObject)=> { diff --git a/library/sw-core.js b/library/sw-core.js index 8c7de2c32..46ef95e21 100644 --- a/library/sw-core.js +++ b/library/sw-core.js @@ -59,12 +59,6 @@ const dbController = new DbController({ key: STORAGE_KEY, global: self, version: 2, - initialState: { - dataStore: { - meta: 2, - data: firstTimeState, - }, - }, }) asyncQ.waterfall([ () => loadStateFromPersistence(), @@ -87,36 +81,12 @@ function loadStateFromPersistence() { const initialState = migrator.generateInitialState(firstTimeState) dbController.initialState = initialState return dbController.open() - .then((openRequest) => { - return dbController.get('dataStore') + .then((versionedData) => migrator.migrateData(versionedData)) + .then((versionedData) => { + dbController.put(versionedData) + return Promise.resolve(versionedData) }) - .then((data) => { - if (!data) { - return dbController._add('dataStore', initialState) - .then(() => dbController.get('dataStore')) - .then((versionedData) => Promise.resolve(versionedData.data)) - } - - return Promise.resolve(data.data) - }) - .catch((err) => console.error(err)) - /* - need to get migrations working - */ - - // return asyncQ.waterfall([ - // // read from disk - // () => Promise.resolve(diskStore || initialState), - // // migrate data - // (versionedData) => migrator.migrateData(versionedData), - // // write to disk - // (versionedData) => { - // diskStore.put(versionedData) - // return Promise.resolve(versionedData) - // }, - // // resolve to just data - // (versionedData) => Promise.resolve(versionedData.data), - // ]) + .then((versionedData) => Promise.resolve(versionedData.data)) } function setupController (initState, client) { @@ -142,14 +112,20 @@ function setupController (initState, client) { // diskStore // ) controller.store.subscribe((state) => { - dbController.put(versionifyData(state)) + versionifyData(state) + .then((versionedData) => dbController.put(versionedData)) .catch((err) => {console.error(err)}) }) function versionifyData(state) { - // let versionedData = diskStore.getState() + // let versionedData // versionedData.data = state - let versionedData = {data: state} - return versionedData + return dbController.get() + .then((rawData) => { + return Promise.resolve({ + data: state, + meta: rawData.meta, + })} + ) } // -- cgit From 79248ae5cd3fb1314c5a7ff71c05f9dbe7b3a4cd Mon Sep 17 00:00:00 2001 From: frankiebee Date: Tue, 28 Mar 2017 18:02:08 -0700 Subject: WIP: Untrusted external connections eg: dapps --- library/controller.js | 192 ++++++++++++++++++++++++++++-- library/example/index.js | 4 +- library/index.js | 2 + library/lib/setup-provider.js | 1 - library/lib/setup-untrusted-connection.js | 27 +++++ library/popup.js | 2 + library/sw-controller.js | 20 +--- library/sw-core.js | 25 +--- package.json | 2 +- 9 files changed, 221 insertions(+), 54 deletions(-) create mode 100644 library/lib/setup-untrusted-connection.js diff --git a/library/controller.js b/library/controller.js index f0aa7172c..cbba9584a 100644 --- a/library/controller.js +++ b/library/controller.js @@ -1,13 +1,181 @@ -// const SWcontroller = require('./sw-controller') -// const SwStream = require('sw-stream/lib/sw-stream.js') -// const startPopup = require('../app/scripts/popup-core') - -// console.log('outside:open') -// const background = new SWcontroller({ -// fileName: 'sw-build.js', -// }) -// background.on('ready', (readSw) => { -// startPopup(SwStream(background.controller)) -// }) -// background.startWorker() +const ParentStream = require('iframe-stream').ParentStream +const SWcontroller = require('./sw-controller') +const SwStream = require('sw-stream/lib/sw-stream.js') +const SetupUntrustedComunication = ('./lib/setup-untrusted-connection.js') +const background = new SWcontroller({ + fileName: '/popup/sw-build.js', +}) + +background.on('ready', (readSw) => { + // var inpageProvider = new MetamaskInpageProvider(SwStream(background.controller)) + let pageStream = new ParentStream() + let swStream = SwStream(background.controller) + pageStream.pipe(swStream).pipe(pageStream) +}) + +background.on('error', console.error) +background.startWorker() + console.log('hello from controller') +/* +const urlUtil = require('url') +const extend = require('xtend') +const Dnode = require('dnode') +const eos = require('end-of-stream') +const ParentStream = require('iframe-stream').ParentStream +const PortStream = require('../app/scripts/lib/port-stream.js') +const notification = require('../app/scripts/lib/notifications.js') +const messageManager = require('../app/scripts/lib/message-manager') +const setupMultiplex = require('../app/scripts/lib/stream-utils.js').setupMultiplex +const MetamaskController = require('../app/scripts/metamask-controller') +const extension = require('../app/scripts/lib/extension') + +const STORAGE_KEY = 'metamask-config' + + +initializeZeroClient() + +function initializeZeroClient() { + + const controller = new MetamaskController({ + // User confirmation callbacks: + showUnconfirmedMessage, + unlockAccountMessage, + showUnapprovedTx, + // Persistence Methods: + setData, + loadData, + }) + const idStore = controller.idStore + + function unlockAccountMessage () { + console.log('notif stub - unlockAccountMessage') + } + + function showUnconfirmedMessage (msgParams, msgId) { + console.log('notif stub - showUnconfirmedMessage') + } + + function showUnapprovedTx (txParams, txData, onTxDoneCb) { + console.log('notif stub - showUnapprovedTx') + } + + // + // connect to other contexts + // + + var connectionStream = new ParentStream() + + connectRemote(connectionStream, getParentHref()) + + function connectRemote (connectionStream, originDomain) { + var isMetaMaskInternalProcess = (originDomain === '127.0.0.1:9001') + if (isMetaMaskInternalProcess) { + // communication with popup + setupTrustedCommunication(connectionStream, 'MetaMask') + } else { + // communication with page + setupUntrustedCommunication(connectionStream, originDomain) + } + } + + function setupUntrustedCommunication (connectionStream, originDomain) { + // setup multiplexing + var mx = setupMultiplex(connectionStream) + // connect features + controller.setupProviderConnection(mx.createStream('provider'), originDomain) + controller.setupPublicConfig(mx.createStream('publicConfig')) + } + + function setupTrustedCommunication (connectionStream, originDomain) { + // setup multiplexing + var mx = setupMultiplex(connectionStream) + // connect features + setupControllerConnection(mx.createStream('controller')) + controller.setupProviderConnection(mx.createStream('provider'), originDomain) + } + + // + // remote features + // + + function setupControllerConnection (stream) { + controller.stream = stream + var api = controller.getApi() + var dnode = Dnode(api) + stream.pipe(dnode).pipe(stream) + dnode.on('remote', (remote) => { + // push updates to popup + controller.ethStore.on('update', controller.sendUpdate.bind(controller)) + controller.listeners.push(remote) + idStore.on('update', controller.sendUpdate.bind(controller)) + + // teardown on disconnect + eos(stream, () => { + controller.ethStore.removeListener('update', controller.sendUpdate.bind(controller)) + }) + }) + } + + function loadData () { + var oldData = getOldStyleData() + var newData + try { + newData = JSON.parse(window.localStorage[STORAGE_KEY]) + } catch (e) {} + + var data = extend({ + meta: { + version: 0, + }, + data: { + config: { + provider: { + type: 'testnet', + }, + }, + }, + }, oldData || null, newData || null) + return data + } + + function getOldStyleData () { + var config, wallet, seedWords + + var result = { + meta: { version: 0 }, + data: {}, + } + + try { + config = JSON.parse(window.localStorage['config']) + result.data.config = config + } catch (e) {} + try { + wallet = JSON.parse(window.localStorage['lightwallet']) + result.data.wallet = wallet + } catch (e) {} + try { + seedWords = window.localStorage['seedWords'] + result.data.seedWords = seedWords + } catch (e) {} + + return result + } + + function setData (data) { + window.localStorage[STORAGE_KEY] = JSON.stringify(data) + } + + function getParentHref(){ + try { + var parentLocation = window.parent.location + return parentLocation.hostname + ':' + parentLocation.port + } catch (err) { + return 'unknown' + } + } + +} + +*/ diff --git a/library/example/index.js b/library/example/index.js index 4a107df6a..329302a4d 100644 --- a/library/example/index.js +++ b/library/example/index.js @@ -1,4 +1,3 @@ - window.addEventListener('load', web3Detect) function web3Detect() { @@ -18,6 +17,7 @@ function startApp(){ web3.eth.getAccounts(function(err, addresses){ if (err) throw err console.log('set address', addresses[0]) + debugger primaryAccount = addresses[0] }) @@ -53,4 +53,4 @@ function startApp(){ function logToDom(message){ document.body.appendChild(document.createTextNode(message)) console.log(message) -} \ No newline at end of file +} diff --git a/library/index.js b/library/index.js index af82c6546..44ee401d8 100644 --- a/library/index.js +++ b/library/index.js @@ -41,3 +41,5 @@ function hijackProvider(provider){ _super(payload, cb) } } + + diff --git a/library/lib/setup-provider.js b/library/lib/setup-provider.js index 9efd209cb..68be99c9e 100644 --- a/library/lib/setup-provider.js +++ b/library/lib/setup-provider.js @@ -22,4 +22,3 @@ function getProvider(){ return inpageProvider } - diff --git a/library/lib/setup-untrusted-connection.js b/library/lib/setup-untrusted-connection.js new file mode 100644 index 000000000..b2aeb7905 --- /dev/null +++ b/library/lib/setup-untrusted-connection.js @@ -0,0 +1,27 @@ + +/* +IFRAME + var pageStream = new LocalMessageDuplexStream({ + name: 'contentscript', + target: 'inpage', + }) +SERVICEWORKER + pageStream.on('error', console.error) + var pluginPort = extension.runtime.connect({name: 'contentscript'}) + var pluginStream = new PortStream(pluginPort) + pluginStream.on('error', console.error) +IFRAME --> SW + // forward communication plugin->inpage + pageStream.pipe(pluginStream).pipe(pageStream) +*/ + +module.exports = SetupUntrustedComunicationWithSW + +function SetupUntrustedComunicationWithSW (connectionStream, readySwStream) { + pageStream.on('error', console.error) + var pluginPort = extension.runtime.connect({name: 'contentscript'}) + var pluginStream = new PortStream(pluginPort) + pluginStream.on('error', console.error) + // forward communication plugin->inpage + pageStream.pipe(pluginStream).pipe(pageStream) +} diff --git a/library/popup.js b/library/popup.js index 3825661cf..d956dc0b1 100644 --- a/library/popup.js +++ b/library/popup.js @@ -19,6 +19,7 @@ var iframeStream = setupIframe({ container: document.body, }) console.log('outside:open') + const background = new SWcontroller({ fileName: '/popup/sw-build.js', }) @@ -27,5 +28,6 @@ background.on('ready', (readSw) => { // startPopup(inpageProvider) startPopup(SwStream(background.controller)) }) +background.on('message', (messageEvent) => {debugger}) background.startWorker() console.log('hello from /library/popup.js') diff --git a/library/sw-controller.js b/library/sw-controller.js index 23d67026e..1a7b1cad3 100644 --- a/library/sw-controller.js +++ b/library/sw-controller.js @@ -7,22 +7,10 @@ module.exports = class ClientSideServiceWorker extends EventEmitter{ this.startDelay = opts.startDelay this.serviceWorkerApi = navigator.serviceWorker - this.serviceWorkerApi.onmessage = (event) => this.emit('message', event) - this.serviceWorkerApi.onerror = (event) => this.emit('error') - - // temporary function - this.askForId = (message) => { - this.sendMessage('check-in') - .then((data) => console.log(`${message}----${data}`)) - } - - // if (!!this.serviceWorkerApi) this.askForId('before') - + this.serviceWorkerApi.onmessage = (messageEvent) => this.emit('message', messageEvent) + this.serviceWorkerApi.onerror = (err) => this.emit('error', err) + this.on('message', (messageEvent) => {debugger}) if (opts.initStart) this.startWorker() - - this.on('ready', (sw) => { - this.askForId('ready') - }) } get controller () { @@ -34,7 +22,6 @@ module.exports = class ClientSideServiceWorker extends EventEmitter{ return this.registerWorker() .then((sw) => { this.sw = sw - this.askForId('after register:') this.sw.onerror = (err) => this.emit('error', err) this.sw = sw this.emit('ready', this.sw) @@ -46,7 +33,6 @@ module.exports = class ClientSideServiceWorker extends EventEmitter{ return this.serviceWorkerApi.register(this.fileName) .then((registerdWorker) => { return new Promise((resolve, reject) => { - this.askForId('after') let timeOutId = setTimeout(() => { if (this.serviceWorkerApi.controller) return resolve(this.serviceWorkerApi.controller) if (registerdWorker.active) return resolve(registerdWorker.active) diff --git a/library/sw-core.js b/library/sw-core.js index 46ef95e21..1d31b2acd 100644 --- a/library/sw-core.js +++ b/library/sw-core.js @@ -1,7 +1,4 @@ global.window = global -const SWGlobal = self -const urlUtil = require('url') -const endOfStream = require('end-of-stream') const asyncQ = require('async-q') const pipe = require('pump') @@ -14,7 +11,7 @@ const PortStream = require('../app/scripts/lib/port-stream.js') const DbController = require('./controllers/index-db-controller') const MetamaskController = require('../app/scripts/metamask-controller') -// const extension = require('../app/scripts/lib/extension') +const extension = {} //require('../app/scripts/lib/extension') // const LocalStorageStore = require('obs-store/lib/localStorage') const storeTransform = require('obs-store/lib/transform') const Migrator = require('../app/scripts/lib/migrator/') @@ -36,20 +33,6 @@ self.addEventListener('activate', function(event) { event.waitUntil(self.clients.claim()) }) -self.onsync = function (syncEvent) { -// What is done when a sync even is fired - console.log('inside:sync') - var focused - self.clients.matchAll() - .then(clients => { - clients.forEach(function(client) { - - }) - }) -} - - - console.log('inside:open') @@ -117,8 +100,6 @@ function setupController (initState, client) { .catch((err) => {console.error(err)}) }) function versionifyData(state) { - // let versionedData - // versionedData.data = state return dbController.get() .then((rawData) => { return Promise.resolve({ @@ -143,6 +124,7 @@ function setupController (initState, client) { if (isMetaMaskInternalProcess) { // communication with popup controller.setupTrustedCommunication(connectionStream, 'MetaMask') + popupIsOpen = true } else { // communication with page setupUntrustedCommunication(connectionStream, originDomain) @@ -175,6 +157,7 @@ function setupController (initState, client) { // // // // // // popup trigger + +/*send a message to the client that has focus and tell it to open a window*/ function triggerUi () { - if (!popupIsOpen) notification.show() } diff --git a/package.json b/package.json index c08d92339..cc51ef032 100644 --- a/package.json +++ b/package.json @@ -110,7 +110,7 @@ "valid-url": "^1.0.9", "vreme": "^3.0.2", "web3": "0.18.2", - "web3-provider-engine": "^11.0.0", + "web3-provider-engine": "^11.0.1", "web3-stream-provider": "^2.0.6", "xtend": "^4.0.1" }, -- cgit From 84b3415b4479eb849b69d77a7e178c67fcaaf3fb Mon Sep 17 00:00:00 2001 From: frankiebee Date: Wed, 29 Mar 2017 10:53:43 -0700 Subject: WIP: lost enital call from dapp to getAccounts --- app/scripts/controllers/preferences.js | 1 + app/scripts/metamask-controller.js | 1 + library/controller.js | 12 ++---------- library/example/index.js | 9 +++++---- library/index.js | 5 ++--- library/lib/setup-provider.js | 4 ++-- library/popup.js | 5 ----- library/sw-core.js | 1 + 8 files changed, 14 insertions(+), 24 deletions(-) diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index c7f675a41..dbd5aeaaa 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -24,6 +24,7 @@ class PreferencesController { } getSelectedAddress (_address) { + console.log('PREFERNCES: getSelectedAddress was called') return this.store.getState().selectedAddress } diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 0393caeab..db80d5f1b 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -165,6 +165,7 @@ module.exports = class MetamaskController extends EventEmitter { rpcUrl: this.configManager.getCurrentRpcAddress(), // account mgmt getAccounts: (cb) => { + console.log('METAMASK CONTROLLER: getAccounts was called') let selectedAddress = this.preferencesController.getSelectedAddress() let result = selectedAddress ? [selectedAddress] : [] cb(null, result) diff --git a/library/controller.js b/library/controller.js index cbba9584a..c3f2fa5fa 100644 --- a/library/controller.js +++ b/library/controller.js @@ -6,17 +6,17 @@ const background = new SWcontroller({ fileName: '/popup/sw-build.js', }) -background.on('ready', (readSw) => { +background.on('ready', (_) => { // var inpageProvider = new MetamaskInpageProvider(SwStream(background.controller)) let pageStream = new ParentStream() let swStream = SwStream(background.controller) pageStream.pipe(swStream).pipe(pageStream) + console.log('********************WOOP*********************') }) background.on('error', console.error) background.startWorker() -console.log('hello from controller') /* const urlUtil = require('url') const extend = require('xtend') @@ -167,14 +167,6 @@ function initializeZeroClient() { window.localStorage[STORAGE_KEY] = JSON.stringify(data) } - function getParentHref(){ - try { - var parentLocation = window.parent.location - return parentLocation.hostname + ':' + parentLocation.port - } catch (err) { - return 'unknown' - } - } } diff --git a/library/example/index.js b/library/example/index.js index 329302a4d..aae7ccd19 100644 --- a/library/example/index.js +++ b/library/example/index.js @@ -1,4 +1,5 @@ window.addEventListener('load', web3Detect) +window.addEventListener('message', console.warn) function web3Detect() { if (global.web3) { @@ -12,18 +13,18 @@ function web3Detect() { function startApp(){ console.log('app started') - var primaryAccount = null + var primaryAccount console.log('getting main account...') - web3.eth.getAccounts(function(err, addresses){ - if (err) throw err + web3.eth.getAccounts((err, addresses) => { + if (err) console.error(err) console.log('set address', addresses[0]) - debugger primaryAccount = addresses[0] }) document.querySelector('.action-button-1').addEventListener('click', function(){ console.log('saw click') console.log('sending tx') + primaryAccount web3.eth.sendTransaction({ from: primaryAccount, to: primaryAccount, diff --git a/library/index.js b/library/index.js index 44ee401d8..3503d15cc 100644 --- a/library/index.js +++ b/library/index.js @@ -5,13 +5,12 @@ const setupProvider = require('./lib/setup-provider.js') // setup web3 // var provider = setupProvider() -hijackProvider(provider) +// hijackProvider(provider) var web3 = new Web3(provider) web3.setProvider = function(){ console.log('MetaMask - overrode web3.setProvider') } -console.log('metamask lib hijacked provider') - +// // // export web3 // diff --git a/library/lib/setup-provider.js b/library/lib/setup-provider.js index 68be99c9e..a99fc1c68 100644 --- a/library/lib/setup-provider.js +++ b/library/lib/setup-provider.js @@ -10,15 +10,15 @@ function getProvider(){ console.log('MetaMask ZeroClient - using environmental web3 provider') return global.web3.currentProvider } - console.log('MetaMask ZeroClient - injecting zero-client iframe!') var iframeStream = setupIframe({ - zeroClientProvider: 'http://127.0.0.1:9001', + zeroClientProvider: 'http://localhost:9001', sandboxAttributes: ['allow-scripts', 'allow-popups', 'allow-same-origin'], container: document.body, }) var inpageProvider = new MetamaskInpageProvider(iframeStream) + console.log('ABOUT TO RETURN INPAGE') return inpageProvider } diff --git a/library/popup.js b/library/popup.js index d956dc0b1..bb7051055 100644 --- a/library/popup.js +++ b/library/popup.js @@ -13,11 +13,6 @@ injectCss(css) var name = 'popup' window.METAMASK_UI_TYPE = name -var iframeStream = setupIframe({ - zeroClientProvider: 'http://localhost:9001', - sandboxAttributes: ['allow-scripts', 'allow-popups', 'allow-same-origin'], - container: document.body, -}) console.log('outside:open') const background = new SWcontroller({ diff --git a/library/sw-core.js b/library/sw-core.js index 1d31b2acd..4d95898d9 100644 --- a/library/sw-core.js +++ b/library/sw-core.js @@ -116,6 +116,7 @@ function setupController (initState, client) { need to write a service worker stream for this */ connectionListener.on('remote', (portStream, messageEvent) => { + console.log('REMOTE CONECTION FOUND***********') connectRemote(portStream, messageEvent.origin) }) -- cgit From 2b1a9c5ae880afe1a5bf2d11eefbbdf26dc6e27c Mon Sep 17 00:00:00 2001 From: frankiebee Date: Wed, 29 Mar 2017 11:02:50 -0700 Subject: Create a Transaction from within the dapp --- library/controller.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/controller.js b/library/controller.js index c3f2fa5fa..126e972c8 100644 --- a/library/controller.js +++ b/library/controller.js @@ -6,9 +6,9 @@ const background = new SWcontroller({ fileName: '/popup/sw-build.js', }) +const pageStream = new ParentStream() background.on('ready', (_) => { // var inpageProvider = new MetamaskInpageProvider(SwStream(background.controller)) - let pageStream = new ParentStream() let swStream = SwStream(background.controller) pageStream.pipe(swStream).pipe(pageStream) console.log('********************WOOP*********************') -- cgit From 4cf3beda25e7883aac37ee188d3bb102dea4afa3 Mon Sep 17 00:00:00 2001 From: frankiebee Date: Wed, 29 Mar 2017 15:19:46 -0700 Subject: Bump sw-stream and setup "untrusted and trusted comunication" --- library/controller.js | 5 ++++- library/popup.js | 5 ++++- library/sw-core.js | 6 +++--- package.json | 2 +- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/library/controller.js b/library/controller.js index 126e972c8..d4a76d316 100644 --- a/library/controller.js +++ b/library/controller.js @@ -9,7 +9,10 @@ const background = new SWcontroller({ const pageStream = new ParentStream() background.on('ready', (_) => { // var inpageProvider = new MetamaskInpageProvider(SwStream(background.controller)) - let swStream = SwStream(background.controller) + let swStream = SwStream({ + serviceWorker: background.controller, + context: 'dapp', + }) pageStream.pipe(swStream).pipe(pageStream) console.log('********************WOOP*********************') }) diff --git a/library/popup.js b/library/popup.js index bb7051055..a9d934c43 100644 --- a/library/popup.js +++ b/library/popup.js @@ -21,7 +21,10 @@ const background = new SWcontroller({ background.on('ready', (readSw) => { // var inpageProvider = new MetamaskInpageProvider(SwStream(background.controller)) // startPopup(inpageProvider) - startPopup(SwStream(background.controller)) + swStream = SwStream({ + serviceWorker: background.controller, + }) + startPopup() }) background.on('message', (messageEvent) => {debugger}) background.startWorker() diff --git a/library/sw-core.js b/library/sw-core.js index 4d95898d9..9f399cccf 100644 --- a/library/sw-core.js +++ b/library/sw-core.js @@ -117,11 +117,11 @@ function setupController (initState, client) { */ connectionListener.on('remote', (portStream, messageEvent) => { console.log('REMOTE CONECTION FOUND***********') - connectRemote(portStream, messageEvent.origin) + connectRemote(portStream, messageEvent.data.context) }) - function connectRemote (connectionStream, originDomain) { - var isMetaMaskInternalProcess = (originDomain === 'http://localhost:9001') + function connectRemote (connectionStream, context) { + var isMetaMaskInternalProcess = (context !== 'dapp') if (isMetaMaskInternalProcess) { // communication with popup controller.setupTrustedCommunication(connectionStream, 'MetaMask') diff --git a/package.json b/package.json index cc51ef032..d6c80496a 100644 --- a/package.json +++ b/package.json @@ -103,7 +103,7 @@ "request-promise": "^4.1.1", "sandwich-expando": "^1.0.5", "semaphore": "^1.0.5", - "sw-stream": "^1.0.2", + "sw-stream": "^2.0.0", "textarea-caret": "^3.0.1", "three.js": "^0.73.2", "through2": "^2.0.1", -- cgit From 19302778ee0dd0535867cde29d4a5ce56d573dec Mon Sep 17 00:00:00 2001 From: frankiebee Date: Wed, 29 Mar 2017 16:19:49 -0700 Subject: fix stream --- library/popup.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/popup.js b/library/popup.js index a9d934c43..0c297d9a2 100644 --- a/library/popup.js +++ b/library/popup.js @@ -21,7 +21,7 @@ const background = new SWcontroller({ background.on('ready', (readSw) => { // var inpageProvider = new MetamaskInpageProvider(SwStream(background.controller)) // startPopup(inpageProvider) - swStream = SwStream({ + let swStream = SwStream({ serviceWorker: background.controller, }) startPopup() -- cgit From 29a602a89b176e7af3f15297c2f586a4ece0a726 Mon Sep 17 00:00:00 2001 From: frankiebee Date: Thu, 30 Mar 2017 11:28:22 -0700 Subject: Clean up --- app/scripts/controllers/preferences.js | 1 - library/controller.js | 157 +-------------------------------- library/index.js | 2 +- library/lib/setup-provider.js | 2 - library/popup.js | 8 +- library/sw-core.js | 22 ++--- 6 files changed, 11 insertions(+), 181 deletions(-) diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index dbd5aeaaa..c7f675a41 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -24,7 +24,6 @@ class PreferencesController { } getSelectedAddress (_address) { - console.log('PREFERNCES: getSelectedAddress was called') return this.store.getState().selectedAddress } diff --git a/library/controller.js b/library/controller.js index d4a76d316..1e9bc84d2 100644 --- a/library/controller.js +++ b/library/controller.js @@ -14,163 +14,8 @@ background.on('ready', (_) => { context: 'dapp', }) pageStream.pipe(swStream).pipe(pageStream) - console.log('********************WOOP*********************') + }) background.on('error', console.error) background.startWorker() - -/* -const urlUtil = require('url') -const extend = require('xtend') -const Dnode = require('dnode') -const eos = require('end-of-stream') -const ParentStream = require('iframe-stream').ParentStream -const PortStream = require('../app/scripts/lib/port-stream.js') -const notification = require('../app/scripts/lib/notifications.js') -const messageManager = require('../app/scripts/lib/message-manager') -const setupMultiplex = require('../app/scripts/lib/stream-utils.js').setupMultiplex -const MetamaskController = require('../app/scripts/metamask-controller') -const extension = require('../app/scripts/lib/extension') - -const STORAGE_KEY = 'metamask-config' - - -initializeZeroClient() - -function initializeZeroClient() { - - const controller = new MetamaskController({ - // User confirmation callbacks: - showUnconfirmedMessage, - unlockAccountMessage, - showUnapprovedTx, - // Persistence Methods: - setData, - loadData, - }) - const idStore = controller.idStore - - function unlockAccountMessage () { - console.log('notif stub - unlockAccountMessage') - } - - function showUnconfirmedMessage (msgParams, msgId) { - console.log('notif stub - showUnconfirmedMessage') - } - - function showUnapprovedTx (txParams, txData, onTxDoneCb) { - console.log('notif stub - showUnapprovedTx') - } - - // - // connect to other contexts - // - - var connectionStream = new ParentStream() - - connectRemote(connectionStream, getParentHref()) - - function connectRemote (connectionStream, originDomain) { - var isMetaMaskInternalProcess = (originDomain === '127.0.0.1:9001') - if (isMetaMaskInternalProcess) { - // communication with popup - setupTrustedCommunication(connectionStream, 'MetaMask') - } else { - // communication with page - setupUntrustedCommunication(connectionStream, originDomain) - } - } - - function setupUntrustedCommunication (connectionStream, originDomain) { - // setup multiplexing - var mx = setupMultiplex(connectionStream) - // connect features - controller.setupProviderConnection(mx.createStream('provider'), originDomain) - controller.setupPublicConfig(mx.createStream('publicConfig')) - } - - function setupTrustedCommunication (connectionStream, originDomain) { - // setup multiplexing - var mx = setupMultiplex(connectionStream) - // connect features - setupControllerConnection(mx.createStream('controller')) - controller.setupProviderConnection(mx.createStream('provider'), originDomain) - } - - // - // remote features - // - - function setupControllerConnection (stream) { - controller.stream = stream - var api = controller.getApi() - var dnode = Dnode(api) - stream.pipe(dnode).pipe(stream) - dnode.on('remote', (remote) => { - // push updates to popup - controller.ethStore.on('update', controller.sendUpdate.bind(controller)) - controller.listeners.push(remote) - idStore.on('update', controller.sendUpdate.bind(controller)) - - // teardown on disconnect - eos(stream, () => { - controller.ethStore.removeListener('update', controller.sendUpdate.bind(controller)) - }) - }) - } - - function loadData () { - var oldData = getOldStyleData() - var newData - try { - newData = JSON.parse(window.localStorage[STORAGE_KEY]) - } catch (e) {} - - var data = extend({ - meta: { - version: 0, - }, - data: { - config: { - provider: { - type: 'testnet', - }, - }, - }, - }, oldData || null, newData || null) - return data - } - - function getOldStyleData () { - var config, wallet, seedWords - - var result = { - meta: { version: 0 }, - data: {}, - } - - try { - config = JSON.parse(window.localStorage['config']) - result.data.config = config - } catch (e) {} - try { - wallet = JSON.parse(window.localStorage['lightwallet']) - result.data.wallet = wallet - } catch (e) {} - try { - seedWords = window.localStorage['seedWords'] - result.data.seedWords = seedWords - } catch (e) {} - - return result - } - - function setData (data) { - window.localStorage[STORAGE_KEY] = JSON.stringify(data) - } - - -} - -*/ diff --git a/library/index.js b/library/index.js index 3503d15cc..759353c1b 100644 --- a/library/index.js +++ b/library/index.js @@ -5,7 +5,7 @@ const setupProvider = require('./lib/setup-provider.js') // setup web3 // var provider = setupProvider() -// hijackProvider(provider) +hijackProvider(provider) var web3 = new Web3(provider) web3.setProvider = function(){ console.log('MetaMask - overrode web3.setProvider') diff --git a/library/lib/setup-provider.js b/library/lib/setup-provider.js index a99fc1c68..1b53e7f54 100644 --- a/library/lib/setup-provider.js +++ b/library/lib/setup-provider.js @@ -5,7 +5,6 @@ module.exports = getProvider function getProvider(){ - if (global.web3) { console.log('MetaMask ZeroClient - using environmental web3 provider') return global.web3.currentProvider @@ -18,7 +17,6 @@ function getProvider(){ }) var inpageProvider = new MetamaskInpageProvider(iframeStream) - console.log('ABOUT TO RETURN INPAGE') return inpageProvider } diff --git a/library/popup.js b/library/popup.js index 0c297d9a2..f294e5c69 100644 --- a/library/popup.js +++ b/library/popup.js @@ -19,13 +19,11 @@ const background = new SWcontroller({ fileName: '/popup/sw-build.js', }) background.on('ready', (readSw) => { - // var inpageProvider = new MetamaskInpageProvider(SwStream(background.controller)) - // startPopup(inpageProvider) let swStream = SwStream({ serviceWorker: background.controller, - }) - startPopup() + }) + startPopup(swStream) }) -background.on('message', (messageEvent) => {debugger}) + background.startWorker() console.log('hello from /library/popup.js') diff --git a/library/sw-core.js b/library/sw-core.js index 9f399cccf..d39bfdbfb 100644 --- a/library/sw-core.js +++ b/library/sw-core.js @@ -6,13 +6,12 @@ const SwGlobalListener = require('sw-stream/lib/sw-global-listener.js') const connectionListener = new SwGlobalListener(self) const setupMultiplex = require('../app/scripts/lib/stream-utils.js').setupMultiplex const PortStream = require('../app/scripts/lib/port-stream.js') -// const notification = require('../app/scripts/lib/notifications.js') const DbController = require('./controllers/index-db-controller') const MetamaskController = require('../app/scripts/metamask-controller') const extension = {} //require('../app/scripts/lib/extension') -// const LocalStorageStore = require('obs-store/lib/localStorage') + const storeTransform = require('obs-store/lib/transform') const Migrator = require('../app/scripts/lib/migrator/') const migrations = require('../app/scripts/migrations/') @@ -80,9 +79,9 @@ function setupController (initState, client) { const controller = new MetamaskController({ // User confirmation callbacks: - showUnconfirmedMessage: triggerUi, - unlockAccountMessage: triggerUi, - showUnapprovedTx: triggerUi, + showUnconfirmedMessage: noop, + unlockAccountMessage: noop, + showUnapprovedTx: noop, // initial state initState, }) @@ -128,7 +127,7 @@ function setupController (initState, client) { popupIsOpen = true } else { // communication with page - setupUntrustedCommunication(connectionStream, originDomain) + setupUntrustedCommunication(connectionStream, context) } } @@ -152,13 +151,4 @@ function setupController (initState, client) { return Promise.resolve() } - -// // // -// // // Etc... -// // // - -// // // popup trigger - -/*send a message to the client that has focus and tell it to open a window*/ -function triggerUi () { -} +function noop () {} -- cgit From 8d49d519c090d287484008346aba1df6d7ad77e7 Mon Sep 17 00:00:00 2001 From: frankiebee Date: Sun, 2 Apr 2017 22:01:44 -0700 Subject: Rename and move around files --- library/controller.js | 21 ---- library/controllers/index-db-controller.js | 88 ----------------- library/index.js | 44 --------- library/lib/setup-iframe.js | 19 ---- library/lib/setup-provider.js | 22 ----- library/lib/setup-untrusted-connection.js | 27 ----- library/popup.js | 29 ------ library/server.js | 9 +- library/src/background.js | 154 +++++++++++++++++++++++++++++ library/src/dapp-connection.js | 21 ++++ library/src/lib/index-db-controller.js | 88 +++++++++++++++++ library/src/lib/setup-iframe.js | 19 ++++ library/src/lib/setup-provider.js | 22 +++++ library/src/mascara.js | 44 +++++++++ library/src/popup.js | 29 ++++++ library/sw-controller.js | 64 ------------ library/sw-core.js | 154 ----------------------------- package.json | 1 + 18 files changed, 383 insertions(+), 472 deletions(-) delete mode 100644 library/controller.js delete mode 100644 library/controllers/index-db-controller.js delete mode 100644 library/index.js delete mode 100644 library/lib/setup-iframe.js delete mode 100644 library/lib/setup-provider.js delete mode 100644 library/lib/setup-untrusted-connection.js delete mode 100644 library/popup.js create mode 100644 library/src/background.js create mode 100644 library/src/dapp-connection.js create mode 100644 library/src/lib/index-db-controller.js create mode 100644 library/src/lib/setup-iframe.js create mode 100644 library/src/lib/setup-provider.js create mode 100644 library/src/mascara.js create mode 100644 library/src/popup.js delete mode 100644 library/sw-controller.js delete mode 100644 library/sw-core.js diff --git a/library/controller.js b/library/controller.js deleted file mode 100644 index 1e9bc84d2..000000000 --- a/library/controller.js +++ /dev/null @@ -1,21 +0,0 @@ -const ParentStream = require('iframe-stream').ParentStream -const SWcontroller = require('./sw-controller') -const SwStream = require('sw-stream/lib/sw-stream.js') -const SetupUntrustedComunication = ('./lib/setup-untrusted-connection.js') -const background = new SWcontroller({ - fileName: '/popup/sw-build.js', -}) - -const pageStream = new ParentStream() -background.on('ready', (_) => { - // var inpageProvider = new MetamaskInpageProvider(SwStream(background.controller)) - let swStream = SwStream({ - serviceWorker: background.controller, - context: 'dapp', - }) - pageStream.pipe(swStream).pipe(pageStream) - -}) - -background.on('error', console.error) -background.startWorker() diff --git a/library/controllers/index-db-controller.js b/library/controllers/index-db-controller.js deleted file mode 100644 index 041ddae2e..000000000 --- a/library/controllers/index-db-controller.js +++ /dev/null @@ -1,88 +0,0 @@ -const EventEmitter = require('events') -module.exports = class IndexDbController extends EventEmitter { - - constructor (opts) { - super() - this.migrations = opts.migrations - this.key = opts.key - this.dbObject = global.indexedDB - this.IDBTransaction = global.IDBTransaction || global.webkitIDBTransaction || global.msIDBTransaction || {READ_WRITE: "readwrite"}; // This line should only be needed if it is needed to support the object's constants for older browsers - this.IDBKeyRange = global.IDBKeyRange || global.webkitIDBKeyRange || global.msIDBKeyRange; - this.version = opts.version - this.logging = opts.logging - this.initialState = opts.initialState - if (this.logging) this.on('log', logger) - } - - // Opens the database connection and returns a promise - open (version = this.version) { - return new Promise((resolve, reject) => { - const dbOpenRequest = this.dbObject.open(this.key, version) - dbOpenRequest.onerror = (event) => { - return reject(event) - } - dbOpenRequest.onsuccess = (event) => { - this.db = dbOpenRequest.result - this.emit('success') - resolve(this.db) - } - dbOpenRequest.onupgradeneeded = (event) => { - this.db = event.target.result - this.db.createObjectStore('dataStore') - } - }) - .then((openRequest) => { - return this.get('dataStore') - }) - .then((data) => { - if (!data) { - return this._add('dataStore', this.initialState) - .then(() => this.get('dataStore')) - .then((versionedData) => Promise.resolve(versionedData.data)) - } - return Promise.resolve(data) - }) - } - - requestObjectStore (key, type = 'readonly') { - return new Promise((resolve, reject) => { - const dbReadWrite = this.db.transaction(key, type) - const dataStore = dbReadWrite.objectStore(key) - resolve(dataStore) - }) - } - - get (key = 'dataStore') { - return this.requestObjectStore(key) - .then((dataObject)=> { - return new Promise((resolve, reject) => { - const getRequest = dataObject.get(key) - getRequest.onsuccess = (event) => resolve(event.currentTarget.result) - getRequest.onerror = (event) => reject(event) - }) - }) - } - - put (state) { - return this.requestObjectStore('dataStore', 'readwrite') - .then((dataObject)=> { - const putRequest = dataObject.put(state, 'dataStore') - putRequest.onsuccess = (event) => Promise.resolve(event.currentTarget.result) - putRequest.onerror = (event) => Promise.reject(event) - }) - } - - _add (key, objStore, cb = logger) { - return this.requestObjectStore(key, 'readwrite') - .then((dataObject)=> { - const addRequest = dataObject.add(objStore, key) - addRequest.onsuccess = (event) => Promise.resolve(event.currentTarget.result) - addRequest.onerror = (event) => Promise.reject(event) - }) - } - -} - -function logger (err, ress) { - err ? console.error(`Logger says: ${err}`) : console.dir(`Logger says: ${ress}`) -} diff --git a/library/index.js b/library/index.js deleted file mode 100644 index 759353c1b..000000000 --- a/library/index.js +++ /dev/null @@ -1,44 +0,0 @@ -const Web3 = require('web3') -const setupProvider = require('./lib/setup-provider.js') - -// -// setup web3 -// -var provider = setupProvider() -hijackProvider(provider) -var web3 = new Web3(provider) -web3.setProvider = function(){ - console.log('MetaMask - overrode web3.setProvider') -} -// -// -// export web3 -// - -global.web3 = web3 - -// -// ui stuff -// - -var shouldPop = false -window.addEventListener('click', function(){ - if (!shouldPop) return - shouldPop = false - window.open('http://localhost:9001/popup/popup.html', '', 'width=360 height=500') - console.log('opening window...') -}) - - -function hijackProvider(provider){ - var _super = provider.sendAsync.bind(provider) - provider.sendAsync = function(payload, cb){ - if (payload.method === 'eth_sendTransaction') { - console.log('saw send') - shouldPop = true - } - _super(payload, cb) - } -} - - diff --git a/library/lib/setup-iframe.js b/library/lib/setup-iframe.js deleted file mode 100644 index db67163df..000000000 --- a/library/lib/setup-iframe.js +++ /dev/null @@ -1,19 +0,0 @@ -const Iframe = require('iframe') -const IframeStream = require('iframe-stream').IframeStream - -module.exports = setupIframe - - -function setupIframe(opts) { - opts = opts || {} - var frame = Iframe({ - src: opts.zeroClientProvider || 'https://zero.metamask.io/', - container: opts.container || document.head, - sandboxAttributes: opts.sandboxAttributes || ['allow-scripts', 'allow-popups'], - }) - var iframe = frame.iframe - iframe.style.setProperty('display', 'none') - var iframeStream = new IframeStream(iframe) - - return iframeStream -} diff --git a/library/lib/setup-provider.js b/library/lib/setup-provider.js deleted file mode 100644 index 1b53e7f54..000000000 --- a/library/lib/setup-provider.js +++ /dev/null @@ -1,22 +0,0 @@ -const setupIframe = require('./setup-iframe.js') -const MetamaskInpageProvider = require('../../app/scripts/lib/inpage-provider.js') - -module.exports = getProvider - - -function getProvider(){ - if (global.web3) { - console.log('MetaMask ZeroClient - using environmental web3 provider') - return global.web3.currentProvider - } - console.log('MetaMask ZeroClient - injecting zero-client iframe!') - var iframeStream = setupIframe({ - zeroClientProvider: 'http://localhost:9001', - sandboxAttributes: ['allow-scripts', 'allow-popups', 'allow-same-origin'], - container: document.body, - }) - - var inpageProvider = new MetamaskInpageProvider(iframeStream) - return inpageProvider - -} diff --git a/library/lib/setup-untrusted-connection.js b/library/lib/setup-untrusted-connection.js deleted file mode 100644 index b2aeb7905..000000000 --- a/library/lib/setup-untrusted-connection.js +++ /dev/null @@ -1,27 +0,0 @@ - -/* -IFRAME - var pageStream = new LocalMessageDuplexStream({ - name: 'contentscript', - target: 'inpage', - }) -SERVICEWORKER - pageStream.on('error', console.error) - var pluginPort = extension.runtime.connect({name: 'contentscript'}) - var pluginStream = new PortStream(pluginPort) - pluginStream.on('error', console.error) -IFRAME --> SW - // forward communication plugin->inpage - pageStream.pipe(pluginStream).pipe(pageStream) -*/ - -module.exports = SetupUntrustedComunicationWithSW - -function SetupUntrustedComunicationWithSW (connectionStream, readySwStream) { - pageStream.on('error', console.error) - var pluginPort = extension.runtime.connect({name: 'contentscript'}) - var pluginStream = new PortStream(pluginPort) - pluginStream.on('error', console.error) - // forward communication plugin->inpage - pageStream.pipe(pluginStream).pipe(pageStream) -} diff --git a/library/popup.js b/library/popup.js deleted file mode 100644 index f294e5c69..000000000 --- a/library/popup.js +++ /dev/null @@ -1,29 +0,0 @@ -const injectCss = require('inject-css') -const MetaMaskUiCss = require('../ui/css') -const setupIframe = require('./lib/setup-iframe.js') -const MetamaskInpageProvider = require('../app/scripts/lib/inpage-provider.js') -const SWcontroller = require('./sw-controller') -const SwStream = require('sw-stream/lib/sw-stream.js') -const startPopup = require('../app/scripts/popup-core') - - -var css = MetaMaskUiCss() -injectCss(css) - -var name = 'popup' -window.METAMASK_UI_TYPE = name - -console.log('outside:open') - -const background = new SWcontroller({ - fileName: '/popup/sw-build.js', -}) -background.on('ready', (readSw) => { - let swStream = SwStream({ - serviceWorker: background.controller, - }) - startPopup(swStream) -}) - -background.startWorker() -console.log('hello from /library/popup.js') diff --git a/library/server.js b/library/server.js index a284d3e05..67c89f11b 100644 --- a/library/server.js +++ b/library/server.js @@ -3,11 +3,12 @@ const browserify = require('browserify') const watchify = require('watchify') const babelify = require('babelify') -const zeroBundle = createBundle('./index.js') -const controllerBundle = createBundle('./controller.js') -const popupBundle = createBundle('./popup.js') +const zeroBundle = createBundle('./src/mascara.js') +const controllerBundle = createBundle('./src/dapp-connection.js') +const popupBundle = createBundle('./src/popup.js') +const swBuild = createBundle('./src/background.js') + const appBundle = createBundle('./example/index.js') -const swBuild = createBundle('./sw-core.js') // // Iframe Server diff --git a/library/src/background.js b/library/src/background.js new file mode 100644 index 000000000..0af692ab8 --- /dev/null +++ b/library/src/background.js @@ -0,0 +1,154 @@ +global.window = global +const asyncQ = require('async-q') +const pipe = require('pump') + +const SwGlobalListener = require('sw-stream/lib/sw-global-listener.js') +const connectionListener = new SwGlobalListener(self) +const setupMultiplex = require('../../app/scripts/lib/stream-utils.js').setupMultiplex +const PortStream = require('../../app/scripts/lib/port-stream.js') + +const DbController = require('./lib/index-db-controller') + +const MetamaskController = require('../../app/scripts/metamask-controller') +const extension = {} //require('../../app/scripts/lib/extension') + +const storeTransform = require('obs-store/lib/transform') +const Migrator = require('../../app/scripts/lib/migrator/') +const migrations = require('../../app/scripts/migrations/') +const firstTimeState = require('../../app/scripts/first-time-state') + +const STORAGE_KEY = 'metamask-config' +const METAMASK_DEBUG = 'GULP_METAMASK_DEBUG' +let popupIsOpen = false + +const log = require('loglevel') +global.log = log +log.setDefaultLevel(METAMASK_DEBUG ? 'debug' : 'warn') + +self.addEventListener('install', function(event) { + event.waitUntil(self.skipWaiting()) +}) +self.addEventListener('activate', function(event) { + event.waitUntil(self.clients.claim()) +}) + +console.log('inside:open') + + +// // state persistence +let diskStore +const dbController = new DbController({ + key: STORAGE_KEY, + global: self, + version: 2, +}) +asyncQ.waterfall([ + () => loadStateFromPersistence(), + (initState) => setupController(initState), +]) +.then(() => console.log('MetaMask initialization complete.')) +.catch((err) => { + console.log('WHILE SETTING UP:') + console.error(err) +}) + +// initialization flow + +// +// State and Persistence +// +function loadStateFromPersistence() { + // migrations + let migrator = new Migrator({ migrations }) + const initialState = migrator.generateInitialState(firstTimeState) + dbController.initialState = initialState + return dbController.open() + .then((versionedData) => migrator.migrateData(versionedData)) + .then((versionedData) => { + dbController.put(versionedData) + return Promise.resolve(versionedData) + }) + .then((versionedData) => Promise.resolve(versionedData.data)) +} + +function setupController (initState, client) { + + // + // MetaMask Controller + // + + const controller = new MetamaskController({ + // User confirmation callbacks: + showUnconfirmedMessage: noop, + unlockAccountMessage: noop, + showUnapprovedTx: noop, + // initial state + initState, + }) + global.metamaskController = controller + + // setup state persistence + // pipe( + // controller.store, + // storeTransform(versionifyData), + // diskStore + // ) + controller.store.subscribe((state) => { + versionifyData(state) + .then((versionedData) => dbController.put(versionedData)) + .catch((err) => {console.error(err)}) + }) + function versionifyData(state) { + return dbController.get() + .then((rawData) => { + return Promise.resolve({ + data: state, + meta: rawData.meta, + })} + ) + } + + // + // connect to other contexts + // + /* + need to write a service worker stream for this + */ + connectionListener.on('remote', (portStream, messageEvent) => { + console.log('REMOTE CONECTION FOUND***********') + connectRemote(portStream, messageEvent.data.context) + }) + + function connectRemote (connectionStream, context) { + var isMetaMaskInternalProcess = (context !== 'dapp') + if (isMetaMaskInternalProcess) { + // communication with popup + controller.setupTrustedCommunication(connectionStream, 'MetaMask') + popupIsOpen = true + } else { + // communication with page + setupUntrustedCommunication(connectionStream, context) + } + } + + function setupUntrustedCommunication (connectionStream, originDomain) { + // setup multiplexing + var mx = setupMultiplex(connectionStream) + // connect features + controller.setupProviderConnection(mx.createStream('provider'), originDomain) + controller.setupPublicConfig(mx.createStream('publicConfig')) + } + + function setupTrustedCommunication (connectionStream, originDomain) { + // setup multiplexing + var mx = setupMultiplex(connectionStream) + // connect features + controller.setupProviderConnection(mx.createStream('provider'), originDomain) + } + // + // User Interface setup + // + return Promise.resolve() + +} +function noop () {} diff --git a/library/src/dapp-connection.js b/library/src/dapp-connection.js new file mode 100644 index 000000000..30680c9d7 --- /dev/null +++ b/library/src/dapp-connection.js @@ -0,0 +1,21 @@ +const ParentStream = require('iframe-stream').ParentStream +const SWcontroller = require('client-sw-ready-event/lib/sw-client.js') +const SwStream = require('sw-stream/lib/sw-stream.js') +const SetupUntrustedComunication = ('./lib/setup-untrusted-connection.js') + +const background = new SWcontroller({ + fileName: '/popup/sw-build.js', +}) + +const pageStream = new ParentStream() +background.on('ready', (_) => { + let swStream = SwStream({ + serviceWorker: background.controller, + context: 'dapp', + }) + pageStream.pipe(swStream).pipe(pageStream) + +}) + +background.on('error', console.error) +background.startWorker() diff --git a/library/src/lib/index-db-controller.js b/library/src/lib/index-db-controller.js new file mode 100644 index 000000000..041ddae2e --- /dev/null +++ b/library/src/lib/index-db-controller.js @@ -0,0 +1,88 @@ +const EventEmitter = require('events') +module.exports = class IndexDbController extends EventEmitter { + + constructor (opts) { + super() + this.migrations = opts.migrations + this.key = opts.key + this.dbObject = global.indexedDB + this.IDBTransaction = global.IDBTransaction || global.webkitIDBTransaction || global.msIDBTransaction || {READ_WRITE: "readwrite"}; // This line should only be needed if it is needed to support the object's constants for older browsers + this.IDBKeyRange = global.IDBKeyRange || global.webkitIDBKeyRange || global.msIDBKeyRange; + this.version = opts.version + this.logging = opts.logging + this.initialState = opts.initialState + if (this.logging) this.on('log', logger) + } + + // Opens the database connection and returns a promise + open (version = this.version) { + return new Promise((resolve, reject) => { + const dbOpenRequest = this.dbObject.open(this.key, version) + dbOpenRequest.onerror = (event) => { + return reject(event) + } + dbOpenRequest.onsuccess = (event) => { + this.db = dbOpenRequest.result + this.emit('success') + resolve(this.db) + } + dbOpenRequest.onupgradeneeded = (event) => { + this.db = event.target.result + this.db.createObjectStore('dataStore') + } + }) + .then((openRequest) => { + return this.get('dataStore') + }) + .then((data) => { + if (!data) { + return this._add('dataStore', this.initialState) + .then(() => this.get('dataStore')) + .then((versionedData) => Promise.resolve(versionedData.data)) + } + return Promise.resolve(data) + }) + } + + requestObjectStore (key, type = 'readonly') { + return new Promise((resolve, reject) => { + const dbReadWrite = this.db.transaction(key, type) + const dataStore = dbReadWrite.objectStore(key) + resolve(dataStore) + }) + } + + get (key = 'dataStore') { + return this.requestObjectStore(key) + .then((dataObject)=> { + return new Promise((resolve, reject) => { + const getRequest = dataObject.get(key) + getRequest.onsuccess = (event) => resolve(event.currentTarget.result) + getRequest.onerror = (event) => reject(event) + }) + }) + } + + put (state) { + return this.requestObjectStore('dataStore', 'readwrite') + .then((dataObject)=> { + const putRequest = dataObject.put(state, 'dataStore') + putRequest.onsuccess = (event) => Promise.resolve(event.currentTarget.result) + putRequest.onerror = (event) => Promise.reject(event) + }) + } + + _add (key, objStore, cb = logger) { + return this.requestObjectStore(key, 'readwrite') + .then((dataObject)=> { + const addRequest = dataObject.add(objStore, key) + addRequest.onsuccess = (event) => Promise.resolve(event.currentTarget.result) + addRequest.onerror = (event) => Promise.reject(event) + }) + } + +} + +function logger (err, ress) { + err ? console.error(`Logger says: ${err}`) : console.dir(`Logger says: ${ress}`) +} diff --git a/library/src/lib/setup-iframe.js b/library/src/lib/setup-iframe.js new file mode 100644 index 000000000..db67163df --- /dev/null +++ b/library/src/lib/setup-iframe.js @@ -0,0 +1,19 @@ +const Iframe = require('iframe') +const IframeStream = require('iframe-stream').IframeStream + +module.exports = setupIframe + + +function setupIframe(opts) { + opts = opts || {} + var frame = Iframe({ + src: opts.zeroClientProvider || 'https://zero.metamask.io/', + container: opts.container || document.head, + sandboxAttributes: opts.sandboxAttributes || ['allow-scripts', 'allow-popups'], + }) + var iframe = frame.iframe + iframe.style.setProperty('display', 'none') + var iframeStream = new IframeStream(iframe) + + return iframeStream +} diff --git a/library/src/lib/setup-provider.js b/library/src/lib/setup-provider.js new file mode 100644 index 000000000..4f2432ae4 --- /dev/null +++ b/library/src/lib/setup-provider.js @@ -0,0 +1,22 @@ +const setupIframe = require('./setup-iframe.js') +const MetamaskInpageProvider = require('../../../app/scripts/lib/inpage-provider.js') + +module.exports = getProvider + + +function getProvider(){ + if (global.web3) { + console.log('MetaMask ZeroClient - using environmental web3 provider') + return global.web3.currentProvider + } + console.log('MetaMask ZeroClient - injecting zero-client iframe!') + var iframeStream = setupIframe({ + zeroClientProvider: 'http://localhost:9001', + sandboxAttributes: ['allow-scripts', 'allow-popups', 'allow-same-origin'], + container: document.body, + }) + + var inpageProvider = new MetamaskInpageProvider(iframeStream) + return inpageProvider + +} diff --git a/library/src/mascara.js b/library/src/mascara.js new file mode 100644 index 000000000..759353c1b --- /dev/null +++ b/library/src/mascara.js @@ -0,0 +1,44 @@ +const Web3 = require('web3') +const setupProvider = require('./lib/setup-provider.js') + +// +// setup web3 +// +var provider = setupProvider() +hijackProvider(provider) +var web3 = new Web3(provider) +web3.setProvider = function(){ + console.log('MetaMask - overrode web3.setProvider') +} +// +// +// export web3 +// + +global.web3 = web3 + +// +// ui stuff +// + +var shouldPop = false +window.addEventListener('click', function(){ + if (!shouldPop) return + shouldPop = false + window.open('http://localhost:9001/popup/popup.html', '', 'width=360 height=500') + console.log('opening window...') +}) + + +function hijackProvider(provider){ + var _super = provider.sendAsync.bind(provider) + provider.sendAsync = function(payload, cb){ + if (payload.method === 'eth_sendTransaction') { + console.log('saw send') + shouldPop = true + } + _super(payload, cb) + } +} + + diff --git a/library/src/popup.js b/library/src/popup.js new file mode 100644 index 000000000..3dcc508bf --- /dev/null +++ b/library/src/popup.js @@ -0,0 +1,29 @@ +const injectCss = require('inject-css') +const MetaMaskUiCss = require('../../ui/css') +const setupIframe = require('./lib/setup-iframe.js') +const MetamaskInpageProvider = require('../../app/scripts/lib/inpage-provider.js') +const SWcontroller = require('client-sw-ready-event/lib/sw-client.js') +const SwStream = require('sw-stream/lib/sw-stream.js') +const startPopup = require('../../app/scripts/popup-core') + + +var css = MetaMaskUiCss() +injectCss(css) + +var name = 'popup' +window.METAMASK_UI_TYPE = name + +console.log('outside:open') + +const background = new SWcontroller({ + fileName: '/popup/sw-build.js', +}) +background.on('ready', (readSw) => { + let swStream = SwStream({ + serviceWorker: background.controller, + }) + startPopup(swStream) +}) + +background.startWorker() +console.log('hello from /library/popup.js') diff --git a/library/sw-controller.js b/library/sw-controller.js deleted file mode 100644 index 1a7b1cad3..000000000 --- a/library/sw-controller.js +++ /dev/null @@ -1,64 +0,0 @@ -const EventEmitter = require('events') - -module.exports = class ClientSideServiceWorker extends EventEmitter{ - constructor (opts) { - super() - this.fileName = opts.fileName - this.startDelay = opts.startDelay - - this.serviceWorkerApi = navigator.serviceWorker - this.serviceWorkerApi.onmessage = (messageEvent) => this.emit('message', messageEvent) - this.serviceWorkerApi.onerror = (err) => this.emit('error', err) - this.on('message', (messageEvent) => {debugger}) - if (opts.initStart) this.startWorker() - } - - get controller () { - return this.sw || this.serviceWorkerApi.controller - } - - - startWorker () { - return this.registerWorker() - .then((sw) => { - this.sw = sw - this.sw.onerror = (err) => this.emit('error', err) - this.sw = sw - this.emit('ready', this.sw) - }) - .catch((err) => this.emit('error', err)) - } - - registerWorker () { - return this.serviceWorkerApi.register(this.fileName) - .then((registerdWorker) => { - return new Promise((resolve, reject) => { - let timeOutId = setTimeout(() => { - if (this.serviceWorkerApi.controller) return resolve(this.serviceWorkerApi.controller) - if (registerdWorker.active) return resolve(registerdWorker.active) - return reject(new Error('ClientSideServiceWorker: No controller found and onupdatefound timed out')) - }, this.startDelay || 1000 ) - - registerdWorker.onupdatefound = (event) => { - this.emit('updatefound') - registerdWorker.update() - } - }) - }) - } - - sendMessage (message) { - const self = this - return new Promise((resolve, reject) => { - var messageChannel = new MessageChannel() - messageChannel.port1.onmessage = (event) => { - if (event.data.err) { - reject(event.data.error) - } else { - resolve(event.data.data) - } - } - this.controller.postMessage(message, [messageChannel.port2]) - }) - } -} diff --git a/library/sw-core.js b/library/sw-core.js deleted file mode 100644 index d39bfdbfb..000000000 --- a/library/sw-core.js +++ /dev/null @@ -1,154 +0,0 @@ -global.window = global -const asyncQ = require('async-q') -const pipe = require('pump') - -const SwGlobalListener = require('sw-stream/lib/sw-global-listener.js') -const connectionListener = new SwGlobalListener(self) -const setupMultiplex = require('../app/scripts/lib/stream-utils.js').setupMultiplex -const PortStream = require('../app/scripts/lib/port-stream.js') - -const DbController = require('./controllers/index-db-controller') - -const MetamaskController = require('../app/scripts/metamask-controller') -const extension = {} //require('../app/scripts/lib/extension') - -const storeTransform = require('obs-store/lib/transform') -const Migrator = require('../app/scripts/lib/migrator/') -const migrations = require('../app/scripts/migrations/') -const firstTimeState = require('../app/scripts/first-time-state') - -const STORAGE_KEY = 'metamask-config' -const METAMASK_DEBUG = 'GULP_METAMASK_DEBUG' -let popupIsOpen = false - -const log = require('loglevel') -global.log = log -log.setDefaultLevel(METAMASK_DEBUG ? 'debug' : 'warn') - -self.addEventListener('install', function(event) { - event.waitUntil(self.skipWaiting()) -}) -self.addEventListener('activate', function(event) { - event.waitUntil(self.clients.claim()) -}) - -console.log('inside:open') - - -// // state persistence -let diskStore -const dbController = new DbController({ - key: STORAGE_KEY, - global: self, - version: 2, -}) -asyncQ.waterfall([ - () => loadStateFromPersistence(), - (initState) => setupController(initState), -]) -.then(() => console.log('MetaMask initialization complete.')) -.catch((err) => { - console.log('WHILE SETTING UP:') - console.error(err) -}) - -// initialization flow - -// -// State and Persistence -// -function loadStateFromPersistence() { - // migrations - let migrator = new Migrator({ migrations }) - const initialState = migrator.generateInitialState(firstTimeState) - dbController.initialState = initialState - return dbController.open() - .then((versionedData) => migrator.migrateData(versionedData)) - .then((versionedData) => { - dbController.put(versionedData) - return Promise.resolve(versionedData) - }) - .then((versionedData) => Promise.resolve(versionedData.data)) -} - -function setupController (initState, client) { - - // - // MetaMask Controller - // - - const controller = new MetamaskController({ - // User confirmation callbacks: - showUnconfirmedMessage: noop, - unlockAccountMessage: noop, - showUnapprovedTx: noop, - // initial state - initState, - }) - global.metamaskController = controller - - // setup state persistence - // pipe( - // controller.store, - // storeTransform(versionifyData), - // diskStore - // ) - controller.store.subscribe((state) => { - versionifyData(state) - .then((versionedData) => dbController.put(versionedData)) - .catch((err) => {console.error(err)}) - }) - function versionifyData(state) { - return dbController.get() - .then((rawData) => { - return Promise.resolve({ - data: state, - meta: rawData.meta, - })} - ) - } - - // - // connect to other contexts - // - /* - need to write a service worker stream for this - */ - connectionListener.on('remote', (portStream, messageEvent) => { - console.log('REMOTE CONECTION FOUND***********') - connectRemote(portStream, messageEvent.data.context) - }) - - function connectRemote (connectionStream, context) { - var isMetaMaskInternalProcess = (context !== 'dapp') - if (isMetaMaskInternalProcess) { - // communication with popup - controller.setupTrustedCommunication(connectionStream, 'MetaMask') - popupIsOpen = true - } else { - // communication with page - setupUntrustedCommunication(connectionStream, context) - } - } - - function setupUntrustedCommunication (connectionStream, originDomain) { - // setup multiplexing - var mx = setupMultiplex(connectionStream) - // connect features - controller.setupProviderConnection(mx.createStream('provider'), originDomain) - controller.setupPublicConfig(mx.createStream('publicConfig')) - } - - function setupTrustedCommunication (connectionStream, originDomain) { - // setup multiplexing - var mx = setupMultiplex(connectionStream) - // connect features - controller.setupProviderConnection(mx.createStream('provider'), originDomain) - } - // - // User Interface setup - // - return Promise.resolve() - -} -function noop () {} diff --git a/package.json b/package.json index d6c80496a..d69dcbb91 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "bip39": "^2.2.0", "browser-passworder": "^2.0.3", "browserify-derequire": "^0.9.4", + "client-sw-ready-event": "^1.0.2", "clone": "^1.0.2", "copy-to-clipboard": "^2.0.0", "debounce": "^1.0.0", -- cgit From 12065a10aab05690b45c83648ee26f85f403b864 Mon Sep 17 00:00:00 2001 From: frankiebee Date: Mon, 3 Apr 2017 11:03:58 +0200 Subject: Make Popup close after approving a transaction --- library/src/popup.js | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/library/src/popup.js b/library/src/popup.js index 3dcc508bf..ef7759a81 100644 --- a/library/src/popup.js +++ b/library/src/popup.js @@ -1,28 +1,35 @@ const injectCss = require('inject-css') +const SWcontroller = require('client-sw-ready-event/lib/sw-client.js') +const SwStream = require('sw-stream/lib/sw-stream.js') const MetaMaskUiCss = require('../../ui/css') const setupIframe = require('./lib/setup-iframe.js') const MetamaskInpageProvider = require('../../app/scripts/lib/inpage-provider.js') -const SWcontroller = require('client-sw-ready-event/lib/sw-client.js') -const SwStream = require('sw-stream/lib/sw-stream.js') const startPopup = require('../../app/scripts/popup-core') - var css = MetaMaskUiCss() injectCss(css) +const container = document.getElementById('app-content') var name = 'popup' window.METAMASK_UI_TYPE = name -console.log('outside:open') - const background = new SWcontroller({ fileName: '/popup/sw-build.js', }) + +// Setup listener for when the service worker is read background.on('ready', (readSw) => { - let swStream = SwStream({ + let connectionStream = SwStream({ serviceWorker: background.controller, + context: name, + }) + startPopup({container, connectionStream}, (err, store) => { + if (err) return displayCriticalError(err) + store.subscribe(() => { + const state = store.getState() + if (state.appState.shouldClose) window.close() + }) }) - startPopup(swStream) }) background.startWorker() -- cgit From 9736e96a93799f081ede01bc7ecd295fa264ffd5 Mon Sep 17 00:00:00 2001 From: frankiebee Date: Mon, 3 Apr 2017 11:04:48 +0200 Subject: Check to see if connection is from popup --- library/src/background.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/src/background.js b/library/src/background.js index 0af692ab8..dd0e13239 100644 --- a/library/src/background.js +++ b/library/src/background.js @@ -120,7 +120,7 @@ function setupController (initState, client) { }) function connectRemote (connectionStream, context) { - var isMetaMaskInternalProcess = (context !== 'dapp') + var isMetaMaskInternalProcess = (context === 'popup') if (isMetaMaskInternalProcess) { // communication with popup controller.setupTrustedCommunication(connectionStream, 'MetaMask') -- cgit From 57655073f6ab4e93b9947302d46a20bd2c7288f1 Mon Sep 17 00:00:00 2001 From: frankiebee Date: Mon, 3 Apr 2017 11:08:31 +0200 Subject: Rename mascara root directory --- library/README.md | 24 ----- library/example/index.html | 17 ---- library/example/index.js | 57 ------------ library/server.js | 103 ---------------------- library/server/index.html | 20 ----- library/src/background.js | 154 --------------------------------- library/src/dapp-connection.js | 21 ----- library/src/lib/index-db-controller.js | 88 ------------------- library/src/lib/setup-iframe.js | 19 ---- library/src/lib/setup-provider.js | 22 ----- library/src/mascara.js | 44 ---------- library/src/popup.js | 36 -------- mascara/README.md | 24 +++++ mascara/example/index.html | 17 ++++ mascara/example/index.js | 57 ++++++++++++ mascara/server.js | 103 ++++++++++++++++++++++ mascara/server/index.html | 20 +++++ mascara/src/background.js | 154 +++++++++++++++++++++++++++++++++ mascara/src/dapp-connection.js | 21 +++++ mascara/src/lib/index-db-controller.js | 88 +++++++++++++++++++ mascara/src/lib/setup-iframe.js | 19 ++++ mascara/src/lib/setup-provider.js | 22 +++++ mascara/src/mascara.js | 44 ++++++++++ mascara/src/popup.js | 36 ++++++++ 24 files changed, 605 insertions(+), 605 deletions(-) delete mode 100644 library/README.md delete mode 100644 library/example/index.html delete mode 100644 library/example/index.js delete mode 100644 library/server.js delete mode 100644 library/server/index.html delete mode 100644 library/src/background.js delete mode 100644 library/src/dapp-connection.js delete mode 100644 library/src/lib/index-db-controller.js delete mode 100644 library/src/lib/setup-iframe.js delete mode 100644 library/src/lib/setup-provider.js delete mode 100644 library/src/mascara.js delete mode 100644 library/src/popup.js create mode 100644 mascara/README.md create mode 100644 mascara/example/index.html create mode 100644 mascara/example/index.js create mode 100644 mascara/server.js create mode 100644 mascara/server/index.html create mode 100644 mascara/src/background.js create mode 100644 mascara/src/dapp-connection.js create mode 100644 mascara/src/lib/index-db-controller.js create mode 100644 mascara/src/lib/setup-iframe.js create mode 100644 mascara/src/lib/setup-provider.js create mode 100644 mascara/src/mascara.js create mode 100644 mascara/src/popup.js diff --git a/library/README.md b/library/README.md deleted file mode 100644 index 6a6574dbd..000000000 --- a/library/README.md +++ /dev/null @@ -1,24 +0,0 @@ -start the dual servers (dapp + mascara) -``` -node server.js -``` - -open the example dapp at `http://localhost:9002/` - -*You will need to build MetaMask in order for this to work* -``` -gulp dev -``` -to build MetaMask and have it live reload if you make changes - - -## First time use: - -- navigate to: http://127.0.0.1:9001/popup/popup.html -- Create an Account -- go back to http://localhost:9002/ -- open devTools -- click Sync Tx - -### Todos -- Look into using [Service Workers](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API) diff --git a/library/example/index.html b/library/example/index.html deleted file mode 100644 index 47d6da34f..000000000 --- a/library/example/index.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - MetaMask ZeroClient Example - - - - - - - - - - \ No newline at end of file diff --git a/library/example/index.js b/library/example/index.js deleted file mode 100644 index aae7ccd19..000000000 --- a/library/example/index.js +++ /dev/null @@ -1,57 +0,0 @@ -window.addEventListener('load', web3Detect) -window.addEventListener('message', console.warn) - -function web3Detect() { - if (global.web3) { - logToDom('web3 detected!') - startApp() - } else { - logToDom('no web3 detected!') - } -} - -function startApp(){ - console.log('app started') - - var primaryAccount - console.log('getting main account...') - web3.eth.getAccounts((err, addresses) => { - if (err) console.error(err) - console.log('set address', addresses[0]) - primaryAccount = addresses[0] - }) - - document.querySelector('.action-button-1').addEventListener('click', function(){ - console.log('saw click') - console.log('sending tx') - primaryAccount - web3.eth.sendTransaction({ - from: primaryAccount, - to: primaryAccount, - value: 0, - }, function(err, txHash){ - if (err) throw err - console.log('sendTransaction result:', err || txHash) - }) - }) - document.querySelector('.action-button-2').addEventListener('click', function(){ - console.log('saw click') - setTimeout(function(){ - console.log('sending tx') - web3.eth.sendTransaction({ - from: primaryAccount, - to: primaryAccount, - value: 0, - }, function(err, txHash){ - if (err) throw err - console.log('sendTransaction result:', err || txHash) - }) - }) - }) - -} - -function logToDom(message){ - document.body.appendChild(document.createTextNode(message)) - console.log(message) -} diff --git a/library/server.js b/library/server.js deleted file mode 100644 index 67c89f11b..000000000 --- a/library/server.js +++ /dev/null @@ -1,103 +0,0 @@ -const express = require('express') -const browserify = require('browserify') -const watchify = require('watchify') -const babelify = require('babelify') - -const zeroBundle = createBundle('./src/mascara.js') -const controllerBundle = createBundle('./src/dapp-connection.js') -const popupBundle = createBundle('./src/popup.js') -const swBuild = createBundle('./src/background.js') - -const appBundle = createBundle('./example/index.js') - -// -// Iframe Server -// - -const iframeServer = express() - -// serve popup window -iframeServer.get('/popup/scripts/popup.js', function(req, res){ - res.send(popupBundle.latest) -}) -iframeServer.use('/popup', express.static('../dist/chrome')) - -// serve controller bundle -iframeServer.get('/controller.js', function(req, res){ - res.send(controllerBundle.latest) -}) -iframeServer.get('/popup/sw-build.js', function(req, res){ - console.log('/sw-build.js') - res.setHeader('Content-Type', 'application/javascript') - res.send(swBuild.latest) -}) - -// serve background controller -iframeServer.use(express.static('./server')) - -// start the server -const mascaraPort = 9001 -iframeServer.listen(mascaraPort) -console.log(`Mascara service listening on port ${mascaraPort}`) - - -// -// Dapp Server -// - -const dappServer = express() - -// serve metamask-lib bundle -dappServer.get('/zero.js', function(req, res){ - res.send(zeroBundle.latest) -}) - -// serve dapp bundle -dappServer.get('/app.js', function(req, res){ - res.send(appBundle.latest) -}) - -// serve static -dappServer.use(express.static('./example')) - -// start the server -const dappPort = '9002' -dappServer.listen(dappPort) -console.log(`Dapp listening on port ${dappPort}`) - -// -// util -// - -function serveBundle(entryPoint){ - const bundle = createBundle(entryPoint) - return function(req, res){ - res.send(bundle.latest) - } -} - -function createBundle(entryPoint){ - - var bundleContainer = {} - - var bundler = browserify({ - entries: [entryPoint], - cache: {}, - packageCache: {}, - plugin: [watchify], - }) - - bundler.on('update', bundle) - bundle() - - return bundleContainer - - function bundle() { - bundler.bundle(function(err, result){ - if (err) throw err - console.log(`Bundle updated! (${entryPoint})`) - bundleContainer.latest = result.toString() - }) - } - -} diff --git a/library/server/index.html b/library/server/index.html deleted file mode 100644 index 2308dd98b..000000000 --- a/library/server/index.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - MetaMask ZeroClient Iframe - - - - - - - - Hello! I am the MetaMask iframe. - - - \ No newline at end of file diff --git a/library/src/background.js b/library/src/background.js deleted file mode 100644 index dd0e13239..000000000 --- a/library/src/background.js +++ /dev/null @@ -1,154 +0,0 @@ -global.window = global -const asyncQ = require('async-q') -const pipe = require('pump') - -const SwGlobalListener = require('sw-stream/lib/sw-global-listener.js') -const connectionListener = new SwGlobalListener(self) -const setupMultiplex = require('../../app/scripts/lib/stream-utils.js').setupMultiplex -const PortStream = require('../../app/scripts/lib/port-stream.js') - -const DbController = require('./lib/index-db-controller') - -const MetamaskController = require('../../app/scripts/metamask-controller') -const extension = {} //require('../../app/scripts/lib/extension') - -const storeTransform = require('obs-store/lib/transform') -const Migrator = require('../../app/scripts/lib/migrator/') -const migrations = require('../../app/scripts/migrations/') -const firstTimeState = require('../../app/scripts/first-time-state') - -const STORAGE_KEY = 'metamask-config' -const METAMASK_DEBUG = 'GULP_METAMASK_DEBUG' -let popupIsOpen = false - -const log = require('loglevel') -global.log = log -log.setDefaultLevel(METAMASK_DEBUG ? 'debug' : 'warn') - -self.addEventListener('install', function(event) { - event.waitUntil(self.skipWaiting()) -}) -self.addEventListener('activate', function(event) { - event.waitUntil(self.clients.claim()) -}) - -console.log('inside:open') - - -// // state persistence -let diskStore -const dbController = new DbController({ - key: STORAGE_KEY, - global: self, - version: 2, -}) -asyncQ.waterfall([ - () => loadStateFromPersistence(), - (initState) => setupController(initState), -]) -.then(() => console.log('MetaMask initialization complete.')) -.catch((err) => { - console.log('WHILE SETTING UP:') - console.error(err) -}) - -// initialization flow - -// -// State and Persistence -// -function loadStateFromPersistence() { - // migrations - let migrator = new Migrator({ migrations }) - const initialState = migrator.generateInitialState(firstTimeState) - dbController.initialState = initialState - return dbController.open() - .then((versionedData) => migrator.migrateData(versionedData)) - .then((versionedData) => { - dbController.put(versionedData) - return Promise.resolve(versionedData) - }) - .then((versionedData) => Promise.resolve(versionedData.data)) -} - -function setupController (initState, client) { - - // - // MetaMask Controller - // - - const controller = new MetamaskController({ - // User confirmation callbacks: - showUnconfirmedMessage: noop, - unlockAccountMessage: noop, - showUnapprovedTx: noop, - // initial state - initState, - }) - global.metamaskController = controller - - // setup state persistence - // pipe( - // controller.store, - // storeTransform(versionifyData), - // diskStore - // ) - controller.store.subscribe((state) => { - versionifyData(state) - .then((versionedData) => dbController.put(versionedData)) - .catch((err) => {console.error(err)}) - }) - function versionifyData(state) { - return dbController.get() - .then((rawData) => { - return Promise.resolve({ - data: state, - meta: rawData.meta, - })} - ) - } - - // - // connect to other contexts - // - /* - need to write a service worker stream for this - */ - connectionListener.on('remote', (portStream, messageEvent) => { - console.log('REMOTE CONECTION FOUND***********') - connectRemote(portStream, messageEvent.data.context) - }) - - function connectRemote (connectionStream, context) { - var isMetaMaskInternalProcess = (context === 'popup') - if (isMetaMaskInternalProcess) { - // communication with popup - controller.setupTrustedCommunication(connectionStream, 'MetaMask') - popupIsOpen = true - } else { - // communication with page - setupUntrustedCommunication(connectionStream, context) - } - } - - function setupUntrustedCommunication (connectionStream, originDomain) { - // setup multiplexing - var mx = setupMultiplex(connectionStream) - // connect features - controller.setupProviderConnection(mx.createStream('provider'), originDomain) - controller.setupPublicConfig(mx.createStream('publicConfig')) - } - - function setupTrustedCommunication (connectionStream, originDomain) { - // setup multiplexing - var mx = setupMultiplex(connectionStream) - // connect features - controller.setupProviderConnection(mx.createStream('provider'), originDomain) - } - // - // User Interface setup - // - return Promise.resolve() - -} -function noop () {} diff --git a/library/src/dapp-connection.js b/library/src/dapp-connection.js deleted file mode 100644 index 30680c9d7..000000000 --- a/library/src/dapp-connection.js +++ /dev/null @@ -1,21 +0,0 @@ -const ParentStream = require('iframe-stream').ParentStream -const SWcontroller = require('client-sw-ready-event/lib/sw-client.js') -const SwStream = require('sw-stream/lib/sw-stream.js') -const SetupUntrustedComunication = ('./lib/setup-untrusted-connection.js') - -const background = new SWcontroller({ - fileName: '/popup/sw-build.js', -}) - -const pageStream = new ParentStream() -background.on('ready', (_) => { - let swStream = SwStream({ - serviceWorker: background.controller, - context: 'dapp', - }) - pageStream.pipe(swStream).pipe(pageStream) - -}) - -background.on('error', console.error) -background.startWorker() diff --git a/library/src/lib/index-db-controller.js b/library/src/lib/index-db-controller.js deleted file mode 100644 index 041ddae2e..000000000 --- a/library/src/lib/index-db-controller.js +++ /dev/null @@ -1,88 +0,0 @@ -const EventEmitter = require('events') -module.exports = class IndexDbController extends EventEmitter { - - constructor (opts) { - super() - this.migrations = opts.migrations - this.key = opts.key - this.dbObject = global.indexedDB - this.IDBTransaction = global.IDBTransaction || global.webkitIDBTransaction || global.msIDBTransaction || {READ_WRITE: "readwrite"}; // This line should only be needed if it is needed to support the object's constants for older browsers - this.IDBKeyRange = global.IDBKeyRange || global.webkitIDBKeyRange || global.msIDBKeyRange; - this.version = opts.version - this.logging = opts.logging - this.initialState = opts.initialState - if (this.logging) this.on('log', logger) - } - - // Opens the database connection and returns a promise - open (version = this.version) { - return new Promise((resolve, reject) => { - const dbOpenRequest = this.dbObject.open(this.key, version) - dbOpenRequest.onerror = (event) => { - return reject(event) - } - dbOpenRequest.onsuccess = (event) => { - this.db = dbOpenRequest.result - this.emit('success') - resolve(this.db) - } - dbOpenRequest.onupgradeneeded = (event) => { - this.db = event.target.result - this.db.createObjectStore('dataStore') - } - }) - .then((openRequest) => { - return this.get('dataStore') - }) - .then((data) => { - if (!data) { - return this._add('dataStore', this.initialState) - .then(() => this.get('dataStore')) - .then((versionedData) => Promise.resolve(versionedData.data)) - } - return Promise.resolve(data) - }) - } - - requestObjectStore (key, type = 'readonly') { - return new Promise((resolve, reject) => { - const dbReadWrite = this.db.transaction(key, type) - const dataStore = dbReadWrite.objectStore(key) - resolve(dataStore) - }) - } - - get (key = 'dataStore') { - return this.requestObjectStore(key) - .then((dataObject)=> { - return new Promise((resolve, reject) => { - const getRequest = dataObject.get(key) - getRequest.onsuccess = (event) => resolve(event.currentTarget.result) - getRequest.onerror = (event) => reject(event) - }) - }) - } - - put (state) { - return this.requestObjectStore('dataStore', 'readwrite') - .then((dataObject)=> { - const putRequest = dataObject.put(state, 'dataStore') - putRequest.onsuccess = (event) => Promise.resolve(event.currentTarget.result) - putRequest.onerror = (event) => Promise.reject(event) - }) - } - - _add (key, objStore, cb = logger) { - return this.requestObjectStore(key, 'readwrite') - .then((dataObject)=> { - const addRequest = dataObject.add(objStore, key) - addRequest.onsuccess = (event) => Promise.resolve(event.currentTarget.result) - addRequest.onerror = (event) => Promise.reject(event) - }) - } - -} - -function logger (err, ress) { - err ? console.error(`Logger says: ${err}`) : console.dir(`Logger says: ${ress}`) -} diff --git a/library/src/lib/setup-iframe.js b/library/src/lib/setup-iframe.js deleted file mode 100644 index db67163df..000000000 --- a/library/src/lib/setup-iframe.js +++ /dev/null @@ -1,19 +0,0 @@ -const Iframe = require('iframe') -const IframeStream = require('iframe-stream').IframeStream - -module.exports = setupIframe - - -function setupIframe(opts) { - opts = opts || {} - var frame = Iframe({ - src: opts.zeroClientProvider || 'https://zero.metamask.io/', - container: opts.container || document.head, - sandboxAttributes: opts.sandboxAttributes || ['allow-scripts', 'allow-popups'], - }) - var iframe = frame.iframe - iframe.style.setProperty('display', 'none') - var iframeStream = new IframeStream(iframe) - - return iframeStream -} diff --git a/library/src/lib/setup-provider.js b/library/src/lib/setup-provider.js deleted file mode 100644 index 4f2432ae4..000000000 --- a/library/src/lib/setup-provider.js +++ /dev/null @@ -1,22 +0,0 @@ -const setupIframe = require('./setup-iframe.js') -const MetamaskInpageProvider = require('../../../app/scripts/lib/inpage-provider.js') - -module.exports = getProvider - - -function getProvider(){ - if (global.web3) { - console.log('MetaMask ZeroClient - using environmental web3 provider') - return global.web3.currentProvider - } - console.log('MetaMask ZeroClient - injecting zero-client iframe!') - var iframeStream = setupIframe({ - zeroClientProvider: 'http://localhost:9001', - sandboxAttributes: ['allow-scripts', 'allow-popups', 'allow-same-origin'], - container: document.body, - }) - - var inpageProvider = new MetamaskInpageProvider(iframeStream) - return inpageProvider - -} diff --git a/library/src/mascara.js b/library/src/mascara.js deleted file mode 100644 index 759353c1b..000000000 --- a/library/src/mascara.js +++ /dev/null @@ -1,44 +0,0 @@ -const Web3 = require('web3') -const setupProvider = require('./lib/setup-provider.js') - -// -// setup web3 -// -var provider = setupProvider() -hijackProvider(provider) -var web3 = new Web3(provider) -web3.setProvider = function(){ - console.log('MetaMask - overrode web3.setProvider') -} -// -// -// export web3 -// - -global.web3 = web3 - -// -// ui stuff -// - -var shouldPop = false -window.addEventListener('click', function(){ - if (!shouldPop) return - shouldPop = false - window.open('http://localhost:9001/popup/popup.html', '', 'width=360 height=500') - console.log('opening window...') -}) - - -function hijackProvider(provider){ - var _super = provider.sendAsync.bind(provider) - provider.sendAsync = function(payload, cb){ - if (payload.method === 'eth_sendTransaction') { - console.log('saw send') - shouldPop = true - } - _super(payload, cb) - } -} - - diff --git a/library/src/popup.js b/library/src/popup.js deleted file mode 100644 index ef7759a81..000000000 --- a/library/src/popup.js +++ /dev/null @@ -1,36 +0,0 @@ -const injectCss = require('inject-css') -const SWcontroller = require('client-sw-ready-event/lib/sw-client.js') -const SwStream = require('sw-stream/lib/sw-stream.js') -const MetaMaskUiCss = require('../../ui/css') -const setupIframe = require('./lib/setup-iframe.js') -const MetamaskInpageProvider = require('../../app/scripts/lib/inpage-provider.js') -const startPopup = require('../../app/scripts/popup-core') - -var css = MetaMaskUiCss() -injectCss(css) -const container = document.getElementById('app-content') - -var name = 'popup' -window.METAMASK_UI_TYPE = name - -const background = new SWcontroller({ - fileName: '/popup/sw-build.js', -}) - -// Setup listener for when the service worker is read -background.on('ready', (readSw) => { - let connectionStream = SwStream({ - serviceWorker: background.controller, - context: name, - }) - startPopup({container, connectionStream}, (err, store) => { - if (err) return displayCriticalError(err) - store.subscribe(() => { - const state = store.getState() - if (state.appState.shouldClose) window.close() - }) - }) -}) - -background.startWorker() -console.log('hello from /library/popup.js') diff --git a/mascara/README.md b/mascara/README.md new file mode 100644 index 000000000..6a6574dbd --- /dev/null +++ b/mascara/README.md @@ -0,0 +1,24 @@ +start the dual servers (dapp + mascara) +``` +node server.js +``` + +open the example dapp at `http://localhost:9002/` + +*You will need to build MetaMask in order for this to work* +``` +gulp dev +``` +to build MetaMask and have it live reload if you make changes + + +## First time use: + +- navigate to: http://127.0.0.1:9001/popup/popup.html +- Create an Account +- go back to http://localhost:9002/ +- open devTools +- click Sync Tx + +### Todos +- Look into using [Service Workers](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API) diff --git a/mascara/example/index.html b/mascara/example/index.html new file mode 100644 index 000000000..47d6da34f --- /dev/null +++ b/mascara/example/index.html @@ -0,0 +1,17 @@ + + + + + + + MetaMask ZeroClient Example + + + + + + + + + + \ No newline at end of file diff --git a/mascara/example/index.js b/mascara/example/index.js new file mode 100644 index 000000000..aae7ccd19 --- /dev/null +++ b/mascara/example/index.js @@ -0,0 +1,57 @@ +window.addEventListener('load', web3Detect) +window.addEventListener('message', console.warn) + +function web3Detect() { + if (global.web3) { + logToDom('web3 detected!') + startApp() + } else { + logToDom('no web3 detected!') + } +} + +function startApp(){ + console.log('app started') + + var primaryAccount + console.log('getting main account...') + web3.eth.getAccounts((err, addresses) => { + if (err) console.error(err) + console.log('set address', addresses[0]) + primaryAccount = addresses[0] + }) + + document.querySelector('.action-button-1').addEventListener('click', function(){ + console.log('saw click') + console.log('sending tx') + primaryAccount + web3.eth.sendTransaction({ + from: primaryAccount, + to: primaryAccount, + value: 0, + }, function(err, txHash){ + if (err) throw err + console.log('sendTransaction result:', err || txHash) + }) + }) + document.querySelector('.action-button-2').addEventListener('click', function(){ + console.log('saw click') + setTimeout(function(){ + console.log('sending tx') + web3.eth.sendTransaction({ + from: primaryAccount, + to: primaryAccount, + value: 0, + }, function(err, txHash){ + if (err) throw err + console.log('sendTransaction result:', err || txHash) + }) + }) + }) + +} + +function logToDom(message){ + document.body.appendChild(document.createTextNode(message)) + console.log(message) +} diff --git a/mascara/server.js b/mascara/server.js new file mode 100644 index 000000000..67c89f11b --- /dev/null +++ b/mascara/server.js @@ -0,0 +1,103 @@ +const express = require('express') +const browserify = require('browserify') +const watchify = require('watchify') +const babelify = require('babelify') + +const zeroBundle = createBundle('./src/mascara.js') +const controllerBundle = createBundle('./src/dapp-connection.js') +const popupBundle = createBundle('./src/popup.js') +const swBuild = createBundle('./src/background.js') + +const appBundle = createBundle('./example/index.js') + +// +// Iframe Server +// + +const iframeServer = express() + +// serve popup window +iframeServer.get('/popup/scripts/popup.js', function(req, res){ + res.send(popupBundle.latest) +}) +iframeServer.use('/popup', express.static('../dist/chrome')) + +// serve controller bundle +iframeServer.get('/controller.js', function(req, res){ + res.send(controllerBundle.latest) +}) +iframeServer.get('/popup/sw-build.js', function(req, res){ + console.log('/sw-build.js') + res.setHeader('Content-Type', 'application/javascript') + res.send(swBuild.latest) +}) + +// serve background controller +iframeServer.use(express.static('./server')) + +// start the server +const mascaraPort = 9001 +iframeServer.listen(mascaraPort) +console.log(`Mascara service listening on port ${mascaraPort}`) + + +// +// Dapp Server +// + +const dappServer = express() + +// serve metamask-lib bundle +dappServer.get('/zero.js', function(req, res){ + res.send(zeroBundle.latest) +}) + +// serve dapp bundle +dappServer.get('/app.js', function(req, res){ + res.send(appBundle.latest) +}) + +// serve static +dappServer.use(express.static('./example')) + +// start the server +const dappPort = '9002' +dappServer.listen(dappPort) +console.log(`Dapp listening on port ${dappPort}`) + +// +// util +// + +function serveBundle(entryPoint){ + const bundle = createBundle(entryPoint) + return function(req, res){ + res.send(bundle.latest) + } +} + +function createBundle(entryPoint){ + + var bundleContainer = {} + + var bundler = browserify({ + entries: [entryPoint], + cache: {}, + packageCache: {}, + plugin: [watchify], + }) + + bundler.on('update', bundle) + bundle() + + return bundleContainer + + function bundle() { + bundler.bundle(function(err, result){ + if (err) throw err + console.log(`Bundle updated! (${entryPoint})`) + bundleContainer.latest = result.toString() + }) + } + +} diff --git a/mascara/server/index.html b/mascara/server/index.html new file mode 100644 index 000000000..2308dd98b --- /dev/null +++ b/mascara/server/index.html @@ -0,0 +1,20 @@ + + + + + + + MetaMask ZeroClient Iframe + + + + + + + + Hello! I am the MetaMask iframe. + + + \ No newline at end of file diff --git a/mascara/src/background.js b/mascara/src/background.js new file mode 100644 index 000000000..dd0e13239 --- /dev/null +++ b/mascara/src/background.js @@ -0,0 +1,154 @@ +global.window = global +const asyncQ = require('async-q') +const pipe = require('pump') + +const SwGlobalListener = require('sw-stream/lib/sw-global-listener.js') +const connectionListener = new SwGlobalListener(self) +const setupMultiplex = require('../../app/scripts/lib/stream-utils.js').setupMultiplex +const PortStream = require('../../app/scripts/lib/port-stream.js') + +const DbController = require('./lib/index-db-controller') + +const MetamaskController = require('../../app/scripts/metamask-controller') +const extension = {} //require('../../app/scripts/lib/extension') + +const storeTransform = require('obs-store/lib/transform') +const Migrator = require('../../app/scripts/lib/migrator/') +const migrations = require('../../app/scripts/migrations/') +const firstTimeState = require('../../app/scripts/first-time-state') + +const STORAGE_KEY = 'metamask-config' +const METAMASK_DEBUG = 'GULP_METAMASK_DEBUG' +let popupIsOpen = false + +const log = require('loglevel') +global.log = log +log.setDefaultLevel(METAMASK_DEBUG ? 'debug' : 'warn') + +self.addEventListener('install', function(event) { + event.waitUntil(self.skipWaiting()) +}) +self.addEventListener('activate', function(event) { + event.waitUntil(self.clients.claim()) +}) + +console.log('inside:open') + + +// // state persistence +let diskStore +const dbController = new DbController({ + key: STORAGE_KEY, + global: self, + version: 2, +}) +asyncQ.waterfall([ + () => loadStateFromPersistence(), + (initState) => setupController(initState), +]) +.then(() => console.log('MetaMask initialization complete.')) +.catch((err) => { + console.log('WHILE SETTING UP:') + console.error(err) +}) + +// initialization flow + +// +// State and Persistence +// +function loadStateFromPersistence() { + // migrations + let migrator = new Migrator({ migrations }) + const initialState = migrator.generateInitialState(firstTimeState) + dbController.initialState = initialState + return dbController.open() + .then((versionedData) => migrator.migrateData(versionedData)) + .then((versionedData) => { + dbController.put(versionedData) + return Promise.resolve(versionedData) + }) + .then((versionedData) => Promise.resolve(versionedData.data)) +} + +function setupController (initState, client) { + + // + // MetaMask Controller + // + + const controller = new MetamaskController({ + // User confirmation callbacks: + showUnconfirmedMessage: noop, + unlockAccountMessage: noop, + showUnapprovedTx: noop, + // initial state + initState, + }) + global.metamaskController = controller + + // setup state persistence + // pipe( + // controller.store, + // storeTransform(versionifyData), + // diskStore + // ) + controller.store.subscribe((state) => { + versionifyData(state) + .then((versionedData) => dbController.put(versionedData)) + .catch((err) => {console.error(err)}) + }) + function versionifyData(state) { + return dbController.get() + .then((rawData) => { + return Promise.resolve({ + data: state, + meta: rawData.meta, + })} + ) + } + + // + // connect to other contexts + // + /* + need to write a service worker stream for this + */ + connectionListener.on('remote', (portStream, messageEvent) => { + console.log('REMOTE CONECTION FOUND***********') + connectRemote(portStream, messageEvent.data.context) + }) + + function connectRemote (connectionStream, context) { + var isMetaMaskInternalProcess = (context === 'popup') + if (isMetaMaskInternalProcess) { + // communication with popup + controller.setupTrustedCommunication(connectionStream, 'MetaMask') + popupIsOpen = true + } else { + // communication with page + setupUntrustedCommunication(connectionStream, context) + } + } + + function setupUntrustedCommunication (connectionStream, originDomain) { + // setup multiplexing + var mx = setupMultiplex(connectionStream) + // connect features + controller.setupProviderConnection(mx.createStream('provider'), originDomain) + controller.setupPublicConfig(mx.createStream('publicConfig')) + } + + function setupTrustedCommunication (connectionStream, originDomain) { + // setup multiplexing + var mx = setupMultiplex(connectionStream) + // connect features + controller.setupProviderConnection(mx.createStream('provider'), originDomain) + } + // + // User Interface setup + // + return Promise.resolve() + +} +function noop () {} diff --git a/mascara/src/dapp-connection.js b/mascara/src/dapp-connection.js new file mode 100644 index 000000000..30680c9d7 --- /dev/null +++ b/mascara/src/dapp-connection.js @@ -0,0 +1,21 @@ +const ParentStream = require('iframe-stream').ParentStream +const SWcontroller = require('client-sw-ready-event/lib/sw-client.js') +const SwStream = require('sw-stream/lib/sw-stream.js') +const SetupUntrustedComunication = ('./lib/setup-untrusted-connection.js') + +const background = new SWcontroller({ + fileName: '/popup/sw-build.js', +}) + +const pageStream = new ParentStream() +background.on('ready', (_) => { + let swStream = SwStream({ + serviceWorker: background.controller, + context: 'dapp', + }) + pageStream.pipe(swStream).pipe(pageStream) + +}) + +background.on('error', console.error) +background.startWorker() diff --git a/mascara/src/lib/index-db-controller.js b/mascara/src/lib/index-db-controller.js new file mode 100644 index 000000000..041ddae2e --- /dev/null +++ b/mascara/src/lib/index-db-controller.js @@ -0,0 +1,88 @@ +const EventEmitter = require('events') +module.exports = class IndexDbController extends EventEmitter { + + constructor (opts) { + super() + this.migrations = opts.migrations + this.key = opts.key + this.dbObject = global.indexedDB + this.IDBTransaction = global.IDBTransaction || global.webkitIDBTransaction || global.msIDBTransaction || {READ_WRITE: "readwrite"}; // This line should only be needed if it is needed to support the object's constants for older browsers + this.IDBKeyRange = global.IDBKeyRange || global.webkitIDBKeyRange || global.msIDBKeyRange; + this.version = opts.version + this.logging = opts.logging + this.initialState = opts.initialState + if (this.logging) this.on('log', logger) + } + + // Opens the database connection and returns a promise + open (version = this.version) { + return new Promise((resolve, reject) => { + const dbOpenRequest = this.dbObject.open(this.key, version) + dbOpenRequest.onerror = (event) => { + return reject(event) + } + dbOpenRequest.onsuccess = (event) => { + this.db = dbOpenRequest.result + this.emit('success') + resolve(this.db) + } + dbOpenRequest.onupgradeneeded = (event) => { + this.db = event.target.result + this.db.createObjectStore('dataStore') + } + }) + .then((openRequest) => { + return this.get('dataStore') + }) + .then((data) => { + if (!data) { + return this._add('dataStore', this.initialState) + .then(() => this.get('dataStore')) + .then((versionedData) => Promise.resolve(versionedData.data)) + } + return Promise.resolve(data) + }) + } + + requestObjectStore (key, type = 'readonly') { + return new Promise((resolve, reject) => { + const dbReadWrite = this.db.transaction(key, type) + const dataStore = dbReadWrite.objectStore(key) + resolve(dataStore) + }) + } + + get (key = 'dataStore') { + return this.requestObjectStore(key) + .then((dataObject)=> { + return new Promise((resolve, reject) => { + const getRequest = dataObject.get(key) + getRequest.onsuccess = (event) => resolve(event.currentTarget.result) + getRequest.onerror = (event) => reject(event) + }) + }) + } + + put (state) { + return this.requestObjectStore('dataStore', 'readwrite') + .then((dataObject)=> { + const putRequest = dataObject.put(state, 'dataStore') + putRequest.onsuccess = (event) => Promise.resolve(event.currentTarget.result) + putRequest.onerror = (event) => Promise.reject(event) + }) + } + + _add (key, objStore, cb = logger) { + return this.requestObjectStore(key, 'readwrite') + .then((dataObject)=> { + const addRequest = dataObject.add(objStore, key) + addRequest.onsuccess = (event) => Promise.resolve(event.currentTarget.result) + addRequest.onerror = (event) => Promise.reject(event) + }) + } + +} + +function logger (err, ress) { + err ? console.error(`Logger says: ${err}`) : console.dir(`Logger says: ${ress}`) +} diff --git a/mascara/src/lib/setup-iframe.js b/mascara/src/lib/setup-iframe.js new file mode 100644 index 000000000..db67163df --- /dev/null +++ b/mascara/src/lib/setup-iframe.js @@ -0,0 +1,19 @@ +const Iframe = require('iframe') +const IframeStream = require('iframe-stream').IframeStream + +module.exports = setupIframe + + +function setupIframe(opts) { + opts = opts || {} + var frame = Iframe({ + src: opts.zeroClientProvider || 'https://zero.metamask.io/', + container: opts.container || document.head, + sandboxAttributes: opts.sandboxAttributes || ['allow-scripts', 'allow-popups'], + }) + var iframe = frame.iframe + iframe.style.setProperty('display', 'none') + var iframeStream = new IframeStream(iframe) + + return iframeStream +} diff --git a/mascara/src/lib/setup-provider.js b/mascara/src/lib/setup-provider.js new file mode 100644 index 000000000..4f2432ae4 --- /dev/null +++ b/mascara/src/lib/setup-provider.js @@ -0,0 +1,22 @@ +const setupIframe = require('./setup-iframe.js') +const MetamaskInpageProvider = require('../../../app/scripts/lib/inpage-provider.js') + +module.exports = getProvider + + +function getProvider(){ + if (global.web3) { + console.log('MetaMask ZeroClient - using environmental web3 provider') + return global.web3.currentProvider + } + console.log('MetaMask ZeroClient - injecting zero-client iframe!') + var iframeStream = setupIframe({ + zeroClientProvider: 'http://localhost:9001', + sandboxAttributes: ['allow-scripts', 'allow-popups', 'allow-same-origin'], + container: document.body, + }) + + var inpageProvider = new MetamaskInpageProvider(iframeStream) + return inpageProvider + +} diff --git a/mascara/src/mascara.js b/mascara/src/mascara.js new file mode 100644 index 000000000..759353c1b --- /dev/null +++ b/mascara/src/mascara.js @@ -0,0 +1,44 @@ +const Web3 = require('web3') +const setupProvider = require('./lib/setup-provider.js') + +// +// setup web3 +// +var provider = setupProvider() +hijackProvider(provider) +var web3 = new Web3(provider) +web3.setProvider = function(){ + console.log('MetaMask - overrode web3.setProvider') +} +// +// +// export web3 +// + +global.web3 = web3 + +// +// ui stuff +// + +var shouldPop = false +window.addEventListener('click', function(){ + if (!shouldPop) return + shouldPop = false + window.open('http://localhost:9001/popup/popup.html', '', 'width=360 height=500') + console.log('opening window...') +}) + + +function hijackProvider(provider){ + var _super = provider.sendAsync.bind(provider) + provider.sendAsync = function(payload, cb){ + if (payload.method === 'eth_sendTransaction') { + console.log('saw send') + shouldPop = true + } + _super(payload, cb) + } +} + + diff --git a/mascara/src/popup.js b/mascara/src/popup.js new file mode 100644 index 000000000..ef7759a81 --- /dev/null +++ b/mascara/src/popup.js @@ -0,0 +1,36 @@ +const injectCss = require('inject-css') +const SWcontroller = require('client-sw-ready-event/lib/sw-client.js') +const SwStream = require('sw-stream/lib/sw-stream.js') +const MetaMaskUiCss = require('../../ui/css') +const setupIframe = require('./lib/setup-iframe.js') +const MetamaskInpageProvider = require('../../app/scripts/lib/inpage-provider.js') +const startPopup = require('../../app/scripts/popup-core') + +var css = MetaMaskUiCss() +injectCss(css) +const container = document.getElementById('app-content') + +var name = 'popup' +window.METAMASK_UI_TYPE = name + +const background = new SWcontroller({ + fileName: '/popup/sw-build.js', +}) + +// Setup listener for when the service worker is read +background.on('ready', (readSw) => { + let connectionStream = SwStream({ + serviceWorker: background.controller, + context: name, + }) + startPopup({container, connectionStream}, (err, store) => { + if (err) return displayCriticalError(err) + store.subscribe(() => { + const state = store.getState() + if (state.appState.shouldClose) window.close() + }) + }) +}) + +background.startWorker() +console.log('hello from /library/popup.js') -- cgit From 0adbc87316402349d462bbd7bc89e887d4b3b3c2 Mon Sep 17 00:00:00 2001 From: frankiebee Date: Mon, 3 Apr 2017 11:34:01 +0200 Subject: Update MetaMascara README --- mascara/README.md | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/mascara/README.md b/mascara/README.md index 6a6574dbd..7045ea8bb 100644 --- a/mascara/README.md +++ b/mascara/README.md @@ -3,22 +3,14 @@ start the dual servers (dapp + mascara) node server.js ``` -open the example dapp at `http://localhost:9002/` - -*You will need to build MetaMask in order for this to work* -``` -gulp dev -``` -to build MetaMask and have it live reload if you make changes - - ## First time use: -- navigate to: http://127.0.0.1:9001/popup/popup.html +- navigate to: http://localhost:9001/popup/popup.html - Create an Account - go back to http://localhost:9002/ - open devTools - click Sync Tx ### Todos -- Look into using [Service Workers](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API) + + - [ ] Figure out user flows and UI redesign -- cgit From 5baa4fd8968092d605a8768c9934cf4e9b8a820d Mon Sep 17 00:00:00 2001 From: frankiebee Date: Mon, 3 Apr 2017 13:29:19 +0200 Subject: Update todos on README --- mascara/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mascara/README.md b/mascara/README.md index 7045ea8bb..cdeb4795c 100644 --- a/mascara/README.md +++ b/mascara/README.md @@ -14,3 +14,7 @@ node server.js ### Todos - [ ] Figure out user flows and UI redesign + - [ ] Figure out FireFox + Standing problems: + - [ ] IndexDb + -- cgit From 16c24db13b1c5da7afc222022af4bebf0f42f3aa Mon Sep 17 00:00:00 2001 From: frankiebee Date: Tue, 4 Apr 2017 11:08:10 +0200 Subject: Fix first install flow --- mascara/src/background.js | 13 +++---------- mascara/src/lib/index-db-controller.js | 2 +- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/mascara/src/background.js b/mascara/src/background.js index dd0e13239..fbfffa9b8 100644 --- a/mascara/src/background.js +++ b/mascara/src/background.js @@ -1,5 +1,4 @@ global.window = global -const asyncQ = require('async-q') const pipe = require('pump') const SwGlobalListener = require('sw-stream/lib/sw-global-listener.js') @@ -39,18 +38,12 @@ console.log('inside:open') let diskStore const dbController = new DbController({ key: STORAGE_KEY, - global: self, version: 2, }) -asyncQ.waterfall([ - () => loadStateFromPersistence(), - (initState) => setupController(initState), -]) +loadStateFromPersistence() +.then((initState) => setupController(initState)) .then(() => console.log('MetaMask initialization complete.')) -.catch((err) => { - console.log('WHILE SETTING UP:') - console.error(err) -}) +.catch((err) => console.error('WHILE SETTING UP:', err)) // initialization flow diff --git a/mascara/src/lib/index-db-controller.js b/mascara/src/lib/index-db-controller.js index 041ddae2e..8db1d5d21 100644 --- a/mascara/src/lib/index-db-controller.js +++ b/mascara/src/lib/index-db-controller.js @@ -38,7 +38,7 @@ module.exports = class IndexDbController extends EventEmitter { if (!data) { return this._add('dataStore', this.initialState) .then(() => this.get('dataStore')) - .then((versionedData) => Promise.resolve(versionedData.data)) + .then((versionedData) => Promise.resolve(versionedData)) } return Promise.resolve(data) }) -- cgit From 5e939540e575147ae7d1bca16e36701ce0a61340 Mon Sep 17 00:00:00 2001 From: frankiebee Date: Tue, 4 Apr 2017 14:25:52 +0200 Subject: Remove out of date comments --- mascara/src/background.js | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/mascara/src/background.js b/mascara/src/background.js index fbfffa9b8..6f9fb3d13 100644 --- a/mascara/src/background.js +++ b/mascara/src/background.js @@ -80,12 +80,6 @@ function setupController (initState, client) { }) global.metamaskController = controller - // setup state persistence - // pipe( - // controller.store, - // storeTransform(versionifyData), - // diskStore - // ) controller.store.subscribe((state) => { versionifyData(state) .then((versionedData) => dbController.put(versionedData)) @@ -104,9 +98,7 @@ function setupController (initState, client) { // // connect to other contexts // - /* - need to write a service worker stream for this - */ + connectionListener.on('remote', (portStream, messageEvent) => { console.log('REMOTE CONECTION FOUND***********') connectRemote(portStream, messageEvent.data.context) -- cgit From 4779999bfc7e03eedf3fd2702f7f448d751218f8 Mon Sep 17 00:00:00 2001 From: kumavis Date: Tue, 4 Apr 2017 11:13:07 -0700 Subject: clean - metamask controller - remove log --- app/scripts/metamask-controller.js | 1 - 1 file changed, 1 deletion(-) diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index d360e7d95..040c093df 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -167,7 +167,6 @@ module.exports = class MetamaskController extends EventEmitter { rpcUrl: this.configManager.getCurrentRpcAddress(), // account mgmt getAccounts: (cb) => { - console.log('METAMASK CONTROLLER: getAccounts was called') let selectedAddress = this.preferencesController.getSelectedAddress() let result = selectedAddress ? [selectedAddress] : [] cb(null, result) -- cgit