Added Web3Provider.

This commit is contained in:
Richard Moore 2018-01-16 18:55:56 -05:00
parent eddf93b200
commit 67bb0b7f93
No known key found for this signature in database
GPG Key ID: 525F70A6FCABC295
5 changed files with 180 additions and 2 deletions

@ -6,6 +6,7 @@ var EtherscanProvider = require('./etherscan-provider.js');
var FallbackProvider = require('./fallback-provider.js'); var FallbackProvider = require('./fallback-provider.js');
var InfuraProvider = require('./infura-provider.js'); var InfuraProvider = require('./infura-provider.js');
var JsonRpcProvider = require('./json-rpc-provider.js'); var JsonRpcProvider = require('./json-rpc-provider.js');
var Web3Provider = require('./web3-provider.js');
function getDefaultProvider(network) { function getDefaultProvider(network) {
return new FallbackProvider([ return new FallbackProvider([
@ -19,6 +20,7 @@ module.exports = {
FallbackProvider: FallbackProvider, FallbackProvider: FallbackProvider,
InfuraProvider: InfuraProvider, InfuraProvider: InfuraProvider,
JsonRpcProvider: JsonRpcProvider, JsonRpcProvider: JsonRpcProvider,
Web3Provider: Web3Provider,
isProvider: Provider.isProvider, isProvider: Provider.isProvider,

@ -54,6 +54,12 @@ function getTransaction(transaction) {
result[key] = stripHexZeros(result[key]); result[key] = stripHexZeros(result[key]);
}); });
// Transform "gasLimit" to "gas"
if (result.gasLimit != null && result.gas == null) {
result.gas = result.gasLimit;
delete result.gasLimit;
}
return result; return result;
} }
@ -208,4 +214,8 @@ utils.defineProperty(JsonRpcProvider.prototype, '_stopPending', function() {
this._pendingFilter = null; this._pendingFilter = null;
}); });
utils.defineProperty(JsonRpcProvider, '_hexlifyTransaction', function(transaction) {
return getTransaction(transaction);
});
module.exports = JsonRpcProvider; module.exports = JsonRpcProvider;

@ -1,6 +1,6 @@
{ {
"name": "ethers-providers", "name": "ethers-providers",
"version": "2.1.16", "version": "2.1.17",
"description": "Service provider for Ethereum wallet library.", "description": "Service provider for Ethereum wallet library.",
"bugs": { "bugs": {
"url": "http://github.com/ethers-io/ethers.js/issues", "url": "http://github.com/ethers-io/ethers.js/issues",

159
providers/web3-provider.js Normal file

@ -0,0 +1,159 @@
'use strict';
var utils = require('ethers-utils');
var Provider = require('./provider');
var JsonRpcProvider = require('./json-rpc-provider');
function Web3Signer(provider, address) {
if (!(this instanceof Web3Signer)) { throw new Error('missing new'); }
utils.defineProperty(this, 'provider', provider);
// Statically attach to a given address
if (address) {
utils.defineProperty(this, 'address', address);
utils.defineProperty(this, '_syncAddress', true);
} else {
Object.defineProperty(this, 'address', {
enumerable: true,
get: function() {
throw new Error('unsupported sync operation; use getAddress');
},
writable: false
});
utils.defineProperty(this, '_syncAddress', false);
}
}
utils.defineProperty(Web3Signer.prototype, 'getAddress', function() {
if (this._syncAddress) { return Promise.resolve(this.address); }
return this.provider.send('eth_accounts', []).then(function(accounts) {
if (accounts.length === 0) {
throw new Error('no account');
}
return utils.getAddress(accounts[0]);
});
});
utils.defineProperty(Web3Signer.prototype, 'getBalance', function(blockTag) {
var provider = this.provider;
return this.getAddress().then(function(address) {
return provider.getBalance(address, blockTag);
});
});
utils.defineProperty(Web3Signer.prototype, 'getTransactionCount', function(blockTag) {
var provider = this.provider;
return this.getAddress().then(function(address) {
return provider.getTransactionCount(address, blockTag);
});
});
utils.defineProperty(Web3Signer.prototype, 'sendTransaction', function(transaction) {
var provider = this.provider;
transaction = JsonRpcProvider._hexlifyTransaction(transaction);
return this.getAddress().then(function(address) {
transaction.from = address;
return provider.send('eth_sendTransaction', [ transaction ]).then(function(hash) {
return new Promise(function(resolve, reject) {
function check() {
provider.getTransaction(hash).then(function(transaction) {
if (!transaction) {
setTimeout(check, 1000);
return;
}
resolve(transaction);
});
}
check();
});
});
});
});
utils.defineProperty(Web3Signer.prototype, 'signMessage', function(message) {
var provider = this.provider;
var data = ((typeof(message) === 'string') ? utils.toUtf8Bytes(message): message);
return this.getAddress().then(function(address) {
return provider.send('eth_sign', [ address, utils.hexlify(data) ]);
});
});
utils.defineProperty(Web3Signer.prototype, 'unlock', function(password) {
var provider = this.provider;
return this.getAddress().then(function(address) {
return provider.send('personal_unlockAccount', [ address, password, null ]);
});
});
/*
@TODO
utils.defineProperty(Web3Signer, 'onchange', {
});
*/
function Web3Provider(web3Provider, network) {
if (!(this instanceof Web3Provider)) { throw new Error('missing new'); }
// HTTP has a host; IPC has a path.
var url = web3Provider.host || web3Provider.path || 'unknown';
// No need to support legacy parameters since this is post-legacy network
if (network == null) {
network = Provider.networks.homestead;
} else if (typeof(network) === 'string') {
network = Provider.networks[network];
if (!network) { throw new Error('invalid network'); }
}
JsonRpcProvider.call(this, url, network);
utils.defineProperty(this, '_web3Provider', web3Provider);
}
JsonRpcProvider.inherits(Web3Provider);
utils.defineProperty(Web3Provider.prototype, 'getSigner', function(address) {
return new Web3Signer(this, address);
});
utils.defineProperty(Web3Provider.prototype, 'listAccounts', function() {
return this.send('eth_accounts', []).then(function(accounts) {
accounts.forEach(function(address, index) {
accounts[index] = utils.getAddress(address);
});
return accounts;
});
});
utils.defineProperty(Web3Provider.prototype, 'send', function(method, params) {
var provider = this._web3Provider;
return new Promise(function(resolve, reject) {
var request = {
method: method,
params: params,
id: 42,
jsonrpc: "2.0"
};
provider.sendAsync(request, function(error, result) {
if (error) {
reject(error);
return;
}
if (result.error) {
var error = new Error(result.error.message);
error.code = result.error.code;
error.data = result.error.data;
reject(error);
return;
}
resolve(result.result);
});
});
});
module.exports = Web3Provider;

@ -1,6 +1,7 @@
'use strict'; 'use strict';
var assert = require('assert'); var assert = require('assert');
var web3 = require('web3');
var providers = require('../providers'); var providers = require('../providers');
@ -258,12 +259,18 @@ function testProvider(providerName, networkName) {
if (networkName === 'default') { if (networkName === 'default') {
if (providerName === 'getDefaultProvider') { if (providerName === 'getDefaultProvider') {
provider = providers.getDefaultProvider(); provider = providers.getDefaultProvider();
} else if (providerName === 'Web3Provider') {
var infuraUrl = (new providers.InfuraProvider()).url;
provider = new providers.Web3Provider(new web3.providers.HttpProvider(infuraUrl));
} else { } else {
provider = new providers[providerName](); provider = new providers[providerName]();
} }
} else { } else {
if (providerName === 'getDefaultProvider') { if (providerName === 'getDefaultProvider') {
provider = providers.getDefaultProvider(networkName); provider = providers.getDefaultProvider(networkName);
} else if (providerName === 'Web3Provider') {
var infuraUrl = (new providers.InfuraProvider(networkName)).url;
provider = new providers.Web3Provider(new web3.providers.HttpProvider(infuraUrl), networkName);
} else { } else {
provider = new providers[providerName](networkName); provider = new providers[providerName](networkName);
} }
@ -354,7 +361,7 @@ function testProvider(providerName, networkName) {
} }
['default', 'homestead', 'ropsten', 'rinkeby', 'kovan'].forEach(function(networkName) { ['default', 'homestead', 'ropsten', 'rinkeby', 'kovan'].forEach(function(networkName) {
['getDefaultProvider', 'InfuraProvider', 'EtherscanProvider'].forEach(function(providerName) { ['getDefaultProvider', 'InfuraProvider', 'EtherscanProvider', 'Web3Provider'].forEach(function(providerName) {
// HACK! Etherscan is being cloudflare heavy right now and I need // HACK! Etherscan is being cloudflare heavy right now and I need
// to release a new version; temporarily turning off these tests // to release a new version; temporarily turning off these tests