mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
integrate metamask-ui with id mgmt
This commit is contained in:
parent
3eaf027e30
commit
7347a66eb0
@ -1,33 +1,184 @@
|
|||||||
|
const Dnode = require('dnode')
|
||||||
|
const KeyStore = require('eth-lightwallet').keystore
|
||||||
|
const PortStream = require('./lib/port-stream.js')
|
||||||
const MetaMaskProvider = require('./lib/metamask-provider')
|
const MetaMaskProvider = require('./lib/metamask-provider')
|
||||||
// const PortStream = require('./lib/port-stream.js')
|
|
||||||
const identitiesUrl = 'https://alpha.metamask.io/identities/'
|
|
||||||
|
|
||||||
// var unsignedTxs = {}
|
console.log('ready to roll')
|
||||||
|
|
||||||
var zeroClient = MetaMaskProvider()
|
// setup provider
|
||||||
|
var zeroClient = MetaMaskProvider({
|
||||||
|
rpcUrl: 'https://testrpc.metamask.io/',
|
||||||
|
getAccounts: getAccounts,
|
||||||
|
sendTransaction: confirmTransaction,
|
||||||
|
})
|
||||||
|
|
||||||
// setup messaging
|
// setup messaging
|
||||||
chrome.runtime.onConnect.addListener(connectRemote)
|
chrome.runtime.onConnect.addListener(connectRemote)
|
||||||
// chrome.runtime.onConnectExternal.addListener(connectRemote)
|
|
||||||
function connectRemote(remotePort){
|
function connectRemote(remotePort){
|
||||||
|
var isMetaMaskInternalProcess = (remotePort.name === 'popup')
|
||||||
|
if (isMetaMaskInternalProcess) {
|
||||||
|
// communication with popup
|
||||||
|
handleInternalCommunication(remotePort)
|
||||||
|
} else {
|
||||||
|
// communication with page
|
||||||
|
handleExternalCommunication(remotePort)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleInternalCommunication(remotePort){
|
||||||
|
var duplex = new PortStream(remotePort)
|
||||||
|
var remote = Dnode({
|
||||||
|
getState: getState,
|
||||||
|
setLocked: setLocked,
|
||||||
|
submitPassword: submitPassword,
|
||||||
|
setSelectedAddress: setSelectedAddress,
|
||||||
|
signTransaction: signTransaction,
|
||||||
|
})
|
||||||
|
duplex.pipe(remote).pipe(duplex)
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleExternalCommunication(remotePort){
|
||||||
remotePort.onMessage.addListener(onRpcRequest.bind(null, remotePort))
|
remotePort.onMessage.addListener(onRpcRequest.bind(null, remotePort))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handle rpc requests
|
||||||
function onRpcRequest(remotePort, payload){
|
function onRpcRequest(remotePort, payload){
|
||||||
|
// console.log('MetaMaskPlugin - incoming payload:', payload)
|
||||||
zeroClient.sendAsync(payload, function onPayloadHandled(err, response){
|
zeroClient.sendAsync(payload, function onPayloadHandled(err, response){
|
||||||
if (err) throw err
|
if (err) throw err
|
||||||
console.log('MetaMaskPlugin - RPC complete:', payload, '->', response)
|
console.log('MetaMaskPlugin - RPC complete:', payload, '->', response)
|
||||||
// if (response.result === true) debugger
|
|
||||||
// if (typeof response !== 'object') {
|
|
||||||
// if (!response) {
|
|
||||||
// console.warn('-------------------------------')
|
|
||||||
// console.warn(payload, '->', response)
|
|
||||||
// console.warn('-------------------------------')
|
|
||||||
// }
|
|
||||||
remotePort.postMessage(response)
|
remotePort.postMessage(response)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// id mgmt
|
||||||
|
var selectedAddress = null
|
||||||
|
|
||||||
|
function getState(cb){
|
||||||
|
var result = _getState()
|
||||||
|
cb(null, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
function _getState(cb){
|
||||||
|
var unlocked = isUnlocked()
|
||||||
|
var result = {
|
||||||
|
isUnlocked: unlocked,
|
||||||
|
identities: unlocked ? getIdentities() : {},
|
||||||
|
selectedAddress: selectedAddress,
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
function isUnlocked(){
|
||||||
|
var password = window.sessionStorage['password']
|
||||||
|
var result = Boolean(password)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
function setLocked(){
|
||||||
|
delete window.sessionStorage['password']
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSelectedAddress(address, cb){
|
||||||
|
selectedAddress = address
|
||||||
|
cb(null, _getState())
|
||||||
|
}
|
||||||
|
|
||||||
|
function submitPassword(password, cb){
|
||||||
|
console.log('submitPassword:', password)
|
||||||
|
tryPassword(password, function(err){
|
||||||
|
if (err) console.log('bad password:', password, err)
|
||||||
|
if (err) return cb(err)
|
||||||
|
console.log('good password:', password)
|
||||||
|
window.sessionStorage['password'] = password
|
||||||
|
cb(null, _getState())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAccounts(cb){
|
||||||
|
var identities = getIdentities()
|
||||||
|
var result = selectedAddress ? [selectedAddress] : []
|
||||||
|
cb(null, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
function getIdentities(cb){
|
||||||
|
var keyStore = getKeyStore()
|
||||||
|
var addresses = keyStore.getAddresses()
|
||||||
|
var accountStore = {}
|
||||||
|
addresses.map(function(address){
|
||||||
|
address = '0x'+address
|
||||||
|
accountStore[address] = {
|
||||||
|
name: 'Wally',
|
||||||
|
img: 'QmW6hcwYzXrNkuHrpvo58YeZvbZxUddv69ATSHY3BHpPdd',
|
||||||
|
address: address,
|
||||||
|
balance: 10.005,
|
||||||
|
txCount: 16,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return accountStore
|
||||||
|
}
|
||||||
|
|
||||||
|
function tryPassword(password, cb){
|
||||||
|
var keyStore = getKeyStore(password)
|
||||||
|
var address = keyStore.getAddresses()[0]
|
||||||
|
if (!address) return cb(new Error('KeyStore - No address to check.'))
|
||||||
|
var hdPathString = keyStore.defaultHdPathString
|
||||||
|
try {
|
||||||
|
var encKey = keyStore.generateEncKey(password)
|
||||||
|
var encPrivKey = keyStore.ksData[hdPathString].encPrivKeys[address]
|
||||||
|
var privKey = KeyStore._decryptKey(encPrivKey, encKey)
|
||||||
|
var addrFromPrivKey = KeyStore._computeAddressFromPrivKey(privKey)
|
||||||
|
} catch (err) {
|
||||||
|
return cb(err)
|
||||||
|
}
|
||||||
|
if (addrFromPrivKey !== address) return cb(new Error('KeyStore - Decrypting private key failed!'))
|
||||||
|
cb()
|
||||||
|
}
|
||||||
|
|
||||||
|
function confirmTransaction(txParams, cb){
|
||||||
|
console.log('confirmTransaction:', txParams)
|
||||||
|
}
|
||||||
|
|
||||||
|
function signTransaction(txParams, cb){
|
||||||
|
console.log('signTransaction:', txParams)
|
||||||
|
}
|
||||||
|
|
||||||
|
var keyStore = null
|
||||||
|
function getKeyStore(password){
|
||||||
|
if (keyStore) return keyStore
|
||||||
|
password = password || getPassword()
|
||||||
|
var serializedKeystore = window.localStorage['lightwallet']
|
||||||
|
// returning user
|
||||||
|
if (serializedKeystore) {
|
||||||
|
keyStore = KeyStore.deserialize(serializedKeystore)
|
||||||
|
// first time here
|
||||||
|
} else {
|
||||||
|
var defaultPassword = 'test'
|
||||||
|
console.log('creating new keystore with default password:', defaultPassword)
|
||||||
|
var secretSeed = KeyStore.generateRandomSeed()
|
||||||
|
keyStore = new KeyStore(secretSeed, defaultPassword)
|
||||||
|
keyStore.generateNewAddress(defaultPassword, 3)
|
||||||
|
saveKeystore()
|
||||||
|
}
|
||||||
|
keyStore.passwordProvider = unlockKeystore
|
||||||
|
return keyStore
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveKeystore(){
|
||||||
|
window.localStorage['lightwallet'] = keyStore.serialize()
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPassword(){
|
||||||
|
var password = window.sessionStorage['password']
|
||||||
|
if (!password) throw new Error('No password found...')
|
||||||
|
}
|
||||||
|
|
||||||
|
function unlockKeystore(cb){
|
||||||
|
var password = getPassword()
|
||||||
|
console.warn('unlocking keystore...')
|
||||||
|
cb(null, password)
|
||||||
|
}
|
||||||
|
|
||||||
// // load from storage
|
// // load from storage
|
||||||
// chrome.storage.sync.get(function(data){
|
// chrome.storage.sync.get(function(data){
|
||||||
// for (var key in data) {
|
// for (var key in data) {
|
||||||
|
@ -14,7 +14,7 @@ var pageStream = new LocalMessageDuplexStream({
|
|||||||
name: 'contentscript',
|
name: 'contentscript',
|
||||||
target: 'inpage',
|
target: 'inpage',
|
||||||
})
|
})
|
||||||
var pluginPort = chrome.runtime.connect({name: 'metamask'})
|
var pluginPort = chrome.runtime.connect({name: 'contentscript'})
|
||||||
var pluginStream = new PortStream(pluginPort)
|
var pluginStream = new PortStream(pluginPort)
|
||||||
|
|
||||||
// forward communication across
|
// forward communication across
|
||||||
|
@ -3,7 +3,7 @@ const CacheSubprovider = require('web3-provider-engine/subproviders/cache.js')
|
|||||||
const StaticSubprovider = require('web3-provider-engine/subproviders/static.js')
|
const StaticSubprovider = require('web3-provider-engine/subproviders/static.js')
|
||||||
const FilterSubprovider = require('web3-provider-engine/subproviders/filters.js')
|
const FilterSubprovider = require('web3-provider-engine/subproviders/filters.js')
|
||||||
const VmSubprovider = require('web3-provider-engine/subproviders/vm.js')
|
const VmSubprovider = require('web3-provider-engine/subproviders/vm.js')
|
||||||
const LightWalletSubprovider = require('web3-provider-engine/subproviders/lightwallet.js')
|
const HookedWalletSubprovider = require('web3-provider-engine/subproviders/hooked-wallet.js')
|
||||||
const RpcSubprovider = require('web3-provider-engine/subproviders/rpc.js')
|
const RpcSubprovider = require('web3-provider-engine/subproviders/rpc.js')
|
||||||
|
|
||||||
module.exports = metamaskProvider
|
module.exports = metamaskProvider
|
||||||
@ -22,7 +22,7 @@ function metamaskProvider(opts){
|
|||||||
eth_hashrate: '0x0',
|
eth_hashrate: '0x0',
|
||||||
eth_mining: false,
|
eth_mining: false,
|
||||||
eth_syncing: true,
|
eth_syncing: true,
|
||||||
})
|
}))
|
||||||
|
|
||||||
// filters
|
// filters
|
||||||
engine.addProvider(new FilterSubprovider())
|
engine.addProvider(new FilterSubprovider())
|
||||||
@ -31,21 +31,22 @@ function metamaskProvider(opts){
|
|||||||
engine.addProvider(new VmSubprovider())
|
engine.addProvider(new VmSubprovider())
|
||||||
|
|
||||||
// id mgmt
|
// id mgmt
|
||||||
engine.addProvider(new LightWalletSubprovider())
|
engine.addProvider(new HookedWalletSubprovider({
|
||||||
|
getAccounts: opts.getAccounts,
|
||||||
|
sendTransaction: opts.sendTransaction,
|
||||||
|
}))
|
||||||
|
|
||||||
// data source
|
// data source
|
||||||
engine.addProvider(new RpcSubprovider({
|
engine.addProvider(new RpcSubprovider({
|
||||||
rpcUrl: 'https://testrpc.metamask.io/',
|
rpcUrl: opts.rpcUrl,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
// log new blocks
|
// log new blocks
|
||||||
engine.on('block', function(block){
|
// engine.on('block', function(block){
|
||||||
// lazy hack - move caching and current block to engine
|
// console.log('================================')
|
||||||
engine.currentBlock = block
|
// console.log('BLOCK CHANGED:', '#'+block.number.toString('hex'), '0x'+block.hash.toString('hex'))
|
||||||
console.log('================================')
|
// console.log('================================')
|
||||||
console.log('BLOCK CHANGED:', '#'+block.number.toString('hex'), '0x'+block.hash.toString('hex'))
|
// })
|
||||||
console.log('================================')
|
|
||||||
})
|
|
||||||
|
|
||||||
// start polling for blocks
|
// start polling for blocks
|
||||||
engine.start()
|
engine.start()
|
||||||
|
@ -1,13 +1,30 @@
|
|||||||
|
const Dnode = require('dnode')
|
||||||
const MetaMaskUi = require('metamask-ui')
|
const MetaMaskUi = require('metamask-ui')
|
||||||
const MetaMaskUiCss = require('metamask-ui/css')
|
const MetaMaskUiCss = require('metamask-ui/css')
|
||||||
const injectCss = require('inject-css')
|
const injectCss = require('inject-css')
|
||||||
|
const PortStream = require('./lib/port-stream.js')
|
||||||
|
|
||||||
|
|
||||||
var container = document.getElementById('app-content')
|
// setup communication with background
|
||||||
|
var pluginPort = chrome.runtime.connect({name: 'popup'})
|
||||||
|
var duplex = new PortStream(pluginPort)
|
||||||
|
var background = Dnode({
|
||||||
|
// setUnconfirmedTxs: setUnconfirmedTxs,
|
||||||
|
})
|
||||||
|
duplex.pipe(background).pipe(duplex)
|
||||||
|
background.once('remote', setupApp)
|
||||||
|
|
||||||
|
// setup app
|
||||||
var css = MetaMaskUiCss()
|
var css = MetaMaskUiCss()
|
||||||
injectCss(css)
|
injectCss(css)
|
||||||
|
|
||||||
var app = MetaMaskUi({
|
function setupApp(accountManager){
|
||||||
container: container,
|
|
||||||
})
|
var container = document.getElementById('app-content')
|
||||||
|
|
||||||
|
var app = MetaMaskUi({
|
||||||
|
container: container,
|
||||||
|
accountManager: accountManager,
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
@ -8,6 +8,8 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"async": "^1.4.0",
|
"async": "^1.4.0",
|
||||||
|
"dnode": "^1.2.2",
|
||||||
|
"eth-lightwallet": "^1.0.1",
|
||||||
"ethereumjs-tx": "^0.6.7",
|
"ethereumjs-tx": "^0.6.7",
|
||||||
"ethereumjs-util": "^1.3.5",
|
"ethereumjs-util": "^1.3.5",
|
||||||
"inject-css": "^0.1.1",
|
"inject-css": "^0.1.1",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user