Added beginning of RPC providers.

This commit is contained in:
ricmoo 2016-07-26 17:57:11 -04:00
parent fa0d54966d
commit 5c9ee7f2a5
5 changed files with 147 additions and 30 deletions

@ -0,0 +1,10 @@
'use strict';
try {
console.log('Starting load xml')
module.exports.XMLHttpRequest = XMLHttpRequest;
console.log('Done load xml')
} catch(error) {
console.log('Warning: XMLHttpRequest is not defined');
module.exports.XMLHttpRequest = null;
}

@ -325,7 +325,7 @@ function Interface(abi) {
result.parse = function(data) {
return Interface.decodeParams(
outputTypes,
utils.hexOrBuffer(data).toString('hex')
utils.hexOrBuffer(data)
)
};
} else {
@ -358,7 +358,7 @@ function Interface(abi) {
result.parse = function(data) {
return Interface.decodeParams(
inputTypes,
utils.hexOrBuffer(data).toString('hex')
utils.hexOrBuffer(data)
);
};
return result;
@ -434,7 +434,6 @@ utils.defineProperty(Interface, 'decodeParams', function(types, data) {
data = utils.hexOrBuffer(data);
var values = [];
var offset = 0;
types.forEach(function(type) {
var coder = getParamCoder(type);
@ -448,7 +447,6 @@ utils.defineProperty(Interface, 'decodeParams', function(types, data) {
}
values.push(result.value);
});
return values;
});
@ -457,13 +455,14 @@ var allowedTransactionKeys = {
data: true, from: true, gasLimit: true, gasPrice:true, to: true, value: true
}
function Contract(web3, wallet, contractAddress, contractInterface) {
utils.defineProperty(this, 'web3', web3);
function Contract(provider, wallet, contractAddress, contractInterface) {
utils.defineProperty(this, 'provider', provider);
utils.defineProperty(this, 'wallet', wallet);
utils.defineProperty(this, 'contractAddress', contractAddress);
utils.defineProperty(this, 'interface', contractInterface);
/*
function getWeb3Promise(method) {
var params = Array.prototype.slice.call(arguments, 1);
return new Promise(function(resolve, reject) {
@ -476,7 +475,7 @@ function Contract(web3, wallet, contractAddress, contractInterface) {
web3.eth[method].apply(web3, params);
});
}
*/
var self = this;
var filters = {};
@ -504,6 +503,7 @@ function Contract(web3, wallet, contractAddress, contractInterface) {
filters[call.name] = info;
// Start a new filter
/*
info.filter = web3.eth.filter({
address: contractAddress,
topics: call.topics
@ -520,8 +520,8 @@ function Contract(web3, wallet, contractAddress, contractInterface) {
console.log(error);
}
});
*/
}
function runMethod(method) {
return function() {
var transaction = {}
@ -539,6 +539,7 @@ function Contract(web3, wallet, contractAddress, contractInterface) {
}
}
var call = contractInterface[method].apply(contractInterface, params);
switch (call.type) {
case 'call':
@ -554,7 +555,7 @@ function Contract(web3, wallet, contractAddress, contractInterface) {
transaction.to = contractAddress;
return new Promise(function(resolve, reject) {
getWeb3Promise('call', transaction).then(function(value) {
provider.client.sendMessage('eth_call', [transaction]).then(function(value) {
resolve(call.parse(value));
}, function(error) {
reject(error);
@ -575,8 +576,8 @@ function Contract(web3, wallet, contractAddress, contractInterface) {
return new Promise(function(resolve, reject) {
Promise.all([
getWeb3Promise('getTransactionCount', wallet.address, 'pending'),
getWeb3Promise('getGasPrice'),
provider.client.sendMessage('getTransactionCount', [wallet.address, 'pending']),
provider.client.sendMessage('getGasPrice', []),
]).then(function(results) {
if (transaction.nonce == null) {
transaction.nonce = results[0];
@ -588,16 +589,9 @@ function Contract(web3, wallet, contractAddress, contractInterface) {
} else if (console.warn) {
console.warn('Overriding suggested gasPrice: ' + utils.hexlify(results[1]));
}
var signedTransaction = wallet.sign(transaction);
/*
data: call.data,
gasLimit: 3000000,
gasPrice: results[1],
nonce: results[0],
to: contractAddress,
});
*/
getWeb3Promise('sendRawTransaction', signedTransaction).then(function(txid) {
provider.client.sendMessage('sendRawTransaction', [signedTransaction]).then(function(txid) {
resolve(txid);
}, function(error) {
reject(error);
@ -619,13 +613,13 @@ function Contract(web3, wallet, contractAddress, contractInterface) {
Object.defineProperty(self, 'on' + call.name.toLowerCase(), {
enumerable: true,
get: function() {
console.log('get');
//console.log('get');
var info = filters[call.name];
if (!info || !info[call.name]) { return null; }
return info.callback;
},
set: function(value) {
console.log('set');
//console.log('set');
setupFilter(call, value);
}
});

102
lib/provider.js Normal file

@ -0,0 +1,102 @@
'use strict';
var utils = require('./utils.js');
var XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest;
function Web3Connector(provider) {
if (!(this instanceof Web3Connector)) { throw new Error('missing new'); }
var nextMessageId = 1;
utils.defineProperty(this, 'sendMessage', function(method, params) {
//console.log('mm', method, params);
return new Promise(function(resolve, reject) {
provider.sendAsync({
id: (nextMessageId++),
jsonrpc: '2.0',
method: method,
params: params
}, function(error, result) {
console.log(error, result);
if (error) {
reject(error);
} else {
if (result.code) {
var error = new Error(result.message);
error.code = result.code;
error.data = result.data;
reject(error);
} else {
resolve(result.result);
}
}
});
});
});
}
function rpcSendAsync(url) {
return {
sendAsync: function(payload, callback) {
var request = new XMLHttpRequest();
request.open('POST', url, true);
request.setRequestHeader('Content-Type','application/json');
request.onreadystatechange = function() {
if (request.readyState !== 4) { return; }
if (typeof(callback) !== 'function') { return; }
var result = request.responseText;
try {
callback(null, JSON.parse(result));
} catch (error) {
callback(new Error('invalid response'));
}
};
try {
request.send(JSON.stringify(payload));
} catch (error) {
var connectionError = new Error('connection error');
connectionError.error = error;
callback(connectionError);
}
}
}
}
function Provider(provider) {
if (!(this instanceof Provider)) { throw new Error('missing new'); }
var client = null;
if (typeof(provider) === 'string') {
// An RPC URL
if (provider.substring(0, 7) === 'http://') {
client = new Web3Connector(rpcSendAsync(provider));
// An ethers.io URL
} else if (provider.substring(0, 5) === 'ws://' || provider.substirng(0, 6) === 'wss://') {
//client =
}
// A Web3 Instance
} else if (provider.currentProvider && provider.currentProvider.sendAsync) {
client = new Web3Connector(provider.currentProvider);
// A Web3 Provider
} else if (provider.sendAsync) {
client = new Web3Connector(provider);
}
if (!client) { throw new Error('invalid connector'); }
utils.defineProperty(this, 'client', client);
}
module.exports = Provider;

@ -3,6 +3,7 @@
var rlp = require('rlp');
var Contract = require('./contract.js');
var Provider = require('./provider.js');
var SigningKey = require('./signing-key.js');
var utils = require('./utils.js');
@ -17,7 +18,7 @@ var transactionFields = [
{name: 'data'},
];
function Wallet(privateKey) {
function Wallet(privateKey, provider) {
if (!(this instanceof Wallet)) { throw new Error('missing new'); }
// Make sure we have a valid signing key
@ -27,6 +28,10 @@ function Wallet(privateKey) {
}
utils.defineProperty(this, 'privateKey', signingKey.privateKey);
if (provider) {
utils.defineProperty(this, 'provider', new Provider(provider));
}
utils.defineProperty(this, 'address', signingKey.address);
utils.defineProperty(this, 'sign', function(transaction) {
@ -71,14 +76,15 @@ function Wallet(privateKey) {
});
}
utils.defineProperty(Wallet.prototype, 'getContract', function(address, abi) {
return new Contract(this.provider, this, address, new Contract.Interface(abi));
});
utils.defineProperty(Wallet, 'getAddress', SigningKey.getAddress);
utils.defineProperty(Wallet, 'getIcapAddress', SigningKey.getIcapAddress);
utils.defineProperty(Wallet, '_Contract', Contract);
utils.defineProperty(Wallet.prototype, 'getContract', function(address, abi, web3) {
return new Contract(web3, this, address, new Contract.Interface(abi));
});
module.exports = Wallet;

@ -4,16 +4,21 @@
"description": "Ethereum wallet library.",
"main": "index.js",
"scripts": {
"test": "./node_modules/.bin/nodeunit test.js",
"test": "./node_modules/.bin/nodeunit tests/index.js",
"version": "grunt dist"
},
"dependencies": {
"aes-js": "0.2.4",
"elliptic": "6.3.1",
"pbkdf2": "3.0.4",
"randombytes": "2.0.3",
"rlp": "2.0.0",
"scrypt-js": "2.0.0",
"uuid": "2.0.1"
"uuid": "2.0.1",
"xmlhttprequest": "1.8.0"
},
"browser": {
"xmlhttprequest": "./lib/browser/browser-xmlhttprequest.js"
},
"devDependencies": {
"ethereumjs-abi": "0.6.2",