| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110 | 
							- "use strict";
 
- /**
 
-  *  The Interface class is a low-level class that accepts an
 
-  *  ABI and provides all the necessary functionality to encode
 
-  *  and decode paramaters to and results from methods, events
 
-  *  and errors.
 
-  *
 
-  *  It also provides several convenience methods to automatically
 
-  *  search and find matching transactions and events to parse them.
 
-  *
 
-  *  @_subsection api/abi:Interfaces  [interfaces]
 
-  */
 
- Object.defineProperty(exports, "__esModule", { value: true });
 
- exports.Interface = exports.Indexed = exports.ErrorDescription = exports.TransactionDescription = exports.LogDescription = exports.Result = exports.checkResultErrors = void 0;
 
- const index_js_1 = require("../crypto/index.js");
 
- const index_js_2 = require("../hash/index.js");
 
- const index_js_3 = require("../utils/index.js");
 
- const abi_coder_js_1 = require("./abi-coder.js");
 
- const abstract_coder_js_1 = require("./coders/abstract-coder.js");
 
- Object.defineProperty(exports, "checkResultErrors", { enumerable: true, get: function () { return abstract_coder_js_1.checkResultErrors; } });
 
- Object.defineProperty(exports, "Result", { enumerable: true, get: function () { return abstract_coder_js_1.Result; } });
 
- const fragments_js_1 = require("./fragments.js");
 
- const typed_js_1 = require("./typed.js");
 
- /**
 
-  *  When using the [[Interface-parseLog]] to automatically match a Log to its event
 
-  *  for parsing, a **LogDescription** is returned.
 
-  */
 
- class LogDescription {
 
-     /**
 
-      *  The matching fragment for the ``topic0``.
 
-      */
 
-     fragment;
 
-     /**
 
-      *  The name of the Event.
 
-      */
 
-     name;
 
-     /**
 
-      *  The full Event signature.
 
-      */
 
-     signature;
 
-     /**
 
-      *  The topic hash for the Event.
 
-      */
 
-     topic;
 
-     /**
 
-      *  The arguments passed into the Event with ``emit``.
 
-      */
 
-     args;
 
-     /**
 
-      *  @_ignore:
 
-      */
 
-     constructor(fragment, topic, args) {
 
-         const name = fragment.name, signature = fragment.format();
 
-         (0, index_js_3.defineProperties)(this, {
 
-             fragment, name, signature, topic, args
 
-         });
 
-     }
 
- }
 
- exports.LogDescription = LogDescription;
 
- /**
 
-  *  When using the [[Interface-parseTransaction]] to automatically match
 
-  *  a transaction data to its function for parsing,
 
-  *  a **TransactionDescription** is returned.
 
-  */
 
- class TransactionDescription {
 
-     /**
 
-      *  The matching fragment from the transaction ``data``.
 
-      */
 
-     fragment;
 
-     /**
 
-      *  The name of the Function from the transaction ``data``.
 
-      */
 
-     name;
 
-     /**
 
-      *  The arguments passed to the Function from the transaction ``data``.
 
-      */
 
-     args;
 
-     /**
 
-      *  The full Function signature from the transaction ``data``.
 
-      */
 
-     signature;
 
-     /**
 
-      *  The selector for the Function from the transaction ``data``.
 
-      */
 
-     selector;
 
-     /**
 
-      *  The ``value`` (in wei) from the transaction.
 
-      */
 
-     value;
 
-     /**
 
-      *  @_ignore:
 
-      */
 
-     constructor(fragment, selector, args, value) {
 
-         const name = fragment.name, signature = fragment.format();
 
-         (0, index_js_3.defineProperties)(this, {
 
-             fragment, name, args, signature, selector, value
 
-         });
 
-     }
 
- }
 
- exports.TransactionDescription = TransactionDescription;
 
- /**
 
-  *  When using the [[Interface-parseError]] to automatically match an
 
-  *  error for a call result for parsing, an **ErrorDescription** is returned.
 
-  */
 
- class ErrorDescription {
 
-     /**
 
-      *  The matching fragment.
 
-      */
 
-     fragment;
 
-     /**
 
-      *  The name of the Error.
 
-      */
 
-     name;
 
-     /**
 
-      *  The arguments passed to the Error with ``revert``.
 
-      */
 
-     args;
 
-     /**
 
-      *  The full Error signature.
 
-      */
 
-     signature;
 
-     /**
 
-      *  The selector for the Error.
 
-      */
 
-     selector;
 
-     /**
 
-      *  @_ignore:
 
-      */
 
-     constructor(fragment, selector, args) {
 
-         const name = fragment.name, signature = fragment.format();
 
-         (0, index_js_3.defineProperties)(this, {
 
-             fragment, name, args, signature, selector
 
-         });
 
-     }
 
- }
 
- exports.ErrorDescription = ErrorDescription;
 
- /**
 
-  *  An **Indexed** is used as a value when a value that does not
 
-  *  fit within a topic (i.e. not a fixed-length, 32-byte type). It
 
-  *  is the ``keccak256`` of the value, and used for types such as
 
-  *  arrays, tuples, bytes and strings.
 
-  */
 
- class Indexed {
 
-     /**
 
-      *  The ``keccak256`` of the value logged.
 
-      */
 
-     hash;
 
-     /**
 
-      *  @_ignore:
 
-      */
 
-     _isIndexed;
 
-     /**
 
-      *  Returns ``true`` if %%value%% is an **Indexed**.
 
-      *
 
-      *  This provides a Type Guard for property access.
 
-      */
 
-     static isIndexed(value) {
 
-         return !!(value && value._isIndexed);
 
-     }
 
-     /**
 
-      *  @_ignore:
 
-      */
 
-     constructor(hash) {
 
-         (0, index_js_3.defineProperties)(this, { hash, _isIndexed: true });
 
-     }
 
- }
 
- exports.Indexed = Indexed;
 
- // https://docs.soliditylang.org/en/v0.8.13/control-structures.html?highlight=panic#panic-via-assert-and-error-via-require
 
- const PanicReasons = {
 
-     "0": "generic panic",
 
-     "1": "assert(false)",
 
-     "17": "arithmetic overflow",
 
-     "18": "division or modulo by zero",
 
-     "33": "enum overflow",
 
-     "34": "invalid encoded storage byte array accessed",
 
-     "49": "out-of-bounds array access; popping on an empty array",
 
-     "50": "out-of-bounds access of an array or bytesN",
 
-     "65": "out of memory",
 
-     "81": "uninitialized function",
 
- };
 
- const BuiltinErrors = {
 
-     "0x08c379a0": {
 
-         signature: "Error(string)",
 
-         name: "Error",
 
-         inputs: ["string"],
 
-         reason: (message) => {
 
-             return `reverted with reason string ${JSON.stringify(message)}`;
 
-         }
 
-     },
 
-     "0x4e487b71": {
 
-         signature: "Panic(uint256)",
 
-         name: "Panic",
 
-         inputs: ["uint256"],
 
-         reason: (code) => {
 
-             let reason = "unknown panic code";
 
-             if (code >= 0 && code <= 0xff && PanicReasons[code.toString()]) {
 
-                 reason = PanicReasons[code.toString()];
 
-             }
 
-             return `reverted with panic code 0x${code.toString(16)} (${reason})`;
 
-         }
 
-     }
 
- };
 
- /**
 
-  *  An Interface abstracts many of the low-level details for
 
-  *  encoding and decoding the data on the blockchain.
 
-  *
 
-  *  An ABI provides information on how to encode data to send to
 
-  *  a Contract, how to decode the results and events and how to
 
-  *  interpret revert errors.
 
-  *
 
-  *  The ABI can be specified by [any supported format](InterfaceAbi).
 
-  */
 
- class Interface {
 
-     /**
 
-      *  All the Contract ABI members (i.e. methods, events, errors, etc).
 
-      */
 
-     fragments;
 
-     /**
 
-      *  The Contract constructor.
 
-      */
 
-     deploy;
 
-     /**
 
-      *  The Fallback method, if any.
 
-      */
 
-     fallback;
 
-     /**
 
-      *  If receiving ether is supported.
 
-      */
 
-     receive;
 
-     #errors;
 
-     #events;
 
-     #functions;
 
-     //    #structs: Map<string, StructFragment>;
 
-     #abiCoder;
 
-     /**
 
-      *  Create a new Interface for the %%fragments%%.
 
-      */
 
-     constructor(fragments) {
 
-         let abi = [];
 
-         if (typeof (fragments) === "string") {
 
-             abi = JSON.parse(fragments);
 
-         }
 
-         else {
 
-             abi = fragments;
 
-         }
 
-         this.#functions = new Map();
 
-         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) {
 
-                 console.log(`[Warning] Invalid Fragment ${JSON.stringify(a)}:`, error.message);
 
-             }
 
-         }
 
-         (0, index_js_3.defineProperties)(this, {
 
-             fragments: Object.freeze(frags)
 
-         });
 
-         let fallback = null;
 
-         let receive = false;
 
-         this.#abiCoder = this.getAbiCoder();
 
-         // Add all fragments by their signature
 
-         this.fragments.forEach((fragment, index) => {
 
-             let bucket;
 
-             switch (fragment.type) {
 
-                 case "constructor":
 
-                     if (this.deploy) {
 
-                         console.log("duplicate definition - constructor");
 
-                         return;
 
-                     }
 
-                     //checkNames(fragment, "input", fragment.inputs);
 
-                     (0, index_js_3.defineProperties)(this, { deploy: fragment });
 
-                     return;
 
-                 case "fallback":
 
-                     if (fragment.inputs.length === 0) {
 
-                         receive = true;
 
-                     }
 
-                     else {
 
-                         (0, index_js_3.assertArgument)(!fallback || fragment.payable !== fallback.payable, "conflicting fallback fragments", `fragments[${index}]`, fragment);
 
-                         fallback = fragment;
 
-                         receive = fallback.payable;
 
-                     }
 
-                     return;
 
-                 case "function":
 
-                     //checkNames(fragment, "input", fragment.inputs);
 
-                     //checkNames(fragment, "output", (<FunctionFragment>fragment).outputs);
 
-                     bucket = this.#functions;
 
-                     break;
 
-                 case "event":
 
-                     //checkNames(fragment, "input", fragment.inputs);
 
-                     bucket = this.#events;
 
-                     break;
 
-                 case "error":
 
-                     bucket = this.#errors;
 
-                     break;
 
-                 default:
 
-                     return;
 
-             }
 
-             // Two identical entries; ignore it
 
-             const signature = fragment.format();
 
-             if (bucket.has(signature)) {
 
-                 return;
 
-             }
 
-             bucket.set(signature, fragment);
 
-         });
 
-         // If we do not have a constructor add a default
 
-         if (!this.deploy) {
 
-             (0, index_js_3.defineProperties)(this, {
 
-                 deploy: fragments_js_1.ConstructorFragment.from("constructor()")
 
-             });
 
-         }
 
-         (0, index_js_3.defineProperties)(this, { fallback, receive });
 
-     }
 
-     /**
 
-      *  Returns the entire Human-Readable ABI, as an array of
 
-      *  signatures, optionally as %%minimal%% strings, which
 
-      *  removes parameter names and unneceesary spaces.
 
-      */
 
-     format(minimal) {
 
-         const format = (minimal ? "minimal" : "full");
 
-         const abi = this.fragments.map((f) => f.format(format));
 
-         return abi;
 
-     }
 
-     /**
 
-      *  Return the JSON-encoded ABI. This is the format Solidiy
 
-      *  returns.
 
-      */
 
-     formatJson() {
 
-         const abi = this.fragments.map((f) => f.format("json"));
 
-         // We need to re-bundle the JSON fragments a bit
 
-         return JSON.stringify(abi.map((j) => JSON.parse(j)));
 
-     }
 
-     /**
 
-      *  The ABI coder that will be used to encode and decode binary
 
-      *  data.
 
-      */
 
-     getAbiCoder() {
 
-         return abi_coder_js_1.AbiCoder.defaultAbiCoder();
 
-     }
 
-     // Find a function definition by any means necessary (unless it is ambiguous)
 
-     #getFunction(key, values, forceUnique) {
 
-         // Selector
 
-         if ((0, index_js_3.isHexString)(key)) {
 
-             const selector = key.toLowerCase();
 
-             for (const fragment of this.#functions.values()) {
 
-                 if (selector === fragment.selector) {
 
-                     return fragment;
 
-                 }
 
-             }
 
-             return null;
 
-         }
 
-         // It is a bare name, look up the function (will return null if ambiguous)
 
-         if (key.indexOf("(") === -1) {
 
-             const matching = [];
 
-             for (const [name, fragment] of this.#functions) {
 
-                 if (name.split("(" /* fix:) */)[0] === key) {
 
-                     matching.push(fragment);
 
-                 }
 
-             }
 
-             if (values) {
 
-                 const lastValue = (values.length > 0) ? values[values.length - 1] : null;
 
-                 let valueLength = values.length;
 
-                 let allowOptions = true;
 
-                 if (typed_js_1.Typed.isTyped(lastValue) && lastValue.type === "overrides") {
 
-                     allowOptions = false;
 
-                     valueLength--;
 
-                 }
 
-                 // Remove all matches that don't have a compatible length. The args
 
-                 // may contain an overrides, so the match may have n or n - 1 parameters
 
-                 for (let i = matching.length - 1; i >= 0; i--) {
 
-                     const inputs = matching[i].inputs.length;
 
-                     if (inputs !== valueLength && (!allowOptions || inputs !== valueLength - 1)) {
 
-                         matching.splice(i, 1);
 
-                     }
 
-                 }
 
-                 // Remove all matches that don't match the Typed signature
 
-                 for (let i = matching.length - 1; i >= 0; i--) {
 
-                     const inputs = matching[i].inputs;
 
-                     for (let j = 0; j < values.length; j++) {
 
-                         // Not a typed value
 
-                         if (!typed_js_1.Typed.isTyped(values[j])) {
 
-                             continue;
 
-                         }
 
-                         // We are past the inputs
 
-                         if (j >= inputs.length) {
 
-                             if (values[j].type === "overrides") {
 
-                                 continue;
 
-                             }
 
-                             matching.splice(i, 1);
 
-                             break;
 
-                         }
 
-                         // Make sure the value type matches the input type
 
-                         if (values[j].type !== inputs[j].baseType) {
 
-                             matching.splice(i, 1);
 
-                             break;
 
-                         }
 
-                     }
 
-                 }
 
-             }
 
-             // We found a single matching signature with an overrides, but the
 
-             // last value is something that cannot possibly be an options
 
-             if (matching.length === 1 && values && values.length !== matching[0].inputs.length) {
 
-                 const lastArg = values[values.length - 1];
 
-                 if (lastArg == null || Array.isArray(lastArg) || typeof (lastArg) !== "object") {
 
-                     matching.splice(0, 1);
 
-                 }
 
-             }
 
-             if (matching.length === 0) {
 
-                 return null;
 
-             }
 
-             if (matching.length > 1 && forceUnique) {
 
-                 const matchStr = matching.map((m) => JSON.stringify(m.format())).join(", ");
 
-                 (0, index_js_3.assertArgument)(false, `ambiguous function description (i.e. matches ${matchStr})`, "key", key);
 
-             }
 
-             return matching[0];
 
-         }
 
-         // Normalize the signature and lookup the function
 
-         const result = this.#functions.get(fragments_js_1.FunctionFragment.from(key).format());
 
-         if (result) {
 
-             return result;
 
-         }
 
-         return null;
 
-     }
 
-     /**
 
-      *  Get the function name for %%key%%, which may be a function selector,
 
-      *  function name or function signature that belongs to the ABI.
 
-      */
 
-     getFunctionName(key) {
 
-         const fragment = this.#getFunction(key, null, false);
 
-         (0, index_js_3.assertArgument)(fragment, "no matching function", "key", key);
 
-         return fragment.name;
 
-     }
 
-     /**
 
-      *  Returns true if %%key%% (a function selector, function name or
 
-      *  function signature) is present in the ABI.
 
-      *
 
-      *  In the case of a function name, the name may be ambiguous, so
 
-      *  accessing the [[FunctionFragment]] may require refinement.
 
-      */
 
-     hasFunction(key) {
 
-         return !!this.#getFunction(key, null, false);
 
-     }
 
-     /**
 
-      *  Get the [[FunctionFragment]] for %%key%%, which may be a function
 
-      *  selector, function name or function signature that belongs to the ABI.
 
-      *
 
-      *  If %%values%% is provided, it will use the Typed API to handle
 
-      *  ambiguous cases where multiple functions match by name.
 
-      *
 
-      *  If the %%key%% and %%values%% do not refine to a single function in
 
-      *  the ABI, this will throw.
 
-      */
 
-     getFunction(key, values) {
 
-         return this.#getFunction(key, values || null, true);
 
-     }
 
-     /**
 
-      *  Iterate over all functions, calling %%callback%%, sorted by their name.
 
-      */
 
-     forEachFunction(callback) {
 
-         const names = Array.from(this.#functions.keys());
 
-         names.sort((a, b) => a.localeCompare(b));
 
-         for (let i = 0; i < names.length; i++) {
 
-             const name = names[i];
 
-             callback((this.#functions.get(name)), i);
 
-         }
 
-     }
 
-     // Find an event definition by any means necessary (unless it is ambiguous)
 
-     #getEvent(key, values, forceUnique) {
 
-         // EventTopic
 
-         if ((0, index_js_3.isHexString)(key)) {
 
-             const eventTopic = key.toLowerCase();
 
-             for (const fragment of this.#events.values()) {
 
-                 if (eventTopic === fragment.topicHash) {
 
-                     return fragment;
 
-                 }
 
-             }
 
-             return null;
 
-         }
 
-         // It is a bare name, look up the function (will return null if ambiguous)
 
-         if (key.indexOf("(") === -1) {
 
-             const matching = [];
 
-             for (const [name, fragment] of this.#events) {
 
-                 if (name.split("(" /* fix:) */)[0] === key) {
 
-                     matching.push(fragment);
 
-                 }
 
-             }
 
-             if (values) {
 
-                 // Remove all matches that don't have a compatible length.
 
-                 for (let i = matching.length - 1; i >= 0; i--) {
 
-                     if (matching[i].inputs.length < values.length) {
 
-                         matching.splice(i, 1);
 
-                     }
 
-                 }
 
-                 // Remove all matches that don't match the Typed signature
 
-                 for (let i = matching.length - 1; i >= 0; i--) {
 
-                     const inputs = matching[i].inputs;
 
-                     for (let j = 0; j < values.length; j++) {
 
-                         // Not a typed value
 
-                         if (!typed_js_1.Typed.isTyped(values[j])) {
 
-                             continue;
 
-                         }
 
-                         // Make sure the value type matches the input type
 
-                         if (values[j].type !== inputs[j].baseType) {
 
-                             matching.splice(i, 1);
 
-                             break;
 
-                         }
 
-                     }
 
-                 }
 
-             }
 
-             if (matching.length === 0) {
 
-                 return null;
 
-             }
 
-             if (matching.length > 1 && forceUnique) {
 
-                 const matchStr = matching.map((m) => JSON.stringify(m.format())).join(", ");
 
-                 (0, index_js_3.assertArgument)(false, `ambiguous event description (i.e. matches ${matchStr})`, "key", key);
 
-             }
 
-             return matching[0];
 
-         }
 
-         // Normalize the signature and lookup the function
 
-         const result = this.#events.get(fragments_js_1.EventFragment.from(key).format());
 
-         if (result) {
 
-             return result;
 
-         }
 
-         return null;
 
-     }
 
-     /**
 
-      *  Get the event name for %%key%%, which may be a topic hash,
 
-      *  event name or event signature that belongs to the ABI.
 
-      */
 
-     getEventName(key) {
 
-         const fragment = this.#getEvent(key, null, false);
 
-         (0, index_js_3.assertArgument)(fragment, "no matching event", "key", key);
 
-         return fragment.name;
 
-     }
 
-     /**
 
-      *  Returns true if %%key%% (an event topic hash, event name or
 
-      *  event signature) is present in the ABI.
 
-      *
 
-      *  In the case of an event name, the name may be ambiguous, so
 
-      *  accessing the [[EventFragment]] may require refinement.
 
-      */
 
-     hasEvent(key) {
 
-         return !!this.#getEvent(key, null, false);
 
-     }
 
-     /**
 
-      *  Get the [[EventFragment]] for %%key%%, which may be a topic hash,
 
-      *  event name or event signature that belongs to the ABI.
 
-      *
 
-      *  If %%values%% is provided, it will use the Typed API to handle
 
-      *  ambiguous cases where multiple events match by name.
 
-      *
 
-      *  If the %%key%% and %%values%% do not refine to a single event in
 
-      *  the ABI, this will throw.
 
-      */
 
-     getEvent(key, values) {
 
-         return this.#getEvent(key, values || null, true);
 
-     }
 
-     /**
 
-      *  Iterate over all events, calling %%callback%%, sorted by their name.
 
-      */
 
-     forEachEvent(callback) {
 
-         const names = Array.from(this.#events.keys());
 
-         names.sort((a, b) => a.localeCompare(b));
 
-         for (let i = 0; i < names.length; i++) {
 
-             const name = names[i];
 
-             callback((this.#events.get(name)), i);
 
-         }
 
-     }
 
-     /**
 
-      *  Get the [[ErrorFragment]] for %%key%%, which may be an error
 
-      *  selector, error name or error signature that belongs to the ABI.
 
-      *
 
-      *  If %%values%% is provided, it will use the Typed API to handle
 
-      *  ambiguous cases where multiple errors match by name.
 
-      *
 
-      *  If the %%key%% and %%values%% do not refine to a single error in
 
-      *  the ABI, this will throw.
 
-      */
 
-     getError(key, values) {
 
-         if ((0, index_js_3.isHexString)(key)) {
 
-             const selector = key.toLowerCase();
 
-             if (BuiltinErrors[selector]) {
 
-                 return fragments_js_1.ErrorFragment.from(BuiltinErrors[selector].signature);
 
-             }
 
-             for (const fragment of this.#errors.values()) {
 
-                 if (selector === fragment.selector) {
 
-                     return fragment;
 
-                 }
 
-             }
 
-             return null;
 
-         }
 
-         // It is a bare name, look up the function (will return null if ambiguous)
 
-         if (key.indexOf("(") === -1) {
 
-             const matching = [];
 
-             for (const [name, fragment] of this.#errors) {
 
-                 if (name.split("(" /* fix:) */)[0] === key) {
 
-                     matching.push(fragment);
 
-                 }
 
-             }
 
-             if (matching.length === 0) {
 
-                 if (key === "Error") {
 
-                     return fragments_js_1.ErrorFragment.from("error Error(string)");
 
-                 }
 
-                 if (key === "Panic") {
 
-                     return fragments_js_1.ErrorFragment.from("error Panic(uint256)");
 
-                 }
 
-                 return null;
 
-             }
 
-             else if (matching.length > 1) {
 
-                 const matchStr = matching.map((m) => JSON.stringify(m.format())).join(", ");
 
-                 (0, index_js_3.assertArgument)(false, `ambiguous error description (i.e. ${matchStr})`, "name", key);
 
-             }
 
-             return matching[0];
 
-         }
 
-         // Normalize the signature and lookup the function
 
-         key = fragments_js_1.ErrorFragment.from(key).format();
 
-         if (key === "Error(string)") {
 
-             return fragments_js_1.ErrorFragment.from("error Error(string)");
 
-         }
 
-         if (key === "Panic(uint256)") {
 
-             return fragments_js_1.ErrorFragment.from("error Panic(uint256)");
 
-         }
 
-         const result = this.#errors.get(key);
 
-         if (result) {
 
-             return result;
 
-         }
 
-         return null;
 
-     }
 
-     /**
 
-      *  Iterate over all errors, calling %%callback%%, sorted by their name.
 
-      */
 
-     forEachError(callback) {
 
-         const names = Array.from(this.#errors.keys());
 
-         names.sort((a, b) => a.localeCompare(b));
 
-         for (let i = 0; i < names.length; i++) {
 
-             const name = names[i];
 
-             callback((this.#errors.get(name)), i);
 
-         }
 
-     }
 
-     // Get the 4-byte selector used by Solidity to identify a function
 
-     /*
 
- getSelector(fragment: ErrorFragment | FunctionFragment): string {
 
-     if (typeof(fragment) === "string") {
 
-         const matches: Array<Fragment> = [ ];
 
-         try { matches.push(this.getFunction(fragment)); } catch (error) { }
 
-         try { matches.push(this.getError(<string>fragment)); } catch (_) { }
 
-         if (matches.length === 0) {
 
-             logger.throwArgumentError("unknown fragment", "key", fragment);
 
-         } else if (matches.length > 1) {
 
-             logger.throwArgumentError("ambiguous fragment matches function and error", "key", fragment);
 
-         }
 
-         fragment = matches[0];
 
-     }
 
-     return dataSlice(id(fragment.format()), 0, 4);
 
- }
 
-     */
 
-     // Get the 32-byte topic hash used by Solidity to identify an event
 
-     /*
 
-     getEventTopic(fragment: EventFragment): string {
 
-         //if (typeof(fragment) === "string") { fragment = this.getEvent(eventFragment); }
 
-         return id(fragment.format());
 
-     }
 
-     */
 
-     _decodeParams(params, data) {
 
-         return this.#abiCoder.decode(params, data);
 
-     }
 
-     _encodeParams(params, values) {
 
-         return this.#abiCoder.encode(params, values);
 
-     }
 
-     /**
 
-      *  Encodes a ``tx.data`` object for deploying the Contract with
 
-      *  the %%values%% as the constructor arguments.
 
-      */
 
-     encodeDeploy(values) {
 
-         return this._encodeParams(this.deploy.inputs, values || []);
 
-     }
 
-     /**
 
-      *  Decodes the result %%data%% (e.g. from an ``eth_call``) for the
 
-      *  specified error (see [[getError]] for valid values for
 
-      *  %%key%%).
 
-      *
 
-      *  Most developers should prefer the [[parseCallResult]] method instead,
 
-      *  which will automatically detect a ``CALL_EXCEPTION`` and throw the
 
-      *  corresponding error.
 
-      */
 
-     decodeErrorResult(fragment, data) {
 
-         if (typeof (fragment) === "string") {
 
-             const f = this.getError(fragment);
 
-             (0, index_js_3.assertArgument)(f, "unknown error", "fragment", fragment);
 
-             fragment = f;
 
-         }
 
-         (0, index_js_3.assertArgument)((0, index_js_3.dataSlice)(data, 0, 4) === fragment.selector, `data signature does not match error ${fragment.name}.`, "data", data);
 
-         return this._decodeParams(fragment.inputs, (0, index_js_3.dataSlice)(data, 4));
 
-     }
 
-     /**
 
-      *  Encodes the transaction revert data for a call result that
 
-      *  reverted from the the Contract with the sepcified %%error%%
 
-      *  (see [[getError]] for valid values for %%fragment%%) with the %%values%%.
 
-      *
 
-      *  This is generally not used by most developers, unless trying to mock
 
-      *  a result from a Contract.
 
-      */
 
-     encodeErrorResult(fragment, values) {
 
-         if (typeof (fragment) === "string") {
 
-             const f = this.getError(fragment);
 
-             (0, index_js_3.assertArgument)(f, "unknown error", "fragment", fragment);
 
-             fragment = f;
 
-         }
 
-         return (0, index_js_3.concat)([
 
-             fragment.selector,
 
-             this._encodeParams(fragment.inputs, values || [])
 
-         ]);
 
-     }
 
-     /**
 
-      *  Decodes the %%data%% from a transaction ``tx.data`` for
 
-      *  the function specified (see [[getFunction]] for valid values
 
-      *  for %%fragment%%).
 
-      *
 
-      *  Most developers should prefer the [[parseTransaction]] method
 
-      *  instead, which will automatically detect the fragment.
 
-      */
 
-     decodeFunctionData(fragment, data) {
 
-         if (typeof (fragment) === "string") {
 
-             const f = this.getFunction(fragment);
 
-             (0, index_js_3.assertArgument)(f, "unknown function", "fragment", fragment);
 
-             fragment = f;
 
-         }
 
-         (0, index_js_3.assertArgument)((0, index_js_3.dataSlice)(data, 0, 4) === fragment.selector, `data signature does not match function ${fragment.name}.`, "data", data);
 
-         return this._decodeParams(fragment.inputs, (0, index_js_3.dataSlice)(data, 4));
 
-     }
 
-     /**
 
-      *  Encodes the ``tx.data`` for a transaction that calls the function
 
-      *  specified (see [[getFunction]] for valid values for %%fragment%%) with
 
-      *  the %%values%%.
 
-      */
 
-     encodeFunctionData(fragment, values) {
 
-         if (typeof (fragment) === "string") {
 
-             const f = this.getFunction(fragment);
 
-             (0, index_js_3.assertArgument)(f, "unknown function", "fragment", fragment);
 
-             fragment = f;
 
-         }
 
-         return (0, index_js_3.concat)([
 
-             fragment.selector,
 
-             this._encodeParams(fragment.inputs, values || [])
 
-         ]);
 
-     }
 
-     /**
 
-      *  Decodes the result %%data%% (e.g. from an ``eth_call``) for the
 
-      *  specified function (see [[getFunction]] for valid values for
 
-      *  %%key%%).
 
-      *
 
-      *  Most developers should prefer the [[parseCallResult]] method instead,
 
-      *  which will automatically detect a ``CALL_EXCEPTION`` and throw the
 
-      *  corresponding error.
 
-      */
 
-     decodeFunctionResult(fragment, data) {
 
-         if (typeof (fragment) === "string") {
 
-             const f = this.getFunction(fragment);
 
-             (0, index_js_3.assertArgument)(f, "unknown function", "fragment", fragment);
 
-             fragment = f;
 
-         }
 
-         let message = "invalid length for result data";
 
-         const bytes = (0, index_js_3.getBytesCopy)(data);
 
-         if ((bytes.length % 32) === 0) {
 
-             try {
 
-                 return this.#abiCoder.decode(fragment.outputs, bytes);
 
-             }
 
-             catch (error) {
 
-                 message = "could not decode result data";
 
-             }
 
-         }
 
-         // Call returned data with no error, but the data is junk
 
-         (0, index_js_3.assert)(false, message, "BAD_DATA", {
 
-             value: (0, index_js_3.hexlify)(bytes),
 
-             info: { method: fragment.name, signature: fragment.format() }
 
-         });
 
-     }
 
-     makeError(_data, tx) {
 
-         const data = (0, index_js_3.getBytes)(_data, "data");
 
-         const error = abi_coder_js_1.AbiCoder.getBuiltinCallException("call", tx, data);
 
-         // Not a built-in error; try finding a custom error
 
-         const customPrefix = "execution reverted (unknown custom error)";
 
-         if (error.message.startsWith(customPrefix)) {
 
-             const selector = (0, index_js_3.hexlify)(data.slice(0, 4));
 
-             const ef = this.getError(selector);
 
-             if (ef) {
 
-                 try {
 
-                     const args = this.#abiCoder.decode(ef.inputs, data.slice(4));
 
-                     error.revert = {
 
-                         name: ef.name, signature: ef.format(), args
 
-                     };
 
-                     error.reason = error.revert.signature;
 
-                     error.message = `execution reverted: ${error.reason}`;
 
-                 }
 
-                 catch (e) {
 
-                     error.message = `execution reverted (coult not decode custom error)`;
 
-                 }
 
-             }
 
-         }
 
-         // Add the invocation, if available
 
-         const parsed = this.parseTransaction(tx);
 
-         if (parsed) {
 
-             error.invocation = {
 
-                 method: parsed.name,
 
-                 signature: parsed.signature,
 
-                 args: parsed.args
 
-             };
 
-         }
 
-         return error;
 
-     }
 
-     /**
 
-      *  Encodes the result data (e.g. from an ``eth_call``) for the
 
-      *  specified function (see [[getFunction]] for valid values
 
-      *  for %%fragment%%) with %%values%%.
 
-      *
 
-      *  This is generally not used by most developers, unless trying to mock
 
-      *  a result from a Contract.
 
-      */
 
-     encodeFunctionResult(fragment, values) {
 
-         if (typeof (fragment) === "string") {
 
-             const f = this.getFunction(fragment);
 
-             (0, index_js_3.assertArgument)(f, "unknown function", "fragment", fragment);
 
-             fragment = f;
 
-         }
 
-         return (0, index_js_3.hexlify)(this.#abiCoder.encode(fragment.outputs, values || []));
 
-     }
 
-     /*
 
-         spelunk(inputs: Array<ParamType>, values: ReadonlyArray<any>, processfunc: (type: string, value: any) => Promise<any>): Promise<Array<any>> {
 
-             const promises: Array<Promise<>> = [ ];
 
-             const process = function(type: ParamType, value: any): any {
 
-                 if (type.baseType === "array") {
 
-                     return descend(type.child
 
-                 }
 
-                 if (type. === "address") {
 
-                 }
 
-             };
 
-     
 
-             const descend = function (inputs: Array<ParamType>, values: ReadonlyArray<any>) {
 
-                 if (inputs.length !== values.length) { throw new Error("length mismatch"); }
 
-                 
 
-             };
 
-     
 
-             const result: Array<any> = [ ];
 
-             values.forEach((value, index) => {
 
-                 if (value == null) {
 
-                     topics.push(null);
 
-                 } else if (param.baseType === "array" || param.baseType === "tuple") {
 
-                     logger.throwArgumentError("filtering with tuples or arrays not supported", ("contract." + param.name), value);
 
-                 } else if (Array.isArray(value)) {
 
-                     topics.push(value.map((value) => encodeTopic(param, value)));
 
-                 } else {
 
-                     topics.push(encodeTopic(param, value));
 
-                 }
 
-             });
 
-         }
 
-     */
 
-     // Create the filter for the event with search criteria (e.g. for eth_filterLog)
 
-     encodeFilterTopics(fragment, values) {
 
-         if (typeof (fragment) === "string") {
 
-             const f = this.getEvent(fragment);
 
-             (0, index_js_3.assertArgument)(f, "unknown event", "eventFragment", fragment);
 
-             fragment = f;
 
-         }
 
-         (0, index_js_3.assert)(values.length <= fragment.inputs.length, `too many arguments for ${fragment.format()}`, "UNEXPECTED_ARGUMENT", { count: values.length, expectedCount: fragment.inputs.length });
 
-         const topics = [];
 
-         if (!fragment.anonymous) {
 
-             topics.push(fragment.topicHash);
 
-         }
 
-         // @TODO: Use the coders for this; to properly support tuples, etc.
 
-         const encodeTopic = (param, value) => {
 
-             if (param.type === "string") {
 
-                 return (0, index_js_2.id)(value);
 
-             }
 
-             else if (param.type === "bytes") {
 
-                 return (0, index_js_1.keccak256)((0, index_js_3.hexlify)(value));
 
-             }
 
-             if (param.type === "bool" && typeof (value) === "boolean") {
 
-                 value = (value ? "0x01" : "0x00");
 
-             }
 
-             else if (param.type.match(/^u?int/)) {
 
-                 value = (0, index_js_3.toBeHex)(value); // @TODO: Should this toTwos??
 
-             }
 
-             else if (param.type.match(/^bytes/)) {
 
-                 value = (0, index_js_3.zeroPadBytes)(value, 32);
 
-             }
 
-             else if (param.type === "address") {
 
-                 // Check addresses are valid
 
-                 this.#abiCoder.encode(["address"], [value]);
 
-             }
 
-             return (0, index_js_3.zeroPadValue)((0, index_js_3.hexlify)(value), 32);
 
-         };
 
-         values.forEach((value, index) => {
 
-             const param = fragment.inputs[index];
 
-             if (!param.indexed) {
 
-                 (0, index_js_3.assertArgument)(value == null, "cannot filter non-indexed parameters; must be null", ("contract." + param.name), value);
 
-                 return;
 
-             }
 
-             if (value == null) {
 
-                 topics.push(null);
 
-             }
 
-             else if (param.baseType === "array" || param.baseType === "tuple") {
 
-                 (0, index_js_3.assertArgument)(false, "filtering with tuples or arrays not supported", ("contract." + param.name), value);
 
-             }
 
-             else if (Array.isArray(value)) {
 
-                 topics.push(value.map((value) => encodeTopic(param, value)));
 
-             }
 
-             else {
 
-                 topics.push(encodeTopic(param, value));
 
-             }
 
-         });
 
-         // Trim off trailing nulls
 
-         while (topics.length && topics[topics.length - 1] === null) {
 
-             topics.pop();
 
-         }
 
-         return topics;
 
-     }
 
-     encodeEventLog(fragment, values) {
 
-         if (typeof (fragment) === "string") {
 
-             const f = this.getEvent(fragment);
 
-             (0, index_js_3.assertArgument)(f, "unknown event", "eventFragment", fragment);
 
-             fragment = f;
 
-         }
 
-         const topics = [];
 
-         const dataTypes = [];
 
-         const dataValues = [];
 
-         if (!fragment.anonymous) {
 
-             topics.push(fragment.topicHash);
 
-         }
 
-         (0, index_js_3.assertArgument)(values.length === fragment.inputs.length, "event arguments/values mismatch", "values", values);
 
-         fragment.inputs.forEach((param, index) => {
 
-             const value = values[index];
 
-             if (param.indexed) {
 
-                 if (param.type === "string") {
 
-                     topics.push((0, index_js_2.id)(value));
 
-                 }
 
-                 else if (param.type === "bytes") {
 
-                     topics.push((0, index_js_1.keccak256)(value));
 
-                 }
 
-                 else if (param.baseType === "tuple" || param.baseType === "array") {
 
-                     // @TODO
 
-                     throw new Error("not implemented");
 
-                 }
 
-                 else {
 
-                     topics.push(this.#abiCoder.encode([param.type], [value]));
 
-                 }
 
-             }
 
-             else {
 
-                 dataTypes.push(param);
 
-                 dataValues.push(value);
 
-             }
 
-         });
 
-         return {
 
-             data: this.#abiCoder.encode(dataTypes, dataValues),
 
-             topics: topics
 
-         };
 
-     }
 
-     // Decode a filter for the event and the search criteria
 
-     decodeEventLog(fragment, data, topics) {
 
-         if (typeof (fragment) === "string") {
 
-             const f = this.getEvent(fragment);
 
-             (0, index_js_3.assertArgument)(f, "unknown event", "eventFragment", fragment);
 
-             fragment = f;
 
-         }
 
-         if (topics != null && !fragment.anonymous) {
 
-             const eventTopic = fragment.topicHash;
 
-             (0, index_js_3.assertArgument)((0, index_js_3.isHexString)(topics[0], 32) && topics[0].toLowerCase() === eventTopic, "fragment/topic mismatch", "topics[0]", topics[0]);
 
-             topics = topics.slice(1);
 
-         }
 
-         const indexed = [];
 
-         const nonIndexed = [];
 
-         const dynamic = [];
 
-         fragment.inputs.forEach((param, index) => {
 
-             if (param.indexed) {
 
-                 if (param.type === "string" || param.type === "bytes" || param.baseType === "tuple" || param.baseType === "array") {
 
-                     indexed.push(fragments_js_1.ParamType.from({ type: "bytes32", name: param.name }));
 
-                     dynamic.push(true);
 
-                 }
 
-                 else {
 
-                     indexed.push(param);
 
-                     dynamic.push(false);
 
-                 }
 
-             }
 
-             else {
 
-                 nonIndexed.push(param);
 
-                 dynamic.push(false);
 
-             }
 
-         });
 
-         const resultIndexed = (topics != null) ? this.#abiCoder.decode(indexed, (0, index_js_3.concat)(topics)) : null;
 
-         const resultNonIndexed = this.#abiCoder.decode(nonIndexed, data, true);
 
-         //const result: (Array<any> & { [ key: string ]: any }) = [ ];
 
-         const values = [];
 
-         const keys = [];
 
-         let nonIndexedIndex = 0, indexedIndex = 0;
 
-         fragment.inputs.forEach((param, index) => {
 
-             let value = null;
 
-             if (param.indexed) {
 
-                 if (resultIndexed == null) {
 
-                     value = new Indexed(null);
 
-                 }
 
-                 else if (dynamic[index]) {
 
-                     value = new Indexed(resultIndexed[indexedIndex++]);
 
-                 }
 
-                 else {
 
-                     try {
 
-                         value = resultIndexed[indexedIndex++];
 
-                     }
 
-                     catch (error) {
 
-                         value = error;
 
-                     }
 
-                 }
 
-             }
 
-             else {
 
-                 try {
 
-                     value = resultNonIndexed[nonIndexedIndex++];
 
-                 }
 
-                 catch (error) {
 
-                     value = error;
 
-                 }
 
-             }
 
-             values.push(value);
 
-             keys.push(param.name || null);
 
-         });
 
-         return abstract_coder_js_1.Result.fromItems(values, keys);
 
-     }
 
-     /**
 
-      *  Parses a transaction, finding the matching function and extracts
 
-      *  the parameter values along with other useful function details.
 
-      *
 
-      *  If the matching function cannot be found, return null.
 
-      */
 
-     parseTransaction(tx) {
 
-         const data = (0, index_js_3.getBytes)(tx.data, "tx.data");
 
-         const value = (0, index_js_3.getBigInt)((tx.value != null) ? tx.value : 0, "tx.value");
 
-         const fragment = this.getFunction((0, index_js_3.hexlify)(data.slice(0, 4)));
 
-         if (!fragment) {
 
-             return null;
 
-         }
 
-         const args = this.#abiCoder.decode(fragment.inputs, data.slice(4));
 
-         return new TransactionDescription(fragment, fragment.selector, args, value);
 
-     }
 
-     parseCallResult(data) {
 
-         throw new Error("@TODO");
 
-     }
 
-     /**
 
-      *  Parses a receipt log, finding the matching event and extracts
 
-      *  the parameter values along with other useful event details.
 
-      *
 
-      *  If the matching event cannot be found, returns null.
 
-      */
 
-     parseLog(log) {
 
-         const fragment = this.getEvent(log.topics[0]);
 
-         if (!fragment || fragment.anonymous) {
 
-             return null;
 
-         }
 
-         // @TODO: If anonymous, and the only method, and the input count matches, should we parse?
 
-         //        Probably not, because just because it is the only event in the ABI does
 
-         //        not mean we have the full ABI; maybe just a fragment?
 
-         return new LogDescription(fragment, fragment.topicHash, this.decodeEventLog(fragment, log.data, log.topics));
 
-     }
 
-     /**
 
-      *  Parses a revert data, finding the matching error and extracts
 
-      *  the parameter values along with other useful error details.
 
-      *
 
-      *  If the matching error cannot be found, returns null.
 
-      */
 
-     parseError(data) {
 
-         const hexData = (0, index_js_3.hexlify)(data);
 
-         const fragment = this.getError((0, index_js_3.dataSlice)(hexData, 0, 4));
 
-         if (!fragment) {
 
-             return null;
 
-         }
 
-         const args = this.#abiCoder.decode(fragment.inputs, (0, index_js_3.dataSlice)(hexData, 4));
 
-         return new ErrorDescription(fragment, fragment.selector, args);
 
-     }
 
-     /**
 
-      *  Creates a new [[Interface]] from the ABI %%value%%.
 
-      *
 
-      *  The %%value%% may be provided as an existing [[Interface]] object,
 
-      *  a JSON-encoded ABI or any Human-Readable ABI format.
 
-      */
 
-     static from(value) {
 
-         // Already an Interface, which is immutable
 
-         if (value instanceof Interface) {
 
-             return value;
 
-         }
 
-         // JSON
 
-         if (typeof (value) === "string") {
 
-             return new Interface(JSON.parse(value));
 
-         }
 
-         // An Interface; possibly from another v6 instance
 
-         if (typeof (value.formatJson) === "function") {
 
-             return new Interface(value.formatJson());
 
-         }
 
-         // A legacy Interface; from an older version
 
-         if (typeof (value.format) === "function") {
 
-             return new Interface(value.format("json"));
 
-         }
 
-         // Array of fragments
 
-         return new Interface(value);
 
-     }
 
- }
 
- exports.Interface = Interface;
 
- //# sourceMappingURL=interface.js.map
 
 
  |