Updated dist files.
This commit is contained in:
parent
de8a717b4c
commit
a3821f6c4b
@ -12,7 +12,7 @@ const Words = fs.readFileSync("/usr/share/dict/words").toString().split("\n").re
|
|||||||
// Words missing from the dictionary
|
// Words missing from the dictionary
|
||||||
accessing addresses aligned autofill called cancelled changed censored
|
accessing addresses aligned autofill called cancelled changed censored
|
||||||
clamping compiled computed configured consumed creating decoded decoding
|
clamping compiled computed configured consumed creating decoded decoding
|
||||||
decrypt decrypted decrypting deployed deploying deprecated detected
|
decreased decrypt decrypted decrypting deployed deploying deprecated detected
|
||||||
discontinued earliest email enabled encoded encoding encrypt
|
discontinued earliest email enabled encoded encoding encrypt
|
||||||
encrypted encrypting entries euro exceeded existing expected
|
encrypted encrypting entries euro exceeded existing expected
|
||||||
expired failed fetches formatted formatting funding generated
|
expired failed fetches formatted formatting funding generated
|
||||||
@ -47,9 +47,9 @@ bytecode callback calldata checksum ciphertext cli codepoint commify config
|
|||||||
contenthash ctr ctrl debug dd dklen eexist encseed eof ethaddr
|
contenthash ctr ctrl debug dd dklen eexist encseed eof ethaddr
|
||||||
ethseed ethers eval exec filename func gz hid http https hw iv
|
ethseed ethers eval exec filename func gz hid http https hw iv
|
||||||
info init ipc json kdf kdfparams labelhash lang lib mm multihash nfc
|
info init ipc json kdf kdfparams labelhash lang lib mm multihash nfc
|
||||||
nfkc nfd nfkd nodehash notok nullish oob opcode pbkdf pc plugin pragma pre prf
|
nfkc nfd nfkd nodehash notok nowait nullish oob opcode pbkdf pc plugin
|
||||||
repl rpc sighash topichash solc stdin stdout subclasses subnode
|
pragma pre prf repl rpc sighash topichash solc stdin stdout subclasses
|
||||||
timeout todo txt ufixed utc utf util url uuid vm vs websocket
|
subnode timeout todo txt ufixed utc utf util url uuid vm vs websocket
|
||||||
wikipedia wx xe xpriv xpub xx yyyy zlib
|
wikipedia wx xe xpriv xpub xx yyyy zlib
|
||||||
|
|
||||||
// AbiV2
|
// AbiV2
|
||||||
|
@ -65,7 +65,7 @@ const blockchainData = {
|
|||||||
s: "0x269c3e5b3558267ad91b0a887d51f9f10098771c67b82ea6cb74f29638754f54",
|
s: "0x269c3e5b3558267ad91b0a887d51f9f10098771c67b82ea6cb74f29638754f54",
|
||||||
v: 38,
|
v: 38,
|
||||||
creates: null,
|
creates: null,
|
||||||
raw: "0xf8d2808504a817c8008303d090946fc21092da55b392b045ed78f4732bff3c580e2c880186cc6acd4b0000b864f2c298be000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000067269636d6f6f000000000000000000000000000000000000000000000000000026a01e5605197a03e3f0a168f14749168dfeefc44c9228312dacbffdcbbb13263265a0269c3e5b3558267ad91b0a887d51f9f10098771c67b82ea6cb74f29638754f54",
|
//raw: "0xf8d2808504a817c8008303d090946fc21092da55b392b045ed78f4732bff3c580e2c880186cc6acd4b0000b864f2c298be000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000067269636d6f6f000000000000000000000000000000000000000000000000000026a01e5605197a03e3f0a168f14749168dfeefc44c9228312dacbffdcbbb13263265a0269c3e5b3558267ad91b0a887d51f9f10098771c67b82ea6cb74f29638754f54",
|
||||||
chainId: 1
|
chainId: 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -364,6 +364,8 @@ function equals(name, actual, expected) {
|
|||||||
if (actual == null) {
|
if (actual == null) {
|
||||||
assert.ok(false, name + " - actual big number null");
|
assert.ok(false, name + " - actual big number null");
|
||||||
}
|
}
|
||||||
|
expected = ethers.BigNumber.from(expected);
|
||||||
|
actual = ethers.BigNumber.from(actual);
|
||||||
assert.ok(expected.eq(actual), name + " matches");
|
assert.ok(expected.eq(actual), name + " matches");
|
||||||
}
|
}
|
||||||
else if (Array.isArray(expected)) {
|
else if (Array.isArray(expected)) {
|
||||||
@ -398,265 +400,315 @@ function equals(name, actual, expected) {
|
|||||||
}
|
}
|
||||||
function waiter(duration) {
|
function waiter(duration) {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
setTimeout(resolve, duration);
|
const timer = setTimeout(resolve, duration);
|
||||||
|
if (timer.unref) {
|
||||||
|
timer.unref();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function testProvider(providerName, networkName) {
|
const allNetworks = ["default", "homestead", "ropsten", "rinkeby", "kovan", "goerli"];
|
||||||
// Delay (ms) after each test case to prevent the backends from throttling
|
const providerFunctions = [
|
||||||
const delay = 1000;
|
{
|
||||||
describe(("Read-Only " + providerName + " (" + networkName + ")"), function () {
|
name: "getDefaultProvider",
|
||||||
this.retries(3);
|
networks: allNetworks,
|
||||||
// Get the Provider based on the name of the provider we are testing and the network
|
create: (network) => {
|
||||||
let provider = null;
|
if (network == "default") {
|
||||||
if (networkName === "default") {
|
return ethers.getDefaultProvider();
|
||||||
if (providerName === "getDefaultProvider") {
|
|
||||||
provider = ethers.getDefaultProvider();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
provider = new (ethers.providers)[providerName]();
|
|
||||||
}
|
}
|
||||||
|
return ethers.getDefaultProvider(network);
|
||||||
}
|
}
|
||||||
else {
|
},
|
||||||
if (providerName === "getDefaultProvider") {
|
{
|
||||||
provider = ethers.getDefaultProvider(networkName);
|
name: "AlchemyProvider",
|
||||||
}
|
networks: allNetworks,
|
||||||
else {
|
create: (network) => {
|
||||||
provider = new (ethers.providers)[providerName](networkName);
|
if (network == "default") {
|
||||||
|
return new ethers.providers.AlchemyProvider();
|
||||||
}
|
}
|
||||||
|
return new ethers.providers.AlchemyProvider(network);
|
||||||
}
|
}
|
||||||
const tests = blockchainData[networkName];
|
},
|
||||||
// And address test case can have any of the following:
|
{
|
||||||
// - balance
|
name: "CloudflareProvider",
|
||||||
// - code
|
networks: ["homestead"],
|
||||||
// - storage
|
create: (network) => {
|
||||||
// - ENS name
|
return new ethers.providers.AlchemyProvider(network);
|
||||||
tests.addresses.forEach((test) => {
|
}
|
||||||
if (test.balance) {
|
},
|
||||||
it(`fetches address balance: ${test.address}`, function () {
|
{
|
||||||
// Note: These tests could be fiddled with if someone sends ether
|
name: "InfuraProvider",
|
||||||
// to our address; we just have to live with jerks sending us
|
networks: allNetworks,
|
||||||
// money. *smile emoji*
|
create: (network) => {
|
||||||
this.timeout(60000);
|
if (network == "default") {
|
||||||
return provider.getBalance(test.address).then((balance) => {
|
return new ethers.providers.InfuraProvider();
|
||||||
equals("Balance", test.balance, balance);
|
|
||||||
return waiter(delay);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
if (test.code) {
|
return new ethers.providers.InfuraProvider(network);
|
||||||
it(`fetches address code: ${test.address}`, function () {
|
}
|
||||||
this.timeout(60000);
|
},
|
||||||
return provider.getCode(test.address).then((code) => {
|
{
|
||||||
equals("Code", test.code, code);
|
name: "EtherscanProvider",
|
||||||
return waiter(delay);
|
networks: allNetworks,
|
||||||
});
|
create: (network) => {
|
||||||
});
|
if (network == "default") {
|
||||||
}
|
return new ethers.providers.EtherscanProvider();
|
||||||
if (test.storage) {
|
|
||||||
Object.keys(test.storage).forEach((position) => {
|
|
||||||
it(`fetches storage: ${test.address}:${position}`, function () {
|
|
||||||
this.timeout(60000);
|
|
||||||
return provider.getStorageAt(test.address, bnify(position)).then((value) => {
|
|
||||||
equals("Storage", test.storage[position], value);
|
|
||||||
return waiter(delay);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (test.name) {
|
|
||||||
it(`fetches the ENS name: ${test.name}`, function () {
|
|
||||||
this.timeout(60000);
|
|
||||||
return provider.resolveName(test.name).then((address) => {
|
|
||||||
equals("ENS Name", test.address, address);
|
|
||||||
return waiter(delay);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
return new ethers.providers.EtherscanProvider(network);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "NodesmithProvider",
|
||||||
|
networks: [],
|
||||||
|
create: (network) => {
|
||||||
|
throw new Error("not tested");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Web3Provider",
|
||||||
|
networks: [],
|
||||||
|
create: (network) => {
|
||||||
|
throw new Error("not tested");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
// This wallet can be funded and used for various test cases
|
||||||
|
const fundWallet = ethers.Wallet.createRandom();
|
||||||
|
const testFunctions = [];
|
||||||
|
Object.keys(blockchainData).forEach((network) => {
|
||||||
|
function addSimpleTest(name, func, expected) {
|
||||||
|
testFunctions.push({
|
||||||
|
name: name,
|
||||||
|
networks: [network],
|
||||||
|
execute: (provider) => __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const value = yield func(provider);
|
||||||
|
equals(name, expected, value);
|
||||||
|
})
|
||||||
});
|
});
|
||||||
tests.blocks.forEach((test) => {
|
}
|
||||||
function checkBlock(promise) {
|
function addObjectTest(name, func, expected, checkSkip) {
|
||||||
return promise.then((block) => {
|
testFunctions.push({
|
||||||
for (let key in test) {
|
name,
|
||||||
equals("Block " + key, block[key], test[key]);
|
networks: [network],
|
||||||
}
|
checkSkip,
|
||||||
return waiter(delay);
|
execute: (provider) => __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const value = yield func(provider);
|
||||||
|
Object.keys(expected).forEach((key) => {
|
||||||
|
equals(`${name}.${key}`, value[key], expected[key]);
|
||||||
});
|
});
|
||||||
}
|
})
|
||||||
it(`fetches block (by number) #${test.number}`, function () {
|
|
||||||
this.timeout(60000);
|
|
||||||
return checkBlock(provider.getBlock(test.number));
|
|
||||||
});
|
|
||||||
// Etherscan does not support getBlockByBlockhash... *sad emoji*
|
|
||||||
if (providerName === "EtherscanProvider") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
it(`fetches block (by hash) ${test.hash}`, function () {
|
|
||||||
this.timeout(60000);
|
|
||||||
return checkBlock(provider.getBlock(test.hash));
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
tests.transactions.forEach((test) => {
|
}
|
||||||
function testTransaction(expected) {
|
const tests = blockchainData[network];
|
||||||
const title = ("Transaction " + expected.hash.substring(0, 10) + " - ");
|
// And address test case can have any of the following:
|
||||||
return provider.getTransaction(expected.hash).then((tx) => {
|
// - balance
|
||||||
// This changes with every block
|
// - code
|
||||||
assert.equal(typeof (tx.confirmations), "number", "confirmations is a number");
|
// - storage
|
||||||
delete tx.confirmations;
|
// - ENS name
|
||||||
assert.equal(typeof (tx.wait), "function", "wait is a function");
|
tests.addresses.forEach((test) => {
|
||||||
delete tx.wait;
|
if (test.balance) {
|
||||||
for (const key in tx) {
|
addSimpleTest(`fetches account balance: ${test.address}`, (provider) => {
|
||||||
equals((title + key), tx[key], expected[key]);
|
return provider.getBalance(test.address);
|
||||||
}
|
}, test.balance);
|
||||||
return waiter(delay);
|
}
|
||||||
});
|
if (test.code) {
|
||||||
}
|
addSimpleTest(`fetches account code: ${test.address}`, (provider) => {
|
||||||
it(`fetches transaction: ${test.hash}`, function () {
|
return provider.getCode(test.address);
|
||||||
this.timeout(60000);
|
}, test.code);
|
||||||
return testTransaction(test);
|
}
|
||||||
});
|
if (test.storage) {
|
||||||
});
|
Object.keys(test.storage).forEach((position) => {
|
||||||
tests.transactionReceipts.forEach((test) => {
|
addSimpleTest(`fetches storage: ${test.address}:${position}`, (provider) => {
|
||||||
function testTransactionReceipt(expected) {
|
return provider.getStorageAt(test.address, bnify(position));
|
||||||
const title = ("Receipt " + expected.transactionHash.substring(0, 10) + " - ");
|
}, test.storage[position]);
|
||||||
return provider.getTransactionReceipt(expected.transactionHash).then(function (receipt) {
|
|
||||||
// This changes with every block; so just make sure it is a number
|
|
||||||
assert.equal(typeof (receipt.confirmations), "number", "confirmations is a number");
|
|
||||||
delete receipt.confirmations;
|
|
||||||
for (const key in receipt) {
|
|
||||||
equals((title + key), receipt[key], expected[key]);
|
|
||||||
}
|
|
||||||
//equals(("Receipt " + expected.transactionHash.substring(0, 10)), receipt, expected);
|
|
||||||
return waiter(delay);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
it(`fetches transaction receipt: ${test.transactionHash}`, function () {
|
|
||||||
this.timeout(60000);
|
|
||||||
return testTransactionReceipt(test);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
if (networkName === "ropsten") {
|
|
||||||
it("throws correct NONCE_EXPIRED errors", function () {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
this.timeout(60000);
|
|
||||||
try {
|
|
||||||
const tx = yield provider.sendTransaction("0xf86480850218711a0082520894000000000000000000000000000000000000000002801ba038aaddcaaae7d3fa066dfd6f196c8348e1bb210f2c121d36cb2c24ef20cea1fba008ae378075d3cd75aae99ab75a70da82161dffb2c8263dabc5d8adecfa9447fa");
|
|
||||||
console.log(tx);
|
|
||||||
assert.ok(false);
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
assert.equal(error.code, ethers.utils.Logger.errors.NONCE_EXPIRED);
|
|
||||||
}
|
|
||||||
yield waiter(delay);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it("throws correct INSUFFICIENT_FUNDS errors", function () {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
this.timeout(60000);
|
|
||||||
const txProps = {
|
|
||||||
to: "0x8ba1f109551bD432803012645Ac136ddd64DBA72",
|
|
||||||
gasPrice: 9000000000,
|
|
||||||
gasLimit: 21000,
|
|
||||||
value: 1
|
|
||||||
};
|
|
||||||
const wallet = ethers.Wallet.createRandom();
|
|
||||||
const tx = yield wallet.signTransaction(txProps);
|
|
||||||
try {
|
|
||||||
yield provider.sendTransaction(tx);
|
|
||||||
assert.ok(false);
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
assert.equal(error.code, ethers.utils.Logger.errors.INSUFFICIENT_FUNDS);
|
|
||||||
}
|
|
||||||
yield waiter(delay);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it("throws correct INSUFFICIENT_FUNDS errors (signer)", function () {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
this.timeout(60000);
|
|
||||||
const txProps = {
|
|
||||||
to: "0x8ba1f109551bD432803012645Ac136ddd64DBA72",
|
|
||||||
gasPrice: 9000000000,
|
|
||||||
gasLimit: 21000,
|
|
||||||
value: 1
|
|
||||||
};
|
|
||||||
const wallet = ethers.Wallet.createRandom().connect(provider);
|
|
||||||
try {
|
|
||||||
yield wallet.sendTransaction(txProps);
|
|
||||||
assert.ok(false);
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
assert.equal(error.code, ethers.utils.Logger.errors.INSUFFICIENT_FUNDS);
|
|
||||||
}
|
|
||||||
yield waiter(delay);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it("throws correct UNPREDICTABLE_GAS_LIMIT errors", function () {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
this.timeout(60000);
|
|
||||||
try {
|
|
||||||
yield provider.estimateGas({
|
|
||||||
to: "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e" // ENS; no payable fallback
|
|
||||||
});
|
|
||||||
assert.ok(false);
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
assert.equal(error.code, ethers.utils.Logger.errors.UNPREDICTABLE_GAS_LIMIT);
|
|
||||||
}
|
|
||||||
yield waiter(delay);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it("sends a transaction", function () {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
this.timeout(360000);
|
|
||||||
const wallet = ethers.Wallet.createRandom().connect(provider);
|
|
||||||
const funder = yield ethers.utils.fetchJson(`https:/\/api.ethers.io/api/v1/?action=fundAccount&address=${wallet.address.toLowerCase()}`);
|
|
||||||
yield provider.waitForTransaction(funder.hash);
|
|
||||||
const addr = "0x8210357f377E901f18E45294e86a2A32215Cc3C9";
|
|
||||||
const gasPrice = 9000000000;
|
|
||||||
let balance = yield provider.getBalance(wallet.address);
|
|
||||||
assert.ok(balance.eq(ethers.utils.parseEther("3.141592653589793238")), "balance is pi after funding");
|
|
||||||
const tx = yield wallet.sendTransaction({
|
|
||||||
to: addr,
|
|
||||||
gasPrice: gasPrice,
|
|
||||||
value: balance.sub(21000 * gasPrice)
|
|
||||||
});
|
|
||||||
yield tx.wait();
|
|
||||||
balance = yield provider.getBalance(wallet.address);
|
|
||||||
assert.ok(balance.eq(ethers.constants.Zero), "balance is zero after after sweeping");
|
|
||||||
yield waiter(delay);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// Obviously many more cases to add here
|
if (test.name) {
|
||||||
// - getTransactionCount
|
addSimpleTest(`fetches ENS name: ${test.address}`, (provider) => {
|
||||||
// - getBlockNumber
|
return provider.resolveName(test.name);
|
||||||
// - getGasPrice
|
}, test.address);
|
||||||
// - estimateGas
|
}
|
||||||
// - sendTransaction
|
|
||||||
// - call
|
|
||||||
// - getLogs
|
|
||||||
//
|
|
||||||
// Many of these are tLegacyParametersested in run-providers, which uses nodeunit, but
|
|
||||||
// also creates a local private key which must then be funded to
|
|
||||||
// execute the tests. I am working on a better test contract to deploy
|
|
||||||
// to all the networks to help test these.
|
|
||||||
});
|
});
|
||||||
}
|
tests.blocks.forEach((test) => {
|
||||||
["default", "homestead", "ropsten", "rinkeby", "kovan", "goerli"].forEach(function (networkName) {
|
addObjectTest(`fetches block (by number) #${test.number}`, (provider) => {
|
||||||
["getDefaultProvider", "AlchemyProvider", "CloudflareProvider", "InfuraProvider", "EtherscanProvider", "NodesmithProvider", "Web3Provider"].forEach(function (providerName) {
|
return provider.getBlock(test.number);
|
||||||
if (providerName === "NodesmithProvider") {
|
}, test);
|
||||||
return;
|
});
|
||||||
}
|
tests.blocks.forEach((test) => {
|
||||||
if (providerName === "CloudflareProvider") {
|
addObjectTest(`fetches block (by hash) ${test.hash}`, (provider) => {
|
||||||
return;
|
return provider.getBlock(test.hash);
|
||||||
}
|
}, test, (provider, network, test) => {
|
||||||
if (providerName === "Web3Provider") {
|
return (provider === "EtherscanProvider");
|
||||||
return;
|
});
|
||||||
}
|
});
|
||||||
if ((networkName !== "homestead" && networkName !== "default") && providerName === "CloudflareProvider") {
|
tests.transactions.forEach((test) => {
|
||||||
return;
|
addObjectTest(`fetches transaction ${test.hash}`, (provider) => __awaiter(void 0, void 0, void 0, function* () {
|
||||||
}
|
const tx = yield provider.getTransaction(test.hash);
|
||||||
testProvider(providerName, networkName);
|
// This changes with every block
|
||||||
|
assert.equal(typeof (tx.confirmations), "number", "confirmations is a number");
|
||||||
|
delete tx.confirmations;
|
||||||
|
assert.equal(typeof (tx.wait), "function", "wait is a function");
|
||||||
|
delete tx.wait;
|
||||||
|
return tx;
|
||||||
|
}), test, (provider, network, test) => {
|
||||||
|
return (provider === "EtherscanProvider");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
tests.transactionReceipts.forEach((test) => {
|
||||||
|
addObjectTest(`fetches transaction receipt ${test.transactionHash}`, (provider) => __awaiter(void 0, void 0, void 0, function* () {
|
||||||
|
const receipt = yield provider.getTransactionReceipt(test.transactionHash);
|
||||||
|
if (test.status === null) {
|
||||||
|
assert.ok(receipt.status === undefined, "no status");
|
||||||
|
receipt.status = null;
|
||||||
|
}
|
||||||
|
// This changes with every block; so just make sure it is a number
|
||||||
|
assert.equal(typeof (receipt.confirmations), "number", "confirmations is a number");
|
||||||
|
delete receipt.confirmations;
|
||||||
|
return receipt;
|
||||||
|
}), test);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
(function () {
|
||||||
|
function addErrorTest(code, func) {
|
||||||
|
testFunctions.push({
|
||||||
|
name: `throws correct ${code} error`,
|
||||||
|
networks: ["ropsten"],
|
||||||
|
execute: (provider) => __awaiter(this, void 0, void 0, function* () {
|
||||||
|
try {
|
||||||
|
const value = yield func(provider);
|
||||||
|
console.log(value);
|
||||||
|
assert.ok(false, "did not throw");
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
assert.equal(error.code, code, "incorrect error thrown");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
addErrorTest(ethers.utils.Logger.errors.NONCE_EXPIRED, (provider) => __awaiter(this, void 0, void 0, function* () {
|
||||||
|
return provider.sendTransaction("0xf86480850218711a0082520894000000000000000000000000000000000000000002801ba038aaddcaaae7d3fa066dfd6f196c8348e1bb210f2c121d36cb2c24ef20cea1fba008ae378075d3cd75aae99ab75a70da82161dffb2c8263dabc5d8adecfa9447fa");
|
||||||
|
}));
|
||||||
|
addErrorTest(ethers.utils.Logger.errors.INSUFFICIENT_FUNDS, (provider) => __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const txProps = {
|
||||||
|
to: "0x8ba1f109551bD432803012645Ac136ddd64DBA72",
|
||||||
|
gasPrice: 9000000000,
|
||||||
|
gasLimit: 21000,
|
||||||
|
value: 1
|
||||||
|
};
|
||||||
|
const wallet = ethers.Wallet.createRandom();
|
||||||
|
const tx = yield wallet.signTransaction(txProps);
|
||||||
|
return provider.sendTransaction(tx);
|
||||||
|
}));
|
||||||
|
addErrorTest(ethers.utils.Logger.errors.INSUFFICIENT_FUNDS, (provider) => __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const txProps = {
|
||||||
|
to: "0x8ba1f109551bD432803012645Ac136ddd64DBA72",
|
||||||
|
gasPrice: 9000000000,
|
||||||
|
gasLimit: 21000,
|
||||||
|
value: 1
|
||||||
|
};
|
||||||
|
const wallet = ethers.Wallet.createRandom().connect(provider);
|
||||||
|
return wallet.sendTransaction(txProps);
|
||||||
|
}));
|
||||||
|
addErrorTest(ethers.utils.Logger.errors.UNPREDICTABLE_GAS_LIMIT, (provider) => __awaiter(this, void 0, void 0, function* () {
|
||||||
|
return provider.estimateGas({
|
||||||
|
to: "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e" // ENS contract
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
})();
|
||||||
|
testFunctions.push({
|
||||||
|
name: "sends a transaction",
|
||||||
|
extras: ["funding"],
|
||||||
|
timeout: 300,
|
||||||
|
networks: ["ropsten"],
|
||||||
|
execute: (provider) => __awaiter(void 0, void 0, void 0, function* () {
|
||||||
|
const wallet = fundWallet.connect(provider);
|
||||||
|
const addr = "0x8210357f377E901f18E45294e86a2A32215Cc3C9";
|
||||||
|
const b0 = yield provider.getBalance(wallet.address);
|
||||||
|
assert.ok(b0.gt(ethers.constants.Zero), "balance is non-zero");
|
||||||
|
const tx = yield wallet.sendTransaction({
|
||||||
|
to: addr,
|
||||||
|
value: 123
|
||||||
|
});
|
||||||
|
yield tx.wait();
|
||||||
|
const b1 = yield provider.getBalance(wallet.address);
|
||||||
|
assert.ok(b0.gt(b1), "balance is decreased");
|
||||||
|
})
|
||||||
|
});
|
||||||
|
describe("Test Provider Methods", function () {
|
||||||
|
let fundReceipt = null;
|
||||||
|
const faucet = "0x8210357f377E901f18E45294e86a2A32215Cc3C9";
|
||||||
|
before(function () {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
// Get some ether from the faucet
|
||||||
|
const provider = ethers.getDefaultProvider("ropsten");
|
||||||
|
const funder = yield ethers.utils.fetchJson(`https:/\/api.ethers.io/api/v1/?action=fundAccount&address=${fundWallet.address.toLowerCase()}`);
|
||||||
|
fundReceipt = provider.waitForTransaction(funder.hash);
|
||||||
|
fundReceipt.then((receipt) => {
|
||||||
|
console.log(`*** Funded: ${fundWallet.address}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
after(function () {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
// Wait until the funding is complete
|
||||||
|
yield fundReceipt;
|
||||||
|
// Refund all unused ether to the faucet
|
||||||
|
const provider = ethers.getDefaultProvider("ropsten");
|
||||||
|
const gasPrice = yield provider.getGasPrice();
|
||||||
|
const balance = yield provider.getBalance(fundWallet.address);
|
||||||
|
fundWallet.connect(provider).sendTransaction({
|
||||||
|
to: faucet,
|
||||||
|
gasLimit: 21000,
|
||||||
|
gasPrice: gasPrice,
|
||||||
|
value: balance.sub(gasPrice.mul(21000))
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
providerFunctions.forEach(({ name, networks, create }) => {
|
||||||
|
networks.forEach((network) => {
|
||||||
|
const provider = create(network);
|
||||||
|
testFunctions.forEach((test) => {
|
||||||
|
// Skip tests not supported on this network
|
||||||
|
if (test.networks.indexOf(network) === -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (test.checkSkip && test.checkSkip(name, network, test)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// How many attempts to try?
|
||||||
|
const attempts = (test.attempts != null) ? test.attempts : 3;
|
||||||
|
const timeout = (test.timeout != null) ? test.timeout : 60;
|
||||||
|
const extras = (test.extras || []).reduce((accum, key) => {
|
||||||
|
accum[key] = true;
|
||||||
|
return accum;
|
||||||
|
}, {});
|
||||||
|
it(`${name}.${network ? network : "default"} ${test.name}`, function () {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
this.timeout(timeout * 1000 * attempts);
|
||||||
|
// Wait for the funding transaction to be mined
|
||||||
|
if (extras.funding) {
|
||||||
|
yield fundReceipt;
|
||||||
|
}
|
||||||
|
// We wait at least 1 seconds between tests
|
||||||
|
if (!extras.nowait) {
|
||||||
|
yield waiter(1000);
|
||||||
|
}
|
||||||
|
let error = null;
|
||||||
|
for (let attempt = 0; attempt < attempts; attempt++) {
|
||||||
|
try {
|
||||||
|
return yield Promise.race([
|
||||||
|
test.execute(provider),
|
||||||
|
waiter(timeout * 1000).then((resolve) => { throw new Error("timeout"); })
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
catch (attemptError) {
|
||||||
|
console.log(`*** Failed attempt ${attempt + 1}: ${attemptError.message}`);
|
||||||
|
error = attemptError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
/*
|
/*
|
||||||
@ -679,7 +731,7 @@ describe("Test extra Etherscan operations", function() {
|
|||||||
});
|
});
|
||||||
*/
|
*/
|
||||||
describe("Test Basic Authentication", function () {
|
describe("Test Basic Authentication", function () {
|
||||||
this.retries(3);
|
//this.retries(3);
|
||||||
function test(name, url) {
|
function test(name, url) {
|
||||||
it("tests " + name, function () {
|
it("tests " + name, function () {
|
||||||
this.timeout(60000);
|
this.timeout(60000);
|
||||||
|
File diff suppressed because one or more lines are too long
@ -96,7 +96,7 @@ var blockchainData = {
|
|||||||
s: "0x269c3e5b3558267ad91b0a887d51f9f10098771c67b82ea6cb74f29638754f54",
|
s: "0x269c3e5b3558267ad91b0a887d51f9f10098771c67b82ea6cb74f29638754f54",
|
||||||
v: 38,
|
v: 38,
|
||||||
creates: null,
|
creates: null,
|
||||||
raw: "0xf8d2808504a817c8008303d090946fc21092da55b392b045ed78f4732bff3c580e2c880186cc6acd4b0000b864f2c298be000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000067269636d6f6f000000000000000000000000000000000000000000000000000026a01e5605197a03e3f0a168f14749168dfeefc44c9228312dacbffdcbbb13263265a0269c3e5b3558267ad91b0a887d51f9f10098771c67b82ea6cb74f29638754f54",
|
//raw: "0xf8d2808504a817c8008303d090946fc21092da55b392b045ed78f4732bff3c580e2c880186cc6acd4b0000b864f2c298be000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000067269636d6f6f000000000000000000000000000000000000000000000000000026a01e5605197a03e3f0a168f14749168dfeefc44c9228312dacbffdcbbb13263265a0269c3e5b3558267ad91b0a887d51f9f10098771c67b82ea6cb74f29638754f54",
|
||||||
chainId: 1
|
chainId: 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -395,6 +395,8 @@ function equals(name, actual, expected) {
|
|||||||
if (actual == null) {
|
if (actual == null) {
|
||||||
assert_1.default.ok(false, name + " - actual big number null");
|
assert_1.default.ok(false, name + " - actual big number null");
|
||||||
}
|
}
|
||||||
|
expected = ethers_1.ethers.BigNumber.from(expected);
|
||||||
|
actual = ethers_1.ethers.BigNumber.from(actual);
|
||||||
assert_1.default.ok(expected.eq(actual), name + " matches");
|
assert_1.default.ok(expected.eq(actual), name + " matches");
|
||||||
}
|
}
|
||||||
else if (Array.isArray(expected)) {
|
else if (Array.isArray(expected)) {
|
||||||
@ -429,344 +431,429 @@ function equals(name, actual, expected) {
|
|||||||
}
|
}
|
||||||
function waiter(duration) {
|
function waiter(duration) {
|
||||||
return new Promise(function (resolve) {
|
return new Promise(function (resolve) {
|
||||||
setTimeout(resolve, duration);
|
var timer = setTimeout(resolve, duration);
|
||||||
|
if (timer.unref) {
|
||||||
|
timer.unref();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function testProvider(providerName, networkName) {
|
var allNetworks = ["default", "homestead", "ropsten", "rinkeby", "kovan", "goerli"];
|
||||||
// Delay (ms) after each test case to prevent the backends from throttling
|
var providerFunctions = [
|
||||||
var delay = 1000;
|
{
|
||||||
describe(("Read-Only " + providerName + " (" + networkName + ")"), function () {
|
name: "getDefaultProvider",
|
||||||
this.retries(3);
|
networks: allNetworks,
|
||||||
// Get the Provider based on the name of the provider we are testing and the network
|
create: function (network) {
|
||||||
var provider = null;
|
if (network == "default") {
|
||||||
if (networkName === "default") {
|
return ethers_1.ethers.getDefaultProvider();
|
||||||
if (providerName === "getDefaultProvider") {
|
|
||||||
provider = ethers_1.ethers.getDefaultProvider();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
provider = new (ethers_1.ethers.providers)[providerName]();
|
|
||||||
}
|
}
|
||||||
|
return ethers_1.ethers.getDefaultProvider(network);
|
||||||
}
|
}
|
||||||
else {
|
},
|
||||||
if (providerName === "getDefaultProvider") {
|
{
|
||||||
provider = ethers_1.ethers.getDefaultProvider(networkName);
|
name: "AlchemyProvider",
|
||||||
}
|
networks: allNetworks,
|
||||||
else {
|
create: function (network) {
|
||||||
provider = new (ethers_1.ethers.providers)[providerName](networkName);
|
if (network == "default") {
|
||||||
|
return new ethers_1.ethers.providers.AlchemyProvider();
|
||||||
}
|
}
|
||||||
|
return new ethers_1.ethers.providers.AlchemyProvider(network);
|
||||||
}
|
}
|
||||||
var tests = blockchainData[networkName];
|
},
|
||||||
// And address test case can have any of the following:
|
{
|
||||||
// - balance
|
name: "CloudflareProvider",
|
||||||
// - code
|
networks: ["homestead"],
|
||||||
// - storage
|
create: function (network) {
|
||||||
// - ENS name
|
return new ethers_1.ethers.providers.AlchemyProvider(network);
|
||||||
tests.addresses.forEach(function (test) {
|
}
|
||||||
if (test.balance) {
|
},
|
||||||
it("fetches address balance: " + test.address, function () {
|
{
|
||||||
// Note: These tests could be fiddled with if someone sends ether
|
name: "InfuraProvider",
|
||||||
// to our address; we just have to live with jerks sending us
|
networks: allNetworks,
|
||||||
// money. *smile emoji*
|
create: function (network) {
|
||||||
this.timeout(60000);
|
if (network == "default") {
|
||||||
return provider.getBalance(test.address).then(function (balance) {
|
return new ethers_1.ethers.providers.InfuraProvider();
|
||||||
equals("Balance", test.balance, balance);
|
|
||||||
return waiter(delay);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
if (test.code) {
|
return new ethers_1.ethers.providers.InfuraProvider(network);
|
||||||
it("fetches address code: " + test.address, function () {
|
}
|
||||||
this.timeout(60000);
|
},
|
||||||
return provider.getCode(test.address).then(function (code) {
|
{
|
||||||
equals("Code", test.code, code);
|
name: "EtherscanProvider",
|
||||||
return waiter(delay);
|
networks: allNetworks,
|
||||||
});
|
create: function (network) {
|
||||||
});
|
if (network == "default") {
|
||||||
|
return new ethers_1.ethers.providers.EtherscanProvider();
|
||||||
}
|
}
|
||||||
if (test.storage) {
|
return new ethers_1.ethers.providers.EtherscanProvider(network);
|
||||||
Object.keys(test.storage).forEach(function (position) {
|
}
|
||||||
it("fetches storage: " + test.address + ":" + position, function () {
|
},
|
||||||
this.timeout(60000);
|
{
|
||||||
return provider.getStorageAt(test.address, bnify(position)).then(function (value) {
|
name: "NodesmithProvider",
|
||||||
equals("Storage", test.storage[position], value);
|
networks: [],
|
||||||
return waiter(delay);
|
create: function (network) {
|
||||||
|
throw new Error("not tested");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Web3Provider",
|
||||||
|
networks: [],
|
||||||
|
create: function (network) {
|
||||||
|
throw new Error("not tested");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
// This wallet can be funded and used for various test cases
|
||||||
|
var fundWallet = ethers_1.ethers.Wallet.createRandom();
|
||||||
|
var testFunctions = [];
|
||||||
|
Object.keys(blockchainData).forEach(function (network) {
|
||||||
|
function addSimpleTest(name, func, expected) {
|
||||||
|
var _this = this;
|
||||||
|
testFunctions.push({
|
||||||
|
name: name,
|
||||||
|
networks: [network],
|
||||||
|
execute: function (provider) { return __awaiter(_this, void 0, void 0, function () {
|
||||||
|
var value;
|
||||||
|
return __generator(this, function (_a) {
|
||||||
|
switch (_a.label) {
|
||||||
|
case 0: return [4 /*yield*/, func(provider)];
|
||||||
|
case 1:
|
||||||
|
value = _a.sent();
|
||||||
|
equals(name, expected, value);
|
||||||
|
return [2 /*return*/];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}); }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function addObjectTest(name, func, expected, checkSkip) {
|
||||||
|
var _this = this;
|
||||||
|
testFunctions.push({
|
||||||
|
name: name,
|
||||||
|
networks: [network],
|
||||||
|
checkSkip: checkSkip,
|
||||||
|
execute: function (provider) { return __awaiter(_this, void 0, void 0, function () {
|
||||||
|
var value;
|
||||||
|
return __generator(this, function (_a) {
|
||||||
|
switch (_a.label) {
|
||||||
|
case 0: return [4 /*yield*/, func(provider)];
|
||||||
|
case 1:
|
||||||
|
value = _a.sent();
|
||||||
|
Object.keys(expected).forEach(function (key) {
|
||||||
|
equals(name + "." + key, value[key], expected[key]);
|
||||||
|
});
|
||||||
|
return [2 /*return*/];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}); }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
var tests = blockchainData[network];
|
||||||
|
// And address test case can have any of the following:
|
||||||
|
// - balance
|
||||||
|
// - code
|
||||||
|
// - storage
|
||||||
|
// - ENS name
|
||||||
|
tests.addresses.forEach(function (test) {
|
||||||
|
if (test.balance) {
|
||||||
|
addSimpleTest("fetches account balance: " + test.address, function (provider) {
|
||||||
|
return provider.getBalance(test.address);
|
||||||
|
}, test.balance);
|
||||||
|
}
|
||||||
|
if (test.code) {
|
||||||
|
addSimpleTest("fetches account code: " + test.address, function (provider) {
|
||||||
|
return provider.getCode(test.address);
|
||||||
|
}, test.code);
|
||||||
|
}
|
||||||
|
if (test.storage) {
|
||||||
|
Object.keys(test.storage).forEach(function (position) {
|
||||||
|
addSimpleTest("fetches storage: " + test.address + ":" + position, function (provider) {
|
||||||
|
return provider.getStorageAt(test.address, bnify(position));
|
||||||
|
}, test.storage[position]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (test.name) {
|
||||||
|
addSimpleTest("fetches ENS name: " + test.address, function (provider) {
|
||||||
|
return provider.resolveName(test.name);
|
||||||
|
}, test.address);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
tests.blocks.forEach(function (test) {
|
||||||
|
addObjectTest("fetches block (by number) #" + test.number, function (provider) {
|
||||||
|
return provider.getBlock(test.number);
|
||||||
|
}, test);
|
||||||
|
});
|
||||||
|
tests.blocks.forEach(function (test) {
|
||||||
|
addObjectTest("fetches block (by hash) " + test.hash, function (provider) {
|
||||||
|
return provider.getBlock(test.hash);
|
||||||
|
}, test, function (provider, network, test) {
|
||||||
|
return (provider === "EtherscanProvider");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
tests.transactions.forEach(function (test) {
|
||||||
|
addObjectTest("fetches transaction " + test.hash, function (provider) { return __awaiter(void 0, void 0, void 0, function () {
|
||||||
|
var tx;
|
||||||
|
return __generator(this, function (_a) {
|
||||||
|
switch (_a.label) {
|
||||||
|
case 0: return [4 /*yield*/, provider.getTransaction(test.hash)];
|
||||||
|
case 1:
|
||||||
|
tx = _a.sent();
|
||||||
|
// This changes with every block
|
||||||
|
assert_1.default.equal(typeof (tx.confirmations), "number", "confirmations is a number");
|
||||||
|
delete tx.confirmations;
|
||||||
|
assert_1.default.equal(typeof (tx.wait), "function", "wait is a function");
|
||||||
|
delete tx.wait;
|
||||||
|
return [2 /*return*/, tx];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}); }, test, function (provider, network, test) {
|
||||||
|
return (provider === "EtherscanProvider");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
tests.transactionReceipts.forEach(function (test) {
|
||||||
|
addObjectTest("fetches transaction receipt " + test.transactionHash, function (provider) { return __awaiter(void 0, void 0, void 0, function () {
|
||||||
|
var receipt;
|
||||||
|
return __generator(this, function (_a) {
|
||||||
|
switch (_a.label) {
|
||||||
|
case 0: return [4 /*yield*/, provider.getTransactionReceipt(test.transactionHash)];
|
||||||
|
case 1:
|
||||||
|
receipt = _a.sent();
|
||||||
|
if (test.status === null) {
|
||||||
|
assert_1.default.ok(receipt.status === undefined, "no status");
|
||||||
|
receipt.status = null;
|
||||||
|
}
|
||||||
|
// This changes with every block; so just make sure it is a number
|
||||||
|
assert_1.default.equal(typeof (receipt.confirmations), "number", "confirmations is a number");
|
||||||
|
delete receipt.confirmations;
|
||||||
|
return [2 /*return*/, receipt];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}); }, test);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
(function () {
|
||||||
|
var _this = this;
|
||||||
|
function addErrorTest(code, func) {
|
||||||
|
var _this = this;
|
||||||
|
testFunctions.push({
|
||||||
|
name: "throws correct " + code + " error",
|
||||||
|
networks: ["ropsten"],
|
||||||
|
execute: function (provider) { return __awaiter(_this, void 0, void 0, function () {
|
||||||
|
var value, error_1;
|
||||||
|
return __generator(this, function (_a) {
|
||||||
|
switch (_a.label) {
|
||||||
|
case 0:
|
||||||
|
_a.trys.push([0, 2, , 3]);
|
||||||
|
return [4 /*yield*/, func(provider)];
|
||||||
|
case 1:
|
||||||
|
value = _a.sent();
|
||||||
|
console.log(value);
|
||||||
|
assert_1.default.ok(false, "did not throw");
|
||||||
|
return [3 /*break*/, 3];
|
||||||
|
case 2:
|
||||||
|
error_1 = _a.sent();
|
||||||
|
assert_1.default.equal(error_1.code, code, "incorrect error thrown");
|
||||||
|
return [3 /*break*/, 3];
|
||||||
|
case 3: return [2 /*return*/];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}); }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
addErrorTest(ethers_1.ethers.utils.Logger.errors.NONCE_EXPIRED, function (provider) { return __awaiter(_this, void 0, void 0, function () {
|
||||||
|
return __generator(this, function (_a) {
|
||||||
|
return [2 /*return*/, provider.sendTransaction("0xf86480850218711a0082520894000000000000000000000000000000000000000002801ba038aaddcaaae7d3fa066dfd6f196c8348e1bb210f2c121d36cb2c24ef20cea1fba008ae378075d3cd75aae99ab75a70da82161dffb2c8263dabc5d8adecfa9447fa")];
|
||||||
|
});
|
||||||
|
}); });
|
||||||
|
addErrorTest(ethers_1.ethers.utils.Logger.errors.INSUFFICIENT_FUNDS, function (provider) { return __awaiter(_this, void 0, void 0, function () {
|
||||||
|
var txProps, wallet, tx;
|
||||||
|
return __generator(this, function (_a) {
|
||||||
|
switch (_a.label) {
|
||||||
|
case 0:
|
||||||
|
txProps = {
|
||||||
|
to: "0x8ba1f109551bD432803012645Ac136ddd64DBA72",
|
||||||
|
gasPrice: 9000000000,
|
||||||
|
gasLimit: 21000,
|
||||||
|
value: 1
|
||||||
|
};
|
||||||
|
wallet = ethers_1.ethers.Wallet.createRandom();
|
||||||
|
return [4 /*yield*/, wallet.signTransaction(txProps)];
|
||||||
|
case 1:
|
||||||
|
tx = _a.sent();
|
||||||
|
return [2 /*return*/, provider.sendTransaction(tx)];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}); });
|
||||||
|
addErrorTest(ethers_1.ethers.utils.Logger.errors.INSUFFICIENT_FUNDS, function (provider) { return __awaiter(_this, void 0, void 0, function () {
|
||||||
|
var txProps, wallet;
|
||||||
|
return __generator(this, function (_a) {
|
||||||
|
txProps = {
|
||||||
|
to: "0x8ba1f109551bD432803012645Ac136ddd64DBA72",
|
||||||
|
gasPrice: 9000000000,
|
||||||
|
gasLimit: 21000,
|
||||||
|
value: 1
|
||||||
|
};
|
||||||
|
wallet = ethers_1.ethers.Wallet.createRandom().connect(provider);
|
||||||
|
return [2 /*return*/, wallet.sendTransaction(txProps)];
|
||||||
|
});
|
||||||
|
}); });
|
||||||
|
addErrorTest(ethers_1.ethers.utils.Logger.errors.UNPREDICTABLE_GAS_LIMIT, function (provider) { return __awaiter(_this, void 0, void 0, function () {
|
||||||
|
return __generator(this, function (_a) {
|
||||||
|
return [2 /*return*/, provider.estimateGas({
|
||||||
|
to: "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e" // ENS contract
|
||||||
|
})];
|
||||||
|
});
|
||||||
|
}); });
|
||||||
|
})();
|
||||||
|
testFunctions.push({
|
||||||
|
name: "sends a transaction",
|
||||||
|
extras: ["funding"],
|
||||||
|
timeout: 300,
|
||||||
|
networks: ["ropsten"],
|
||||||
|
execute: function (provider) { return __awaiter(void 0, void 0, void 0, function () {
|
||||||
|
var wallet, addr, b0, tx, b1;
|
||||||
|
return __generator(this, function (_a) {
|
||||||
|
switch (_a.label) {
|
||||||
|
case 0:
|
||||||
|
wallet = fundWallet.connect(provider);
|
||||||
|
addr = "0x8210357f377E901f18E45294e86a2A32215Cc3C9";
|
||||||
|
return [4 /*yield*/, provider.getBalance(wallet.address)];
|
||||||
|
case 1:
|
||||||
|
b0 = _a.sent();
|
||||||
|
assert_1.default.ok(b0.gt(ethers_1.ethers.constants.Zero), "balance is non-zero");
|
||||||
|
return [4 /*yield*/, wallet.sendTransaction({
|
||||||
|
to: addr,
|
||||||
|
value: 123
|
||||||
|
})];
|
||||||
|
case 2:
|
||||||
|
tx = _a.sent();
|
||||||
|
return [4 /*yield*/, tx.wait()];
|
||||||
|
case 3:
|
||||||
|
_a.sent();
|
||||||
|
return [4 /*yield*/, provider.getBalance(wallet.address)];
|
||||||
|
case 4:
|
||||||
|
b1 = _a.sent();
|
||||||
|
assert_1.default.ok(b0.gt(b1), "balance is decreased");
|
||||||
|
return [2 /*return*/];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}); }
|
||||||
|
});
|
||||||
|
describe("Test Provider Methods", function () {
|
||||||
|
var fundReceipt = null;
|
||||||
|
var faucet = "0x8210357f377E901f18E45294e86a2A32215Cc3C9";
|
||||||
|
before(function () {
|
||||||
|
return __awaiter(this, void 0, void 0, function () {
|
||||||
|
var provider, funder;
|
||||||
|
return __generator(this, function (_a) {
|
||||||
|
switch (_a.label) {
|
||||||
|
case 0:
|
||||||
|
provider = ethers_1.ethers.getDefaultProvider("ropsten");
|
||||||
|
return [4 /*yield*/, ethers_1.ethers.utils.fetchJson("https://api.ethers.io/api/v1/?action=fundAccount&address=" + fundWallet.address.toLowerCase())];
|
||||||
|
case 1:
|
||||||
|
funder = _a.sent();
|
||||||
|
fundReceipt = provider.waitForTransaction(funder.hash);
|
||||||
|
fundReceipt.then(function (receipt) {
|
||||||
|
console.log("*** Funded: " + fundWallet.address);
|
||||||
|
});
|
||||||
|
return [2 /*return*/];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
after(function () {
|
||||||
|
return __awaiter(this, void 0, void 0, function () {
|
||||||
|
var provider, gasPrice, balance;
|
||||||
|
return __generator(this, function (_a) {
|
||||||
|
switch (_a.label) {
|
||||||
|
case 0:
|
||||||
|
// Wait until the funding is complete
|
||||||
|
return [4 /*yield*/, fundReceipt];
|
||||||
|
case 1:
|
||||||
|
// Wait until the funding is complete
|
||||||
|
_a.sent();
|
||||||
|
provider = ethers_1.ethers.getDefaultProvider("ropsten");
|
||||||
|
return [4 /*yield*/, provider.getGasPrice()];
|
||||||
|
case 2:
|
||||||
|
gasPrice = _a.sent();
|
||||||
|
return [4 /*yield*/, provider.getBalance(fundWallet.address)];
|
||||||
|
case 3:
|
||||||
|
balance = _a.sent();
|
||||||
|
fundWallet.connect(provider).sendTransaction({
|
||||||
|
to: faucet,
|
||||||
|
gasLimit: 21000,
|
||||||
|
gasPrice: gasPrice,
|
||||||
|
value: balance.sub(gasPrice.mul(21000))
|
||||||
|
});
|
||||||
|
return [2 /*return*/];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
providerFunctions.forEach(function (_a) {
|
||||||
|
var name = _a.name, networks = _a.networks, create = _a.create;
|
||||||
|
networks.forEach(function (network) {
|
||||||
|
var provider = create(network);
|
||||||
|
testFunctions.forEach(function (test) {
|
||||||
|
// Skip tests not supported on this network
|
||||||
|
if (test.networks.indexOf(network) === -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (test.checkSkip && test.checkSkip(name, network, test)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// How many attempts to try?
|
||||||
|
var attempts = (test.attempts != null) ? test.attempts : 3;
|
||||||
|
var timeout = (test.timeout != null) ? test.timeout : 60;
|
||||||
|
var extras = (test.extras || []).reduce(function (accum, key) {
|
||||||
|
accum[key] = true;
|
||||||
|
return accum;
|
||||||
|
}, {});
|
||||||
|
it(name + "." + (network ? network : "default") + " " + test.name, function () {
|
||||||
|
return __awaiter(this, void 0, void 0, function () {
|
||||||
|
var error, attempt, attemptError_1;
|
||||||
|
return __generator(this, function (_a) {
|
||||||
|
switch (_a.label) {
|
||||||
|
case 0:
|
||||||
|
this.timeout(timeout * 1000 * attempts);
|
||||||
|
if (!extras.funding) return [3 /*break*/, 2];
|
||||||
|
return [4 /*yield*/, fundReceipt];
|
||||||
|
case 1:
|
||||||
|
_a.sent();
|
||||||
|
_a.label = 2;
|
||||||
|
case 2:
|
||||||
|
if (!!extras.nowait) return [3 /*break*/, 4];
|
||||||
|
return [4 /*yield*/, waiter(1000)];
|
||||||
|
case 3:
|
||||||
|
_a.sent();
|
||||||
|
_a.label = 4;
|
||||||
|
case 4:
|
||||||
|
error = null;
|
||||||
|
attempt = 0;
|
||||||
|
_a.label = 5;
|
||||||
|
case 5:
|
||||||
|
if (!(attempt < attempts)) return [3 /*break*/, 10];
|
||||||
|
_a.label = 6;
|
||||||
|
case 6:
|
||||||
|
_a.trys.push([6, 8, , 9]);
|
||||||
|
return [4 /*yield*/, Promise.race([
|
||||||
|
test.execute(provider),
|
||||||
|
waiter(timeout * 1000).then(function (resolve) { throw new Error("timeout"); })
|
||||||
|
])];
|
||||||
|
case 7: return [2 /*return*/, _a.sent()];
|
||||||
|
case 8:
|
||||||
|
attemptError_1 = _a.sent();
|
||||||
|
console.log("*** Failed attempt " + (attempt + 1) + ": " + attemptError_1.message);
|
||||||
|
error = attemptError_1;
|
||||||
|
return [3 /*break*/, 9];
|
||||||
|
case 9:
|
||||||
|
attempt++;
|
||||||
|
return [3 /*break*/, 5];
|
||||||
|
case 10: throw error;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
if (test.name) {
|
|
||||||
it("fetches the ENS name: " + test.name, function () {
|
|
||||||
this.timeout(60000);
|
|
||||||
return provider.resolveName(test.name).then(function (address) {
|
|
||||||
equals("ENS Name", test.address, address);
|
|
||||||
return waiter(delay);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
tests.blocks.forEach(function (test) {
|
|
||||||
function checkBlock(promise) {
|
|
||||||
return promise.then(function (block) {
|
|
||||||
for (var key in test) {
|
|
||||||
equals("Block " + key, block[key], test[key]);
|
|
||||||
}
|
|
||||||
return waiter(delay);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
it("fetches block (by number) #" + test.number, function () {
|
|
||||||
this.timeout(60000);
|
|
||||||
return checkBlock(provider.getBlock(test.number));
|
|
||||||
});
|
|
||||||
// Etherscan does not support getBlockByBlockhash... *sad emoji*
|
|
||||||
if (providerName === "EtherscanProvider") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
it("fetches block (by hash) " + test.hash, function () {
|
|
||||||
this.timeout(60000);
|
|
||||||
return checkBlock(provider.getBlock(test.hash));
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
tests.transactions.forEach(function (test) {
|
|
||||||
function testTransaction(expected) {
|
|
||||||
var title = ("Transaction " + expected.hash.substring(0, 10) + " - ");
|
|
||||||
return provider.getTransaction(expected.hash).then(function (tx) {
|
|
||||||
// This changes with every block
|
|
||||||
assert_1.default.equal(typeof (tx.confirmations), "number", "confirmations is a number");
|
|
||||||
delete tx.confirmations;
|
|
||||||
assert_1.default.equal(typeof (tx.wait), "function", "wait is a function");
|
|
||||||
delete tx.wait;
|
|
||||||
for (var key in tx) {
|
|
||||||
equals((title + key), tx[key], expected[key]);
|
|
||||||
}
|
|
||||||
return waiter(delay);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
it("fetches transaction: " + test.hash, function () {
|
|
||||||
this.timeout(60000);
|
|
||||||
return testTransaction(test);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
tests.transactionReceipts.forEach(function (test) {
|
|
||||||
function testTransactionReceipt(expected) {
|
|
||||||
var title = ("Receipt " + expected.transactionHash.substring(0, 10) + " - ");
|
|
||||||
return provider.getTransactionReceipt(expected.transactionHash).then(function (receipt) {
|
|
||||||
// This changes with every block; so just make sure it is a number
|
|
||||||
assert_1.default.equal(typeof (receipt.confirmations), "number", "confirmations is a number");
|
|
||||||
delete receipt.confirmations;
|
|
||||||
for (var key in receipt) {
|
|
||||||
equals((title + key), receipt[key], expected[key]);
|
|
||||||
}
|
|
||||||
//equals(("Receipt " + expected.transactionHash.substring(0, 10)), receipt, expected);
|
|
||||||
return waiter(delay);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
it("fetches transaction receipt: " + test.transactionHash, function () {
|
|
||||||
this.timeout(60000);
|
|
||||||
return testTransactionReceipt(test);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
if (networkName === "ropsten") {
|
|
||||||
it("throws correct NONCE_EXPIRED errors", function () {
|
|
||||||
return __awaiter(this, void 0, void 0, function () {
|
|
||||||
var tx, error_1;
|
|
||||||
return __generator(this, function (_a) {
|
|
||||||
switch (_a.label) {
|
|
||||||
case 0:
|
|
||||||
this.timeout(60000);
|
|
||||||
_a.label = 1;
|
|
||||||
case 1:
|
|
||||||
_a.trys.push([1, 3, , 4]);
|
|
||||||
return [4 /*yield*/, provider.sendTransaction("0xf86480850218711a0082520894000000000000000000000000000000000000000002801ba038aaddcaaae7d3fa066dfd6f196c8348e1bb210f2c121d36cb2c24ef20cea1fba008ae378075d3cd75aae99ab75a70da82161dffb2c8263dabc5d8adecfa9447fa")];
|
|
||||||
case 2:
|
|
||||||
tx = _a.sent();
|
|
||||||
console.log(tx);
|
|
||||||
assert_1.default.ok(false);
|
|
||||||
return [3 /*break*/, 4];
|
|
||||||
case 3:
|
|
||||||
error_1 = _a.sent();
|
|
||||||
assert_1.default.equal(error_1.code, ethers_1.ethers.utils.Logger.errors.NONCE_EXPIRED);
|
|
||||||
return [3 /*break*/, 4];
|
|
||||||
case 4: return [4 /*yield*/, waiter(delay)];
|
|
||||||
case 5:
|
|
||||||
_a.sent();
|
|
||||||
return [2 /*return*/];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it("throws correct INSUFFICIENT_FUNDS errors", function () {
|
|
||||||
return __awaiter(this, void 0, void 0, function () {
|
|
||||||
var txProps, wallet, tx, error_2;
|
|
||||||
return __generator(this, function (_a) {
|
|
||||||
switch (_a.label) {
|
|
||||||
case 0:
|
|
||||||
this.timeout(60000);
|
|
||||||
txProps = {
|
|
||||||
to: "0x8ba1f109551bD432803012645Ac136ddd64DBA72",
|
|
||||||
gasPrice: 9000000000,
|
|
||||||
gasLimit: 21000,
|
|
||||||
value: 1
|
|
||||||
};
|
|
||||||
wallet = ethers_1.ethers.Wallet.createRandom();
|
|
||||||
return [4 /*yield*/, wallet.signTransaction(txProps)];
|
|
||||||
case 1:
|
|
||||||
tx = _a.sent();
|
|
||||||
_a.label = 2;
|
|
||||||
case 2:
|
|
||||||
_a.trys.push([2, 4, , 5]);
|
|
||||||
return [4 /*yield*/, provider.sendTransaction(tx)];
|
|
||||||
case 3:
|
|
||||||
_a.sent();
|
|
||||||
assert_1.default.ok(false);
|
|
||||||
return [3 /*break*/, 5];
|
|
||||||
case 4:
|
|
||||||
error_2 = _a.sent();
|
|
||||||
assert_1.default.equal(error_2.code, ethers_1.ethers.utils.Logger.errors.INSUFFICIENT_FUNDS);
|
|
||||||
return [3 /*break*/, 5];
|
|
||||||
case 5: return [4 /*yield*/, waiter(delay)];
|
|
||||||
case 6:
|
|
||||||
_a.sent();
|
|
||||||
return [2 /*return*/];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it("throws correct INSUFFICIENT_FUNDS errors (signer)", function () {
|
|
||||||
return __awaiter(this, void 0, void 0, function () {
|
|
||||||
var txProps, wallet, error_3;
|
|
||||||
return __generator(this, function (_a) {
|
|
||||||
switch (_a.label) {
|
|
||||||
case 0:
|
|
||||||
this.timeout(60000);
|
|
||||||
txProps = {
|
|
||||||
to: "0x8ba1f109551bD432803012645Ac136ddd64DBA72",
|
|
||||||
gasPrice: 9000000000,
|
|
||||||
gasLimit: 21000,
|
|
||||||
value: 1
|
|
||||||
};
|
|
||||||
wallet = ethers_1.ethers.Wallet.createRandom().connect(provider);
|
|
||||||
_a.label = 1;
|
|
||||||
case 1:
|
|
||||||
_a.trys.push([1, 3, , 4]);
|
|
||||||
return [4 /*yield*/, wallet.sendTransaction(txProps)];
|
|
||||||
case 2:
|
|
||||||
_a.sent();
|
|
||||||
assert_1.default.ok(false);
|
|
||||||
return [3 /*break*/, 4];
|
|
||||||
case 3:
|
|
||||||
error_3 = _a.sent();
|
|
||||||
assert_1.default.equal(error_3.code, ethers_1.ethers.utils.Logger.errors.INSUFFICIENT_FUNDS);
|
|
||||||
return [3 /*break*/, 4];
|
|
||||||
case 4: return [4 /*yield*/, waiter(delay)];
|
|
||||||
case 5:
|
|
||||||
_a.sent();
|
|
||||||
return [2 /*return*/];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it("throws correct UNPREDICTABLE_GAS_LIMIT errors", function () {
|
|
||||||
return __awaiter(this, void 0, void 0, function () {
|
|
||||||
var error_4;
|
|
||||||
return __generator(this, function (_a) {
|
|
||||||
switch (_a.label) {
|
|
||||||
case 0:
|
|
||||||
this.timeout(60000);
|
|
||||||
_a.label = 1;
|
|
||||||
case 1:
|
|
||||||
_a.trys.push([1, 3, , 4]);
|
|
||||||
return [4 /*yield*/, provider.estimateGas({
|
|
||||||
to: "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e" // ENS; no payable fallback
|
|
||||||
})];
|
|
||||||
case 2:
|
|
||||||
_a.sent();
|
|
||||||
assert_1.default.ok(false);
|
|
||||||
return [3 /*break*/, 4];
|
|
||||||
case 3:
|
|
||||||
error_4 = _a.sent();
|
|
||||||
assert_1.default.equal(error_4.code, ethers_1.ethers.utils.Logger.errors.UNPREDICTABLE_GAS_LIMIT);
|
|
||||||
return [3 /*break*/, 4];
|
|
||||||
case 4: return [4 /*yield*/, waiter(delay)];
|
|
||||||
case 5:
|
|
||||||
_a.sent();
|
|
||||||
return [2 /*return*/];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it("sends a transaction", function () {
|
|
||||||
return __awaiter(this, void 0, void 0, function () {
|
|
||||||
var wallet, funder, addr, gasPrice, balance, tx;
|
|
||||||
return __generator(this, function (_a) {
|
|
||||||
switch (_a.label) {
|
|
||||||
case 0:
|
|
||||||
this.timeout(360000);
|
|
||||||
wallet = ethers_1.ethers.Wallet.createRandom().connect(provider);
|
|
||||||
return [4 /*yield*/, ethers_1.ethers.utils.fetchJson("https://api.ethers.io/api/v1/?action=fundAccount&address=" + wallet.address.toLowerCase())];
|
|
||||||
case 1:
|
|
||||||
funder = _a.sent();
|
|
||||||
return [4 /*yield*/, provider.waitForTransaction(funder.hash)];
|
|
||||||
case 2:
|
|
||||||
_a.sent();
|
|
||||||
addr = "0x8210357f377E901f18E45294e86a2A32215Cc3C9";
|
|
||||||
gasPrice = 9000000000;
|
|
||||||
return [4 /*yield*/, provider.getBalance(wallet.address)];
|
|
||||||
case 3:
|
|
||||||
balance = _a.sent();
|
|
||||||
assert_1.default.ok(balance.eq(ethers_1.ethers.utils.parseEther("3.141592653589793238")), "balance is pi after funding");
|
|
||||||
return [4 /*yield*/, wallet.sendTransaction({
|
|
||||||
to: addr,
|
|
||||||
gasPrice: gasPrice,
|
|
||||||
value: balance.sub(21000 * gasPrice)
|
|
||||||
})];
|
|
||||||
case 4:
|
|
||||||
tx = _a.sent();
|
|
||||||
return [4 /*yield*/, tx.wait()];
|
|
||||||
case 5:
|
|
||||||
_a.sent();
|
|
||||||
return [4 /*yield*/, provider.getBalance(wallet.address)];
|
|
||||||
case 6:
|
|
||||||
balance = _a.sent();
|
|
||||||
assert_1.default.ok(balance.eq(ethers_1.ethers.constants.Zero), "balance is zero after after sweeping");
|
|
||||||
return [4 /*yield*/, waiter(delay)];
|
|
||||||
case 7:
|
|
||||||
_a.sent();
|
|
||||||
return [2 /*return*/];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// Obviously many more cases to add here
|
|
||||||
// - getTransactionCount
|
|
||||||
// - getBlockNumber
|
|
||||||
// - getGasPrice
|
|
||||||
// - estimateGas
|
|
||||||
// - sendTransaction
|
|
||||||
// - call
|
|
||||||
// - getLogs
|
|
||||||
//
|
|
||||||
// Many of these are tLegacyParametersested in run-providers, which uses nodeunit, but
|
|
||||||
// also creates a local private key which must then be funded to
|
|
||||||
// execute the tests. I am working on a better test contract to deploy
|
|
||||||
// to all the networks to help test these.
|
|
||||||
});
|
|
||||||
}
|
|
||||||
["default", "homestead", "ropsten", "rinkeby", "kovan", "goerli"].forEach(function (networkName) {
|
|
||||||
["getDefaultProvider", "AlchemyProvider", "CloudflareProvider", "InfuraProvider", "EtherscanProvider", "NodesmithProvider", "Web3Provider"].forEach(function (providerName) {
|
|
||||||
if (providerName === "NodesmithProvider") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (providerName === "CloudflareProvider") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (providerName === "Web3Provider") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ((networkName !== "homestead" && networkName !== "default") && providerName === "CloudflareProvider") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
testProvider(providerName, networkName);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
/*
|
/*
|
||||||
@ -789,7 +876,7 @@ describe("Test extra Etherscan operations", function() {
|
|||||||
});
|
});
|
||||||
*/
|
*/
|
||||||
describe("Test Basic Authentication", function () {
|
describe("Test Basic Authentication", function () {
|
||||||
this.retries(3);
|
//this.retries(3);
|
||||||
function test(name, url) {
|
function test(name, url) {
|
||||||
it("tests " + name, function () {
|
it("tests " + name, function () {
|
||||||
this.timeout(60000);
|
this.timeout(60000);
|
||||||
|
File diff suppressed because one or more lines are too long
@ -39,7 +39,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "exit 1"
|
"test": "exit 1"
|
||||||
},
|
},
|
||||||
"tarballHash": "0xeba001b6d7814b9df776d8a5b395ba7080d99ea8a6dfc8fad70888a5f7d01f3e",
|
"tarballHash": "0x71309e6063699613deb6d5d29f7c87963ee1d71e252f006cdd3ad930e187e47c",
|
||||||
"types": "./lib/index.d.ts",
|
"types": "./lib/index.d.ts",
|
||||||
"version": "5.0.8"
|
"version": "5.0.8"
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user