@vechain/connex
Version:
Standard interface to connect DApp with VeChain and user
1,487 lines (1,470 loc) • 583 kB
JavaScript
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