metamask provider skeleton
27
Gruntfile.js
@ -15,6 +15,8 @@ module.exports = function (grunt) {
|
|||||||
// Time how long tasks take. Can help when optimizing build times
|
// Time how long tasks take. Can help when optimizing build times
|
||||||
require('time-grunt')(grunt);
|
require('time-grunt')(grunt);
|
||||||
|
|
||||||
|
grunt.loadNpmTasks('grunt-browserify');
|
||||||
|
|
||||||
// Configurable paths
|
// Configurable paths
|
||||||
var config = {
|
var config = {
|
||||||
app: 'app',
|
app: 'app',
|
||||||
@ -36,7 +38,8 @@ module.exports = function (grunt) {
|
|||||||
files: ['<%= config.app %>/scripts/{,*/}*.js'],
|
files: ['<%= config.app %>/scripts/{,*/}*.js'],
|
||||||
options: {
|
options: {
|
||||||
livereload: '<%= connect.options.livereload %>'
|
livereload: '<%= connect.options.livereload %>'
|
||||||
}
|
},
|
||||||
|
tasks: ['useminPrepare', 'usemin', 'browserify'],
|
||||||
},
|
},
|
||||||
gruntfile: {
|
gruntfile: {
|
||||||
files: ['Gruntfile.js']
|
files: ['Gruntfile.js']
|
||||||
@ -61,7 +64,7 @@ module.exports = function (grunt) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Grunt server and debug server setting
|
// Grunt server and dev server setting
|
||||||
connect: {
|
connect: {
|
||||||
options: {
|
options: {
|
||||||
port: 9000,
|
port: 9000,
|
||||||
@ -225,6 +228,14 @@ module.exports = function (grunt) {
|
|||||||
// dist: {}
|
// dist: {}
|
||||||
// },
|
// },
|
||||||
|
|
||||||
|
browserify: {
|
||||||
|
basic: {
|
||||||
|
files: {
|
||||||
|
'<%= config.dist %>/scripts/web3.js': ['<%= config.app %>/scripts/web3.js'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
// Copies remaining files to places other tasks can use
|
// Copies remaining files to places other tasks can use
|
||||||
copy: {
|
copy: {
|
||||||
dist: {
|
dist: {
|
||||||
@ -248,16 +259,19 @@ module.exports = function (grunt) {
|
|||||||
// Run some tasks in parallel to speed up build process
|
// Run some tasks in parallel to speed up build process
|
||||||
concurrent: {
|
concurrent: {
|
||||||
chrome: [
|
chrome: [
|
||||||
|
'browserify',
|
||||||
],
|
],
|
||||||
dist: [
|
dist: [
|
||||||
'imagemin',
|
'imagemin',
|
||||||
'svgmin'
|
'svgmin',
|
||||||
|
'browserify',
|
||||||
],
|
],
|
||||||
test: [
|
test: [
|
||||||
|
'browserify',
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
// Auto buildnumber, exclude debug files. smart builds that event pages
|
// Auto buildnumber, exclude dev files. smart builds that event pages
|
||||||
chromeManifest: {
|
chromeManifest: {
|
||||||
dist: {
|
dist: {
|
||||||
options: {
|
options: {
|
||||||
@ -294,11 +308,12 @@ module.exports = function (grunt) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
grunt.registerTask('debug', function () {
|
grunt.registerTask('dev', function () {
|
||||||
grunt.task.run([
|
grunt.task.run([
|
||||||
'concurrent:chrome',
|
'concurrent:chrome',
|
||||||
'connect:chrome',
|
'connect:chrome',
|
||||||
'watch'
|
'build',
|
||||||
|
'watch',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
BIN
app/.DS_Store
vendored
Normal file
BIN
app/images/.DS_Store
vendored
Normal file
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 758 B After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 2.7 KiB |
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "__MSG_appName__",
|
"name": "__MSG_appName__",
|
||||||
"version": "0.0.1",
|
"version": "0.0.17",
|
||||||
"manifest_version": 2,
|
"manifest_version": 2,
|
||||||
"description": "__MSG_appDescription__",
|
"description": "__MSG_appDescription__",
|
||||||
"icons": {
|
"icons": {
|
||||||
@ -38,4 +38,4 @@
|
|||||||
"web_accessible_resources": [
|
"web_accessible_resources": [
|
||||||
"scripts/web3.js"
|
"scripts/web3.js"
|
||||||
]
|
]
|
||||||
}
|
}
|
@ -1,8 +1,5 @@
|
|||||||
console.log('\'Allo \'Allo! Content script')
|
|
||||||
|
|
||||||
var scriptTag = document.createElement('script')
|
var scriptTag = document.createElement('script')
|
||||||
// TODO: add "script.js" to web_accessible_resources in manifest.json
|
|
||||||
scriptTag.src = chrome.extension.getURL('scripts/web3.js')
|
scriptTag.src = chrome.extension.getURL('scripts/web3.js')
|
||||||
|
|
||||||
// scriptTag.onload = function() { this.parentNode.removeChild(this) }
|
scriptTag.onload = function() { debugger; this.parentNode.removeChild(this) }
|
||||||
;(document.head||document.documentElement).appendChild(scriptTag)
|
;(document.head||document.documentElement).appendChild(scriptTag)
|
||||||
|
122
app/scripts/metamask-provider.js
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
var HttpProvider = require('web3/lib/web3/httpprovider.js')
|
||||||
|
var ethUtils = require('ethereumjs-util')
|
||||||
|
var async = require('async')
|
||||||
|
|
||||||
|
module.exports = MetamaskProvider
|
||||||
|
|
||||||
|
|
||||||
|
function MetamaskProvider(forwardPayload, host) {
|
||||||
|
this.handlers = []
|
||||||
|
this.forwardPayload = forwardPayload
|
||||||
|
this.http = new HttpProvider(host)
|
||||||
|
}
|
||||||
|
|
||||||
|
MetamaskProvider.prototype.send = function (payload) {
|
||||||
|
if (Array.isArray(payload)) {
|
||||||
|
return payload.map( this.handlePayload.bind(this) )
|
||||||
|
} else {
|
||||||
|
return this.handlePayload( payload )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MetamaskProvider.prototype.sendAsync = function (payload, cb) {
|
||||||
|
if (Array.isArray(payload)) {
|
||||||
|
async.map( payload, this.handlePayload.bind(this), cb )
|
||||||
|
} else {
|
||||||
|
this.handlePayload( payload, cb )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MetamaskProvider.prototype.handlePayload = function (payload, cb) {
|
||||||
|
var _this = this
|
||||||
|
var isSync = !cb
|
||||||
|
var resolvedSync = true
|
||||||
|
var result = undefined
|
||||||
|
|
||||||
|
// TODO - this should be injected from Vapor dapp starts
|
||||||
|
var exposedAccounts = ['0xa06ef3ed1ce41ade87f764de6ce8095c569d6d57']
|
||||||
|
|
||||||
|
switch (payload.method) {
|
||||||
|
|
||||||
|
case 'web3_sha3':
|
||||||
|
var inputHex = stripHexStringPrefix(payload.params[0])
|
||||||
|
var hash = '0x'+ethUtils.sha3(new Buffer(inputHex, 'hex')).toString('hex')
|
||||||
|
return handleResult(null, wrapResponse(payload, hash))
|
||||||
|
|
||||||
|
case 'eth_sendTransaction':
|
||||||
|
this.forwardPayload(payload)
|
||||||
|
return handleResult(null, wrapResponse(payload, ''))
|
||||||
|
|
||||||
|
case 'eth_coinbase':
|
||||||
|
var currentAddress = exposedAccounts[0]
|
||||||
|
return handleResult(null, wrapResponse(payload, currentAddress))
|
||||||
|
|
||||||
|
case 'eth_accounts':
|
||||||
|
return handleResult(null, wrapResponse(payload, exposedAccounts))
|
||||||
|
|
||||||
|
case 'eth_gasPrice':
|
||||||
|
// TODO - this should be dynamically set somehow
|
||||||
|
var gasPrice = '0x01'
|
||||||
|
return handleResult(null, wrapResponse(payload, [gasPrice]))
|
||||||
|
|
||||||
|
case 'eth_call':
|
||||||
|
var params = payload.params
|
||||||
|
// default 'from' to default account
|
||||||
|
var args = params[0]
|
||||||
|
if (!args.from) {
|
||||||
|
var currentAddress = exposedAccounts[0]
|
||||||
|
args.from = currentAddress
|
||||||
|
}
|
||||||
|
// default block to latest
|
||||||
|
params[1] = params[1] || 'latest'
|
||||||
|
// turn on debug trace
|
||||||
|
params[2] = global.DEBUG_RPC
|
||||||
|
return handleNormally()
|
||||||
|
|
||||||
|
default:
|
||||||
|
return handleNormally()
|
||||||
|
}
|
||||||
|
|
||||||
|
resolvedSync = false
|
||||||
|
|
||||||
|
function handleNormally(){
|
||||||
|
if (isSync) {
|
||||||
|
return handleResult(null, _this.http.send(payload))
|
||||||
|
} else {
|
||||||
|
_this.http.sendAsync(payload, handleResult)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// helper for normalizing handling of sync+async responses
|
||||||
|
function handleResult(err, resp) {
|
||||||
|
if (isSync) {
|
||||||
|
return resp
|
||||||
|
} else {
|
||||||
|
if (resolvedSync) {
|
||||||
|
process.nextTick(cb.bind(null, err, resp))
|
||||||
|
} else {
|
||||||
|
cb(err, resp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function wrapResponse(payload, result){
|
||||||
|
return {
|
||||||
|
jsonrpc: payload.jsonrpc,
|
||||||
|
id: payload.id,
|
||||||
|
result: result,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function stripHexStringPrefix(hex) {
|
||||||
|
if (!hex) {
|
||||||
|
return hex
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hex.slice(0, 2) === '0x') {
|
||||||
|
return hex.slice(2);
|
||||||
|
} else {
|
||||||
|
return hex;
|
||||||
|
}
|
||||||
|
}
|
@ -1,2 +1,14 @@
|
|||||||
|
const web3 = require('web3')
|
||||||
|
const MetamaskProvider = require('./metamask-provider.js')
|
||||||
|
|
||||||
|
|
||||||
|
var provider = new MetamaskProvider(forwardPayload, 'https://rpc.metamask.io')
|
||||||
|
web3.setProvider(provider)
|
||||||
|
|
||||||
console.log('injecting web3....')
|
console.log('injecting web3....')
|
||||||
window.web3 = {}
|
window.web3 = web3
|
||||||
|
|
||||||
|
|
||||||
|
function forwardPayload(){
|
||||||
|
debugger
|
||||||
|
}
|
@ -2,6 +2,8 @@
|
|||||||
"name": "metamask",
|
"name": "metamask",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"async": "^1.4.0",
|
||||||
|
"ethereumjs-util": "^1.3.5",
|
||||||
"web3": "^0.9.2"
|
"web3": "^0.9.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|