admin: update dist files
This commit is contained in:
parent
4d435cd56e
commit
a6faed5098
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,3 +1,6 @@
|
||||
node_modules/**
|
||||
output/**
|
||||
misc/**
|
||||
|
||||
**/*.swp
|
||||
dist/*.gz
|
||||
|
2475
dist/ethers.js
vendored
2475
dist/ethers.js
vendored
File diff suppressed because it is too large
Load Diff
2
dist/ethers.js.map
vendored
2
dist/ethers.js.map
vendored
File diff suppressed because one or more lines are too long
2
dist/ethers.min.js
vendored
2
dist/ethers.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/wordlists-extra.js
vendored
2
dist/wordlists-extra.js
vendored
@ -145,7 +145,7 @@ const u64 = {
|
||||
add, add3L, add3H, add4L, add4H, add5H, add5L,
|
||||
};
|
||||
|
||||
const version = "6.0.0-beta-exports.1";
|
||||
const version = "6.0.0-beta-exports.2";
|
||||
|
||||
function defineReadOnly(object, name, value) {
|
||||
Object.defineProperty(object, name, {
|
||||
|
2
dist/wordlists-extra.js.map
vendored
2
dist/wordlists-extra.js.map
vendored
File diff suppressed because one or more lines are too long
2
dist/wordlists-extra.min.js
vendored
2
dist/wordlists-extra.min.js
vendored
File diff suppressed because one or more lines are too long
@ -638,7 +638,7 @@ class Fragment {
|
||||
case "function": return FunctionFragment.fromObject(obj);
|
||||
case "struct": return StructFragment.fromObject(obj);
|
||||
}
|
||||
throw new Error("not implemented yet");
|
||||
throw new Error(`not implemented yet: ${obj.type}`);
|
||||
}
|
||||
static fromString(text) {
|
||||
try {
|
||||
@ -727,6 +727,9 @@ class ErrorFragment extends NamedFragment {
|
||||
result.push(this.name + joinParams(format, this.inputs));
|
||||
return result.join(" ");
|
||||
}
|
||||
static fromObject(obj) {
|
||||
return new ErrorFragment(_guard, obj.name, obj.inputs ? obj.inputs.map(ParamType.fromObject) : []);
|
||||
}
|
||||
static fromString(text) {
|
||||
return ErrorFragment.fromTokens(lex(text));
|
||||
}
|
||||
@ -766,6 +769,9 @@ class EventFragment extends NamedFragment {
|
||||
}
|
||||
return result.join(" ");
|
||||
}
|
||||
static fromObject(obj) {
|
||||
return new EventFragment(_guard, obj.name, obj.inputs ? obj.inputs.map(ParamType.fromObject) : [], !!obj.anonymous);
|
||||
}
|
||||
static fromString(text) {
|
||||
return EventFragment.fromTokens(lex(text));
|
||||
}
|
||||
@ -807,12 +813,12 @@ class ConstructorFragment extends Fragment {
|
||||
}
|
||||
return result.join(" ");
|
||||
}
|
||||
static fromObject(obj) {
|
||||
return new ConstructorFragment(_guard, "constructor", obj.inputs ? obj.inputs.map(ParamType.fromObject) : [], !!obj.payable, (obj.gas != null) ? obj.gas : null);
|
||||
}
|
||||
static fromString(text) {
|
||||
return ConstructorFragment.fromTokens(lex(text));
|
||||
}
|
||||
static fromObject(obj) {
|
||||
throw new Error("TODO");
|
||||
}
|
||||
static fromTokens(tokens) {
|
||||
consumeKeywords(tokens, setify(["constructor"]));
|
||||
const inputs = consumeParams(tokens);
|
||||
@ -871,6 +877,10 @@ class FunctionFragment extends NamedFragment {
|
||||
}
|
||||
return result.join(" ");
|
||||
}
|
||||
static fromObject(obj) {
|
||||
// @TODO: verifyState for stateMutability
|
||||
return new FunctionFragment(_guard, obj.name, obj.stateMutability, obj.inputs ? obj.inputs.map(ParamType.fromObject) : [], obj.outputs ? obj.outputs.map(ParamType.fromObject) : [], (obj.gas != null) ? obj.gas : null);
|
||||
}
|
||||
static fromString(text) {
|
||||
return FunctionFragment.fromTokens(lex(text));
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
@ -125,8 +125,15 @@ class Interface {
|
||||
this.#errors = new Map();
|
||||
this.#events = new Map();
|
||||
// this.#structs = new Map();
|
||||
const frags = [];
|
||||
for (const a of abi) {
|
||||
try {
|
||||
frags.push(fragments_js_1.Fragment.from(a));
|
||||
}
|
||||
catch (error) { }
|
||||
}
|
||||
(0, index_js_3.defineProperties)(this, {
|
||||
fragments: Object.freeze(abi.map((f) => fragments_js_1.Fragment.from(f)).filter((f) => (f != null))),
|
||||
fragments: Object.freeze(frags)
|
||||
});
|
||||
this.#abiCoder = this.getAbiCoder();
|
||||
// Add all fragments by their signature
|
||||
|
File diff suppressed because one or more lines are too long
@ -170,6 +170,8 @@ class WrappedMethod extends _WrappedMethodBase() {
|
||||
}
|
||||
const tx = await runner.sendTransaction(await this.populateTransaction(...args));
|
||||
const provider = getProvider(this._contract.runner);
|
||||
// @TODO: the provider can be null; make a custom dummy provider that will throw a
|
||||
// meaningful error
|
||||
return new wrappers_js_1.ContractTransactionResponse(this._contract.interface, provider, tx);
|
||||
}
|
||||
async estimateGas(...args) {
|
||||
@ -387,6 +389,8 @@ class BaseContract {
|
||||
let deployTx = null;
|
||||
if (_deployTx) {
|
||||
const provider = getProvider(runner);
|
||||
// @TODO: the provider can be null; make a custom dummy provider that will throw a
|
||||
// meaningful error
|
||||
deployTx = new wrappers_js_1.ContractTransactionResponse(this.interface, provider, _deployTx);
|
||||
}
|
||||
let subs = new Map();
|
||||
|
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src.ts/contract/types.ts"],"names":[],"mappings":";;AAeC,CAAC;AAiBqE,CAAC;AAkDvE,CAAC"}
|
||||
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src.ts/contract/types.ts"],"names":[],"mappings":";;AAeC,CAAC;AAiB4E,CAAC;AAkD9E,CAAC"}
|
@ -1 +1 @@
|
||||
{"version":3,"file":"wrappers.js","sourceRoot":"","sources":["../../src.ts/contract/wrappers.ts"],"names":[],"mappings":"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"}
|
||||
{"version":3,"file":"wrappers.js","sourceRoot":"","sources":["../../src.ts/contract/wrappers.ts"],"names":[],"mappings":"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"}
|
@ -7,16 +7,20 @@
|
||||
// migrate the listener to the static event. We also need to maintain a map
|
||||
// of Signer/ENS name to address so we can sync respond to listenerCount.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.AbstractProvider = exports.copyRequest = exports.UnmanagedSubscriber = void 0;
|
||||
exports.AbstractProvider = exports.UnmanagedSubscriber = void 0;
|
||||
const index_js_1 = require("../address/index.js");
|
||||
const index_js_2 = require("../utils/index.js");
|
||||
const ens_resolver_js_1 = require("./ens-resolver.js");
|
||||
const format_js_1 = require("./format.js");
|
||||
const network_js_1 = require("./network.js");
|
||||
const provider_js_1 = require("./provider.js");
|
||||
const subscriber_polling_js_1 = require("./subscriber-polling.js");
|
||||
// Constants
|
||||
const BN_2 = BigInt(2);
|
||||
const MAX_CCIP_REDIRECTS = 10;
|
||||
function isPromise(value) {
|
||||
return (value && typeof (value.then) === "function");
|
||||
}
|
||||
function getTag(prefix, value) {
|
||||
return prefix + ":" + JSON.stringify(value, (k, v) => {
|
||||
if (typeof (v) === "bigint") {
|
||||
@ -54,10 +58,6 @@ function concisify(items) {
|
||||
items.sort();
|
||||
return items;
|
||||
}
|
||||
// Normalize a ProviderEvent into a Subscription
|
||||
// @TODO: Make events sync if possible; like block
|
||||
//function getSyncSubscription(_event: ProviderEvent): Subscription {
|
||||
//}
|
||||
async function getSubscription(_event, provider) {
|
||||
if (_event == null) {
|
||||
throw new Error("invalid event");
|
||||
@ -127,11 +127,6 @@ async function getSubscription(_event, provider) {
|
||||
return (0, index_js_2.throwArgumentError)("unknown ProviderEvent", "event", _event);
|
||||
}
|
||||
function getTime() { return (new Date()).getTime(); }
|
||||
function copyRequest(tx) {
|
||||
// @TODO: copy the copy from contracts and use it from this
|
||||
return tx;
|
||||
}
|
||||
exports.copyRequest = copyRequest;
|
||||
class AbstractProvider {
|
||||
#subs;
|
||||
#plugins;
|
||||
@ -140,6 +135,8 @@ class AbstractProvider {
|
||||
#networkPromise;
|
||||
#anyNetwork;
|
||||
#performCache;
|
||||
// The most recent block number if running an event or -1 if no "block" event
|
||||
#lastBlockNumber;
|
||||
#nextTimer;
|
||||
#timers;
|
||||
#disableCcipRead;
|
||||
@ -160,6 +157,7 @@ class AbstractProvider {
|
||||
this.#anyNetwork = false;
|
||||
this.#networkPromise = null;
|
||||
}
|
||||
this.#lastBlockNumber = -1;
|
||||
this.#performCache = new Map();
|
||||
this.#subs = new Map();
|
||||
this.#plugins = new Map();
|
||||
@ -248,8 +246,20 @@ class AbstractProvider {
|
||||
transaction: tx, info: { urls, errorMessages }
|
||||
});
|
||||
}
|
||||
_wrapTransaction(tx, hash, blockNumber) {
|
||||
return tx;
|
||||
_wrapBlock(value, network) {
|
||||
return new provider_js_1.Block((0, format_js_1.formatBlock)(value), this);
|
||||
}
|
||||
_wrapBlockWithTransactions(value, network) {
|
||||
return new provider_js_1.Block((0, format_js_1.formatBlock)(value), this);
|
||||
}
|
||||
_wrapLog(value, network) {
|
||||
return new provider_js_1.Log((0, format_js_1.formatLog)(value), this);
|
||||
}
|
||||
_wrapTransactionReceipt(value, network) {
|
||||
return new provider_js_1.TransactionReceipt((0, format_js_1.formatTransactionReceipt)(value), this);
|
||||
}
|
||||
_wrapTransactionResponse(tx, network) {
|
||||
return new provider_js_1.TransactionResponse(tx, this);
|
||||
}
|
||||
_detectNetwork() {
|
||||
return (0, index_js_2.throwError)("sub-classes must implement this", "UNSUPPORTED_OPERATION", {
|
||||
@ -266,20 +276,14 @@ class AbstractProvider {
|
||||
}
|
||||
// State
|
||||
async getBlockNumber() {
|
||||
return (0, index_js_2.getNumber)(await this.#perform({ method: "getBlockNumber" }), "%response");
|
||||
const blockNumber = (0, index_js_2.getNumber)(await this.#perform({ method: "getBlockNumber" }), "%response");
|
||||
if (this.#lastBlockNumber >= 0) {
|
||||
this.#lastBlockNumber = blockNumber;
|
||||
}
|
||||
return blockNumber;
|
||||
}
|
||||
// @TODO: Make this string | Promsie<string> so no await needed if sync is possible
|
||||
_getAddress(address) {
|
||||
return (0, index_js_1.resolveAddress)(address, this);
|
||||
/*
|
||||
if (typeof(address) === "string") {
|
||||
if (address.match(/^0x[0-9a-f]+$/i)) { return address; }
|
||||
const resolved = await this.resolveName(address);
|
||||
if (resolved == null) { throw new Error("not confiugred @TODO"); }
|
||||
return resolved;
|
||||
}
|
||||
return address.getAddress();
|
||||
*/
|
||||
}
|
||||
_getBlockTag(blockTag) {
|
||||
if (blockTag == null) {
|
||||
@ -304,236 +308,13 @@ class AbstractProvider {
|
||||
if (blockTag >= 0) {
|
||||
return (0, index_js_2.toQuantity)(blockTag);
|
||||
}
|
||||
if (this.#lastBlockNumber >= 0) {
|
||||
return (0, index_js_2.toQuantity)(this.#lastBlockNumber + blockTag);
|
||||
}
|
||||
return this.getBlockNumber().then((b) => (0, index_js_2.toQuantity)(b + blockTag));
|
||||
}
|
||||
return (0, index_js_2.throwArgumentError)("invalid blockTag", "blockTag", blockTag);
|
||||
}
|
||||
async getNetwork() {
|
||||
// No explicit network was set and this is our first time
|
||||
if (this.#networkPromise == null) {
|
||||
// Detect the current network (shared with all calls)
|
||||
const detectNetwork = this._detectNetwork().then((network) => {
|
||||
this.emit("network", network, null);
|
||||
return network;
|
||||
}, (error) => {
|
||||
// Reset the networkPromise on failure, so we will try again
|
||||
if (this.#networkPromise === detectNetwork) {
|
||||
this.#networkPromise = null;
|
||||
}
|
||||
throw error;
|
||||
});
|
||||
this.#networkPromise = detectNetwork;
|
||||
return await detectNetwork;
|
||||
}
|
||||
const networkPromise = this.#networkPromise;
|
||||
const [expected, actual] = await Promise.all([
|
||||
networkPromise,
|
||||
this._detectNetwork() // The actual connected network
|
||||
]);
|
||||
if (expected.chainId !== actual.chainId) {
|
||||
if (this.#anyNetwork) {
|
||||
// The "any" network can change, so notify listeners
|
||||
this.emit("network", actual, expected);
|
||||
// Update the network if something else hasn't already changed it
|
||||
if (this.#networkPromise === networkPromise) {
|
||||
this.#networkPromise = Promise.resolve(actual);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Otherwise, we do not allow changes to the underlying network
|
||||
(0, index_js_2.throwError)(`network changed: ${expected.chainId} => ${actual.chainId} `, "NETWORK_ERROR", {
|
||||
event: "changed"
|
||||
});
|
||||
}
|
||||
}
|
||||
return expected.clone().freeze();
|
||||
}
|
||||
async getFeeData() {
|
||||
const { block, gasPrice } = await (0, index_js_2.resolveProperties)({
|
||||
block: this.getBlock("latest"),
|
||||
gasPrice: ((async () => {
|
||||
try {
|
||||
const gasPrice = await this.#perform({ method: "getGasPrice" });
|
||||
return (0, index_js_2.getBigInt)(gasPrice, "%response");
|
||||
}
|
||||
catch (error) { }
|
||||
return null;
|
||||
})())
|
||||
});
|
||||
let maxFeePerGas = null, maxPriorityFeePerGas = null;
|
||||
if (block && block.baseFeePerGas) {
|
||||
// We may want to compute this more accurately in the future,
|
||||
// using the formula "check if the base fee is correct".
|
||||
// See: https://eips.ethereum.org/EIPS/eip-1559
|
||||
maxPriorityFeePerGas = BigInt("1500000000");
|
||||
// Allow a network to override their maximum priority fee per gas
|
||||
//const priorityFeePlugin = (await this.getNetwork()).getPlugin<MaxPriorityFeePlugin>("org.ethers.plugins.max-priority-fee");
|
||||
//if (priorityFeePlugin) {
|
||||
// maxPriorityFeePerGas = await priorityFeePlugin.getPriorityFee(this);
|
||||
//}
|
||||
maxFeePerGas = (block.baseFeePerGas * BN_2) + maxPriorityFeePerGas;
|
||||
}
|
||||
return new provider_js_1.FeeData(gasPrice, maxFeePerGas, maxPriorityFeePerGas);
|
||||
}
|
||||
async _getTransaction(_request) {
|
||||
const network = await this.getNetwork();
|
||||
// Fill in any addresses
|
||||
const request = Object.assign({}, _request, await (0, index_js_2.resolveProperties)({
|
||||
to: (_request.to ? (0, index_js_1.resolveAddress)(_request.to, this) : undefined),
|
||||
from: (_request.from ? (0, index_js_1.resolveAddress)(_request.from, this) : undefined),
|
||||
}));
|
||||
return network.formatter.transactionRequest(request);
|
||||
}
|
||||
async estimateGas(_tx) {
|
||||
const transaction = await this._getTransaction(_tx);
|
||||
return (0, index_js_2.getBigInt)(await this.#perform({
|
||||
method: "estimateGas", transaction
|
||||
}), "%response");
|
||||
}
|
||||
async #call(tx, blockTag, attempt) {
|
||||
if (attempt >= MAX_CCIP_REDIRECTS) {
|
||||
(0, index_js_2.throwError)("CCIP read exceeded maximum redirections", "OFFCHAIN_FAULT", {
|
||||
reason: "TOO_MANY_REDIRECTS",
|
||||
transaction: Object.assign({}, tx, { blockTag, enableCcipRead: true })
|
||||
});
|
||||
}
|
||||
const transaction = copyRequest(tx);
|
||||
try {
|
||||
return (0, index_js_2.hexlify)(await this._perform({ method: "call", transaction, blockTag }));
|
||||
}
|
||||
catch (error) {
|
||||
// CCIP Read OffchainLookup
|
||||
if (!this.disableCcipRead && (0, index_js_2.isCallException)(error) && attempt >= 0 && blockTag === "latest" && transaction.to != null && (0, index_js_2.dataSlice)(error.data, 0, 4) === "0x556f1830") {
|
||||
const data = error.data;
|
||||
const txSender = await (0, index_js_1.resolveAddress)(transaction.to, this);
|
||||
// Parse the CCIP Read Arguments
|
||||
let ccipArgs;
|
||||
try {
|
||||
ccipArgs = parseOffchainLookup((0, index_js_2.dataSlice)(error.data, 4));
|
||||
}
|
||||
catch (error) {
|
||||
return (0, index_js_2.throwError)(error.message, "OFFCHAIN_FAULT", {
|
||||
reason: "BAD_DATA",
|
||||
transaction, info: { data }
|
||||
});
|
||||
}
|
||||
// Check the sender of the OffchainLookup matches the transaction
|
||||
if (ccipArgs.sender.toLowerCase() !== txSender.toLowerCase()) {
|
||||
return (0, index_js_2.throwError)("CCIP Read sender mismatch", "CALL_EXCEPTION", {
|
||||
data, transaction,
|
||||
errorSignature: "OffchainLookup(address,string[],bytes,bytes4,bytes)",
|
||||
errorName: "OffchainLookup",
|
||||
errorArgs: ccipArgs.errorArgs
|
||||
});
|
||||
}
|
||||
const ccipResult = await this.ccipReadFetch(transaction, ccipArgs.calldata, ccipArgs.urls);
|
||||
if (ccipResult == null) {
|
||||
return (0, index_js_2.throwError)("CCIP Read failed to fetch data", "OFFCHAIN_FAULT", {
|
||||
reason: "FETCH_FAILED",
|
||||
transaction, info: { data: error.data, errorArgs: ccipArgs.errorArgs }
|
||||
});
|
||||
}
|
||||
return this.#call({
|
||||
to: txSender,
|
||||
data: (0, index_js_2.concat)([
|
||||
ccipArgs.selector, encodeBytes([ccipResult, ccipArgs.extraData])
|
||||
]),
|
||||
}, blockTag, attempt + 1);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
async call(_tx) {
|
||||
const [tx, blockTag] = await Promise.all([
|
||||
this._getTransaction(_tx), this._getBlockTag(_tx.blockTag)
|
||||
]);
|
||||
return this.#call(tx, blockTag, _tx.enableCcipRead ? 0 : -1);
|
||||
}
|
||||
// Account
|
||||
async #getAccountValue(request, _address, _blockTag) {
|
||||
let address = this._getAddress(_address);
|
||||
let blockTag = this._getBlockTag(_blockTag);
|
||||
if (typeof (address) !== "string" || typeof (blockTag) !== "string") {
|
||||
[address, blockTag] = await Promise.all([address, blockTag]);
|
||||
}
|
||||
return await this.#perform(Object.assign(request, { address, blockTag }));
|
||||
}
|
||||
async getBalance(address, blockTag) {
|
||||
return (0, index_js_2.getBigInt)(await this.#getAccountValue({ method: "getBalance" }, address, blockTag), "%response");
|
||||
}
|
||||
async getTransactionCount(address, blockTag) {
|
||||
return (0, index_js_2.getNumber)(await this.#getAccountValue({ method: "getTransactionCount" }, address, blockTag), "%response");
|
||||
}
|
||||
async getCode(address, blockTag) {
|
||||
return (0, index_js_2.hexlify)(await this.#getAccountValue({ method: "getCode" }, address, blockTag));
|
||||
}
|
||||
async getStorageAt(address, _position, blockTag) {
|
||||
const position = (0, index_js_2.getBigInt)(_position, "position");
|
||||
return (0, index_js_2.hexlify)(await this.#getAccountValue({ method: "getStorageAt", position }, address, blockTag));
|
||||
}
|
||||
// Write
|
||||
async broadcastTransaction(signedTx) {
|
||||
throw new Error();
|
||||
return {};
|
||||
}
|
||||
async #getBlock(block, includeTransactions) {
|
||||
if ((0, index_js_2.isHexString)(block, 32)) {
|
||||
return await this.#perform({
|
||||
method: "getBlock", blockHash: block, includeTransactions
|
||||
});
|
||||
}
|
||||
let blockTag = this._getBlockTag(block);
|
||||
if (typeof (blockTag) !== "string") {
|
||||
blockTag = await blockTag;
|
||||
}
|
||||
return await this.#perform({
|
||||
method: "getBlock", blockTag, includeTransactions
|
||||
});
|
||||
}
|
||||
// Queries
|
||||
async getBlock(block) {
|
||||
const [network, params] = await Promise.all([
|
||||
this.getNetwork(), this.#getBlock(block, false)
|
||||
]);
|
||||
if (params == null) {
|
||||
return null;
|
||||
}
|
||||
return network.formatter.block(params, this);
|
||||
}
|
||||
async getBlockWithTransactions(block) {
|
||||
const format = (await this.getNetwork()).formatter;
|
||||
const params = this.#getBlock(block, true);
|
||||
if (params == null) {
|
||||
return null;
|
||||
}
|
||||
return format.blockWithTransactions(params, this);
|
||||
}
|
||||
async getTransaction(hash) {
|
||||
const format = (await this.getNetwork()).formatter;
|
||||
const params = await this.#perform({ method: "getTransaction", hash });
|
||||
return format.transactionResponse(params, this);
|
||||
}
|
||||
async getTransactionReceipt(hash) {
|
||||
const format = (await this.getNetwork()).formatter;
|
||||
const receipt = await this.#perform({ method: "getTransactionReceipt", hash });
|
||||
if (receipt == null) {
|
||||
return null;
|
||||
}
|
||||
// Some backends did not backfill the effectiveGasPrice into old transactions
|
||||
// in the receipt, so we look it up manually and inject it.
|
||||
if (receipt.gasPrice == null && receipt.effectiveGasPrice == null) {
|
||||
const tx = await this.#perform({ method: "getTransaction", hash });
|
||||
receipt.effectiveGasPrice = tx.gasPrice;
|
||||
}
|
||||
return format.receipt(receipt, this);
|
||||
}
|
||||
async getTransactionResult(hash) {
|
||||
const result = await this.#perform({ method: "getTransactionResult", hash });
|
||||
if (result == null) {
|
||||
return null;
|
||||
}
|
||||
return (0, index_js_2.hexlify)(result);
|
||||
}
|
||||
_getFilter(filter) {
|
||||
// Create a canonical representation of the topics
|
||||
const topics = (filter.topics || []).map((t) => {
|
||||
@ -609,15 +390,295 @@ class AbstractProvider {
|
||||
}
|
||||
return resolve(address, fromBlock, toBlock);
|
||||
}
|
||||
_getTransactionRequest(_request) {
|
||||
const request = (0, provider_js_1.copyRequest)(_request);
|
||||
const promises = [];
|
||||
["to", "from"].forEach((key) => {
|
||||
if (request[key] == null) {
|
||||
return;
|
||||
}
|
||||
const addr = (0, index_js_1.resolveAddress)(request[key]);
|
||||
if (isPromise(addr)) {
|
||||
promises.push((async function () { request[key] = await addr; })());
|
||||
}
|
||||
else {
|
||||
request[key] = addr;
|
||||
}
|
||||
});
|
||||
if (request.blockTag != null) {
|
||||
const blockTag = this._getBlockTag(request.blockTag);
|
||||
if (isPromise(blockTag)) {
|
||||
promises.push((async function () { request.blockTag = await blockTag; })());
|
||||
}
|
||||
else {
|
||||
request.blockTag = blockTag;
|
||||
}
|
||||
}
|
||||
if (promises.length) {
|
||||
return (async function () {
|
||||
await Promise.all(promises);
|
||||
return request;
|
||||
})();
|
||||
}
|
||||
return request;
|
||||
}
|
||||
async getNetwork() {
|
||||
// No explicit network was set and this is our first time
|
||||
if (this.#networkPromise == null) {
|
||||
// Detect the current network (shared with all calls)
|
||||
const detectNetwork = this._detectNetwork().then((network) => {
|
||||
this.emit("network", network, null);
|
||||
return network;
|
||||
}, (error) => {
|
||||
// Reset the networkPromise on failure, so we will try again
|
||||
if (this.#networkPromise === detectNetwork) {
|
||||
this.#networkPromise = null;
|
||||
}
|
||||
throw error;
|
||||
});
|
||||
this.#networkPromise = detectNetwork;
|
||||
return (await detectNetwork).clone();
|
||||
}
|
||||
const networkPromise = this.#networkPromise;
|
||||
const [expected, actual] = await Promise.all([
|
||||
networkPromise,
|
||||
this._detectNetwork() // The actual connected network
|
||||
]);
|
||||
if (expected.chainId !== actual.chainId) {
|
||||
if (this.#anyNetwork) {
|
||||
// The "any" network can change, so notify listeners
|
||||
this.emit("network", actual, expected);
|
||||
// Update the network if something else hasn't already changed it
|
||||
if (this.#networkPromise === networkPromise) {
|
||||
this.#networkPromise = Promise.resolve(actual);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Otherwise, we do not allow changes to the underlying network
|
||||
(0, index_js_2.throwError)(`network changed: ${expected.chainId} => ${actual.chainId} `, "NETWORK_ERROR", {
|
||||
event: "changed"
|
||||
});
|
||||
}
|
||||
}
|
||||
return expected.clone();
|
||||
}
|
||||
async getFeeData() {
|
||||
const { block, gasPrice } = await (0, index_js_2.resolveProperties)({
|
||||
block: this.getBlock("latest"),
|
||||
gasPrice: ((async () => {
|
||||
try {
|
||||
const gasPrice = await this.#perform({ method: "getGasPrice" });
|
||||
return (0, index_js_2.getBigInt)(gasPrice, "%response");
|
||||
}
|
||||
catch (error) { }
|
||||
return null;
|
||||
})())
|
||||
});
|
||||
let maxFeePerGas = null, maxPriorityFeePerGas = null;
|
||||
if (block && block.baseFeePerGas) {
|
||||
// We may want to compute this more accurately in the future,
|
||||
// using the formula "check if the base fee is correct".
|
||||
// See: https://eips.ethereum.org/EIPS/eip-1559
|
||||
maxPriorityFeePerGas = BigInt("1500000000");
|
||||
// Allow a network to override their maximum priority fee per gas
|
||||
//const priorityFeePlugin = (await this.getNetwork()).getPlugin<MaxPriorityFeePlugin>("org.ethers.plugins.max-priority-fee");
|
||||
//if (priorityFeePlugin) {
|
||||
// maxPriorityFeePerGas = await priorityFeePlugin.getPriorityFee(this);
|
||||
//}
|
||||
maxFeePerGas = (block.baseFeePerGas * BN_2) + maxPriorityFeePerGas;
|
||||
}
|
||||
return new provider_js_1.FeeData(gasPrice, maxFeePerGas, maxPriorityFeePerGas);
|
||||
}
|
||||
async estimateGas(_tx) {
|
||||
let tx = this._getTransactionRequest(_tx);
|
||||
if (isPromise(tx)) {
|
||||
tx = await tx;
|
||||
}
|
||||
return (0, index_js_2.getBigInt)(await this.#perform({
|
||||
method: "estimateGas", transaction: tx
|
||||
}), "%response");
|
||||
}
|
||||
async #call(tx, blockTag, attempt) {
|
||||
if (attempt >= MAX_CCIP_REDIRECTS) {
|
||||
(0, index_js_2.throwError)("CCIP read exceeded maximum redirections", "OFFCHAIN_FAULT", {
|
||||
reason: "TOO_MANY_REDIRECTS",
|
||||
transaction: Object.assign({}, tx, { blockTag, enableCcipRead: true })
|
||||
});
|
||||
}
|
||||
// This came in as a PerformActionTransaction, so to/from are safe; we can cast
|
||||
const transaction = (0, provider_js_1.copyRequest)(tx);
|
||||
try {
|
||||
return (0, index_js_2.hexlify)(await this._perform({ method: "call", transaction, blockTag }));
|
||||
}
|
||||
catch (error) {
|
||||
// CCIP Read OffchainLookup
|
||||
if (!this.disableCcipRead && (0, index_js_2.isCallException)(error) && attempt >= 0 && blockTag === "latest" && transaction.to != null && (0, index_js_2.dataSlice)(error.data, 0, 4) === "0x556f1830") {
|
||||
const data = error.data;
|
||||
const txSender = await (0, index_js_1.resolveAddress)(transaction.to, this);
|
||||
// Parse the CCIP Read Arguments
|
||||
let ccipArgs;
|
||||
try {
|
||||
ccipArgs = parseOffchainLookup((0, index_js_2.dataSlice)(error.data, 4));
|
||||
}
|
||||
catch (error) {
|
||||
return (0, index_js_2.throwError)(error.message, "OFFCHAIN_FAULT", {
|
||||
reason: "BAD_DATA",
|
||||
transaction, info: { data }
|
||||
});
|
||||
}
|
||||
// Check the sender of the OffchainLookup matches the transaction
|
||||
if (ccipArgs.sender.toLowerCase() !== txSender.toLowerCase()) {
|
||||
return (0, index_js_2.throwError)("CCIP Read sender mismatch", "CALL_EXCEPTION", {
|
||||
data, transaction,
|
||||
errorSignature: "OffchainLookup(address,string[],bytes,bytes4,bytes)",
|
||||
errorName: "OffchainLookup",
|
||||
errorArgs: ccipArgs.errorArgs
|
||||
});
|
||||
}
|
||||
const ccipResult = await this.ccipReadFetch(transaction, ccipArgs.calldata, ccipArgs.urls);
|
||||
if (ccipResult == null) {
|
||||
return (0, index_js_2.throwError)("CCIP Read failed to fetch data", "OFFCHAIN_FAULT", {
|
||||
reason: "FETCH_FAILED",
|
||||
transaction, info: { data: error.data, errorArgs: ccipArgs.errorArgs }
|
||||
});
|
||||
}
|
||||
return this.#call({
|
||||
to: txSender,
|
||||
data: (0, index_js_2.concat)([
|
||||
ccipArgs.selector, encodeBytes([ccipResult, ccipArgs.extraData])
|
||||
]),
|
||||
}, blockTag, attempt + 1);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
async #checkNetwork(promise) {
|
||||
const { value } = await (0, index_js_2.resolveProperties)({
|
||||
network: this.getNetwork(),
|
||||
value: promise
|
||||
});
|
||||
return value;
|
||||
}
|
||||
async call(_tx) {
|
||||
const { tx, blockTag } = await (0, index_js_2.resolveProperties)({
|
||||
tx: this._getTransactionRequest(_tx),
|
||||
blockTag: this._getBlockTag(_tx.blockTag)
|
||||
});
|
||||
return await this.#checkNetwork(this.#call(tx, blockTag, _tx.enableCcipRead ? 0 : -1));
|
||||
}
|
||||
// Account
|
||||
async #getAccountValue(request, _address, _blockTag) {
|
||||
let address = this._getAddress(_address);
|
||||
let blockTag = this._getBlockTag(_blockTag);
|
||||
if (typeof (address) !== "string" || typeof (blockTag) !== "string") {
|
||||
[address, blockTag] = await Promise.all([address, blockTag]);
|
||||
}
|
||||
return await this.#checkNetwork(this.#perform(Object.assign(request, { address, blockTag })));
|
||||
}
|
||||
async getBalance(address, blockTag) {
|
||||
return (0, index_js_2.getBigInt)(await this.#getAccountValue({ method: "getBalance" }, address, blockTag), "%response");
|
||||
}
|
||||
async getTransactionCount(address, blockTag) {
|
||||
return (0, index_js_2.getNumber)(await this.#getAccountValue({ method: "getTransactionCount" }, address, blockTag), "%response");
|
||||
}
|
||||
async getCode(address, blockTag) {
|
||||
return (0, index_js_2.hexlify)(await this.#getAccountValue({ method: "getCode" }, address, blockTag));
|
||||
}
|
||||
async getStorageAt(address, _position, blockTag) {
|
||||
const position = (0, index_js_2.getBigInt)(_position, "position");
|
||||
return (0, index_js_2.hexlify)(await this.#getAccountValue({ method: "getStorageAt", position }, address, blockTag));
|
||||
}
|
||||
// Write
|
||||
async broadcastTransaction(signedTx) {
|
||||
throw new Error();
|
||||
return {};
|
||||
}
|
||||
async #getBlock(block, includeTransactions) {
|
||||
// @TODO: Add CustomBlockPlugin check
|
||||
if ((0, index_js_2.isHexString)(block, 32)) {
|
||||
return await this.#perform({
|
||||
method: "getBlock", blockHash: block, includeTransactions
|
||||
});
|
||||
}
|
||||
let blockTag = this._getBlockTag(block);
|
||||
if (typeof (blockTag) !== "string") {
|
||||
blockTag = await blockTag;
|
||||
}
|
||||
return await this.#perform({
|
||||
method: "getBlock", blockTag, includeTransactions
|
||||
});
|
||||
}
|
||||
// Queries
|
||||
async getBlock(block) {
|
||||
const { network, params } = await (0, index_js_2.resolveProperties)({
|
||||
network: this.getNetwork(),
|
||||
params: this.#getBlock(block, false)
|
||||
});
|
||||
if (params == null) {
|
||||
return null;
|
||||
}
|
||||
return this._wrapBlock((0, format_js_1.formatBlock)(params), network);
|
||||
}
|
||||
async getBlockWithTransactions(block) {
|
||||
const { network, params } = await (0, index_js_2.resolveProperties)({
|
||||
network: this.getNetwork(),
|
||||
params: this.#getBlock(block, true)
|
||||
});
|
||||
if (params == null) {
|
||||
return null;
|
||||
}
|
||||
return this._wrapBlockWithTransactions((0, format_js_1.formatBlockWithTransactions)(params), network);
|
||||
}
|
||||
async getTransaction(hash) {
|
||||
const { network, params } = await (0, index_js_2.resolveProperties)({
|
||||
network: this.getNetwork(),
|
||||
params: this.#perform({ method: "getTransaction", hash })
|
||||
});
|
||||
if (params == null) {
|
||||
return null;
|
||||
}
|
||||
return this._wrapTransactionResponse((0, format_js_1.formatTransactionResponse)(params), network);
|
||||
}
|
||||
async getTransactionReceipt(hash) {
|
||||
const { network, params } = await (0, index_js_2.resolveProperties)({
|
||||
network: this.getNetwork(),
|
||||
params: this.#perform({ method: "getTransactionReceipt", hash })
|
||||
});
|
||||
if (params == null) {
|
||||
return null;
|
||||
}
|
||||
// Some backends did not backfill the effectiveGasPrice into old transactions
|
||||
// in the receipt, so we look it up manually and inject it.
|
||||
if (params.gasPrice == null && params.effectiveGasPrice == null) {
|
||||
const tx = await this.#perform({ method: "getTransaction", hash });
|
||||
if (tx == null) {
|
||||
throw new Error("report this; could not find tx or effectiveGasPrice");
|
||||
}
|
||||
params.effectiveGasPrice = tx.gasPrice;
|
||||
}
|
||||
return this._wrapTransactionReceipt((0, format_js_1.formatTransactionReceipt)(params), network);
|
||||
}
|
||||
async getTransactionResult(hash) {
|
||||
const { result } = await (0, index_js_2.resolveProperties)({
|
||||
network: this.getNetwork(),
|
||||
result: this.#perform({ method: "getTransactionResult", hash })
|
||||
});
|
||||
if (result == null) {
|
||||
return null;
|
||||
}
|
||||
return (0, index_js_2.hexlify)(result);
|
||||
}
|
||||
// Bloom-filter Queries
|
||||
async getLogs(_filter) {
|
||||
const { network, filter } = await (0, index_js_2.resolveProperties)({
|
||||
let filter = this._getFilter(_filter);
|
||||
if (isPromise(filter)) {
|
||||
filter = await filter;
|
||||
}
|
||||
const { network, params } = await (0, index_js_2.resolveProperties)({
|
||||
network: this.getNetwork(),
|
||||
filter: this._getFilter(_filter)
|
||||
});
|
||||
return (await this.#perform({ method: "getLogs", filter })).map((l) => {
|
||||
return network.formatter.log(l, this);
|
||||
params: this.#perform({ method: "getLogs", filter })
|
||||
});
|
||||
return params.map((p) => this._wrapLog((0, format_js_1.formatLog)(p), network));
|
||||
}
|
||||
// ENS
|
||||
_getProvider(chainId) {
|
||||
@ -927,6 +988,7 @@ class AbstractProvider {
|
||||
}
|
||||
}
|
||||
pause(dropWhilePaused) {
|
||||
this.#lastBlockNumber = -1;
|
||||
if (this.#pausedState != null) {
|
||||
if (this.#pausedState == !!dropWhilePaused) {
|
||||
return;
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -6,7 +6,7 @@
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Network = exports.injectCommonNetworks = void 0;
|
||||
const plugins_network_js_1 = require("./plugins-network.js");
|
||||
const provider_etherscan_js_1 = require("./provider-etherscan.js");
|
||||
const provider_etherscan_base_js_1 = require("./provider-etherscan-base.js");
|
||||
const network_js_1 = require("./network.js");
|
||||
Object.defineProperty(exports, "Network", { enumerable: true, get: function () { return network_js_1.Network; } });
|
||||
// See: https://chainlist.org
|
||||
@ -24,7 +24,7 @@ function injectCommonNetworks() {
|
||||
}
|
||||
if (options.etherscan) {
|
||||
const { url, apiKey } = options.etherscan;
|
||||
network.attachPlugin(new provider_etherscan_js_1.EtherscanPlugin(url, apiKey));
|
||||
network.attachPlugin(new provider_etherscan_base_js_1.EtherscanPlugin(url, apiKey));
|
||||
}
|
||||
network.attachPlugin(new plugins_network_js_1.GasCostPlugin());
|
||||
return network;
|
||||
|
@ -1 +1 @@
|
||||
{"version":3,"file":"common-networks.js","sourceRoot":"","sources":["../../src.ts/providers/common-networks.ts"],"names":[],"mappings":"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"}
|
||||
{"version":3,"file":"common-networks.js","sourceRoot":"","sources":["../../src.ts/providers/common-networks.ts"],"names":[],"mappings":"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"}
|
@ -1,31 +1,32 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.EnsResolver = exports.BasicMulticoinProviderPlugin = exports.MulticoinProviderPlugin = void 0;
|
||||
const index_js_1 = require("../address/index.js");
|
||||
const hashes_js_1 = require("../constants/hashes.js");
|
||||
const index_js_1 = require("../hash/index.js");
|
||||
const index_js_2 = require("../utils/index.js");
|
||||
const index_js_2 = require("../hash/index.js");
|
||||
const index_js_3 = require("../utils/index.js");
|
||||
const BN_1 = BigInt(1);
|
||||
const Empty = new Uint8Array([]);
|
||||
function parseBytes(result, start) {
|
||||
if (result === "0x") {
|
||||
return null;
|
||||
}
|
||||
const offset = (0, index_js_2.toNumber)((0, index_js_2.dataSlice)(result, start, start + 32));
|
||||
const length = (0, index_js_2.toNumber)((0, index_js_2.dataSlice)(result, offset, offset + 32));
|
||||
return (0, index_js_2.dataSlice)(result, offset + 32, offset + 32 + length);
|
||||
const offset = (0, index_js_3.toNumber)((0, index_js_3.dataSlice)(result, start, start + 32));
|
||||
const length = (0, index_js_3.toNumber)((0, index_js_3.dataSlice)(result, offset, offset + 32));
|
||||
return (0, index_js_3.dataSlice)(result, offset + 32, offset + 32 + length);
|
||||
}
|
||||
function parseString(result, start) {
|
||||
try {
|
||||
const bytes = parseBytes(result, start);
|
||||
if (bytes != null) {
|
||||
return (0, index_js_2.toUtf8String)(bytes);
|
||||
return (0, index_js_3.toUtf8String)(bytes);
|
||||
}
|
||||
}
|
||||
catch (error) { }
|
||||
return null;
|
||||
}
|
||||
function numPad(value) {
|
||||
const result = (0, index_js_2.toArray)(value);
|
||||
const result = (0, index_js_3.toArray)(value);
|
||||
if (result.length > 32) {
|
||||
throw new Error("internal; should not happen");
|
||||
}
|
||||
@ -51,7 +52,7 @@ function encodeBytes(datas) {
|
||||
byteCount += 32;
|
||||
}
|
||||
for (let i = 0; i < datas.length; i++) {
|
||||
const data = (0, index_js_2.getBytes)(datas[i]);
|
||||
const data = (0, index_js_3.getBytes)(datas[i]);
|
||||
// Update the bytes offset
|
||||
result[i] = numPad(byteCount);
|
||||
// The length and padded value of data
|
||||
@ -59,7 +60,13 @@ function encodeBytes(datas) {
|
||||
result.push(bytesPad(data));
|
||||
byteCount += 32 + Math.ceil(data.length / 32) * 32;
|
||||
}
|
||||
return (0, index_js_2.concat)(result);
|
||||
return (0, index_js_3.concat)(result);
|
||||
}
|
||||
function callAddress(value) {
|
||||
if (value.length !== 66 || (0, index_js_3.dataSlice)(value, 0, 12) !== "0x000000000000000000000000") {
|
||||
(0, index_js_3.throwArgumentError)("invalid call address", "value", value);
|
||||
}
|
||||
return (0, index_js_1.getAddress)("0x" + value.substring(26));
|
||||
}
|
||||
// @TODO: This should use the fetch-data:ipfs gateway
|
||||
// Trim off the ipfs:// prefix and return the default gateway URL
|
||||
@ -71,7 +78,7 @@ function getIpfsLink(link) {
|
||||
link = link.substring(7);
|
||||
}
|
||||
else {
|
||||
(0, index_js_2.throwArgumentError)("unsupported IPFS format", "link", link);
|
||||
(0, index_js_3.throwArgumentError)("unsupported IPFS format", "link", link);
|
||||
}
|
||||
return `https:/\/gateway.ipfs.io/ipfs/${link}`;
|
||||
}
|
||||
@ -80,7 +87,7 @@ function getIpfsLink(link) {
|
||||
class MulticoinProviderPlugin {
|
||||
name;
|
||||
constructor(name) {
|
||||
(0, index_js_2.defineProperties)(this, { name });
|
||||
(0, index_js_3.defineProperties)(this, { name });
|
||||
}
|
||||
validate(proivder) {
|
||||
return this;
|
||||
@ -117,7 +124,7 @@ class EnsResolver {
|
||||
// For EIP-2544 names, the ancestor that provided the resolver
|
||||
#supports2544;
|
||||
constructor(provider, address, name) {
|
||||
(0, index_js_2.defineProperties)(this, { provider, address, name });
|
||||
(0, index_js_3.defineProperties)(this, { provider, address, name });
|
||||
this.#supports2544 = null;
|
||||
}
|
||||
async supportsWildcard() {
|
||||
@ -127,7 +134,7 @@ class EnsResolver {
|
||||
to: this.address,
|
||||
data: "0x01ffc9a79061b92300000000000000000000000000000000000000000000000000000000"
|
||||
}).then((result) => {
|
||||
return ((0, index_js_2.getBigInt)(result) === BN_1);
|
||||
return ((0, index_js_3.getBigInt)(result) === BN_1);
|
||||
}).catch((error) => {
|
||||
if (error.code === "CALL_EXCEPTION") {
|
||||
return false;
|
||||
@ -141,7 +148,7 @@ class EnsResolver {
|
||||
}
|
||||
async _fetch(selector, parameters = "0x") {
|
||||
// e.g. keccak256("addr(bytes32,uint256)")
|
||||
const addrData = (0, index_js_2.concat)([selector, (0, index_js_1.namehash)(this.name), parameters]);
|
||||
const addrData = (0, index_js_3.concat)([selector, (0, index_js_2.namehash)(this.name), parameters]);
|
||||
const tx = {
|
||||
to: this.address,
|
||||
enableCcipRead: true,
|
||||
@ -152,12 +159,12 @@ class EnsResolver {
|
||||
if (await this.supportsWildcard()) {
|
||||
wrapped = true;
|
||||
// selector("resolve(bytes,bytes)")
|
||||
tx.data = (0, index_js_2.concat)(["0x9061b923", encodeBytes([(0, index_js_1.dnsEncode)(this.name), addrData])]);
|
||||
tx.data = (0, index_js_3.concat)(["0x9061b923", encodeBytes([(0, index_js_2.dnsEncode)(this.name), addrData])]);
|
||||
}
|
||||
try {
|
||||
let data = await this.provider.call(tx);
|
||||
if (((0, index_js_2.getBytes)(data).length % 32) === 4) {
|
||||
return (0, index_js_2.throwError)("resolver threw error", "CALL_EXCEPTION", {
|
||||
if (((0, index_js_3.getBytes)(data).length % 32) === 4) {
|
||||
return (0, index_js_3.throwError)("resolver threw error", "CALL_EXCEPTION", {
|
||||
transaction: tx, data
|
||||
});
|
||||
}
|
||||
@ -179,11 +186,10 @@ class EnsResolver {
|
||||
// keccak256("addr(bytes32)")
|
||||
const result = await this._fetch("0x3b3b57de");
|
||||
// No address
|
||||
if (result === "0x" || result === hashes_js_1.ZeroHash) {
|
||||
if (result == null || result === "0x" || result === hashes_js_1.ZeroHash) {
|
||||
return null;
|
||||
}
|
||||
const network = await this.provider.getNetwork();
|
||||
return network.formatter.callAddress(result);
|
||||
return callAddress(result);
|
||||
}
|
||||
catch (error) {
|
||||
if (error.code === "CALL_EXCEPTION") {
|
||||
@ -216,22 +222,22 @@ class EnsResolver {
|
||||
if (address != null) {
|
||||
return address;
|
||||
}
|
||||
return (0, index_js_2.throwError)(`invalid coin data`, "UNSUPPORTED_OPERATION", {
|
||||
return (0, index_js_3.throwError)(`invalid coin data`, "UNSUPPORTED_OPERATION", {
|
||||
operation: `getAddress(${coinType})`,
|
||||
info: { coinType, data }
|
||||
});
|
||||
}
|
||||
async getText(key) {
|
||||
// The key encoded as parameter to fetchBytes
|
||||
let keyBytes = (0, index_js_2.toUtf8Bytes)(key);
|
||||
let keyBytes = (0, index_js_3.toUtf8Bytes)(key);
|
||||
// The nodehash consumes the first slot, so the string pointer targets
|
||||
// offset 64, with the length at offset 64 and data starting at offset 96
|
||||
const calldata = (0, index_js_2.getBytes)((0, index_js_2.concat)([numPad(64), numPad(keyBytes.length), keyBytes]));
|
||||
const calldata = (0, index_js_3.getBytes)((0, index_js_3.concat)([numPad(64), numPad(keyBytes.length), keyBytes]));
|
||||
const hexBytes = parseBytes((await this._fetch("0x59d1d43c", bytesPad(calldata))) || "0x", 0);
|
||||
if (hexBytes == null || hexBytes === "0x") {
|
||||
return null;
|
||||
}
|
||||
return (0, index_js_2.toUtf8String)(hexBytes);
|
||||
return (0, index_js_3.toUtf8String)(hexBytes);
|
||||
}
|
||||
async getContentHash() {
|
||||
// keccak256("contenthash()")
|
||||
@ -246,7 +252,7 @@ class EnsResolver {
|
||||
const scheme = (ipfs[1] === "e3010170") ? "ipfs" : "ipns";
|
||||
const length = parseInt(ipfs[4], 16);
|
||||
if (ipfs[5].length === length * 2) {
|
||||
return `${scheme}:/\/${(0, index_js_2.encodeBase58)("0x" + ipfs[2])}`;
|
||||
return `${scheme}:/\/${(0, index_js_3.encodeBase58)("0x" + ipfs[2])}`;
|
||||
}
|
||||
}
|
||||
// Swarm (CID: 1, Type: swarm-manifest; hash/length hard-coded to keccak256/32)
|
||||
@ -254,7 +260,7 @@ class EnsResolver {
|
||||
if (swarm && swarm[1].length === 64) {
|
||||
return `bzz:/\/${swarm[1]}`;
|
||||
}
|
||||
return (0, index_js_2.throwError)(`invalid or unsupported content hash data`, "UNSUPPORTED_OPERATION", {
|
||||
return (0, index_js_3.throwError)(`invalid or unsupported content hash data`, "UNSUPPORTED_OPERATION", {
|
||||
operation: "getContentHash()",
|
||||
info: { data: hexBytes }
|
||||
});
|
||||
@ -306,14 +312,13 @@ class EnsResolver {
|
||||
linkage.push({ type: `!${scheme}caip`, value: (match[2] || "") });
|
||||
throw new Error("!caip");
|
||||
}
|
||||
const formatter = (await this.provider.getNetwork()).formatter;
|
||||
const addr = formatter.address(comps[0]);
|
||||
const addr = (0, index_js_1.getAddress)(comps[0]);
|
||||
const tokenId = numPad(comps[1]);
|
||||
// Check that this account owns the token
|
||||
if (scheme === "erc721") {
|
||||
// ownerOf(uint256 tokenId)
|
||||
const tokenOwner = formatter.callAddress(await this.provider.call({
|
||||
to: addr, data: (0, index_js_2.concat)(["0x6352211e", tokenId])
|
||||
const tokenOwner = callAddress(await this.provider.call({
|
||||
to: addr, data: (0, index_js_3.concat)(["0x6352211e", tokenId])
|
||||
}));
|
||||
if (owner !== tokenOwner) {
|
||||
linkage.push({ type: "!owner", value: tokenOwner });
|
||||
@ -323,8 +328,8 @@ class EnsResolver {
|
||||
}
|
||||
else if (scheme === "erc1155") {
|
||||
// balanceOf(address owner, uint256 tokenId)
|
||||
const balance = (0, index_js_2.getBigInt)(await this.provider.call({
|
||||
to: addr, data: (0, index_js_2.concat)(["0x00fdd58e", (0, index_js_2.zeroPadValue)(owner, 32), tokenId])
|
||||
const balance = (0, index_js_3.getBigInt)(await this.provider.call({
|
||||
to: addr, data: (0, index_js_3.concat)(["0x00fdd58e", (0, index_js_3.zeroPadValue)(owner, 32), tokenId])
|
||||
}));
|
||||
if (!balance) {
|
||||
linkage.push({ type: "!balance", value: "0" });
|
||||
@ -335,7 +340,7 @@ class EnsResolver {
|
||||
// Call the token contract for the metadata URL
|
||||
const tx = {
|
||||
to: comps[0],
|
||||
data: (0, index_js_2.concat)([selector, tokenId])
|
||||
data: (0, index_js_3.concat)([selector, tokenId])
|
||||
};
|
||||
let metadataUrl = parseString(await this.provider.call(tx), 0);
|
||||
if (metadataUrl == null) {
|
||||
@ -345,7 +350,7 @@ class EnsResolver {
|
||||
linkage.push({ type: "metadata-url-base", value: metadataUrl });
|
||||
// ERC-1155 allows a generic {id} in the URL
|
||||
if (scheme === "erc1155") {
|
||||
metadataUrl = metadataUrl.replace("{id}", (0, index_js_2.hexlify)(tokenId).substring(2));
|
||||
metadataUrl = metadataUrl.replace("{id}", (0, index_js_3.hexlify)(tokenId).substring(2));
|
||||
linkage.push({ type: "metadata-url-expanded", value: metadataUrl });
|
||||
}
|
||||
// Transform IPFS metadata links
|
||||
@ -355,7 +360,7 @@ class EnsResolver {
|
||||
linkage.push({ type: "metadata-url", value: metadataUrl });
|
||||
// Get the token metadata
|
||||
let metadata = {};
|
||||
const response = await (new index_js_2.FetchRequest(metadataUrl)).send();
|
||||
const response = await (new index_js_3.FetchRequest(metadataUrl)).send();
|
||||
response.assertOk();
|
||||
try {
|
||||
metadata = response.bodyJson;
|
||||
@ -367,7 +372,7 @@ class EnsResolver {
|
||||
catch (error) {
|
||||
const bytes = response.body;
|
||||
if (bytes) {
|
||||
linkage.push({ type: "!metadata", value: (0, index_js_2.hexlify)(bytes) });
|
||||
linkage.push({ type: "!metadata", value: (0, index_js_3.hexlify)(bytes) });
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
@ -413,7 +418,7 @@ class EnsResolver {
|
||||
const ensPlugin = network.getPlugin("org.ethers.network-plugins.ens");
|
||||
// No ENS...
|
||||
if (!ensPlugin) {
|
||||
return (0, index_js_2.throwError)("network does not support ENS", "UNSUPPORTED_OPERATION", {
|
||||
return (0, index_js_3.throwError)("network does not support ENS", "UNSUPPORTED_OPERATION", {
|
||||
operation: "getResolver", info: { network: network.name }
|
||||
});
|
||||
}
|
||||
@ -421,11 +426,11 @@ class EnsResolver {
|
||||
// keccak256("resolver(bytes32)")
|
||||
const addrData = await provider.call({
|
||||
to: ensPlugin.address,
|
||||
data: (0, index_js_2.concat)(["0x0178b8bf", (0, index_js_1.namehash)(name)]),
|
||||
data: (0, index_js_3.concat)(["0x0178b8bf", (0, index_js_2.namehash)(name)]),
|
||||
enableCcipRead: true
|
||||
});
|
||||
const addr = network.formatter.callAddress(addrData);
|
||||
if (addr === (0, index_js_2.dataSlice)(hashes_js_1.ZeroHash, 0, 20)) {
|
||||
const addr = callAddress(addrData);
|
||||
if (addr === (0, index_js_3.dataSlice)(hashes_js_1.ZeroHash, 0, 20)) {
|
||||
return null;
|
||||
}
|
||||
return addr;
|
||||
|
File diff suppressed because one or more lines are too long
240
lib.commonjs/providers/format.js
Normal file
240
lib.commonjs/providers/format.js
Normal file
@ -0,0 +1,240 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.formatTransactionResponse = exports.formatTransactionReceipt = exports.formatReceiptLog = exports.formatBlockWithTransactions = exports.formatBlock = exports.formatLog = exports.formatUint256 = exports.formatHash = exports.formatData = exports.formatBoolean = exports.object = exports.arrayOf = exports.allowNull = void 0;
|
||||
const index_js_1 = require("../address/index.js");
|
||||
const index_js_2 = require("../transaction/index.js");
|
||||
const index_js_3 = require("../utils/index.js");
|
||||
const BN_0 = BigInt(0);
|
||||
function allowNull(format, nullValue) {
|
||||
return (function (value) {
|
||||
if (value == null) {
|
||||
return nullValue;
|
||||
}
|
||||
return format(value);
|
||||
});
|
||||
}
|
||||
exports.allowNull = allowNull;
|
||||
function arrayOf(format) {
|
||||
return ((array) => {
|
||||
if (!Array.isArray(array)) {
|
||||
throw new Error("not an array");
|
||||
}
|
||||
return array.map((i) => format(i));
|
||||
});
|
||||
}
|
||||
exports.arrayOf = arrayOf;
|
||||
// Requires an object which matches a fleet of other formatters
|
||||
// Any FormatFunc may return `undefined` to have the value omitted
|
||||
// from the result object. Calls preserve `this`.
|
||||
function object(format, altNames) {
|
||||
return ((value) => {
|
||||
const result = {};
|
||||
for (const key in format) {
|
||||
let srcKey = key;
|
||||
if (altNames && key in altNames && !(srcKey in value)) {
|
||||
for (const altKey of altNames[key]) {
|
||||
if (altKey in value) {
|
||||
srcKey = altKey;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
const nv = format[key](value[srcKey]);
|
||||
if (nv !== undefined) {
|
||||
result[key] = nv;
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
const message = (error instanceof Error) ? error.message : "not-an-error";
|
||||
(0, index_js_3.throwError)(`invalid value for value.${key} (${message})`, "BAD_DATA", { value });
|
||||
}
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
exports.object = object;
|
||||
function formatBoolean(value) {
|
||||
switch (value) {
|
||||
case true:
|
||||
case "true":
|
||||
return true;
|
||||
case false:
|
||||
case "false":
|
||||
return false;
|
||||
}
|
||||
return (0, index_js_3.throwArgumentError)(`invalid boolean; ${JSON.stringify(value)}`, "value", value);
|
||||
}
|
||||
exports.formatBoolean = formatBoolean;
|
||||
function formatData(value) {
|
||||
if (!(0, index_js_3.isHexString)(value, true)) {
|
||||
(0, index_js_3.throwArgumentError)("", "value", value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
exports.formatData = formatData;
|
||||
function formatHash(value) {
|
||||
if (!(0, index_js_3.isHexString)(value, 32)) {
|
||||
(0, index_js_3.throwArgumentError)("", "value", value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
exports.formatHash = formatHash;
|
||||
function formatUint256(value) {
|
||||
if (!(0, index_js_3.isHexString)(value)) {
|
||||
throw new Error("invalid uint256");
|
||||
}
|
||||
return (0, index_js_3.zeroPadValue)(value, 32);
|
||||
}
|
||||
exports.formatUint256 = formatUint256;
|
||||
exports.formatLog = object({
|
||||
address: index_js_1.getAddress,
|
||||
blockHash: formatHash,
|
||||
blockNumber: index_js_3.getNumber,
|
||||
data: formatData,
|
||||
index: index_js_3.getNumber,
|
||||
removed: formatBoolean,
|
||||
topics: arrayOf(formatHash),
|
||||
transactionHash: formatHash,
|
||||
transactionIndex: index_js_3.getNumber,
|
||||
}, {
|
||||
index: ["logIndex"]
|
||||
});
|
||||
function _formatBlock(txFunc) {
|
||||
return object({
|
||||
hash: allowNull(formatHash),
|
||||
parentHash: formatHash,
|
||||
number: index_js_3.getNumber,
|
||||
timestamp: index_js_3.getNumber,
|
||||
nonce: allowNull(formatData),
|
||||
difficulty: index_js_3.getBigInt,
|
||||
gasLimit: index_js_3.getBigInt,
|
||||
gasUsed: index_js_3.getBigInt,
|
||||
miner: allowNull(index_js_1.getAddress),
|
||||
extraData: formatData,
|
||||
transactions: arrayOf(txFunc),
|
||||
baseFeePerGas: allowNull(index_js_3.getBigInt)
|
||||
});
|
||||
}
|
||||
exports.formatBlock = _formatBlock(formatHash);
|
||||
exports.formatBlockWithTransactions = _formatBlock(formatTransactionResponse);
|
||||
exports.formatReceiptLog = object({
|
||||
transactionIndex: index_js_3.getNumber,
|
||||
blockNumber: index_js_3.getNumber,
|
||||
transactionHash: formatHash,
|
||||
address: index_js_1.getAddress,
|
||||
topics: arrayOf(formatHash),
|
||||
data: formatData,
|
||||
logIndex: index_js_3.getNumber,
|
||||
blockHash: formatHash,
|
||||
});
|
||||
exports.formatTransactionReceipt = object({
|
||||
to: allowNull(index_js_1.getAddress, null),
|
||||
from: allowNull(index_js_1.getAddress, null),
|
||||
contractAddress: allowNull(index_js_1.getAddress, null),
|
||||
transactionIndex: index_js_3.getNumber,
|
||||
// should be allowNull(hash), but broken-EIP-658 support is handled in receipt
|
||||
root: allowNull(index_js_3.hexlify),
|
||||
gasUsed: index_js_3.getBigInt,
|
||||
logsBloom: allowNull(formatData),
|
||||
blockHash: formatHash,
|
||||
transactionHash: formatHash,
|
||||
logs: arrayOf(exports.formatReceiptLog),
|
||||
blockNumber: index_js_3.getNumber,
|
||||
confirmations: allowNull(index_js_3.getNumber, null),
|
||||
cumulativeGasUsed: index_js_3.getBigInt,
|
||||
effectiveGasPrice: allowNull(index_js_3.getBigInt),
|
||||
status: allowNull(index_js_3.getNumber),
|
||||
type: index_js_3.getNumber
|
||||
}, {
|
||||
effectiveGasPrice: ["gasPrice"]
|
||||
});
|
||||
function formatTransactionResponse(value) {
|
||||
// Some clients (TestRPC) do strange things like return 0x0 for the
|
||||
// 0 address; correct this to be a real address
|
||||
if (value.to && (0, index_js_3.getBigInt)(value.to) === BN_0) {
|
||||
value.to = "0x0000000000000000000000000000000000000000";
|
||||
}
|
||||
const result = object({
|
||||
hash: formatHash,
|
||||
type: (value) => {
|
||||
if (value === "0x" || value == null) {
|
||||
return 0;
|
||||
}
|
||||
return (0, index_js_3.getNumber)(value);
|
||||
},
|
||||
accessList: allowNull(index_js_2.accessListify, null),
|
||||
blockHash: allowNull(formatHash, null),
|
||||
blockNumber: allowNull(index_js_3.getNumber, null),
|
||||
transactionIndex: allowNull(index_js_3.getNumber, null),
|
||||
confirmations: allowNull(index_js_3.getNumber, null),
|
||||
from: index_js_1.getAddress,
|
||||
// either (gasPrice) or (maxPriorityFeePerGas + maxFeePerGas) must be set
|
||||
gasPrice: allowNull(index_js_3.getBigInt),
|
||||
maxPriorityFeePerGas: allowNull(index_js_3.getBigInt),
|
||||
maxFeePerGas: allowNull(index_js_3.getBigInt),
|
||||
gasLimit: index_js_3.getBigInt,
|
||||
to: allowNull(index_js_1.getAddress, null),
|
||||
value: index_js_3.getBigInt,
|
||||
nonce: index_js_3.getNumber,
|
||||
data: formatData,
|
||||
r: allowNull(formatUint256),
|
||||
s: allowNull(formatUint256),
|
||||
v: allowNull(index_js_3.getNumber),
|
||||
creates: allowNull(index_js_1.getAddress, null),
|
||||
chainId: allowNull(index_js_3.getBigInt, null)
|
||||
}, {
|
||||
data: ["input"],
|
||||
gasLimit: ["gas"]
|
||||
})(value);
|
||||
// If to and creates are empty, populate the creates from the value
|
||||
if (result.to == null && result.creates == null) {
|
||||
result.creates = (0, index_js_1.getCreateAddress)(result);
|
||||
}
|
||||
// @TODO: Check fee data
|
||||
// Add an access list to supported transaction types
|
||||
if ((value.type === 1 || value.type === 2) && value.accessList == null) {
|
||||
value.accessList = [];
|
||||
}
|
||||
// @TODO: check chainID
|
||||
/*
|
||||
if (value.chainId != null) {
|
||||
let chainId = value.chainId;
|
||||
|
||||
if (isHexString(chainId)) {
|
||||
chainId = BigNumber.from(chainId).toNumber();
|
||||
}
|
||||
|
||||
result.chainId = chainId;
|
||||
|
||||
} else {
|
||||
let chainId = value.networkId;
|
||||
|
||||
// geth-etc returns chainId
|
||||
if (chainId == null && result.v == null) {
|
||||
chainId = value.chainId;
|
||||
}
|
||||
|
||||
if (isHexString(chainId)) {
|
||||
chainId = BigNumber.from(chainId).toNumber();
|
||||
}
|
||||
|
||||
if (typeof(chainId) !== "number" && result.v != null) {
|
||||
chainId = (result.v - 35) / 2;
|
||||
if (chainId < 0) { chainId = 0; }
|
||||
chainId = parseInt(chainId);
|
||||
}
|
||||
|
||||
if (typeof(chainId) !== "number") { chainId = 0; }
|
||||
|
||||
result.chainId = chainId;
|
||||
}
|
||||
*/
|
||||
// 0x0000... should actually be null
|
||||
if (result.blockHash && (0, index_js_3.getBigInt)(result.blockHash) === BN_0) {
|
||||
result.blockHash = null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
exports.formatTransactionResponse = formatTransactionResponse;
|
||||
//# sourceMappingURL=format.js.map
|
1
lib.commonjs/providers/format.js.map
Normal file
1
lib.commonjs/providers/format.js.map
Normal file
File diff suppressed because one or more lines are too long
@ -1,8 +1,6 @@
|
||||
"use strict";
|
||||
// Belongs to Networks; requires abstract-provider
|
||||
// provider requires abstract-provider and network
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Formatter = void 0;
|
||||
/**
|
||||
* Formatter
|
||||
*
|
||||
@ -16,26 +14,56 @@ exports.Formatter = void 0;
|
||||
* Network object this allows exotic (non-Ethereum) networks
|
||||
* to be fairly simple to adapt to ethers.
|
||||
*/
|
||||
const index_js_1 = require("../address/index.js");
|
||||
const index_js_2 = require("../utils/index.js");
|
||||
const signature_js_1 = require("../crypto/signature.js");
|
||||
const index_js_3 = require("../transaction/index.js");
|
||||
const provider_js_1 = require("./provider.js");
|
||||
/*
|
||||
import { getAddress, getCreateAddress } from "../address/index.js";
|
||||
import {
|
||||
dataLength, dataSlice, getBigInt, getNumber, isHexString, toQuantity,
|
||||
throwArgumentError, throwError
|
||||
} from "../utils/index.js";
|
||||
import { Signature } from "../crypto/signature.js";
|
||||
import { accessListify } from "../transaction/index.js";
|
||||
|
||||
import { Block, Log, TransactionReceipt, TransactionResponse } from "./provider.js";
|
||||
|
||||
import type { AccessList } from "../transaction/index.js";
|
||||
|
||||
import type { PerformActionTransaction } from "./abstract-provider.js";
|
||||
import type { Filter, Provider } from "./provider.js";
|
||||
|
||||
|
||||
const BN_MAX_UINT256 = BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
|
||||
|
||||
export type FormatFunc = (value: any) => any;
|
||||
|
||||
//export type AccessListSet = { address: string, storageKeys: Array<string> };
|
||||
//export type AccessList = Array<AccessListSet>;
|
||||
|
||||
//export type AccessListish = AccessList |
|
||||
// Array<[ string, Array<string> ]> |
|
||||
// Record<string, Array<string>>;
|
||||
function stringify(value) {
|
||||
if (typeof (value) !== "string") {
|
||||
throw new Error("invalid string");
|
||||
}
|
||||
|
||||
function stringify(value: any): string {
|
||||
if (typeof(value) !== "string") { throw new Error("invalid string"); }
|
||||
return value;
|
||||
}
|
||||
class Formatter {
|
||||
#format;
|
||||
#baseBlock;
|
||||
|
||||
export class Formatter {
|
||||
#format: {
|
||||
address: FormatFunc,
|
||||
bigNumber: FormatFunc,
|
||||
blockTag: FormatFunc,
|
||||
data: FormatFunc,
|
||||
filter: FormatFunc,
|
||||
hash: FormatFunc,
|
||||
number: FormatFunc,
|
||||
topics: FormatFunc,
|
||||
transactionRequest: FormatFunc,
|
||||
transactionResponse: FormatFunc,
|
||||
uint256: FormatFunc,
|
||||
};
|
||||
|
||||
#baseBlock: FormatFunc;
|
||||
|
||||
constructor() {
|
||||
const address = this.address.bind(this);
|
||||
const bigNumber = this.bigNumber.bind(this);
|
||||
@ -44,7 +72,9 @@ class Formatter {
|
||||
const hash = this.hash.bind(this);
|
||||
const number = this.number.bind(this);
|
||||
const uint256 = this.uint256.bind(this);
|
||||
|
||||
const topics = this.arrayOf(hash);
|
||||
|
||||
this.#format = {
|
||||
address,
|
||||
bigNumber,
|
||||
@ -53,7 +83,9 @@ class Formatter {
|
||||
hash,
|
||||
number,
|
||||
uint256,
|
||||
|
||||
topics,
|
||||
|
||||
filter: this.object({
|
||||
fromBlock: this.allowNull(blockTag, undefined),
|
||||
toBlock: this.allowNull(blockTag, undefined),
|
||||
@ -61,6 +93,7 @@ class Formatter {
|
||||
address: this.allowNull(address, undefined),
|
||||
topics: this.allowNull(topics, undefined)
|
||||
}),
|
||||
|
||||
transactionRequest: this.object({
|
||||
from: this.allowNull(address),
|
||||
type: this.allowNull(number),
|
||||
@ -73,21 +106,29 @@ class Formatter {
|
||||
data: this.allowNull(data),
|
||||
value: this.allowNull(uint256),
|
||||
}),
|
||||
|
||||
transactionResponse: this.object({
|
||||
hash: hash,
|
||||
index: number,
|
||||
|
||||
type: this.allowNull(number, 0),
|
||||
|
||||
// These can be null for pending blocks
|
||||
blockHash: this.allowNull(hash),
|
||||
blockNumber: this.allowNull(number),
|
||||
|
||||
// For Legacy transactions, this comes from the v
|
||||
chainId: this.allowNull(number),
|
||||
|
||||
from: address,
|
||||
to: this.address,
|
||||
|
||||
gasLimit: bigNumber,
|
||||
|
||||
gasPrice: this.allowNull(bigNumber),
|
||||
maxFeePerGas: this.allowNull(bigNumber),
|
||||
maxPriorityFeePerGas: this.allowNull(bigNumber),
|
||||
|
||||
value: bigNumber,
|
||||
data: data,
|
||||
nonce: number,
|
||||
@ -99,89 +140,99 @@ class Formatter {
|
||||
index: [ "transactionIndex" ]
|
||||
}),
|
||||
};
|
||||
|
||||
this.#baseBlock = this.object({
|
||||
number: number,
|
||||
hash: this.allowNull(hash, null),
|
||||
timestamp: number,
|
||||
|
||||
parentHash: hash,
|
||||
|
||||
nonce: this.allowNull(stringify, "0x0000000000000000"),
|
||||
difficulty: bigNumber,
|
||||
|
||||
gasLimit: bigNumber,
|
||||
gasUsed: bigNumber,
|
||||
miner: this.allowNull(address, "0x0000000000000000000000000000000000000000"),
|
||||
extraData: stringify,
|
||||
|
||||
baseFeePerGas: this.allowNull(bigNumber),
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// An address
|
||||
address(value) {
|
||||
return (0, index_js_1.getAddress)(value);
|
||||
address(value: any): string {
|
||||
return getAddress(value);
|
||||
}
|
||||
|
||||
// An address from a call result; may be zero-padded
|
||||
callAddress(value) {
|
||||
if ((0, index_js_2.dataLength)(value) !== 32 || (0, index_js_2.dataSlice)(value, 0, 12) !== "0x000000000000000000000000") {
|
||||
(0, index_js_2.throwArgumentError)("invalid call address", "value", value);
|
||||
callAddress(value: any): string {
|
||||
if (dataLength(value) !== 32 || dataSlice(value, 0, 12) !== "0x000000000000000000000000") {
|
||||
throwArgumentError("invalid call address", "value", value);
|
||||
}
|
||||
return this.address((0, index_js_2.dataSlice)(value, 12));
|
||||
return this.address(dataSlice(value, 12));
|
||||
}
|
||||
|
||||
// An address from a transaction (e.g. { from: string, nonce: number })
|
||||
contractAddress(value) {
|
||||
return (0, index_js_1.getCreateAddress)({
|
||||
contractAddress(value: any): string {
|
||||
return getCreateAddress({
|
||||
from: this.address(value.from),
|
||||
nonce: (0, index_js_2.getNumber)(value.nonce, "value.nonce")
|
||||
nonce: getNumber(value.nonce, "value.nonce")
|
||||
});
|
||||
}
|
||||
|
||||
// Block Tag
|
||||
blockTag(value) {
|
||||
if (value == null) {
|
||||
return "latest";
|
||||
}
|
||||
blockTag(value?: any): string {
|
||||
if (value == null) { return "latest"; }
|
||||
|
||||
switch (value) {
|
||||
case "earliest":
|
||||
return "0x0";
|
||||
case "latest":
|
||||
case "pending":
|
||||
case "safe":
|
||||
case "finalized":
|
||||
case "latest": case "pending": case "safe": case "finalized":
|
||||
return value;
|
||||
}
|
||||
if (typeof (value) === "number" || ((0, index_js_2.isHexString)(value) && (0, index_js_2.dataLength)(value) < 32)) {
|
||||
return (0, index_js_2.toQuantity)(value);
|
||||
|
||||
if (typeof(value) === "number" || (isHexString(value) && dataLength(value) < 32)) {
|
||||
return toQuantity(value);
|
||||
}
|
||||
return (0, index_js_2.throwArgumentError)("invalid blockTag", "value", value);
|
||||
|
||||
return throwArgumentError("invalid blockTag", "value", value);
|
||||
}
|
||||
|
||||
// Block objects
|
||||
block(value, provider) {
|
||||
block(value: any, provider?: Provider): Block<string> {
|
||||
const params = this.#baseBlock(value);
|
||||
params.transactions = value.transactions.map((t) => this.hash(t));
|
||||
return new provider_js_1.Block(params, provider);
|
||||
params.transactions = value.transactions.map((t: any) => this.hash(t));
|
||||
return new Block(params, provider);
|
||||
}
|
||||
blockWithTransactions(value, provider) {
|
||||
blockWithTransactions(value: any, provider?: Provider): Block<TransactionResponse> {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
// Transactions
|
||||
transactionRequest(value, provider) {
|
||||
transactionRequest(value: any, provider?: Provider): PerformActionTransaction {
|
||||
return this.#format.transactionRequest(value);
|
||||
}
|
||||
transactionResponse(value, provider) {
|
||||
|
||||
transactionResponse(value: any, provider?: Provider): TransactionResponse {
|
||||
value = Object.assign({ }, value);
|
||||
|
||||
// @TODO: Use the remap feature
|
||||
if (value.data == null && value.input != null) {
|
||||
value.data = value.input;
|
||||
}
|
||||
if (value.gasLimit == null && value.gas) {
|
||||
value.gasLimit = value.gas;
|
||||
}
|
||||
if (value.data == null && value.input != null) { value.data = value.input; }
|
||||
if (value.gasLimit == null && value.gas) { value.gasLimit = value.gas; }
|
||||
|
||||
value = this.#format.transactionResponse(value);
|
||||
const sig = signature_js_1.Signature.from({ r: value.r, s: value.s, v: value.v });
|
||||
|
||||
const sig = Signature.from({ r: value.r, s: value.s, v: value.v });
|
||||
value.signature = sig;
|
||||
if (value.chainId == null) {
|
||||
value.chainId = sig.legacyChainId;
|
||||
}
|
||||
return new provider_js_1.TransactionResponse(value, provider);
|
||||
if (value.chainId == null) { value.chainId = sig.legacyChainId; }
|
||||
|
||||
return new TransactionResponse(value, provider);
|
||||
}
|
||||
|
||||
// Receipts
|
||||
log(value, provider) {
|
||||
log(value: any, provider?: Provider): Log {
|
||||
const log = this.object({
|
||||
address: this.address,
|
||||
blockHash: this.hash,
|
||||
@ -195,9 +246,10 @@ class Formatter {
|
||||
}, {
|
||||
index: [ "logIndex" ]
|
||||
})(value);
|
||||
return new provider_js_1.Log(log, provider);
|
||||
return new Log(log, provider);
|
||||
}
|
||||
receipt(value, provider) {
|
||||
|
||||
receipt(value: any, provider?: Provider): TransactionReceipt {
|
||||
const receipt = this.object({
|
||||
blockHash: this.hash,
|
||||
blockNumber: this.number,
|
||||
@ -205,7 +257,7 @@ class Formatter {
|
||||
cumulativeGasUsed: this.bigNumber,
|
||||
from: this.address,
|
||||
gasUsed: this.bigNumber,
|
||||
logs: this.arrayOf((v) => (this.log(v, provider))),
|
||||
logs: this.arrayOf((v: any) => (this.log(v, provider))),
|
||||
logsBloom: this.data,
|
||||
root: this.allowNull(this.data),
|
||||
status: this.allowNull(this.number),
|
||||
@ -219,6 +271,7 @@ class Formatter {
|
||||
gasPrice: [ "effectiveGasPrice" ],
|
||||
index: [ "transactionIndex" ]
|
||||
})(value);
|
||||
|
||||
// RSK incorrectly implemented EIP-658, so we munge things a bit here for it
|
||||
if (receipt.root != null) {
|
||||
if (receipt.root.length <= 4) {
|
||||
@ -227,137 +280,144 @@ class Formatter {
|
||||
if (value === 0 || value === 1) {
|
||||
// Make sure if both are specified, they match
|
||||
if (receipt.status != null && receipt.status !== value) {
|
||||
return (0, index_js_2.throwError)("alt-root-status/status mismatch", "BAD_DATA", {
|
||||
return throwError("alt-root-status/status mismatch", "BAD_DATA", {
|
||||
value: { root: receipt.root, status: receipt.status }
|
||||
});
|
||||
}
|
||||
receipt.status = value;
|
||||
delete receipt.root;
|
||||
}
|
||||
else {
|
||||
return (0, index_js_2.throwError)("invalid alt-root-status", "BAD_DATA", {
|
||||
} else {
|
||||
return throwError("invalid alt-root-status", "BAD_DATA", {
|
||||
value: receipt.root
|
||||
});
|
||||
}
|
||||
}
|
||||
else if (!(0, index_js_2.isHexString)(receipt.root, 32)) {
|
||||
} else if (!isHexString(receipt.root, 32)) {
|
||||
// Must be a valid bytes32
|
||||
return (0, index_js_2.throwError)("invalid receipt root hash", "BAD_DATA", {
|
||||
return throwError("invalid receipt root hash", "BAD_DATA", {
|
||||
value: receipt.root
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//receipt.byzantium = (receipt.root == null);
|
||||
return new provider_js_1.TransactionReceipt(receipt, provider);
|
||||
|
||||
return new TransactionReceipt(receipt, provider);
|
||||
}
|
||||
|
||||
// Fitlers
|
||||
topics(value) {
|
||||
topics(value: any): Array<string> {
|
||||
return this.#format.topics(value);
|
||||
}
|
||||
filter(value) {
|
||||
|
||||
filter(value: any): Filter {
|
||||
return this.#format.filter(value);
|
||||
}
|
||||
filterLog(value) {
|
||||
|
||||
filterLog(value: any): any {
|
||||
console.log("ME", value);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Converts a serialized transaction to a TransactionResponse
|
||||
transaction(value) {
|
||||
transaction(value: any): TransactionResponse {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
// Useful utility formatters functions, which if need be use the
|
||||
// methods within the formatter to ensure internal compatibility
|
||||
|
||||
// Access List; converts an AccessListish to an AccessList
|
||||
accessList(value) {
|
||||
return (0, index_js_3.accessListify)(value);
|
||||
accessList(value: any): AccessList {
|
||||
return accessListify(value);
|
||||
}
|
||||
|
||||
// Converts falsish values to a specific value, otherwise use the formatter. Calls preserve `this`.
|
||||
allowFalsish(format, ifFalse) {
|
||||
return ((value) => {
|
||||
if (!value) {
|
||||
return ifFalse;
|
||||
}
|
||||
allowFalsish(format: FormatFunc, ifFalse: any): FormatFunc {
|
||||
return ((value: any) => {
|
||||
if (!value) { return ifFalse; }
|
||||
return format.call(this, value);
|
||||
});
|
||||
}
|
||||
|
||||
// Allows null, optionally replacing it with a default value. Calls preserve `this`.
|
||||
allowNull(format, ifNull) {
|
||||
return ((value) => {
|
||||
if (value == null) {
|
||||
return ifNull;
|
||||
}
|
||||
allowNull(format: FormatFunc, ifNull?: any): FormatFunc {
|
||||
return ((value: any) => {
|
||||
if (value == null) { return ifNull; }
|
||||
return format.call(this, value);
|
||||
});
|
||||
}
|
||||
|
||||
// Requires an Array satisfying the formatter. Calls preserves `this`.
|
||||
arrayOf(format) {
|
||||
return ((array) => {
|
||||
if (!Array.isArray(array)) {
|
||||
throw new Error("not an array");
|
||||
}
|
||||
arrayOf(format: FormatFunc): FormatFunc {
|
||||
return ((array: any) => {
|
||||
if (!Array.isArray(array)) { throw new Error("not an array"); }
|
||||
return array.map((i) => format.call(this, i));
|
||||
});
|
||||
}
|
||||
|
||||
// Requires a value which is a value BigNumber
|
||||
bigNumber(value) {
|
||||
return (0, index_js_2.getBigInt)(value, "value");
|
||||
bigNumber(value: any): bigint {
|
||||
return getBigInt(value, "value");
|
||||
}
|
||||
uint256(value) {
|
||||
|
||||
uint256(value: any): bigint {
|
||||
const result = this.bigNumber(value);
|
||||
if (result < 0 || result > BN_MAX_UINT256) {
|
||||
(0, index_js_2.throwArgumentError)("invalid uint256", "value", value);
|
||||
throwArgumentError("invalid uint256", "value", value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Requires a value which is a value boolean or string equivalent
|
||||
boolean(value) {
|
||||
boolean(value: any): boolean {
|
||||
switch (value) {
|
||||
case true:
|
||||
case "true":
|
||||
case true: case "true":
|
||||
return true;
|
||||
case false:
|
||||
case "false":
|
||||
case false: case "false":
|
||||
return false;
|
||||
}
|
||||
return (0, index_js_2.throwArgumentError)(`invalid boolean; ${JSON.stringify(value)}`, "value", value);
|
||||
return throwArgumentError(`invalid boolean; ${ JSON.stringify(value) }`, "value", value);
|
||||
}
|
||||
|
||||
// Requires a value which is a valid hexstring. If dataOrLength is true,
|
||||
// the length must be even (i.e. a datahexstring) or if it is a number,
|
||||
// specifies teh number of bytes value must represent
|
||||
_hexstring(dataOrLength) {
|
||||
if (dataOrLength == null) {
|
||||
dataOrLength = false;
|
||||
}
|
||||
return (function (value) {
|
||||
if ((0, index_js_2.isHexString)(value, dataOrLength)) {
|
||||
_hexstring(dataOrLength?: boolean | number): FormatFunc {
|
||||
if (dataOrLength == null) { dataOrLength = false; }
|
||||
return (function(value: any) {
|
||||
if (isHexString(value, dataOrLength)) {
|
||||
return value.toLowerCase();
|
||||
}
|
||||
throw new Error("bad hexstring");
|
||||
});
|
||||
}
|
||||
data(value) {
|
||||
if ((0, index_js_2.dataLength)(value) == null) {
|
||||
(0, index_js_2.throwArgumentError)("", "value", value);
|
||||
|
||||
data(value: string): string {
|
||||
if (dataLength(value) == null) {
|
||||
throwArgumentError("", "value", value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
// Requires a network-native hash
|
||||
hash(value) {
|
||||
if ((0, index_js_2.dataLength)(value) !== 32) {
|
||||
(0, index_js_2.throwArgumentError)("", "value", value);
|
||||
hash(value: any): string {
|
||||
if (dataLength(value) !== 32) {
|
||||
throwArgumentError("", "value", value);
|
||||
}
|
||||
return this.#format.data(value);
|
||||
}
|
||||
|
||||
// Requires a valid number, within the IEEE 754 safe range
|
||||
number(value) {
|
||||
return (0, index_js_2.getNumber)(value);
|
||||
number(value: any): number {
|
||||
return getNumber(value);
|
||||
}
|
||||
|
||||
// Requires an object which matches a fleet of other formatters
|
||||
// Any FormatFunc may return `undefined` to have the value omitted
|
||||
// from the result object. Calls preserve `this`.
|
||||
object(format, altNames) {
|
||||
return ((value) => {
|
||||
const result = {};
|
||||
object(format: Record<string, FormatFunc>, altNames?: Record<string, Array<string>>): FormatFunc {
|
||||
return ((value: any) => {
|
||||
const result: any = { };
|
||||
for (const key in format) {
|
||||
let srcKey = key;
|
||||
if (altNames && key in altNames && !(srcKey in value)) {
|
||||
@ -368,20 +428,18 @@ class Formatter {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const nv = format[key].call(this, value[srcKey]);
|
||||
if (nv !== undefined) {
|
||||
result[key] = nv;
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
if (nv !== undefined) { result[key] = nv; }
|
||||
} catch (error) {
|
||||
const message = (error instanceof Error) ? error.message: "not-an-error";
|
||||
(0, index_js_2.throwError)(`invalid value for value.${key} (${message})`, "BAD_DATA", { value });
|
||||
throwError(`invalid value for value.${ key } (${ message })`, "BAD_DATA", { value })
|
||||
}
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.Formatter = Formatter;
|
||||
*/
|
||||
//# sourceMappingURL=formatter.js.map
|
File diff suppressed because one or more lines are too long
@ -1,7 +1,7 @@
|
||||
"use strict";
|
||||
/////
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.SocketEventSubscriber = exports.SocketPendingSubscriber = exports.SocketBlockSubscriber = exports.SocketSubscriber = exports.WebSocketProvider = exports.SocketProvider = exports.IpcSocketProvider = exports.InfuraProvider = exports.EtherscanProvider = exports.CloudflareProvider = exports.AnkrProvider = exports.AlchemyProvider = exports.JsonRpcSigner = exports.JsonRpcProvider = exports.JsonRpcApiProvider = exports.FallbackProvider = exports.copyRequest = exports.dummyProvider = exports.TransactionResponse = exports.TransactionReceipt = exports.Log = exports.FeeData = exports.Block = exports.EnsPlugin = exports.GasCostPlugin = exports.NetworkPlugin = exports.Network = exports.Formatter = exports.WrappedSigner = exports.VoidSigner = exports.AbstractSigner = exports.UnmanagedSubscriber = exports.AbstractProvider = void 0;
|
||||
exports.SocketEventSubscriber = exports.SocketPendingSubscriber = exports.SocketBlockSubscriber = exports.SocketSubscriber = exports.WebSocketProvider = exports.SocketProvider = exports.IpcSocketProvider = exports.InfuraProvider = exports.EtherscanProvider = exports.EtherscanPlugin = exports.BaseEtherscanProvider = exports.CloudflareProvider = exports.AnkrProvider = exports.AlchemyProvider = exports.JsonRpcSigner = exports.JsonRpcProvider = exports.JsonRpcApiProvider = exports.FallbackProvider = exports.copyRequest = exports.TransactionResponse = exports.TransactionReceipt = exports.Log = exports.FeeData = exports.Block = exports.EnsPlugin = exports.GasCostPlugin = exports.NetworkPlugin = exports.Network = exports.WrappedSigner = exports.VoidSigner = exports.AbstractSigner = exports.UnmanagedSubscriber = exports.AbstractProvider = void 0;
|
||||
var abstract_provider_js_1 = require("./abstract-provider.js");
|
||||
Object.defineProperty(exports, "AbstractProvider", { enumerable: true, get: function () { return abstract_provider_js_1.AbstractProvider; } });
|
||||
Object.defineProperty(exports, "UnmanagedSubscriber", { enumerable: true, get: function () { return abstract_provider_js_1.UnmanagedSubscriber; } });
|
||||
@ -18,8 +18,6 @@ export { getDefaultProvider } from "./default-provider.js";
|
||||
|
||||
export { EnsResolver } from "./ens-resolver.js";
|
||||
*/
|
||||
var formatter_js_1 = require("./formatter.js");
|
||||
Object.defineProperty(exports, "Formatter", { enumerable: true, get: function () { return formatter_js_1.Formatter; } });
|
||||
var common_networks_js_1 = require("./common-networks.js");
|
||||
Object.defineProperty(exports, "Network", { enumerable: true, get: function () { return common_networks_js_1.Network; } });
|
||||
var plugins_network_js_1 = require("./plugins-network.js");
|
||||
@ -32,7 +30,6 @@ Object.defineProperty(exports, "FeeData", { enumerable: true, get: function () {
|
||||
Object.defineProperty(exports, "Log", { enumerable: true, get: function () { return provider_js_1.Log; } });
|
||||
Object.defineProperty(exports, "TransactionReceipt", { enumerable: true, get: function () { return provider_js_1.TransactionReceipt; } });
|
||||
Object.defineProperty(exports, "TransactionResponse", { enumerable: true, get: function () { return provider_js_1.TransactionResponse; } });
|
||||
Object.defineProperty(exports, "dummyProvider", { enumerable: true, get: function () { return provider_js_1.dummyProvider; } });
|
||||
Object.defineProperty(exports, "copyRequest", { enumerable: true, get: function () { return provider_js_1.copyRequest; } });
|
||||
var provider_fallback_js_1 = require("./provider-fallback.js");
|
||||
Object.defineProperty(exports, "FallbackProvider", { enumerable: true, get: function () { return provider_fallback_js_1.FallbackProvider; } });
|
||||
@ -46,6 +43,9 @@ var provider_ankr_js_1 = require("./provider-ankr.js");
|
||||
Object.defineProperty(exports, "AnkrProvider", { enumerable: true, get: function () { return provider_ankr_js_1.AnkrProvider; } });
|
||||
var provider_cloudflare_js_1 = require("./provider-cloudflare.js");
|
||||
Object.defineProperty(exports, "CloudflareProvider", { enumerable: true, get: function () { return provider_cloudflare_js_1.CloudflareProvider; } });
|
||||
var provider_etherscan_base_js_1 = require("./provider-etherscan-base.js");
|
||||
Object.defineProperty(exports, "BaseEtherscanProvider", { enumerable: true, get: function () { return provider_etherscan_base_js_1.BaseEtherscanProvider; } });
|
||||
Object.defineProperty(exports, "EtherscanPlugin", { enumerable: true, get: function () { return provider_etherscan_base_js_1.EtherscanPlugin; } });
|
||||
var provider_etherscan_js_1 = require("./provider-etherscan.js");
|
||||
Object.defineProperty(exports, "EtherscanProvider", { enumerable: true, get: function () { return provider_etherscan_js_1.EtherscanProvider; } });
|
||||
var provider_infura_js_1 = require("./provider-infura.js");
|
||||
|
@ -1 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src.ts/providers/index.ts"],"names":[],"mappings":";AAGA,KAAK;;;AAEL,+DAEgC;AAD5B,wHAAA,gBAAgB,OAAA;AAAE,2HAAA,mBAAmB,OAAA;AAGzC,2DAI8B;AAH1B,oHAAA,cAAc,OAAA;AACd,gHAAA,UAAU,OAAA;AACV,mHAAA,aAAa,OAAA;AAEjB;;;;;;;;EAQE;AAEF,+CAA2C;AAAlC,yGAAA,SAAS,OAAA;AAElB,2DAA+C;AAAtC,6GAAA,OAAO,OAAA;AAEhB,2DAO8B;AAN1B,mHAAA,aAAa,OAAA;AACb,mHAAA,aAAa,OAAA;AACb,+GAAA,SAAS,OAAA;AAMb,6CAWuB;AAVnB,oGAAA,KAAK,OAAA;AACL,sGAAA,OAAO,OAAA;AACP,kGAAA,GAAG,OAAA;AACH,iHAAA,kBAAkB,OAAA;AAClB,kHAAA,mBAAmB,OAAA;AAEnB,4GAAA,aAAa,OAAA;AAEb,0GAAA,WAAW,OAAA;AAIf,+DAA0D;AAAjD,wHAAA,gBAAgB,OAAA;AACzB,6DAA0F;AAAjF,yHAAA,kBAAkB,OAAA;AAAE,sHAAA,eAAe,OAAA;AAAE,oHAAA,aAAa,OAAA;AAE3D,6DAAwD;AAA/C,sHAAA,eAAe,OAAA;AACxB,uDAAkD;AAAzC,gHAAA,YAAY,OAAA;AACrB,mEAA8D;AAArD,4HAAA,kBAAkB,OAAA;AAC3B,iEAA4D;AAAnD,0HAAA,iBAAiB,OAAA;AAC1B,2DAAsD;AAA7C,oHAAA,cAAc,OAAA;AACvB,wDAAwD;AAExD,mEAA4D,CAAC,YAAY;AAChE,kGADA,yCAAiB,OACA;AAC1B,2DAAsD;AAA7C,oHAAA,cAAc,OAAA;AACvB,iEAA4D;AAAnD,0HAAA,iBAAiB,OAAA;AAE1B,2DAG8B;AAF1B,sHAAA,gBAAgB,OAAA;AAAE,2HAAA,qBAAqB,OAAA;AAAE,6HAAA,uBAAuB,OAAA;AAChE,2HAAA,qBAAqB,OAAA"}
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src.ts/providers/index.ts"],"names":[],"mappings":";AAGA,KAAK;;;AAEL,+DAEgC;AAD5B,wHAAA,gBAAgB,OAAA;AAAE,2HAAA,mBAAmB,OAAA;AAGzC,2DAI8B;AAH1B,oHAAA,cAAc,OAAA;AACd,gHAAA,UAAU,OAAA;AACV,mHAAA,aAAa,OAAA;AAEjB;;;;;;;;EAQE;AAEF,2DAA+C;AAAtC,6GAAA,OAAO,OAAA;AAEhB,2DAO8B;AAN1B,mHAAA,aAAa,OAAA;AACb,mHAAA,aAAa,OAAA;AACb,+GAAA,SAAS,OAAA;AAMb,6CASuB;AARnB,oGAAA,KAAK,OAAA;AACL,sGAAA,OAAO,OAAA;AACP,kGAAA,GAAG,OAAA;AACH,iHAAA,kBAAkB,OAAA;AAClB,kHAAA,mBAAmB,OAAA;AAEnB,0GAAA,WAAW,OAAA;AAIf,+DAA0D;AAAjD,wHAAA,gBAAgB,OAAA;AACzB,6DAA0F;AAAjF,yHAAA,kBAAkB,OAAA;AAAE,sHAAA,eAAe,OAAA;AAAE,oHAAA,aAAa,OAAA;AAE3D,6DAAwD;AAA/C,sHAAA,eAAe,OAAA;AACxB,uDAAkD;AAAzC,gHAAA,YAAY,OAAA;AACrB,mEAA8D;AAArD,4HAAA,kBAAkB,OAAA;AAC3B,2EAAsF;AAA7E,mIAAA,qBAAqB,OAAA;AAAE,6HAAA,eAAe,OAAA;AAC/C,iEAA4D;AAAnD,0HAAA,iBAAiB,OAAA;AAC1B,2DAAsD;AAA7C,oHAAA,cAAc,OAAA;AACvB,wDAAwD;AAExD,mEAA4D,CAAC,YAAY;AAChE,kGADA,yCAAiB,OACA;AAC1B,2DAAsD;AAA7C,oHAAA,cAAc,OAAA;AACvB,iEAA4D;AAAnD,0HAAA,iBAAiB,OAAA;AAE1B,2DAG8B;AAF1B,sHAAA,gBAAgB,OAAA;AAAE,2HAAA,qBAAqB,OAAA;AAAE,6HAAA,uBAAuB,OAAA;AAChE,2HAAA,qBAAqB,OAAA"}
|
@ -1,8 +1,8 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Network = void 0;
|
||||
const index_js_1 = require("../utils/index.js");
|
||||
const formatter_js_1 = require("./formatter.js");
|
||||
const index_js_1 = require("../transaction/index.js");
|
||||
const index_js_2 = require("../utils/index.js");
|
||||
const plugins_network_js_1 = require("./plugins-network.js");
|
||||
/* * * *
|
||||
// Networks which operation against an L2 can use this plugin to
|
||||
@ -55,37 +55,29 @@ export class CcipPreflightPlugin extends NetworkPlugin {
|
||||
}
|
||||
*/
|
||||
const Networks = new Map();
|
||||
const defaultFormatter = new formatter_js_1.Formatter();
|
||||
// @TODO: Add a _ethersNetworkObj variable to better detect network ovjects
|
||||
class Network {
|
||||
#props;
|
||||
constructor(name, _chainId, formatter) {
|
||||
const chainId = (0, index_js_1.getBigInt)(_chainId);
|
||||
if (formatter == null) {
|
||||
formatter = defaultFormatter;
|
||||
}
|
||||
constructor(name, _chainId) {
|
||||
const chainId = (0, index_js_2.getBigInt)(_chainId);
|
||||
const plugins = new Map();
|
||||
this.#props = { name, chainId, formatter, plugins };
|
||||
this.#props = { name, chainId, plugins };
|
||||
}
|
||||
toJSON() {
|
||||
return { name: this.name, chainId: this.chainId };
|
||||
}
|
||||
get name() { return (0, index_js_1.getStore)(this.#props, "name"); }
|
||||
set name(value) { (0, index_js_1.setStore)(this.#props, "name", value); }
|
||||
get chainId() { return (0, index_js_1.getStore)(this.#props, "chainId"); }
|
||||
set chainId(value) { (0, index_js_1.setStore)(this.#props, "chainId", (0, index_js_1.getBigInt)(value, "chainId")); }
|
||||
get formatter() { return (0, index_js_1.getStore)(this.#props, "formatter"); }
|
||||
set formatter(value) { (0, index_js_1.setStore)(this.#props, "formatter", value); }
|
||||
get name() { return (0, index_js_2.getStore)(this.#props, "name"); }
|
||||
set name(value) { (0, index_js_2.setStore)(this.#props, "name", value); }
|
||||
get chainId() { return (0, index_js_2.getStore)(this.#props, "chainId"); }
|
||||
set chainId(value) { (0, index_js_2.setStore)(this.#props, "chainId", (0, index_js_2.getBigInt)(value, "chainId")); }
|
||||
get plugins() {
|
||||
return Array.from(this.#props.plugins.values());
|
||||
}
|
||||
attachPlugin(plugin) {
|
||||
if (this.isFrozen()) {
|
||||
throw new Error("frozen");
|
||||
}
|
||||
if (this.#props.plugins.get(plugin.name)) {
|
||||
throw new Error(`cannot replace existing plugin: ${plugin.name} `);
|
||||
}
|
||||
this.#props.plugins.set(plugin.name, plugin.validate(this));
|
||||
this.#props.plugins.set(plugin.name, plugin.clone());
|
||||
return this;
|
||||
}
|
||||
getPlugin(name) {
|
||||
@ -96,19 +88,22 @@ class Network {
|
||||
return (this.plugins.filter((p) => (p.name.split("#")[0] === basename)));
|
||||
}
|
||||
clone() {
|
||||
const clone = new Network(this.name, this.chainId, this.formatter);
|
||||
const clone = new Network(this.name, this.chainId);
|
||||
this.plugins.forEach((plugin) => {
|
||||
clone.attachPlugin(plugin.clone());
|
||||
});
|
||||
return clone;
|
||||
}
|
||||
freeze() {
|
||||
/*
|
||||
freeze(): Frozen<Network> {
|
||||
Object.freeze(this.#props);
|
||||
return this;
|
||||
}
|
||||
isFrozen() {
|
||||
|
||||
isFrozen(): boolean {
|
||||
return Object.isFrozen(this.#props);
|
||||
}
|
||||
*/
|
||||
computeIntrinsicGas(tx) {
|
||||
const costs = this.getPlugin("org.ethers.gas-cost") || (new plugins_network_js_1.GasCostPlugin());
|
||||
let gas = costs.txBase;
|
||||
@ -126,7 +121,7 @@ class Network {
|
||||
}
|
||||
}
|
||||
if (tx.accessList) {
|
||||
const accessList = this.formatter.accessList(tx.accessList);
|
||||
const accessList = (0, index_js_1.accessListify)(tx.accessList);
|
||||
for (const addr in accessList) {
|
||||
gas += costs.txAccessListAddress + costs.txAccessListStorageKey * accessList[addr].storageKeys.length;
|
||||
}
|
||||
@ -153,7 +148,7 @@ class Network {
|
||||
if (typeof (network) === "bigint") {
|
||||
return new Network("unknown", network);
|
||||
}
|
||||
(0, index_js_1.throwArgumentError)("unknown network", "network", network);
|
||||
(0, index_js_2.throwArgumentError)("unknown network", "network", network);
|
||||
}
|
||||
// Clonable with network-like abilities
|
||||
if (typeof (network.clone) === "function") {
|
||||
@ -165,7 +160,7 @@ class Network {
|
||||
// Networkish
|
||||
if (typeof (network) === "object") {
|
||||
if (typeof (network.name) !== "string" || typeof (network.chainId) !== "number") {
|
||||
(0, index_js_1.throwArgumentError)("invalid network object name or chainId", "network", network);
|
||||
(0, index_js_2.throwArgumentError)("invalid network object name or chainId", "network", network);
|
||||
}
|
||||
const custom = new Network((network.name), (network.chainId));
|
||||
if (network.ensAddress || network.ensNetwork != null) {
|
||||
@ -176,7 +171,7 @@ class Network {
|
||||
//}
|
||||
return custom;
|
||||
}
|
||||
return (0, index_js_1.throwArgumentError)("invalid network", "network", network);
|
||||
return (0, index_js_2.throwArgumentError)("invalid network", "network", network);
|
||||
}
|
||||
/**
|
||||
* Register %%nameOrChainId%% with a function which returns
|
||||
@ -188,7 +183,7 @@ class Network {
|
||||
}
|
||||
const existing = Networks.get(nameOrChainId);
|
||||
if (existing) {
|
||||
(0, index_js_1.throwArgumentError)(`conflicting network for ${JSON.stringify(existing.name)}`, "nameOrChainId", nameOrChainId);
|
||||
(0, index_js_2.throwArgumentError)(`conflicting network for ${JSON.stringify(existing.name)}`, "nameOrChainId", nameOrChainId);
|
||||
}
|
||||
Networks.set(nameOrChainId, networkFunc);
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
@ -1,6 +1,6 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.FeeDataNetworkPlugin = exports.EnsPlugin = exports.GasCostPlugin = exports.NetworkPlugin = void 0;
|
||||
exports.CustomBlockNetworkPlugin = exports.FeeDataNetworkPlugin = exports.EnsPlugin = exports.GasCostPlugin = exports.NetworkPlugin = void 0;
|
||||
const properties_js_1 = require("../utils/properties.js");
|
||||
const index_js_1 = require("../utils/index.js");
|
||||
const EnsAddress = "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e";
|
||||
@ -12,9 +12,6 @@ class NetworkPlugin {
|
||||
clone() {
|
||||
return new NetworkPlugin(this.name);
|
||||
}
|
||||
validate(network) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
exports.NetworkPlugin = NetworkPlugin;
|
||||
class GasCostPlugin extends NetworkPlugin {
|
||||
@ -68,10 +65,6 @@ class EnsPlugin extends NetworkPlugin {
|
||||
clone() {
|
||||
return new EnsPlugin(this.address, this.targetNetwork);
|
||||
}
|
||||
validate(network) {
|
||||
network.formatter.address(this.address);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
exports.EnsPlugin = EnsPlugin;
|
||||
/*
|
||||
@ -109,4 +102,23 @@ class FeeDataNetworkPlugin extends NetworkPlugin {
|
||||
}
|
||||
}
|
||||
exports.FeeDataNetworkPlugin = FeeDataNetworkPlugin;
|
||||
class CustomBlockNetworkPlugin extends NetworkPlugin {
|
||||
#blockFunc;
|
||||
#blockWithTxsFunc;
|
||||
constructor(blockFunc, blockWithTxsFunc) {
|
||||
super("org.ethers.network-plugins.custom-block");
|
||||
this.#blockFunc = blockFunc;
|
||||
this.#blockWithTxsFunc = blockWithTxsFunc;
|
||||
}
|
||||
async getBlock(provider, block) {
|
||||
return await this.#blockFunc(provider, block);
|
||||
}
|
||||
async getBlockWithTransactions(provider, block) {
|
||||
return await this.#blockWithTxsFunc(provider, block);
|
||||
}
|
||||
clone() {
|
||||
return new CustomBlockNetworkPlugin(this.#blockFunc, this.#blockWithTxsFunc);
|
||||
}
|
||||
}
|
||||
exports.CustomBlockNetworkPlugin = CustomBlockNetworkPlugin;
|
||||
//# sourceMappingURL=plugins-network.js.map
|
@ -1 +1 @@
|
||||
{"version":3,"file":"plugins-network.js","sourceRoot":"","sources":["../../src.ts/providers/plugins-network.ts"],"names":[],"mappings":"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"}
|
||||
{"version":3,"file":"plugins-network.js","sourceRoot":"","sources":["../../src.ts/providers/plugins-network.ts"],"names":[],"mappings":"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"}
|
432
lib.commonjs/providers/provider-etherscan-base.js
Normal file
432
lib.commonjs/providers/provider-etherscan-base.js
Normal file
@ -0,0 +1,432 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.BaseEtherscanProvider = exports.EtherscanPlugin = void 0;
|
||||
const index_js_1 = require("../transaction/index.js");
|
||||
const index_js_2 = require("../utils/index.js");
|
||||
const abstract_provider_js_1 = require("./abstract-provider.js");
|
||||
const network_js_1 = require("./network.js");
|
||||
const plugins_network_js_1 = require("./plugins-network.js");
|
||||
const community_js_1 = require("./community.js");
|
||||
const THROTTLE = 2000;
|
||||
const EtherscanPluginId = "org.ethers.plugins.etherscan";
|
||||
class EtherscanPlugin extends plugins_network_js_1.NetworkPlugin {
|
||||
baseUrl;
|
||||
communityApiKey;
|
||||
constructor(baseUrl, communityApiKey) {
|
||||
super(EtherscanPluginId);
|
||||
//if (communityApiKey == null) { communityApiKey = null; }
|
||||
(0, index_js_2.defineProperties)(this, { baseUrl, communityApiKey });
|
||||
}
|
||||
clone() {
|
||||
return new EtherscanPlugin(this.baseUrl, this.communityApiKey);
|
||||
}
|
||||
}
|
||||
exports.EtherscanPlugin = EtherscanPlugin;
|
||||
let nextId = 1;
|
||||
class BaseEtherscanProvider extends abstract_provider_js_1.AbstractProvider {
|
||||
network;
|
||||
apiKey;
|
||||
#plugin;
|
||||
constructor(_network, apiKey) {
|
||||
super();
|
||||
const network = network_js_1.Network.from(_network);
|
||||
this.#plugin = network.getPlugin(EtherscanPluginId);
|
||||
if (apiKey == null && this.#plugin) {
|
||||
apiKey = this.#plugin.communityApiKey;
|
||||
}
|
||||
(0, index_js_2.defineProperties)(this, { apiKey, network });
|
||||
// Test that the network is supported by Etherscan
|
||||
this.getBaseUrl();
|
||||
}
|
||||
getBaseUrl() {
|
||||
if (this.#plugin) {
|
||||
return this.#plugin.baseUrl;
|
||||
}
|
||||
switch (this.network.name) {
|
||||
case "homestead":
|
||||
return "https:/\/api.etherscan.io";
|
||||
case "ropsten":
|
||||
return "https:/\/api-ropsten.etherscan.io";
|
||||
case "rinkeby":
|
||||
return "https:/\/api-rinkeby.etherscan.io";
|
||||
case "kovan":
|
||||
return "https:/\/api-kovan.etherscan.io";
|
||||
case "goerli":
|
||||
return "https:/\/api-goerli.etherscan.io";
|
||||
default:
|
||||
}
|
||||
return (0, index_js_2.throwArgumentError)("unsupported network", "network", this.network);
|
||||
}
|
||||
getUrl(module, params) {
|
||||
const query = Object.keys(params).reduce((accum, key) => {
|
||||
const value = params[key];
|
||||
if (value != null) {
|
||||
accum += `&${key}=${value}`;
|
||||
}
|
||||
return accum;
|
||||
}, "");
|
||||
const apiKey = ((this.apiKey) ? `&apikey=${this.apiKey}` : "");
|
||||
return `${this.getBaseUrl()}/api?module=${module}${query}${apiKey}`;
|
||||
}
|
||||
getPostUrl() {
|
||||
return `${this.getBaseUrl()}/api`;
|
||||
}
|
||||
getPostData(module, params) {
|
||||
params.module = module;
|
||||
params.apikey = this.apiKey;
|
||||
return params;
|
||||
}
|
||||
async detectNetwork() {
|
||||
return this.network;
|
||||
}
|
||||
async fetch(module, params, post) {
|
||||
const id = nextId++;
|
||||
const url = (post ? this.getPostUrl() : this.getUrl(module, params));
|
||||
const payload = (post ? this.getPostData(module, params) : null);
|
||||
this.emit("debug", { action: "sendRequest", id, url, payload: payload });
|
||||
const request = new index_js_2.FetchRequest(url);
|
||||
request.setThrottleParams({ slotInterval: 1000 });
|
||||
request.retryFunc = (req, resp, attempt) => {
|
||||
if (this.isCommunityResource()) {
|
||||
(0, community_js_1.showThrottleMessage)("Etherscan");
|
||||
}
|
||||
return Promise.resolve(true);
|
||||
};
|
||||
request.processFunc = async (request, response) => {
|
||||
const result = response.hasBody() ? JSON.parse((0, index_js_2.toUtf8String)(response.body)) : {};
|
||||
const throttle = ((typeof (result.result) === "string") ? result.result : "").toLowerCase().indexOf("rate limit") >= 0;
|
||||
if (module === "proxy") {
|
||||
// This JSON response indicates we are being throttled
|
||||
if (result && result.status == 0 && result.message == "NOTOK" && throttle) {
|
||||
this.emit("debug", { action: "receiveError", id, reason: "proxy-NOTOK", error: result });
|
||||
response.throwThrottleError(result.result, THROTTLE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (throttle) {
|
||||
this.emit("debug", { action: "receiveError", id, reason: "null result", error: result.result });
|
||||
response.throwThrottleError(result.result, THROTTLE);
|
||||
}
|
||||
}
|
||||
return response;
|
||||
};
|
||||
if (payload) {
|
||||
request.setHeader("content-type", "application/x-www-form-urlencoded; charset=UTF-8");
|
||||
request.body = Object.keys(payload).map((k) => `${k}=${payload[k]}`).join("&");
|
||||
}
|
||||
const response = await request.send();
|
||||
try {
|
||||
response.assertOk();
|
||||
}
|
||||
catch (error) {
|
||||
this.emit("debug", { action: "receiveError", id, error, reason: "assertOk" });
|
||||
}
|
||||
if (!response.hasBody()) {
|
||||
this.emit("debug", { action: "receiveError", id, error: "missing body", reason: "null body" });
|
||||
throw new Error();
|
||||
}
|
||||
const result = JSON.parse((0, index_js_2.toUtf8String)(response.body));
|
||||
if (module === "proxy") {
|
||||
if (result.jsonrpc != "2.0") {
|
||||
this.emit("debug", { action: "receiveError", id, result, reason: "invalid JSON-RPC" });
|
||||
const error = new Error("invalid response");
|
||||
error.result = JSON.stringify(result);
|
||||
throw error;
|
||||
}
|
||||
if (result.error) {
|
||||
this.emit("debug", { action: "receiveError", id, result, reason: "JSON-RPC error" });
|
||||
const error = new Error(result.error.message || "unknown error");
|
||||
if (result.error.code) {
|
||||
error.code = result.error.code;
|
||||
}
|
||||
if (result.error.data) {
|
||||
error.data = result.error.data;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
this.emit("debug", { action: "receiveRequest", id, result });
|
||||
return result.result;
|
||||
}
|
||||
else {
|
||||
// getLogs, getHistory have weird success responses
|
||||
if (result.status == 0 && (result.message === "No records found" || result.message === "No transactions found")) {
|
||||
this.emit("debug", { action: "receiveRequest", id, result });
|
||||
return result.result;
|
||||
}
|
||||
if (result.status != 1 || (typeof (result.message) === "string" && !result.message.match(/^OK/))) {
|
||||
this.emit("debug", { action: "receiveError", id, result });
|
||||
const error = new Error("invalid response");
|
||||
error.result = JSON.stringify(result);
|
||||
// if ((result.result || "").toLowerCase().indexOf("rate limit") >= 0) {
|
||||
// error.throttleRetry = true;
|
||||
// }
|
||||
throw error;
|
||||
}
|
||||
this.emit("debug", { action: "receiveRequest", id, result });
|
||||
return result.result;
|
||||
}
|
||||
}
|
||||
// The transaction has already been sanitized by the calls in Provider
|
||||
_getTransactionPostData(transaction) {
|
||||
const result = {};
|
||||
for (let key in transaction) {
|
||||
if (transaction[key] == null) {
|
||||
continue;
|
||||
}
|
||||
let value = transaction[key];
|
||||
if (key === "type" && value === 0) {
|
||||
continue;
|
||||
}
|
||||
// Quantity-types require no leading zero, unless 0
|
||||
if ({ type: true, gasLimit: true, gasPrice: true, maxFeePerGs: true, maxPriorityFeePerGas: true, nonce: true, value: true }[key]) {
|
||||
value = (0, index_js_2.toQuantity)((0, index_js_2.hexlify)(value));
|
||||
}
|
||||
else if (key === "accessList") {
|
||||
value = "[" + (0, index_js_1.accessListify)(value).map((set) => {
|
||||
return `{address:"${set.address}",storageKeys:["${set.storageKeys.join('","')}"]}`;
|
||||
}).join(",") + "]";
|
||||
}
|
||||
else {
|
||||
value = (0, index_js_2.hexlify)(value);
|
||||
}
|
||||
result[key] = value;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
_checkError(req, error, transaction) {
|
||||
/*
|
||||
let body = "";
|
||||
if (isError(error, Logger.Errors.SERVER_ERROR) && error.response && error.response.hasBody()) {
|
||||
body = toUtf8String(error.response.body);
|
||||
}
|
||||
console.log(body);
|
||||
|
||||
// Undo the "convenience" some nodes are attempting to prevent backwards
|
||||
// incompatibility; maybe for v6 consider forwarding reverts as errors
|
||||
if (method === "call" && body) {
|
||||
|
||||
// Etherscan keeps changing their string
|
||||
if (body.match(/reverted/i) || body.match(/VM execution error/i)) {
|
||||
|
||||
// Etherscan prefixes the data like "Reverted 0x1234"
|
||||
let data = e.data;
|
||||
if (data) { data = "0x" + data.replace(/^.*0x/i, ""); }
|
||||
if (!isHexString(data)) { data = "0x"; }
|
||||
|
||||
logger.throwError("call exception", Logger.Errors.CALL_EXCEPTION, {
|
||||
error, data
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Get the message from any nested error structure
|
||||
let message = error.message;
|
||||
if (isError(error, Logger.Errors.SERVER_ERROR)) {
|
||||
if (error.error && typeof(error.error.message) === "string") {
|
||||
message = error.error.message;
|
||||
} else if (typeof(error.body) === "string") {
|
||||
message = error.body;
|
||||
} else if (typeof(error.responseText) === "string") {
|
||||
message = error.responseText;
|
||||
}
|
||||
}
|
||||
message = (message || "").toLowerCase();
|
||||
|
||||
// "Insufficient funds. The account you tried to send transaction from
|
||||
// does not have enough funds. Required 21464000000000 and got: 0"
|
||||
if (message.match(/insufficient funds/)) {
|
||||
logger.throwError("insufficient funds for intrinsic transaction cost", Logger.Errors.INSUFFICIENT_FUNDS, {
|
||||
error, transaction, info: { method }
|
||||
});
|
||||
}
|
||||
|
||||
// "Transaction with the same hash was already imported."
|
||||
if (message.match(/same hash was already imported|transaction nonce is too low|nonce too low/)) {
|
||||
logger.throwError("nonce has already been used", Logger.Errors.NONCE_EXPIRED, {
|
||||
error, transaction, info: { method }
|
||||
});
|
||||
}
|
||||
|
||||
// "Transaction gas price is too low. There is another transaction with
|
||||
// same nonce in the queue. Try increasing the gas price or incrementing the nonce."
|
||||
if (message.match(/another transaction with same nonce/)) {
|
||||
logger.throwError("replacement fee too low", Logger.Errors.REPLACEMENT_UNDERPRICED, {
|
||||
error, transaction, info: { method }
|
||||
});
|
||||
}
|
||||
|
||||
if (message.match(/execution failed due to an exception|execution reverted/)) {
|
||||
logger.throwError("cannot estimate gas; transaction may fail or may require manual gas limit", Logger.Errors.UNPREDICTABLE_GAS_LIMIT, {
|
||||
error, transaction, info: { method }
|
||||
});
|
||||
}
|
||||
*/
|
||||
throw error;
|
||||
}
|
||||
async _detectNetwork() {
|
||||
return this.network;
|
||||
}
|
||||
async _perform(req) {
|
||||
switch (req.method) {
|
||||
case "chainId":
|
||||
return this.network.chainId;
|
||||
case "getBlockNumber":
|
||||
return this.fetch("proxy", { action: "eth_blockNumber" });
|
||||
case "getGasPrice":
|
||||
return this.fetch("proxy", { action: "eth_gasPrice" });
|
||||
case "getBalance":
|
||||
// Returns base-10 result
|
||||
return this.fetch("account", {
|
||||
action: "balance",
|
||||
address: req.address,
|
||||
tag: req.blockTag
|
||||
});
|
||||
case "getTransactionCount":
|
||||
return this.fetch("proxy", {
|
||||
action: "eth_getTransactionCount",
|
||||
address: req.address,
|
||||
tag: req.blockTag
|
||||
});
|
||||
case "getCode":
|
||||
return this.fetch("proxy", {
|
||||
action: "eth_getCode",
|
||||
address: req.address,
|
||||
tag: req.blockTag
|
||||
});
|
||||
case "getStorageAt":
|
||||
return this.fetch("proxy", {
|
||||
action: "eth_getStorageAt",
|
||||
address: req.address,
|
||||
position: req.position,
|
||||
tag: req.blockTag
|
||||
});
|
||||
case "broadcastTransaction":
|
||||
return this.fetch("proxy", {
|
||||
action: "eth_sendRawTransaction",
|
||||
hex: req.signedTransaction
|
||||
}, true).catch((error) => {
|
||||
return this._checkError(req, error, req.signedTransaction);
|
||||
});
|
||||
case "getBlock":
|
||||
if ("blockTag" in req) {
|
||||
return this.fetch("proxy", {
|
||||
action: "eth_getBlockByNumber",
|
||||
tag: req.blockTag,
|
||||
boolean: (req.includeTransactions ? "true" : "false")
|
||||
});
|
||||
}
|
||||
return (0, index_js_2.throwError)("getBlock by blockHash not supported by Etherscan", "UNSUPPORTED_OPERATION", {
|
||||
operation: "getBlock(blockHash)"
|
||||
});
|
||||
case "getTransaction":
|
||||
return this.fetch("proxy", {
|
||||
action: "eth_getTransactionByHash",
|
||||
txhash: req.hash
|
||||
});
|
||||
case "getTransactionReceipt":
|
||||
return this.fetch("proxy", {
|
||||
action: "eth_getTransactionReceipt",
|
||||
txhash: req.hash
|
||||
});
|
||||
case "call": {
|
||||
if (req.blockTag !== "latest") {
|
||||
throw new Error("EtherscanProvider does not support blockTag for call");
|
||||
}
|
||||
const postData = this._getTransactionPostData(req.transaction);
|
||||
postData.module = "proxy";
|
||||
postData.action = "eth_call";
|
||||
try {
|
||||
return await this.fetch("proxy", postData, true);
|
||||
}
|
||||
catch (error) {
|
||||
return this._checkError(req, error, req.transaction);
|
||||
}
|
||||
}
|
||||
case "estimateGas": {
|
||||
const postData = this._getTransactionPostData(req.transaction);
|
||||
postData.module = "proxy";
|
||||
postData.action = "eth_estimateGas";
|
||||
try {
|
||||
return await this.fetch("proxy", postData, true);
|
||||
}
|
||||
catch (error) {
|
||||
return this._checkError(req, error, req.transaction);
|
||||
}
|
||||
}
|
||||
/*
|
||||
case "getLogs": {
|
||||
// Needs to complain if more than one address is passed in
|
||||
const args: Record<string, any> = { action: "getLogs" }
|
||||
|
||||
if (params.filter.fromBlock) {
|
||||
args.fromBlock = checkLogTag(params.filter.fromBlock);
|
||||
}
|
||||
|
||||
if (params.filter.toBlock) {
|
||||
args.toBlock = checkLogTag(params.filter.toBlock);
|
||||
}
|
||||
|
||||
if (params.filter.address) {
|
||||
args.address = params.filter.address;
|
||||
}
|
||||
|
||||
// @TODO: We can handle slightly more complicated logs using the logs API
|
||||
if (params.filter.topics && params.filter.topics.length > 0) {
|
||||
if (params.filter.topics.length > 1) {
|
||||
logger.throwError("unsupported topic count", Logger.Errors.UNSUPPORTED_OPERATION, { topics: params.filter.topics });
|
||||
}
|
||||
if (params.filter.topics.length === 1) {
|
||||
const topic0 = params.filter.topics[0];
|
||||
if (typeof(topic0) !== "string" || topic0.length !== 66) {
|
||||
logger.throwError("unsupported topic format", Logger.Errors.UNSUPPORTED_OPERATION, { topic0: topic0 });
|
||||
}
|
||||
args.topic0 = topic0;
|
||||
}
|
||||
}
|
||||
|
||||
const logs: Array<any> = await this.fetch("logs", args);
|
||||
|
||||
// Cache txHash => blockHash
|
||||
let blocks: { [tag: string]: string } = {};
|
||||
|
||||
// Add any missing blockHash to the logs
|
||||
for (let i = 0; i < logs.length; i++) {
|
||||
const log = logs[i];
|
||||
if (log.blockHash != null) { continue; }
|
||||
if (blocks[log.blockNumber] == null) {
|
||||
const block = await this.getBlock(log.blockNumber);
|
||||
if (block) {
|
||||
blocks[log.blockNumber] = block.hash;
|
||||
}
|
||||
}
|
||||
|
||||
log.blockHash = blocks[log.blockNumber];
|
||||
}
|
||||
|
||||
return logs;
|
||||
}
|
||||
*/
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return super._perform(req);
|
||||
}
|
||||
async getNetwork() {
|
||||
return this.network;
|
||||
}
|
||||
async getEtherPrice() {
|
||||
if (this.network.name !== "homestead") {
|
||||
return 0.0;
|
||||
}
|
||||
return parseFloat((await this.fetch("stats", { action: "ethprice" })).ethusd);
|
||||
}
|
||||
isCommunityResource() {
|
||||
const plugin = this.network.getPlugin(EtherscanPluginId);
|
||||
if (plugin) {
|
||||
return (plugin.communityApiKey === this.apiKey);
|
||||
}
|
||||
return (this.apiKey == null);
|
||||
}
|
||||
}
|
||||
exports.BaseEtherscanProvider = BaseEtherscanProvider;
|
||||
//# sourceMappingURL=provider-etherscan-base.js.map
|
1
lib.commonjs/providers/provider-etherscan-base.js.map
Normal file
1
lib.commonjs/providers/provider-etherscan-base.js.map
Normal file
File diff suppressed because one or more lines are too long
@ -1,459 +1,26 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.EtherscanProvider = exports.EtherscanPlugin = void 0;
|
||||
const index_js_1 = require("../utils/index.js");
|
||||
const abstract_provider_js_1 = require("./abstract-provider.js");
|
||||
const network_js_1 = require("./network.js");
|
||||
const plugins_network_js_1 = require("./plugins-network.js");
|
||||
const defaultApiKey = "9D13ZE7XSBTJ94N9BNJ2MA33VMAY2YPIRB";
|
||||
const EtherscanPluginId = "org.ethers.plugins.etherscan";
|
||||
class EtherscanPlugin extends plugins_network_js_1.NetworkPlugin {
|
||||
baseUrl;
|
||||
communityApiKey;
|
||||
constructor(baseUrl, communityApiKey) {
|
||||
super(EtherscanPluginId);
|
||||
//if (communityApiKey == null) { communityApiKey = null; }
|
||||
(0, index_js_1.defineProperties)(this, { baseUrl, communityApiKey });
|
||||
exports.EtherscanProvider = void 0;
|
||||
const provider_etherscan_base_js_1 = require("./provider-etherscan-base.js");
|
||||
const index_js_1 = require("../contract/index.js");
|
||||
function isPromise(value) {
|
||||
return (value && typeof (value.then) === "function");
|
||||
}
|
||||
clone() {
|
||||
return new EtherscanPlugin(this.baseUrl, this.communityApiKey);
|
||||
class EtherscanProvider extends provider_etherscan_base_js_1.BaseEtherscanProvider {
|
||||
async getContract(_address) {
|
||||
let address = this._getAddress(_address);
|
||||
if (isPromise(address)) {
|
||||
address = await address;
|
||||
}
|
||||
}
|
||||
exports.EtherscanPlugin = EtherscanPlugin;
|
||||
class EtherscanProvider extends abstract_provider_js_1.AbstractProvider {
|
||||
network;
|
||||
apiKey;
|
||||
constructor(_network, apiKey) {
|
||||
super();
|
||||
const network = network_js_1.Network.from(_network);
|
||||
if (apiKey == null) {
|
||||
const plugin = network.getPlugin(EtherscanPluginId);
|
||||
if (plugin) {
|
||||
apiKey = plugin.communityApiKey;
|
||||
}
|
||||
else {
|
||||
apiKey = defaultApiKey;
|
||||
}
|
||||
}
|
||||
(0, index_js_1.defineProperties)(this, { apiKey, network });
|
||||
// Test that the network is supported by Etherscan
|
||||
this.getBaseUrl();
|
||||
}
|
||||
getBaseUrl() {
|
||||
const plugin = this.network.getPlugin(EtherscanPluginId);
|
||||
if (plugin) {
|
||||
return plugin.baseUrl;
|
||||
}
|
||||
switch (this.network.name) {
|
||||
case "homestead":
|
||||
return "https:/\/api.etherscan.io";
|
||||
case "ropsten":
|
||||
return "https:/\/api-ropsten.etherscan.io";
|
||||
case "rinkeby":
|
||||
return "https:/\/api-rinkeby.etherscan.io";
|
||||
case "kovan":
|
||||
return "https:/\/api-kovan.etherscan.io";
|
||||
case "goerli":
|
||||
return "https:/\/api-goerli.etherscan.io";
|
||||
default:
|
||||
}
|
||||
return (0, index_js_1.throwArgumentError)("unsupported network", "network", this.network);
|
||||
}
|
||||
getUrl(module, params) {
|
||||
const query = Object.keys(params).reduce((accum, key) => {
|
||||
const value = params[key];
|
||||
if (value != null) {
|
||||
accum += `&${key}=${value}`;
|
||||
}
|
||||
return accum;
|
||||
}, "");
|
||||
const apiKey = ((this.apiKey) ? `&apikey=${this.apiKey}` : "");
|
||||
return `${this.getBaseUrl()}/api?module=${module}${query}${apiKey}`;
|
||||
}
|
||||
getPostUrl() {
|
||||
return `${this.getBaseUrl()}/api`;
|
||||
}
|
||||
getPostData(module, params) {
|
||||
params.module = module;
|
||||
params.apikey = this.apiKey;
|
||||
return params;
|
||||
}
|
||||
async detectNetwork() {
|
||||
return this.network;
|
||||
}
|
||||
async fetch(module, params, post) {
|
||||
const url = (post ? this.getPostUrl() : this.getUrl(module, params));
|
||||
const payload = (post ? this.getPostData(module, params) : null);
|
||||
/*
|
||||
this.emit("debug", {
|
||||
action: "request",
|
||||
request: url,
|
||||
provider: this
|
||||
});
|
||||
*/
|
||||
const request = new index_js_1.FetchRequest(url);
|
||||
request.processFunc = async (request, response) => {
|
||||
const result = response.hasBody() ? JSON.parse((0, index_js_1.toUtf8String)(response.body)) : {};
|
||||
const throttle = ((typeof (result.result) === "string") ? result.result : "").toLowerCase().indexOf("rate limit") >= 0;
|
||||
if (module === "proxy") {
|
||||
// This JSON response indicates we are being throttled
|
||||
if (result && result.status == 0 && result.message == "NOTOK" && throttle) {
|
||||
response.throwThrottleError(result.result);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (throttle) {
|
||||
response.throwThrottleError(result.result);
|
||||
}
|
||||
}
|
||||
return response;
|
||||
};
|
||||
// @TODO:
|
||||
//throttleSlotInterval: 1000,
|
||||
if (payload) {
|
||||
request.setHeader("content-type", "application/x-www-form-urlencoded; charset=UTF-8");
|
||||
request.body = Object.keys(payload).map((k) => `${k}=${payload[k]}`).join("&");
|
||||
}
|
||||
const response = await request.send();
|
||||
response.assertOk();
|
||||
if (!response.hasBody()) {
|
||||
throw new Error();
|
||||
}
|
||||
/*
|
||||
this.emit("debug", {
|
||||
action: "response",
|
||||
request: url,
|
||||
response: deepCopy(result),
|
||||
provider: this
|
||||
});
|
||||
*/
|
||||
const result = JSON.parse((0, index_js_1.toUtf8String)(response.body));
|
||||
if (module === "proxy") {
|
||||
if (result.jsonrpc != "2.0") {
|
||||
// @TODO: not any
|
||||
const error = new Error("invalid response");
|
||||
error.result = JSON.stringify(result);
|
||||
throw error;
|
||||
}
|
||||
if (result.error) {
|
||||
// @TODO: not any
|
||||
const error = new Error(result.error.message || "unknown error");
|
||||
if (result.error.code) {
|
||||
error.code = result.error.code;
|
||||
}
|
||||
if (result.error.data) {
|
||||
error.data = result.error.data;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
return result.result;
|
||||
}
|
||||
else {
|
||||
// getLogs, getHistory have weird success responses
|
||||
if (result.status == 0 && (result.message === "No records found" || result.message === "No transactions found")) {
|
||||
return result.result;
|
||||
}
|
||||
if (result.status != 1 || result.message != "OK") {
|
||||
const error = new Error("invalid response");
|
||||
error.result = JSON.stringify(result);
|
||||
// if ((result.result || "").toLowerCase().indexOf("rate limit") >= 0) {
|
||||
// error.throttleRetry = true;
|
||||
// }
|
||||
throw error;
|
||||
}
|
||||
return result.result;
|
||||
}
|
||||
}
|
||||
// The transaction has already been sanitized by the calls in Provider
|
||||
_getTransactionPostData(transaction) {
|
||||
const result = {};
|
||||
for (let key in transaction) {
|
||||
if (transaction[key] == null) {
|
||||
continue;
|
||||
}
|
||||
let value = transaction[key];
|
||||
if (key === "type" && value === 0) {
|
||||
continue;
|
||||
}
|
||||
// Quantity-types require no leading zero, unless 0
|
||||
if ({ type: true, gasLimit: true, gasPrice: true, maxFeePerGs: true, maxPriorityFeePerGas: true, nonce: true, value: true }[key]) {
|
||||
value = (0, index_js_1.toQuantity)((0, index_js_1.hexlify)(value));
|
||||
}
|
||||
else if (key === "accessList") {
|
||||
value = "[" + this.network.formatter.accessList(value).map((set) => {
|
||||
return `{address:"${set.address}",storageKeys:["${set.storageKeys.join('","')}"]}`;
|
||||
}).join(",") + "]";
|
||||
}
|
||||
else {
|
||||
value = (0, index_js_1.hexlify)(value);
|
||||
}
|
||||
result[key] = value;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
_checkError(req, error, transaction) {
|
||||
/*
|
||||
let body = "";
|
||||
if (isError(error, Logger.Errors.SERVER_ERROR) && error.response && error.response.hasBody()) {
|
||||
body = toUtf8String(error.response.body);
|
||||
}
|
||||
console.log(body);
|
||||
|
||||
// Undo the "convenience" some nodes are attempting to prevent backwards
|
||||
// incompatibility; maybe for v6 consider forwarding reverts as errors
|
||||
if (method === "call" && body) {
|
||||
|
||||
// Etherscan keeps changing their string
|
||||
if (body.match(/reverted/i) || body.match(/VM execution error/i)) {
|
||||
|
||||
// Etherscan prefixes the data like "Reverted 0x1234"
|
||||
let data = e.data;
|
||||
if (data) { data = "0x" + data.replace(/^.*0x/i, ""); }
|
||||
if (!isHexString(data)) { data = "0x"; }
|
||||
|
||||
logger.throwError("call exception", Logger.Errors.CALL_EXCEPTION, {
|
||||
error, data
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Get the message from any nested error structure
|
||||
let message = error.message;
|
||||
if (isError(error, Logger.Errors.SERVER_ERROR)) {
|
||||
if (error.error && typeof(error.error.message) === "string") {
|
||||
message = error.error.message;
|
||||
} else if (typeof(error.body) === "string") {
|
||||
message = error.body;
|
||||
} else if (typeof(error.responseText) === "string") {
|
||||
message = error.responseText;
|
||||
}
|
||||
}
|
||||
message = (message || "").toLowerCase();
|
||||
|
||||
// "Insufficient funds. The account you tried to send transaction from
|
||||
// does not have enough funds. Required 21464000000000 and got: 0"
|
||||
if (message.match(/insufficient funds/)) {
|
||||
logger.throwError("insufficient funds for intrinsic transaction cost", Logger.Errors.INSUFFICIENT_FUNDS, {
|
||||
error, transaction, info: { method }
|
||||
});
|
||||
}
|
||||
|
||||
// "Transaction with the same hash was already imported."
|
||||
if (message.match(/same hash was already imported|transaction nonce is too low|nonce too low/)) {
|
||||
logger.throwError("nonce has already been used", Logger.Errors.NONCE_EXPIRED, {
|
||||
error, transaction, info: { method }
|
||||
});
|
||||
}
|
||||
|
||||
// "Transaction gas price is too low. There is another transaction with
|
||||
// same nonce in the queue. Try increasing the gas price or incrementing the nonce."
|
||||
if (message.match(/another transaction with same nonce/)) {
|
||||
logger.throwError("replacement fee too low", Logger.Errors.REPLACEMENT_UNDERPRICED, {
|
||||
error, transaction, info: { method }
|
||||
});
|
||||
}
|
||||
|
||||
if (message.match(/execution failed due to an exception|execution reverted/)) {
|
||||
logger.throwError("cannot estimate gas; transaction may fail or may require manual gas limit", Logger.Errors.UNPREDICTABLE_GAS_LIMIT, {
|
||||
error, transaction, info: { method }
|
||||
});
|
||||
}
|
||||
*/
|
||||
throw error;
|
||||
}
|
||||
async _detectNetwork() {
|
||||
return this.network;
|
||||
}
|
||||
async _perform(req) {
|
||||
switch (req.method) {
|
||||
case "chainId":
|
||||
return this.network.chainId;
|
||||
case "getBlockNumber":
|
||||
return this.fetch("proxy", { action: "eth_blockNumber" });
|
||||
case "getGasPrice":
|
||||
return this.fetch("proxy", { action: "eth_gasPrice" });
|
||||
case "getBalance":
|
||||
// Returns base-10 result
|
||||
return this.fetch("account", {
|
||||
action: "balance",
|
||||
address: req.address,
|
||||
tag: req.blockTag
|
||||
});
|
||||
case "getTransactionCount":
|
||||
return this.fetch("proxy", {
|
||||
action: "eth_getTransactionCount",
|
||||
address: req.address,
|
||||
tag: req.blockTag
|
||||
});
|
||||
case "getCode":
|
||||
return this.fetch("proxy", {
|
||||
action: "eth_getCode",
|
||||
address: req.address,
|
||||
tag: req.blockTag
|
||||
});
|
||||
case "getStorageAt":
|
||||
return this.fetch("proxy", {
|
||||
action: "eth_getStorageAt",
|
||||
address: req.address,
|
||||
position: req.position,
|
||||
tag: req.blockTag
|
||||
});
|
||||
case "broadcastTransaction":
|
||||
return this.fetch("proxy", {
|
||||
action: "eth_sendRawTransaction",
|
||||
hex: req.signedTransaction
|
||||
}, true).catch((error) => {
|
||||
return this._checkError(req, error, req.signedTransaction);
|
||||
});
|
||||
case "getBlock":
|
||||
if ("blockTag" in req) {
|
||||
return this.fetch("proxy", {
|
||||
action: "eth_getBlockByNumber",
|
||||
tag: req.blockTag,
|
||||
boolean: (req.includeTransactions ? "true" : "false")
|
||||
});
|
||||
}
|
||||
return (0, index_js_1.throwError)("getBlock by blockHash not supported by Etherscan", "UNSUPPORTED_OPERATION", {
|
||||
operation: "getBlock(blockHash)"
|
||||
});
|
||||
case "getTransaction":
|
||||
return this.fetch("proxy", {
|
||||
action: "eth_getTransactionByHash",
|
||||
txhash: req.hash
|
||||
});
|
||||
case "getTransactionReceipt":
|
||||
return this.fetch("proxy", {
|
||||
action: "eth_getTransactionReceipt",
|
||||
txhash: req.hash
|
||||
});
|
||||
case "call": {
|
||||
if (req.blockTag !== "latest") {
|
||||
throw new Error("EtherscanProvider does not support blockTag for call");
|
||||
}
|
||||
const postData = this._getTransactionPostData(req.transaction);
|
||||
postData.module = "proxy";
|
||||
postData.action = "eth_call";
|
||||
try {
|
||||
return await this.fetch("proxy", postData, true);
|
||||
const resp = await this.fetch("contract", { action: "getabi", address });
|
||||
const abi = JSON.parse(resp);
|
||||
return new index_js_1.Contract(address, abi, this);
|
||||
}
|
||||
catch (error) {
|
||||
return this._checkError(req, error, req.transaction);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
case "estimateGas": {
|
||||
const postData = this._getTransactionPostData(req.transaction);
|
||||
postData.module = "proxy";
|
||||
postData.action = "eth_estimateGas";
|
||||
try {
|
||||
return await this.fetch("proxy", postData, true);
|
||||
}
|
||||
catch (error) {
|
||||
return this._checkError(req, error, req.transaction);
|
||||
}
|
||||
}
|
||||
/*
|
||||
case "getLogs": {
|
||||
// Needs to complain if more than one address is passed in
|
||||
const args: Record<string, any> = { action: "getLogs" }
|
||||
|
||||
if (params.filter.fromBlock) {
|
||||
args.fromBlock = checkLogTag(params.filter.fromBlock);
|
||||
}
|
||||
|
||||
if (params.filter.toBlock) {
|
||||
args.toBlock = checkLogTag(params.filter.toBlock);
|
||||
}
|
||||
|
||||
if (params.filter.address) {
|
||||
args.address = params.filter.address;
|
||||
}
|
||||
|
||||
// @TODO: We can handle slightly more complicated logs using the logs API
|
||||
if (params.filter.topics && params.filter.topics.length > 0) {
|
||||
if (params.filter.topics.length > 1) {
|
||||
logger.throwError("unsupported topic count", Logger.Errors.UNSUPPORTED_OPERATION, { topics: params.filter.topics });
|
||||
}
|
||||
if (params.filter.topics.length === 1) {
|
||||
const topic0 = params.filter.topics[0];
|
||||
if (typeof(topic0) !== "string" || topic0.length !== 66) {
|
||||
logger.throwError("unsupported topic format", Logger.Errors.UNSUPPORTED_OPERATION, { topic0: topic0 });
|
||||
}
|
||||
args.topic0 = topic0;
|
||||
}
|
||||
}
|
||||
|
||||
const logs: Array<any> = await this.fetch("logs", args);
|
||||
|
||||
// Cache txHash => blockHash
|
||||
let blocks: { [tag: string]: string } = {};
|
||||
|
||||
// Add any missing blockHash to the logs
|
||||
for (let i = 0; i < logs.length; i++) {
|
||||
const log = logs[i];
|
||||
if (log.blockHash != null) { continue; }
|
||||
if (blocks[log.blockNumber] == null) {
|
||||
const block = await this.getBlock(log.blockNumber);
|
||||
if (block) {
|
||||
blocks[log.blockNumber] = block.hash;
|
||||
}
|
||||
}
|
||||
|
||||
log.blockHash = blocks[log.blockNumber];
|
||||
}
|
||||
|
||||
return logs;
|
||||
}
|
||||
*/
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return super._perform(req);
|
||||
}
|
||||
async getNetwork() {
|
||||
return this.network;
|
||||
}
|
||||
async getEtherPrice() {
|
||||
if (this.network.name !== "homestead") {
|
||||
return 0.0;
|
||||
}
|
||||
return parseFloat((await this.fetch("stats", { action: "ethprice" })).ethusd);
|
||||
}
|
||||
isCommunityResource() {
|
||||
const plugin = this.network.getPlugin(EtherscanPluginId);
|
||||
if (plugin) {
|
||||
return (plugin.communityApiKey === this.apiKey);
|
||||
}
|
||||
return (defaultApiKey === this.apiKey);
|
||||
}
|
||||
}
|
||||
exports.EtherscanProvider = EtherscanProvider;
|
||||
/*
|
||||
(async function() {
|
||||
const provider = new EtherscanProvider();
|
||||
console.log(provider);
|
||||
console.log(await provider.getBlockNumber());
|
||||
/ *
|
||||
provider.on("block", (b) => {
|
||||
console.log("BB", b);
|
||||
});
|
||||
console.log(await provider.getTransactionReceipt("0xa5ded92f548e9f362192f9ab7e5b3fbc9b5a919a868e29247f177d49ce38de6e"));
|
||||
|
||||
provider.once("0xa5ded92f548e9f362192f9ab7e5b3fbc9b5a919a868e29247f177d49ce38de6e", (tx) => {
|
||||
console.log("TT", tx);
|
||||
});
|
||||
* /
|
||||
try {
|
||||
console.log(await provider.getBlock(100));
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
try {
|
||||
console.log(await provider.getBlock(13821768));
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
})();
|
||||
*/
|
||||
//# sourceMappingURL=provider-etherscan.js.map
|
File diff suppressed because one or more lines are too long
@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.FallbackProvider = void 0;
|
||||
const index_js_1 = require("../utils/index.js");
|
||||
const abstract_provider_js_1 = require("./abstract-provider.js");
|
||||
const format_js_1 = require("./format.js");
|
||||
const network_js_1 = require("./network.js");
|
||||
//const BN_0 = BigInt("0");
|
||||
const BN_1 = BigInt("1");
|
||||
@ -43,7 +44,7 @@ async function waitForSync(config, blockNumber) {
|
||||
}
|
||||
// Normalizes a result to a string that can be used to compare against
|
||||
// other results using normal string equality
|
||||
function normalize(network, value, req) {
|
||||
function normalize(provider, value, req) {
|
||||
switch (req.method) {
|
||||
case "chainId":
|
||||
return (0, index_js_1.getBigInt)(value).toString();
|
||||
@ -61,19 +62,19 @@ function normalize(network, value, req) {
|
||||
return (0, index_js_1.hexlify)(value);
|
||||
case "getBlock":
|
||||
if (req.includeTransactions) {
|
||||
return JSON.stringify(network.formatter.blockWithTransactions(value));
|
||||
return JSON.stringify((0, format_js_1.formatBlockWithTransactions)(value));
|
||||
}
|
||||
return JSON.stringify(network.formatter.block(value));
|
||||
return JSON.stringify((0, format_js_1.formatBlock)(value));
|
||||
case "getTransaction":
|
||||
return JSON.stringify(network.formatter.transactionResponse(value));
|
||||
return JSON.stringify((0, format_js_1.formatTransactionResponse)(value));
|
||||
case "getTransactionReceipt":
|
||||
return JSON.stringify(network.formatter.receipt(value));
|
||||
return JSON.stringify((0, format_js_1.formatTransactionReceipt)(value));
|
||||
case "call":
|
||||
return (0, index_js_1.hexlify)(value);
|
||||
case "estimateGas":
|
||||
return (0, index_js_1.getBigInt)(value).toString();
|
||||
case "getLogs":
|
||||
return JSON.stringify(value.map((v) => network.formatter.log(v)));
|
||||
return JSON.stringify(value.map((v) => (0, format_js_1.formatLog)(v)));
|
||||
}
|
||||
return (0, index_js_1.throwError)("unsupported method", "UNSUPPORTED_OPERATION", {
|
||||
operation: `_perform(${JSON.stringify(req.method)})`
|
||||
@ -177,7 +178,7 @@ class FallbackProvider extends abstract_provider_js_1.AbstractProvider {
|
||||
return this.#configs.slice();
|
||||
}
|
||||
async _detectNetwork() {
|
||||
return network_js_1.Network.from((0, index_js_1.getBigInt)(await this._perform({ method: "chainId" }))).freeze();
|
||||
return network_js_1.Network.from((0, index_js_1.getBigInt)(await this._perform({ method: "chainId" })));
|
||||
}
|
||||
// @TODO: Add support to select providers to be the event subscriber
|
||||
//_getSubscriber(sub: Subscription): Subscriber {
|
||||
@ -272,7 +273,7 @@ class FallbackProvider extends abstract_provider_js_1.AbstractProvider {
|
||||
const result = runner.result.result;
|
||||
results.push({
|
||||
result,
|
||||
normal: normalize((runner.config._network), result, req),
|
||||
normal: normalize(runner.config.provider, result, req),
|
||||
weight: runner.config.weight
|
||||
});
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
@ -24,7 +24,15 @@ class IpcSocketProvider extends provider_socket_js_1.SocketProvider {
|
||||
constructor(path, network) {
|
||||
super(network);
|
||||
this.#socket = (0, net_1.connect)(path);
|
||||
this.socket.on("ready", () => { this._start(); });
|
||||
this.socket.on("ready", async () => {
|
||||
try {
|
||||
await this._start();
|
||||
}
|
||||
catch (error) {
|
||||
console.log("failed to start IpcSocketProvider", error);
|
||||
// @TODO: Now what? Restart?
|
||||
}
|
||||
});
|
||||
let response = Buffer.alloc(0);
|
||||
this.socket.on("data", (data) => {
|
||||
response = Buffer.concat([response, data]);
|
||||
|
@ -1 +1 @@
|
||||
{"version":3,"file":"provider-ipcsocket.js","sourceRoot":"","sources":["../../src.ts/providers/provider-ipcsocket.ts"],"names":[],"mappings":";;;AACA,6BAA8B;AAC9B,6DAAsD;AAMtD,yEAAyE;AACzE,0CAA0C;AAC1C,SAAS,WAAW,CAAC,IAAY;IAC7B,MAAM,QAAQ,GAAkB,EAAG,CAAC;IAEpC,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,OAAO,IAAI,EAAE;QACT,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;QACvC,IAAI,EAAE,KAAK,CAAC,CAAC,EAAE;YAAE,MAAM;SAAE;QACzB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;QAC9D,SAAS,GAAG,EAAE,GAAG,CAAC,CAAC;KACtB;IAED,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;AAC7D,CAAC;AAED,MAAa,iBAAkB,SAAQ,mCAAc;IACjD,OAAO,CAAS;IAChB,IAAI,MAAM,KAAa,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IAE7C,YAAY,IAAY,EAAE,OAAoB;QAC1C,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,OAAO,GAAG,IAAA,aAAO,EAAC,IAAI,CAAC,CAAC;QAE7B,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAElD,IAAI,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC/B,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YAC5B,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAE,QAAQ,EAAE,IAAI,CAAE,CAAC,CAAC;YAC7C,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;YACtD,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;gBACzB,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YAClC,CAAC,CAAC,CAAC;YACH,QAAQ,GAAG,SAAS,CAAC;QACzB,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;YACvB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACnB,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACtB,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QACtB,CAAC,CAAC,CAAC;IACP,CAAC;IAED,IAAI;QACA,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACtB,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,OAAe;QACxB,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC5B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;CACJ;AApCD,8CAoCC;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoCE"}
|
||||
{"version":3,"file":"provider-ipcsocket.js","sourceRoot":"","sources":["../../src.ts/providers/provider-ipcsocket.ts"],"names":[],"mappings":";;;AACA,6BAA8B;AAC9B,6DAAsD;AAMtD,yEAAyE;AACzE,0CAA0C;AAC1C,SAAS,WAAW,CAAC,IAAY;IAC7B,MAAM,QAAQ,GAAkB,EAAG,CAAC;IAEpC,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,OAAO,IAAI,EAAE;QACT,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;QACvC,IAAI,EAAE,KAAK,CAAC,CAAC,EAAE;YAAE,MAAM;SAAE;QACzB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;QAC9D,SAAS,GAAG,EAAE,GAAG,CAAC,CAAC;KACtB;IAED,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;AAC7D,CAAC;AAED,MAAa,iBAAkB,SAAQ,mCAAc;IACjD,OAAO,CAAS;IAChB,IAAI,MAAM,KAAa,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IAE7C,YAAY,IAAY,EAAE,OAAoB;QAC1C,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,OAAO,GAAG,IAAA,aAAO,EAAC,IAAI,CAAC,CAAC;QAE7B,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE;YAC/B,IAAI;gBACA,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;aACvB;YAAC,OAAO,KAAK,EAAE;gBACZ,OAAO,CAAC,GAAG,CAAC,mCAAmC,EAAE,KAAK,CAAC,CAAC;gBACxD,4BAA4B;aAC/B;QACL,CAAC,CAAC,CAAC;QAEH,IAAI,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC/B,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YAC5B,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAE,QAAQ,EAAE,IAAI,CAAE,CAAC,CAAC;YAC7C,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;YACtD,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;gBACzB,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YAClC,CAAC,CAAC,CAAC;YACH,QAAQ,GAAG,SAAS,CAAC;QACzB,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;YACvB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACnB,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACtB,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QACtB,CAAC,CAAC,CAAC;IACP,CAAC;IAED,IAAI;QACA,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACtB,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,OAAe;QACxB,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC5B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;CACJ;AA3CD,8CA2CC;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoCE"}
|
@ -33,6 +33,9 @@ function deepCopy(value) {
|
||||
}
|
||||
throw new Error(`should not happen: ${value} (${typeof (value)})`);
|
||||
}
|
||||
function stall(duration) {
|
||||
return new Promise((resolve) => { setTimeout(resolve, duration); });
|
||||
}
|
||||
function getLowerCase(value) {
|
||||
if (value) {
|
||||
return value.toLowerCase();
|
||||
@ -123,7 +126,7 @@ class JsonRpcSigner extends abstract_signer_js_1.AbstractSigner {
|
||||
// Try getting the transaction
|
||||
const tx = await this.provider.getTransaction(hash);
|
||||
if (tx != null) {
|
||||
resolve(this.provider._wrapTransaction(tx, hash, blockNumber));
|
||||
resolve(tx.replaceableTransaction(blockNumber));
|
||||
return;
|
||||
}
|
||||
// Wait another 4 seconds
|
||||
@ -188,23 +191,36 @@ exports.JsonRpcSigner = JsonRpcSigner;
|
||||
* sub-classed.
|
||||
*
|
||||
* It provides the base for all JSON-RPC-based Provider interaction.
|
||||
*
|
||||
* Sub-classing Notes:
|
||||
* - a sub-class MUST override _send
|
||||
* - a sub-class MUST call the `_start()` method once connected
|
||||
*/
|
||||
class JsonRpcApiProvider extends abstract_provider_js_1.AbstractProvider {
|
||||
#options;
|
||||
#nextId;
|
||||
#payloads;
|
||||
#ready;
|
||||
#starting;
|
||||
#drainTimer;
|
||||
#network;
|
||||
constructor(network, options) {
|
||||
super(network);
|
||||
this.#ready = false;
|
||||
this.#starting = null;
|
||||
this.#nextId = 1;
|
||||
this.#options = Object.assign({}, defaultOptions, options || {});
|
||||
this.#payloads = [];
|
||||
this.#drainTimer = null;
|
||||
this.#network = null;
|
||||
// This could be relaxed in the future to just check equivalent networks
|
||||
const staticNetwork = this._getOption("staticNetwork");
|
||||
if (staticNetwork && staticNetwork !== network) {
|
||||
if (staticNetwork) {
|
||||
if (staticNetwork !== network) {
|
||||
(0, index_js_4.throwArgumentError)("staticNetwork MUST match network object", "options", options);
|
||||
}
|
||||
this.#network = staticNetwork;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Returns the value associated with the option %%key%%.
|
||||
@ -214,8 +230,40 @@ class JsonRpcApiProvider extends abstract_provider_js_1.AbstractProvider {
|
||||
_getOption(key) {
|
||||
return this.#options[key];
|
||||
}
|
||||
get _network() {
|
||||
if (!this.#network) {
|
||||
(0, index_js_4.throwError)("network is not available yet", "NETWORK_ERROR");
|
||||
}
|
||||
return this.#network;
|
||||
}
|
||||
get ready() { return this.#ready; }
|
||||
async _start() {
|
||||
if (this.#ready) {
|
||||
return;
|
||||
}
|
||||
if (this.#starting) {
|
||||
return this.#starting;
|
||||
}
|
||||
this.#starting = (async () => {
|
||||
// Bootstrap the network
|
||||
if (this.#network == null) {
|
||||
try {
|
||||
this.#network = await this._detectNetwork();
|
||||
}
|
||||
catch (error) {
|
||||
console.log("JsonRpcProvider failed to startup; retry in 1s");
|
||||
await stall(1000);
|
||||
this.#starting = null;
|
||||
}
|
||||
}
|
||||
this.#ready = true;
|
||||
this.#starting = null;
|
||||
// Start dispatching requests
|
||||
this.#scheduleDrain();
|
||||
})();
|
||||
}
|
||||
#scheduleDrain() {
|
||||
if (this.#drainTimer) {
|
||||
if (this.#drainTimer || !this.ready) {
|
||||
return;
|
||||
}
|
||||
// If we aren't using batching, no hard in sending it immeidately
|
||||
@ -272,7 +320,6 @@ class JsonRpcApiProvider extends abstract_provider_js_1.AbstractProvider {
|
||||
}
|
||||
}, stallTime);
|
||||
}
|
||||
// Sub-classes should **NOT** override this
|
||||
/**
|
||||
* Requests the %%method%% with %%params%% via the JSON-RPC protocol
|
||||
* over the underlying channel. This can be used to call methods
|
||||
@ -331,25 +378,44 @@ class JsonRpcApiProvider extends abstract_provider_js_1.AbstractProvider {
|
||||
}
|
||||
return new JsonRpcSigner(this, accounts[address]);
|
||||
}
|
||||
const [network, accounts] = await Promise.all([this.getNetwork(), accountsPromise]);
|
||||
const { accounts } = await (0, index_js_4.resolveProperties)({
|
||||
network: this.getNetwork(),
|
||||
accounts: accountsPromise
|
||||
});
|
||||
// Account address
|
||||
address = network.formatter.address(address);
|
||||
address = (0, index_js_1.getAddress)(address);
|
||||
for (const account of accounts) {
|
||||
if (network.formatter.address(account) === account) {
|
||||
if ((0, index_js_1.getAddress)(account) === account) {
|
||||
return new JsonRpcSigner(this, account);
|
||||
}
|
||||
}
|
||||
throw new Error("invalid account");
|
||||
}
|
||||
// Sub-classes can override this; it detects the *actual* network we
|
||||
// are connected to
|
||||
/** Sub-classes can override this; it detects the *actual* network that
|
||||
* we are **currently** connected to.
|
||||
*
|
||||
* Keep in mind that [[send]] may only be used once [[ready]].
|
||||
*/
|
||||
async _detectNetwork() {
|
||||
// We have a static network (like INFURA)
|
||||
const network = this._getOption("staticNetwork");
|
||||
if (network) {
|
||||
return network;
|
||||
}
|
||||
return network_js_1.Network.from((0, index_js_4.getBigInt)(await this._perform({ method: "chainId" })));
|
||||
// If we are ready, use ``send``, which enabled requests to be batched
|
||||
if (this.ready) {
|
||||
return network_js_1.Network.from((0, index_js_4.getBigInt)(await this.send("eth_chainId", [])));
|
||||
}
|
||||
// We are not ready yet; use the primitive _send
|
||||
const payload = {
|
||||
id: this.#nextId++, method: "eth_chainId", params: [], jsonrpc: "2.0"
|
||||
};
|
||||
this.emit("debug", { action: "sendRpcPayload", payload });
|
||||
const result = (await this._send(payload))[0];
|
||||
this.emit("debug", { action: "receiveRpcResult", result });
|
||||
if ("result" in result) {
|
||||
return network_js_1.Network.from((0, index_js_4.getBigInt)(result.result));
|
||||
}
|
||||
throw this.getRpcError(payload, result);
|
||||
}
|
||||
/**
|
||||
* Return a Subscriber that will manage the %%sub%%.
|
||||
@ -602,6 +668,13 @@ class JsonRpcProvider extends JsonRpcApiProvider {
|
||||
}
|
||||
this.#pollingInterval = 4000;
|
||||
}
|
||||
async send(method, params) {
|
||||
// All requests are over HTTP, so we can just start handling requests
|
||||
// We do this here rather than the constructor so that we don't send any
|
||||
// requests to the network until we absolutely have to.
|
||||
await this._start();
|
||||
return await super.send(method, params);
|
||||
}
|
||||
async _send(payload) {
|
||||
// Configure a POST connection for the requested method
|
||||
const request = this.#connect.clone();
|
||||
|
File diff suppressed because one or more lines are too long
@ -101,21 +101,17 @@ exports.SocketPendingSubscriber = SocketPendingSubscriber;
|
||||
class SocketEventSubscriber extends SocketSubscriber {
|
||||
#logFilter;
|
||||
get logFilter() { return JSON.parse(this.#logFilter); }
|
||||
#formatter;
|
||||
constructor(provider, filter) {
|
||||
super(provider, ["logs", filter]);
|
||||
this.#logFilter = JSON.stringify(filter);
|
||||
this.#formatter = provider.getNetwork().then((network) => network.formatter);
|
||||
}
|
||||
async _emit(provider, message) {
|
||||
const formatter = await this.#formatter;
|
||||
provider.emit(this.#logFilter, formatter.log(message, provider));
|
||||
provider.emit(this.#logFilter, provider._wrapLog(message, provider._network));
|
||||
}
|
||||
}
|
||||
exports.SocketEventSubscriber = SocketEventSubscriber;
|
||||
class SocketProvider extends provider_jsonrpc_js_1.JsonRpcApiProvider {
|
||||
#callbacks;
|
||||
#ready;
|
||||
// Maps each filterId to its subscriber
|
||||
#subs;
|
||||
// If any events come in before a subscriber has finished
|
||||
@ -124,10 +120,18 @@ class SocketProvider extends provider_jsonrpc_js_1.JsonRpcApiProvider {
|
||||
constructor(network) {
|
||||
super(network, { batchMaxCount: 1 });
|
||||
this.#callbacks = new Map();
|
||||
this.#ready = false;
|
||||
this.#subs = new Map();
|
||||
this.#pending = new Map();
|
||||
}
|
||||
// This value is only valid after _start has been called
|
||||
/*
|
||||
get _network(): Network {
|
||||
if (this.#network == null) {
|
||||
throw new Error("this shouldn't happen");
|
||||
}
|
||||
return this.#network.clone();
|
||||
}
|
||||
*/
|
||||
_getSubscriber(sub) {
|
||||
switch (sub.type) {
|
||||
case "close":
|
||||
@ -164,21 +168,23 @@ class SocketProvider extends provider_jsonrpc_js_1.JsonRpcApiProvider {
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
this.#callbacks.set(payload.id, { payload, resolve, reject });
|
||||
});
|
||||
if (this.#ready) {
|
||||
await this._write(JSON.stringify(payload));
|
||||
}
|
||||
return [await promise];
|
||||
}
|
||||
// Sub-classes must call this once they are connected
|
||||
async _start() {
|
||||
if (this.#ready) {
|
||||
return;
|
||||
}
|
||||
this.#ready = true;
|
||||
/*
|
||||
async _start(): Promise<void> {
|
||||
if (this.#ready) { return; }
|
||||
|
||||
for (const { payload } of this.#callbacks.values()) {
|
||||
await this._write(JSON.stringify(payload));
|
||||
}
|
||||
|
||||
this.#ready = (async function() {
|
||||
await super._start();
|
||||
})();
|
||||
}
|
||||
*/
|
||||
// Sub-classes must call this for each message
|
||||
async _processMessage(message) {
|
||||
const result = (JSON.parse(message));
|
||||
|
File diff suppressed because one or more lines are too long
@ -15,8 +15,14 @@ class WebSocketProvider extends provider_socket_js_1.SocketProvider {
|
||||
else {
|
||||
this.#websocket = url;
|
||||
}
|
||||
this.websocket.onopen = () => {
|
||||
this._start();
|
||||
this.websocket.onopen = async () => {
|
||||
try {
|
||||
await this._start();
|
||||
}
|
||||
catch (error) {
|
||||
console.log("failed to start WebsocketProvider", error);
|
||||
// @TODO: now what? Attempt reconnect?
|
||||
}
|
||||
};
|
||||
this.websocket.onmessage = (message) => {
|
||||
this._processMessage(message.data);
|
||||
|
@ -1 +1 @@
|
||||
{"version":3,"file":"provider-websocket.js","sourceRoot":"","sources":["../../src.ts/providers/provider-websocket.ts"],"names":[],"mappings":";;;AAEA,mCAAkD,CAAC,YAAY;AAE/D,6DAAsD;AAetD,MAAa,iBAAkB,SAAQ,mCAAc;IACjD,GAAG,CAAU;IAEb,UAAU,CAAgB;IAC1B,IAAI,SAAS,KAAoB,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;IAE1D,YAAY,GAA2B,EAAE,OAAoB;QACzD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,OAAM,CAAC,GAAG,CAAC,KAAK,QAAQ,EAAE;YAC1B,IAAI,CAAC,UAAU,GAAG,IAAI,iBAAU,CAAC,GAAG,CAAC,CAAC;SACzC;aAAM;YACH,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;SACzB;QAED,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,GAAG,EAAE;YACzB,IAAI,CAAC,MAAM,EAAE,CAAC;QAClB,CAAC,CAAC;QAEF,IAAI,CAAC,SAAS,CAAC,SAAS,GAAG,CAAC,OAAyB,EAAE,EAAE;YACrD,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACvC,CAAC,CAAC;IACN,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,OAAe;QACxB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;CACJ;AA1BD,8CA0BC"}
|
||||
{"version":3,"file":"provider-websocket.js","sourceRoot":"","sources":["../../src.ts/providers/provider-websocket.ts"],"names":[],"mappings":";;;AAEA,mCAAkD,CAAC,YAAY;AAE/D,6DAAsD;AAetD,MAAa,iBAAkB,SAAQ,mCAAc;IACjD,GAAG,CAAU;IAEb,UAAU,CAAgB;IAC1B,IAAI,SAAS,KAAoB,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;IAE1D,YAAY,GAA2B,EAAE,OAAoB;QACzD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,OAAM,CAAC,GAAG,CAAC,KAAK,QAAQ,EAAE;YAC1B,IAAI,CAAC,UAAU,GAAG,IAAI,iBAAU,CAAC,GAAG,CAAC,CAAC;SACzC;aAAM;YACH,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;SACzB;QAED,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,KAAK,IAAI,EAAE;YAC/B,IAAI;gBACA,MAAM,IAAI,CAAC,MAAM,EAAE,CAAA;aACtB;YAAC,OAAO,KAAK,EAAE;gBACZ,OAAO,CAAC,GAAG,CAAC,mCAAmC,EAAE,KAAK,CAAC,CAAC;gBACxD,sCAAsC;aACzC;QACL,CAAC,CAAC;QAEF,IAAI,CAAC,SAAS,CAAC,SAAS,GAAG,CAAC,OAAyB,EAAE,EAAE;YACrD,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACvC,CAAC,CAAC;IACN,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,OAAe;QACxB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;CACJ;AA/BD,8CA+BC"}
|
@ -1,9 +1,10 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.dummyProvider = exports.TransactionResponse = exports.TransactionReceipt = exports.Log = exports.Block = exports.copyRequest = exports.FeeData = void 0;
|
||||
exports.TransactionResponse = exports.TransactionReceipt = exports.Log = exports.Block = exports.copyRequest = exports.FeeData = void 0;
|
||||
//import { resolveAddress } from "@ethersproject/address";
|
||||
const index_js_1 = require("../utils/index.js");
|
||||
const index_js_2 = require("../transaction/index.js");
|
||||
const BN_0 = BigInt(0);
|
||||
// -----------------------
|
||||
function getValue(value) {
|
||||
if (value == null) {
|
||||
@ -98,9 +99,6 @@ class Block {
|
||||
baseFeePerGas;
|
||||
#transactions;
|
||||
constructor(block, provider) {
|
||||
if (provider == null) {
|
||||
provider = exports.dummyProvider;
|
||||
}
|
||||
this.#transactions = Object.freeze(block.transactions.map((tx) => {
|
||||
if (typeof (tx) !== "string" && tx.provider !== provider) {
|
||||
throw new Error("provider mismatch");
|
||||
@ -196,9 +194,6 @@ class Log {
|
||||
index;
|
||||
transactionIndex;
|
||||
constructor(log, provider) {
|
||||
if (provider == null) {
|
||||
provider = exports.dummyProvider;
|
||||
}
|
||||
this.provider = provider;
|
||||
const topics = Object.freeze(log.topics.slice());
|
||||
(0, index_js_1.defineProperties)(this, {
|
||||
@ -269,9 +264,6 @@ class TransactionReceipt {
|
||||
root;
|
||||
#logs;
|
||||
constructor(tx, provider) {
|
||||
if (provider == null) {
|
||||
provider = exports.dummyProvider;
|
||||
}
|
||||
this.#logs = Object.freeze(tx.logs.map((log) => {
|
||||
if (provider !== log.provider) {
|
||||
//return log.connect(provider);
|
||||
@ -381,10 +373,8 @@ class TransactionResponse {
|
||||
chainId;
|
||||
signature;
|
||||
accessList;
|
||||
#startBlock;
|
||||
constructor(tx, provider) {
|
||||
if (provider == null) {
|
||||
provider = exports.dummyProvider;
|
||||
}
|
||||
this.provider = provider;
|
||||
this.blockNumber = (tx.blockNumber != null) ? tx.blockNumber : null;
|
||||
this.blockHash = (tx.blockHash != null) ? tx.blockHash : null;
|
||||
@ -403,10 +393,8 @@ class TransactionResponse {
|
||||
this.chainId = tx.chainId;
|
||||
this.signature = tx.signature;
|
||||
this.accessList = (tx.accessList != null) ? tx.accessList : null;
|
||||
this.#startBlock = -1;
|
||||
}
|
||||
//connect(provider: Provider): TransactionResponse {
|
||||
// return new TransactionResponse(this, provider);
|
||||
//}
|
||||
toJSON() {
|
||||
const { blockNumber, blockHash, index, hash, type, to, from, nonce, data, signature, accessList } = this;
|
||||
return {
|
||||
@ -443,8 +431,153 @@ class TransactionResponse {
|
||||
async getTransaction() {
|
||||
return this.provider.getTransaction(this.hash);
|
||||
}
|
||||
async wait(confirms) {
|
||||
return this.provider.waitForTransaction(this.hash, confirms);
|
||||
async wait(_confirms, _timeout) {
|
||||
const confirms = (_confirms == null) ? 1 : _confirms;
|
||||
const timeout = (_timeout == null) ? 0 : _timeout;
|
||||
let startBlock = this.#startBlock;
|
||||
let nextScan = -1;
|
||||
let stopScanning = (startBlock === -1) ? true : false;
|
||||
const checkReplacement = async () => {
|
||||
// Get the current transaction count for this sender
|
||||
if (stopScanning) {
|
||||
return null;
|
||||
}
|
||||
const { blockNumber, nonce } = await (0, index_js_1.resolveProperties)({
|
||||
blockNumber: this.provider.getBlockNumber(),
|
||||
nonce: this.provider.getTransactionCount(this.from)
|
||||
});
|
||||
// No transaction for our nonce has been mined yet; but we can start
|
||||
// scanning later when we do start
|
||||
if (nonce < this.nonce) {
|
||||
startBlock = blockNumber;
|
||||
return;
|
||||
}
|
||||
// We were mined; no replacement
|
||||
if (stopScanning) {
|
||||
return null;
|
||||
}
|
||||
const mined = await this.getTransaction();
|
||||
if (mined && mined.blockNumber != null) {
|
||||
return;
|
||||
}
|
||||
// We were replaced; start scanning for that transaction
|
||||
// Starting to scan; look back a few extra blocks for safety
|
||||
if (nextScan === -1) {
|
||||
nextScan = startBlock - 3;
|
||||
if (nextScan < this.#startBlock) {
|
||||
nextScan = this.#startBlock;
|
||||
}
|
||||
}
|
||||
while (nextScan <= blockNumber) {
|
||||
// Get the next block to scan
|
||||
if (stopScanning) {
|
||||
return null;
|
||||
}
|
||||
const block = await this.provider.getBlockWithTransactions(nextScan);
|
||||
// This should not happen; but we'll try again shortly
|
||||
if (block == null) {
|
||||
return;
|
||||
}
|
||||
for (const tx of block.transactions) {
|
||||
// We were mined; no replacement
|
||||
if (tx.hash === this.hash) {
|
||||
return;
|
||||
}
|
||||
if (tx.from === this.from && tx.nonce === this.nonce) {
|
||||
// Get the receipt
|
||||
if (stopScanning) {
|
||||
return null;
|
||||
}
|
||||
const receipt = await this.provider.getTransactionReceipt(tx.hash);
|
||||
// This should not happen; but we'll try again shortly
|
||||
if (receipt == null) {
|
||||
return;
|
||||
}
|
||||
// We will retry this on the next block (this case could be optimized)
|
||||
if ((blockNumber - receipt.blockNumber + 1) < confirms) {
|
||||
return;
|
||||
}
|
||||
// The reason we were replaced
|
||||
let reason = "replaced";
|
||||
if (tx.data === this.data && tx.to === this.to && tx.value === this.value) {
|
||||
reason = "repriced";
|
||||
}
|
||||
else if (tx.data === "0x" && tx.from === tx.to && tx.value === BN_0) {
|
||||
reason = "cancelled";
|
||||
}
|
||||
(0, index_js_1.throwError)("transaction was replaced", "TRANSACTION_REPLACED", {
|
||||
cancelled: (reason === "replaced" || reason === "cancelled"),
|
||||
reason,
|
||||
replacement: tx.replaceableTransaction(startBlock),
|
||||
hash: tx.hash,
|
||||
receipt
|
||||
});
|
||||
}
|
||||
}
|
||||
nextScan++;
|
||||
}
|
||||
return;
|
||||
};
|
||||
const receipt = await this.provider.getTransactionReceipt(this.hash);
|
||||
if (receipt) {
|
||||
if ((await receipt.confirmations()) >= confirms) {
|
||||
return receipt;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Check for a replacement; throws if a replacement was found
|
||||
await checkReplacement();
|
||||
// Allow null only when the confirms is 0
|
||||
if (confirms === 0) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
const waiter = new Promise((resolve, reject) => {
|
||||
// List of things to cancel when we have a result (one way or the other)
|
||||
const cancellers = [];
|
||||
const cancel = () => { cancellers.forEach((c) => c()); };
|
||||
// On cancel, stop scanning for replacements
|
||||
cancellers.push(() => { stopScanning = true; });
|
||||
// Set up any timeout requested
|
||||
if (timeout > 0) {
|
||||
const timer = setTimeout(() => {
|
||||
cancel();
|
||||
reject((0, index_js_1.makeError)("wait for transaction timeout", "TIMEOUT"));
|
||||
}, timeout);
|
||||
cancellers.push(() => { clearTimeout(timer); });
|
||||
}
|
||||
const txListener = async (receipt) => {
|
||||
// Done; return it!
|
||||
if ((await receipt.confirmations()) >= confirms) {
|
||||
cancel();
|
||||
resolve(receipt);
|
||||
}
|
||||
};
|
||||
cancellers.push(() => { this.provider.off(this.hash, txListener); });
|
||||
this.provider.on(this.hash, txListener);
|
||||
// We support replacement detection; start checking
|
||||
if (startBlock >= 0) {
|
||||
const replaceListener = async () => {
|
||||
try {
|
||||
// Check for a replacement; this throws only if one is found
|
||||
await checkReplacement();
|
||||
}
|
||||
catch (error) {
|
||||
// We were replaced (with enough confirms); re-throw the error
|
||||
if ((0, index_js_1.isError)(error, "TRANSACTION_REPLACED")) {
|
||||
cancel();
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Rescheudle a check on the next block
|
||||
this.provider.once("block", replaceListener);
|
||||
};
|
||||
cancellers.push(() => { this.provider.off("block", replaceListener); });
|
||||
this.provider.once("block", replaceListener);
|
||||
}
|
||||
});
|
||||
return await waiter;
|
||||
}
|
||||
isMined() {
|
||||
return (this.blockHash != null);
|
||||
@ -479,6 +612,21 @@ class TransactionResponse {
|
||||
}
|
||||
return createReorderedTransactionFilter(this, other);
|
||||
}
|
||||
/**
|
||||
* Returns a new TransactionResponse instance which has the ability to
|
||||
* detect (and throw an error) if the transaction is replaced, which
|
||||
* will begin scanning at %%startBlock%%.
|
||||
*
|
||||
* This should generally not be used by developers and is intended
|
||||
* primarily for internal use. Setting an incorrect %%startBlock%% can
|
||||
* have devastating performance consequences if used incorrectly.
|
||||
*/
|
||||
replaceableTransaction(startBlock) {
|
||||
(0, index_js_1.assertArgument)(Number.isInteger(startBlock) && startBlock >= 0, "invalid startBlock", "startBlock", startBlock);
|
||||
const tx = new TransactionResponse(this, this.provider);
|
||||
tx.#startBlock = startBlock;
|
||||
return tx;
|
||||
}
|
||||
}
|
||||
exports.TransactionResponse = TransactionResponse;
|
||||
function createOrphanedBlockFilter(block) {
|
||||
@ -501,80 +649,4 @@ function createRemovedLogFilter(log) {
|
||||
index: log.index
|
||||
} };
|
||||
}
|
||||
// @TODO: I think I can drop T
|
||||
function fail() {
|
||||
throw new Error("this provider should not be used");
|
||||
}
|
||||
class DummyProvider {
|
||||
get provider() { return this; }
|
||||
async getNetwork() { return fail(); }
|
||||
async getFeeData() { return fail(); }
|
||||
async estimateGas(tx) { return fail(); }
|
||||
async call(tx) { return fail(); }
|
||||
async resolveName(name) { return fail(); }
|
||||
// State
|
||||
async getBlockNumber() { return fail(); }
|
||||
// Account
|
||||
async getBalance(address, blockTag) {
|
||||
return fail();
|
||||
}
|
||||
async getTransactionCount(address, blockTag) {
|
||||
return fail();
|
||||
}
|
||||
async getCode(address, blockTag) {
|
||||
return fail();
|
||||
}
|
||||
async getStorageAt(address, position, blockTag) {
|
||||
return fail();
|
||||
}
|
||||
// Write
|
||||
async broadcastTransaction(signedTx) { return fail(); }
|
||||
// Queries
|
||||
async getBlock(blockHashOrBlockTag) {
|
||||
return fail();
|
||||
}
|
||||
async getBlockWithTransactions(blockHashOrBlockTag) {
|
||||
return fail();
|
||||
}
|
||||
async getTransaction(hash) {
|
||||
return fail();
|
||||
}
|
||||
async getTransactionReceipt(hash) {
|
||||
return fail();
|
||||
}
|
||||
async getTransactionResult(hash) {
|
||||
return fail();
|
||||
}
|
||||
// Bloom-filter Queries
|
||||
async getLogs(filter) {
|
||||
return fail();
|
||||
}
|
||||
// ENS
|
||||
async lookupAddress(address) {
|
||||
return fail();
|
||||
}
|
||||
async waitForTransaction(hash, confirms, timeout) {
|
||||
return fail();
|
||||
}
|
||||
async waitForBlock(blockTag) {
|
||||
return fail();
|
||||
}
|
||||
// EventEmitterable
|
||||
async on(event, listener) { return fail(); }
|
||||
async once(event, listener) { return fail(); }
|
||||
async emit(event, ...args) { return fail(); }
|
||||
async listenerCount(event) { return fail(); }
|
||||
async listeners(event) { return fail(); }
|
||||
async off(event, listener) { return fail(); }
|
||||
async removeAllListeners(event) { return fail(); }
|
||||
async addListener(event, listener) { return fail(); }
|
||||
async removeListener(event, listener) { return fail(); }
|
||||
}
|
||||
/**
|
||||
* A singleton [[Provider]] instance that can be used as a placeholder. This
|
||||
* allows API that have a Provider added later to not require a null check.
|
||||
*
|
||||
* All operations performed on this [[Provider]] will throw.
|
||||
*/
|
||||
exports.dummyProvider = new DummyProvider();
|
||||
//# sourceMappingURL=provider.js.map
|
File diff suppressed because one or more lines are too long
@ -88,10 +88,8 @@ class FilterIdEventSubscriber extends FilterIdSubscriber {
|
||||
return filterId;
|
||||
}
|
||||
async _emitResults(provider, results) {
|
||||
const network = await provider.getNetwork();
|
||||
for (const result of results) {
|
||||
const log = network.formatter.log(result, provider);
|
||||
provider.emit(this.#event, log);
|
||||
provider.emit(this.#event, provider._wrapLog(result, provider._network));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -101,9 +99,8 @@ class FilterIdPendingSubscriber extends FilterIdSubscriber {
|
||||
return await provider.send("eth_newPendingTransactionFilter", []);
|
||||
}
|
||||
async _emitResults(provider, results) {
|
||||
const network = await provider.getNetwork();
|
||||
for (const result of results) {
|
||||
provider.emit("pending", network.formatter.hash(result));
|
||||
provider.emit("pending", result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
{"version":3,"file":"subscriber-filterid.js","sourceRoot":"","sources":["../../src.ts/providers/subscriber-filterid.ts"],"names":[],"mappings":"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"}
|
||||
{"version":3,"file":"subscriber-filterid.js","sourceRoot":"","sources":["../../src.ts/providers/subscriber-filterid.ts"],"names":[],"mappings":"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"}
|
@ -118,6 +118,7 @@ class FetchRequest {
|
||||
#process;
|
||||
#retry;
|
||||
#signal;
|
||||
#throttle;
|
||||
/**
|
||||
* The fetch URI to requrest.
|
||||
*/
|
||||
@ -338,10 +339,22 @@ class FetchRequest {
|
||||
this.#gzip = false;
|
||||
this.#headers = {};
|
||||
this.#method = "";
|
||||
this.#timeout = 300;
|
||||
this.#timeout = 300000;
|
||||
this.#throttle = {
|
||||
slotInterval: SLOT_INTERVAL,
|
||||
maxAttempts: MAX_ATTEMPTS
|
||||
};
|
||||
}
|
||||
setThrottleParams(params) {
|
||||
if (params.slotInterval != null) {
|
||||
this.#throttle.slotInterval = params.slotInterval;
|
||||
}
|
||||
if (params.maxAttempts != null) {
|
||||
this.#throttle.maxAttempts = params.maxAttempts;
|
||||
}
|
||||
}
|
||||
async #send(attempt, expires, delay, _request, _response) {
|
||||
if (attempt >= MAX_ATTEMPTS) {
|
||||
if (attempt >= this.#throttle.maxAttempts) {
|
||||
return _response.makeServerError("exceeded maximum retry limit");
|
||||
}
|
||||
if (getTime() > expires) {
|
||||
@ -396,7 +409,7 @@ class FetchRequest {
|
||||
// Throttle
|
||||
if (this.retryFunc == null || (await this.retryFunc(req, response, attempt))) {
|
||||
const retryAfter = response.headers["retry-after"];
|
||||
let delay = SLOT_INTERVAL * Math.trunc(Math.random() * Math.pow(2, attempt));
|
||||
let delay = this.#throttle.slotInterval * Math.trunc(Math.random() * Math.pow(2, attempt));
|
||||
if (typeof (retryAfter) === "string" && retryAfter.match(/^[1-9][0-9]*$/)) {
|
||||
delay = parseInt(retryAfter);
|
||||
}
|
||||
@ -414,7 +427,7 @@ class FetchRequest {
|
||||
response.makeServerError("error in post-processing function", error).assertOk();
|
||||
}
|
||||
// Throttle
|
||||
let delay = SLOT_INTERVAL * Math.trunc(Math.random() * Math.pow(2, attempt));
|
||||
let delay = this.#throttle.slotInterval * Math.trunc(Math.random() * Math.pow(2, attempt));
|
||||
;
|
||||
if (error.stall >= 0) {
|
||||
delay = error.stall;
|
||||
|
File diff suppressed because one or more lines are too long
80
lib.esm/_admin/update-publish-properties.js
Normal file
80
lib.esm/_admin/update-publish-properties.js
Normal file
@ -0,0 +1,80 @@
|
||||
import fs from "fs";
|
||||
import semver from "semver";
|
||||
import { keccak256 } from "../crypto/index.js";
|
||||
import { FetchRequest } from "../utils/index.js";
|
||||
import { loadJson, saveJson } from "./utils/json.js";
|
||||
import { getGitTag } from "./utils/git.js";
|
||||
import { resolve } from "./utils/path.js";
|
||||
import { run } from "./utils/run.js";
|
||||
const cache = {};
|
||||
async function getNpmPackage(name) {
|
||||
if (!cache[name]) {
|
||||
const resp = await (new FetchRequest("https:/\/registry.npmjs.org/" + name)).send();
|
||||
resp.assertOk();
|
||||
cache[name] = resp.bodyJson;
|
||||
}
|
||||
return cache[name] || null;
|
||||
}
|
||||
function getPackList() {
|
||||
const result = run("npm", ["pack", "--json", resolve("."), "--dry-run"]);
|
||||
if (!result.ok) {
|
||||
const error = new Error("failed to run npm pack");
|
||||
error.result = result;
|
||||
throw error;
|
||||
}
|
||||
return JSON.parse(result.stdout)[0].files.map((info) => info.path);
|
||||
}
|
||||
function computeTarballHash() {
|
||||
// Sort the files to get a consistent hash
|
||||
const files = getPackList();
|
||||
files.sort();
|
||||
const hashes = files.reduce((accum, filename) => {
|
||||
let content = fs.readFileSync(resolve(filename));
|
||||
// The package.json includes the hash, so we need to normalize it first
|
||||
if (filename === "package.json") {
|
||||
const info = JSON.parse(content.toString());
|
||||
delete info.gitHead;
|
||||
delete info.tarballHash;
|
||||
content = Buffer.from(JSON.stringify(info, null, 2));
|
||||
}
|
||||
accum[filename] = keccak256(content);
|
||||
return accum;
|
||||
}, {});
|
||||
return keccak256(Buffer.from("{" + files.map((filename) => {
|
||||
return `${JSON.stringify(filename)}:"${hashes[filename]}"`;
|
||||
}).join(",") + "}"));
|
||||
}
|
||||
(async function () {
|
||||
// Local pkg
|
||||
const pkgPath = resolve("package.json");
|
||||
const pkgInfo = loadJson(pkgPath);
|
||||
const tag = pkgInfo.publishConfig.tag;
|
||||
// Get the remote version that matches our dist-tag
|
||||
const remoteInfo = await getNpmPackage(pkgInfo.name);
|
||||
const remoteVersion = remoteInfo["dist-tags"][tag];
|
||||
// Remote pkg
|
||||
const remotePkgInfo = remoteInfo.versions[remoteVersion];
|
||||
// Compute the populated values
|
||||
const tarballHash = computeTarballHash();
|
||||
const gitHead = await getGitTag(resolve("."));
|
||||
if (remotePkgInfo.tarballHash !== tarballHash) {
|
||||
pkgInfo.tarballHash = tarballHash;
|
||||
pkgInfo.gitHead = gitHead;
|
||||
if (tag.indexOf("beta") >= 0) {
|
||||
// Still a beta branch; advance the beta version
|
||||
const prerelease = semver.prerelease(remoteVersion);
|
||||
if (prerelease == null || prerelease.length !== 2) {
|
||||
throw new Error("no prerelease found");
|
||||
}
|
||||
pkgInfo.version = semver.inc(remoteVersion, "prerelease", String(prerelease[0]));
|
||||
}
|
||||
else if (semver.minor(remoteVersion) == semver.minor(pkgInfo.version)) {
|
||||
// If we want to bump the minor version, it was done explicitly in the pkg
|
||||
pkgInfo.version = semver.inc(remoteVersion, "patch");
|
||||
}
|
||||
}
|
||||
saveJson(pkgPath, pkgInfo, true);
|
||||
})().catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
//# sourceMappingURL=update-publish-properties.js.map
|
1
lib.esm/_admin/update-publish-properties.js.map
Normal file
1
lib.esm/_admin/update-publish-properties.js.map
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"update-publish-properties.js","sourceRoot":"","sources":["../../src.ts/_admin/update-publish-properties.ts"],"names":[],"mappings":"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"}
|
18
lib.esm/_admin/utils/git.js
Normal file
18
lib.esm/_admin/utils/git.js
Normal file
@ -0,0 +1,18 @@
|
||||
import { run } from "./run.js";
|
||||
// Returns the most recent git commit hash for a given filename
|
||||
export async function getGitTag(filename) {
|
||||
const result = await run("git", ["log", "-n", "1", "--", filename]);
|
||||
if (!result.ok) {
|
||||
throw new Error(`git log error`);
|
||||
}
|
||||
let log = result.stdout.trim();
|
||||
if (!log) {
|
||||
return null;
|
||||
}
|
||||
const hashMatch = log.match(/^commit\s+([0-9a-f]{40})\n/i);
|
||||
if (!hashMatch) {
|
||||
return null;
|
||||
}
|
||||
return hashMatch[1];
|
||||
}
|
||||
//# sourceMappingURL=git.js.map
|
1
lib.esm/_admin/utils/git.js.map
Normal file
1
lib.esm/_admin/utils/git.js.map
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../../src.ts/_admin/utils/git.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAE/B,+DAA+D;AAC/D,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,QAAgB;IAC5C,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,KAAK,EAAE,CAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,CAAE,CAAC,CAAC;IACtE,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;KAAE;IAErD,IAAI,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAC/B,IAAI,CAAC,GAAG,EAAE;QAAE,OAAO,IAAI,CAAC;KAAE;IAE1B,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;IAC3D,IAAI,CAAC,SAAS,EAAE;QAAE,OAAO,IAAI,CAAC;KAAE;IAChC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC;AACxB,CAAC"}
|
78
lib.esm/_admin/utils/npm.js
Normal file
78
lib.esm/_admin/utils/npm.js
Normal file
@ -0,0 +1,78 @@
|
||||
"use strict";
|
||||
/*
|
||||
import semver from "semver";
|
||||
|
||||
import { FetchRequest } from "../../utils/index.js";
|
||||
|
||||
export type PackageInfo = {
|
||||
dependencies: { [ name: string ]: string };
|
||||
devDependencies: { [ name: string ]: string };
|
||||
gitHead: string;
|
||||
name: string;
|
||||
version: string;
|
||||
tarballHash: string;
|
||||
location: "remote" | "local";
|
||||
_ethers_nobuild: boolean;
|
||||
};
|
||||
|
||||
export class Package {
|
||||
readonly #info: PackageInfo;
|
||||
|
||||
constructor(info: PackageInfo) {
|
||||
this.#info = info;
|
||||
}
|
||||
|
||||
get name(): string { return this.#info.name; }
|
||||
get version(): string { return this.#info.version; }
|
||||
|
||||
get dependencies(): Record<string, string> { return this.#info.dependencies; }
|
||||
get devDependencies(): Record<string, string> { return this.#info.devDependencies; }
|
||||
|
||||
get gitHead(): string { return this.#info.gitHead; }
|
||||
get tarballHash(): string { return this.#info.tarballHash; }
|
||||
|
||||
}
|
||||
|
||||
|
||||
const cache: Record<string, any> = { };
|
||||
|
||||
async function getPackageInfo(name: string): Promise<any> {
|
||||
if (!cache[name]) {
|
||||
const resp = await (new FetchRequest("https:/\/registry.npmjs.org/" + name)).send();
|
||||
resp.assertOk();
|
||||
cache[name] = resp.bodyJson();
|
||||
}
|
||||
|
||||
return cache[name] || null;
|
||||
}
|
||||
|
||||
export async function getPackage(name: string, version?: string): Promise<null | Package> {
|
||||
const infos = await getPackageInfo(name);
|
||||
if (infos == null) { return null; }
|
||||
|
||||
if (version == null) {
|
||||
const versions = Object.keys(infos.versions);
|
||||
versions.sort(semver.compare);
|
||||
|
||||
// HACK: So v5 continues working while v6 is managed by reticulate
|
||||
version = "6.0.0";
|
||||
while (version.indexOf("beta") >= 0 || semver.gte(version, "6.0.0")) {
|
||||
version = versions.pop();
|
||||
}
|
||||
}
|
||||
|
||||
const info = infos.versions[version];
|
||||
|
||||
return new Package({
|
||||
dependencies: (info.dependencies || {}),
|
||||
devDependencies: (info.devDependencies || {}),
|
||||
gitHead: info.gitHead,
|
||||
location: "remote",
|
||||
name: info.name,
|
||||
tarballHash: info.tarballHash,
|
||||
version : info.version,
|
||||
_ethers_nobuild: !!info._ethers_nobuild,
|
||||
});
|
||||
}
|
||||
*/
|
||||
//# sourceMappingURL=npm.js.map
|
1
lib.esm/_admin/utils/npm.js.map
Normal file
1
lib.esm/_admin/utils/npm.js.map
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"npm.js","sourceRoot":"","sources":["../../../src.ts/_admin/utils/npm.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2EE"}
|
54
lib.esm/_admin/utils/run.js
Normal file
54
lib.esm/_admin/utils/run.js
Normal file
@ -0,0 +1,54 @@
|
||||
import { spawnSync } from "child_process";
|
||||
export class RunResult {
|
||||
#cmd;
|
||||
#status;
|
||||
#stdout;
|
||||
#stderr;
|
||||
constructor(progname, args, status, stdout, stderr) {
|
||||
this.#cmd = `${progname} ${args.map((a) => JSON.stringify(a))}`;
|
||||
this.#status = status;
|
||||
this.#stdout = stdout;
|
||||
this.#stderr = stderr;
|
||||
}
|
||||
get cmd() { return this.#cmd; }
|
||||
get stderr() {
|
||||
return this._stderr.toString() || null;
|
||||
}
|
||||
get _stderr() {
|
||||
return this.#stderr;
|
||||
}
|
||||
get stdout() {
|
||||
return this._stdout.toString();
|
||||
}
|
||||
get _stdout() {
|
||||
return this.#stdout;
|
||||
}
|
||||
get status() { return this.#status; }
|
||||
get ok() {
|
||||
return (this.#stderr.length === 0 && this.#status === 0);
|
||||
}
|
||||
assertOk(message) {
|
||||
if (!this.ok) {
|
||||
throw new Error(message || `failed to run: ${this.#cmd}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
;
|
||||
export function run(progname, args, currentWorkingDirectory) {
|
||||
if (args == null) {
|
||||
args = [];
|
||||
}
|
||||
const options = {};
|
||||
if (currentWorkingDirectory) {
|
||||
options.cwd = currentWorkingDirectory;
|
||||
}
|
||||
const child = spawnSync(progname, args, options);
|
||||
const result = new RunResult(progname, args, child.status, child.stdout, child.stderr);
|
||||
if (child.error) {
|
||||
const error = child.error;
|
||||
error.result = result;
|
||||
throw error;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
//# sourceMappingURL=run.js.map
|
1
lib.esm/_admin/utils/run.js.map
Normal file
1
lib.esm/_admin/utils/run.js.map
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../../src.ts/_admin/utils/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C,MAAM,OAAO,SAAS;IACT,IAAI,CAAS;IACb,OAAO,CAAgB;IACvB,OAAO,CAAkB;IACzB,OAAO,CAAkB;IAElC,YAAY,QAAgB,EAAE,IAAmB,EAAE,MAAqB,EAAE,MAAuB,EAAE,MAAuB;QACtH,IAAI,CAAC,IAAI,GAAG,GAAI,QAAS,IAAK,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACnE,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;IAC1B,CAAC;IAED,IAAI,GAAG,KAAa,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAEvC,IAAI,MAAM;QACN,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,IAAI,CAAC;IAC3C,CAAC;IAED,IAAI,OAAO;QACP,OAAO,IAAI,CAAC,OAAO,CAAC;IACxB,CAAC;IAED,IAAI,MAAM;QACN,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;IACnC,CAAC;IAED,IAAI,OAAO;QACP,OAAO,IAAI,CAAC,OAAO,CAAC;IACxB,CAAC;IAED,IAAI,MAAM,KAAoB,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IAEpD,IAAI,EAAE;QACF,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC;IAC7D,CAAC;IAED,QAAQ,CAAC,OAAgB;QACrB,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE;YACV,MAAM,IAAI,KAAK,CAAC,OAAO,IAAI,kBAAmB,IAAI,CAAC,IAAK,EAAE,CAAC,CAAC;SAC/D;IACL,CAAC;CACJ;AAAA,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,QAAgB,EAAE,IAAoB,EAAE,uBAAgC;IACxF,IAAI,IAAI,IAAI,IAAI,EAAE;QAAE,IAAI,GAAG,EAAG,CAAC;KAAE;IAEjC,MAAM,OAAO,GAAQ,EAAG,CAAC;IACzB,IAAI,uBAAuB,EAAE;QAAE,OAAO,CAAC,GAAG,GAAG,uBAAuB,CAAC;KAAE;IACvE,MAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IAEjD,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAEvF,IAAI,KAAK,CAAC,KAAK,EAAE;QACb,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;QACpB,KAAM,CAAC,MAAM,GAAG,MAAM,CAAC;QAC7B,MAAM,KAAK,CAAC;KACf;IAED,OAAO,MAAM,CAAC;AAClB,CAAC"}
|
@ -1,2 +1,2 @@
|
||||
export const version = "6.0.0-beta-exports.1";
|
||||
export const version = "6.0.0-beta-exports.2";
|
||||
//# sourceMappingURL=_version.js.map
|
@ -634,7 +634,7 @@ export class Fragment {
|
||||
case "function": return FunctionFragment.fromObject(obj);
|
||||
case "struct": return StructFragment.fromObject(obj);
|
||||
}
|
||||
throw new Error("not implemented yet");
|
||||
throw new Error(`not implemented yet: ${obj.type}`);
|
||||
}
|
||||
static fromString(text) {
|
||||
try {
|
||||
@ -721,6 +721,9 @@ export class ErrorFragment extends NamedFragment {
|
||||
result.push(this.name + joinParams(format, this.inputs));
|
||||
return result.join(" ");
|
||||
}
|
||||
static fromObject(obj) {
|
||||
return new ErrorFragment(_guard, obj.name, obj.inputs ? obj.inputs.map(ParamType.fromObject) : []);
|
||||
}
|
||||
static fromString(text) {
|
||||
return ErrorFragment.fromTokens(lex(text));
|
||||
}
|
||||
@ -759,6 +762,9 @@ export class EventFragment extends NamedFragment {
|
||||
}
|
||||
return result.join(" ");
|
||||
}
|
||||
static fromObject(obj) {
|
||||
return new EventFragment(_guard, obj.name, obj.inputs ? obj.inputs.map(ParamType.fromObject) : [], !!obj.anonymous);
|
||||
}
|
||||
static fromString(text) {
|
||||
return EventFragment.fromTokens(lex(text));
|
||||
}
|
||||
@ -799,12 +805,12 @@ export class ConstructorFragment extends Fragment {
|
||||
}
|
||||
return result.join(" ");
|
||||
}
|
||||
static fromObject(obj) {
|
||||
return new ConstructorFragment(_guard, "constructor", obj.inputs ? obj.inputs.map(ParamType.fromObject) : [], !!obj.payable, (obj.gas != null) ? obj.gas : null);
|
||||
}
|
||||
static fromString(text) {
|
||||
return ConstructorFragment.fromTokens(lex(text));
|
||||
}
|
||||
static fromObject(obj) {
|
||||
throw new Error("TODO");
|
||||
}
|
||||
static fromTokens(tokens) {
|
||||
consumeKeywords(tokens, setify(["constructor"]));
|
||||
const inputs = consumeParams(tokens);
|
||||
@ -862,6 +868,10 @@ export class FunctionFragment extends NamedFragment {
|
||||
}
|
||||
return result.join(" ");
|
||||
}
|
||||
static fromObject(obj) {
|
||||
// @TODO: verifyState for stateMutability
|
||||
return new FunctionFragment(_guard, obj.name, obj.stateMutability, obj.inputs ? obj.inputs.map(ParamType.fromObject) : [], obj.outputs ? obj.outputs.map(ParamType.fromObject) : [], (obj.gas != null) ? obj.gas : null);
|
||||
}
|
||||
static fromString(text) {
|
||||
return FunctionFragment.fromTokens(lex(text));
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
@ -117,8 +117,15 @@ export class Interface {
|
||||
this.#errors = new Map();
|
||||
this.#events = new Map();
|
||||
// this.#structs = new Map();
|
||||
const frags = [];
|
||||
for (const a of abi) {
|
||||
try {
|
||||
frags.push(Fragment.from(a));
|
||||
}
|
||||
catch (error) { }
|
||||
}
|
||||
defineProperties(this, {
|
||||
fragments: Object.freeze(abi.map((f) => Fragment.from(f)).filter((f) => (f != null))),
|
||||
fragments: Object.freeze(frags)
|
||||
});
|
||||
this.#abiCoder = this.getAbiCoder();
|
||||
// Add all fragments by their signature
|
||||
|
File diff suppressed because one or more lines are too long
@ -165,6 +165,8 @@ class WrappedMethod extends _WrappedMethodBase() {
|
||||
}
|
||||
const tx = await runner.sendTransaction(await this.populateTransaction(...args));
|
||||
const provider = getProvider(this._contract.runner);
|
||||
// @TODO: the provider can be null; make a custom dummy provider that will throw a
|
||||
// meaningful error
|
||||
return new ContractTransactionResponse(this._contract.interface, provider, tx);
|
||||
}
|
||||
async estimateGas(...args) {
|
||||
@ -382,6 +384,8 @@ export class BaseContract {
|
||||
let deployTx = null;
|
||||
if (_deployTx) {
|
||||
const provider = getProvider(runner);
|
||||
// @TODO: the provider can be null; make a custom dummy provider that will throw a
|
||||
// meaningful error
|
||||
deployTx = new ContractTransactionResponse(this.interface, provider, _deployTx);
|
||||
}
|
||||
let subs = new Map();
|
||||
|
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src.ts/contract/types.ts"],"names":[],"mappings":"AAeC,CAAC;AAiBqE,CAAC;AAkDvE,CAAC"}
|
||||
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src.ts/contract/types.ts"],"names":[],"mappings":"AAeC,CAAC;AAiB4E,CAAC;AAkD9E,CAAC"}
|
@ -1 +1 @@
|
||||
{"version":3,"file":"wrappers.js","sourceRoot":"","sources":["../../src.ts/contract/wrappers.ts"],"names":[],"mappings":"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"}
|
||||
{"version":3,"file":"wrappers.js","sourceRoot":"","sources":["../../src.ts/contract/wrappers.ts"],"names":[],"mappings":"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"}
|
@ -8,12 +8,16 @@
|
||||
import { resolveAddress } from "../address/index.js";
|
||||
import { concat, dataLength, dataSlice, hexlify, isHexString, getBigInt, getBytes, getNumber, isCallException, makeError, throwError, throwArgumentError, FetchRequest, toArray, toQuantity, defineProperties, EventPayload, resolveProperties, toUtf8String } from "../utils/index.js";
|
||||
import { EnsResolver } from "./ens-resolver.js";
|
||||
import { formatBlock, formatBlockWithTransactions, formatLog, formatTransactionReceipt, formatTransactionResponse } from "./format.js";
|
||||
import { Network } from "./network.js";
|
||||
import { FeeData } from "./provider.js";
|
||||
import { copyRequest, Block, FeeData, Log, TransactionReceipt, TransactionResponse } from "./provider.js";
|
||||
import { PollingBlockSubscriber, PollingEventSubscriber, PollingOrphanSubscriber, PollingTransactionSubscriber } from "./subscriber-polling.js";
|
||||
// Constants
|
||||
const BN_2 = BigInt(2);
|
||||
const MAX_CCIP_REDIRECTS = 10;
|
||||
function isPromise(value) {
|
||||
return (value && typeof (value.then) === "function");
|
||||
}
|
||||
function getTag(prefix, value) {
|
||||
return prefix + ":" + JSON.stringify(value, (k, v) => {
|
||||
if (typeof (v) === "bigint") {
|
||||
@ -50,10 +54,6 @@ function concisify(items) {
|
||||
items.sort();
|
||||
return items;
|
||||
}
|
||||
// Normalize a ProviderEvent into a Subscription
|
||||
// @TODO: Make events sync if possible; like block
|
||||
//function getSyncSubscription(_event: ProviderEvent): Subscription {
|
||||
//}
|
||||
async function getSubscription(_event, provider) {
|
||||
if (_event == null) {
|
||||
throw new Error("invalid event");
|
||||
@ -123,10 +123,6 @@ async function getSubscription(_event, provider) {
|
||||
return throwArgumentError("unknown ProviderEvent", "event", _event);
|
||||
}
|
||||
function getTime() { return (new Date()).getTime(); }
|
||||
export function copyRequest(tx) {
|
||||
// @TODO: copy the copy from contracts and use it from this
|
||||
return tx;
|
||||
}
|
||||
export class AbstractProvider {
|
||||
#subs;
|
||||
#plugins;
|
||||
@ -135,6 +131,8 @@ export class AbstractProvider {
|
||||
#networkPromise;
|
||||
#anyNetwork;
|
||||
#performCache;
|
||||
// The most recent block number if running an event or -1 if no "block" event
|
||||
#lastBlockNumber;
|
||||
#nextTimer;
|
||||
#timers;
|
||||
#disableCcipRead;
|
||||
@ -155,6 +153,7 @@ export class AbstractProvider {
|
||||
this.#anyNetwork = false;
|
||||
this.#networkPromise = null;
|
||||
}
|
||||
this.#lastBlockNumber = -1;
|
||||
this.#performCache = new Map();
|
||||
this.#subs = new Map();
|
||||
this.#plugins = new Map();
|
||||
@ -243,8 +242,20 @@ export class AbstractProvider {
|
||||
transaction: tx, info: { urls, errorMessages }
|
||||
});
|
||||
}
|
||||
_wrapTransaction(tx, hash, blockNumber) {
|
||||
return tx;
|
||||
_wrapBlock(value, network) {
|
||||
return new Block(formatBlock(value), this);
|
||||
}
|
||||
_wrapBlockWithTransactions(value, network) {
|
||||
return new Block(formatBlock(value), this);
|
||||
}
|
||||
_wrapLog(value, network) {
|
||||
return new Log(formatLog(value), this);
|
||||
}
|
||||
_wrapTransactionReceipt(value, network) {
|
||||
return new TransactionReceipt(formatTransactionReceipt(value), this);
|
||||
}
|
||||
_wrapTransactionResponse(tx, network) {
|
||||
return new TransactionResponse(tx, this);
|
||||
}
|
||||
_detectNetwork() {
|
||||
return throwError("sub-classes must implement this", "UNSUPPORTED_OPERATION", {
|
||||
@ -261,20 +272,14 @@ export class AbstractProvider {
|
||||
}
|
||||
// State
|
||||
async getBlockNumber() {
|
||||
return getNumber(await this.#perform({ method: "getBlockNumber" }), "%response");
|
||||
const blockNumber = getNumber(await this.#perform({ method: "getBlockNumber" }), "%response");
|
||||
if (this.#lastBlockNumber >= 0) {
|
||||
this.#lastBlockNumber = blockNumber;
|
||||
}
|
||||
return blockNumber;
|
||||
}
|
||||
// @TODO: Make this string | Promsie<string> so no await needed if sync is possible
|
||||
_getAddress(address) {
|
||||
return resolveAddress(address, this);
|
||||
/*
|
||||
if (typeof(address) === "string") {
|
||||
if (address.match(/^0x[0-9a-f]+$/i)) { return address; }
|
||||
const resolved = await this.resolveName(address);
|
||||
if (resolved == null) { throw new Error("not confiugred @TODO"); }
|
||||
return resolved;
|
||||
}
|
||||
return address.getAddress();
|
||||
*/
|
||||
}
|
||||
_getBlockTag(blockTag) {
|
||||
if (blockTag == null) {
|
||||
@ -299,236 +304,13 @@ export class AbstractProvider {
|
||||
if (blockTag >= 0) {
|
||||
return toQuantity(blockTag);
|
||||
}
|
||||
if (this.#lastBlockNumber >= 0) {
|
||||
return toQuantity(this.#lastBlockNumber + blockTag);
|
||||
}
|
||||
return this.getBlockNumber().then((b) => toQuantity(b + blockTag));
|
||||
}
|
||||
return throwArgumentError("invalid blockTag", "blockTag", blockTag);
|
||||
}
|
||||
async getNetwork() {
|
||||
// No explicit network was set and this is our first time
|
||||
if (this.#networkPromise == null) {
|
||||
// Detect the current network (shared with all calls)
|
||||
const detectNetwork = this._detectNetwork().then((network) => {
|
||||
this.emit("network", network, null);
|
||||
return network;
|
||||
}, (error) => {
|
||||
// Reset the networkPromise on failure, so we will try again
|
||||
if (this.#networkPromise === detectNetwork) {
|
||||
this.#networkPromise = null;
|
||||
}
|
||||
throw error;
|
||||
});
|
||||
this.#networkPromise = detectNetwork;
|
||||
return await detectNetwork;
|
||||
}
|
||||
const networkPromise = this.#networkPromise;
|
||||
const [expected, actual] = await Promise.all([
|
||||
networkPromise,
|
||||
this._detectNetwork() // The actual connected network
|
||||
]);
|
||||
if (expected.chainId !== actual.chainId) {
|
||||
if (this.#anyNetwork) {
|
||||
// The "any" network can change, so notify listeners
|
||||
this.emit("network", actual, expected);
|
||||
// Update the network if something else hasn't already changed it
|
||||
if (this.#networkPromise === networkPromise) {
|
||||
this.#networkPromise = Promise.resolve(actual);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Otherwise, we do not allow changes to the underlying network
|
||||
throwError(`network changed: ${expected.chainId} => ${actual.chainId} `, "NETWORK_ERROR", {
|
||||
event: "changed"
|
||||
});
|
||||
}
|
||||
}
|
||||
return expected.clone().freeze();
|
||||
}
|
||||
async getFeeData() {
|
||||
const { block, gasPrice } = await resolveProperties({
|
||||
block: this.getBlock("latest"),
|
||||
gasPrice: ((async () => {
|
||||
try {
|
||||
const gasPrice = await this.#perform({ method: "getGasPrice" });
|
||||
return getBigInt(gasPrice, "%response");
|
||||
}
|
||||
catch (error) { }
|
||||
return null;
|
||||
})())
|
||||
});
|
||||
let maxFeePerGas = null, maxPriorityFeePerGas = null;
|
||||
if (block && block.baseFeePerGas) {
|
||||
// We may want to compute this more accurately in the future,
|
||||
// using the formula "check if the base fee is correct".
|
||||
// See: https://eips.ethereum.org/EIPS/eip-1559
|
||||
maxPriorityFeePerGas = BigInt("1500000000");
|
||||
// Allow a network to override their maximum priority fee per gas
|
||||
//const priorityFeePlugin = (await this.getNetwork()).getPlugin<MaxPriorityFeePlugin>("org.ethers.plugins.max-priority-fee");
|
||||
//if (priorityFeePlugin) {
|
||||
// maxPriorityFeePerGas = await priorityFeePlugin.getPriorityFee(this);
|
||||
//}
|
||||
maxFeePerGas = (block.baseFeePerGas * BN_2) + maxPriorityFeePerGas;
|
||||
}
|
||||
return new FeeData(gasPrice, maxFeePerGas, maxPriorityFeePerGas);
|
||||
}
|
||||
async _getTransaction(_request) {
|
||||
const network = await this.getNetwork();
|
||||
// Fill in any addresses
|
||||
const request = Object.assign({}, _request, await resolveProperties({
|
||||
to: (_request.to ? resolveAddress(_request.to, this) : undefined),
|
||||
from: (_request.from ? resolveAddress(_request.from, this) : undefined),
|
||||
}));
|
||||
return network.formatter.transactionRequest(request);
|
||||
}
|
||||
async estimateGas(_tx) {
|
||||
const transaction = await this._getTransaction(_tx);
|
||||
return getBigInt(await this.#perform({
|
||||
method: "estimateGas", transaction
|
||||
}), "%response");
|
||||
}
|
||||
async #call(tx, blockTag, attempt) {
|
||||
if (attempt >= MAX_CCIP_REDIRECTS) {
|
||||
throwError("CCIP read exceeded maximum redirections", "OFFCHAIN_FAULT", {
|
||||
reason: "TOO_MANY_REDIRECTS",
|
||||
transaction: Object.assign({}, tx, { blockTag, enableCcipRead: true })
|
||||
});
|
||||
}
|
||||
const transaction = copyRequest(tx);
|
||||
try {
|
||||
return hexlify(await this._perform({ method: "call", transaction, blockTag }));
|
||||
}
|
||||
catch (error) {
|
||||
// CCIP Read OffchainLookup
|
||||
if (!this.disableCcipRead && isCallException(error) && attempt >= 0 && blockTag === "latest" && transaction.to != null && dataSlice(error.data, 0, 4) === "0x556f1830") {
|
||||
const data = error.data;
|
||||
const txSender = await resolveAddress(transaction.to, this);
|
||||
// Parse the CCIP Read Arguments
|
||||
let ccipArgs;
|
||||
try {
|
||||
ccipArgs = parseOffchainLookup(dataSlice(error.data, 4));
|
||||
}
|
||||
catch (error) {
|
||||
return throwError(error.message, "OFFCHAIN_FAULT", {
|
||||
reason: "BAD_DATA",
|
||||
transaction, info: { data }
|
||||
});
|
||||
}
|
||||
// Check the sender of the OffchainLookup matches the transaction
|
||||
if (ccipArgs.sender.toLowerCase() !== txSender.toLowerCase()) {
|
||||
return throwError("CCIP Read sender mismatch", "CALL_EXCEPTION", {
|
||||
data, transaction,
|
||||
errorSignature: "OffchainLookup(address,string[],bytes,bytes4,bytes)",
|
||||
errorName: "OffchainLookup",
|
||||
errorArgs: ccipArgs.errorArgs
|
||||
});
|
||||
}
|
||||
const ccipResult = await this.ccipReadFetch(transaction, ccipArgs.calldata, ccipArgs.urls);
|
||||
if (ccipResult == null) {
|
||||
return throwError("CCIP Read failed to fetch data", "OFFCHAIN_FAULT", {
|
||||
reason: "FETCH_FAILED",
|
||||
transaction, info: { data: error.data, errorArgs: ccipArgs.errorArgs }
|
||||
});
|
||||
}
|
||||
return this.#call({
|
||||
to: txSender,
|
||||
data: concat([
|
||||
ccipArgs.selector, encodeBytes([ccipResult, ccipArgs.extraData])
|
||||
]),
|
||||
}, blockTag, attempt + 1);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
async call(_tx) {
|
||||
const [tx, blockTag] = await Promise.all([
|
||||
this._getTransaction(_tx), this._getBlockTag(_tx.blockTag)
|
||||
]);
|
||||
return this.#call(tx, blockTag, _tx.enableCcipRead ? 0 : -1);
|
||||
}
|
||||
// Account
|
||||
async #getAccountValue(request, _address, _blockTag) {
|
||||
let address = this._getAddress(_address);
|
||||
let blockTag = this._getBlockTag(_blockTag);
|
||||
if (typeof (address) !== "string" || typeof (blockTag) !== "string") {
|
||||
[address, blockTag] = await Promise.all([address, blockTag]);
|
||||
}
|
||||
return await this.#perform(Object.assign(request, { address, blockTag }));
|
||||
}
|
||||
async getBalance(address, blockTag) {
|
||||
return getBigInt(await this.#getAccountValue({ method: "getBalance" }, address, blockTag), "%response");
|
||||
}
|
||||
async getTransactionCount(address, blockTag) {
|
||||
return getNumber(await this.#getAccountValue({ method: "getTransactionCount" }, address, blockTag), "%response");
|
||||
}
|
||||
async getCode(address, blockTag) {
|
||||
return hexlify(await this.#getAccountValue({ method: "getCode" }, address, blockTag));
|
||||
}
|
||||
async getStorageAt(address, _position, blockTag) {
|
||||
const position = getBigInt(_position, "position");
|
||||
return hexlify(await this.#getAccountValue({ method: "getStorageAt", position }, address, blockTag));
|
||||
}
|
||||
// Write
|
||||
async broadcastTransaction(signedTx) {
|
||||
throw new Error();
|
||||
return {};
|
||||
}
|
||||
async #getBlock(block, includeTransactions) {
|
||||
if (isHexString(block, 32)) {
|
||||
return await this.#perform({
|
||||
method: "getBlock", blockHash: block, includeTransactions
|
||||
});
|
||||
}
|
||||
let blockTag = this._getBlockTag(block);
|
||||
if (typeof (blockTag) !== "string") {
|
||||
blockTag = await blockTag;
|
||||
}
|
||||
return await this.#perform({
|
||||
method: "getBlock", blockTag, includeTransactions
|
||||
});
|
||||
}
|
||||
// Queries
|
||||
async getBlock(block) {
|
||||
const [network, params] = await Promise.all([
|
||||
this.getNetwork(), this.#getBlock(block, false)
|
||||
]);
|
||||
if (params == null) {
|
||||
return null;
|
||||
}
|
||||
return network.formatter.block(params, this);
|
||||
}
|
||||
async getBlockWithTransactions(block) {
|
||||
const format = (await this.getNetwork()).formatter;
|
||||
const params = this.#getBlock(block, true);
|
||||
if (params == null) {
|
||||
return null;
|
||||
}
|
||||
return format.blockWithTransactions(params, this);
|
||||
}
|
||||
async getTransaction(hash) {
|
||||
const format = (await this.getNetwork()).formatter;
|
||||
const params = await this.#perform({ method: "getTransaction", hash });
|
||||
return format.transactionResponse(params, this);
|
||||
}
|
||||
async getTransactionReceipt(hash) {
|
||||
const format = (await this.getNetwork()).formatter;
|
||||
const receipt = await this.#perform({ method: "getTransactionReceipt", hash });
|
||||
if (receipt == null) {
|
||||
return null;
|
||||
}
|
||||
// Some backends did not backfill the effectiveGasPrice into old transactions
|
||||
// in the receipt, so we look it up manually and inject it.
|
||||
if (receipt.gasPrice == null && receipt.effectiveGasPrice == null) {
|
||||
const tx = await this.#perform({ method: "getTransaction", hash });
|
||||
receipt.effectiveGasPrice = tx.gasPrice;
|
||||
}
|
||||
return format.receipt(receipt, this);
|
||||
}
|
||||
async getTransactionResult(hash) {
|
||||
const result = await this.#perform({ method: "getTransactionResult", hash });
|
||||
if (result == null) {
|
||||
return null;
|
||||
}
|
||||
return hexlify(result);
|
||||
}
|
||||
_getFilter(filter) {
|
||||
// Create a canonical representation of the topics
|
||||
const topics = (filter.topics || []).map((t) => {
|
||||
@ -604,15 +386,295 @@ export class AbstractProvider {
|
||||
}
|
||||
return resolve(address, fromBlock, toBlock);
|
||||
}
|
||||
_getTransactionRequest(_request) {
|
||||
const request = copyRequest(_request);
|
||||
const promises = [];
|
||||
["to", "from"].forEach((key) => {
|
||||
if (request[key] == null) {
|
||||
return;
|
||||
}
|
||||
const addr = resolveAddress(request[key]);
|
||||
if (isPromise(addr)) {
|
||||
promises.push((async function () { request[key] = await addr; })());
|
||||
}
|
||||
else {
|
||||
request[key] = addr;
|
||||
}
|
||||
});
|
||||
if (request.blockTag != null) {
|
||||
const blockTag = this._getBlockTag(request.blockTag);
|
||||
if (isPromise(blockTag)) {
|
||||
promises.push((async function () { request.blockTag = await blockTag; })());
|
||||
}
|
||||
else {
|
||||
request.blockTag = blockTag;
|
||||
}
|
||||
}
|
||||
if (promises.length) {
|
||||
return (async function () {
|
||||
await Promise.all(promises);
|
||||
return request;
|
||||
})();
|
||||
}
|
||||
return request;
|
||||
}
|
||||
async getNetwork() {
|
||||
// No explicit network was set and this is our first time
|
||||
if (this.#networkPromise == null) {
|
||||
// Detect the current network (shared with all calls)
|
||||
const detectNetwork = this._detectNetwork().then((network) => {
|
||||
this.emit("network", network, null);
|
||||
return network;
|
||||
}, (error) => {
|
||||
// Reset the networkPromise on failure, so we will try again
|
||||
if (this.#networkPromise === detectNetwork) {
|
||||
this.#networkPromise = null;
|
||||
}
|
||||
throw error;
|
||||
});
|
||||
this.#networkPromise = detectNetwork;
|
||||
return (await detectNetwork).clone();
|
||||
}
|
||||
const networkPromise = this.#networkPromise;
|
||||
const [expected, actual] = await Promise.all([
|
||||
networkPromise,
|
||||
this._detectNetwork() // The actual connected network
|
||||
]);
|
||||
if (expected.chainId !== actual.chainId) {
|
||||
if (this.#anyNetwork) {
|
||||
// The "any" network can change, so notify listeners
|
||||
this.emit("network", actual, expected);
|
||||
// Update the network if something else hasn't already changed it
|
||||
if (this.#networkPromise === networkPromise) {
|
||||
this.#networkPromise = Promise.resolve(actual);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Otherwise, we do not allow changes to the underlying network
|
||||
throwError(`network changed: ${expected.chainId} => ${actual.chainId} `, "NETWORK_ERROR", {
|
||||
event: "changed"
|
||||
});
|
||||
}
|
||||
}
|
||||
return expected.clone();
|
||||
}
|
||||
async getFeeData() {
|
||||
const { block, gasPrice } = await resolveProperties({
|
||||
block: this.getBlock("latest"),
|
||||
gasPrice: ((async () => {
|
||||
try {
|
||||
const gasPrice = await this.#perform({ method: "getGasPrice" });
|
||||
return getBigInt(gasPrice, "%response");
|
||||
}
|
||||
catch (error) { }
|
||||
return null;
|
||||
})())
|
||||
});
|
||||
let maxFeePerGas = null, maxPriorityFeePerGas = null;
|
||||
if (block && block.baseFeePerGas) {
|
||||
// We may want to compute this more accurately in the future,
|
||||
// using the formula "check if the base fee is correct".
|
||||
// See: https://eips.ethereum.org/EIPS/eip-1559
|
||||
maxPriorityFeePerGas = BigInt("1500000000");
|
||||
// Allow a network to override their maximum priority fee per gas
|
||||
//const priorityFeePlugin = (await this.getNetwork()).getPlugin<MaxPriorityFeePlugin>("org.ethers.plugins.max-priority-fee");
|
||||
//if (priorityFeePlugin) {
|
||||
// maxPriorityFeePerGas = await priorityFeePlugin.getPriorityFee(this);
|
||||
//}
|
||||
maxFeePerGas = (block.baseFeePerGas * BN_2) + maxPriorityFeePerGas;
|
||||
}
|
||||
return new FeeData(gasPrice, maxFeePerGas, maxPriorityFeePerGas);
|
||||
}
|
||||
async estimateGas(_tx) {
|
||||
let tx = this._getTransactionRequest(_tx);
|
||||
if (isPromise(tx)) {
|
||||
tx = await tx;
|
||||
}
|
||||
return getBigInt(await this.#perform({
|
||||
method: "estimateGas", transaction: tx
|
||||
}), "%response");
|
||||
}
|
||||
async #call(tx, blockTag, attempt) {
|
||||
if (attempt >= MAX_CCIP_REDIRECTS) {
|
||||
throwError("CCIP read exceeded maximum redirections", "OFFCHAIN_FAULT", {
|
||||
reason: "TOO_MANY_REDIRECTS",
|
||||
transaction: Object.assign({}, tx, { blockTag, enableCcipRead: true })
|
||||
});
|
||||
}
|
||||
// This came in as a PerformActionTransaction, so to/from are safe; we can cast
|
||||
const transaction = copyRequest(tx);
|
||||
try {
|
||||
return hexlify(await this._perform({ method: "call", transaction, blockTag }));
|
||||
}
|
||||
catch (error) {
|
||||
// CCIP Read OffchainLookup
|
||||
if (!this.disableCcipRead && isCallException(error) && attempt >= 0 && blockTag === "latest" && transaction.to != null && dataSlice(error.data, 0, 4) === "0x556f1830") {
|
||||
const data = error.data;
|
||||
const txSender = await resolveAddress(transaction.to, this);
|
||||
// Parse the CCIP Read Arguments
|
||||
let ccipArgs;
|
||||
try {
|
||||
ccipArgs = parseOffchainLookup(dataSlice(error.data, 4));
|
||||
}
|
||||
catch (error) {
|
||||
return throwError(error.message, "OFFCHAIN_FAULT", {
|
||||
reason: "BAD_DATA",
|
||||
transaction, info: { data }
|
||||
});
|
||||
}
|
||||
// Check the sender of the OffchainLookup matches the transaction
|
||||
if (ccipArgs.sender.toLowerCase() !== txSender.toLowerCase()) {
|
||||
return throwError("CCIP Read sender mismatch", "CALL_EXCEPTION", {
|
||||
data, transaction,
|
||||
errorSignature: "OffchainLookup(address,string[],bytes,bytes4,bytes)",
|
||||
errorName: "OffchainLookup",
|
||||
errorArgs: ccipArgs.errorArgs
|
||||
});
|
||||
}
|
||||
const ccipResult = await this.ccipReadFetch(transaction, ccipArgs.calldata, ccipArgs.urls);
|
||||
if (ccipResult == null) {
|
||||
return throwError("CCIP Read failed to fetch data", "OFFCHAIN_FAULT", {
|
||||
reason: "FETCH_FAILED",
|
||||
transaction, info: { data: error.data, errorArgs: ccipArgs.errorArgs }
|
||||
});
|
||||
}
|
||||
return this.#call({
|
||||
to: txSender,
|
||||
data: concat([
|
||||
ccipArgs.selector, encodeBytes([ccipResult, ccipArgs.extraData])
|
||||
]),
|
||||
}, blockTag, attempt + 1);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
async #checkNetwork(promise) {
|
||||
const { value } = await resolveProperties({
|
||||
network: this.getNetwork(),
|
||||
value: promise
|
||||
});
|
||||
return value;
|
||||
}
|
||||
async call(_tx) {
|
||||
const { tx, blockTag } = await resolveProperties({
|
||||
tx: this._getTransactionRequest(_tx),
|
||||
blockTag: this._getBlockTag(_tx.blockTag)
|
||||
});
|
||||
return await this.#checkNetwork(this.#call(tx, blockTag, _tx.enableCcipRead ? 0 : -1));
|
||||
}
|
||||
// Account
|
||||
async #getAccountValue(request, _address, _blockTag) {
|
||||
let address = this._getAddress(_address);
|
||||
let blockTag = this._getBlockTag(_blockTag);
|
||||
if (typeof (address) !== "string" || typeof (blockTag) !== "string") {
|
||||
[address, blockTag] = await Promise.all([address, blockTag]);
|
||||
}
|
||||
return await this.#checkNetwork(this.#perform(Object.assign(request, { address, blockTag })));
|
||||
}
|
||||
async getBalance(address, blockTag) {
|
||||
return getBigInt(await this.#getAccountValue({ method: "getBalance" }, address, blockTag), "%response");
|
||||
}
|
||||
async getTransactionCount(address, blockTag) {
|
||||
return getNumber(await this.#getAccountValue({ method: "getTransactionCount" }, address, blockTag), "%response");
|
||||
}
|
||||
async getCode(address, blockTag) {
|
||||
return hexlify(await this.#getAccountValue({ method: "getCode" }, address, blockTag));
|
||||
}
|
||||
async getStorageAt(address, _position, blockTag) {
|
||||
const position = getBigInt(_position, "position");
|
||||
return hexlify(await this.#getAccountValue({ method: "getStorageAt", position }, address, blockTag));
|
||||
}
|
||||
// Write
|
||||
async broadcastTransaction(signedTx) {
|
||||
throw new Error();
|
||||
return {};
|
||||
}
|
||||
async #getBlock(block, includeTransactions) {
|
||||
// @TODO: Add CustomBlockPlugin check
|
||||
if (isHexString(block, 32)) {
|
||||
return await this.#perform({
|
||||
method: "getBlock", blockHash: block, includeTransactions
|
||||
});
|
||||
}
|
||||
let blockTag = this._getBlockTag(block);
|
||||
if (typeof (blockTag) !== "string") {
|
||||
blockTag = await blockTag;
|
||||
}
|
||||
return await this.#perform({
|
||||
method: "getBlock", blockTag, includeTransactions
|
||||
});
|
||||
}
|
||||
// Queries
|
||||
async getBlock(block) {
|
||||
const { network, params } = await resolveProperties({
|
||||
network: this.getNetwork(),
|
||||
params: this.#getBlock(block, false)
|
||||
});
|
||||
if (params == null) {
|
||||
return null;
|
||||
}
|
||||
return this._wrapBlock(formatBlock(params), network);
|
||||
}
|
||||
async getBlockWithTransactions(block) {
|
||||
const { network, params } = await resolveProperties({
|
||||
network: this.getNetwork(),
|
||||
params: this.#getBlock(block, true)
|
||||
});
|
||||
if (params == null) {
|
||||
return null;
|
||||
}
|
||||
return this._wrapBlockWithTransactions(formatBlockWithTransactions(params), network);
|
||||
}
|
||||
async getTransaction(hash) {
|
||||
const { network, params } = await resolveProperties({
|
||||
network: this.getNetwork(),
|
||||
params: this.#perform({ method: "getTransaction", hash })
|
||||
});
|
||||
if (params == null) {
|
||||
return null;
|
||||
}
|
||||
return this._wrapTransactionResponse(formatTransactionResponse(params), network);
|
||||
}
|
||||
async getTransactionReceipt(hash) {
|
||||
const { network, params } = await resolveProperties({
|
||||
network: this.getNetwork(),
|
||||
params: this.#perform({ method: "getTransactionReceipt", hash })
|
||||
});
|
||||
if (params == null) {
|
||||
return null;
|
||||
}
|
||||
// Some backends did not backfill the effectiveGasPrice into old transactions
|
||||
// in the receipt, so we look it up manually and inject it.
|
||||
if (params.gasPrice == null && params.effectiveGasPrice == null) {
|
||||
const tx = await this.#perform({ method: "getTransaction", hash });
|
||||
if (tx == null) {
|
||||
throw new Error("report this; could not find tx or effectiveGasPrice");
|
||||
}
|
||||
params.effectiveGasPrice = tx.gasPrice;
|
||||
}
|
||||
return this._wrapTransactionReceipt(formatTransactionReceipt(params), network);
|
||||
}
|
||||
async getTransactionResult(hash) {
|
||||
const { result } = await resolveProperties({
|
||||
network: this.getNetwork(),
|
||||
result: this.#perform({ method: "getTransactionResult", hash })
|
||||
});
|
||||
if (result == null) {
|
||||
return null;
|
||||
}
|
||||
return hexlify(result);
|
||||
}
|
||||
// Bloom-filter Queries
|
||||
async getLogs(_filter) {
|
||||
const { network, filter } = await resolveProperties({
|
||||
let filter = this._getFilter(_filter);
|
||||
if (isPromise(filter)) {
|
||||
filter = await filter;
|
||||
}
|
||||
const { network, params } = await resolveProperties({
|
||||
network: this.getNetwork(),
|
||||
filter: this._getFilter(_filter)
|
||||
});
|
||||
return (await this.#perform({ method: "getLogs", filter })).map((l) => {
|
||||
return network.formatter.log(l, this);
|
||||
params: this.#perform({ method: "getLogs", filter })
|
||||
});
|
||||
return params.map((p) => this._wrapLog(formatLog(p), network));
|
||||
}
|
||||
// ENS
|
||||
_getProvider(chainId) {
|
||||
@ -922,6 +984,7 @@ export class AbstractProvider {
|
||||
}
|
||||
}
|
||||
pause(dropWhilePaused) {
|
||||
this.#lastBlockNumber = -1;
|
||||
if (this.#pausedState != null) {
|
||||
if (this.#pausedState == !!dropWhilePaused) {
|
||||
return;
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -3,7 +3,7 @@
|
||||
* networks injected registered.
|
||||
*/
|
||||
import { EnsPlugin, GasCostPlugin } from "./plugins-network.js";
|
||||
import { EtherscanPlugin } from "./provider-etherscan.js";
|
||||
import { EtherscanPlugin } from "./provider-etherscan-base.js";
|
||||
import { Network } from "./network.js";
|
||||
// See: https://chainlist.org
|
||||
export function injectCommonNetworks() {
|
||||
|
@ -1 +1 @@
|
||||
{"version":3,"file":"common-networks.js","sourceRoot":"","sources":["../../src.ts/providers/common-networks.ts"],"names":[],"mappings":"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"}
|
||||
{"version":3,"file":"common-networks.js","sourceRoot":"","sources":["../../src.ts/providers/common-networks.ts"],"names":[],"mappings":"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"}
|
@ -1,3 +1,4 @@
|
||||
import { getAddress } from "../address/index.js";
|
||||
import { ZeroHash } from "../constants/hashes.js";
|
||||
import { dnsEncode, namehash } from "../hash/index.js";
|
||||
import { concat, dataSlice, getBytes, hexlify, zeroPadValue, defineProperties, encodeBase58, getBigInt, toArray, toNumber, toUtf8Bytes, toUtf8String, throwArgumentError, throwError, FetchRequest } from "../utils/index.js";
|
||||
@ -58,6 +59,12 @@ function encodeBytes(datas) {
|
||||
}
|
||||
return concat(result);
|
||||
}
|
||||
function callAddress(value) {
|
||||
if (value.length !== 66 || dataSlice(value, 0, 12) !== "0x000000000000000000000000") {
|
||||
throwArgumentError("invalid call address", "value", value);
|
||||
}
|
||||
return getAddress("0x" + value.substring(26));
|
||||
}
|
||||
// @TODO: This should use the fetch-data:ipfs gateway
|
||||
// Trim off the ipfs:// prefix and return the default gateway URL
|
||||
function getIpfsLink(link) {
|
||||
@ -174,11 +181,10 @@ export class EnsResolver {
|
||||
// keccak256("addr(bytes32)")
|
||||
const result = await this._fetch("0x3b3b57de");
|
||||
// No address
|
||||
if (result === "0x" || result === ZeroHash) {
|
||||
if (result == null || result === "0x" || result === ZeroHash) {
|
||||
return null;
|
||||
}
|
||||
const network = await this.provider.getNetwork();
|
||||
return network.formatter.callAddress(result);
|
||||
return callAddress(result);
|
||||
}
|
||||
catch (error) {
|
||||
if (error.code === "CALL_EXCEPTION") {
|
||||
@ -301,13 +307,12 @@ export class EnsResolver {
|
||||
linkage.push({ type: `!${scheme}caip`, value: (match[2] || "") });
|
||||
throw new Error("!caip");
|
||||
}
|
||||
const formatter = (await this.provider.getNetwork()).formatter;
|
||||
const addr = formatter.address(comps[0]);
|
||||
const addr = getAddress(comps[0]);
|
||||
const tokenId = numPad(comps[1]);
|
||||
// Check that this account owns the token
|
||||
if (scheme === "erc721") {
|
||||
// ownerOf(uint256 tokenId)
|
||||
const tokenOwner = formatter.callAddress(await this.provider.call({
|
||||
const tokenOwner = callAddress(await this.provider.call({
|
||||
to: addr, data: concat(["0x6352211e", tokenId])
|
||||
}));
|
||||
if (owner !== tokenOwner) {
|
||||
@ -419,7 +424,7 @@ export class EnsResolver {
|
||||
data: concat(["0x0178b8bf", namehash(name)]),
|
||||
enableCcipRead: true
|
||||
});
|
||||
const addr = network.formatter.callAddress(addrData);
|
||||
const addr = callAddress(addrData);
|
||||
if (addr === dataSlice(ZeroHash, 0, 20)) {
|
||||
return null;
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
229
lib.esm/providers/format.js
Normal file
229
lib.esm/providers/format.js
Normal file
@ -0,0 +1,229 @@
|
||||
import { getAddress, getCreateAddress } from "../address/index.js";
|
||||
import { accessListify } from "../transaction/index.js";
|
||||
import { getBigInt, getNumber, hexlify, isHexString, zeroPadValue, throwArgumentError, throwError } from "../utils/index.js";
|
||||
const BN_0 = BigInt(0);
|
||||
export function allowNull(format, nullValue) {
|
||||
return (function (value) {
|
||||
if (value == null) {
|
||||
return nullValue;
|
||||
}
|
||||
return format(value);
|
||||
});
|
||||
}
|
||||
export function arrayOf(format) {
|
||||
return ((array) => {
|
||||
if (!Array.isArray(array)) {
|
||||
throw new Error("not an array");
|
||||
}
|
||||
return array.map((i) => format(i));
|
||||
});
|
||||
}
|
||||
// Requires an object which matches a fleet of other formatters
|
||||
// Any FormatFunc may return `undefined` to have the value omitted
|
||||
// from the result object. Calls preserve `this`.
|
||||
export function object(format, altNames) {
|
||||
return ((value) => {
|
||||
const result = {};
|
||||
for (const key in format) {
|
||||
let srcKey = key;
|
||||
if (altNames && key in altNames && !(srcKey in value)) {
|
||||
for (const altKey of altNames[key]) {
|
||||
if (altKey in value) {
|
||||
srcKey = altKey;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
const nv = format[key](value[srcKey]);
|
||||
if (nv !== undefined) {
|
||||
result[key] = nv;
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
const message = (error instanceof Error) ? error.message : "not-an-error";
|
||||
throwError(`invalid value for value.${key} (${message})`, "BAD_DATA", { value });
|
||||
}
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
export function formatBoolean(value) {
|
||||
switch (value) {
|
||||
case true:
|
||||
case "true":
|
||||
return true;
|
||||
case false:
|
||||
case "false":
|
||||
return false;
|
||||
}
|
||||
return throwArgumentError(`invalid boolean; ${JSON.stringify(value)}`, "value", value);
|
||||
}
|
||||
export function formatData(value) {
|
||||
if (!isHexString(value, true)) {
|
||||
throwArgumentError("", "value", value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
export function formatHash(value) {
|
||||
if (!isHexString(value, 32)) {
|
||||
throwArgumentError("", "value", value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
export function formatUint256(value) {
|
||||
if (!isHexString(value)) {
|
||||
throw new Error("invalid uint256");
|
||||
}
|
||||
return zeroPadValue(value, 32);
|
||||
}
|
||||
export const formatLog = object({
|
||||
address: getAddress,
|
||||
blockHash: formatHash,
|
||||
blockNumber: getNumber,
|
||||
data: formatData,
|
||||
index: getNumber,
|
||||
removed: formatBoolean,
|
||||
topics: arrayOf(formatHash),
|
||||
transactionHash: formatHash,
|
||||
transactionIndex: getNumber,
|
||||
}, {
|
||||
index: ["logIndex"]
|
||||
});
|
||||
function _formatBlock(txFunc) {
|
||||
return object({
|
||||
hash: allowNull(formatHash),
|
||||
parentHash: formatHash,
|
||||
number: getNumber,
|
||||
timestamp: getNumber,
|
||||
nonce: allowNull(formatData),
|
||||
difficulty: getBigInt,
|
||||
gasLimit: getBigInt,
|
||||
gasUsed: getBigInt,
|
||||
miner: allowNull(getAddress),
|
||||
extraData: formatData,
|
||||
transactions: arrayOf(txFunc),
|
||||
baseFeePerGas: allowNull(getBigInt)
|
||||
});
|
||||
}
|
||||
export const formatBlock = _formatBlock(formatHash);
|
||||
export const formatBlockWithTransactions = _formatBlock(formatTransactionResponse);
|
||||
export const formatReceiptLog = object({
|
||||
transactionIndex: getNumber,
|
||||
blockNumber: getNumber,
|
||||
transactionHash: formatHash,
|
||||
address: getAddress,
|
||||
topics: arrayOf(formatHash),
|
||||
data: formatData,
|
||||
logIndex: getNumber,
|
||||
blockHash: formatHash,
|
||||
});
|
||||
export const formatTransactionReceipt = object({
|
||||
to: allowNull(getAddress, null),
|
||||
from: allowNull(getAddress, null),
|
||||
contractAddress: allowNull(getAddress, null),
|
||||
transactionIndex: getNumber,
|
||||
// should be allowNull(hash), but broken-EIP-658 support is handled in receipt
|
||||
root: allowNull(hexlify),
|
||||
gasUsed: getBigInt,
|
||||
logsBloom: allowNull(formatData),
|
||||
blockHash: formatHash,
|
||||
transactionHash: formatHash,
|
||||
logs: arrayOf(formatReceiptLog),
|
||||
blockNumber: getNumber,
|
||||
confirmations: allowNull(getNumber, null),
|
||||
cumulativeGasUsed: getBigInt,
|
||||
effectiveGasPrice: allowNull(getBigInt),
|
||||
status: allowNull(getNumber),
|
||||
type: getNumber
|
||||
}, {
|
||||
effectiveGasPrice: ["gasPrice"]
|
||||
});
|
||||
export function formatTransactionResponse(value) {
|
||||
// Some clients (TestRPC) do strange things like return 0x0 for the
|
||||
// 0 address; correct this to be a real address
|
||||
if (value.to && getBigInt(value.to) === BN_0) {
|
||||
value.to = "0x0000000000000000000000000000000000000000";
|
||||
}
|
||||
const result = object({
|
||||
hash: formatHash,
|
||||
type: (value) => {
|
||||
if (value === "0x" || value == null) {
|
||||
return 0;
|
||||
}
|
||||
return getNumber(value);
|
||||
},
|
||||
accessList: allowNull(accessListify, null),
|
||||
blockHash: allowNull(formatHash, null),
|
||||
blockNumber: allowNull(getNumber, null),
|
||||
transactionIndex: allowNull(getNumber, null),
|
||||
confirmations: allowNull(getNumber, null),
|
||||
from: getAddress,
|
||||
// either (gasPrice) or (maxPriorityFeePerGas + maxFeePerGas) must be set
|
||||
gasPrice: allowNull(getBigInt),
|
||||
maxPriorityFeePerGas: allowNull(getBigInt),
|
||||
maxFeePerGas: allowNull(getBigInt),
|
||||
gasLimit: getBigInt,
|
||||
to: allowNull(getAddress, null),
|
||||
value: getBigInt,
|
||||
nonce: getNumber,
|
||||
data: formatData,
|
||||
r: allowNull(formatUint256),
|
||||
s: allowNull(formatUint256),
|
||||
v: allowNull(getNumber),
|
||||
creates: allowNull(getAddress, null),
|
||||
chainId: allowNull(getBigInt, null)
|
||||
}, {
|
||||
data: ["input"],
|
||||
gasLimit: ["gas"]
|
||||
})(value);
|
||||
// If to and creates are empty, populate the creates from the value
|
||||
if (result.to == null && result.creates == null) {
|
||||
result.creates = getCreateAddress(result);
|
||||
}
|
||||
// @TODO: Check fee data
|
||||
// Add an access list to supported transaction types
|
||||
if ((value.type === 1 || value.type === 2) && value.accessList == null) {
|
||||
value.accessList = [];
|
||||
}
|
||||
// @TODO: check chainID
|
||||
/*
|
||||
if (value.chainId != null) {
|
||||
let chainId = value.chainId;
|
||||
|
||||
if (isHexString(chainId)) {
|
||||
chainId = BigNumber.from(chainId).toNumber();
|
||||
}
|
||||
|
||||
result.chainId = chainId;
|
||||
|
||||
} else {
|
||||
let chainId = value.networkId;
|
||||
|
||||
// geth-etc returns chainId
|
||||
if (chainId == null && result.v == null) {
|
||||
chainId = value.chainId;
|
||||
}
|
||||
|
||||
if (isHexString(chainId)) {
|
||||
chainId = BigNumber.from(chainId).toNumber();
|
||||
}
|
||||
|
||||
if (typeof(chainId) !== "number" && result.v != null) {
|
||||
chainId = (result.v - 35) / 2;
|
||||
if (chainId < 0) { chainId = 0; }
|
||||
chainId = parseInt(chainId);
|
||||
}
|
||||
|
||||
if (typeof(chainId) !== "number") { chainId = 0; }
|
||||
|
||||
result.chainId = chainId;
|
||||
}
|
||||
*/
|
||||
// 0x0000... should actually be null
|
||||
if (result.blockHash && getBigInt(result.blockHash) === BN_0) {
|
||||
result.blockHash = null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
//# sourceMappingURL=format.js.map
|
1
lib.esm/providers/format.js.map
Normal file
1
lib.esm/providers/format.js.map
Normal file
File diff suppressed because one or more lines are too long
@ -1,3 +1,4 @@
|
||||
"use strict";
|
||||
// Belongs to Networks; requires abstract-provider
|
||||
// provider requires abstract-provider and network
|
||||
/**
|
||||
@ -13,26 +14,56 @@
|
||||
* Network object this allows exotic (non-Ethereum) networks
|
||||
* to be fairly simple to adapt to ethers.
|
||||
*/
|
||||
/*
|
||||
import { getAddress, getCreateAddress } from "../address/index.js";
|
||||
import { dataLength, dataSlice, getBigInt, getNumber, isHexString, toQuantity, throwArgumentError, throwError } from "../utils/index.js";
|
||||
import {
|
||||
dataLength, dataSlice, getBigInt, getNumber, isHexString, toQuantity,
|
||||
throwArgumentError, throwError
|
||||
} from "../utils/index.js";
|
||||
import { Signature } from "../crypto/signature.js";
|
||||
import { accessListify } from "../transaction/index.js";
|
||||
|
||||
import { Block, Log, TransactionReceipt, TransactionResponse } from "./provider.js";
|
||||
|
||||
import type { AccessList } from "../transaction/index.js";
|
||||
|
||||
import type { PerformActionTransaction } from "./abstract-provider.js";
|
||||
import type { Filter, Provider } from "./provider.js";
|
||||
|
||||
|
||||
const BN_MAX_UINT256 = BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
|
||||
|
||||
export type FormatFunc = (value: any) => any;
|
||||
|
||||
//export type AccessListSet = { address: string, storageKeys: Array<string> };
|
||||
//export type AccessList = Array<AccessListSet>;
|
||||
|
||||
//export type AccessListish = AccessList |
|
||||
// Array<[ string, Array<string> ]> |
|
||||
// Record<string, Array<string>>;
|
||||
function stringify(value) {
|
||||
if (typeof (value) !== "string") {
|
||||
throw new Error("invalid string");
|
||||
}
|
||||
|
||||
function stringify(value: any): string {
|
||||
if (typeof(value) !== "string") { throw new Error("invalid string"); }
|
||||
return value;
|
||||
}
|
||||
|
||||
export class Formatter {
|
||||
#format;
|
||||
#baseBlock;
|
||||
#format: {
|
||||
address: FormatFunc,
|
||||
bigNumber: FormatFunc,
|
||||
blockTag: FormatFunc,
|
||||
data: FormatFunc,
|
||||
filter: FormatFunc,
|
||||
hash: FormatFunc,
|
||||
number: FormatFunc,
|
||||
topics: FormatFunc,
|
||||
transactionRequest: FormatFunc,
|
||||
transactionResponse: FormatFunc,
|
||||
uint256: FormatFunc,
|
||||
};
|
||||
|
||||
#baseBlock: FormatFunc;
|
||||
|
||||
constructor() {
|
||||
const address = this.address.bind(this);
|
||||
const bigNumber = this.bigNumber.bind(this);
|
||||
@ -41,7 +72,9 @@ export class Formatter {
|
||||
const hash = this.hash.bind(this);
|
||||
const number = this.number.bind(this);
|
||||
const uint256 = this.uint256.bind(this);
|
||||
|
||||
const topics = this.arrayOf(hash);
|
||||
|
||||
this.#format = {
|
||||
address,
|
||||
bigNumber,
|
||||
@ -50,7 +83,9 @@ export class Formatter {
|
||||
hash,
|
||||
number,
|
||||
uint256,
|
||||
|
||||
topics,
|
||||
|
||||
filter: this.object({
|
||||
fromBlock: this.allowNull(blockTag, undefined),
|
||||
toBlock: this.allowNull(blockTag, undefined),
|
||||
@ -58,6 +93,7 @@ export class Formatter {
|
||||
address: this.allowNull(address, undefined),
|
||||
topics: this.allowNull(topics, undefined)
|
||||
}),
|
||||
|
||||
transactionRequest: this.object({
|
||||
from: this.allowNull(address),
|
||||
type: this.allowNull(number),
|
||||
@ -70,21 +106,29 @@ export class Formatter {
|
||||
data: this.allowNull(data),
|
||||
value: this.allowNull(uint256),
|
||||
}),
|
||||
|
||||
transactionResponse: this.object({
|
||||
hash: hash,
|
||||
index: number,
|
||||
|
||||
type: this.allowNull(number, 0),
|
||||
|
||||
// These can be null for pending blocks
|
||||
blockHash: this.allowNull(hash),
|
||||
blockNumber: this.allowNull(number),
|
||||
|
||||
// For Legacy transactions, this comes from the v
|
||||
chainId: this.allowNull(number),
|
||||
|
||||
from: address,
|
||||
to: this.address,
|
||||
|
||||
gasLimit: bigNumber,
|
||||
|
||||
gasPrice: this.allowNull(bigNumber),
|
||||
maxFeePerGas: this.allowNull(bigNumber),
|
||||
maxPriorityFeePerGas: this.allowNull(bigNumber),
|
||||
|
||||
value: bigNumber,
|
||||
data: data,
|
||||
nonce: number,
|
||||
@ -96,89 +140,99 @@ export class Formatter {
|
||||
index: [ "transactionIndex" ]
|
||||
}),
|
||||
};
|
||||
|
||||
this.#baseBlock = this.object({
|
||||
number: number,
|
||||
hash: this.allowNull(hash, null),
|
||||
timestamp: number,
|
||||
|
||||
parentHash: hash,
|
||||
|
||||
nonce: this.allowNull(stringify, "0x0000000000000000"),
|
||||
difficulty: bigNumber,
|
||||
|
||||
gasLimit: bigNumber,
|
||||
gasUsed: bigNumber,
|
||||
miner: this.allowNull(address, "0x0000000000000000000000000000000000000000"),
|
||||
extraData: stringify,
|
||||
|
||||
baseFeePerGas: this.allowNull(bigNumber),
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// An address
|
||||
address(value) {
|
||||
address(value: any): string {
|
||||
return getAddress(value);
|
||||
}
|
||||
|
||||
// An address from a call result; may be zero-padded
|
||||
callAddress(value) {
|
||||
callAddress(value: any): string {
|
||||
if (dataLength(value) !== 32 || dataSlice(value, 0, 12) !== "0x000000000000000000000000") {
|
||||
throwArgumentError("invalid call address", "value", value);
|
||||
}
|
||||
return this.address(dataSlice(value, 12));
|
||||
}
|
||||
|
||||
// An address from a transaction (e.g. { from: string, nonce: number })
|
||||
contractAddress(value) {
|
||||
contractAddress(value: any): string {
|
||||
return getCreateAddress({
|
||||
from: this.address(value.from),
|
||||
nonce: getNumber(value.nonce, "value.nonce")
|
||||
});
|
||||
}
|
||||
|
||||
// Block Tag
|
||||
blockTag(value) {
|
||||
if (value == null) {
|
||||
return "latest";
|
||||
}
|
||||
blockTag(value?: any): string {
|
||||
if (value == null) { return "latest"; }
|
||||
|
||||
switch (value) {
|
||||
case "earliest":
|
||||
return "0x0";
|
||||
case "latest":
|
||||
case "pending":
|
||||
case "safe":
|
||||
case "finalized":
|
||||
case "latest": case "pending": case "safe": case "finalized":
|
||||
return value;
|
||||
}
|
||||
|
||||
if (typeof(value) === "number" || (isHexString(value) && dataLength(value) < 32)) {
|
||||
return toQuantity(value);
|
||||
}
|
||||
|
||||
return throwArgumentError("invalid blockTag", "value", value);
|
||||
}
|
||||
|
||||
// Block objects
|
||||
block(value, provider) {
|
||||
block(value: any, provider?: Provider): Block<string> {
|
||||
const params = this.#baseBlock(value);
|
||||
params.transactions = value.transactions.map((t) => this.hash(t));
|
||||
params.transactions = value.transactions.map((t: any) => this.hash(t));
|
||||
return new Block(params, provider);
|
||||
}
|
||||
blockWithTransactions(value, provider) {
|
||||
blockWithTransactions(value: any, provider?: Provider): Block<TransactionResponse> {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
// Transactions
|
||||
transactionRequest(value, provider) {
|
||||
transactionRequest(value: any, provider?: Provider): PerformActionTransaction {
|
||||
return this.#format.transactionRequest(value);
|
||||
}
|
||||
transactionResponse(value, provider) {
|
||||
|
||||
transactionResponse(value: any, provider?: Provider): TransactionResponse {
|
||||
value = Object.assign({ }, value);
|
||||
|
||||
// @TODO: Use the remap feature
|
||||
if (value.data == null && value.input != null) {
|
||||
value.data = value.input;
|
||||
}
|
||||
if (value.gasLimit == null && value.gas) {
|
||||
value.gasLimit = value.gas;
|
||||
}
|
||||
if (value.data == null && value.input != null) { value.data = value.input; }
|
||||
if (value.gasLimit == null && value.gas) { value.gasLimit = value.gas; }
|
||||
|
||||
value = this.#format.transactionResponse(value);
|
||||
|
||||
const sig = Signature.from({ r: value.r, s: value.s, v: value.v });
|
||||
value.signature = sig;
|
||||
if (value.chainId == null) {
|
||||
value.chainId = sig.legacyChainId;
|
||||
}
|
||||
if (value.chainId == null) { value.chainId = sig.legacyChainId; }
|
||||
|
||||
return new TransactionResponse(value, provider);
|
||||
}
|
||||
|
||||
// Receipts
|
||||
log(value, provider) {
|
||||
log(value: any, provider?: Provider): Log {
|
||||
const log = this.object({
|
||||
address: this.address,
|
||||
blockHash: this.hash,
|
||||
@ -194,7 +248,8 @@ export class Formatter {
|
||||
})(value);
|
||||
return new Log(log, provider);
|
||||
}
|
||||
receipt(value, provider) {
|
||||
|
||||
receipt(value: any, provider?: Provider): TransactionReceipt {
|
||||
const receipt = this.object({
|
||||
blockHash: this.hash,
|
||||
blockNumber: this.number,
|
||||
@ -202,7 +257,7 @@ export class Formatter {
|
||||
cumulativeGasUsed: this.bigNumber,
|
||||
from: this.address,
|
||||
gasUsed: this.bigNumber,
|
||||
logs: this.arrayOf((v) => (this.log(v, provider))),
|
||||
logs: this.arrayOf((v: any) => (this.log(v, provider))),
|
||||
logsBloom: this.data,
|
||||
root: this.allowNull(this.data),
|
||||
status: this.allowNull(this.number),
|
||||
@ -216,6 +271,7 @@ export class Formatter {
|
||||
gasPrice: [ "effectiveGasPrice" ],
|
||||
index: [ "transactionIndex" ]
|
||||
})(value);
|
||||
|
||||
// RSK incorrectly implemented EIP-658, so we munge things a bit here for it
|
||||
if (receipt.root != null) {
|
||||
if (receipt.root.length <= 4) {
|
||||
@ -230,131 +286,138 @@ export class Formatter {
|
||||
}
|
||||
receipt.status = value;
|
||||
delete receipt.root;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return throwError("invalid alt-root-status", "BAD_DATA", {
|
||||
value: receipt.root
|
||||
});
|
||||
}
|
||||
}
|
||||
else if (!isHexString(receipt.root, 32)) {
|
||||
} else if (!isHexString(receipt.root, 32)) {
|
||||
// Must be a valid bytes32
|
||||
return throwError("invalid receipt root hash", "BAD_DATA", {
|
||||
value: receipt.root
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//receipt.byzantium = (receipt.root == null);
|
||||
|
||||
return new TransactionReceipt(receipt, provider);
|
||||
}
|
||||
|
||||
// Fitlers
|
||||
topics(value) {
|
||||
topics(value: any): Array<string> {
|
||||
return this.#format.topics(value);
|
||||
}
|
||||
filter(value) {
|
||||
|
||||
filter(value: any): Filter {
|
||||
return this.#format.filter(value);
|
||||
}
|
||||
filterLog(value) {
|
||||
|
||||
filterLog(value: any): any {
|
||||
console.log("ME", value);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Converts a serialized transaction to a TransactionResponse
|
||||
transaction(value) {
|
||||
transaction(value: any): TransactionResponse {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
// Useful utility formatters functions, which if need be use the
|
||||
// methods within the formatter to ensure internal compatibility
|
||||
|
||||
// Access List; converts an AccessListish to an AccessList
|
||||
accessList(value) {
|
||||
accessList(value: any): AccessList {
|
||||
return accessListify(value);
|
||||
}
|
||||
|
||||
// Converts falsish values to a specific value, otherwise use the formatter. Calls preserve `this`.
|
||||
allowFalsish(format, ifFalse) {
|
||||
return ((value) => {
|
||||
if (!value) {
|
||||
return ifFalse;
|
||||
}
|
||||
allowFalsish(format: FormatFunc, ifFalse: any): FormatFunc {
|
||||
return ((value: any) => {
|
||||
if (!value) { return ifFalse; }
|
||||
return format.call(this, value);
|
||||
});
|
||||
}
|
||||
|
||||
// Allows null, optionally replacing it with a default value. Calls preserve `this`.
|
||||
allowNull(format, ifNull) {
|
||||
return ((value) => {
|
||||
if (value == null) {
|
||||
return ifNull;
|
||||
}
|
||||
allowNull(format: FormatFunc, ifNull?: any): FormatFunc {
|
||||
return ((value: any) => {
|
||||
if (value == null) { return ifNull; }
|
||||
return format.call(this, value);
|
||||
});
|
||||
}
|
||||
|
||||
// Requires an Array satisfying the formatter. Calls preserves `this`.
|
||||
arrayOf(format) {
|
||||
return ((array) => {
|
||||
if (!Array.isArray(array)) {
|
||||
throw new Error("not an array");
|
||||
}
|
||||
arrayOf(format: FormatFunc): FormatFunc {
|
||||
return ((array: any) => {
|
||||
if (!Array.isArray(array)) { throw new Error("not an array"); }
|
||||
return array.map((i) => format.call(this, i));
|
||||
});
|
||||
}
|
||||
|
||||
// Requires a value which is a value BigNumber
|
||||
bigNumber(value) {
|
||||
bigNumber(value: any): bigint {
|
||||
return getBigInt(value, "value");
|
||||
}
|
||||
uint256(value) {
|
||||
|
||||
uint256(value: any): bigint {
|
||||
const result = this.bigNumber(value);
|
||||
if (result < 0 || result > BN_MAX_UINT256) {
|
||||
throwArgumentError("invalid uint256", "value", value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Requires a value which is a value boolean or string equivalent
|
||||
boolean(value) {
|
||||
boolean(value: any): boolean {
|
||||
switch (value) {
|
||||
case true:
|
||||
case "true":
|
||||
case true: case "true":
|
||||
return true;
|
||||
case false:
|
||||
case "false":
|
||||
case false: case "false":
|
||||
return false;
|
||||
}
|
||||
return throwArgumentError(`invalid boolean; ${ JSON.stringify(value) }`, "value", value);
|
||||
}
|
||||
|
||||
// Requires a value which is a valid hexstring. If dataOrLength is true,
|
||||
// the length must be even (i.e. a datahexstring) or if it is a number,
|
||||
// specifies teh number of bytes value must represent
|
||||
_hexstring(dataOrLength) {
|
||||
if (dataOrLength == null) {
|
||||
dataOrLength = false;
|
||||
}
|
||||
return (function (value) {
|
||||
_hexstring(dataOrLength?: boolean | number): FormatFunc {
|
||||
if (dataOrLength == null) { dataOrLength = false; }
|
||||
return (function(value: any) {
|
||||
if (isHexString(value, dataOrLength)) {
|
||||
return value.toLowerCase();
|
||||
}
|
||||
throw new Error("bad hexstring");
|
||||
});
|
||||
}
|
||||
data(value) {
|
||||
|
||||
data(value: string): string {
|
||||
if (dataLength(value) == null) {
|
||||
throwArgumentError("", "value", value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
// Requires a network-native hash
|
||||
hash(value) {
|
||||
hash(value: any): string {
|
||||
if (dataLength(value) !== 32) {
|
||||
throwArgumentError("", "value", value);
|
||||
}
|
||||
return this.#format.data(value);
|
||||
}
|
||||
|
||||
// Requires a valid number, within the IEEE 754 safe range
|
||||
number(value) {
|
||||
number(value: any): number {
|
||||
return getNumber(value);
|
||||
}
|
||||
|
||||
// Requires an object which matches a fleet of other formatters
|
||||
// Any FormatFunc may return `undefined` to have the value omitted
|
||||
// from the result object. Calls preserve `this`.
|
||||
object(format, altNames) {
|
||||
return ((value) => {
|
||||
const result = {};
|
||||
object(format: Record<string, FormatFunc>, altNames?: Record<string, Array<string>>): FormatFunc {
|
||||
return ((value: any) => {
|
||||
const result: any = { };
|
||||
for (const key in format) {
|
||||
let srcKey = key;
|
||||
if (altNames && key in altNames && !(srcKey in value)) {
|
||||
@ -365,19 +428,18 @@ export class Formatter {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const nv = format[key].call(this, value[srcKey]);
|
||||
if (nv !== undefined) {
|
||||
result[key] = nv;
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
if (nv !== undefined) { result[key] = nv; }
|
||||
} catch (error) {
|
||||
const message = (error instanceof Error) ? error.message: "not-an-error";
|
||||
throwError(`invalid value for value.${key} (${message})`, "BAD_DATA", { value });
|
||||
throwError(`invalid value for value.${ key } (${ message })`, "BAD_DATA", { value })
|
||||
}
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
}
|
||||
*/
|
||||
//# sourceMappingURL=formatter.js.map
|
File diff suppressed because one or more lines are too long
@ -10,14 +10,13 @@ export { getDefaultProvider } from "./default-provider.js";
|
||||
|
||||
export { EnsResolver } from "./ens-resolver.js";
|
||||
*/
|
||||
export { Formatter } from "./formatter.js";
|
||||
export { Network } from "./common-networks.js";
|
||||
export { NetworkPlugin, GasCostPlugin, EnsPlugin,
|
||||
//LayerOneConnectionPlugin,
|
||||
//MaxPriorityFeePlugin,
|
||||
//PriceOraclePlugin,
|
||||
} from "./plugins-network.js";
|
||||
export { Block, FeeData, Log, TransactionReceipt, TransactionResponse, dummyProvider, copyRequest,
|
||||
export { Block, FeeData, Log, TransactionReceipt, TransactionResponse, copyRequest,
|
||||
//resolveTransactionRequest,
|
||||
} from "./provider.js";
|
||||
export { FallbackProvider } from "./provider-fallback.js";
|
||||
@ -25,6 +24,7 @@ export { JsonRpcApiProvider, JsonRpcProvider, JsonRpcSigner } from "./provider-j
|
||||
export { AlchemyProvider } from "./provider-alchemy.js";
|
||||
export { AnkrProvider } from "./provider-ankr.js";
|
||||
export { CloudflareProvider } from "./provider-cloudflare.js";
|
||||
export { BaseEtherscanProvider, EtherscanPlugin } from "./provider-etherscan-base.js";
|
||||
export { EtherscanProvider } from "./provider-etherscan.js";
|
||||
export { InfuraProvider } from "./provider-infura.js";
|
||||
//export { PocketProvider } from "./provider-pocket.js";
|
||||
|
@ -1 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src.ts/providers/index.ts"],"names":[],"mappings":"AAGA,KAAK;AAEL,OAAO,EACH,gBAAgB,EAAE,mBAAmB,EACxC,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACH,cAAc,EACd,UAAU,EACV,aAAa,EAChB,MAAM,sBAAsB,CAAC;AAC9B;;;;;;;;EAQE;AAEF,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAE/C,OAAO,EACH,aAAa,EACb,aAAa,EACb,SAAS;AACT,2BAA2B;AAC3B,uBAAuB;AACvB,oBAAoB;EACvB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACH,KAAK,EACL,OAAO,EACP,GAAG,EACH,kBAAkB,EAClB,mBAAmB,EAEnB,aAAa,EAEb,WAAW;AACX,4BAA4B;EAC/B,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAE1F,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,wDAAwD;AAExD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC,CAAC,YAAY;AACzE,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAE5D,OAAO,EACH,gBAAgB,EAAE,qBAAqB,EAAE,uBAAuB,EAChE,qBAAqB,EACxB,MAAM,sBAAsB,CAAC"}
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src.ts/providers/index.ts"],"names":[],"mappings":"AAGA,KAAK;AAEL,OAAO,EACH,gBAAgB,EAAE,mBAAmB,EACxC,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACH,cAAc,EACd,UAAU,EACV,aAAa,EAChB,MAAM,sBAAsB,CAAC;AAC9B;;;;;;;;EAQE;AAEF,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAE/C,OAAO,EACH,aAAa,EACb,aAAa,EACb,SAAS;AACT,2BAA2B;AAC3B,uBAAuB;AACvB,oBAAoB;EACvB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACH,KAAK,EACL,OAAO,EACP,GAAG,EACH,kBAAkB,EAClB,mBAAmB,EAEnB,WAAW;AACX,4BAA4B;EAC/B,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAE1F,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AACtF,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,wDAAwD;AAExD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC,CAAC,YAAY;AACzE,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAE5D,OAAO,EACH,gBAAgB,EAAE,qBAAqB,EAAE,uBAAuB,EAChE,qBAAqB,EACxB,MAAM,sBAAsB,CAAC"}
|
@ -1,5 +1,5 @@
|
||||
import { accessListify } from "../transaction/index.js";
|
||||
import { getStore, getBigInt, setStore, throwArgumentError } from "../utils/index.js";
|
||||
import { Formatter } from "./formatter.js";
|
||||
import { EnsPlugin, GasCostPlugin } from "./plugins-network.js";
|
||||
/* * * *
|
||||
// Networks which operation against an L2 can use this plugin to
|
||||
@ -52,16 +52,13 @@ export class CcipPreflightPlugin extends NetworkPlugin {
|
||||
}
|
||||
*/
|
||||
const Networks = new Map();
|
||||
const defaultFormatter = new Formatter();
|
||||
// @TODO: Add a _ethersNetworkObj variable to better detect network ovjects
|
||||
export class Network {
|
||||
#props;
|
||||
constructor(name, _chainId, formatter) {
|
||||
constructor(name, _chainId) {
|
||||
const chainId = getBigInt(_chainId);
|
||||
if (formatter == null) {
|
||||
formatter = defaultFormatter;
|
||||
}
|
||||
const plugins = new Map();
|
||||
this.#props = { name, chainId, formatter, plugins };
|
||||
this.#props = { name, chainId, plugins };
|
||||
}
|
||||
toJSON() {
|
||||
return { name: this.name, chainId: this.chainId };
|
||||
@ -70,19 +67,14 @@ export class Network {
|
||||
set name(value) { setStore(this.#props, "name", value); }
|
||||
get chainId() { return getStore(this.#props, "chainId"); }
|
||||
set chainId(value) { setStore(this.#props, "chainId", getBigInt(value, "chainId")); }
|
||||
get formatter() { return getStore(this.#props, "formatter"); }
|
||||
set formatter(value) { setStore(this.#props, "formatter", value); }
|
||||
get plugins() {
|
||||
return Array.from(this.#props.plugins.values());
|
||||
}
|
||||
attachPlugin(plugin) {
|
||||
if (this.isFrozen()) {
|
||||
throw new Error("frozen");
|
||||
}
|
||||
if (this.#props.plugins.get(plugin.name)) {
|
||||
throw new Error(`cannot replace existing plugin: ${plugin.name} `);
|
||||
}
|
||||
this.#props.plugins.set(plugin.name, plugin.validate(this));
|
||||
this.#props.plugins.set(plugin.name, plugin.clone());
|
||||
return this;
|
||||
}
|
||||
getPlugin(name) {
|
||||
@ -93,19 +85,22 @@ export class Network {
|
||||
return (this.plugins.filter((p) => (p.name.split("#")[0] === basename)));
|
||||
}
|
||||
clone() {
|
||||
const clone = new Network(this.name, this.chainId, this.formatter);
|
||||
const clone = new Network(this.name, this.chainId);
|
||||
this.plugins.forEach((plugin) => {
|
||||
clone.attachPlugin(plugin.clone());
|
||||
});
|
||||
return clone;
|
||||
}
|
||||
freeze() {
|
||||
/*
|
||||
freeze(): Frozen<Network> {
|
||||
Object.freeze(this.#props);
|
||||
return this;
|
||||
}
|
||||
isFrozen() {
|
||||
|
||||
isFrozen(): boolean {
|
||||
return Object.isFrozen(this.#props);
|
||||
}
|
||||
*/
|
||||
computeIntrinsicGas(tx) {
|
||||
const costs = this.getPlugin("org.ethers.gas-cost") || (new GasCostPlugin());
|
||||
let gas = costs.txBase;
|
||||
@ -123,7 +118,7 @@ export class Network {
|
||||
}
|
||||
}
|
||||
if (tx.accessList) {
|
||||
const accessList = this.formatter.accessList(tx.accessList);
|
||||
const accessList = accessListify(tx.accessList);
|
||||
for (const addr in accessList) {
|
||||
gas += costs.txAccessListAddress + costs.txAccessListStorageKey * accessList[addr].storageKeys.length;
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
@ -9,9 +9,6 @@ export class NetworkPlugin {
|
||||
clone() {
|
||||
return new NetworkPlugin(this.name);
|
||||
}
|
||||
validate(network) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
export class GasCostPlugin extends NetworkPlugin {
|
||||
effectiveBlock;
|
||||
@ -63,10 +60,6 @@ export class EnsPlugin extends NetworkPlugin {
|
||||
clone() {
|
||||
return new EnsPlugin(this.address, this.targetNetwork);
|
||||
}
|
||||
validate(network) {
|
||||
network.formatter.address(this.address);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
/*
|
||||
export class MaxPriorityFeePlugin extends NetworkPlugin {
|
||||
@ -102,4 +95,22 @@ export class FeeDataNetworkPlugin extends NetworkPlugin {
|
||||
return new FeeDataNetworkPlugin(this.#feeDataFunc);
|
||||
}
|
||||
}
|
||||
export class CustomBlockNetworkPlugin extends NetworkPlugin {
|
||||
#blockFunc;
|
||||
#blockWithTxsFunc;
|
||||
constructor(blockFunc, blockWithTxsFunc) {
|
||||
super("org.ethers.network-plugins.custom-block");
|
||||
this.#blockFunc = blockFunc;
|
||||
this.#blockWithTxsFunc = blockWithTxsFunc;
|
||||
}
|
||||
async getBlock(provider, block) {
|
||||
return await this.#blockFunc(provider, block);
|
||||
}
|
||||
async getBlockWithTransactions(provider, block) {
|
||||
return await this.#blockWithTxsFunc(provider, block);
|
||||
}
|
||||
clone() {
|
||||
return new CustomBlockNetworkPlugin(this.#blockFunc, this.#blockWithTxsFunc);
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=plugins-network.js.map
|
@ -1 +1 @@
|
||||
{"version":3,"file":"plugins-network.js","sourceRoot":"","sources":["../../src.ts/providers/plugins-network.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAQvD,MAAM,UAAU,GAAG,4CAA4C,CAAC;AAEhE,MAAM,OAAO,aAAa;IACb,IAAI,CAAU;IAEvB,YAAY,IAAY;QACpB,gBAAgB,CAAgB,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IACpD,CAAC;IAED,KAAK;QACD,OAAO,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC;IAED,QAAQ,CAAC,OAAgB;QACrB,OAAO,IAAI,CAAC;IAChB,CAAC;CACJ;AAcD,MAAM,OAAO,aAAc,SAAQ,aAAa;IACnC,cAAc,CAAU;IAExB,MAAM,CAAU;IAChB,QAAQ,CAAU;IAClB,UAAU,CAAU;IACpB,aAAa,CAAU;IACvB,sBAAsB,CAAU;IAChC,mBAAmB,CAAU;IAEtC,YAAY,iBAAyB,CAAC,EAAE,KAAyB;QAC7D,KAAK,CAAC,uCAAwC,CAAC,cAAc,IAAI,CAAC,CAAE,EAAE,CAAC,CAAC;QAExE,MAAM,KAAK,GAA2B,EAAE,cAAc,EAAE,CAAC;QACzD,SAAS,GAAG,CAAC,IAA6B,EAAE,OAAe;YACvD,IAAI,KAAK,GAAG,CAAC,KAAK,IAAI,EAAG,CAAC,CAAC,IAAI,CAAC,CAAC;YACjC,IAAI,KAAK,IAAI,IAAI,EAAE;gBAAE,KAAK,GAAG,OAAO,CAAC;aAAE;YACvC,IAAI,OAAM,CAAC,KAAK,CAAC,KAAK,QAAQ,EAAE;gBAC5B,kBAAkB,CAAC,qBAAsB,IAAK,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;aACrE;YACD,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;QACxB,CAAC;QAED,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QACrB,GAAG,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QACvB,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;QACrB,GAAG,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;QACzB,GAAG,CAAC,wBAAwB,EAAE,IAAI,CAAC,CAAC;QACpC,GAAG,CAAC,qBAAqB,EAAE,IAAI,CAAC,CAAC;QAEjC,gBAAgB,CAAgB,IAAI,EAAE,KAAK,CAAC,CAAC;IACjD,CAAC;IAED,KAAK;QACD,OAAO,IAAI,aAAa,CAAC,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;IACxD,CAAC;CACJ;AAED,kEAAkE;AAClE,8CAA8C;AAC9C,MAAM,OAAO,SAAU,SAAQ,aAAa;IAExC,2BAA2B;IAClB,OAAO,CAAU;IAE1B,gDAAgD;IACvC,aAAa,CAAU;IAEhC,YAAY,OAAuB,EAAE,aAA6B;QAC9D,KAAK,CAAC,gCAAgC,CAAC,CAAC;QACxC,gBAAgB,CAAY,IAAI,EAAE;YAC9B,OAAO,EAAE,CAAC,OAAO,IAAI,UAAU,CAAC;YAChC,aAAa,EAAE,CAAC,CAAC,aAAa,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA,CAAC,CAAC,aAAa,CAAC;SAC9D,CAAC,CAAC;IACP,CAAC;IAED,KAAK;QACD,OAAO,IAAI,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;IAC3D,CAAC;IAED,QAAQ,CAAC,OAAgB;QACrB,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxC,OAAO,IAAI,CAAC;IAChB,CAAC;CACJ;AACD;;;;;;;;;;;;;;;;;;;EAmBE;AACF,MAAM,OAAO,oBAAqB,SAAQ,aAAa;IAC1C,YAAY,CAA2C;IAEhE,IAAI,WAAW,KAA+C,OAAO,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;IAEzF,YAAY,WAAqD;QAC7D,KAAK,CAAC,qCAAqC,CAAC,CAAC;QAC7C,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC;IACpC,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,QAAkB;QAC/B,OAAO,MAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK;QACD,OAAO,IAAI,oBAAoB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACvD,CAAC;CACJ"}
|
||||
{"version":3,"file":"plugins-network.js","sourceRoot":"","sources":["../../src.ts/providers/plugins-network.ts"],"names":[],"mappings":"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"}
|
427
lib.esm/providers/provider-etherscan-base.js
Normal file
427
lib.esm/providers/provider-etherscan-base.js
Normal file
@ -0,0 +1,427 @@
|
||||
import { accessListify } from "../transaction/index.js";
|
||||
import { defineProperties, hexlify, toQuantity, FetchRequest, throwArgumentError, throwError, toUtf8String } from "../utils/index.js";
|
||||
import { AbstractProvider } from "./abstract-provider.js";
|
||||
import { Network } from "./network.js";
|
||||
import { NetworkPlugin } from "./plugins-network.js";
|
||||
import { showThrottleMessage } from "./community.js";
|
||||
const THROTTLE = 2000;
|
||||
const EtherscanPluginId = "org.ethers.plugins.etherscan";
|
||||
export class EtherscanPlugin extends NetworkPlugin {
|
||||
baseUrl;
|
||||
communityApiKey;
|
||||
constructor(baseUrl, communityApiKey) {
|
||||
super(EtherscanPluginId);
|
||||
//if (communityApiKey == null) { communityApiKey = null; }
|
||||
defineProperties(this, { baseUrl, communityApiKey });
|
||||
}
|
||||
clone() {
|
||||
return new EtherscanPlugin(this.baseUrl, this.communityApiKey);
|
||||
}
|
||||
}
|
||||
let nextId = 1;
|
||||
export class BaseEtherscanProvider extends AbstractProvider {
|
||||
network;
|
||||
apiKey;
|
||||
#plugin;
|
||||
constructor(_network, apiKey) {
|
||||
super();
|
||||
const network = Network.from(_network);
|
||||
this.#plugin = network.getPlugin(EtherscanPluginId);
|
||||
if (apiKey == null && this.#plugin) {
|
||||
apiKey = this.#plugin.communityApiKey;
|
||||
}
|
||||
defineProperties(this, { apiKey, network });
|
||||
// Test that the network is supported by Etherscan
|
||||
this.getBaseUrl();
|
||||
}
|
||||
getBaseUrl() {
|
||||
if (this.#plugin) {
|
||||
return this.#plugin.baseUrl;
|
||||
}
|
||||
switch (this.network.name) {
|
||||
case "homestead":
|
||||
return "https:/\/api.etherscan.io";
|
||||
case "ropsten":
|
||||
return "https:/\/api-ropsten.etherscan.io";
|
||||
case "rinkeby":
|
||||
return "https:/\/api-rinkeby.etherscan.io";
|
||||
case "kovan":
|
||||
return "https:/\/api-kovan.etherscan.io";
|
||||
case "goerli":
|
||||
return "https:/\/api-goerli.etherscan.io";
|
||||
default:
|
||||
}
|
||||
return throwArgumentError("unsupported network", "network", this.network);
|
||||
}
|
||||
getUrl(module, params) {
|
||||
const query = Object.keys(params).reduce((accum, key) => {
|
||||
const value = params[key];
|
||||
if (value != null) {
|
||||
accum += `&${key}=${value}`;
|
||||
}
|
||||
return accum;
|
||||
}, "");
|
||||
const apiKey = ((this.apiKey) ? `&apikey=${this.apiKey}` : "");
|
||||
return `${this.getBaseUrl()}/api?module=${module}${query}${apiKey}`;
|
||||
}
|
||||
getPostUrl() {
|
||||
return `${this.getBaseUrl()}/api`;
|
||||
}
|
||||
getPostData(module, params) {
|
||||
params.module = module;
|
||||
params.apikey = this.apiKey;
|
||||
return params;
|
||||
}
|
||||
async detectNetwork() {
|
||||
return this.network;
|
||||
}
|
||||
async fetch(module, params, post) {
|
||||
const id = nextId++;
|
||||
const url = (post ? this.getPostUrl() : this.getUrl(module, params));
|
||||
const payload = (post ? this.getPostData(module, params) : null);
|
||||
this.emit("debug", { action: "sendRequest", id, url, payload: payload });
|
||||
const request = new FetchRequest(url);
|
||||
request.setThrottleParams({ slotInterval: 1000 });
|
||||
request.retryFunc = (req, resp, attempt) => {
|
||||
if (this.isCommunityResource()) {
|
||||
showThrottleMessage("Etherscan");
|
||||
}
|
||||
return Promise.resolve(true);
|
||||
};
|
||||
request.processFunc = async (request, response) => {
|
||||
const result = response.hasBody() ? JSON.parse(toUtf8String(response.body)) : {};
|
||||
const throttle = ((typeof (result.result) === "string") ? result.result : "").toLowerCase().indexOf("rate limit") >= 0;
|
||||
if (module === "proxy") {
|
||||
// This JSON response indicates we are being throttled
|
||||
if (result && result.status == 0 && result.message == "NOTOK" && throttle) {
|
||||
this.emit("debug", { action: "receiveError", id, reason: "proxy-NOTOK", error: result });
|
||||
response.throwThrottleError(result.result, THROTTLE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (throttle) {
|
||||
this.emit("debug", { action: "receiveError", id, reason: "null result", error: result.result });
|
||||
response.throwThrottleError(result.result, THROTTLE);
|
||||
}
|
||||
}
|
||||
return response;
|
||||
};
|
||||
if (payload) {
|
||||
request.setHeader("content-type", "application/x-www-form-urlencoded; charset=UTF-8");
|
||||
request.body = Object.keys(payload).map((k) => `${k}=${payload[k]}`).join("&");
|
||||
}
|
||||
const response = await request.send();
|
||||
try {
|
||||
response.assertOk();
|
||||
}
|
||||
catch (error) {
|
||||
this.emit("debug", { action: "receiveError", id, error, reason: "assertOk" });
|
||||
}
|
||||
if (!response.hasBody()) {
|
||||
this.emit("debug", { action: "receiveError", id, error: "missing body", reason: "null body" });
|
||||
throw new Error();
|
||||
}
|
||||
const result = JSON.parse(toUtf8String(response.body));
|
||||
if (module === "proxy") {
|
||||
if (result.jsonrpc != "2.0") {
|
||||
this.emit("debug", { action: "receiveError", id, result, reason: "invalid JSON-RPC" });
|
||||
const error = new Error("invalid response");
|
||||
error.result = JSON.stringify(result);
|
||||
throw error;
|
||||
}
|
||||
if (result.error) {
|
||||
this.emit("debug", { action: "receiveError", id, result, reason: "JSON-RPC error" });
|
||||
const error = new Error(result.error.message || "unknown error");
|
||||
if (result.error.code) {
|
||||
error.code = result.error.code;
|
||||
}
|
||||
if (result.error.data) {
|
||||
error.data = result.error.data;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
this.emit("debug", { action: "receiveRequest", id, result });
|
||||
return result.result;
|
||||
}
|
||||
else {
|
||||
// getLogs, getHistory have weird success responses
|
||||
if (result.status == 0 && (result.message === "No records found" || result.message === "No transactions found")) {
|
||||
this.emit("debug", { action: "receiveRequest", id, result });
|
||||
return result.result;
|
||||
}
|
||||
if (result.status != 1 || (typeof (result.message) === "string" && !result.message.match(/^OK/))) {
|
||||
this.emit("debug", { action: "receiveError", id, result });
|
||||
const error = new Error("invalid response");
|
||||
error.result = JSON.stringify(result);
|
||||
// if ((result.result || "").toLowerCase().indexOf("rate limit") >= 0) {
|
||||
// error.throttleRetry = true;
|
||||
// }
|
||||
throw error;
|
||||
}
|
||||
this.emit("debug", { action: "receiveRequest", id, result });
|
||||
return result.result;
|
||||
}
|
||||
}
|
||||
// The transaction has already been sanitized by the calls in Provider
|
||||
_getTransactionPostData(transaction) {
|
||||
const result = {};
|
||||
for (let key in transaction) {
|
||||
if (transaction[key] == null) {
|
||||
continue;
|
||||
}
|
||||
let value = transaction[key];
|
||||
if (key === "type" && value === 0) {
|
||||
continue;
|
||||
}
|
||||
// Quantity-types require no leading zero, unless 0
|
||||
if ({ type: true, gasLimit: true, gasPrice: true, maxFeePerGs: true, maxPriorityFeePerGas: true, nonce: true, value: true }[key]) {
|
||||
value = toQuantity(hexlify(value));
|
||||
}
|
||||
else if (key === "accessList") {
|
||||
value = "[" + accessListify(value).map((set) => {
|
||||
return `{address:"${set.address}",storageKeys:["${set.storageKeys.join('","')}"]}`;
|
||||
}).join(",") + "]";
|
||||
}
|
||||
else {
|
||||
value = hexlify(value);
|
||||
}
|
||||
result[key] = value;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
_checkError(req, error, transaction) {
|
||||
/*
|
||||
let body = "";
|
||||
if (isError(error, Logger.Errors.SERVER_ERROR) && error.response && error.response.hasBody()) {
|
||||
body = toUtf8String(error.response.body);
|
||||
}
|
||||
console.log(body);
|
||||
|
||||
// Undo the "convenience" some nodes are attempting to prevent backwards
|
||||
// incompatibility; maybe for v6 consider forwarding reverts as errors
|
||||
if (method === "call" && body) {
|
||||
|
||||
// Etherscan keeps changing their string
|
||||
if (body.match(/reverted/i) || body.match(/VM execution error/i)) {
|
||||
|
||||
// Etherscan prefixes the data like "Reverted 0x1234"
|
||||
let data = e.data;
|
||||
if (data) { data = "0x" + data.replace(/^.*0x/i, ""); }
|
||||
if (!isHexString(data)) { data = "0x"; }
|
||||
|
||||
logger.throwError("call exception", Logger.Errors.CALL_EXCEPTION, {
|
||||
error, data
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Get the message from any nested error structure
|
||||
let message = error.message;
|
||||
if (isError(error, Logger.Errors.SERVER_ERROR)) {
|
||||
if (error.error && typeof(error.error.message) === "string") {
|
||||
message = error.error.message;
|
||||
} else if (typeof(error.body) === "string") {
|
||||
message = error.body;
|
||||
} else if (typeof(error.responseText) === "string") {
|
||||
message = error.responseText;
|
||||
}
|
||||
}
|
||||
message = (message || "").toLowerCase();
|
||||
|
||||
// "Insufficient funds. The account you tried to send transaction from
|
||||
// does not have enough funds. Required 21464000000000 and got: 0"
|
||||
if (message.match(/insufficient funds/)) {
|
||||
logger.throwError("insufficient funds for intrinsic transaction cost", Logger.Errors.INSUFFICIENT_FUNDS, {
|
||||
error, transaction, info: { method }
|
||||
});
|
||||
}
|
||||
|
||||
// "Transaction with the same hash was already imported."
|
||||
if (message.match(/same hash was already imported|transaction nonce is too low|nonce too low/)) {
|
||||
logger.throwError("nonce has already been used", Logger.Errors.NONCE_EXPIRED, {
|
||||
error, transaction, info: { method }
|
||||
});
|
||||
}
|
||||
|
||||
// "Transaction gas price is too low. There is another transaction with
|
||||
// same nonce in the queue. Try increasing the gas price or incrementing the nonce."
|
||||
if (message.match(/another transaction with same nonce/)) {
|
||||
logger.throwError("replacement fee too low", Logger.Errors.REPLACEMENT_UNDERPRICED, {
|
||||
error, transaction, info: { method }
|
||||
});
|
||||
}
|
||||
|
||||
if (message.match(/execution failed due to an exception|execution reverted/)) {
|
||||
logger.throwError("cannot estimate gas; transaction may fail or may require manual gas limit", Logger.Errors.UNPREDICTABLE_GAS_LIMIT, {
|
||||
error, transaction, info: { method }
|
||||
});
|
||||
}
|
||||
*/
|
||||
throw error;
|
||||
}
|
||||
async _detectNetwork() {
|
||||
return this.network;
|
||||
}
|
||||
async _perform(req) {
|
||||
switch (req.method) {
|
||||
case "chainId":
|
||||
return this.network.chainId;
|
||||
case "getBlockNumber":
|
||||
return this.fetch("proxy", { action: "eth_blockNumber" });
|
||||
case "getGasPrice":
|
||||
return this.fetch("proxy", { action: "eth_gasPrice" });
|
||||
case "getBalance":
|
||||
// Returns base-10 result
|
||||
return this.fetch("account", {
|
||||
action: "balance",
|
||||
address: req.address,
|
||||
tag: req.blockTag
|
||||
});
|
||||
case "getTransactionCount":
|
||||
return this.fetch("proxy", {
|
||||
action: "eth_getTransactionCount",
|
||||
address: req.address,
|
||||
tag: req.blockTag
|
||||
});
|
||||
case "getCode":
|
||||
return this.fetch("proxy", {
|
||||
action: "eth_getCode",
|
||||
address: req.address,
|
||||
tag: req.blockTag
|
||||
});
|
||||
case "getStorageAt":
|
||||
return this.fetch("proxy", {
|
||||
action: "eth_getStorageAt",
|
||||
address: req.address,
|
||||
position: req.position,
|
||||
tag: req.blockTag
|
||||
});
|
||||
case "broadcastTransaction":
|
||||
return this.fetch("proxy", {
|
||||
action: "eth_sendRawTransaction",
|
||||
hex: req.signedTransaction
|
||||
}, true).catch((error) => {
|
||||
return this._checkError(req, error, req.signedTransaction);
|
||||
});
|
||||
case "getBlock":
|
||||
if ("blockTag" in req) {
|
||||
return this.fetch("proxy", {
|
||||
action: "eth_getBlockByNumber",
|
||||
tag: req.blockTag,
|
||||
boolean: (req.includeTransactions ? "true" : "false")
|
||||
});
|
||||
}
|
||||
return throwError("getBlock by blockHash not supported by Etherscan", "UNSUPPORTED_OPERATION", {
|
||||
operation: "getBlock(blockHash)"
|
||||
});
|
||||
case "getTransaction":
|
||||
return this.fetch("proxy", {
|
||||
action: "eth_getTransactionByHash",
|
||||
txhash: req.hash
|
||||
});
|
||||
case "getTransactionReceipt":
|
||||
return this.fetch("proxy", {
|
||||
action: "eth_getTransactionReceipt",
|
||||
txhash: req.hash
|
||||
});
|
||||
case "call": {
|
||||
if (req.blockTag !== "latest") {
|
||||
throw new Error("EtherscanProvider does not support blockTag for call");
|
||||
}
|
||||
const postData = this._getTransactionPostData(req.transaction);
|
||||
postData.module = "proxy";
|
||||
postData.action = "eth_call";
|
||||
try {
|
||||
return await this.fetch("proxy", postData, true);
|
||||
}
|
||||
catch (error) {
|
||||
return this._checkError(req, error, req.transaction);
|
||||
}
|
||||
}
|
||||
case "estimateGas": {
|
||||
const postData = this._getTransactionPostData(req.transaction);
|
||||
postData.module = "proxy";
|
||||
postData.action = "eth_estimateGas";
|
||||
try {
|
||||
return await this.fetch("proxy", postData, true);
|
||||
}
|
||||
catch (error) {
|
||||
return this._checkError(req, error, req.transaction);
|
||||
}
|
||||
}
|
||||
/*
|
||||
case "getLogs": {
|
||||
// Needs to complain if more than one address is passed in
|
||||
const args: Record<string, any> = { action: "getLogs" }
|
||||
|
||||
if (params.filter.fromBlock) {
|
||||
args.fromBlock = checkLogTag(params.filter.fromBlock);
|
||||
}
|
||||
|
||||
if (params.filter.toBlock) {
|
||||
args.toBlock = checkLogTag(params.filter.toBlock);
|
||||
}
|
||||
|
||||
if (params.filter.address) {
|
||||
args.address = params.filter.address;
|
||||
}
|
||||
|
||||
// @TODO: We can handle slightly more complicated logs using the logs API
|
||||
if (params.filter.topics && params.filter.topics.length > 0) {
|
||||
if (params.filter.topics.length > 1) {
|
||||
logger.throwError("unsupported topic count", Logger.Errors.UNSUPPORTED_OPERATION, { topics: params.filter.topics });
|
||||
}
|
||||
if (params.filter.topics.length === 1) {
|
||||
const topic0 = params.filter.topics[0];
|
||||
if (typeof(topic0) !== "string" || topic0.length !== 66) {
|
||||
logger.throwError("unsupported topic format", Logger.Errors.UNSUPPORTED_OPERATION, { topic0: topic0 });
|
||||
}
|
||||
args.topic0 = topic0;
|
||||
}
|
||||
}
|
||||
|
||||
const logs: Array<any> = await this.fetch("logs", args);
|
||||
|
||||
// Cache txHash => blockHash
|
||||
let blocks: { [tag: string]: string } = {};
|
||||
|
||||
// Add any missing blockHash to the logs
|
||||
for (let i = 0; i < logs.length; i++) {
|
||||
const log = logs[i];
|
||||
if (log.blockHash != null) { continue; }
|
||||
if (blocks[log.blockNumber] == null) {
|
||||
const block = await this.getBlock(log.blockNumber);
|
||||
if (block) {
|
||||
blocks[log.blockNumber] = block.hash;
|
||||
}
|
||||
}
|
||||
|
||||
log.blockHash = blocks[log.blockNumber];
|
||||
}
|
||||
|
||||
return logs;
|
||||
}
|
||||
*/
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return super._perform(req);
|
||||
}
|
||||
async getNetwork() {
|
||||
return this.network;
|
||||
}
|
||||
async getEtherPrice() {
|
||||
if (this.network.name !== "homestead") {
|
||||
return 0.0;
|
||||
}
|
||||
return parseFloat((await this.fetch("stats", { action: "ethprice" })).ethusd);
|
||||
}
|
||||
isCommunityResource() {
|
||||
const plugin = this.network.getPlugin(EtherscanPluginId);
|
||||
if (plugin) {
|
||||
return (plugin.communityApiKey === this.apiKey);
|
||||
}
|
||||
return (this.apiKey == null);
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=provider-etherscan-base.js.map
|
1
lib.esm/providers/provider-etherscan-base.js.map
Normal file
1
lib.esm/providers/provider-etherscan-base.js.map
Normal file
File diff suppressed because one or more lines are too long
@ -1,454 +1,22 @@
|
||||
import { defineProperties, hexlify, toQuantity, FetchRequest, throwArgumentError, throwError, toUtf8String } from "../utils/index.js";
|
||||
import { AbstractProvider } from "./abstract-provider.js";
|
||||
import { Network } from "./network.js";
|
||||
import { NetworkPlugin } from "./plugins-network.js";
|
||||
const defaultApiKey = "9D13ZE7XSBTJ94N9BNJ2MA33VMAY2YPIRB";
|
||||
const EtherscanPluginId = "org.ethers.plugins.etherscan";
|
||||
export class EtherscanPlugin extends NetworkPlugin {
|
||||
baseUrl;
|
||||
communityApiKey;
|
||||
constructor(baseUrl, communityApiKey) {
|
||||
super(EtherscanPluginId);
|
||||
//if (communityApiKey == null) { communityApiKey = null; }
|
||||
defineProperties(this, { baseUrl, communityApiKey });
|
||||
import { BaseEtherscanProvider } from "./provider-etherscan-base.js";
|
||||
import { Contract } from "../contract/index.js";
|
||||
function isPromise(value) {
|
||||
return (value && typeof (value.then) === "function");
|
||||
}
|
||||
clone() {
|
||||
return new EtherscanPlugin(this.baseUrl, this.communityApiKey);
|
||||
export class EtherscanProvider extends BaseEtherscanProvider {
|
||||
async getContract(_address) {
|
||||
let address = this._getAddress(_address);
|
||||
if (isPromise(address)) {
|
||||
address = await address;
|
||||
}
|
||||
}
|
||||
export class EtherscanProvider extends AbstractProvider {
|
||||
network;
|
||||
apiKey;
|
||||
constructor(_network, apiKey) {
|
||||
super();
|
||||
const network = Network.from(_network);
|
||||
if (apiKey == null) {
|
||||
const plugin = network.getPlugin(EtherscanPluginId);
|
||||
if (plugin) {
|
||||
apiKey = plugin.communityApiKey;
|
||||
}
|
||||
else {
|
||||
apiKey = defaultApiKey;
|
||||
}
|
||||
}
|
||||
defineProperties(this, { apiKey, network });
|
||||
// Test that the network is supported by Etherscan
|
||||
this.getBaseUrl();
|
||||
}
|
||||
getBaseUrl() {
|
||||
const plugin = this.network.getPlugin(EtherscanPluginId);
|
||||
if (plugin) {
|
||||
return plugin.baseUrl;
|
||||
}
|
||||
switch (this.network.name) {
|
||||
case "homestead":
|
||||
return "https:/\/api.etherscan.io";
|
||||
case "ropsten":
|
||||
return "https:/\/api-ropsten.etherscan.io";
|
||||
case "rinkeby":
|
||||
return "https:/\/api-rinkeby.etherscan.io";
|
||||
case "kovan":
|
||||
return "https:/\/api-kovan.etherscan.io";
|
||||
case "goerli":
|
||||
return "https:/\/api-goerli.etherscan.io";
|
||||
default:
|
||||
}
|
||||
return throwArgumentError("unsupported network", "network", this.network);
|
||||
}
|
||||
getUrl(module, params) {
|
||||
const query = Object.keys(params).reduce((accum, key) => {
|
||||
const value = params[key];
|
||||
if (value != null) {
|
||||
accum += `&${key}=${value}`;
|
||||
}
|
||||
return accum;
|
||||
}, "");
|
||||
const apiKey = ((this.apiKey) ? `&apikey=${this.apiKey}` : "");
|
||||
return `${this.getBaseUrl()}/api?module=${module}${query}${apiKey}`;
|
||||
}
|
||||
getPostUrl() {
|
||||
return `${this.getBaseUrl()}/api`;
|
||||
}
|
||||
getPostData(module, params) {
|
||||
params.module = module;
|
||||
params.apikey = this.apiKey;
|
||||
return params;
|
||||
}
|
||||
async detectNetwork() {
|
||||
return this.network;
|
||||
}
|
||||
async fetch(module, params, post) {
|
||||
const url = (post ? this.getPostUrl() : this.getUrl(module, params));
|
||||
const payload = (post ? this.getPostData(module, params) : null);
|
||||
/*
|
||||
this.emit("debug", {
|
||||
action: "request",
|
||||
request: url,
|
||||
provider: this
|
||||
});
|
||||
*/
|
||||
const request = new FetchRequest(url);
|
||||
request.processFunc = async (request, response) => {
|
||||
const result = response.hasBody() ? JSON.parse(toUtf8String(response.body)) : {};
|
||||
const throttle = ((typeof (result.result) === "string") ? result.result : "").toLowerCase().indexOf("rate limit") >= 0;
|
||||
if (module === "proxy") {
|
||||
// This JSON response indicates we are being throttled
|
||||
if (result && result.status == 0 && result.message == "NOTOK" && throttle) {
|
||||
response.throwThrottleError(result.result);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (throttle) {
|
||||
response.throwThrottleError(result.result);
|
||||
}
|
||||
}
|
||||
return response;
|
||||
};
|
||||
// @TODO:
|
||||
//throttleSlotInterval: 1000,
|
||||
if (payload) {
|
||||
request.setHeader("content-type", "application/x-www-form-urlencoded; charset=UTF-8");
|
||||
request.body = Object.keys(payload).map((k) => `${k}=${payload[k]}`).join("&");
|
||||
}
|
||||
const response = await request.send();
|
||||
response.assertOk();
|
||||
if (!response.hasBody()) {
|
||||
throw new Error();
|
||||
}
|
||||
/*
|
||||
this.emit("debug", {
|
||||
action: "response",
|
||||
request: url,
|
||||
response: deepCopy(result),
|
||||
provider: this
|
||||
});
|
||||
*/
|
||||
const result = JSON.parse(toUtf8String(response.body));
|
||||
if (module === "proxy") {
|
||||
if (result.jsonrpc != "2.0") {
|
||||
// @TODO: not any
|
||||
const error = new Error("invalid response");
|
||||
error.result = JSON.stringify(result);
|
||||
throw error;
|
||||
}
|
||||
if (result.error) {
|
||||
// @TODO: not any
|
||||
const error = new Error(result.error.message || "unknown error");
|
||||
if (result.error.code) {
|
||||
error.code = result.error.code;
|
||||
}
|
||||
if (result.error.data) {
|
||||
error.data = result.error.data;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
return result.result;
|
||||
}
|
||||
else {
|
||||
// getLogs, getHistory have weird success responses
|
||||
if (result.status == 0 && (result.message === "No records found" || result.message === "No transactions found")) {
|
||||
return result.result;
|
||||
}
|
||||
if (result.status != 1 || result.message != "OK") {
|
||||
const error = new Error("invalid response");
|
||||
error.result = JSON.stringify(result);
|
||||
// if ((result.result || "").toLowerCase().indexOf("rate limit") >= 0) {
|
||||
// error.throttleRetry = true;
|
||||
// }
|
||||
throw error;
|
||||
}
|
||||
return result.result;
|
||||
}
|
||||
}
|
||||
// The transaction has already been sanitized by the calls in Provider
|
||||
_getTransactionPostData(transaction) {
|
||||
const result = {};
|
||||
for (let key in transaction) {
|
||||
if (transaction[key] == null) {
|
||||
continue;
|
||||
}
|
||||
let value = transaction[key];
|
||||
if (key === "type" && value === 0) {
|
||||
continue;
|
||||
}
|
||||
// Quantity-types require no leading zero, unless 0
|
||||
if ({ type: true, gasLimit: true, gasPrice: true, maxFeePerGs: true, maxPriorityFeePerGas: true, nonce: true, value: true }[key]) {
|
||||
value = toQuantity(hexlify(value));
|
||||
}
|
||||
else if (key === "accessList") {
|
||||
value = "[" + this.network.formatter.accessList(value).map((set) => {
|
||||
return `{address:"${set.address}",storageKeys:["${set.storageKeys.join('","')}"]}`;
|
||||
}).join(",") + "]";
|
||||
}
|
||||
else {
|
||||
value = hexlify(value);
|
||||
}
|
||||
result[key] = value;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
_checkError(req, error, transaction) {
|
||||
/*
|
||||
let body = "";
|
||||
if (isError(error, Logger.Errors.SERVER_ERROR) && error.response && error.response.hasBody()) {
|
||||
body = toUtf8String(error.response.body);
|
||||
}
|
||||
console.log(body);
|
||||
|
||||
// Undo the "convenience" some nodes are attempting to prevent backwards
|
||||
// incompatibility; maybe for v6 consider forwarding reverts as errors
|
||||
if (method === "call" && body) {
|
||||
|
||||
// Etherscan keeps changing their string
|
||||
if (body.match(/reverted/i) || body.match(/VM execution error/i)) {
|
||||
|
||||
// Etherscan prefixes the data like "Reverted 0x1234"
|
||||
let data = e.data;
|
||||
if (data) { data = "0x" + data.replace(/^.*0x/i, ""); }
|
||||
if (!isHexString(data)) { data = "0x"; }
|
||||
|
||||
logger.throwError("call exception", Logger.Errors.CALL_EXCEPTION, {
|
||||
error, data
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Get the message from any nested error structure
|
||||
let message = error.message;
|
||||
if (isError(error, Logger.Errors.SERVER_ERROR)) {
|
||||
if (error.error && typeof(error.error.message) === "string") {
|
||||
message = error.error.message;
|
||||
} else if (typeof(error.body) === "string") {
|
||||
message = error.body;
|
||||
} else if (typeof(error.responseText) === "string") {
|
||||
message = error.responseText;
|
||||
}
|
||||
}
|
||||
message = (message || "").toLowerCase();
|
||||
|
||||
// "Insufficient funds. The account you tried to send transaction from
|
||||
// does not have enough funds. Required 21464000000000 and got: 0"
|
||||
if (message.match(/insufficient funds/)) {
|
||||
logger.throwError("insufficient funds for intrinsic transaction cost", Logger.Errors.INSUFFICIENT_FUNDS, {
|
||||
error, transaction, info: { method }
|
||||
});
|
||||
}
|
||||
|
||||
// "Transaction with the same hash was already imported."
|
||||
if (message.match(/same hash was already imported|transaction nonce is too low|nonce too low/)) {
|
||||
logger.throwError("nonce has already been used", Logger.Errors.NONCE_EXPIRED, {
|
||||
error, transaction, info: { method }
|
||||
});
|
||||
}
|
||||
|
||||
// "Transaction gas price is too low. There is another transaction with
|
||||
// same nonce in the queue. Try increasing the gas price or incrementing the nonce."
|
||||
if (message.match(/another transaction with same nonce/)) {
|
||||
logger.throwError("replacement fee too low", Logger.Errors.REPLACEMENT_UNDERPRICED, {
|
||||
error, transaction, info: { method }
|
||||
});
|
||||
}
|
||||
|
||||
if (message.match(/execution failed due to an exception|execution reverted/)) {
|
||||
logger.throwError("cannot estimate gas; transaction may fail or may require manual gas limit", Logger.Errors.UNPREDICTABLE_GAS_LIMIT, {
|
||||
error, transaction, info: { method }
|
||||
});
|
||||
}
|
||||
*/
|
||||
throw error;
|
||||
}
|
||||
async _detectNetwork() {
|
||||
return this.network;
|
||||
}
|
||||
async _perform(req) {
|
||||
switch (req.method) {
|
||||
case "chainId":
|
||||
return this.network.chainId;
|
||||
case "getBlockNumber":
|
||||
return this.fetch("proxy", { action: "eth_blockNumber" });
|
||||
case "getGasPrice":
|
||||
return this.fetch("proxy", { action: "eth_gasPrice" });
|
||||
case "getBalance":
|
||||
// Returns base-10 result
|
||||
return this.fetch("account", {
|
||||
action: "balance",
|
||||
address: req.address,
|
||||
tag: req.blockTag
|
||||
});
|
||||
case "getTransactionCount":
|
||||
return this.fetch("proxy", {
|
||||
action: "eth_getTransactionCount",
|
||||
address: req.address,
|
||||
tag: req.blockTag
|
||||
});
|
||||
case "getCode":
|
||||
return this.fetch("proxy", {
|
||||
action: "eth_getCode",
|
||||
address: req.address,
|
||||
tag: req.blockTag
|
||||
});
|
||||
case "getStorageAt":
|
||||
return this.fetch("proxy", {
|
||||
action: "eth_getStorageAt",
|
||||
address: req.address,
|
||||
position: req.position,
|
||||
tag: req.blockTag
|
||||
});
|
||||
case "broadcastTransaction":
|
||||
return this.fetch("proxy", {
|
||||
action: "eth_sendRawTransaction",
|
||||
hex: req.signedTransaction
|
||||
}, true).catch((error) => {
|
||||
return this._checkError(req, error, req.signedTransaction);
|
||||
});
|
||||
case "getBlock":
|
||||
if ("blockTag" in req) {
|
||||
return this.fetch("proxy", {
|
||||
action: "eth_getBlockByNumber",
|
||||
tag: req.blockTag,
|
||||
boolean: (req.includeTransactions ? "true" : "false")
|
||||
});
|
||||
}
|
||||
return throwError("getBlock by blockHash not supported by Etherscan", "UNSUPPORTED_OPERATION", {
|
||||
operation: "getBlock(blockHash)"
|
||||
});
|
||||
case "getTransaction":
|
||||
return this.fetch("proxy", {
|
||||
action: "eth_getTransactionByHash",
|
||||
txhash: req.hash
|
||||
});
|
||||
case "getTransactionReceipt":
|
||||
return this.fetch("proxy", {
|
||||
action: "eth_getTransactionReceipt",
|
||||
txhash: req.hash
|
||||
});
|
||||
case "call": {
|
||||
if (req.blockTag !== "latest") {
|
||||
throw new Error("EtherscanProvider does not support blockTag for call");
|
||||
}
|
||||
const postData = this._getTransactionPostData(req.transaction);
|
||||
postData.module = "proxy";
|
||||
postData.action = "eth_call";
|
||||
try {
|
||||
return await this.fetch("proxy", postData, true);
|
||||
const resp = await this.fetch("contract", { action: "getabi", address });
|
||||
const abi = JSON.parse(resp);
|
||||
return new Contract(address, abi, this);
|
||||
}
|
||||
catch (error) {
|
||||
return this._checkError(req, error, req.transaction);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
case "estimateGas": {
|
||||
const postData = this._getTransactionPostData(req.transaction);
|
||||
postData.module = "proxy";
|
||||
postData.action = "eth_estimateGas";
|
||||
try {
|
||||
return await this.fetch("proxy", postData, true);
|
||||
}
|
||||
catch (error) {
|
||||
return this._checkError(req, error, req.transaction);
|
||||
}
|
||||
}
|
||||
/*
|
||||
case "getLogs": {
|
||||
// Needs to complain if more than one address is passed in
|
||||
const args: Record<string, any> = { action: "getLogs" }
|
||||
|
||||
if (params.filter.fromBlock) {
|
||||
args.fromBlock = checkLogTag(params.filter.fromBlock);
|
||||
}
|
||||
|
||||
if (params.filter.toBlock) {
|
||||
args.toBlock = checkLogTag(params.filter.toBlock);
|
||||
}
|
||||
|
||||
if (params.filter.address) {
|
||||
args.address = params.filter.address;
|
||||
}
|
||||
|
||||
// @TODO: We can handle slightly more complicated logs using the logs API
|
||||
if (params.filter.topics && params.filter.topics.length > 0) {
|
||||
if (params.filter.topics.length > 1) {
|
||||
logger.throwError("unsupported topic count", Logger.Errors.UNSUPPORTED_OPERATION, { topics: params.filter.topics });
|
||||
}
|
||||
if (params.filter.topics.length === 1) {
|
||||
const topic0 = params.filter.topics[0];
|
||||
if (typeof(topic0) !== "string" || topic0.length !== 66) {
|
||||
logger.throwError("unsupported topic format", Logger.Errors.UNSUPPORTED_OPERATION, { topic0: topic0 });
|
||||
}
|
||||
args.topic0 = topic0;
|
||||
}
|
||||
}
|
||||
|
||||
const logs: Array<any> = await this.fetch("logs", args);
|
||||
|
||||
// Cache txHash => blockHash
|
||||
let blocks: { [tag: string]: string } = {};
|
||||
|
||||
// Add any missing blockHash to the logs
|
||||
for (let i = 0; i < logs.length; i++) {
|
||||
const log = logs[i];
|
||||
if (log.blockHash != null) { continue; }
|
||||
if (blocks[log.blockNumber] == null) {
|
||||
const block = await this.getBlock(log.blockNumber);
|
||||
if (block) {
|
||||
blocks[log.blockNumber] = block.hash;
|
||||
}
|
||||
}
|
||||
|
||||
log.blockHash = blocks[log.blockNumber];
|
||||
}
|
||||
|
||||
return logs;
|
||||
}
|
||||
*/
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return super._perform(req);
|
||||
}
|
||||
async getNetwork() {
|
||||
return this.network;
|
||||
}
|
||||
async getEtherPrice() {
|
||||
if (this.network.name !== "homestead") {
|
||||
return 0.0;
|
||||
}
|
||||
return parseFloat((await this.fetch("stats", { action: "ethprice" })).ethusd);
|
||||
}
|
||||
isCommunityResource() {
|
||||
const plugin = this.network.getPlugin(EtherscanPluginId);
|
||||
if (plugin) {
|
||||
return (plugin.communityApiKey === this.apiKey);
|
||||
}
|
||||
return (defaultApiKey === this.apiKey);
|
||||
}
|
||||
}
|
||||
/*
|
||||
(async function() {
|
||||
const provider = new EtherscanProvider();
|
||||
console.log(provider);
|
||||
console.log(await provider.getBlockNumber());
|
||||
/ *
|
||||
provider.on("block", (b) => {
|
||||
console.log("BB", b);
|
||||
});
|
||||
console.log(await provider.getTransactionReceipt("0xa5ded92f548e9f362192f9ab7e5b3fbc9b5a919a868e29247f177d49ce38de6e"));
|
||||
|
||||
provider.once("0xa5ded92f548e9f362192f9ab7e5b3fbc9b5a919a868e29247f177d49ce38de6e", (tx) => {
|
||||
console.log("TT", tx);
|
||||
});
|
||||
* /
|
||||
try {
|
||||
console.log(await provider.getBlock(100));
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
try {
|
||||
console.log(await provider.getBlock(13821768));
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
})();
|
||||
*/
|
||||
//# sourceMappingURL=provider-etherscan.js.map
|
File diff suppressed because one or more lines are too long
@ -1,5 +1,6 @@
|
||||
import { getBigInt, getNumber, hexlify, throwError, throwArgumentError } from "../utils/index.js";
|
||||
import { AbstractProvider } from "./abstract-provider.js";
|
||||
import { formatBlock, formatBlockWithTransactions, formatLog, formatTransactionReceipt, formatTransactionResponse } from "./format.js";
|
||||
import { Network } from "./network.js";
|
||||
//const BN_0 = BigInt("0");
|
||||
const BN_1 = BigInt("1");
|
||||
@ -40,7 +41,7 @@ async function waitForSync(config, blockNumber) {
|
||||
}
|
||||
// Normalizes a result to a string that can be used to compare against
|
||||
// other results using normal string equality
|
||||
function normalize(network, value, req) {
|
||||
function normalize(provider, value, req) {
|
||||
switch (req.method) {
|
||||
case "chainId":
|
||||
return getBigInt(value).toString();
|
||||
@ -58,19 +59,19 @@ function normalize(network, value, req) {
|
||||
return hexlify(value);
|
||||
case "getBlock":
|
||||
if (req.includeTransactions) {
|
||||
return JSON.stringify(network.formatter.blockWithTransactions(value));
|
||||
return JSON.stringify(formatBlockWithTransactions(value));
|
||||
}
|
||||
return JSON.stringify(network.formatter.block(value));
|
||||
return JSON.stringify(formatBlock(value));
|
||||
case "getTransaction":
|
||||
return JSON.stringify(network.formatter.transactionResponse(value));
|
||||
return JSON.stringify(formatTransactionResponse(value));
|
||||
case "getTransactionReceipt":
|
||||
return JSON.stringify(network.formatter.receipt(value));
|
||||
return JSON.stringify(formatTransactionReceipt(value));
|
||||
case "call":
|
||||
return hexlify(value);
|
||||
case "estimateGas":
|
||||
return getBigInt(value).toString();
|
||||
case "getLogs":
|
||||
return JSON.stringify(value.map((v) => network.formatter.log(v)));
|
||||
return JSON.stringify(value.map((v) => formatLog(v)));
|
||||
}
|
||||
return throwError("unsupported method", "UNSUPPORTED_OPERATION", {
|
||||
operation: `_perform(${JSON.stringify(req.method)})`
|
||||
@ -174,7 +175,7 @@ export class FallbackProvider extends AbstractProvider {
|
||||
return this.#configs.slice();
|
||||
}
|
||||
async _detectNetwork() {
|
||||
return Network.from(getBigInt(await this._perform({ method: "chainId" }))).freeze();
|
||||
return Network.from(getBigInt(await this._perform({ method: "chainId" })));
|
||||
}
|
||||
// @TODO: Add support to select providers to be the event subscriber
|
||||
//_getSubscriber(sub: Subscription): Subscriber {
|
||||
@ -269,7 +270,7 @@ export class FallbackProvider extends AbstractProvider {
|
||||
const result = runner.result.result;
|
||||
results.push({
|
||||
result,
|
||||
normal: normalize((runner.config._network), result, req),
|
||||
normal: normalize(runner.config.provider, result, req),
|
||||
weight: runner.config.weight
|
||||
});
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
@ -21,7 +21,15 @@ export class IpcSocketProvider extends SocketProvider {
|
||||
constructor(path, network) {
|
||||
super(network);
|
||||
this.#socket = connect(path);
|
||||
this.socket.on("ready", () => { this._start(); });
|
||||
this.socket.on("ready", async () => {
|
||||
try {
|
||||
await this._start();
|
||||
}
|
||||
catch (error) {
|
||||
console.log("failed to start IpcSocketProvider", error);
|
||||
// @TODO: Now what? Restart?
|
||||
}
|
||||
});
|
||||
let response = Buffer.alloc(0);
|
||||
this.socket.on("data", (data) => {
|
||||
response = Buffer.concat([response, data]);
|
||||
|
@ -1 +1 @@
|
||||
{"version":3,"file":"provider-ipcsocket.js","sourceRoot":"","sources":["../../src.ts/providers/provider-ipcsocket.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAC9B,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAMtD,yEAAyE;AACzE,0CAA0C;AAC1C,SAAS,WAAW,CAAC,IAAY;IAC7B,MAAM,QAAQ,GAAkB,EAAG,CAAC;IAEpC,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,OAAO,IAAI,EAAE;QACT,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;QACvC,IAAI,EAAE,KAAK,CAAC,CAAC,EAAE;YAAE,MAAM;SAAE;QACzB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;QAC9D,SAAS,GAAG,EAAE,GAAG,CAAC,CAAC;KACtB;IAED,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;AAC7D,CAAC;AAED,MAAM,OAAO,iBAAkB,SAAQ,cAAc;IACjD,OAAO,CAAS;IAChB,IAAI,MAAM,KAAa,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IAE7C,YAAY,IAAY,EAAE,OAAoB;QAC1C,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAE7B,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAElD,IAAI,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC/B,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YAC5B,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAE,QAAQ,EAAE,IAAI,CAAE,CAAC,CAAC;YAC7C,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;YACtD,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;gBACzB,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YAClC,CAAC,CAAC,CAAC;YACH,QAAQ,GAAG,SAAS,CAAC;QACzB,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;YACvB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACnB,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACtB,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QACtB,CAAC,CAAC,CAAC;IACP,CAAC;IAED,IAAI;QACA,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACtB,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,OAAe;QACxB,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC5B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;CACJ;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoCE"}
|
||||
{"version":3,"file":"provider-ipcsocket.js","sourceRoot":"","sources":["../../src.ts/providers/provider-ipcsocket.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAC9B,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAMtD,yEAAyE;AACzE,0CAA0C;AAC1C,SAAS,WAAW,CAAC,IAAY;IAC7B,MAAM,QAAQ,GAAkB,EAAG,CAAC;IAEpC,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,OAAO,IAAI,EAAE;QACT,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;QACvC,IAAI,EAAE,KAAK,CAAC,CAAC,EAAE;YAAE,MAAM;SAAE;QACzB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;QAC9D,SAAS,GAAG,EAAE,GAAG,CAAC,CAAC;KACtB;IAED,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;AAC7D,CAAC;AAED,MAAM,OAAO,iBAAkB,SAAQ,cAAc;IACjD,OAAO,CAAS;IAChB,IAAI,MAAM,KAAa,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IAE7C,YAAY,IAAY,EAAE,OAAoB;QAC1C,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAE7B,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE;YAC/B,IAAI;gBACA,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;aACvB;YAAC,OAAO,KAAK,EAAE;gBACZ,OAAO,CAAC,GAAG,CAAC,mCAAmC,EAAE,KAAK,CAAC,CAAC;gBACxD,4BAA4B;aAC/B;QACL,CAAC,CAAC,CAAC;QAEH,IAAI,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC/B,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YAC5B,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAE,QAAQ,EAAE,IAAI,CAAE,CAAC,CAAC;YAC7C,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;YACtD,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;gBACzB,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YAClC,CAAC,CAAC,CAAC;YACH,QAAQ,GAAG,SAAS,CAAC;QACzB,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;YACvB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACnB,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACtB,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QACtB,CAAC,CAAC,CAAC;IACP,CAAC;IAED,IAAI;QACA,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACtB,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,OAAe;QACxB,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC5B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;CACJ;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoCE"}
|
@ -1,10 +1,10 @@
|
||||
// @TODO:
|
||||
// - Add the batching API
|
||||
// https://playground.open-rpc.org/?schemaUrl=https://raw.githubusercontent.com/ethereum/eth1.0-apis/assembled-spec/openrpc.json&uiSchema%5BappBar%5D%5Bui:splitView%5D=true&uiSchema%5BappBar%5D%5Bui:input%5D=false&uiSchema%5BappBar%5D%5Bui:examplesDropdown%5D=false
|
||||
import { resolveAddress } from "../address/index.js";
|
||||
import { getAddress, resolveAddress } from "../address/index.js";
|
||||
import { TypedDataEncoder } from "../hash/index.js";
|
||||
import { accessListify } from "../transaction/index.js";
|
||||
import { defineProperties, getBigInt, hexlify, isHexString, toQuantity, toUtf8Bytes, makeError, throwArgumentError, throwError, FetchRequest } from "../utils/index.js";
|
||||
import { defineProperties, getBigInt, hexlify, isHexString, toQuantity, toUtf8Bytes, makeError, throwArgumentError, throwError, FetchRequest, resolveProperties } from "../utils/index.js";
|
||||
import { AbstractProvider, UnmanagedSubscriber } from "./abstract-provider.js";
|
||||
import { AbstractSigner } from "./abstract-signer.js";
|
||||
import { Network } from "./network.js";
|
||||
@ -30,6 +30,9 @@ function deepCopy(value) {
|
||||
}
|
||||
throw new Error(`should not happen: ${value} (${typeof (value)})`);
|
||||
}
|
||||
function stall(duration) {
|
||||
return new Promise((resolve) => { setTimeout(resolve, duration); });
|
||||
}
|
||||
function getLowerCase(value) {
|
||||
if (value) {
|
||||
return value.toLowerCase();
|
||||
@ -120,7 +123,7 @@ export class JsonRpcSigner extends AbstractSigner {
|
||||
// Try getting the transaction
|
||||
const tx = await this.provider.getTransaction(hash);
|
||||
if (tx != null) {
|
||||
resolve(this.provider._wrapTransaction(tx, hash, blockNumber));
|
||||
resolve(tx.replaceableTransaction(blockNumber));
|
||||
return;
|
||||
}
|
||||
// Wait another 4 seconds
|
||||
@ -184,23 +187,36 @@ export class JsonRpcSigner extends AbstractSigner {
|
||||
* sub-classed.
|
||||
*
|
||||
* It provides the base for all JSON-RPC-based Provider interaction.
|
||||
*
|
||||
* Sub-classing Notes:
|
||||
* - a sub-class MUST override _send
|
||||
* - a sub-class MUST call the `_start()` method once connected
|
||||
*/
|
||||
export class JsonRpcApiProvider extends AbstractProvider {
|
||||
#options;
|
||||
#nextId;
|
||||
#payloads;
|
||||
#ready;
|
||||
#starting;
|
||||
#drainTimer;
|
||||
#network;
|
||||
constructor(network, options) {
|
||||
super(network);
|
||||
this.#ready = false;
|
||||
this.#starting = null;
|
||||
this.#nextId = 1;
|
||||
this.#options = Object.assign({}, defaultOptions, options || {});
|
||||
this.#payloads = [];
|
||||
this.#drainTimer = null;
|
||||
this.#network = null;
|
||||
// This could be relaxed in the future to just check equivalent networks
|
||||
const staticNetwork = this._getOption("staticNetwork");
|
||||
if (staticNetwork && staticNetwork !== network) {
|
||||
if (staticNetwork) {
|
||||
if (staticNetwork !== network) {
|
||||
throwArgumentError("staticNetwork MUST match network object", "options", options);
|
||||
}
|
||||
this.#network = staticNetwork;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Returns the value associated with the option %%key%%.
|
||||
@ -210,8 +226,40 @@ export class JsonRpcApiProvider extends AbstractProvider {
|
||||
_getOption(key) {
|
||||
return this.#options[key];
|
||||
}
|
||||
get _network() {
|
||||
if (!this.#network) {
|
||||
throwError("network is not available yet", "NETWORK_ERROR");
|
||||
}
|
||||
return this.#network;
|
||||
}
|
||||
get ready() { return this.#ready; }
|
||||
async _start() {
|
||||
if (this.#ready) {
|
||||
return;
|
||||
}
|
||||
if (this.#starting) {
|
||||
return this.#starting;
|
||||
}
|
||||
this.#starting = (async () => {
|
||||
// Bootstrap the network
|
||||
if (this.#network == null) {
|
||||
try {
|
||||
this.#network = await this._detectNetwork();
|
||||
}
|
||||
catch (error) {
|
||||
console.log("JsonRpcProvider failed to startup; retry in 1s");
|
||||
await stall(1000);
|
||||
this.#starting = null;
|
||||
}
|
||||
}
|
||||
this.#ready = true;
|
||||
this.#starting = null;
|
||||
// Start dispatching requests
|
||||
this.#scheduleDrain();
|
||||
})();
|
||||
}
|
||||
#scheduleDrain() {
|
||||
if (this.#drainTimer) {
|
||||
if (this.#drainTimer || !this.ready) {
|
||||
return;
|
||||
}
|
||||
// If we aren't using batching, no hard in sending it immeidately
|
||||
@ -268,7 +316,6 @@ export class JsonRpcApiProvider extends AbstractProvider {
|
||||
}
|
||||
}, stallTime);
|
||||
}
|
||||
// Sub-classes should **NOT** override this
|
||||
/**
|
||||
* Requests the %%method%% with %%params%% via the JSON-RPC protocol
|
||||
* over the underlying channel. This can be used to call methods
|
||||
@ -327,25 +374,44 @@ export class JsonRpcApiProvider extends AbstractProvider {
|
||||
}
|
||||
return new JsonRpcSigner(this, accounts[address]);
|
||||
}
|
||||
const [network, accounts] = await Promise.all([this.getNetwork(), accountsPromise]);
|
||||
const { accounts } = await resolveProperties({
|
||||
network: this.getNetwork(),
|
||||
accounts: accountsPromise
|
||||
});
|
||||
// Account address
|
||||
address = network.formatter.address(address);
|
||||
address = getAddress(address);
|
||||
for (const account of accounts) {
|
||||
if (network.formatter.address(account) === account) {
|
||||
if (getAddress(account) === account) {
|
||||
return new JsonRpcSigner(this, account);
|
||||
}
|
||||
}
|
||||
throw new Error("invalid account");
|
||||
}
|
||||
// Sub-classes can override this; it detects the *actual* network we
|
||||
// are connected to
|
||||
/** Sub-classes can override this; it detects the *actual* network that
|
||||
* we are **currently** connected to.
|
||||
*
|
||||
* Keep in mind that [[send]] may only be used once [[ready]].
|
||||
*/
|
||||
async _detectNetwork() {
|
||||
// We have a static network (like INFURA)
|
||||
const network = this._getOption("staticNetwork");
|
||||
if (network) {
|
||||
return network;
|
||||
}
|
||||
return Network.from(getBigInt(await this._perform({ method: "chainId" })));
|
||||
// If we are ready, use ``send``, which enabled requests to be batched
|
||||
if (this.ready) {
|
||||
return Network.from(getBigInt(await this.send("eth_chainId", [])));
|
||||
}
|
||||
// We are not ready yet; use the primitive _send
|
||||
const payload = {
|
||||
id: this.#nextId++, method: "eth_chainId", params: [], jsonrpc: "2.0"
|
||||
};
|
||||
this.emit("debug", { action: "sendRpcPayload", payload });
|
||||
const result = (await this._send(payload))[0];
|
||||
this.emit("debug", { action: "receiveRpcResult", result });
|
||||
if ("result" in result) {
|
||||
return Network.from(getBigInt(result.result));
|
||||
}
|
||||
throw this.getRpcError(payload, result);
|
||||
}
|
||||
/**
|
||||
* Return a Subscriber that will manage the %%sub%%.
|
||||
@ -597,6 +663,13 @@ export class JsonRpcProvider extends JsonRpcApiProvider {
|
||||
}
|
||||
this.#pollingInterval = 4000;
|
||||
}
|
||||
async send(method, params) {
|
||||
// All requests are over HTTP, so we can just start handling requests
|
||||
// We do this here rather than the constructor so that we don't send any
|
||||
// requests to the network until we absolutely have to.
|
||||
await this._start();
|
||||
return await super.send(method, params);
|
||||
}
|
||||
async _send(payload) {
|
||||
// Configure a POST connection for the requested method
|
||||
const request = this.#connect.clone();
|
||||
|
File diff suppressed because one or more lines are too long
@ -95,20 +95,16 @@ export class SocketPendingSubscriber extends SocketSubscriber {
|
||||
export class SocketEventSubscriber extends SocketSubscriber {
|
||||
#logFilter;
|
||||
get logFilter() { return JSON.parse(this.#logFilter); }
|
||||
#formatter;
|
||||
constructor(provider, filter) {
|
||||
super(provider, ["logs", filter]);
|
||||
this.#logFilter = JSON.stringify(filter);
|
||||
this.#formatter = provider.getNetwork().then((network) => network.formatter);
|
||||
}
|
||||
async _emit(provider, message) {
|
||||
const formatter = await this.#formatter;
|
||||
provider.emit(this.#logFilter, formatter.log(message, provider));
|
||||
provider.emit(this.#logFilter, provider._wrapLog(message, provider._network));
|
||||
}
|
||||
}
|
||||
export class SocketProvider extends JsonRpcApiProvider {
|
||||
#callbacks;
|
||||
#ready;
|
||||
// Maps each filterId to its subscriber
|
||||
#subs;
|
||||
// If any events come in before a subscriber has finished
|
||||
@ -117,10 +113,18 @@ export class SocketProvider extends JsonRpcApiProvider {
|
||||
constructor(network) {
|
||||
super(network, { batchMaxCount: 1 });
|
||||
this.#callbacks = new Map();
|
||||
this.#ready = false;
|
||||
this.#subs = new Map();
|
||||
this.#pending = new Map();
|
||||
}
|
||||
// This value is only valid after _start has been called
|
||||
/*
|
||||
get _network(): Network {
|
||||
if (this.#network == null) {
|
||||
throw new Error("this shouldn't happen");
|
||||
}
|
||||
return this.#network.clone();
|
||||
}
|
||||
*/
|
||||
_getSubscriber(sub) {
|
||||
switch (sub.type) {
|
||||
case "close":
|
||||
@ -157,21 +161,23 @@ export class SocketProvider extends JsonRpcApiProvider {
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
this.#callbacks.set(payload.id, { payload, resolve, reject });
|
||||
});
|
||||
if (this.#ready) {
|
||||
await this._write(JSON.stringify(payload));
|
||||
}
|
||||
return [await promise];
|
||||
}
|
||||
// Sub-classes must call this once they are connected
|
||||
async _start() {
|
||||
if (this.#ready) {
|
||||
return;
|
||||
}
|
||||
this.#ready = true;
|
||||
/*
|
||||
async _start(): Promise<void> {
|
||||
if (this.#ready) { return; }
|
||||
|
||||
for (const { payload } of this.#callbacks.values()) {
|
||||
await this._write(JSON.stringify(payload));
|
||||
}
|
||||
|
||||
this.#ready = (async function() {
|
||||
await super._start();
|
||||
})();
|
||||
}
|
||||
*/
|
||||
// Sub-classes must call this for each message
|
||||
async _processMessage(message) {
|
||||
const result = (JSON.parse(message));
|
||||
|
File diff suppressed because one or more lines are too long
@ -12,8 +12,14 @@ export class WebSocketProvider extends SocketProvider {
|
||||
else {
|
||||
this.#websocket = url;
|
||||
}
|
||||
this.websocket.onopen = () => {
|
||||
this._start();
|
||||
this.websocket.onopen = async () => {
|
||||
try {
|
||||
await this._start();
|
||||
}
|
||||
catch (error) {
|
||||
console.log("failed to start WebsocketProvider", error);
|
||||
// @TODO: now what? Attempt reconnect?
|
||||
}
|
||||
};
|
||||
this.websocket.onmessage = (message) => {
|
||||
this._processMessage(message.data);
|
||||
|
@ -1 +1 @@
|
||||
{"version":3,"file":"provider-websocket.js","sourceRoot":"","sources":["../../src.ts/providers/provider-websocket.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,IAAI,UAAU,EAAE,MAAM,SAAS,CAAC,CAAC,YAAY;AAE/D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAetD,MAAM,OAAO,iBAAkB,SAAQ,cAAc;IACjD,GAAG,CAAU;IAEb,UAAU,CAAgB;IAC1B,IAAI,SAAS,KAAoB,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;IAE1D,YAAY,GAA2B,EAAE,OAAoB;QACzD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,OAAM,CAAC,GAAG,CAAC,KAAK,QAAQ,EAAE;YAC1B,IAAI,CAAC,UAAU,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;SACzC;aAAM;YACH,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;SACzB;QAED,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,GAAG,EAAE;YACzB,IAAI,CAAC,MAAM,EAAE,CAAC;QAClB,CAAC,CAAC;QAEF,IAAI,CAAC,SAAS,CAAC,SAAS,GAAG,CAAC,OAAyB,EAAE,EAAE;YACrD,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACvC,CAAC,CAAC;IACN,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,OAAe;QACxB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;CACJ"}
|
||||
{"version":3,"file":"provider-websocket.js","sourceRoot":"","sources":["../../src.ts/providers/provider-websocket.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,IAAI,UAAU,EAAE,MAAM,SAAS,CAAC,CAAC,YAAY;AAE/D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAetD,MAAM,OAAO,iBAAkB,SAAQ,cAAc;IACjD,GAAG,CAAU;IAEb,UAAU,CAAgB;IAC1B,IAAI,SAAS,KAAoB,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;IAE1D,YAAY,GAA2B,EAAE,OAAoB;QACzD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,OAAM,CAAC,GAAG,CAAC,KAAK,QAAQ,EAAE;YAC1B,IAAI,CAAC,UAAU,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;SACzC;aAAM;YACH,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;SACzB;QAED,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,KAAK,IAAI,EAAE;YAC/B,IAAI;gBACA,MAAM,IAAI,CAAC,MAAM,EAAE,CAAA;aACtB;YAAC,OAAO,KAAK,EAAE;gBACZ,OAAO,CAAC,GAAG,CAAC,mCAAmC,EAAE,KAAK,CAAC,CAAC;gBACxD,sCAAsC;aACzC;QACL,CAAC,CAAC;QAEF,IAAI,CAAC,SAAS,CAAC,SAAS,GAAG,CAAC,OAAyB,EAAE,EAAE;YACrD,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACvC,CAAC,CAAC;IACN,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,OAAe;QACxB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;CACJ"}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user