Use ApiFactory and a getter for profile.

pull/1/head
Grandschtroumpf 6 years ago
parent 1562d25378
commit bf669ec817
  1. 63
      src/app.js
  2. 33
      src/app/components/plugin-manager-component.js
  3. 7
      src/app/editor/SourceHighlighters.js
  4. 7
      src/app/files/remixd-handle.js
  5. 33
      src/app/panels/file-panel.js
  6. 7
      src/app/tabs/analysis-tab.js
  7. 29
      src/app/tabs/compile-tab.js
  8. 8
      src/app/tabs/debugger-tab.js
  9. 28
      src/app/tabs/run-tab.js
  10. 10
      src/app/tabs/settings-tab.js
  11. 9
      src/app/tabs/support-tab.js
  12. 9
      src/app/tabs/test-tab.js
  13. 22
      src/app/tabs/txlistener-module.js
  14. 73
      src/app/ui/landing-page/generate.js
  15. 78
      src/app/ui/landing-page/landing-page.js
  16. 138
      src/universal-dapp.js

@ -7,7 +7,6 @@ var async = require('async')
var request = require('request') var request = require('request')
var remixLib = require('remix-lib') var remixLib = require('remix-lib')
var EventManager = require('./lib/events') var EventManager = require('./lib/events')
var EventEmitter = require('events')
var registry = require('./global/registry') var registry = require('./global/registry')
var UniversalDApp = require('./universal-dapp.js') var UniversalDApp = require('./universal-dapp.js')
var UniversalDAppUI = require('./universal-dapp-ui.js') var UniversalDAppUI = require('./universal-dapp-ui.js')
@ -55,8 +54,10 @@ const FilePanel = require('./app/panels/file-panel')
import PanelsResize from './lib/panels-resize' import PanelsResize from './lib/panels-resize'
import { EntityStore } from './lib/store' import { EntityStore } from './lib/store'
import { RemixAppManager } from './remixAppManager' import { RemixAppManager } from './remixAppManager'
import { generateHomePage, homepageProfile } from './app/ui/landing-page/generate' import { LandingPage } from './app/ui/landing-page/landing-page'
import framingService from './framingService' import framingService from './framingService'
import { ApiFactory } from 'remix-plugin'
import { TxListenerModule } from './app/tabs/txlistener-module'
var css = csjs` var css = csjs`
html { box-sizing: border-box; } html { box-sizing: border-box; }
@ -116,8 +117,9 @@ var css = csjs`
} }
` `
class App { class App extends ApiFactory {
constructor (api = {}, events = {}, opts = {}) { constructor (api = {}, events = {}, opts = {}) {
super()
var self = this var self = this
this.event = new EventManager() this.event = new EventManager()
self._components = {} self._components = {}
@ -173,7 +175,7 @@ class App {
run.apply(self) run.apply(self)
} }
profile () { get profile () {
return { return {
name: 'app', name: 'app',
description: 'service - provides information about current context (network).', description: 'service - provides information about current context (network).',
@ -373,26 +375,13 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
/* /*
that proxy is used by appManager to broadcast new transaction event that proxy is used by appManager to broadcast new transaction event
*/ */
const txListenerModuleProxy = { const txListenerModule = new TxListenerModule(txlistener)
event: new EventEmitter(),
profile () {
return {
name: 'txListener',
displayName: 'transaction listener',
events: ['newTransaction'],
description: 'service - notify new transactions'
}
}
}
txlistener.event.register('newTransaction', (tx) => {
txListenerModuleProxy.event.emit('newTransaction', tx)
})
txlistener.startListening() txlistener.startListening()
// TODO: There are still a lot of dep between editorpanel and filemanager // TODO: There are still a lot of dep between editorpanel and filemanager
let appStore = new EntityStore('module', { actives: [], ids: [], entities: {} }) let appStore = new EntityStore('module', 'name')
const appManager = new RemixAppManager(appStore) const appManager = new RemixAppManager(appStore)
registry.put({api: appManager, name: 'appmanager'}) registry.put({api: appManager, name: 'appmanager'})
@ -458,33 +447,35 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
let settings = new SettingsTab(self._components.registry) let settings = new SettingsTab(self._components.registry)
let analysis = new AnalysisTab(registry) let analysis = new AnalysisTab(registry)
let debug = new DebuggerTab() let debug = new DebuggerTab()
const landingPage = new LandingPage(appManager, appStore)
// let support = new SupportTab() // let support = new SupportTab()
let test = new TestTab(self._components.registry, compileTab) let test = new TestTab(self._components.registry, compileTab)
let sourceHighlighters = registry.get('editor').api.sourceHighlighters let sourceHighlighters = registry.get('editor').api.sourceHighlighters
let configProvider = self._components.filesProviders['config'] let configProvider = self._components.filesProviders['config']
appManager.init([ appManager.init([
{ profile: homepageProfile(), api: generateHomePage(appManager, appStore) }, this.api(),
{ profile: this.profile(), api: this }, landingPage.api(),
{ profile: udapp.profile(), api: udapp }, udapp.api(),
{ profile: fileManager.profile(), api: fileManager }, fileManager.api(),
{ profile: sourceHighlighters.profile(), api: sourceHighlighters }, sourceHighlighters.api(),
{ profile: configProvider.profile(), api: configProvider }, configProvider.api(),
{ profile: txListenerModuleProxy.profile(), api: txListenerModuleProxy }, txListenerModule.api(),
{ profile: filePanel.profile(), api: filePanel }, filePanel.api(),
// { profile: support.profile(), api: support }, // { profile: support.profile(), api: support },
{ profile: settings.profile(), api: settings }, settings.api(),
{ profile: pluginManagerComponent.profile(), api: pluginManagerComponent }]) pluginManagerComponent.api()
])
appManager.registerMany([ appManager.registerMany([
{ profile: compileTab.profile(), api: compileTab }, compileTab.api(),
{ profile: run.profile(), api: run }, run.api(),
{ profile: debug.profile(), api: debug }, debug.api(),
{ profile: analysis.profile(), api: analysis }, analysis.api(),
{ profile: test.profile(), api: test }, test.api(),
{ profile: filePanel.remixdHandle.profile(), api: filePanel.remixdHandle } filePanel.remixdHandle.api(),
...appManager.plugins()
]) ])
appManager.registerMany(appManager.plugins())
framingService.start(appStore, swapPanelApi, verticalIconsApi, mainPanelApi, this._components.resizeFeature) framingService.start(appStore, swapPanelApi, verticalIconsApi, mainPanelApi, this._components.resizeFeature)

@ -2,7 +2,7 @@ const yo = require('yo-yo')
const csjs = require('csjs-inject') const csjs = require('csjs-inject')
const EventEmitter = require('events') const EventEmitter = require('events')
const LocalPlugin = require('./local-plugin') const LocalPlugin = require('./local-plugin')
import { Plugin } from 'remix-plugin' import { Plugin, ApiFactory } from 'remix-plugin'
const css = csjs` const css = csjs`
.pluginSearch { .pluginSearch {
@ -34,9 +34,10 @@ const css = csjs`
} }
` `
class PluginManagerComponent { class PluginManagerComponent extends ApiFactory {
constructor () { constructor () {
super()
this.event = new EventEmitter() this.event = new EventEmitter()
this.views = { this.views = {
root: null, root: null,
@ -46,7 +47,7 @@ class PluginManagerComponent {
this.filter = '' this.filter = ''
} }
profile () { get profile () {
return { return {
displayName: 'plugin manager', displayName: 'plugin manager',
name: 'pluginManager', name: 'pluginManager',
@ -71,10 +72,10 @@ class PluginManagerComponent {
} }
renderItem (name) { renderItem (name) {
const mod = this.store.getOne(name) const api = this.store.getOne(name)
if (!mod) return if (!api) return
const isActive = this.store.actives.includes(name) const isActive = this.store.actives.includes(name)
const displayName = (mod.profile.displayName) ? mod.profile.displayName : name const displayName = (api.profile.displayName) ? api.profile.displayName : name
const activationButton = isActive const activationButton = isActive
? yo` ? yo`
@ -92,7 +93,7 @@ class PluginManagerComponent {
<h6 class="${css.displayName}">${displayName}</h6> <h6 class="${css.displayName}">${displayName}</h6>
${activationButton} ${activationButton}
</div> </div>
<p class="${css.description}">${mod.profile.description}</p> <p class="${css.description}">${api.profile.description}</p>
</article> </article>
` `
} }
@ -109,8 +110,8 @@ class PluginManagerComponent {
if (!profile) return if (!profile) return
const resolveLocaton = (iframe) => this.appManager.resolveLocation(profile, iframe) const resolveLocaton = (iframe) => this.appManager.resolveLocation(profile, iframe)
const api = new Plugin(profile, { resolveLocaton }) const api = new Plugin(profile, { resolveLocaton })
this.appManager.registerOne({profile, api}) this.appManager.registerOne(api)
this.appManager.activateOne(profile.name) this.appManager.activateOne(api.name)
} catch (err) { } catch (err) {
// TODO : Use an alert to handle this error instead of a console.log // TODO : Use an alert to handle this error instead of a console.log
console.log(`Cannot create Plugin : ${err.message}`) console.log(`Cannot create Plugin : ${err.message}`)
@ -119,11 +120,11 @@ class PluginManagerComponent {
render () { render () {
// Filtering helpers // Filtering helpers
const isFiltered = ({profile}) => profile.name.toLowerCase().includes(this.filter) const isFiltered = (api) => api.name.toLowerCase().includes(this.filter)
const isNotRequired = ({profile}) => !profile.required const isNotRequired = ({profile}) => !profile.required
const sortByName = (a, b) => { const sortByName = (a, b) => {
const nameA = a.profile.name.toUpperCase() const nameA = a.name.toUpperCase()
const nameB = b.profile.name.toUpperCase() const nameB = b.name.toUpperCase()
return (nameA < nameB) ? -1 : (nameA > nameB) ? 1 : 0 return (nameA < nameB) ? -1 : (nameA > nameB) ? 1 : 0
} }
@ -132,10 +133,10 @@ class PluginManagerComponent {
.filter(isFiltered) .filter(isFiltered)
.filter(isNotRequired) .filter(isNotRequired)
.sort(sortByName) .sort(sortByName)
.reduce(({actives, inactives}, {profile}) => { .reduce(({actives, inactives}, api) => {
return this.store.actives.includes(profile.name) return this.store.actives.includes(api.name)
? { actives: [...actives, profile.name], inactives } ? { actives: [...actives, api.name], inactives }
: { inactives: [...inactives, profile.name], actives } : { inactives: [...inactives, api.name], actives }
}, { actives: [], inactives: [] }) }, { actives: [], inactives: [] })
const activeTile = actives.length !== 0 const activeTile = actives.length !== 0

@ -1,13 +1,16 @@
'use strict' 'use strict'
const SourceHighlighter = require('./sourceHighlighter') const SourceHighlighter = require('./sourceHighlighter')
class SourceHighlighters { import { ApiFactory } from 'remix-plugin'
class SourceHighlighters extends ApiFactory {
constructor () { constructor () {
super()
this.highlighters = {} this.highlighters = {}
} }
profile () { get profile () {
return { return {
displayName: 'source highlighters', displayName: 'source highlighters',
name: 'sourceHighlighters', name: 'sourceHighlighters',

@ -1,3 +1,5 @@
import { ApiFactory } from 'remix-plugin'
var yo = require('yo-yo') var yo = require('yo-yo')
var modalDialog = require('../ui/modaldialog') var modalDialog = require('../ui/modaldialog')
@ -14,13 +16,14 @@ var css = csjs`
} }
` `
export class RemixdHandle { export class RemixdHandle extends ApiFactory {
constructor (fileSystemExplorer, locahostProvider) { constructor (fileSystemExplorer, locahostProvider) {
super()
this.fileSystemExplorer = fileSystemExplorer this.fileSystemExplorer = fileSystemExplorer
this.locahostProvider = locahostProvider this.locahostProvider = locahostProvider
} }
profile () { get profile () {
return { return {
name: 'remixd', name: 'remixd',
methods: [], methods: [],

@ -17,6 +17,8 @@ var globalRegistry = require('../../global/registry')
var css = require('./styles/file-panel-styles') var css = require('./styles/file-panel-styles')
import { ApiFactory } from 'remix-plugin'
var canUpload = window.File || window.FileReader || window.FileList || window.Blob var canUpload = window.File || window.FileReader || window.FileList || window.Blob
/* /*
@ -36,7 +38,10 @@ var canUpload = window.File || window.FileReader || window.FileList || window.Bl
- call fileProvider API - call fileProvider API
*/ */
function filepanel (localRegistry) { module.exports = class Filepanel extends ApiFactory {
constructor (localRegistry) {
super()
var self = this var self = this
self._components = {} self._components = {}
self._components.registry = localRegistry || globalRegistry self._components.registry = localRegistry || globalRegistry
@ -163,18 +168,6 @@ function filepanel (localRegistry) {
self.render = function render () { return element } self.render = function render () { return element }
self.profile = function () {
return {
name: 'fileExplorers',
displayName: 'file explorers',
methods: [],
events: [],
icon: 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xNjk2IDM4NHE0MCAwIDY4IDI4dDI4IDY4djEyMTZxMCA0MC0yOCA2OHQtNjggMjhoLTk2MHEtNDAgMC02OC0yOHQtMjgtNjh2LTI4OGgtNTQ0cS00MCAwLTY4LTI4dC0yOC02OHYtNjcycTAtNDAgMjAtODh0NDgtNzZsNDA4LTQwOHEyOC0yOCA3Ni00OHQ4OC0yMGg0MTZxNDAgMCA2OCAyOHQyOCA2OHYzMjhxNjgtNDAgMTI4LTQwaDQxNnptLTU0NCAyMTNsLTI5OSAyOTloMjk5di0yOTl6bS02NDAtMzg0bC0yOTkgMjk5aDI5OXYtMjk5em0xOTYgNjQ3bDMxNi0zMTZ2LTQxNmgtMzg0djQxNnEwIDQwLTI4IDY4dC02OCAyOGgtNDE2djY0MGg1MTJ2LTI1NnEwLTQwIDIwLTg4dDQ4LTc2em05NTYgODA0di0xMTUyaC0zODR2NDE2cTAgNDAtMjggNjh0LTY4IDI4aC00MTZ2NjQwaDg5NnoiLz48L3N2Zz4=',
description: ' - ',
kind: 'fileexplorer'
}
}
function uploadFile (event) { function uploadFile (event) {
// TODO The file explorer is merely a view on the current state of // TODO The file explorer is merely a view on the current state of
// the files module. Please ask the user here if they want to overwrite // the files module. Please ask the user here if they want to overwrite
@ -317,6 +310,19 @@ function filepanel (localRegistry) {
}) })
} }
} }
}
get profile () {
return {
name: 'fileExplorers',
displayName: 'file explorers',
methods: [],
events: [],
icon: 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xNjk2IDM4NHE0MCAwIDY4IDI4dDI4IDY4djEyMTZxMCA0MC0yOCA2OHQtNjggMjhoLTk2MHEtNDAgMC02OC0yOHQtMjgtNjh2LTI4OGgtNTQ0cS00MCAwLTY4LTI4dC0yOC02OHYtNjcycTAtNDAgMjAtODh0NDgtNzZsNDA4LTQwOHEyOC0yOCA3Ni00OHQ4OC0yMGg0MTZxNDAgMCA2OCAyOHQyOCA2OHYzMjhxNjgtNDAgMTI4LTQwaDQxNnptLTU0NCAyMTNsLTI5OSAyOTloMjk5di0yOTl6bS02NDAtMzg0bC0yOTkgMjk5aDI5OXYtMjk5em0xOTYgNjQ3bDMxNi0zMTZ2LTQxNmgtMzg0djQxNnEwIDQwLTI4IDY4dC02OCAyOGgtNDE2djY0MGg1MTJ2LTI1NnEwLTQwIDIwLTg4dDQ4LTc2em05NTYgODA0di0xMTUyaC0zODR2NDE2cTAgNDAtMjggNjh0LTY4IDI4aC00MTZ2NjQwaDg5NnoiLz48L3N2Zz4=',
description: ' - ',
kind: 'fileexplorer'
}
}
} }
// return all the files, except the temporary/readonly ones.. // return all the files, except the temporary/readonly ones..
@ -340,4 +346,3 @@ function packageFiles (filesProvider, callback) {
}) })
} }
module.exports = filepanel

@ -3,13 +3,16 @@ var StaticAnalysis = require('../staticanalysis/staticAnalysisView')
var EventManager = require('../../lib/events') var EventManager = require('../../lib/events')
var css = require('./styles/analysis-tab-styles') var css = require('./styles/analysis-tab-styles')
class AnalysisTab { import { ApiFactory } from 'remix-plugin'
class AnalysisTab extends ApiFactory {
constructor (registry) { constructor (registry) {
super()
this.event = new EventManager() this.event = new EventManager()
this.registry = registry this.registry = registry
} }
profile () { get profile () {
return { return {
name: 'solidityStaticAnalysis', name: 'solidityStaticAnalysis',
displayName: 'solidity static analysis', displayName: 'solidity static analysis',

@ -17,9 +17,12 @@ var css = require('./styles/compile-tab-styles')
const CompileTabLogic = require('./compileTab/compileTab.js') const CompileTabLogic = require('./compileTab/compileTab.js')
const CompilerContainer = require('./compileTab/compilerContainer.js') const CompilerContainer = require('./compileTab/compilerContainer.js')
class CompileTab { import { ApiFactory } from 'remix-plugin'
class CompileTab extends ApiFactory {
constructor (registry) { constructor (registry) {
super()
this.events = new EventEmitter() this.events = new EventEmitter()
this._view = { this._view = {
el: null, el: null,
@ -56,6 +59,18 @@ class CompileTab {
) )
} }
get profile () {
return {
displayName: 'solidity compiler',
name: 'solidity',
methods: ['getCompilationResult'],
events: ['compilationFinished'],
icon: 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDE2LjAuMywgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zOnNrZXRjaD0iaHR0cDovL3d3dy5ib2hlbWlhbmNvZGluZy5jb20vc2tldGNoL25zIgoJIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iMTMwMHB4IiBoZWlnaHQ9IjEzMDBweCIKCSB2aWV3Qm94PSIwIDAgMTMwMCAxMzAwIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxMzAwIDEzMDAiIHhtbDpzcGFjZT0icHJlc2VydmUiPgo8dGl0bGU+VmVjdG9yIDE8L3RpdGxlPgo8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KPGcgaWQ9IlBhZ2UtMSIgc2tldGNoOnR5cGU9Ik1TUGFnZSI+Cgk8ZyBpZD0ic29saWRpdHkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDQwMi4wMDAwMDAsIDExOC4wMDAwMDApIiBza2V0Y2g6dHlwZT0iTVNMYXllckdyb3VwIj4KCQk8ZyBpZD0iR3JvdXAiIHNrZXRjaDp0eXBlPSJNU1NoYXBlR3JvdXAiPgoJCQk8cGF0aCBpZD0iU2hhcGUiIG9wYWNpdHk9IjAuNDUiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgICAgIiBkPSJNMzcxLjc3MiwxMzUuMzA4TDI0MS4wNjgsMzY3LjYxSC0yMC4xNThsMTMwLjYxNC0yMzIuMzAyCgkJCQlIMzcxLjc3MiIvPgoJCQk8cGF0aCBpZD0iU2hhcGVfMV8iIG9wYWNpdHk9IjAuNiIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAgICAiIGQ9Ik0yNDEuMDY4LDM2Ny42MWgyNjEuMzE4TDM3MS43NzIsMTM1LjMwOEgxMTAuNDU2CgkJCQlMMjQxLjA2OCwzNjcuNjF6Ii8+CgkJCTxwYXRoIGlkPSJTaGFwZV8yXyIgb3BhY2l0eT0iMC44IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3ICAgICIgZD0iTTExMC40NTYsNTk5LjgyMkwyNDEuMDY4LDM2Ny42MUwxMTAuNDU2LDEzNS4zMDgKCQkJCUwtMjAuMTU4LDM2Ny42MUwxMTAuNDU2LDU5OS44MjJ6Ii8+CgkJCTxwYXRoIGlkPSJTaGFwZV8zXyIgb3BhY2l0eT0iMC40NSIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAgICAiIGQ9Ik0xMTEuNzIxLDk0OC4yNzVsMTMwLjcwNC0yMzIuMzAzaDI2MS4zMThMMzczLjAzOCw5NDguMjc1CgkJCQlIMTExLjcyMSIvPgoJCQk8cGF0aCBpZD0iU2hhcGVfNF8iIG9wYWNpdHk9IjAuNiIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAgICAiIGQ9Ik0yNDIuNDI0LDcxNS45NzNILTE4Ljg5M2wxMzAuNjEzLDIzMi4zMDNoMjYxLjMxNwoJCQkJTDI0Mi40MjQsNzE1Ljk3M3oiLz4KCQkJPHBhdGggaWQ9IlNoYXBlXzVfIiBvcGFjaXR5PSIwLjgiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgICAgIiBkPSJNMzczLjAzOCw0ODMuNzYxTDI0Mi40MjQsNzE1Ljk3M2wxMzAuNjE0LDIzMi4zMDMKCQkJCWwxMzAuNzA0LTIzMi4zMDNMMzczLjAzOCw0ODMuNzYxeiIvPgoJCTwvZz4KCTwvZz4KPC9nPgo8L3N2Zz4K',
description: 'compile solidity contracts',
kind: 'compile'
}
}
activate () { activate () {
this.listenToEvents() this.listenToEvents()
this.compilerContainer.activate() this.compilerContainer.activate()
@ -131,18 +146,6 @@ class CompileTab {
}) })
} }
profile () {
return {
displayName: 'solidity compiler',
name: 'solidity',
methods: ['getCompilationResult'],
events: ['compilationFinished'],
icon: 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDE2LjAuMywgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zOnNrZXRjaD0iaHR0cDovL3d3dy5ib2hlbWlhbmNvZGluZy5jb20vc2tldGNoL25zIgoJIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iMTMwMHB4IiBoZWlnaHQ9IjEzMDBweCIKCSB2aWV3Qm94PSIwIDAgMTMwMCAxMzAwIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxMzAwIDEzMDAiIHhtbDpzcGFjZT0icHJlc2VydmUiPgo8dGl0bGU+VmVjdG9yIDE8L3RpdGxlPgo8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KPGcgaWQ9IlBhZ2UtMSIgc2tldGNoOnR5cGU9Ik1TUGFnZSI+Cgk8ZyBpZD0ic29saWRpdHkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDQwMi4wMDAwMDAsIDExOC4wMDAwMDApIiBza2V0Y2g6dHlwZT0iTVNMYXllckdyb3VwIj4KCQk8ZyBpZD0iR3JvdXAiIHNrZXRjaDp0eXBlPSJNU1NoYXBlR3JvdXAiPgoJCQk8cGF0aCBpZD0iU2hhcGUiIG9wYWNpdHk9IjAuNDUiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgICAgIiBkPSJNMzcxLjc3MiwxMzUuMzA4TDI0MS4wNjgsMzY3LjYxSC0yMC4xNThsMTMwLjYxNC0yMzIuMzAyCgkJCQlIMzcxLjc3MiIvPgoJCQk8cGF0aCBpZD0iU2hhcGVfMV8iIG9wYWNpdHk9IjAuNiIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAgICAiIGQ9Ik0yNDEuMDY4LDM2Ny42MWgyNjEuMzE4TDM3MS43NzIsMTM1LjMwOEgxMTAuNDU2CgkJCQlMMjQxLjA2OCwzNjcuNjF6Ii8+CgkJCTxwYXRoIGlkPSJTaGFwZV8yXyIgb3BhY2l0eT0iMC44IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3ICAgICIgZD0iTTExMC40NTYsNTk5LjgyMkwyNDEuMDY4LDM2Ny42MUwxMTAuNDU2LDEzNS4zMDgKCQkJCUwtMjAuMTU4LDM2Ny42MUwxMTAuNDU2LDU5OS44MjJ6Ii8+CgkJCTxwYXRoIGlkPSJTaGFwZV8zXyIgb3BhY2l0eT0iMC40NSIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAgICAiIGQ9Ik0xMTEuNzIxLDk0OC4yNzVsMTMwLjcwNC0yMzIuMzAzaDI2MS4zMThMMzczLjAzOCw5NDguMjc1CgkJCQlIMTExLjcyMSIvPgoJCQk8cGF0aCBpZD0iU2hhcGVfNF8iIG9wYWNpdHk9IjAuNiIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAgICAiIGQ9Ik0yNDIuNDI0LDcxNS45NzNILTE4Ljg5M2wxMzAuNjEzLDIzMi4zMDNoMjYxLjMxNwoJCQkJTDI0Mi40MjQsNzE1Ljk3M3oiLz4KCQkJPHBhdGggaWQ9IlNoYXBlXzVfIiBvcGFjaXR5PSIwLjgiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgICAgIiBkPSJNMzczLjAzOCw0ODMuNzYxTDI0Mi40MjQsNzE1Ljk3M2wxMzAuNjE0LDIzMi4zMDMKCQkJCWwxMzAuNzA0LTIzMi4zMDNMMzczLjAzOCw0ODMuNzYxeiIvPgoJCTwvZz4KCTwvZz4KPC9nPgo8L3N2Zz4K',
description: 'compile solidity contracts',
kind: 'compile'
}
}
getCompilationResult () { getCompilationResult () {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
resolve(this.compileTabLogic.compiler.lastCompilationResult) resolve(this.compileTabLogic.compiler.lastCompilationResult)

@ -3,12 +3,16 @@ var css = require('./styles/debugger-tab-styles')
var DebuggerUI = require('../debugger/debuggerUI') var DebuggerUI = require('../debugger/debuggerUI')
class DebuggerTab { import { ApiFactory } from 'remix-plugin'
class DebuggerTab extends ApiFactory {
constructor () { constructor () {
super()
this.el = null this.el = null
} }
profile () { get profile () {
return { return {
displayName: 'debugger', displayName: 'debugger',
name: 'debugger', name: 'debugger',

@ -12,9 +12,12 @@ var ContractDropdownUI = require('./runTab/contractDropdown.js')
var Recorder = require('./runTab/model/recorder.js') var Recorder = require('./runTab/model/recorder.js')
var RecorderUI = require('./runTab/recorder.js') var RecorderUI = require('./runTab/recorder.js')
class RunTab { import { ApiFactory } from 'remix-plugin'
class RunTab extends ApiFactory {
constructor (udapp, udappUI, config, fileManager, editor, logCallback, filePanel, pluginManager, compilersArtefacts) { constructor (udapp, udappUI, config, fileManager, editor, logCallback, filePanel, pluginManager, compilersArtefacts) {
super()
this.event = new EventManager() this.event = new EventManager()
this.renderInstanceContainer() this.renderInstanceContainer()
@ -25,6 +28,18 @@ class RunTab {
this.renderContainer() this.renderContainer()
} }
get profile () {
return {
name: 'run',
displayName: 'run transactions',
methods: [],
events: [],
icon: 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xNTc2IDkyN2wtMTMyOCA3MzhxLTIzIDEzLTM5LjUgM3QtMTYuNS0zNnYtMTQ3MnEwLTI2IDE2LjUtMzZ0MzkuNSAzbDEzMjggNzM4cTIzIDEzIDIzIDMxdC0yMyAzMXoiLz48L3N2Zz4=',
description: 'execute and save transactions',
kind: 'run'
}
}
renderContainer () { renderContainer () {
this.container = yo`<div class="${css.runTabView}" id="runTabView" ></div>` this.container = yo`<div class="${css.runTabView}" id="runTabView" ></div>`
@ -147,17 +162,6 @@ class RunTab {
return this.container return this.container
} }
profile () {
return {
name: 'run',
displayName: 'run transactions',
methods: [],
events: [],
icon: 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xNTc2IDkyN2wtMTMyOCA3MzhxLTIzIDEzLTM5LjUgM3QtMTYuNS0zNnYtMTQ3MnEwLTI2IDE2LjUtMzZ0MzkuNSAzbDEzMjggNzM4cTIzIDEzIDIzIDMxdC0yMyAzMXoiLz48L3N2Zz4=',
description: 'execute and save transactions',
kind: 'run'
}
}
} }
module.exports = RunTab module.exports = RunTab

@ -9,8 +9,11 @@ var styleGuide = require('../ui/styles-guide/theme-chooser')
var Storage = remixLib.Storage var Storage = remixLib.Storage
var EventManager = require('../../lib/events') var EventManager = require('../../lib/events')
module.exports = class SettingsTab { import { ApiFactory } from 'remix-plugin'
module.exports = class SettingsTab extends ApiFactory {
constructor (localRegistry) { constructor (localRegistry) {
super()
const self = this const self = this
self._components = {} self._components = {}
self._components.registry = localRegistry || globalRegistry self._components.registry = localRegistry || globalRegistry
@ -37,7 +40,7 @@ module.exports = class SettingsTab {
self._components.themeStorage = new Storage('style:') self._components.themeStorage = new Storage('style:')
self.data.currentTheme = self._components.themeStorage.get('theme') || 'light' self.data.currentTheme = self._components.themeStorage.get('theme') || 'light'
} }
profile () { get profile () {
return { return {
displayName: 'settings', displayName: 'settings',
name: 'settings', name: 'settings',
@ -45,7 +48,8 @@ module.exports = class SettingsTab {
events: [], events: [],
icon: 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xMTUyIDg5NnEwLTEwNi03NS0xODF0LTE4MS03NS0xODEgNzUtNzUgMTgxIDc1IDE4MSAxODEgNzUgMTgxLTc1IDc1LTE4MXptNTEyLTEwOXYyMjJxMCAxMi04IDIzdC0yMCAxM2wtMTg1IDI4cS0xOSA1NC0zOSA5MSAzNSA1MCAxMDcgMTM4IDEwIDEyIDEwIDI1dC05IDIzcS0yNyAzNy05OSAxMDh0LTk0IDcxcS0xMiAwLTI2LTlsLTEzOC0xMDhxLTQ0IDIzLTkxIDM4LTE2IDEzNi0yOSAxODYtNyAyOC0zNiAyOGgtMjIycS0xNCAwLTI0LjUtOC41dC0xMS41LTIxLjVsLTI4LTE4NHEtNDktMTYtOTAtMzdsLTE0MSAxMDdxLTEwIDktMjUgOS0xNCAwLTI1LTExLTEyNi0xMTQtMTY1LTE2OC03LTEwLTctMjMgMC0xMiA4LTIzIDE1LTIxIDUxLTY2LjV0NTQtNzAuNXEtMjctNTAtNDEtOTlsLTE4My0yN3EtMTMtMi0yMS0xMi41dC04LTIzLjV2LTIyMnEwLTEyIDgtMjN0MTktMTNsMTg2LTI4cTE0LTQ2IDM5LTkyLTQwLTU3LTEwNy0xMzgtMTAtMTItMTAtMjQgMC0xMCA5LTIzIDI2LTM2IDk4LjUtMTA3LjV0OTQuNS03MS41cTEzIDAgMjYgMTBsMTM4IDEwN3E0NC0yMyA5MS0zOCAxNi0xMzYgMjktMTg2IDctMjggMzYtMjhoMjIycTE0IDAgMjQuNSA4LjV0MTEuNSAyMS41bDI4IDE4NHE0OSAxNiA5MCAzN2wxNDItMTA3cTktOSAyNC05IDEzIDAgMjUgMTAgMTI5IDExOSAxNjUgMTcwIDcgOCA3IDIyIDAgMTItOCAyMy0xNSAyMS01MSA2Ni41dC01NCA3MC41cTI2IDUwIDQxIDk4bDE4MyAyOHExMyAyIDIxIDEyLjV0OCAyMy41eiIvPjwvc3ZnPg==', icon: 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xMTUyIDg5NnEwLTEwNi03NS0xODF0LTE4MS03NS0xODEgNzUtNzUgMTgxIDc1IDE4MSAxODEgNzUgMTgxLTc1IDc1LTE4MXptNTEyLTEwOXYyMjJxMCAxMi04IDIzdC0yMCAxM2wtMTg1IDI4cS0xOSA1NC0zOSA5MSAzNSA1MCAxMDcgMTM4IDEwIDEyIDEwIDI1dC05IDIzcS0yNyAzNy05OSAxMDh0LTk0IDcxcS0xMiAwLTI2LTlsLTEzOC0xMDhxLTQ0IDIzLTkxIDM4LTE2IDEzNi0yOSAxODYtNyAyOC0zNiAyOGgtMjIycS0xNCAwLTI0LjUtOC41dC0xMS41LTIxLjVsLTI4LTE4NHEtNDktMTYtOTAtMzdsLTE0MSAxMDdxLTEwIDktMjUgOS0xNCAwLTI1LTExLTEyNi0xMTQtMTY1LTE2OC03LTEwLTctMjMgMC0xMiA4LTIzIDE1LTIxIDUxLTY2LjV0NTQtNzAuNXEtMjctNTAtNDEtOTlsLTE4My0yN3EtMTMtMi0yMS0xMi41dC04LTIzLjV2LTIyMnEwLTEyIDgtMjN0MTktMTNsMTg2LTI4cTE0LTQ2IDM5LTkyLTQwLTU3LTEwNy0xMzgtMTAtMTItMTAtMjQgMC0xMCA5LTIzIDI2LTM2IDk4LjUtMTA3LjV0OTQuNS03MS41cTEzIDAgMjYgMTBsMTM4IDEwN3E0NC0yMyA5MS0zOCAxNi0xMzYgMjktMTg2IDctMjggMzYtMjhoMjIycTE0IDAgMjQuNSA4LjV0MTEuNSAyMS41bDI4IDE4NHE0OSAxNiA5MCAzN2wxNDItMTA3cTktOSAyNC05IDEzIDAgMjUgMTAgMTI5IDExOSAxNjUgMTcwIDcgOCA3IDIyIDAgMTItOCAyMy0xNSAyMS01MSA2Ni41dC01NCA3MC41cTI2IDUwIDQxIDk4bDE4MyAyOHExMyAyIDIxIDEyLjV0OCAyMy41eiIvPjwvc3ZnPg==',
description: ' - ', description: ' - ',
kind: 'settings' kind: 'settings',
location: 'swapPanel',
} }
} }
render () { render () {

@ -1,9 +1,12 @@
const yo = require('yo-yo') const yo = require('yo-yo')
var css = require('./styles/support-tab-styles') var css = require('./styles/support-tab-styles')
class SupportTab { import { ApiFactory } from 'remix-plugin'
class SupportTab extends ApiFactory {
constructor (localRegistry) { constructor (localRegistry) {
super()
this.el = null this.el = null
this.gitterIframe = '' this.gitterIframe = ''
this.gitterIsLoaded = false this.gitterIsLoaded = false
@ -18,7 +21,8 @@ class SupportTab {
this.el.style.display = 'block' this.el.style.display = 'block'
this.gitterIsLoaded = true this.gitterIsLoaded = true
} }
profile () {
get profile () {
return { return {
name: 'support', name: 'support',
methods: [], methods: [],
@ -27,6 +31,7 @@ class SupportTab {
description: 'help center' description: 'help center'
} }
} }
render () { render () {
if (this.el) return this.el if (this.el) return this.el

@ -7,8 +7,11 @@ var globalRegistry = require('../../global/registry')
var css = require('./styles/test-tab-styles') var css = require('./styles/test-tab-styles')
var remixTests = require('remix-tests') var remixTests = require('remix-tests')
module.exports = class TestTab { import { ApiFactory } from 'remix-plugin'
module.exports = class TestTab extends ApiFactory {
constructor (localRegistry, compileTab) { constructor (localRegistry, compileTab) {
super()
// TODO here is a direct reference to compile tab, should be removed // TODO here is a direct reference to compile tab, should be removed
const self = this const self = this
self.compileTab = compileTab self.compileTab = compileTab
@ -23,7 +26,8 @@ module.exports = class TestTab {
self.data = {} self.data = {}
self.testList = yo`<div class=${css.testList}></div>` self.testList = yo`<div class=${css.testList}></div>`
} }
profile () {
get profile () {
return { return {
name: 'solidityUnitTesting', name: 'solidityUnitTesting',
displayName: 'solidity unit testing', displayName: 'solidity unit testing',
@ -33,6 +37,7 @@ module.exports = class TestTab {
description: ' - ' description: ' - '
} }
} }
render () { render () {
const self = this const self = this
var testsOutput = yo`<div class="${css.container} border border-primary border-right-0 border-left-0 border-bottom-0" hidden='true' id="tests"></div>` var testsOutput = yo`<div class="${css.container} border border-primary border-right-0 border-left-0 border-bottom-0" hidden='true' id="tests"></div>`

@ -0,0 +1,22 @@
import { ApiFactory } from 'remix-plugin'
import { EventEmitter } from 'events'
export class TxListenerModule extends ApiFactory {
constructor (txlistener) {
super()
this.events = new EventEmitter()
txlistener.event.register('newTransaction', (tx) => {
this.events.emit('newTransaction', tx)
})
}
get profile () {
return {
name: 'txListener',
displayName: 'transaction listener',
events: ['newTransaction'],
description: 'service - notify new transactions'
}
}
}

@ -1,73 +0,0 @@
/* global */
import LandingPage from './landing-page'
import Section from './section'
import { defaultWorkspaces } from './workspace'
export function homepageProfile () {
return {
displayName: 'home',
name: 'home',
methods: [],
events: [],
description: ' - ',
icon: 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjwhRE9DVFlQRSBzdmcgIFBVQkxJQyAnLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4nICAnaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkJz48c3ZnIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDUwIDUwIiBoZWlnaHQ9IjUwcHgiIGlkPSJMYXllcl8xIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCA1MCA1MCIgd2lkdGg9IjUwcHgiIHhtbDpzcGFjZT0icHJlc2VydmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxyZWN0IGZpbGw9Im5vbmUiIGhlaWdodD0iNTAiIHdpZHRoPSI1MCIvPjxnPjxwYXRoIGQ9IiAgIE0yNSwxQzExLjc0NSwxLDEsMTEuNzQ1LDEsMjVzMTAuNzQ1LDI0LDI0LDI0czI0LTEwLjc0NSwyNC0yNFMzOC4yNTUsMSwyNSwxTDI1LDF6IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAwMDAiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjIiLz48L2c+PHBhdGggZD0iICBNNDAuNjk2LDYuODMyYzAsMC0xMy4xNjksOC4yMTItMTEuNTMyLDIyLjMzMmMxLjE0Miw5Ljg1OCwxMS45MzUsMTMuMzc3LDExLjkzNSwxMy4zNzciIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMDAwMCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iMi4wNTgzIi8+PHBhdGggZD0iICBNNy4zODUsOC45MTNjMCwwLDMuMDQxLDYuNDc2LDMuMDQxLDE4LjE2OWMwLDkuMjQ2LTMuNTgzLDEyLjkxMS0zLjU4MywxMi45MTEiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMDAwMCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iMi4wNTgzIi8+PHBhdGggZD0iICBNMS44NTIsMjIuOTMyYzAsMCw2LjQ5Myw2LjIzMiwyMy4xNDgsNi4yMzJzMjMuNDM4LTYuMjQ2LDIzLjQzOC02LjI0NiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwMDAwIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIyLjA1ODMiLz48cGF0aCBkPSIgIE0yNS42NDgsMS41NDhjMCwwLTYuODk1LDcuOTM1LTYuODk1LDIzLjQ1MkMxOC43NTQsNDAuNTE4LDI1LDQ4LjYyNSwyNSw0OC42MjUiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMDAwMCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iMi4wNTgzIi8+PC9zdmc+',
prefferedLocation: 'mainPanel'
}
}
export function generateHomePage (appManager, appStore) {
/*
var actions1 = [
{label: 'new file', type: `callback`, payload: () => { alert(`-new file created-`) }},
{label: 'import from GitHub', type: `callback`, payload: () => { alert(`-imported from GitHub-`) }},
{label: 'import from gist', type: `callback`, payload: () => { alert(`-imported from gist-`) }}
]
var actions2 = [
{label: '...', type: `callback`, payload: () => { alert(`-...-`) }}
]
var actions3 = [
{label: 'Remix documentation', type: `link`, payload: `https://remix.readthedocs.io/en/latest/#`},
{label: 'GitHub repository', type: `link`, payload: `https://github.com/ethereum/remix-ide`},
{label: 'acces local file system (remixd)', type: `link`, payload: `https://remix.readthedocs.io/en/latest/tutorial_remixd_filesystem.html`},
{label: 'npm module for remixd', type: `link`, payload: `https://www.npmjs.com/package/remixd`},
{label: 'medium posts', type: `link`, payload: `https://medium.com/remix-ide`},
{label: 'tutorials', type: `link`, payload: `https://github.com/ethereum/remix-workshops`}
]
var actions4 = [
{label: 'Remix plugins & modules', type: `link`, payload: `https://github.com/ethereum/remix-plugin/blob/master/readme.md`},
{label: 'repository on GitHub', type: `link`, payload: `https://github.com/ethereum/remix-plugin`},
{label: 'examples', type: `link`, payload: `https://github.com/ethereum/remix-plugin/tree/master/examples`},
{label: 'build plugin for Remix', type: `link`, payload: `https://medium.com/remix-ide/build-a-plugin-for-remix-90d43b209c5a`}
]
var actions5 = [
{label: 'Gitter channel', type: `link`, payload: `https://gitter.im/ethereum/remix`},
{label: 'Stack Overflow', type: `link`, payload: `https://stackoverflow.com/questions/tagged/remix`},
{label: 'Reddit', type: `link`, payload: `https://www.reddit.com/r/ethdev/search?q=remix&restrict_sr=1`}
]
var section1 = new Section('Start', actions1)
var section2 = new Section('Recent', actions2)
var section3 = new Section('Learn', actions3)
var section4 = new Section('Plugins', actions4)
var section5 = new Section('Help', actions5)
*/
var sectionsWorkspaces = []
sectionsWorkspaces.push({
label: 'Close All Modules',
type: 'callback',
payload: () => {
appStore.getActives()
.filter(({profile}) => !profile.required)
.forEach((profile) => { appManager.deactivateOne(profile.name) })
}})
defaultWorkspaces(appManager).forEach((workspace) => {
sectionsWorkspaces.push({label: workspace.title, type: 'callback', payload: () => { workspace.activate() }})
})
var sectionWorkspace = new Section('Workspaces', sectionsWorkspaces)
return new LandingPage([sectionWorkspace])
}

@ -27,9 +27,79 @@ var css = csjs`
} }
` `
class LandingPage { import { defaultWorkspaces } from './workspace'
constructor (sections) { import { ApiFactory } from 'remix-plugin'
this.sections = sections import Section from './section'
export class LandingPage extends ApiFactory {
constructor (appManager, appStore) {
super()
/*
var actions1 = [
{label: 'new file', type: `callback`, payload: () => { alert(`-new file created-`) }},
{label: 'import from GitHub', type: `callback`, payload: () => { alert(`-imported from GitHub-`) }},
{label: 'import from gist', type: `callback`, payload: () => { alert(`-imported from gist-`) }}
]
var actions2 = [
{label: '...', type: `callback`, payload: () => { alert(`-...-`) }}
]
var actions3 = [
{label: 'Remix documentation', type: `link`, payload: `https://remix.readthedocs.io/en/latest/#`},
{label: 'GitHub repository', type: `link`, payload: `https://github.com/ethereum/remix-ide`},
{label: 'acces local file system (remixd)', type: `link`, payload: `https://remix.readthedocs.io/en/latest/tutorial_remixd_filesystem.html`},
{label: 'npm module for remixd', type: `link`, payload: `https://www.npmjs.com/package/remixd`},
{label: 'medium posts', type: `link`, payload: `https://medium.com/remix-ide`},
{label: 'tutorials', type: `link`, payload: `https://github.com/ethereum/remix-workshops`}
]
var actions4 = [
{label: 'Remix plugins & modules', type: `link`, payload: `https://github.com/ethereum/remix-plugin/blob/master/readme.md`},
{label: 'repository on GitHub', type: `link`, payload: `https://github.com/ethereum/remix-plugin`},
{label: 'examples', type: `link`, payload: `https://github.com/ethereum/remix-plugin/tree/master/examples`},
{label: 'build plugin for Remix', type: `link`, payload: `https://medium.com/remix-ide/build-a-plugin-for-remix-90d43b209c5a`}
]
var actions5 = [
{label: 'Gitter channel', type: `link`, payload: `https://gitter.im/ethereum/remix`},
{label: 'Stack Overflow', type: `link`, payload: `https://stackoverflow.com/questions/tagged/remix`},
{label: 'Reddit', type: `link`, payload: `https://www.reddit.com/r/ethdev/search?q=remix&restrict_sr=1`}
]
var section1 = new Section('Start', actions1)
var section2 = new Section('Recent', actions2)
var section3 = new Section('Learn', actions3)
var section4 = new Section('Plugins', actions4)
var section5 = new Section('Help', actions5)
*/
const sectionsWorkspaces = []
sectionsWorkspaces.push({
label: 'Close All Modules',
type: 'callback',
payload: () => {
appStore.getActives()
.filter(({profile}) => !profile.required)
.forEach((profile) => { appManager.deactivateOne(profile.name) })
}})
defaultWorkspaces(appManager).forEach((workspace) => {
sectionsWorkspaces.push({label: workspace.title, type: 'callback', payload: () => { workspace.activate() }})
})
const sectionWorkspace = new Section('Workspaces', sectionsWorkspaces)
this.sections = sectionWorkspace
}
get profile () {
return {
displayName: 'home',
name: 'home',
methods: [],
events: [],
description: ' - ',
icon: 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjwhRE9DVFlQRSBzdmcgIFBVQkxJQyAnLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4nICAnaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkJz48c3ZnIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDUwIDUwIiBoZWlnaHQ9IjUwcHgiIGlkPSJMYXllcl8xIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCA1MCA1MCIgd2lkdGg9IjUwcHgiIHhtbDpzcGFjZT0icHJlc2VydmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxyZWN0IGZpbGw9Im5vbmUiIGhlaWdodD0iNTAiIHdpZHRoPSI1MCIvPjxnPjxwYXRoIGQ9IiAgIE0yNSwxQzExLjc0NSwxLDEsMTEuNzQ1LDEsMjVzMTAuNzQ1LDI0LDI0LDI0czI0LTEwLjc0NSwyNC0yNFMzOC4yNTUsMSwyNSwxTDI1LDF6IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAwMDAiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjIiLz48L2c+PHBhdGggZD0iICBNNDAuNjk2LDYuODMyYzAsMC0xMy4xNjksOC4yMTItMTEuNTMyLDIyLjMzMmMxLjE0Miw5Ljg1OCwxMS45MzUsMTMuMzc3LDExLjkzNSwxMy4zNzciIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMDAwMCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iMi4wNTgzIi8+PHBhdGggZD0iICBNNy4zODUsOC45MTNjMCwwLDMuMDQxLDYuNDc2LDMuMDQxLDE4LjE2OWMwLDkuMjQ2LTMuNTgzLDEyLjkxMS0zLjU4MywxMi45MTEiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMDAwMCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iMi4wNTgzIi8+PHBhdGggZD0iICBNMS44NTIsMjIuOTMyYzAsMCw2LjQ5Myw2LjIzMiwyMy4xNDgsNi4yMzJzMjMuNDM4LTYuMjQ2LDIzLjQzOC02LjI0NiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwMDAwIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIyLjA1ODMiLz48cGF0aCBkPSIgIE0yNS42NDgsMS41NDhjMCwwLTYuODk1LDcuOTM1LTYuODk1LDIzLjQ1MkMxOC43NTQsNDAuNTE4LDI1LDQ4LjYyNSwyNSw0OC42MjUiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMDAwMCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iMi4wNTgzIi8+PC9zdmc+',
location: 'mainPanel'
}
} }
render () { render () {
@ -48,5 +118,3 @@ class LandingPage {
return totalLook return totalLook
} }
} }
module.exports = LandingPage

@ -7,38 +7,41 @@ var TxRunner = remixLib.execution.txRunner
var txHelper = remixLib.execution.txHelper var txHelper = remixLib.execution.txHelper
var EventManager = remixLib.EventManager var EventManager = remixLib.EventManager
var executionContext = remixLib.execution.executionContext var executionContext = remixLib.execution.executionContext
import { ApiFactory } from 'remix-plugin'
function UniversalDApp (registry) { module.exports = class UniversalDApp extends ApiFactory {
constructor (registry) {
super()
this.event = new EventManager() this.event = new EventManager()
var self = this this._deps = {
self._deps = {
config: registry.get('config').api config: registry.get('config').api
} }
self._txRunnerAPI = { this._txRunnerAPI = {
config: self._deps.config, config: this._deps.config,
detectNetwork: (cb) => { detectNetwork: (cb) => {
executionContext.detectNetwork(cb) executionContext.detectNetwork(cb)
}, },
personalMode: () => { personalMode: () => {
return self._deps.config.get('settings/personal-mode') return this._deps.config.get('settings/personal-mode')
} }
} }
self.txRunner = new TxRunner({}, self._txRunnerAPI) this.txRunner = new TxRunner({}, this._txRunnerAPI)
self.accounts = {} this.accounts = {}
self.resetEnvironment() this.resetEnvironment()
executionContext.event.register('contextChanged', this.resetEnvironment.bind(this)) executionContext.event.register('contextChanged', this.resetEnvironment.bind(this))
} }
UniversalDApp.prototype.profile = function () { get profile () {
return { return {
name: 'udapp', name: 'udapp',
displayName: 'universal dapp', displayName: 'universal dapp',
methods: ['runTestTx', 'getAccounts', 'createVMAccount'], methods: ['runTestTx', 'getAccounts', 'createVMAccount'],
description: 'service - run transaction and access account' description: 'service - run transaction and access account'
} }
} }
UniversalDApp.prototype.resetEnvironment = function () { resetEnvironment () {
this.accounts = {} this.accounts = {}
if (executionContext.isVM()) { if (executionContext.isVM()) {
this._addAccount('3cd7232cd6f3fc66a57a6bedc1a8ed6c228fff0a327e169c2bcc5e869ed49511', '0x56BC75E2D63100000') this._addAccount('3cd7232cd6f3fc66a57a6bedc1a8ed6c228fff0a327e169c2bcc5e869ed49511', '0x56BC75E2D63100000')
@ -66,13 +69,13 @@ UniversalDApp.prototype.resetEnvironment = function () {
this.event.trigger('transactionBroadcasted', [txhash, network.name]) this.event.trigger('transactionBroadcasted', [txhash, network.name])
}) })
}) })
} }
UniversalDApp.prototype.resetAPI = function (transactionContextAPI) { resetAPI (transactionContextAPI) {
this.transactionContextAPI = transactionContextAPI this.transactionContextAPI = transactionContextAPI
} }
UniversalDApp.prototype.createVMAccount = function (privateKey, balance, cb) { createVMAccount (privateKey, balance, cb) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (executionContext.getProvider() !== 'vm') return reject('plugin API does not allow creating a new account through web3 connection. Only vm mode is allowed') if (executionContext.getProvider() !== 'vm') return reject('plugin API does not allow creating a new account through web3 connection. Only vm mode is allowed')
this._addAccount(privateKey, balance) this._addAccount(privateKey, balance)
@ -80,9 +83,9 @@ UniversalDApp.prototype.createVMAccount = function (privateKey, balance, cb) {
privateKey = Buffer.from(privateKey, 'hex') privateKey = Buffer.from(privateKey, 'hex')
resolve('0x' + ethJSUtil.privateToAddress(privateKey).toString('hex')) resolve('0x' + ethJSUtil.privateToAddress(privateKey).toString('hex'))
}) })
} }
UniversalDApp.prototype.newAccount = function (password, passwordPromptCb, cb) { newAccount (password, passwordPromptCb, cb) {
if (!executionContext.isVM()) { if (!executionContext.isVM()) {
if (!this.config.get('settings/personal-mode')) { if (!this.config.get('settings/personal-mode')) {
return cb('Not running in personal mode') return cb('Not running in personal mode')
@ -99,28 +102,24 @@ UniversalDApp.prototype.newAccount = function (password, passwordPromptCb, cb) {
executionContext.vm().stateManager.cache.flush(function () {}) executionContext.vm().stateManager.cache.flush(function () {})
cb(null, '0x' + ethJSUtil.privateToAddress(privateKey).toString('hex')) cb(null, '0x' + ethJSUtil.privateToAddress(privateKey).toString('hex'))
} }
} }
UniversalDApp.prototype._addAccount = function (privateKey, balance) {
var self = this
_addAccount (privateKey, balance) {
if (!executionContext.isVM()) { if (!executionContext.isVM()) {
throw new Error('_addAccount() cannot be called in non-VM mode') throw new Error('_addAccount() cannot be called in non-VM mode')
} }
if (self.accounts) { if (this.accounts) {
privateKey = Buffer.from(privateKey, 'hex') privateKey = Buffer.from(privateKey, 'hex')
var address = ethJSUtil.privateToAddress(privateKey) const address = ethJSUtil.privateToAddress(privateKey)
// FIXME: we don't care about the callback, but we should still make this proper // FIXME: we don't care about the callback, but we should still make this proper
executionContext.vm().stateManager.putAccountBalance(address, balance || '0xf00000000000000001', function cb () {}) executionContext.vm().stateManager.putAccountBalance(address, balance || '0xf00000000000000001', function cb () {})
self.accounts['0x' + address.toString('hex')] = { privateKey: privateKey, nonce: 0 } this.accounts['0x' + address.toString('hex')] = { privateKey, nonce: 0 }
}
} }
}
// TODO should remove this cb getAccounts (cb) {
UniversalDApp.prototype.getAccounts = function (cb) {
var self = this
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (!executionContext.isVM()) { if (!executionContext.isVM()) {
// Weirdness of web3: listAccounts() is sync, `getListAccounts()` is async // Weirdness of web3: listAccounts() is sync, `getListAccounts()` is async
@ -139,24 +138,22 @@ UniversalDApp.prototype.getAccounts = function (cb) {
}) })
} }
} else { } else {
if (!self.accounts) { if (!this.accounts) {
if (cb) cb('No accounts?') if (cb) cb('No accounts?')
reject('No accounts?') reject('No accounts?')
return return
} }
if (cb) cb(null, Object.keys(self.accounts)) if (cb) cb(null, Object.keys(this.accounts))
resolve(Object.keys(self.accounts)) resolve(Object.keys(this.accounts))
} }
}) })
} }
UniversalDApp.prototype.getBalance = function (address, cb) {
var self = this
getBalance (address, cb) {
address = ethJSUtil.stripHexPrefix(address) address = ethJSUtil.stripHexPrefix(address)
if (!executionContext.isVM()) { if (!executionContext.isVM()) {
executionContext.web3().eth.getBalance(address, function (err, res) { executionContext.web3().eth.getBalance(address, (err, res) => {
if (err) { if (err) {
cb(err) cb(err)
} else { } else {
@ -164,11 +161,11 @@ UniversalDApp.prototype.getBalance = function (address, cb) {
} }
}) })
} else { } else {
if (!self.accounts) { if (!this.accounts) {
return cb('No accounts?') return cb('No accounts?')
} }
executionContext.vm().stateManager.getAccountBalance(Buffer.from(address, 'hex'), function (err, res) { executionContext.vm().stateManager.getAccountBalance(Buffer.from(address, 'hex'), (err, res) => {
if (err) { if (err) {
cb('Account not found') cb('Account not found')
} else { } else {
@ -176,37 +173,36 @@ UniversalDApp.prototype.getBalance = function (address, cb) {
} }
}) })
} }
} }
UniversalDApp.prototype.getBalanceInEther = function (address, callback) { getBalanceInEther (address, callback) {
var self = this this.getBalance(address, (error, balance) => {
self.getBalance(address, (error, balance) => {
if (error) { if (error) {
callback(error) callback(error)
} else { } else {
callback(null, executionContext.web3().fromWei(balance, 'ether')) callback(null, executionContext.web3().fromWei(balance, 'ether'))
} }
}) })
} }
UniversalDApp.prototype.pendingTransactionsCount = function () { pendingTransactionsCount () {
return Object.keys(this.txRunner.pendingTxs).length return Object.keys(this.txRunner.pendingTxs).length
} }
/** /**
* deploy the given contract * deploy the given contract
* *
* @param {String} data - data to send with the transaction ( return of txFormat.buildData(...) ). * @param {String} data - data to send with the transaction ( return of txFormat.buildData(...) ).
* @param {Function} callback - callback. * @param {Function} callback - callback.
*/ */
UniversalDApp.prototype.createContract = function (data, confirmationCb, continueCb, promptCb, callback) { createContract (data, confirmationCb, continueCb, promptCb, callback) {
this.runTx({data: data, useCall: false}, confirmationCb, continueCb, promptCb, (error, txResult) => { this.runTx({data: data, useCall: false}, confirmationCb, continueCb, promptCb, (error, txResult) => {
// see universaldapp.js line 660 => 700 to check possible values of txResult (error case) // see universaldapp.js line 660 => 700 to check possible values of txResult (error case)
callback(error, txResult) callback(error, txResult)
}) })
} }
/** /**
* call the current given contract * call the current given contract
* *
* @param {String} to - address of the contract to call. * @param {String} to - address of the contract to call.
@ -214,39 +210,39 @@ UniversalDApp.prototype.createContract = function (data, confirmationCb, continu
* @param {Object} funAbi - abi definition of the function to call. * @param {Object} funAbi - abi definition of the function to call.
* @param {Function} callback - callback. * @param {Function} callback - callback.
*/ */
UniversalDApp.prototype.callFunction = function (to, data, funAbi, confirmationCb, continueCb, promptCb, callback) { callFunction (to, data, funAbi, confirmationCb, continueCb, promptCb, callback) {
this.runTx({to: to, data: data, useCall: funAbi.constant}, confirmationCb, continueCb, promptCb, (error, txResult) => { this.runTx({to: to, data: data, useCall: funAbi.constant}, confirmationCb, continueCb, promptCb, (error, txResult) => {
// see universaldapp.js line 660 => 700 to check possible values of txResult (error case) // see universaldapp.js line 660 => 700 to check possible values of txResult (error case)
callback(error, txResult) callback(error, txResult)
}) })
} }
UniversalDApp.prototype.context = function () { context () {
return (executionContext.isVM() ? 'memory' : 'blockchain') return (executionContext.isVM() ? 'memory' : 'blockchain')
} }
UniversalDApp.prototype.getABI = function (contract) { getABI (contract) {
return txHelper.sortAbiFunction(contract.abi) return txHelper.sortAbiFunction(contract.abi)
} }
UniversalDApp.prototype.getFallbackInterface = function (contractABI) { getFallbackInterface (contractABI) {
return txHelper.getFallbackInterface(contractABI) return txHelper.getFallbackInterface(contractABI)
} }
UniversalDApp.prototype.getInputs = function (funABI) { getInputs (funABI) {
if (!funABI.inputs) { if (!funABI.inputs) {
return '' return ''
} }
return txHelper.inputParametersDeclarationToString(funABI.inputs) return txHelper.inputParametersDeclarationToString(funABI.inputs)
} }
/** /**
* This function send a tx only to javascript VM or testnet, will return an error for the mainnet * This function send a tx only to javascript VM or testnet, will return an error for the mainnet
* SHOULD BE TAKEN CAREFULLY! * SHOULD BE TAKEN CAREFULLY!
* *
* @param {Object} tx - transaction. * @param {Object} tx - transaction.
*/ */
UniversalDApp.prototype.runTestTx = function (tx) { runTestTx (tx) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
executionContext.detectNetwork((error, network) => { executionContext.detectNetwork((error, network) => {
if (error) return reject(error) if (error) return reject(error)
@ -266,26 +262,27 @@ UniversalDApp.prototype.runTestTx = function (tx) {
}) })
}) })
}) })
} }
/** /**
* This function send a tx without alerting the user (if mainnet or if gas estimation too high). * This function send a tx without alerting the user (if mainnet or if gas estimation too high).
* SHOULD BE TAKEN CAREFULLY! * SHOULD BE TAKEN CAREFULLY!
* *
* @param {Object} tx - transaction. * @param {Object} tx - transaction.
* @param {Function} callback - callback. * @param {Function} callback - callback.
*/ */
UniversalDApp.prototype.silentRunTx = function (tx, cb) { silentRunTx (tx, cb) {
if (!executionContext.isVM()) return cb('Cannot silently send transaction through a web3 provider') if (!executionContext.isVM()) return cb('Cannot silently send transaction through a web3 provider')
this.txRunner.rawRun( this.txRunner.rawRun(
tx, tx,
(network, tx, gasEstimation, continueTxExecution, cancelCb) => { continueTxExecution() }, (network, tx, gasEstimation, continueTxExecution, cancelCb) => { continueTxExecution() },
(error, continueTxExecution, cancelCb) => { if (error) { cb(error) } else { continueTxExecution() } }, (error, continueTxExecution, cancelCb) => { if (error) { cb(error) } else { continueTxExecution() } },
(okCb, cancelCb) => { okCb() }, (okCb, cancelCb) => { okCb() },
cb) cb
} )
}
UniversalDApp.prototype.runTx = function (args, confirmationCb, continueCb, promptCb, cb) { runTx (args, confirmationCb, continueCb, promptCb, cb) {
const self = this const self = this
async.waterfall([ async.waterfall([
function getGasLimit (next) { function getGasLimit (next) {
@ -350,6 +347,5 @@ UniversalDApp.prototype.runTx = function (args, confirmationCb, continueCb, prom
) )
} }
], cb) ], cb)
}
} }
module.exports = UniversalDApp

Loading…
Cancel
Save