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
|
||||
accessing addresses aligned autofill called cancelled changed censored
|
||||
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
|
||||
encrypted encrypting entries euro exceeded existing expected
|
||||
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
|
||||
ethseed ethers eval exec filename func gz hid http https hw iv
|
||||
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
|
||||
repl rpc sighash topichash solc stdin stdout subclasses subnode
|
||||
timeout todo txt ufixed utc utf util url uuid vm vs websocket
|
||||
nfkc nfd nfkd nodehash notok nowait nullish oob opcode pbkdf pc plugin
|
||||
pragma pre prf repl rpc sighash topichash solc stdin stdout subclasses
|
||||
subnode timeout todo txt ufixed utc utf util url uuid vm vs websocket
|
||||
wikipedia wx xe xpriv xpub xx yyyy zlib
|
||||
|
||||
// AbiV2
|
||||
|
@ -65,7 +65,7 @@ const blockchainData = {
|
||||
s: "0x269c3e5b3558267ad91b0a887d51f9f10098771c67b82ea6cb74f29638754f54",
|
||||
v: 38,
|
||||
creates: null,
|
||||
raw: "0xf8d2808504a817c8008303d090946fc21092da55b392b045ed78f4732bff3c580e2c880186cc6acd4b0000b864f2c298be000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000067269636d6f6f000000000000000000000000000000000000000000000000000026a01e5605197a03e3f0a168f14749168dfeefc44c9228312dacbffdcbbb13263265a0269c3e5b3558267ad91b0a887d51f9f10098771c67b82ea6cb74f29638754f54",
|
||||
//raw: "0xf8d2808504a817c8008303d090946fc21092da55b392b045ed78f4732bff3c580e2c880186cc6acd4b0000b864f2c298be000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000067269636d6f6f000000000000000000000000000000000000000000000000000026a01e5605197a03e3f0a168f14749168dfeefc44c9228312dacbffdcbbb13263265a0269c3e5b3558267ad91b0a887d51f9f10098771c67b82ea6cb74f29638754f54",
|
||||
chainId: 1
|
||||
}
|
||||
],
|
||||
@ -364,6 +364,8 @@ function equals(name, actual, expected) {
|
||||
if (actual == 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");
|
||||
}
|
||||
else if (Array.isArray(expected)) {
|
||||
@ -398,265 +400,315 @@ function equals(name, actual, expected) {
|
||||
}
|
||||
function waiter(duration) {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(resolve, duration);
|
||||
const timer = setTimeout(resolve, duration);
|
||||
if (timer.unref) {
|
||||
timer.unref();
|
||||
}
|
||||
});
|
||||
}
|
||||
function testProvider(providerName, networkName) {
|
||||
// Delay (ms) after each test case to prevent the backends from throttling
|
||||
const delay = 1000;
|
||||
describe(("Read-Only " + providerName + " (" + networkName + ")"), function () {
|
||||
this.retries(3);
|
||||
// Get the Provider based on the name of the provider we are testing and the network
|
||||
let provider = null;
|
||||
if (networkName === "default") {
|
||||
if (providerName === "getDefaultProvider") {
|
||||
provider = ethers.getDefaultProvider();
|
||||
}
|
||||
else {
|
||||
provider = new (ethers.providers)[providerName]();
|
||||
const allNetworks = ["default", "homestead", "ropsten", "rinkeby", "kovan", "goerli"];
|
||||
const providerFunctions = [
|
||||
{
|
||||
name: "getDefaultProvider",
|
||||
networks: allNetworks,
|
||||
create: (network) => {
|
||||
if (network == "default") {
|
||||
return ethers.getDefaultProvider();
|
||||
}
|
||||
return ethers.getDefaultProvider(network);
|
||||
}
|
||||
else {
|
||||
if (providerName === "getDefaultProvider") {
|
||||
provider = ethers.getDefaultProvider(networkName);
|
||||
}
|
||||
else {
|
||||
provider = new (ethers.providers)[providerName](networkName);
|
||||
},
|
||||
{
|
||||
name: "AlchemyProvider",
|
||||
networks: allNetworks,
|
||||
create: (network) => {
|
||||
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
|
||||
// - code
|
||||
// - storage
|
||||
// - ENS name
|
||||
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
|
||||
// to our address; we just have to live with jerks sending us
|
||||
// money. *smile emoji*
|
||||
this.timeout(60000);
|
||||
return provider.getBalance(test.address).then((balance) => {
|
||||
equals("Balance", test.balance, balance);
|
||||
return waiter(delay);
|
||||
});
|
||||
});
|
||||
},
|
||||
{
|
||||
name: "CloudflareProvider",
|
||||
networks: ["homestead"],
|
||||
create: (network) => {
|
||||
return new ethers.providers.AlchemyProvider(network);
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "InfuraProvider",
|
||||
networks: allNetworks,
|
||||
create: (network) => {
|
||||
if (network == "default") {
|
||||
return new ethers.providers.InfuraProvider();
|
||||
}
|
||||
if (test.code) {
|
||||
it(`fetches address code: ${test.address}`, function () {
|
||||
this.timeout(60000);
|
||||
return provider.getCode(test.address).then((code) => {
|
||||
equals("Code", test.code, code);
|
||||
return waiter(delay);
|
||||
});
|
||||
});
|
||||
}
|
||||
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.InfuraProvider(network);
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "EtherscanProvider",
|
||||
networks: allNetworks,
|
||||
create: (network) => {
|
||||
if (network == "default") {
|
||||
return new ethers.providers.EtherscanProvider();
|
||||
}
|
||||
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) {
|
||||
return promise.then((block) => {
|
||||
for (let key in test) {
|
||||
equals("Block " + key, block[key], test[key]);
|
||||
}
|
||||
return waiter(delay);
|
||||
}
|
||||
function addObjectTest(name, func, expected, checkSkip) {
|
||||
testFunctions.push({
|
||||
name,
|
||||
networks: [network],
|
||||
checkSkip,
|
||||
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 title = ("Transaction " + expected.hash.substring(0, 10) + " - ");
|
||||
return provider.getTransaction(expected.hash).then((tx) => {
|
||||
// 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;
|
||||
for (const 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((test) => {
|
||||
function testTransactionReceipt(expected) {
|
||||
const 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.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);
|
||||
});
|
||||
}
|
||||
const tests = blockchainData[network];
|
||||
// And address test case can have any of the following:
|
||||
// - balance
|
||||
// - code
|
||||
// - storage
|
||||
// - ENS name
|
||||
tests.addresses.forEach((test) => {
|
||||
if (test.balance) {
|
||||
addSimpleTest(`fetches account balance: ${test.address}`, (provider) => {
|
||||
return provider.getBalance(test.address);
|
||||
}, test.balance);
|
||||
}
|
||||
if (test.code) {
|
||||
addSimpleTest(`fetches account code: ${test.address}`, (provider) => {
|
||||
return provider.getCode(test.address);
|
||||
}, test.code);
|
||||
}
|
||||
if (test.storage) {
|
||||
Object.keys(test.storage).forEach((position) => {
|
||||
addSimpleTest(`fetches storage: ${test.address}:${position}`, (provider) => {
|
||||
return provider.getStorageAt(test.address, bnify(position));
|
||||
}, test.storage[position]);
|
||||
});
|
||||
}
|
||||
// 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.
|
||||
if (test.name) {
|
||||
addSimpleTest(`fetches ENS name: ${test.address}`, (provider) => {
|
||||
return provider.resolveName(test.name);
|
||||
}, test.address);
|
||||
}
|
||||
});
|
||||
}
|
||||
["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);
|
||||
tests.blocks.forEach((test) => {
|
||||
addObjectTest(`fetches block (by number) #${test.number}`, (provider) => {
|
||||
return provider.getBlock(test.number);
|
||||
}, test);
|
||||
});
|
||||
tests.blocks.forEach((test) => {
|
||||
addObjectTest(`fetches block (by hash) ${test.hash}`, (provider) => {
|
||||
return provider.getBlock(test.hash);
|
||||
}, test, (provider, network, test) => {
|
||||
return (provider === "EtherscanProvider");
|
||||
});
|
||||
});
|
||||
tests.transactions.forEach((test) => {
|
||||
addObjectTest(`fetches transaction ${test.hash}`, (provider) => __awaiter(void 0, void 0, void 0, function* () {
|
||||
const tx = yield provider.getTransaction(test.hash);
|
||||
// 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 () {
|
||||
this.retries(3);
|
||||
//this.retries(3);
|
||||
function test(name, url) {
|
||||
it("tests " + name, function () {
|
||||
this.timeout(60000);
|
||||
|
File diff suppressed because one or more lines are too long
@ -96,7 +96,7 @@ var blockchainData = {
|
||||
s: "0x269c3e5b3558267ad91b0a887d51f9f10098771c67b82ea6cb74f29638754f54",
|
||||
v: 38,
|
||||
creates: null,
|
||||
raw: "0xf8d2808504a817c8008303d090946fc21092da55b392b045ed78f4732bff3c580e2c880186cc6acd4b0000b864f2c298be000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000067269636d6f6f000000000000000000000000000000000000000000000000000026a01e5605197a03e3f0a168f14749168dfeefc44c9228312dacbffdcbbb13263265a0269c3e5b3558267ad91b0a887d51f9f10098771c67b82ea6cb74f29638754f54",
|
||||
//raw: "0xf8d2808504a817c8008303d090946fc21092da55b392b045ed78f4732bff3c580e2c880186cc6acd4b0000b864f2c298be000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000067269636d6f6f000000000000000000000000000000000000000000000000000026a01e5605197a03e3f0a168f14749168dfeefc44c9228312dacbffdcbbb13263265a0269c3e5b3558267ad91b0a887d51f9f10098771c67b82ea6cb74f29638754f54",
|
||||
chainId: 1
|
||||
}
|
||||
],
|
||||
@ -395,6 +395,8 @@ function equals(name, actual, expected) {
|
||||
if (actual == 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");
|
||||
}
|
||||
else if (Array.isArray(expected)) {
|
||||
@ -429,344 +431,429 @@ function equals(name, actual, expected) {
|
||||
}
|
||||
function waiter(duration) {
|
||||
return new Promise(function (resolve) {
|
||||
setTimeout(resolve, duration);
|
||||
var timer = setTimeout(resolve, duration);
|
||||
if (timer.unref) {
|
||||
timer.unref();
|
||||
}
|
||||
});
|
||||
}
|
||||
function testProvider(providerName, networkName) {
|
||||
// Delay (ms) after each test case to prevent the backends from throttling
|
||||
var delay = 1000;
|
||||
describe(("Read-Only " + providerName + " (" + networkName + ")"), function () {
|
||||
this.retries(3);
|
||||
// Get the Provider based on the name of the provider we are testing and the network
|
||||
var provider = null;
|
||||
if (networkName === "default") {
|
||||
if (providerName === "getDefaultProvider") {
|
||||
provider = ethers_1.ethers.getDefaultProvider();
|
||||
}
|
||||
else {
|
||||
provider = new (ethers_1.ethers.providers)[providerName]();
|
||||
var allNetworks = ["default", "homestead", "ropsten", "rinkeby", "kovan", "goerli"];
|
||||
var providerFunctions = [
|
||||
{
|
||||
name: "getDefaultProvider",
|
||||
networks: allNetworks,
|
||||
create: function (network) {
|
||||
if (network == "default") {
|
||||
return ethers_1.ethers.getDefaultProvider();
|
||||
}
|
||||
return ethers_1.ethers.getDefaultProvider(network);
|
||||
}
|
||||
else {
|
||||
if (providerName === "getDefaultProvider") {
|
||||
provider = ethers_1.ethers.getDefaultProvider(networkName);
|
||||
}
|
||||
else {
|
||||
provider = new (ethers_1.ethers.providers)[providerName](networkName);
|
||||
},
|
||||
{
|
||||
name: "AlchemyProvider",
|
||||
networks: allNetworks,
|
||||
create: function (network) {
|
||||
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
|
||||
// - code
|
||||
// - storage
|
||||
// - ENS name
|
||||
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
|
||||
// to our address; we just have to live with jerks sending us
|
||||
// money. *smile emoji*
|
||||
this.timeout(60000);
|
||||
return provider.getBalance(test.address).then(function (balance) {
|
||||
equals("Balance", test.balance, balance);
|
||||
return waiter(delay);
|
||||
});
|
||||
});
|
||||
},
|
||||
{
|
||||
name: "CloudflareProvider",
|
||||
networks: ["homestead"],
|
||||
create: function (network) {
|
||||
return new ethers_1.ethers.providers.AlchemyProvider(network);
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "InfuraProvider",
|
||||
networks: allNetworks,
|
||||
create: function (network) {
|
||||
if (network == "default") {
|
||||
return new ethers_1.ethers.providers.InfuraProvider();
|
||||
}
|
||||
if (test.code) {
|
||||
it("fetches address code: " + test.address, function () {
|
||||
this.timeout(60000);
|
||||
return provider.getCode(test.address).then(function (code) {
|
||||
equals("Code", test.code, code);
|
||||
return waiter(delay);
|
||||
});
|
||||
});
|
||||
return new ethers_1.ethers.providers.InfuraProvider(network);
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "EtherscanProvider",
|
||||
networks: allNetworks,
|
||||
create: function (network) {
|
||||
if (network == "default") {
|
||||
return new ethers_1.ethers.providers.EtherscanProvider();
|
||||
}
|
||||
if (test.storage) {
|
||||
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) {
|
||||
equals("Storage", test.storage[position], value);
|
||||
return waiter(delay);
|
||||
return new ethers_1.ethers.providers.EtherscanProvider(network);
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "NodesmithProvider",
|
||||
networks: [],
|
||||
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 () {
|
||||
this.retries(3);
|
||||
//this.retries(3);
|
||||
function test(name, url) {
|
||||
it("tests " + name, function () {
|
||||
this.timeout(60000);
|
||||
|
File diff suppressed because one or more lines are too long
@ -39,7 +39,7 @@
|
||||
"scripts": {
|
||||
"test": "exit 1"
|
||||
},
|
||||
"tarballHash": "0xeba001b6d7814b9df776d8a5b395ba7080d99ea8a6dfc8fad70888a5f7d01f3e",
|
||||
"tarballHash": "0x71309e6063699613deb6d5d29f7c87963ee1d71e252f006cdd3ad930e187e47c",
|
||||
"types": "./lib/index.d.ts",
|
||||
"version": "5.0.8"
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user