Merge branch 'homepage2' of https://github.com/ethereum/remix-ide into homepage2
commit
69f85d5833
@ -1,94 +0,0 @@ |
|||||||
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ |
|
||||||
'use strict'; |
|
||||||
|
|
||||||
var _createClass = function () { |
|
||||||
function defineProperties(target, props) { |
|
||||||
for (var i = 0; i < props.length; i++) { |
|
||||||
var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor); |
|
||||||
} |
|
||||||
}return function (Constructor, protoProps, staticProps) { |
|
||||||
if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor; |
|
||||||
}; |
|
||||||
}(); |
|
||||||
|
|
||||||
function _classCallCheck(instance, Constructor) { |
|
||||||
if (!(instance instanceof Constructor)) { |
|
||||||
throw new TypeError("Cannot call a class as a function"); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
var RemixExtension = function () { |
|
||||||
function RemixExtension() { |
|
||||||
var _this = this; |
|
||||||
|
|
||||||
_classCallCheck(this, RemixExtension); |
|
||||||
|
|
||||||
this._notifications = {}; |
|
||||||
this._pendingRequests = {}; |
|
||||||
this._id = 0; |
|
||||||
window.addEventListener('message', function (event) { |
|
||||||
return _this._newMessage(event); |
|
||||||
}, false); |
|
||||||
} |
|
||||||
|
|
||||||
_createClass(RemixExtension, [{ |
|
||||||
key: 'listen', |
|
||||||
value: function listen(key, type, callback) { |
|
||||||
if (!this._notifications[key]) this._notifications[key] = {}; |
|
||||||
this._notifications[key][type] = callback; |
|
||||||
} |
|
||||||
}, { |
|
||||||
key: 'call', |
|
||||||
value: function call(key, type, params, callback) { |
|
||||||
this._id++; |
|
||||||
this._pendingRequests[this._id] = callback; |
|
||||||
window.parent.postMessage(JSON.stringify({ |
|
||||||
action: 'request', |
|
||||||
key: key, |
|
||||||
type: type, |
|
||||||
value: params, |
|
||||||
id: this._id |
|
||||||
}), '*'); |
|
||||||
} |
|
||||||
}, { |
|
||||||
key: '_newMessage', |
|
||||||
value: function _newMessage(event) { |
|
||||||
if (!event.data) return; |
|
||||||
if (typeof event.data !== 'string') return; |
|
||||||
|
|
||||||
var msg; |
|
||||||
try { |
|
||||||
msg = JSON.parse(event.data); |
|
||||||
} catch (e) { |
|
||||||
return console.log('unable to parse data'); |
|
||||||
} |
|
||||||
var _msg = msg, |
|
||||||
action = _msg.action, |
|
||||||
key = _msg.key, |
|
||||||
type = _msg.type, |
|
||||||
value = _msg.value; |
|
||||||
|
|
||||||
if (action === 'notification') { |
|
||||||
if (this._notifications[key] && this._notifications[key][type]) { |
|
||||||
this._notifications[key][type](value); |
|
||||||
} |
|
||||||
} else if (action === 'response') { |
|
||||||
var _msg2 = msg, |
|
||||||
id = _msg2.id, |
|
||||||
error = _msg2.error; |
|
||||||
|
|
||||||
if (this._pendingRequests[id]) { |
|
||||||
this._pendingRequests[id](error, value); |
|
||||||
delete this._pendingRequests[id]; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
}]); |
|
||||||
|
|
||||||
return RemixExtension; |
|
||||||
}(); |
|
||||||
|
|
||||||
if (window) window.RemixExtension = RemixExtension; |
|
||||||
if (module && module.exports) module.exports = RemixExtension; |
|
||||||
|
|
||||||
},{}]},{},[1]); |
|
@ -1,55 +0,0 @@ |
|||||||
'use strict' |
|
||||||
|
|
||||||
class RemixExtension { |
|
||||||
constructor () { |
|
||||||
this._notifications = {} |
|
||||||
this._pendingRequests = {} |
|
||||||
this._id = 0 |
|
||||||
window.addEventListener('message', (event) => this._newMessage(event), false) |
|
||||||
} |
|
||||||
|
|
||||||
listen (key, type, callback) { |
|
||||||
if (!this._notifications[key]) this._notifications[key] = {} |
|
||||||
this._notifications[key][type] = callback |
|
||||||
} |
|
||||||
|
|
||||||
call (key, type, params, callback) { |
|
||||||
this._id++ |
|
||||||
this._pendingRequests[this._id] = callback |
|
||||||
window.parent.postMessage(JSON.stringify({ |
|
||||||
action: 'request', |
|
||||||
key, |
|
||||||
type, |
|
||||||
value: params, |
|
||||||
id: this._id |
|
||||||
}), '*') |
|
||||||
} |
|
||||||
|
|
||||||
_newMessage (event) { |
|
||||||
if (!event.data) return |
|
||||||
if (typeof event.data !== 'string') return |
|
||||||
|
|
||||||
var msg |
|
||||||
try { |
|
||||||
msg = JSON.parse(event.data) |
|
||||||
} catch (e) { |
|
||||||
return console.log('unable to parse data') |
|
||||||
} |
|
||||||
const {action, key, type, value} = msg |
|
||||||
if (action === 'notification') { |
|
||||||
if (this._notifications[key] && this._notifications[key][type]) { |
|
||||||
this._notifications[key][type](value) |
|
||||||
} |
|
||||||
} else if (action === 'response') { |
|
||||||
const {id, error} = msg |
|
||||||
if (this._pendingRequests[id]) { |
|
||||||
this._pendingRequests[id](error, value) |
|
||||||
delete this._pendingRequests[id] |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
if (window) window.RemixExtension = RemixExtension |
|
||||||
if (module && module.exports) module.exports = RemixExtension |
|
||||||
|
|
@ -1,71 +0,0 @@ |
|||||||
{ |
|
||||||
"name": "remix-extension", |
|
||||||
"version": "0.0.1", |
|
||||||
"description": "Ethereum IDE and tools for the web", |
|
||||||
"contributors": [ |
|
||||||
{ |
|
||||||
"name": "Yann Levreau", |
|
||||||
"email": "yann@ethdev.com" |
|
||||||
} |
|
||||||
], |
|
||||||
"main": "./index.js", |
|
||||||
"dependencies": { |
|
||||||
"babel-eslint": "^7.1.1", |
|
||||||
"babel-plugin-transform-object-assign": "^6.22.0", |
|
||||||
"babel-preset-es2015": "^6.24.0", |
|
||||||
"babelify": "^7.3.0", |
|
||||||
"standard": "^7.0.1", |
|
||||||
"tape": "^4.6.0" |
|
||||||
}, |
|
||||||
"scripts": { |
|
||||||
"browserify": "browserify index.js -o bundle.js" |
|
||||||
}, |
|
||||||
"standard": { |
|
||||||
"ignore": [ |
|
||||||
"node_modules/*" |
|
||||||
], |
|
||||||
"parser": "babel-eslint" |
|
||||||
}, |
|
||||||
"repository": { |
|
||||||
"type": "git", |
|
||||||
"url": "git+https://github.com/ethereum/remix-ide.git" |
|
||||||
}, |
|
||||||
"author": "cpp-ethereum team", |
|
||||||
"license": "MIT", |
|
||||||
"bugs": { |
|
||||||
"url": "https://github.com/ethereum/remix-ide/issues" |
|
||||||
}, |
|
||||||
"homepage": "https://github.com/ethereum/remix-ide#readme", |
|
||||||
"browserify": { |
|
||||||
"transform": [ |
|
||||||
[ |
|
||||||
"babelify", |
|
||||||
{ |
|
||||||
"plugins": [ |
|
||||||
[ |
|
||||||
"fast-async", |
|
||||||
{ |
|
||||||
"runtimePatten": null, |
|
||||||
"compiler": { |
|
||||||
"promises": true, |
|
||||||
"es7": true, |
|
||||||
"noRuntime": true, |
|
||||||
"wrapAwait": true |
|
||||||
} |
|
||||||
} |
|
||||||
], |
|
||||||
"transform-object-assign" |
|
||||||
] |
|
||||||
} |
|
||||||
], |
|
||||||
[ |
|
||||||
"babelify", |
|
||||||
{ |
|
||||||
"presets": [ |
|
||||||
"es2015" |
|
||||||
] |
|
||||||
} |
|
||||||
] |
|
||||||
] |
|
||||||
} |
|
||||||
} |
|
@ -1,53 +0,0 @@ |
|||||||
plugin api |
|
||||||
|
|
||||||
# current APIs: |
|
||||||
|
|
||||||
## 1) notifications |
|
||||||
|
|
||||||
### app (key: app) |
|
||||||
|
|
||||||
- unfocus `[]` |
|
||||||
- focus `[]` |
|
||||||
|
|
||||||
### compiler (key: compiler) |
|
||||||
|
|
||||||
- compilationFinished `[success (bool), data (obj), source (obj)]` |
|
||||||
- compilationData `[compilationResult]` |
|
||||||
|
|
||||||
### transaction listener (key: txlistener) |
|
||||||
|
|
||||||
- newTransaction `tx (obj)` |
|
||||||
|
|
||||||
## 2) interactions |
|
||||||
|
|
||||||
### app |
|
||||||
|
|
||||||
- getExecutionContextProvider `@return {String} provider (injected | web3 | vm)` |
|
||||||
- getProviderEndpoint `@return {String} url` |
|
||||||
- updateTitle `@param {String} title` |
|
||||||
- detectNetWork `@return {Object} {name, id}` |
|
||||||
- addProvider `@param {String} name, @param {String} url` |
|
||||||
- removeProvider `@return {String} name` |
|
||||||
|
|
||||||
### config |
|
||||||
|
|
||||||
- setConfig `@param {String} path, @param {String} content` |
|
||||||
- getConfig `@param {String} path` |
|
||||||
- removeConfig `@param {String} path` |
|
||||||
|
|
||||||
### compiler |
|
||||||
- getCompilationResult `@return {Object} compilation result` |
|
||||||
|
|
||||||
### udapp (only VM) |
|
||||||
- runTx `@param {Object} tx` |
|
||||||
- getAccounts `@return {Array} acccounts` |
|
||||||
- createVMAccount `@param {String} privateKey, @param {String} balance (hex)` |
|
||||||
|
|
||||||
### editor |
|
||||||
- getFilesFromPath `@param {Array} [path]` |
|
||||||
- getCurrentFile `@return {String} path` |
|
||||||
- getFile `@param {String} path` |
|
||||||
- setFile `@param {String} path, @param {String} content` |
|
||||||
- highlight `@param {Object} lineColumnPos {start: {line, column}, end: {line, column}}, @param {String} path, @param {String} hexColor` |
|
||||||
- discardHighlight |
|
||||||
|
|
@ -1,150 +0,0 @@ |
|||||||
'use strict' |
|
||||||
var executionContext = require('../../execution-context') |
|
||||||
var SourceHighlighter = require('../editor/sourceHighlighter') |
|
||||||
/* |
|
||||||
Defines available API. `key` / `type` |
|
||||||
*/ |
|
||||||
module.exports = (pluginManager, fileProviders, fileManager, compilesrArtefacts, udapp) => { |
|
||||||
let highlighters = {} |
|
||||||
return { |
|
||||||
app: { |
|
||||||
getExecutionContextProvider: (mod, cb) => { |
|
||||||
cb(null, executionContext.getProvider()) |
|
||||||
}, |
|
||||||
getProviderEndpoint: (mod, cb) => { |
|
||||||
if (executionContext.getProvider() === 'web3') { |
|
||||||
cb(null, executionContext.web3().currentProvider.host) |
|
||||||
} else { |
|
||||||
cb('no endpoint: current provider is either injected or vm') |
|
||||||
} |
|
||||||
}, |
|
||||||
updateTitle: (mod, title, cb) => { |
|
||||||
pluginManager.plugins[mod].modal.setTitle(title) |
|
||||||
if (cb) cb() |
|
||||||
}, |
|
||||||
detectNetWork: (mod, cb) => { |
|
||||||
executionContext.detectNetwork((error, network) => { |
|
||||||
cb(error, network) |
|
||||||
}) |
|
||||||
}, |
|
||||||
addProvider: (mod, name, url, cb) => { |
|
||||||
executionContext.addProvider({ name, url }) |
|
||||||
cb() |
|
||||||
}, |
|
||||||
removeProvider: (mod, name, cb) => { |
|
||||||
executionContext.removeProvider(name) |
|
||||||
cb() |
|
||||||
} |
|
||||||
}, |
|
||||||
config: { |
|
||||||
setConfig: (mod, path, content, cb) => { |
|
||||||
fileProviders['config'].set(mod + '/' + path, content) |
|
||||||
cb() |
|
||||||
}, |
|
||||||
getConfig: (mod, path, cb) => { |
|
||||||
cb(null, fileProviders['config'].get(mod + '/' + path)) |
|
||||||
}, |
|
||||||
removeConfig: (mod, path, cb) => { |
|
||||||
cb(null, fileProviders['config'].remove(mod + '/' + path)) |
|
||||||
if (cb) cb() |
|
||||||
} |
|
||||||
}, |
|
||||||
compiler: { |
|
||||||
getCompilationResult: (mod, cb) => { |
|
||||||
cb(null, compilesrArtefacts['__last']) |
|
||||||
}, |
|
||||||
sendCompilationResult: (mod, file, source, languageVersion, data, cb) => { |
|
||||||
pluginManager.receivedDataFrom('sendCompilationResult', mod, [file, source, languageVersion, data]) |
|
||||||
} |
|
||||||
}, |
|
||||||
udapp: { |
|
||||||
runTx: (mod, tx, cb) => { |
|
||||||
executionContext.detectNetwork((error, network) => { |
|
||||||
if (error) return cb(error) |
|
||||||
if (network.name === 'Main' && network.id === '1') { |
|
||||||
return cb('It is not allowed to make this action against mainnet') |
|
||||||
} |
|
||||||
udapp.silentRunTx(tx, (error, result) => { |
|
||||||
if (error) return cb(error) |
|
||||||
cb(null, { |
|
||||||
transactionHash: result.transactionHash, |
|
||||||
status: result.result.status, |
|
||||||
gasUsed: '0x' + result.result.gasUsed.toString('hex'), |
|
||||||
error: result.result.vm.exceptionError, |
|
||||||
return: result.result.vm.return ? '0x' + result.result.vm.return.toString('hex') : '0x', |
|
||||||
createdAddress: result.result.createdAddress ? '0x' + result.result.createdAddress.toString('hex') : undefined |
|
||||||
}) |
|
||||||
}) |
|
||||||
}) |
|
||||||
}, |
|
||||||
getAccounts: (mod, cb) => { |
|
||||||
executionContext.detectNetwork((error, network) => { |
|
||||||
if (error) return cb(error) |
|
||||||
if (network.name === 'Main' && network.id === '1') { |
|
||||||
return cb('It is not allowed to make this action against mainnet') |
|
||||||
} |
|
||||||
udapp.getAccounts(cb) |
|
||||||
}) |
|
||||||
}, |
|
||||||
createVMAccount: (mod, privateKey, balance, cb) => { |
|
||||||
if (executionContext.getProvider() !== 'vm') return cb('plugin API does not allow creating a new account through web3 connection. Only vm mode is allowed') |
|
||||||
udapp.createVMAccount(privateKey, balance, (error, address) => { |
|
||||||
cb(error, address) |
|
||||||
}) |
|
||||||
} |
|
||||||
}, |
|
||||||
editor: { |
|
||||||
getFilesFromPath: (mod, path, cb) => { |
|
||||||
fileManager.filesFromPath(path, cb) |
|
||||||
}, |
|
||||||
getCurrentFile: (mod, cb) => { |
|
||||||
var path = fileManager.currentFile() |
|
||||||
if (!path) { |
|
||||||
cb('no file selected') |
|
||||||
} else { |
|
||||||
cb(null, path) |
|
||||||
} |
|
||||||
}, |
|
||||||
getFile: (mod, path, cb) => { |
|
||||||
var provider = fileManager.fileProviderOf(path) |
|
||||||
if (provider) { |
|
||||||
// TODO add approval to user for external plugin to get the content of the given `path`
|
|
||||||
provider.get(path, (error, content) => { |
|
||||||
cb(error, content) |
|
||||||
}) |
|
||||||
} else { |
|
||||||
cb(path + ' not available') |
|
||||||
} |
|
||||||
}, |
|
||||||
setFile: (mod, path, content, cb) => { |
|
||||||
var provider = fileManager.fileProviderOf(path) |
|
||||||
if (provider) { |
|
||||||
// TODO add approval to user for external plugin to set the content of the given `path`
|
|
||||||
provider.set(path, content, (error) => { |
|
||||||
if (error) return cb(error) |
|
||||||
fileManager.syncEditor(path) |
|
||||||
cb() |
|
||||||
}) |
|
||||||
} else { |
|
||||||
cb(path + ' not available') |
|
||||||
} |
|
||||||
}, |
|
||||||
highlight: (mod, lineColumnPos, filePath, hexColor, cb) => { |
|
||||||
var position |
|
||||||
try { |
|
||||||
position = JSON.parse(lineColumnPos) |
|
||||||
} catch (e) { |
|
||||||
return cb(e.message) |
|
||||||
} |
|
||||||
if (!highlighters[mod]) highlighters[mod] = new SourceHighlighter() |
|
||||||
highlighters[mod].currentSourceLocation(null) |
|
||||||
highlighters[mod].currentSourceLocationFromfileName(position, filePath, hexColor) |
|
||||||
cb() |
|
||||||
}, |
|
||||||
discardHighlight: (mod, cb) => { |
|
||||||
if (highlighters[mod]) highlighters[mod].currentSourceLocation(null) |
|
||||||
cb() |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,179 +0,0 @@ |
|||||||
'use strict' |
|
||||||
var remixLib = require('remix-lib') |
|
||||||
var EventManager = remixLib.EventManager |
|
||||||
const PluginAPI = require('./pluginAPI') |
|
||||||
/** |
|
||||||
* Register and Manage plugin: |
|
||||||
* |
|
||||||
* Plugin registration is done in the settings tab, |
|
||||||
* using the following format: |
|
||||||
* { |
|
||||||
* "title": "<plugin name>", |
|
||||||
* "url": "<plugin url>" |
|
||||||
* } |
|
||||||
* |
|
||||||
* structure of messages: |
|
||||||
* |
|
||||||
* - Notification sent by Remix: |
|
||||||
*{ |
|
||||||
* action: 'notification', |
|
||||||
* key: <string>, |
|
||||||
* type: <string>, |
|
||||||
* value: <array> |
|
||||||
*} |
|
||||||
* |
|
||||||
* - Request sent by the plugin: |
|
||||||
*{ |
|
||||||
* id: <number>, |
|
||||||
* action: 'request', |
|
||||||
* key: <string>, |
|
||||||
* type: <string>, |
|
||||||
* value: <array> |
|
||||||
*} |
|
||||||
* |
|
||||||
* - Response sent by Remix and receive by the plugin: |
|
||||||
*{ |
|
||||||
* id: <number>, |
|
||||||
* action: 'response', |
|
||||||
* key: <string>, |
|
||||||
* type: <string>, |
|
||||||
* value: <array>, |
|
||||||
* error: (see below) |
|
||||||
*} |
|
||||||
* => The `error` property is `undefined` if no error happened. |
|
||||||
* => In case of error (due to permission, system error, API error, etc...): |
|
||||||
* error: { code, msg (optional), data (optional), stack (optional) |
|
||||||
* => possible error code are still to be defined, but the generic one would be 500. |
|
||||||
* |
|
||||||
* Plugin receive 4 types of message: |
|
||||||
* - focus (when he get focus) |
|
||||||
* - unfocus (when he loose focus - is hidden) |
|
||||||
* - compilationData (that is triggered just after a focus - and send the current compilation data or null) |
|
||||||
* - compilationFinished (that is only sent to the plugin that has focus) |
|
||||||
* |
|
||||||
* Plugin can emit messages and receive response. |
|
||||||
* |
|
||||||
* CONFIG: |
|
||||||
* - getConfig(filename). The data to send should be formatted like: |
|
||||||
* { |
|
||||||
* id: <requestid>, |
|
||||||
* action: 'request', |
|
||||||
* key: 'config', |
|
||||||
* type: 'getConfig', |
|
||||||
* value: ['filename.ext'] |
|
||||||
* } |
|
||||||
* the plugin will reveice a response like: |
|
||||||
* { |
|
||||||
* id: <requestid>, |
|
||||||
* action: 'response', |
|
||||||
* key: 'config', |
|
||||||
* type: 'getConfig', |
|
||||||
* error, |
|
||||||
* value: ['content of filename.ext'] |
|
||||||
* } |
|
||||||
* same apply for the other call |
|
||||||
* - setConfig(filename, content) |
|
||||||
* - removeConfig |
|
||||||
* |
|
||||||
* See index.html and remix.js in test-browser folder for sample |
|
||||||
* |
|
||||||
*/ |
|
||||||
module.exports = class PluginManager { |
|
||||||
constructor (app, compilersArtefacts, txlistener, fileProviders, fileManager, udapp) { |
|
||||||
const self = this |
|
||||||
self.event = new EventManager() |
|
||||||
var pluginAPI = new PluginAPI( |
|
||||||
this, |
|
||||||
fileProviders, |
|
||||||
fileManager, |
|
||||||
compilersArtefacts, |
|
||||||
udapp |
|
||||||
) |
|
||||||
self._components = { pluginAPI } |
|
||||||
self.plugins = {} |
|
||||||
self.origins = {} |
|
||||||
self.inFocus |
|
||||||
fileManager.events.on('currentFileChanged', (file) => { |
|
||||||
self.broadcast(JSON.stringify({ |
|
||||||
action: 'notification', |
|
||||||
key: 'editor', |
|
||||||
type: 'currentFileChanged', |
|
||||||
value: [ file ] |
|
||||||
})) |
|
||||||
}) |
|
||||||
|
|
||||||
txlistener.event.register('newTransaction', (tx) => { |
|
||||||
self.broadcast(JSON.stringify({ |
|
||||||
action: 'notification', |
|
||||||
key: 'txlistener', |
|
||||||
type: 'newTransaction', |
|
||||||
value: [tx] |
|
||||||
})) |
|
||||||
}) |
|
||||||
|
|
||||||
window.addEventListener('message', (event) => { |
|
||||||
if (event.type !== 'message') return |
|
||||||
var extension = self.origins[event.origin] |
|
||||||
if (!extension) return |
|
||||||
|
|
||||||
function response (key, type, callid, error, result) { |
|
||||||
self.postToOrigin(event.origin, JSON.stringify({ |
|
||||||
id: callid, |
|
||||||
action: 'response', |
|
||||||
key: key, |
|
||||||
type: type, |
|
||||||
error: error, |
|
||||||
value: [ result ] |
|
||||||
})) |
|
||||||
} |
|
||||||
var data = JSON.parse(event.data) |
|
||||||
data.value.unshift(extension) |
|
||||||
data.value.push((error, result) => { |
|
||||||
response(data.key, data.type, data.id, error, result) |
|
||||||
}) |
|
||||||
if (pluginAPI[data.key] && pluginAPI[data.key][data.type]) { |
|
||||||
pluginAPI[data.key][data.type].apply({}, data.value) |
|
||||||
} else { |
|
||||||
response(data.key, data.type, data.id, `Endpoint ${data.key}/${data.type} not present`, null) |
|
||||||
} |
|
||||||
}, false) |
|
||||||
} |
|
||||||
unregister (desc) { |
|
||||||
const self = this |
|
||||||
self._components.pluginAPI.editor.discardHighlight(desc.title, () => {}) |
|
||||||
delete self.plugins[desc.title] |
|
||||||
delete self.origins[desc.url] |
|
||||||
} |
|
||||||
register (desc, modal, content) { |
|
||||||
const self = this |
|
||||||
self.plugins[desc.title] = { content, modal, origin: desc.url } |
|
||||||
self.origins[desc.url] = desc.title |
|
||||||
} |
|
||||||
broadcast (value) { |
|
||||||
for (var plugin in this.plugins) { |
|
||||||
this.post(plugin, value) |
|
||||||
} |
|
||||||
} |
|
||||||
postToOrigin (origin, value) { |
|
||||||
if (this.origins[origin]) { |
|
||||||
this.post(this.origins[origin], value) |
|
||||||
} |
|
||||||
} |
|
||||||
receivedDataFrom (methodName, mod, argumentsArray) { |
|
||||||
// TODO check whether 'mod' as right to do that
|
|
||||||
console.log(argumentsArray) |
|
||||||
this.event.trigger(methodName, argumentsArray) // forward to internal modules
|
|
||||||
this.broadcast(JSON.stringify({ // forward to plugins
|
|
||||||
action: 'notification', |
|
||||||
key: mod, |
|
||||||
type: methodName, |
|
||||||
value: argumentsArray |
|
||||||
})) |
|
||||||
} |
|
||||||
post (name, value) { |
|
||||||
const self = this |
|
||||||
if (self.plugins[name]) { |
|
||||||
self.plugins[name].content.querySelector('iframe').contentWindow.postMessage(value, self.plugins[name].origin) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,38 +0,0 @@ |
|||||||
'use strict' |
|
||||||
|
|
||||||
module.exports = { |
|
||||||
'oraclize': { |
|
||||||
url: 'https://remix-plugin.oraclize.it', |
|
||||||
title: 'Oraclize' |
|
||||||
}, |
|
||||||
'solium': { |
|
||||||
url: 'https://two-water.surge.sh', |
|
||||||
title: 'Solium' |
|
||||||
}, |
|
||||||
'ethdoc': { |
|
||||||
url: 'https://30400.swarm-gateways.net/bzz:/ethdoc.remixide.eth', |
|
||||||
title: 'Ethdoc' |
|
||||||
}, |
|
||||||
'openzeppelin snippet': { |
|
||||||
url: 'https://left-edge.surge.sh', |
|
||||||
title: 'Openzeppelin snippet' |
|
||||||
}, |
|
||||||
'vyper': { |
|
||||||
url: 'https://plugin.vyper.live', |
|
||||||
title: 'Vyper' |
|
||||||
}, |
|
||||||
'slither/mythril': { |
|
||||||
url: 'http://jittery-space.surge.sh', |
|
||||||
title: 'Slither/Mythril' |
|
||||||
}, |
|
||||||
'pipeline': { |
|
||||||
url: 'https://pipeline.pipeos.one', |
|
||||||
title: 'Pipeline' |
|
||||||
} |
|
||||||
/* |
|
||||||
'etherscan-general': { |
|
||||||
url: 'http://127.0.0.1:8081', |
|
||||||
title: 'Etherscan-general' |
|
||||||
} |
|
||||||
*/ |
|
||||||
} |
|
@ -0,0 +1,66 @@ |
|||||||
|
const executionContext = require('../../execution-context') |
||||||
|
import { NetworkApi } from 'remix-plugin' |
||||||
|
|
||||||
|
export const profile = { |
||||||
|
name: 'network', |
||||||
|
description: 'Manage the network (mainnet, ropsten, goerli...) and the provider (web3, vm, injected)' |
||||||
|
} |
||||||
|
|
||||||
|
// Network API has :
|
||||||
|
// - events: ['providerChanged']
|
||||||
|
// - methods: ['getNetworkProvider', 'getEndpoint', 'detectNetwork', 'addNetwork', 'removeNetwork']
|
||||||
|
|
||||||
|
export class NetworkModule extends NetworkApi { |
||||||
|
constructor () { |
||||||
|
super(profile) |
||||||
|
// TODO: See with remix-lib to make sementic coherent
|
||||||
|
executionContext.event.register('contextChanged', (provider) => { |
||||||
|
this.events.emit('providerChanged', provider) |
||||||
|
}) |
||||||
|
/* |
||||||
|
// Events that could be implemented later
|
||||||
|
executionContext.event.register('removeProvider', (provider) => { |
||||||
|
this.events.emit('networkRemoved', provider) |
||||||
|
}) |
||||||
|
executionContext.event.register('addProvider', (provider) => { |
||||||
|
this.events.emit('networkAdded', provider) |
||||||
|
}) |
||||||
|
executionContext.event.register('web3EndpointChanged', (provider) => { |
||||||
|
this.events.emit('web3EndpointChanged', provider) |
||||||
|
}) |
||||||
|
*/ |
||||||
|
} |
||||||
|
|
||||||
|
/** Return the current network provider (web3, vm, injected) */ |
||||||
|
getNetworkProvider () { |
||||||
|
return executionContext.getProvider() |
||||||
|
} |
||||||
|
|
||||||
|
/** Return the current network */ |
||||||
|
detectNetwork () { |
||||||
|
return new Promise((resolve, reject) => { |
||||||
|
executionContext.detectNetwork((error, network) => { |
||||||
|
error ? reject(error) : resolve(network) |
||||||
|
}) |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
/** Return the url only if network provider is 'web3' */ |
||||||
|
getEndpoint () { |
||||||
|
const provider = executionContext.getProvider() |
||||||
|
if (provider !== 'web3') { |
||||||
|
throw new Error('no endpoint: current provider is either injected or vm') |
||||||
|
} |
||||||
|
return provider.web3().currentProvider.host |
||||||
|
} |
||||||
|
|
||||||
|
/** Add a custom network to the list of available networks */ |
||||||
|
addNetwork (customNetwork) { |
||||||
|
executionContext.addProvider(customNetwork) |
||||||
|
} |
||||||
|
|
||||||
|
/** Remove a network to the list of availble networks */ |
||||||
|
removeNetwork (name) { |
||||||
|
executionContext.removeProvider(name) |
||||||
|
} |
||||||
|
} |
@ -1,23 +0,0 @@ |
|||||||
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', |
|
||||||
permission: true |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
Loading…
Reference in new issue