UNPKG

@vechain/connex

Version:

Standard interface to connect DApp with VeChain and user

1,487 lines (1,470 loc) 583 kB
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; function getDefaultExportFromCjs (x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; } var dist = {}; var hasRequiredDist; function requireDist () { if (hasRequiredDist) return dist; hasRequiredDist = 1; Object.defineProperty(dist, "__esModule", { value: true }); /** * convert the given Scheme into a Rule that allows undefined value * @param scheme the scheme */ function optional(scheme) { return (value, context) => { if (value !== undefined) { validate(value, scheme, context); } return ''; }; } dist.optional = optional; /** * convert the given Scheme into a Rule that allows null value * @param scheme the scheme */ function nullable(scheme) { return (value, context) => { if (value !== null) { validate(value, scheme, context); } return ''; }; } dist.nullable = nullable; /** Validator class */ class Validator { constructor(scheme) { this.scheme = scheme; } test(value, context) { return validate(value, this.scheme, context); } } dist.Validator = Validator; /** Error class describes validation error */ class ValidationError extends Error { constructor(rawMessage, context) { super(context ? `${context}: ${rawMessage}` : rawMessage); this.rawMessage = rawMessage; this.context = context; } } dist.ValidationError = ValidationError; ValidationError.prototype.name = 'ValidationError'; /** * direct function to validate value without construct Validator object * @param value value to be validated * @param scheme scheme * @param context context string appears in error object */ function validate(value, scheme, context) { if (Array.isArray(scheme)) { if (!Array.isArray(value)) { throw new ValidationError('expected array', context || ''); } value.forEach((el, i) => validate(el, scheme[0], context ? `${context}.#${i}` : `#${i}`)); } else if (scheme instanceof Function) { const errMsg = scheme(value, context); if (errMsg) { throw new ValidationError(errMsg, context || ''); } } else { if (!(value instanceof Object)) { throw new ValidationError('expected object', context || ''); } for (const key in scheme) { if (scheme.hasOwnProperty(key)) { validate(value[key], scheme[key], context ? `${context}.${key}` : key); } } } return value; } dist.validate = validate; return dist; } var distExports = requireDist(); /* Do NOT modify this file; see /src.ts/_admin/update-version.ts */ /** * The current version of Ethers. */ const version = "6.16.0"; /** * Property helper functions. * * @_subsection api/utils:Properties [about-properties] */ function checkType(value, type, name) { const types = type.split("|").map(t => t.trim()); for (let i = 0; i < types.length; i++) { switch (type) { case "any": return; case "bigint": case "boolean": case "number": case "string": if (typeof (value) === type) { return; } } } const error = new Error(`invalid value for type ${type}`); error.code = "INVALID_ARGUMENT"; error.argument = `value.${name}`; error.value = value; throw error; } /** * Assigns the %%values%% to %%target%% as read-only values. * * It %%types%% is specified, the values are checked. */ function defineProperties(target, values, types) { for (let key in values) { let value = values[key]; const type = (types ? types[key] : null); if (type) { checkType(value, type, key); } Object.defineProperty(target, key, { enumerable: true, value, writable: false }); } } /** * All errors in ethers include properties to ensure they are both * human-readable (i.e. ``.message``) and machine-readable (i.e. ``.code``). * * The [[isError]] function can be used to check the error ``code`` and * provide a type guard for the properties present on that error interface. * * @_section: api/utils/errors:Errors [about-errors] */ function stringify(value, seen) { if (value == null) { return "null"; } if (seen == null) { seen = new Set(); } if (typeof (value) === "object") { if (seen.has(value)) { return "[Circular]"; } seen.add(value); } if (Array.isArray(value)) { return "[ " + (value.map((v) => stringify(v, seen))).join(", ") + " ]"; } if (value instanceof Uint8Array) { const HEX = "0123456789abcdef"; let result = "0x"; for (let i = 0; i < value.length; i++) { result += HEX[value[i] >> 4]; result += HEX[value[i] & 0xf]; } return result; } if (typeof (value) === "object" && typeof (value.toJSON) === "function") { return stringify(value.toJSON(), seen); } switch (typeof (value)) { case "boolean": case "number": case "symbol": return value.toString(); case "bigint": return BigInt(value).toString(); case "string": return JSON.stringify(value); case "object": { const keys = Object.keys(value); keys.sort(); return "{ " + keys.map((k) => `${stringify(k, seen)}: ${stringify(value[k], seen)}`).join(", ") + " }"; } } return `[ COULD NOT SERIALIZE ]`; } /** * Returns true if the %%error%% matches an error thrown by ethers * that matches the error %%code%%. * * In TypeScript environments, this can be used to check that %%error%% * matches an EthersError type, which means the expected properties will * be set. * * @See [ErrorCodes](api:ErrorCode) * @example * try { * // code.... * } catch (e) { * if (isError(e, "CALL_EXCEPTION")) { * // The Type Guard has validated this object * console.log(e.data); * } * } */ function isError(error, code) { return (error && error.code === code); } /** * Returns a new Error configured to the format ethers emits errors, with * the %%message%%, [[api:ErrorCode]] %%code%% and additional properties * for the corresponding EthersError. * * Each error in ethers includes the version of ethers, a * machine-readable [[ErrorCode]], and depending on %%code%%, additional * required properties. The error message will also include the %%message%%, * ethers version, %%code%% and all additional properties, serialized. */ function makeError(message, code, info) { let shortMessage = message; { const details = []; if (info) { if ("message" in info || "code" in info || "name" in info) { throw new Error(`value will overwrite populated values: ${stringify(info)}`); } for (const key in info) { if (key === "shortMessage") { continue; } const value = (info[key]); // try { details.push(key + "=" + stringify(value)); // } catch (error: any) { // console.log("MMM", error.message); // details.push(key + "=[could not serialize object]"); // } } } details.push(`code=${code}`); details.push(`version=${version}`); if (details.length) { message += " (" + details.join(", ") + ")"; } } let error; switch (code) { case "INVALID_ARGUMENT": error = new TypeError(message); break; case "NUMERIC_FAULT": case "BUFFER_OVERRUN": error = new RangeError(message); break; default: error = new Error(message); } defineProperties(error, { code }); if (info) { Object.assign(error, info); } if (error.shortMessage == null) { defineProperties(error, { shortMessage }); } return error; } /** * Throws an EthersError with %%message%%, %%code%% and additional error * %%info%% when %%check%% is falsish.. * * @see [[api:makeError]] */ function assert(check, message, code, info) { if (!check) { throw makeError(message, code, info); } } /** * A simple helper to simply ensuring provided arguments match expected * constraints, throwing if not. * * In TypeScript environments, the %%check%% has been asserted true, so * any further code does not need additional compile-time checks. */ function assertArgument(check, message, name, value) { assert(check, message, "INVALID_ARGUMENT", { argument: name, value: value }); } function assertArgumentCount(count, expectedCount, message) { if (message == null) { message = ""; } if (message) { message = ": " + message; } assert(count >= expectedCount, "missing argument" + message, "MISSING_ARGUMENT", { count: count, expectedCount: expectedCount }); assert(count <= expectedCount, "too many arguments" + message, "UNEXPECTED_ARGUMENT", { count: count, expectedCount: expectedCount }); } ["NFD", "NFC", "NFKD", "NFKC"].reduce((accum, form) => { try { // General test for normalize /* c8 ignore start */ if ("test".normalize(form) !== "test") { throw new Error("bad"); } ; /* c8 ignore stop */ if (form === "NFD") { const check = String.fromCharCode(0xe9).normalize("NFD"); const expected = String.fromCharCode(0x65, 0x0301); /* c8 ignore start */ if (check !== expected) { throw new Error("broken"); } /* c8 ignore stop */ } accum.push(form); } catch (error) { } return accum; }, []); /** * Many classes use file-scoped values to guard the constructor, * making it effectively private. This facilitates that pattern * by ensuring the %%givenGaurd%% matches the file-scoped %%guard%%, * throwing if not, indicating the %%className%% if provided. */ function assertPrivate(givenGuard, guard, className) { if (className == null) { className = ""; } if (givenGuard !== guard) { let method = className, operation = "new"; if (className) { method += "."; operation += " " + className; } assert(false, `private constructor; use ${method}from* methods`, "UNSUPPORTED_OPERATION", { operation }); } } /** * Some data helpers. * * * @_subsection api/utils:Data Helpers [about-data] */ function _getBytes(value, name, copy) { if (value instanceof Uint8Array) { if (copy) { return new Uint8Array(value); } return value; } if (typeof (value) === "string" && (value.length % 2) === 0 && value.match(/^0x[0-9a-f]*$/i)) { const result = new Uint8Array((value.length - 2) / 2); let offset = 2; for (let i = 0; i < result.length; i++) { result[i] = parseInt(value.substring(offset, offset + 2), 16); offset += 2; } return result; } assertArgument(false, "invalid BytesLike value", name || "value", value); } /** * Get a typed Uint8Array for %%value%%. If already a Uint8Array * the original %%value%% is returned; if a copy is required use * [[getBytesCopy]]. * * @see: getBytesCopy */ function getBytes(value, name) { return _getBytes(value, name, false); } /** * Get a typed Uint8Array for %%value%%, creating a copy if necessary * to prevent any modifications of the returned value from being * reflected elsewhere. * * @see: getBytes */ function getBytesCopy(value, name) { return _getBytes(value, name, true); } const HexCharacters = "0123456789abcdef"; /** * Returns a [[DataHexString]] representation of %%data%%. */ function hexlify(data) { const bytes = getBytes(data); let result = "0x"; for (let i = 0; i < bytes.length; i++) { const v = bytes[i]; result += HexCharacters[(v & 0xf0) >> 4] + HexCharacters[v & 0x0f]; } return result; } /** * Returns a [[DataHexString]] by concatenating all values * within %%data%%. */ function concat(datas) { return "0x" + datas.map((d) => hexlify(d).substring(2)).join(""); } /** * Some mathematic operations. * * @_subsection: api/utils:Math Helpers [about-maths] */ const BN_0$2 = BigInt(0); const BN_1$1 = BigInt(1); //const BN_Max256 = (BN_1 << BigInt(256)) - BN_1; // IEEE 754 support 53-bits of mantissa const maxValue = 0x1fffffffffffff; /** * Convert %%value%% from a twos-compliment representation of %%width%% * bits to its value. * * If the highest bit is ``1``, the result will be negative. */ function fromTwos(_value, _width) { const value = getUint(_value, "value"); const width = BigInt(getNumber(_width, "width")); assert((value >> width) === BN_0$2, "overflow", "NUMERIC_FAULT", { operation: "fromTwos", fault: "overflow", value: _value }); // Top bit set; treat as a negative value if (value >> (width - BN_1$1)) { const mask = (BN_1$1 << width) - BN_1$1; return -(((~value) & mask) + BN_1$1); } return value; } /** * Convert %%value%% to a twos-compliment representation of * %%width%% bits. * * The result will always be positive. */ function toTwos(_value, _width) { let value = getBigInt(_value, "value"); const width = BigInt(getNumber(_width, "width")); const limit = (BN_1$1 << (width - BN_1$1)); if (value < BN_0$2) { value = -value; assert(value <= limit, "too low", "NUMERIC_FAULT", { operation: "toTwos", fault: "overflow", value: _value }); const mask = (BN_1$1 << width) - BN_1$1; return ((~value) & mask) + BN_1$1; } else { assert(value < limit, "too high", "NUMERIC_FAULT", { operation: "toTwos", fault: "overflow", value: _value }); } return value; } /** * Mask %%value%% with a bitmask of %%bits%% ones. */ function mask(_value, _bits) { const value = getUint(_value, "value"); const bits = BigInt(getNumber(_bits, "bits")); return value & ((BN_1$1 << bits) - BN_1$1); } /** * Gets a BigInt from %%value%%. If it is an invalid value for * a BigInt, then an ArgumentError will be thrown for %%name%%. */ function getBigInt(value, name) { switch (typeof (value)) { case "bigint": return value; case "number": assertArgument(Number.isInteger(value), "underflow", name || "value", value); assertArgument(value >= -maxValue && value <= maxValue, "overflow", name || "value", value); return BigInt(value); case "string": try { if (value === "") { throw new Error("empty string"); } if (value[0] === "-" && value[1] !== "-") { return -BigInt(value.substring(1)); } return BigInt(value); } catch (e) { assertArgument(false, `invalid BigNumberish string: ${e.message}`, name || "value", value); } } assertArgument(false, "invalid BigNumberish value", name || "value", value); } /** * Returns %%value%% as a bigint, validating it is valid as a bigint * value and that it is positive. */ function getUint(value, name) { const result = getBigInt(value, name); assert(result >= BN_0$2, "unsigned value cannot be negative", "NUMERIC_FAULT", { fault: "overflow", operation: "getUint", value }); return result; } const Nibbles = "0123456789abcdef"; /* * Converts %%value%% to a BigInt. If %%value%% is a Uint8Array, it * is treated as Big Endian data. */ function toBigInt(value) { if (value instanceof Uint8Array) { let result = "0x0"; for (const v of value) { result += Nibbles[v >> 4]; result += Nibbles[v & 0x0f]; } return BigInt(result); } return getBigInt(value); } /** * Gets a //number// from %%value%%. If it is an invalid value for * a //number//, then an ArgumentError will be thrown for %%name%%. */ function getNumber(value, name) { switch (typeof (value)) { case "bigint": assertArgument(value >= -maxValue && value <= maxValue, "overflow", name || "value", value); return Number(value); case "number": assertArgument(Number.isInteger(value), "underflow", name || "value", value); assertArgument(value >= -maxValue && value <= maxValue, "overflow", name || "value", value); return value; case "string": try { if (value === "") { throw new Error("empty string"); } return getNumber(BigInt(value), name); } catch (e) { assertArgument(false, `invalid numeric string: ${e.message}`, name || "value", value); } } assertArgument(false, "invalid numeric value", name || "value", value); } /** * Converts %%value%% to a number. If %%value%% is a Uint8Array, it * is treated as Big Endian data. Throws if the value is not safe. */ function toNumber(value) { return getNumber(toBigInt(value)); } /** * Converts %%value%% to a Big Endian hexstring, optionally padded to * %%width%% bytes. */ function toBeHex(_value, _width) { const value = getUint(_value, "value"); let result = value.toString(16); { const width = getNumber(_width, "width"); // Special case when both value and width are 0 (see: #5025) if (width === 0 && value === BN_0$2) { return "0x"; } assert(width * 2 >= result.length, `value exceeds width (${width} bytes)`, "NUMERIC_FAULT", { operation: "toBeHex", fault: "overflow", value: _value }); // Pad the value to the required width while (result.length < (width * 2)) { result = "0" + result; } } return "0x" + result; } /** * Converts %%value%% to a Big Endian Uint8Array. */ function toBeArray(_value, _width) { const value = getUint(_value, "value"); if (value === BN_0$2) { const width = 0; return new Uint8Array(width); } let hex = value.toString(16); if (hex.length % 2) { hex = "0" + hex; } const result = new Uint8Array(hex.length / 2); for (let i = 0; i < result.length; i++) { const offset = i * 2; result[i] = parseInt(hex.substring(offset, offset + 2), 16); } return result; } /** * Using strings in Ethereum (or any security-basd system) requires * additional care. These utilities attempt to mitigate some of the * safety issues as well as provide the ability to recover and analyse * strings. * * @_subsection api/utils:Strings and UTF-8 [about-strings] */ function errorFunc(reason, offset, bytes, output, badCodepoint) { assertArgument(false, `invalid codepoint at offset ${offset}; ${reason}`, "bytes", bytes); } function ignoreFunc(reason, offset, bytes, output, badCodepoint) { // If there is an invalid prefix (including stray continuation), skip any additional continuation bytes if (reason === "BAD_PREFIX" || reason === "UNEXPECTED_CONTINUE") { let i = 0; for (let o = offset + 1; o < bytes.length; o++) { if (bytes[o] >> 6 !== 0x02) { break; } i++; } return i; } // This byte runs us past the end of the string, so just jump to the end // (but the first byte was read already read and therefore skipped) if (reason === "OVERRUN") { return bytes.length - offset - 1; } // Nothing to skip return 0; } function replaceFunc(reason, offset, bytes, output, badCodepoint) { // Overlong representations are otherwise "valid" code points; just non-deistingtished if (reason === "OVERLONG") { assertArgument(typeof (badCodepoint) === "number", "invalid bad code point for replacement", "badCodepoint", badCodepoint); output.push(badCodepoint); return 0; } // Put the replacement character into the output output.push(0xfffd); // Otherwise, process as if ignoring errors return ignoreFunc(reason, offset, bytes); } /** * A handful of popular, built-in UTF-8 error handling strategies. * * **``"error"``** - throws on ANY illegal UTF-8 sequence or * non-canonical (overlong) codepoints (this is the default) * * **``"ignore"``** - silently drops any illegal UTF-8 sequence * and accepts non-canonical (overlong) codepoints * * **``"replace"``** - replace any illegal UTF-8 sequence with the * UTF-8 replacement character (i.e. ``"\\ufffd"``) and accepts * non-canonical (overlong) codepoints * * @returns: Record<"error" | "ignore" | "replace", Utf8ErrorFunc> */ const Utf8ErrorFuncs = Object.freeze({ error: errorFunc, ignore: ignoreFunc, replace: replaceFunc }); // http://stackoverflow.com/questions/13356493/decode-utf-8-with-javascript#13691499 function getUtf8CodePoints(_bytes, onError) { if (onError == null) { onError = Utf8ErrorFuncs.error; } const bytes = getBytes(_bytes, "bytes"); const result = []; let i = 0; // Invalid bytes are ignored while (i < bytes.length) { const c = bytes[i++]; // 0xxx xxxx if (c >> 7 === 0) { result.push(c); continue; } // Multibyte; how many bytes left for this character? let extraLength = null; let overlongMask = null; // 110x xxxx 10xx xxxx if ((c & 0xe0) === 0xc0) { extraLength = 1; overlongMask = 0x7f; // 1110 xxxx 10xx xxxx 10xx xxxx } else if ((c & 0xf0) === 0xe0) { extraLength = 2; overlongMask = 0x7ff; // 1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx } else if ((c & 0xf8) === 0xf0) { extraLength = 3; overlongMask = 0xffff; } else { if ((c & 0xc0) === 0x80) { i += onError("UNEXPECTED_CONTINUE", i - 1, bytes, result); } else { i += onError("BAD_PREFIX", i - 1, bytes, result); } continue; } // Do we have enough bytes in our data? if (i - 1 + extraLength >= bytes.length) { i += onError("OVERRUN", i - 1, bytes, result); continue; } // Remove the length prefix from the char let res = c & ((1 << (8 - extraLength - 1)) - 1); for (let j = 0; j < extraLength; j++) { let nextChar = bytes[i]; // Invalid continuation byte if ((nextChar & 0xc0) != 0x80) { i += onError("MISSING_CONTINUE", i, bytes, result); res = null; break; } res = (res << 6) | (nextChar & 0x3f); i++; } // See above loop for invalid continuation byte if (res === null) { continue; } // Maximum code point if (res > 0x10ffff) { i += onError("OUT_OF_RANGE", i - 1 - extraLength, bytes, result, res); continue; } // Reserved for UTF-16 surrogate halves if (res >= 0xd800 && res <= 0xdfff) { i += onError("UTF16_SURROGATE", i - 1 - extraLength, bytes, result, res); continue; } // Check for overlong sequences (more bytes than needed) if (res <= overlongMask) { i += onError("OVERLONG", i - 1 - extraLength, bytes, result, res); continue; } result.push(res); } return result; } // http://stackoverflow.com/questions/18729405/how-to-convert-utf8-string-to-byte-array /** * Returns the UTF-8 byte representation of %%str%%. * * If %%form%% is specified, the string is normalized. */ function toUtf8Bytes(str, form) { assertArgument(typeof (str) === "string", "invalid string value", "str", str); let result = []; for (let i = 0; i < str.length; i++) { const c = str.charCodeAt(i); if (c < 0x80) { result.push(c); } else if (c < 0x800) { result.push((c >> 6) | 0xc0); result.push((c & 0x3f) | 0x80); } else if ((c & 0xfc00) == 0xd800) { i++; const c2 = str.charCodeAt(i); assertArgument(i < str.length && ((c2 & 0xfc00) === 0xdc00), "invalid surrogate pair", "str", str); // Surrogate Pair const pair = 0x10000 + ((c & 0x03ff) << 10) + (c2 & 0x03ff); result.push((pair >> 18) | 0xf0); result.push(((pair >> 12) & 0x3f) | 0x80); result.push(((pair >> 6) & 0x3f) | 0x80); result.push((pair & 0x3f) | 0x80); } else { result.push((c >> 12) | 0xe0); result.push(((c >> 6) & 0x3f) | 0x80); result.push((c & 0x3f) | 0x80); } } return new Uint8Array(result); } //export function _toUtf8String(codePoints) { return codePoints.map((codePoint) => { if (codePoint <= 0xffff) { return String.fromCharCode(codePoint); } codePoint -= 0x10000; return String.fromCharCode((((codePoint >> 10) & 0x3ff) + 0xd800), ((codePoint & 0x3ff) + 0xdc00)); }).join(""); } /** * Returns the string represented by the UTF-8 data %%bytes%%. * * When %%onError%% function is specified, it is called on UTF-8 * errors allowing recovery using the [[Utf8ErrorFunc]] API. * (default: [error](Utf8ErrorFuncs)) */ function toUtf8String(bytes, onError) { return _toUtf8String(getUtf8CodePoints(bytes, onError)); } /** * @_ignore: */ const WordSize = 32; const Padding = new Uint8Array(WordSize); // Properties used to immediate pass through to the underlying object // - `then` is used to detect if an object is a Promise for await const passProperties = ["then"]; const _guard$1 = {}; const resultNames = new WeakMap(); function getNames(result) { return resultNames.get(result); } function setNames(result, names) { resultNames.set(result, names); } function throwError(name, error) { const wrapped = new Error(`deferred error during ABI decoding triggered accessing ${name}`); wrapped.error = error; throw wrapped; } function toObject(names, items, deep) { if (names.indexOf(null) >= 0) { return items.map((item, index) => { if (item instanceof Result) { return toObject(getNames(item), item, deep); } return item; }); } return names.reduce((accum, name, index) => { let item = items.getValue(name); if (!(name in accum)) { if (deep && item instanceof Result) { item = toObject(getNames(item), item, deep); } accum[name] = item; } return accum; }, {}); } /** * A [[Result]] is a sub-class of Array, which allows accessing any * of its values either positionally by its index or, if keys are * provided by its name. * * @_docloc: api/abi */ class Result extends Array { // No longer used; but cannot be removed as it will remove the // #private field from the .d.ts which may break backwards // compatibility #names; /** * @private */ constructor(...args) { // To properly sub-class Array so the other built-in // functions work, the constructor has to behave fairly // well. So, in the event we are created via fromItems() // we build the read-only Result object we want, but on // any other input, we use the default constructor // constructor(guard: any, items: Array<any>, keys?: Array<null | string>); const guard = args[0]; let items = args[1]; let names = (args[2] || []).slice(); let wrap = true; if (guard !== _guard$1) { items = args; names = []; wrap = false; } // Can't just pass in ...items since an array of length 1 // is a special case in the super. super(items.length); items.forEach((item, index) => { this[index] = item; }); // Find all unique keys const nameCounts = names.reduce((accum, name) => { if (typeof (name) === "string") { accum.set(name, (accum.get(name) || 0) + 1); } return accum; }, (new Map())); // Remove any key thats not unique setNames(this, Object.freeze(items.map((item, index) => { const name = names[index]; if (name != null && nameCounts.get(name) === 1) { return name; } return null; }))); // Dummy operations to prevent TypeScript from complaining this.#names = []; if (this.#names == null) { void (this.#names); } if (!wrap) { return; } // A wrapped Result is immutable Object.freeze(this); // Proxy indices and names so we can trap deferred errors const proxy = new Proxy(this, { get: (target, prop, receiver) => { if (typeof (prop) === "string") { // Index accessor if (prop.match(/^[0-9]+$/)) { const index = getNumber(prop, "%index"); if (index < 0 || index >= this.length) { throw new RangeError("out of result range"); } const item = target[index]; if (item instanceof Error) { throwError(`index ${index}`, item); } return item; } // Pass important checks (like `then` for Promise) through if (passProperties.indexOf(prop) >= 0) { return Reflect.get(target, prop, receiver); } const value = target[prop]; if (value instanceof Function) { // Make sure functions work with private variables // See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy#no_private_property_forwarding return function (...args) { return value.apply((this === receiver) ? target : this, args); }; } else if (!(prop in target)) { // Possible name accessor return target.getValue.apply((this === receiver) ? target : this, [prop]); } } return Reflect.get(target, prop, receiver); } }); setNames(proxy, getNames(this)); return proxy; } /** * Returns the Result as a normal Array. If %%deep%%, any children * which are Result objects are also converted to a normal Array. * * This will throw if there are any outstanding deferred * errors. */ toArray(deep) { const result = []; this.forEach((item, index) => { if (item instanceof Error) { throwError(`index ${index}`, item); } if (deep && item instanceof Result) { item = item.toArray(deep); } result.push(item); }); return result; } /** * Returns the Result as an Object with each name-value pair. If * %%deep%%, any children which are Result objects are also * converted to an Object. * * This will throw if any value is unnamed, or if there are * any outstanding deferred errors. */ toObject(deep) { const names = getNames(this); return names.reduce((accum, name, index) => { assert(name != null, `value at index ${index} unnamed`, "UNSUPPORTED_OPERATION", { operation: "toObject()" }); return toObject(names, this, deep); }, {}); } /** * @_ignore */ slice(start, end) { if (start == null) { start = 0; } if (start < 0) { start += this.length; if (start < 0) { start = 0; } } if (end == null) { end = this.length; } if (end < 0) { end += this.length; if (end < 0) { end = 0; } } if (end > this.length) { end = this.length; } const _names = getNames(this); const result = [], names = []; for (let i = start; i < end; i++) { result.push(this[i]); names.push(_names[i]); } return new Result(_guard$1, result, names); } /** * @_ignore */ filter(callback, thisArg) { const _names = getNames(this); const result = [], names = []; for (let i = 0; i < this.length; i++) { const item = this[i]; if (item instanceof Error) { throwError(`index ${i}`, item); } if (callback.call(thisArg, item, i, this)) { result.push(item); names.push(_names[i]); } } return new Result(_guard$1, result, names); } /** * @_ignore */ map(callback, thisArg) { const result = []; for (let i = 0; i < this.length; i++) { const item = this[i]; if (item instanceof Error) { throwError(`index ${i}`, item); } result.push(callback.call(thisArg, item, i, this)); } return result; } /** * Returns the value for %%name%%. * * Since it is possible to have a key whose name conflicts with * a method on a [[Result]] or its superclass Array, or any * JavaScript keyword, this ensures all named values are still * accessible by name. */ getValue(name) { const index = getNames(this).indexOf(name); if (index === -1) { return undefined; } const value = this[index]; if (value instanceof Error) { throwError(`property ${JSON.stringify(name)}`, value.error); } return value; } /** * Creates a new [[Result]] for %%items%% with each entry * also accessible by its corresponding name in %%keys%%. */ static fromItems(items, keys) { return new Result(_guard$1, items, keys); } } function getValue(value) { let bytes = toBeArray(value); assert(bytes.length <= WordSize, "value out-of-bounds", "BUFFER_OVERRUN", { buffer: bytes, length: WordSize, offset: bytes.length }); if (bytes.length !== WordSize) { bytes = getBytesCopy(concat([Padding.slice(bytes.length % WordSize), bytes])); } return bytes; } /** * @_ignore */ class Coder { // The coder name: // - address, uint256, tuple, array, etc. name; // The fully expanded type, including composite types: // - address, uint256, tuple(address,bytes), uint256[3][4][], etc. type; // The localName bound in the signature, in this example it is "baz": // - tuple(address foo, uint bar) baz localName; // Whether this type is dynamic: // - Dynamic: bytes, string, address[], tuple(boolean[]), etc. // - Not Dynamic: address, uint256, boolean[3], tuple(address, uint8) dynamic; constructor(name, type, localName, dynamic) { defineProperties(this, { name, type, localName, dynamic }, { name: "string", type: "string", localName: "string", dynamic: "boolean" }); } _throwError(message, value) { assertArgument(false, message, this.localName, value); } } /** * @_ignore */ class Writer { // An array of WordSize lengthed objects to concatenation #data; #dataLength; constructor() { this.#data = []; this.#dataLength = 0; } get data() { return concat(this.#data); } get length() { return this.#dataLength; } #writeData(data) { this.#data.push(data); this.#dataLength += data.length; return data.length; } appendWriter(writer) { return this.#writeData(getBytesCopy(writer.data)); } // Arrayish item; pad on the right to *nearest* WordSize writeBytes(value) { let bytes = getBytesCopy(value); const paddingOffset = bytes.length % WordSize; if (paddingOffset) { bytes = getBytesCopy(concat([bytes, Padding.slice(paddingOffset)])); } return this.#writeData(bytes); } // Numeric item; pad on the left *to* WordSize writeValue(value) { return this.#writeData(getValue(value)); } // Inserts a numeric place-holder, returning a callback that can // be used to asjust the value later writeUpdatableValue() { const offset = this.#data.length; this.#data.push(Padding); this.#dataLength += WordSize; return (value) => { this.#data[offset] = getValue(value); }; } } /** * @_ignore */ class Reader { // Allows incomplete unpadded data to be read; otherwise an error // is raised if attempting to overrun the buffer. This is required // to deal with an old Solidity bug, in which event data for // external (not public thoguh) was tightly packed. allowLoose; #data; #offset; #bytesRead; #parent; #maxInflation; constructor(data, allowLoose, maxInflation) { defineProperties(this, { allowLoose: !!allowLoose }); this.#data = getBytesCopy(data); this.#bytesRead = 0; this.#parent = null; this.#maxInflation = (maxInflation != null) ? maxInflation : 1024; this.#offset = 0; } get data() { return hexlify(this.#data); } get dataLength() { return this.#data.length; } get consumed() { return this.#offset; } get bytes() { return new Uint8Array(this.#data); } #incrementBytesRead(count) { if (this.#parent) { return this.#parent.#incrementBytesRead(count); } this.#bytesRead += count; // Check for excessive inflation (see: #4537) assert(this.#maxInflation < 1 || this.#bytesRead <= this.#maxInflation * this.dataLength, `compressed ABI data exceeds inflation ratio of ${this.#maxInflation} ( see: https:/\/github.com/ethers-io/ethers.js/issues/4537 )`, "BUFFER_OVERRUN", { buffer: getBytesCopy(this.#data), offset: this.#offset, length: count, info: { bytesRead: this.#bytesRead, dataLength: this.dataLength } }); } #peekBytes(offset, length, loose) { let alignedLength = Math.ceil(length / WordSize) * WordSize; if (this.#offset + alignedLength > this.#data.length) { if (this.allowLoose && loose && this.#offset + length <= this.#data.length) { alignedLength = length; } else { assert(false, "data out-of-bounds", "BUFFER_OVERRUN", { buffer: getBytesCopy(this.#data), length: this.#data.length, offset: this.#offset + alignedLength }); } } return this.#data.slice(this.#offset, this.#offset + alignedLength); } // Create a sub-reader with the same underlying data, but offset subReader(offset) { const reader = new Reader(this.#data.slice(this.#offset + offset), this.allowLoose, this.#maxInflation); reader.#parent = this; return reader; } // Read bytes readBytes(length, loose) { let bytes = this.#peekBytes(0, length, !!loose); this.#incrementBytesRead(length); this.#offset += bytes.length; // @TODO: Make sure the length..end bytes are all 0? return bytes.slice(0, length); } // Read a numeric values readValue() { return toBigInt(this.readBytes(WordSize)); } readIndex() { return toNumber(this.readBytes(WordSize)); } } function number(n) { if (!Number.isSafeInteger(n) || n < 0) throw new Error(`Wrong positive integer: ${n}`); } function bytes$1(b, ...lengths) { if (!(b instanceof Uint8Array)) throw new Error('Expected Uint8Array'); if (lengths.length > 0 && !lengths.includes(b.length)) throw new Error(`Expected Uint8Array of length ${lengths}, not of length=${b.length}`); } function exists(instance, checkFinished = true) { if (instance.destroyed) throw new Error('Hash instance has been destroyed'); if (checkFinished && instance.finished) throw new Error('Hash#digest() has already been called'); } function output(out, instance) { bytes$1(out); const min = instance.outputLen; if (out.length < min) { throw new Error(`digestInto() expects output buffer of length at least ${min}`); } } /*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */ // We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+. // node.js versions earlier than v19 don't declare it in global scope. // For node.js, package.json#exports field mapping rewrites import // from `crypto` to `cryptoNode`, which imports native module. // Makes the utils un-importable in browsers without a bundler. // Once node.js 18 is deprecated, we can just drop the import. const u8a = (a) => a instanceof Uint8Array; const u32 = (arr) => new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4)); // big-endian hardware is rare. Just in case someone still decides to run hashes: // early-throw an error because we don't support BE yet. const isLE = new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44; if (!isLE) throw new Error('Non little-endian hardware is not supported'); /** * @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99]) */ function utf8ToBytes(str) { if (typeof str !== 'string') throw new Error(`utf8ToBytes expected string, got ${typeof str}`); return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809 } /** * Normalizes (non-hex) string or Uint8Array to Uint8Array. * Warning: when Uint8Array is passed, it would NOT get copied. * Keep in mind for future mutable operations. */ function toBytes(data) { if (typeof data === 'string') data = utf8ToBytes(data); if (!u8a(data)) throw new Error(`expected Uint8Array, got ${typeof data}`); return data; } // For runtime check if class implements interface class Hash { // Safe version that clones internal state clone() { return this._cloneInto(); } } function wrapConstructor(hashCons) { const hashC = (msg) => hashCons().update(toBytes(msg)).digest(); const tmp = hashCons(); hashC.outputLen = tmp.outputLen; hashC.blockLen = tmp.blockLen; hashC.create = () => hashCons(); return hashC; } const U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1); const _32n = /* @__PURE__ */ BigInt(32); // We are not using BigUint64Array, because they are extremely slow as per 2022 function fromBig(n, le = false) { if (le) return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) }; return { h: Number((n >> _32n) & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 }; } function split(lst, le = false) { let Ah = new Uint32Array(lst.length); let Al = new Uint32Array(lst.length); for (let i = 0; i < lst.length; i++) { const { h, l } = fromBig(lst[i], le); [Ah[i], Al[i]] = [h, l]; } return [Ah, Al]; } // Left rotate for Shift in [1, 32) const rotlSH = (h, l, s) => (h << s) | (l >>> (32 - s)); const rotlSL = (h, l, s) => (l << s) | (h >>> (32 - s)); // Left rotate for Shift in (32, 64), NOTE: 32 is special case. const rotlBH = (h, l, s) => (l << (s - 32)) | (h >>> (64 - s)); const rotlBL = (h, l, s) => (h << (s - 32)) | (l >>> (64 - s)); // SHA3 (keccak) is based on a new design: basically, the internal state is bigger than output size. // It's called a sponge function. // Various per round constants calculations const [SHA3_PI, SHA3_ROTL, _SHA3_IOTA] = [[], [], []]; const _0n = /* @__PURE__ */ BigInt(0); const _1n = /* @__PURE__ */ BigInt(1); const _2n = /* @__PURE__ */ BigInt(2); const _7n = /* @__PURE__ */ BigInt(7); const _256n = /* @__PURE__ */ BigInt(256); const _0x71n = /* @__PURE__ */ BigInt(0x71); for (let round = 0, R = _1n, x = 1, y = 0; round < 24; round++) { // Pi [x, y] = [y, (2 * x + 3 * y) % 5]; SHA3_PI.push(2 * (5 * y + x)); // Rotational SHA3_ROTL.push((((round + 1) * (round + 2)) / 2) % 64); // Iota let t = _0n; for (let j = 0; j < 7; j++) { R = ((R << _1n) ^ ((R >> _7n) * _0x71n)) % _256n; if (R & _2n) t ^= _1n << ((_1n << /* @__PURE__ */ BigInt(j)) - _1n); } _SHA3_IOTA.push(t); } const [SHA3_IOTA_H, SHA3_IOTA_L] = /* @__PURE__ */ split(_SHA3_IOTA, true); // Left rotation (without 0, 32, 64) const rotlH = (h, l, s) => (s > 32 ? rotlBH(h, l, s) : rotlSH(h, l, s)); const rotlL = (h, l, s) => (s > 32 ? rotlBL(h, l, s) : rotlSL(h, l, s)); // Same as keccakf1600, but allows to skip some rounds function keccakP(s, rounds = 24) { const B = new Uint32Array(5 * 2); // NOTE: all indices are x2 since we store state as u32 instead of u64 (bigints to slow in js) for (let round = 24 - rounds; round < 24; round++) { // Theta θ for (let x = 0; x < 10; x++) B[x] = s[x] ^ s[x + 10] ^ s[x + 20] ^ s[x + 30] ^ s[x + 40]; for (let x = 0; x < 10; x += 2) { const idx1 = (x + 8) % 10; const idx0 = (x + 2) % 10; const B0 = B[idx0]; const B1 = B[idx0 + 1]; const Th = rotlH(B0, B1, 1) ^ B[idx1]; const Tl = rotlL(B0, B1, 1) ^ B[idx1 + 1]; for (let y = 0; y < 50; y += 10) { s[x + y] ^= Th; s[x + y + 1] ^= Tl; } } // Rho (ρ) and Pi (π) let curH = s[2]; let curL = s[3]; for (let t = 0; t < 24; t++) { const shift = SHA3_ROTL[t]; const Th = rotlH(curH, curL, shift); const Tl = rotlL(curH, curL, shift); const PI = SHA3_PI[t]; curH = s[PI]; curL = s[PI + 1]; s[PI] = Th; s[PI + 1] = Tl; } // Chi (χ) for (let y = 0; y < 50; y += 10) { for (let x = 0; x < 10; x++) B[x] = s[y + x]; for (let x = 0; x < 10; x++) s[y + x] ^= ~B[(x + 2) % 10] & B[(x + 4) % 10]; } // Iota (ι) s[0] ^= SHA3_IOTA_H[round]; s[1] ^= SHA3_IOTA_L[round]; } B.fill(0); } class Keccak extends Hash { // NOTE: we accept arguments in bytes instead of bits here. constructor(blockLen, suffix, outputLen, enableXOF = false, rounds = 24) { super(); this.blockLen = blockLen; this.suffix = suffix; this.outputLen = outputLen; this.enableXOF = enableXOF; this.rounds = rounds; this.pos = 0; this.posOut = 0; this.finished = false; this.destroyed = false; // Can be passed from user as dkLen number(outputLen); // 1600 = 5x5 matrix of 64bit. 1600 bits === 200 bytes if (0 >= this.blockLen || this.blockLen >= 200) throw new Error('Sha3 supports only keccak-f1600 function'); this.state = new Uint8Array(200); this.state32 = u32(this.state); } keccak() { keccakP(this.state32, this.rounds); this.posOut = 0; this.pos = 0; } update(data) { exists(this); const { blockLen, state } = this; data = toBytes(data); const len = data.length; for (let pos = 0; pos < len;) { const take = Math.min(blockLen - this.pos, len - pos); for (let i = 0; i < take; i++) state[this.pos++] ^= data[pos++]; if (this.pos === blockLen) this.keccak(); } return this; } finish() { if (this.finished) return; this.finished = true; const { state, suffix, pos, blockLen } = this; // Do the padding state[pos] ^= suffix; if ((suffix & 0x80) !== 0 && pos === blockLen - 1) this.keccak(); state[blockLen - 1] ^= 0x80; this.keccak(); } writeInto(out) { exists(this, false); bytes$1(out); this.finish(); const bufferOut = this.stat