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
|
||||
require('time-grunt')(grunt);
|
||||
|
||||
grunt.loadNpmTasks('grunt-browserify');
|
||||
|
||||
// Configurable paths
|
||||
var config = {
|
||||
app: 'app',
|
||||
@ -36,7 +38,8 @@ module.exports = function (grunt) {
|
||||
files: ['<%= config.app %>/scripts/{,*/}*.js'],
|
||||
options: {
|
||||
livereload: '<%= connect.options.livereload %>'
|
||||
}
|
||||
},
|
||||
tasks: ['useminPrepare', 'usemin', 'browserify'],
|
||||
},
|
||||
gruntfile: {
|
||||
files: ['Gruntfile.js']
|
||||
@ -61,7 +64,7 @@ module.exports = function (grunt) {
|
||||
}
|
||||
},
|
||||
|
||||
// Grunt server and debug server setting
|
||||
// Grunt server and dev server setting
|
||||
connect: {
|
||||
options: {
|
||||
port: 9000,
|
||||
@ -225,6 +228,14 @@ module.exports = function (grunt) {
|
||||
// dist: {}
|
||||
// },
|
||||
|
||||
browserify: {
|
||||
basic: {
|
||||
files: {
|
||||
'<%= config.dist %>/scripts/web3.js': ['<%= config.app %>/scripts/web3.js'],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// Copies remaining files to places other tasks can use
|
||||
copy: {
|
||||
dist: {
|
||||
@ -248,16 +259,19 @@ module.exports = function (grunt) {
|
||||
// Run some tasks in parallel to speed up build process
|
||||
concurrent: {
|
||||
chrome: [
|
||||
'browserify',
|
||||
],
|
||||
dist: [
|
||||
'imagemin',
|
||||
'svgmin'
|
||||
'svgmin',
|
||||
'browserify',
|
||||
],
|
||||
test: [
|
||||
'browserify',
|
||||
]
|
||||
},
|
||||
|
||||
// Auto buildnumber, exclude debug files. smart builds that event pages
|
||||
// Auto buildnumber, exclude dev files. smart builds that event pages
|
||||
chromeManifest: {
|
||||
dist: {
|
||||
options: {
|
||||
@ -294,11 +308,12 @@ module.exports = function (grunt) {
|
||||
}
|
||||
});
|
||||
|
||||
grunt.registerTask('debug', function () {
|
||||
grunt.registerTask('dev', function () {
|
||||
grunt.task.run([
|
||||
'concurrent: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__",
|
||||
"version": "0.0.1",
|
||||
"version": "0.0.17",
|
||||
"manifest_version": 2,
|
||||
"description": "__MSG_appDescription__",
|
||||
"icons": {
|
||||
@ -38,4 +38,4 @@
|
||||
"web_accessible_resources": [
|
||||
"scripts/web3.js"
|
||||
]
|
||||
}
|
||||
}
|
@ -1,8 +1,5 @@
|
||||
console.log('\'Allo \'Allo! Content 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.onload = function() { this.parentNode.removeChild(this) }
|
||||
;(document.head||document.documentElement).appendChild(scriptTag)
|
||||
scriptTag.onload = function() { debugger; this.parentNode.removeChild(this) }
|
||||
;(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....')
|
||||
window.web3 = {}
|
||||
window.web3 = web3
|
||||
|
||||
|
||||
function forwardPayload(){
|
||||
debugger
|
||||
}
|
@ -2,6 +2,8 @@
|
||||
"name": "metamask",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"async": "^1.4.0",
|
||||
"ethereumjs-util": "^1.3.5",
|
||||
"web3": "^0.9.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
|