refactor: move brother_node development artifact to dev/test-nodes subdirectory
Development Artifact Cleanup: ✅ BROTHER_NODE REORGANIZATION: Moved development test node to appropriate location - dev/test-nodes/brother_node/: Moved from root directory for better organization - Contains development configuration, test logs, and test chain data - No impact on production systems - purely development/testing artifact ✅ DEVELOPMENT ARTIFACTS IDENTIFIED: - Chain ID: aitbc-brother-chain (test/development chain) - Ports: 8010 (P2P) and 8011 (RPC) - different from production - Environment: .env file with test configuration - Logs: rpc.log and node.log from development testing session (March 15, 2026) ✅ ROOT DIRECTORY CLEANUP: Removed development clutter from production directory - brother_node/ moved to dev/test-nodes/brother_node/ - Root directory now contains only production-ready components - Development artifacts properly organized in dev/ subdirectory DIRECTORY STRUCTURE IMPROVEMENT: 📁 dev/test-nodes/: Development and testing node configurations 🏗️ Root Directory: Clean production structure with only essential components 🧪 Development Isolation: Test environments separated from production BENEFITS: ✅ Clean Production Directory: No development artifacts in root ✅ Better Organization: Development nodes grouped in dev/ subdirectory ✅ Clear Separation: Production vs development environments clearly distinguished ✅ Maintainability: Easier to identify and manage development components RESULT: Successfully moved brother_node development artifact to dev/test-nodes/ subdirectory, cleaning up the root directory while preserving development testing environment for future use.
This commit is contained in:
237
dev/env/node_modules/ethers/src.ts/abi/abi-coder.ts
generated
vendored
Executable file
237
dev/env/node_modules/ethers/src.ts/abi/abi-coder.ts
generated
vendored
Executable file
@@ -0,0 +1,237 @@
|
||||
/**
|
||||
* When sending values to or receiving values from a [[Contract]], the
|
||||
* data is generally encoded using the [ABI standard](link-solc-abi).
|
||||
*
|
||||
* The AbiCoder provides a utility to encode values to ABI data and
|
||||
* decode values from ABI data.
|
||||
*
|
||||
* Most of the time, developers should favour the [[Contract]] class,
|
||||
* which further abstracts a lot of the finer details of ABI data.
|
||||
*
|
||||
* @_section api/abi/abi-coder:ABI Encoding
|
||||
*/
|
||||
|
||||
// See: https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI
|
||||
|
||||
import { assertArgumentCount, assertArgument } from "../utils/index.js";
|
||||
|
||||
import { Coder, Reader, Result, Writer } from "./coders/abstract-coder.js";
|
||||
import { AddressCoder } from "./coders/address.js";
|
||||
import { ArrayCoder } from "./coders/array.js";
|
||||
import { BooleanCoder } from "./coders/boolean.js";
|
||||
import { BytesCoder } from "./coders/bytes.js";
|
||||
import { FixedBytesCoder } from "./coders/fixed-bytes.js";
|
||||
import { NullCoder } from "./coders/null.js";
|
||||
import { NumberCoder } from "./coders/number.js";
|
||||
import { StringCoder } from "./coders/string.js";
|
||||
import { TupleCoder } from "./coders/tuple.js";
|
||||
import { ParamType } from "./fragments.js";
|
||||
|
||||
import { getAddress } from "../address/index.js";
|
||||
import { getBytes, hexlify, makeError } from "../utils/index.js";
|
||||
|
||||
import type {
|
||||
BytesLike,
|
||||
CallExceptionAction, CallExceptionError, CallExceptionTransaction
|
||||
} from "../utils/index.js";
|
||||
|
||||
// https://docs.soliditylang.org/en/v0.8.17/control-structures.html
|
||||
const PanicReasons: Map<number, string> = new Map();
|
||||
PanicReasons.set(0x00, "GENERIC_PANIC");
|
||||
PanicReasons.set(0x01, "ASSERT_FALSE");
|
||||
PanicReasons.set(0x11, "OVERFLOW");
|
||||
PanicReasons.set(0x12, "DIVIDE_BY_ZERO");
|
||||
PanicReasons.set(0x21, "ENUM_RANGE_ERROR");
|
||||
PanicReasons.set(0x22, "BAD_STORAGE_DATA");
|
||||
PanicReasons.set(0x31, "STACK_UNDERFLOW");
|
||||
PanicReasons.set(0x32, "ARRAY_RANGE_ERROR");
|
||||
PanicReasons.set(0x41, "OUT_OF_MEMORY");
|
||||
PanicReasons.set(0x51, "UNINITIALIZED_FUNCTION_CALL");
|
||||
|
||||
const paramTypeBytes = new RegExp(/^bytes([0-9]*)$/);
|
||||
const paramTypeNumber = new RegExp(/^(u?int)([0-9]*)$/);
|
||||
|
||||
|
||||
let defaultCoder: null | AbiCoder = null;
|
||||
let defaultMaxInflation = 1024;
|
||||
|
||||
function getBuiltinCallException(action: CallExceptionAction, tx: { to?: null | string, from?: null | string, data?: string }, data: null | BytesLike, abiCoder: AbiCoder): CallExceptionError {
|
||||
let message = "missing revert data";
|
||||
|
||||
let reason: null | string = null;
|
||||
const invocation = null;
|
||||
let revert: null | { signature: string, name: string, args: Array<any> } = null;
|
||||
|
||||
if (data) {
|
||||
message = "execution reverted";
|
||||
|
||||
const bytes = getBytes(data);
|
||||
data = hexlify(data);
|
||||
|
||||
if (bytes.length === 0) {
|
||||
message += " (no data present; likely require(false) occurred";
|
||||
reason = "require(false)";
|
||||
|
||||
} else if (bytes.length % 32 !== 4) {
|
||||
message += " (could not decode reason; invalid data length)";
|
||||
|
||||
} else if (hexlify(bytes.slice(0, 4)) === "0x08c379a0") {
|
||||
// Error(string)
|
||||
try {
|
||||
reason = abiCoder.decode([ "string" ], bytes.slice(4))[0]
|
||||
revert = {
|
||||
signature: "Error(string)",
|
||||
name: "Error",
|
||||
args: [ reason ]
|
||||
};
|
||||
message += `: ${ JSON.stringify(reason) }`;
|
||||
|
||||
} catch (error) {
|
||||
message += " (could not decode reason; invalid string data)";
|
||||
}
|
||||
|
||||
} else if (hexlify(bytes.slice(0, 4)) === "0x4e487b71") {
|
||||
// Panic(uint256)
|
||||
try {
|
||||
const code = Number(abiCoder.decode([ "uint256" ], bytes.slice(4))[0]);
|
||||
revert = {
|
||||
signature: "Panic(uint256)",
|
||||
name: "Panic",
|
||||
args: [ code ]
|
||||
};
|
||||
reason = `Panic due to ${ PanicReasons.get(code) || "UNKNOWN" }(${ code })`;
|
||||
message += `: ${ reason }`;
|
||||
} catch (error) {
|
||||
message += " (could not decode panic code)";
|
||||
}
|
||||
} else {
|
||||
message += " (unknown custom error)";
|
||||
}
|
||||
}
|
||||
|
||||
const transaction: CallExceptionTransaction = {
|
||||
to: (tx.to ? getAddress(tx.to): null),
|
||||
data: (tx.data || "0x")
|
||||
};
|
||||
if (tx.from) { transaction.from = getAddress(tx.from); }
|
||||
|
||||
return makeError(message, "CALL_EXCEPTION", {
|
||||
action, data, reason, transaction, invocation, revert
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* The **AbiCoder** is a low-level class responsible for encoding JavaScript
|
||||
* values into binary data and decoding binary data into JavaScript values.
|
||||
*/
|
||||
export class AbiCoder {
|
||||
|
||||
#getCoder(param: ParamType): Coder {
|
||||
if (param.isArray()) {
|
||||
return new ArrayCoder(this.#getCoder(param.arrayChildren), param.arrayLength, param.name);
|
||||
}
|
||||
|
||||
if (param.isTuple()) {
|
||||
return new TupleCoder(param.components.map((c) => this.#getCoder(c)), param.name);
|
||||
}
|
||||
|
||||
switch (param.baseType) {
|
||||
case "address":
|
||||
return new AddressCoder(param.name);
|
||||
case "bool":
|
||||
return new BooleanCoder(param.name);
|
||||
case "string":
|
||||
return new StringCoder(param.name);
|
||||
case "bytes":
|
||||
return new BytesCoder(param.name);
|
||||
case "":
|
||||
return new NullCoder(param.name);
|
||||
}
|
||||
|
||||
// u?int[0-9]*
|
||||
let match = param.type.match(paramTypeNumber);
|
||||
if (match) {
|
||||
let size = parseInt(match[2] || "256");
|
||||
assertArgument(size !== 0 && size <= 256 && (size % 8) === 0,
|
||||
"invalid " + match[1] + " bit length", "param", param);
|
||||
return new NumberCoder(size / 8, (match[1] === "int"), param.name);
|
||||
}
|
||||
|
||||
// bytes[0-9]+
|
||||
match = param.type.match(paramTypeBytes);
|
||||
if (match) {
|
||||
let size = parseInt(match[1]);
|
||||
assertArgument(size !== 0 && size <= 32, "invalid bytes length", "param", param);
|
||||
return new FixedBytesCoder(size, param.name);
|
||||
}
|
||||
|
||||
assertArgument(false, "invalid type", "type", param.type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default values for the given %%types%%.
|
||||
*
|
||||
* For example, a ``uint`` is by default ``0`` and ``bool``
|
||||
* is by default ``false``.
|
||||
*/
|
||||
getDefaultValue(types: ReadonlyArray<string | ParamType>): Result {
|
||||
const coders: Array<Coder> = types.map((type) => this.#getCoder(ParamType.from(type)));
|
||||
const coder = new TupleCoder(coders, "_");
|
||||
return coder.defaultValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the %%values%% as the %%types%% into ABI data.
|
||||
*
|
||||
* @returns DataHexstring
|
||||
*/
|
||||
encode(types: ReadonlyArray<string | ParamType>, values: ReadonlyArray<any>): string {
|
||||
assertArgumentCount(values.length, types.length, "types/values length mismatch");
|
||||
|
||||
const coders = types.map((type) => this.#getCoder(ParamType.from(type)));
|
||||
const coder = (new TupleCoder(coders, "_"));
|
||||
|
||||
const writer = new Writer();
|
||||
coder.encode(writer, values);
|
||||
return writer.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode the ABI %%data%% as the %%types%% into values.
|
||||
*
|
||||
* If %%loose%% decoding is enabled, then strict padding is
|
||||
* not enforced. Some older versions of Solidity incorrectly
|
||||
* padded event data emitted from ``external`` functions.
|
||||
*/
|
||||
decode(types: ReadonlyArray<string | ParamType>, data: BytesLike, loose?: boolean): Result {
|
||||
const coders: Array<Coder> = types.map((type) => this.#getCoder(ParamType.from(type)));
|
||||
const coder = new TupleCoder(coders, "_");
|
||||
return coder.decode(new Reader(data, loose, defaultMaxInflation));
|
||||
}
|
||||
|
||||
static _setDefaultMaxInflation(value: number): void {
|
||||
assertArgument(typeof(value) === "number" && Number.isInteger(value), "invalid defaultMaxInflation factor", "value", value);
|
||||
defaultMaxInflation = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the shared singleton instance of a default [[AbiCoder]].
|
||||
*
|
||||
* On the first call, the instance is created internally.
|
||||
*/
|
||||
static defaultAbiCoder(): AbiCoder {
|
||||
if (defaultCoder == null) {
|
||||
defaultCoder = new AbiCoder();
|
||||
}
|
||||
return defaultCoder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an ethers-compatible [[CallExceptionError]] Error for the given
|
||||
* result %%data%% for the [[CallExceptionAction]] %%action%% against
|
||||
* the Transaction %%tx%%.
|
||||
*/
|
||||
static getBuiltinCallException(action: CallExceptionAction, tx: { to?: null | string, from?: null | string, data?: string }, data: null | BytesLike): CallExceptionError {
|
||||
return getBuiltinCallException(action, tx, data, AbiCoder.defaultAbiCoder());
|
||||
}
|
||||
}
|
||||
45
dev/env/node_modules/ethers/src.ts/abi/bytes32.ts
generated
vendored
Executable file
45
dev/env/node_modules/ethers/src.ts/abi/bytes32.ts
generated
vendored
Executable file
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* About bytes32 strings...
|
||||
*
|
||||
* @_docloc: api/utils:Bytes32 Strings
|
||||
*/
|
||||
|
||||
import {
|
||||
getBytes, toUtf8Bytes, toUtf8String, zeroPadBytes
|
||||
} from "../utils/index.js";
|
||||
|
||||
import type { BytesLike } from "../utils/index.js";
|
||||
|
||||
/**
|
||||
* Encodes %%text%% as a Bytes32 string.
|
||||
*/
|
||||
export function encodeBytes32String(text: string): string {
|
||||
|
||||
// Get the bytes
|
||||
const bytes = toUtf8Bytes(text);
|
||||
|
||||
// Check we have room for null-termination
|
||||
if (bytes.length > 31) { throw new Error("bytes32 string must be less than 32 bytes"); }
|
||||
|
||||
// Zero-pad (implicitly null-terminates)
|
||||
return zeroPadBytes(bytes, 32);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the Bytes32-encoded %%bytes%% into a string.
|
||||
*/
|
||||
export function decodeBytes32String(_bytes: BytesLike): string {
|
||||
const data = getBytes(_bytes, "bytes");
|
||||
|
||||
// Must be 32 bytes with a null-termination
|
||||
if (data.length !== 32) { throw new Error("invalid bytes32 - not 32 bytes long"); }
|
||||
if (data[31] !== 0) { throw new Error("invalid bytes32 string - no null terminator"); }
|
||||
|
||||
// Find the null termination
|
||||
let length = 31;
|
||||
while (data[length - 1] === 0) { length--; }
|
||||
|
||||
// Determine the string value
|
||||
return toUtf8String(data.slice(0, length));
|
||||
}
|
||||
|
||||
541
dev/env/node_modules/ethers/src.ts/abi/coders/abstract-coder.ts
generated
vendored
Executable file
541
dev/env/node_modules/ethers/src.ts/abi/coders/abstract-coder.ts
generated
vendored
Executable file
@@ -0,0 +1,541 @@
|
||||
|
||||
import {
|
||||
defineProperties, concat, getBytesCopy, getNumber, hexlify,
|
||||
toBeArray, toBigInt, toNumber,
|
||||
assert, assertArgument
|
||||
/*, isError*/
|
||||
} from "../../utils/index.js";
|
||||
|
||||
import type { BigNumberish, BytesLike } from "../../utils/index.js";
|
||||
|
||||
/**
|
||||
* @_ignore:
|
||||
*/
|
||||
export const WordSize: number = 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 = { };
|
||||
|
||||
const resultNames: WeakMap<Result, ReadonlyArray<null | string>> = new WeakMap();
|
||||
|
||||
function getNames(result: Result): ReadonlyArray<null | string> {
|
||||
return resultNames.get(result)!;
|
||||
}
|
||||
function setNames(result: Result, names: ReadonlyArray<null | string>): void {
|
||||
resultNames.set(result, names);
|
||||
}
|
||||
|
||||
function throwError(name: string, error: Error): never {
|
||||
const wrapped = new Error(`deferred error during ABI decoding triggered accessing ${ name }`);
|
||||
(<any>wrapped).error = error;
|
||||
throw wrapped;
|
||||
}
|
||||
|
||||
function toObject(names: ReadonlyArray<null | string>, items: Result, deep?: boolean): Record<string, any> | Array<any> {
|
||||
if (names.indexOf(null) >= 0) {
|
||||
return items.map((item, index) => {
|
||||
if (item instanceof Result) {
|
||||
return toObject(getNames(item), item, deep);
|
||||
}
|
||||
return item;
|
||||
});
|
||||
}
|
||||
|
||||
return (<Array<string>>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;
|
||||
}, <Record<string, any>>{ });
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
export class Result extends Array<any> {
|
||||
// No longer used; but cannot be removed as it will remove the
|
||||
// #private field from the .d.ts which may break backwards
|
||||
// compatibility
|
||||
readonly #names: ReadonlyArray<null | string>;
|
||||
|
||||
[ K: string | number ]: any
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
constructor(...args: Array<any>) {
|
||||
// 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: Array<any> = args[1];
|
||||
let names: Array<null | string> = (args[2] || [ ]).slice();
|
||||
|
||||
let wrap = true;
|
||||
if (guard !== _guard) {
|
||||
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;
|
||||
}, <Map<string, number>>(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(this: any, ...args: Array<any>) {
|
||||
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?: boolean): Array<any> {
|
||||
const result: Array<any> = [ ];
|
||||
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?: boolean): Record<string, any> {
|
||||
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);
|
||||
}, <Record<string, any>>{});
|
||||
}
|
||||
|
||||
/**
|
||||
* @_ignore
|
||||
*/
|
||||
slice(start?: number | undefined, end?: number | undefined): Result {
|
||||
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: Array<any> = [ ], names: Array<null | string> = [ ];
|
||||
for (let i = start; i < end; i++) {
|
||||
result.push(this[i]);
|
||||
names.push(_names[i]);
|
||||
}
|
||||
|
||||
return new Result(_guard, result, names);
|
||||
}
|
||||
|
||||
/**
|
||||
* @_ignore
|
||||
*/
|
||||
filter(callback: (el: any, index: number, array: Result) => boolean, thisArg?: any): Result {
|
||||
const _names = getNames(this);
|
||||
|
||||
const result: Array<any> = [ ], names: Array<null | string> = [ ];
|
||||
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, result, names);
|
||||
}
|
||||
|
||||
/**
|
||||
* @_ignore
|
||||
*/
|
||||
map<T extends any = any>(callback: (el: any, index: number, array: Result) => T, thisArg?: any): Array<T> {
|
||||
const result: Array<T> = [ ];
|
||||
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: string): any {
|
||||
const index = getNames(this).indexOf(name);
|
||||
if (index === -1) { return undefined; }
|
||||
|
||||
const value = this[index];
|
||||
|
||||
if (value instanceof Error) {
|
||||
throwError(`property ${ JSON.stringify(name) }`, (<any>value).error);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new [[Result]] for %%items%% with each entry
|
||||
* also accessible by its corresponding name in %%keys%%.
|
||||
*/
|
||||
static fromItems(items: Array<any>, keys?: Array<null | string>): Result {
|
||||
return new Result(_guard, items, keys);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all errors found in a [[Result]].
|
||||
*
|
||||
* Since certain errors encountered when creating a [[Result]] do
|
||||
* not impact the ability to continue parsing data, they are
|
||||
* deferred until they are actually accessed. Hence a faulty string
|
||||
* in an Event that is never used does not impact the program flow.
|
||||
*
|
||||
* However, sometimes it may be useful to access, identify or
|
||||
* validate correctness of a [[Result]].
|
||||
*
|
||||
* @_docloc api/abi
|
||||
*/
|
||||
export function checkResultErrors(result: Result): Array<{ path: Array<string | number>, error: Error }> {
|
||||
// Find the first error (if any)
|
||||
const errors: Array<{ path: Array<string | number>, error: Error }> = [ ];
|
||||
|
||||
const checkErrors = function(path: Array<string | number>, object: any): void {
|
||||
if (!Array.isArray(object)) { return; }
|
||||
for (let key in object) {
|
||||
const childPath = path.slice();
|
||||
childPath.push(key);
|
||||
|
||||
try {
|
||||
checkErrors(childPath, object[key]);
|
||||
} catch (error: any) {
|
||||
errors.push({ path: childPath, error: error });
|
||||
}
|
||||
}
|
||||
}
|
||||
checkErrors([ ], result);
|
||||
|
||||
return errors;
|
||||
|
||||
}
|
||||
|
||||
function getValue(value: BigNumberish): Uint8Array {
|
||||
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
|
||||
*/
|
||||
export abstract class Coder {
|
||||
|
||||
// The coder name:
|
||||
// - address, uint256, tuple, array, etc.
|
||||
readonly name!: string;
|
||||
|
||||
// The fully expanded type, including composite types:
|
||||
// - address, uint256, tuple(address,bytes), uint256[3][4][], etc.
|
||||
readonly type!: string;
|
||||
|
||||
// The localName bound in the signature, in this example it is "baz":
|
||||
// - tuple(address foo, uint bar) baz
|
||||
readonly localName!: string;
|
||||
|
||||
// Whether this type is dynamic:
|
||||
// - Dynamic: bytes, string, address[], tuple(boolean[]), etc.
|
||||
// - Not Dynamic: address, uint256, boolean[3], tuple(address, uint8)
|
||||
readonly dynamic!: boolean;
|
||||
|
||||
constructor(name: string, type: string, localName: string, dynamic: boolean) {
|
||||
defineProperties<Coder>(this, { name, type, localName, dynamic }, {
|
||||
name: "string", type: "string", localName: "string", dynamic: "boolean"
|
||||
});
|
||||
}
|
||||
|
||||
_throwError(message: string, value: any): never {
|
||||
assertArgument(false, message, this.localName, value);
|
||||
}
|
||||
|
||||
abstract encode(writer: Writer, value: any): number;
|
||||
abstract decode(reader: Reader): any;
|
||||
|
||||
abstract defaultValue(): any;
|
||||
}
|
||||
|
||||
/**
|
||||
* @_ignore
|
||||
*/
|
||||
export class Writer {
|
||||
// An array of WordSize lengthed objects to concatenation
|
||||
#data: Array<Uint8Array>;
|
||||
#dataLength: number;
|
||||
|
||||
constructor() {
|
||||
this.#data = [ ];
|
||||
this.#dataLength = 0;
|
||||
}
|
||||
|
||||
get data(): string {
|
||||
return concat(this.#data);
|
||||
}
|
||||
get length(): number { return this.#dataLength; }
|
||||
|
||||
#writeData(data: Uint8Array): number {
|
||||
this.#data.push(data);
|
||||
this.#dataLength += data.length;
|
||||
return data.length;
|
||||
}
|
||||
|
||||
appendWriter(writer: Writer): number {
|
||||
return this.#writeData(getBytesCopy(writer.data));
|
||||
}
|
||||
|
||||
// Arrayish item; pad on the right to *nearest* WordSize
|
||||
writeBytes(value: BytesLike): number {
|
||||
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: BigNumberish): number {
|
||||
return this.#writeData(getValue(value));
|
||||
}
|
||||
|
||||
// Inserts a numeric place-holder, returning a callback that can
|
||||
// be used to asjust the value later
|
||||
writeUpdatableValue(): (value: BigNumberish) => void {
|
||||
const offset = this.#data.length;
|
||||
this.#data.push(Padding);
|
||||
this.#dataLength += WordSize;
|
||||
return (value: BigNumberish) => {
|
||||
this.#data[offset] = getValue(value);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @_ignore
|
||||
*/
|
||||
export 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.
|
||||
readonly allowLoose!: boolean;
|
||||
|
||||
readonly #data: Uint8Array;
|
||||
#offset: number;
|
||||
|
||||
#bytesRead: number;
|
||||
#parent: null | Reader;
|
||||
#maxInflation: number;
|
||||
|
||||
constructor(data: BytesLike, allowLoose?: boolean, maxInflation?: number) {
|
||||
defineProperties<Reader>(this, { allowLoose: !!allowLoose });
|
||||
|
||||
this.#data = getBytesCopy(data);
|
||||
this.#bytesRead = 0;
|
||||
this.#parent = null;
|
||||
this.#maxInflation = (maxInflation != null) ? maxInflation: 1024;
|
||||
|
||||
this.#offset = 0;
|
||||
}
|
||||
|
||||
get data(): string { return hexlify(this.#data); }
|
||||
get dataLength(): number { return this.#data.length; }
|
||||
get consumed(): number { return this.#offset; }
|
||||
get bytes(): Uint8Array { return new Uint8Array(this.#data); }
|
||||
|
||||
#incrementBytesRead(count: number): void {
|
||||
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: number, length: number, loose?: boolean): Uint8Array {
|
||||
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: number): Reader {
|
||||
const reader = new Reader(this.#data.slice(this.#offset + offset), this.allowLoose, this.#maxInflation);
|
||||
reader.#parent = this;
|
||||
return reader;
|
||||
}
|
||||
|
||||
// Read bytes
|
||||
readBytes(length: number, loose?: boolean): Uint8Array {
|
||||
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(): bigint {
|
||||
return toBigInt(this.readBytes(WordSize));
|
||||
}
|
||||
|
||||
readIndex(): number {
|
||||
return toNumber(this.readBytes(WordSize));
|
||||
}
|
||||
}
|
||||
36
dev/env/node_modules/ethers/src.ts/abi/coders/address.ts
generated
vendored
Executable file
36
dev/env/node_modules/ethers/src.ts/abi/coders/address.ts
generated
vendored
Executable file
@@ -0,0 +1,36 @@
|
||||
import { getAddress } from "../../address/index.js";
|
||||
import { toBeHex } from "../../utils/maths.js";
|
||||
|
||||
import { Typed } from "../typed.js";
|
||||
import { Coder } from "./abstract-coder.js";
|
||||
|
||||
import type { Reader, Writer } from "./abstract-coder.js";
|
||||
|
||||
|
||||
/**
|
||||
* @_ignore
|
||||
*/
|
||||
export class AddressCoder extends Coder {
|
||||
|
||||
constructor(localName: string) {
|
||||
super("address", "address", localName, false);
|
||||
}
|
||||
|
||||
defaultValue(): string {
|
||||
return "0x0000000000000000000000000000000000000000";
|
||||
}
|
||||
|
||||
encode(writer: Writer, _value: string | Typed): number {
|
||||
let value = Typed.dereference(_value, "string");
|
||||
try {
|
||||
value = getAddress(value);
|
||||
} catch (error: any) {
|
||||
return this._throwError(error.message, _value);
|
||||
}
|
||||
return writer.writeValue(value);
|
||||
}
|
||||
|
||||
decode(reader: Reader): any {
|
||||
return getAddress(toBeHex(reader.readValue(), 20));
|
||||
}
|
||||
}
|
||||
29
dev/env/node_modules/ethers/src.ts/abi/coders/anonymous.ts
generated
vendored
Executable file
29
dev/env/node_modules/ethers/src.ts/abi/coders/anonymous.ts
generated
vendored
Executable file
@@ -0,0 +1,29 @@
|
||||
import { Coder } from "./abstract-coder.js";
|
||||
|
||||
import type { Reader, Writer } from "./abstract-coder.js";
|
||||
|
||||
/**
|
||||
* Clones the functionality of an existing Coder, but without a localName
|
||||
*
|
||||
* @_ignore
|
||||
*/
|
||||
export class AnonymousCoder extends Coder {
|
||||
private coder: Coder;
|
||||
|
||||
constructor(coder: Coder) {
|
||||
super(coder.name, coder.type, "_", coder.dynamic);
|
||||
this.coder = coder;
|
||||
}
|
||||
|
||||
defaultValue(): any {
|
||||
return this.coder.defaultValue();
|
||||
}
|
||||
|
||||
encode(writer: Writer, value: any): number {
|
||||
return this.coder.encode(writer, value);
|
||||
}
|
||||
|
||||
decode(reader: Reader): any {
|
||||
return this.coder.decode(reader);
|
||||
}
|
||||
}
|
||||
199
dev/env/node_modules/ethers/src.ts/abi/coders/array.ts
generated
vendored
Executable file
199
dev/env/node_modules/ethers/src.ts/abi/coders/array.ts
generated
vendored
Executable file
@@ -0,0 +1,199 @@
|
||||
import {
|
||||
defineProperties, isError, assert, assertArgument, assertArgumentCount
|
||||
} from "../../utils/index.js";
|
||||
|
||||
import { Typed } from "../typed.js";
|
||||
|
||||
import { Coder, Result, WordSize, Writer } from "./abstract-coder.js";
|
||||
import { AnonymousCoder } from "./anonymous.js";
|
||||
|
||||
import type { Reader } from "./abstract-coder.js";
|
||||
|
||||
/**
|
||||
* @_ignore
|
||||
*/
|
||||
export function pack(writer: Writer, coders: ReadonlyArray<Coder>, values: Array<any> | { [ name: string ]: any }): number {
|
||||
let arrayValues: Array<any> = [ ];
|
||||
|
||||
if (Array.isArray(values)) {
|
||||
arrayValues = values;
|
||||
|
||||
} else if (values && typeof(values) === "object") {
|
||||
let unique: { [ name: string ]: boolean } = { };
|
||||
|
||||
arrayValues = coders.map((coder) => {
|
||||
const name = coder.localName;
|
||||
assert(name, "cannot encode object for signature with missing names",
|
||||
"INVALID_ARGUMENT", { argument: "values", info: { coder }, value: values });
|
||||
|
||||
assert(!unique[name], "cannot encode object for signature with duplicate names",
|
||||
"INVALID_ARGUMENT", { argument: "values", info: { coder }, value: values });
|
||||
|
||||
unique[name] = true;
|
||||
|
||||
return values[name];
|
||||
});
|
||||
|
||||
} else {
|
||||
assertArgument(false, "invalid tuple value", "tuple", values);
|
||||
}
|
||||
|
||||
assertArgument(coders.length === arrayValues.length, "types/value length mismatch", "tuple", values);
|
||||
|
||||
let staticWriter = new Writer();
|
||||
let dynamicWriter = new Writer();
|
||||
|
||||
let updateFuncs: Array<(baseOffset: number) => void> = [];
|
||||
coders.forEach((coder, index) => {
|
||||
let value = arrayValues[index];
|
||||
|
||||
if (coder.dynamic) {
|
||||
// Get current dynamic offset (for the future pointer)
|
||||
let dynamicOffset = dynamicWriter.length;
|
||||
|
||||
// Encode the dynamic value into the dynamicWriter
|
||||
coder.encode(dynamicWriter, value);
|
||||
|
||||
// Prepare to populate the correct offset once we are done
|
||||
let updateFunc = staticWriter.writeUpdatableValue();
|
||||
updateFuncs.push((baseOffset: number) => {
|
||||
updateFunc(baseOffset + dynamicOffset);
|
||||
});
|
||||
|
||||
} else {
|
||||
coder.encode(staticWriter, value);
|
||||
}
|
||||
});
|
||||
|
||||
// Backfill all the dynamic offsets, now that we know the static length
|
||||
updateFuncs.forEach((func) => { func(staticWriter.length); });
|
||||
|
||||
let length = writer.appendWriter(staticWriter);
|
||||
length += writer.appendWriter(dynamicWriter);
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @_ignore
|
||||
*/
|
||||
export function unpack(reader: Reader, coders: ReadonlyArray<Coder>): Result {
|
||||
let values: Array<any> = [];
|
||||
let keys: Array<null | string> = [ ];
|
||||
|
||||
// A reader anchored to this base
|
||||
let baseReader = reader.subReader(0);
|
||||
|
||||
coders.forEach((coder) => {
|
||||
let value: any = null;
|
||||
|
||||
if (coder.dynamic) {
|
||||
let offset = reader.readIndex();
|
||||
let offsetReader = baseReader.subReader(offset);
|
||||
try {
|
||||
value = coder.decode(offsetReader);
|
||||
} catch (error: any) {
|
||||
// Cannot recover from this
|
||||
if (isError(error, "BUFFER_OVERRUN")) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
value = error;
|
||||
value.baseType = coder.name;
|
||||
value.name = coder.localName;
|
||||
value.type = coder.type;
|
||||
}
|
||||
|
||||
} else {
|
||||
try {
|
||||
value = coder.decode(reader);
|
||||
} catch (error: any) {
|
||||
// Cannot recover from this
|
||||
if (isError(error, "BUFFER_OVERRUN")) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
value = error;
|
||||
value.baseType = coder.name;
|
||||
value.name = coder.localName;
|
||||
value.type = coder.type;
|
||||
}
|
||||
}
|
||||
|
||||
if (value == undefined) {
|
||||
throw new Error("investigate");
|
||||
}
|
||||
|
||||
values.push(value);
|
||||
keys.push(coder.localName || null);
|
||||
});
|
||||
|
||||
return Result.fromItems(values, keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* @_ignore
|
||||
*/
|
||||
export class ArrayCoder extends Coder {
|
||||
readonly coder!: Coder;
|
||||
readonly length!: number;
|
||||
|
||||
constructor(coder: Coder, length: number, localName: string) {
|
||||
const type = (coder.type + "[" + (length >= 0 ? length: "") + "]");
|
||||
const dynamic = (length === -1 || coder.dynamic);
|
||||
super("array", type, localName, dynamic);
|
||||
defineProperties<ArrayCoder>(this, { coder, length });
|
||||
}
|
||||
|
||||
defaultValue(): Array<any> {
|
||||
// Verifies the child coder is valid (even if the array is dynamic or 0-length)
|
||||
const defaultChild = this.coder.defaultValue();
|
||||
|
||||
const result: Array<any> = [];
|
||||
for (let i = 0; i < this.length; i++) {
|
||||
result.push(defaultChild);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
encode(writer: Writer, _value: Array<any> | Typed): number {
|
||||
const value = Typed.dereference(_value, "array");
|
||||
|
||||
if(!Array.isArray(value)) {
|
||||
this._throwError("expected array value", value);
|
||||
}
|
||||
|
||||
let count = this.length;
|
||||
|
||||
if (count === -1) {
|
||||
count = value.length;
|
||||
writer.writeValue(value.length);
|
||||
}
|
||||
|
||||
assertArgumentCount(value.length, count, "coder array" + (this.localName? (" "+ this.localName): ""));
|
||||
|
||||
let coders: Array<Coder> = [ ];
|
||||
for (let i = 0; i < value.length; i++) { coders.push(this.coder); }
|
||||
|
||||
return pack(writer, coders, value);
|
||||
}
|
||||
|
||||
decode(reader: Reader): any {
|
||||
let count = this.length;
|
||||
if (count === -1) {
|
||||
count = reader.readIndex();
|
||||
|
||||
// Check that there is *roughly* enough data to ensure
|
||||
// stray random data is not being read as a length. Each
|
||||
// slot requires at least 32 bytes for their value (or 32
|
||||
// bytes as a link to the data). This could use a much
|
||||
// tighter bound, but we are erroring on the side of safety.
|
||||
assert(count * WordSize <= reader.dataLength, "insufficient data length",
|
||||
"BUFFER_OVERRUN", { buffer: reader.bytes, offset: count * WordSize, length: reader.dataLength });
|
||||
}
|
||||
let coders: Array<Coder> = [];
|
||||
for (let i = 0; i < count; i++) { coders.push(new AnonymousCoder(this.coder)); }
|
||||
|
||||
return unpack(reader, coders);
|
||||
}
|
||||
}
|
||||
|
||||
27
dev/env/node_modules/ethers/src.ts/abi/coders/boolean.ts
generated
vendored
Executable file
27
dev/env/node_modules/ethers/src.ts/abi/coders/boolean.ts
generated
vendored
Executable file
@@ -0,0 +1,27 @@
|
||||
import { Typed } from "../typed.js";
|
||||
import { Coder } from "./abstract-coder.js";
|
||||
|
||||
import type { Reader, Writer } from "./abstract-coder.js";
|
||||
|
||||
/**
|
||||
* @_ignore
|
||||
*/
|
||||
export class BooleanCoder extends Coder {
|
||||
|
||||
constructor(localName: string) {
|
||||
super("bool", "bool", localName, false);
|
||||
}
|
||||
|
||||
defaultValue(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
encode(writer: Writer, _value: boolean | Typed): number {
|
||||
const value = Typed.dereference(_value, "bool");
|
||||
return writer.writeValue(value ? 1: 0);
|
||||
}
|
||||
|
||||
decode(reader: Reader): any {
|
||||
return !!reader.readValue();
|
||||
}
|
||||
}
|
||||
43
dev/env/node_modules/ethers/src.ts/abi/coders/bytes.ts
generated
vendored
Executable file
43
dev/env/node_modules/ethers/src.ts/abi/coders/bytes.ts
generated
vendored
Executable file
@@ -0,0 +1,43 @@
|
||||
import { getBytesCopy, hexlify } from "../../utils/index.js";
|
||||
|
||||
import { Coder } from "./abstract-coder.js";
|
||||
|
||||
import type { Reader, Writer } from "./abstract-coder.js";
|
||||
|
||||
|
||||
/**
|
||||
* @_ignore
|
||||
*/
|
||||
export class DynamicBytesCoder extends Coder {
|
||||
constructor(type: string, localName: string) {
|
||||
super(type, type, localName, true);
|
||||
}
|
||||
|
||||
defaultValue(): string {
|
||||
return "0x";
|
||||
}
|
||||
|
||||
encode(writer: Writer, value: any): number {
|
||||
value = getBytesCopy(value);
|
||||
let length = writer.writeValue(value.length);
|
||||
length += writer.writeBytes(value);
|
||||
return length;
|
||||
}
|
||||
|
||||
decode(reader: Reader): any {
|
||||
return reader.readBytes(reader.readIndex(), true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @_ignore
|
||||
*/
|
||||
export class BytesCoder extends DynamicBytesCoder {
|
||||
constructor(localName: string) {
|
||||
super("bytes", localName);
|
||||
}
|
||||
|
||||
decode(reader: Reader): any {
|
||||
return hexlify(super.decode(reader));
|
||||
}
|
||||
}
|
||||
37
dev/env/node_modules/ethers/src.ts/abi/coders/fixed-bytes.ts
generated
vendored
Executable file
37
dev/env/node_modules/ethers/src.ts/abi/coders/fixed-bytes.ts
generated
vendored
Executable file
@@ -0,0 +1,37 @@
|
||||
|
||||
import { defineProperties, getBytesCopy, hexlify } from "../../utils/index.js";
|
||||
|
||||
import { Typed } from "../typed.js";
|
||||
import { Coder } from "./abstract-coder.js";
|
||||
|
||||
import type { BytesLike } from "../../utils/index.js";
|
||||
|
||||
import type { Reader, Writer } from "./abstract-coder.js";
|
||||
|
||||
|
||||
/**
|
||||
* @_ignore
|
||||
*/
|
||||
export class FixedBytesCoder extends Coder {
|
||||
readonly size!: number;
|
||||
|
||||
constructor(size: number, localName: string) {
|
||||
let name = "bytes" + String(size);
|
||||
super(name, name, localName, false);
|
||||
defineProperties<FixedBytesCoder>(this, { size }, { size: "number" });
|
||||
}
|
||||
|
||||
defaultValue(): string {
|
||||
return ("0x0000000000000000000000000000000000000000000000000000000000000000").substring(0, 2 + this.size * 2);
|
||||
}
|
||||
|
||||
encode(writer: Writer, _value: BytesLike | Typed): number {
|
||||
let data = getBytesCopy(Typed.dereference(_value, this.type));
|
||||
if (data.length !== this.size) { this._throwError("incorrect data length", _value); }
|
||||
return writer.writeBytes(data);
|
||||
}
|
||||
|
||||
decode(reader: Reader): any {
|
||||
return hexlify(reader.readBytes(this.size));
|
||||
}
|
||||
}
|
||||
28
dev/env/node_modules/ethers/src.ts/abi/coders/null.ts
generated
vendored
Executable file
28
dev/env/node_modules/ethers/src.ts/abi/coders/null.ts
generated
vendored
Executable file
@@ -0,0 +1,28 @@
|
||||
import { Coder } from "./abstract-coder.js";
|
||||
import type { Reader, Writer } from "./abstract-coder.js";
|
||||
|
||||
const Empty = new Uint8Array([ ]);
|
||||
|
||||
/**
|
||||
* @_ignore
|
||||
*/
|
||||
export class NullCoder extends Coder {
|
||||
|
||||
constructor(localName: string) {
|
||||
super("null", "", localName, false);
|
||||
}
|
||||
|
||||
defaultValue(): null {
|
||||
return null;
|
||||
}
|
||||
|
||||
encode(writer: Writer, value: any): number {
|
||||
if (value != null) { this._throwError("not null", value); }
|
||||
return writer.writeBytes(Empty);
|
||||
}
|
||||
|
||||
decode(reader: Reader): any {
|
||||
reader.readBytes(0);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
63
dev/env/node_modules/ethers/src.ts/abi/coders/number.ts
generated
vendored
Executable file
63
dev/env/node_modules/ethers/src.ts/abi/coders/number.ts
generated
vendored
Executable file
@@ -0,0 +1,63 @@
|
||||
import {
|
||||
defineProperties, fromTwos, getBigInt, mask, toTwos
|
||||
} from "../../utils/index.js";
|
||||
|
||||
import { Typed } from "../typed.js";
|
||||
import { Coder, WordSize } from "./abstract-coder.js";
|
||||
|
||||
import type { BigNumberish } from "../../utils/index.js";
|
||||
|
||||
import type { Reader, Writer } from "./abstract-coder.js";
|
||||
|
||||
|
||||
const BN_0 = BigInt(0);
|
||||
const BN_1 = BigInt(1);
|
||||
const BN_MAX_UINT256 = BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
|
||||
|
||||
/**
|
||||
* @_ignore
|
||||
*/
|
||||
export class NumberCoder extends Coder {
|
||||
readonly size!: number;
|
||||
readonly signed!: boolean;
|
||||
|
||||
constructor(size: number, signed: boolean, localName: string) {
|
||||
const name = ((signed ? "int": "uint") + (size * 8));
|
||||
super(name, name, localName, false);
|
||||
|
||||
defineProperties<NumberCoder>(this, { size, signed }, { size: "number", signed: "boolean" });
|
||||
}
|
||||
|
||||
defaultValue(): number {
|
||||
return 0;
|
||||
}
|
||||
|
||||
encode(writer: Writer, _value: BigNumberish | Typed): number {
|
||||
let value = getBigInt(Typed.dereference(_value, this.type));
|
||||
|
||||
// Check bounds are safe for encoding
|
||||
let maxUintValue = mask(BN_MAX_UINT256, WordSize * 8);
|
||||
if (this.signed) {
|
||||
let bounds = mask(maxUintValue, (this.size * 8) - 1);
|
||||
if (value > bounds || value < -(bounds + BN_1)) {
|
||||
this._throwError("value out-of-bounds", _value);
|
||||
}
|
||||
value = toTwos(value, 8 * WordSize);
|
||||
} else if (value < BN_0 || value > mask(maxUintValue, this.size * 8)) {
|
||||
this._throwError("value out-of-bounds", _value);
|
||||
}
|
||||
|
||||
return writer.writeValue(value);
|
||||
}
|
||||
|
||||
decode(reader: Reader): any {
|
||||
let value = mask(reader.readValue(), this.size * 8);
|
||||
|
||||
if (this.signed) {
|
||||
value = fromTwos(value, this.size * 8);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
29
dev/env/node_modules/ethers/src.ts/abi/coders/string.ts
generated
vendored
Executable file
29
dev/env/node_modules/ethers/src.ts/abi/coders/string.ts
generated
vendored
Executable file
@@ -0,0 +1,29 @@
|
||||
import { toUtf8Bytes, toUtf8String } from "../../utils/utf8.js";
|
||||
|
||||
import { Typed } from "../typed.js";
|
||||
import { DynamicBytesCoder } from "./bytes.js";
|
||||
|
||||
import type { Reader, Writer } from "./abstract-coder.js";
|
||||
|
||||
|
||||
/**
|
||||
* @_ignore
|
||||
*/
|
||||
export class StringCoder extends DynamicBytesCoder {
|
||||
|
||||
constructor(localName: string) {
|
||||
super("string", localName);
|
||||
}
|
||||
|
||||
defaultValue(): string {
|
||||
return "";
|
||||
}
|
||||
|
||||
encode(writer: Writer, _value: string | Typed): number {
|
||||
return super.encode(writer, toUtf8Bytes(Typed.dereference(_value, "string")));
|
||||
}
|
||||
|
||||
decode(reader: Reader): any {
|
||||
return toUtf8String(super.decode(reader));
|
||||
}
|
||||
}
|
||||
69
dev/env/node_modules/ethers/src.ts/abi/coders/tuple.ts
generated
vendored
Executable file
69
dev/env/node_modules/ethers/src.ts/abi/coders/tuple.ts
generated
vendored
Executable file
@@ -0,0 +1,69 @@
|
||||
import { defineProperties } from "../../utils/properties.js";
|
||||
|
||||
import { Typed } from "../typed.js";
|
||||
import { Coder } from "./abstract-coder.js";
|
||||
|
||||
import { pack, unpack } from "./array.js";
|
||||
|
||||
import type { Reader, Writer } from "./abstract-coder.js";
|
||||
|
||||
/**
|
||||
* @_ignore
|
||||
*/
|
||||
export class TupleCoder extends Coder {
|
||||
readonly coders!: ReadonlyArray<Coder>;
|
||||
|
||||
constructor(coders: Array<Coder>, localName: string) {
|
||||
let dynamic = false;
|
||||
const types: Array<string> = [];
|
||||
coders.forEach((coder) => {
|
||||
if (coder.dynamic) { dynamic = true; }
|
||||
types.push(coder.type);
|
||||
});
|
||||
const type = ("tuple(" + types.join(",") + ")");
|
||||
|
||||
super("tuple", type, localName, dynamic);
|
||||
defineProperties<TupleCoder>(this, { coders: Object.freeze(coders.slice()) });
|
||||
}
|
||||
|
||||
defaultValue(): any {
|
||||
const values: any = [ ];
|
||||
this.coders.forEach((coder) => {
|
||||
values.push(coder.defaultValue());
|
||||
});
|
||||
|
||||
// We only output named properties for uniquely named coders
|
||||
const uniqueNames = this.coders.reduce((accum, coder) => {
|
||||
const name = coder.localName;
|
||||
if (name) {
|
||||
if (!accum[name]) { accum[name] = 0; }
|
||||
accum[name]++;
|
||||
}
|
||||
return accum;
|
||||
}, <{ [ name: string ]: number }>{ });
|
||||
|
||||
// Add named values
|
||||
this.coders.forEach((coder: Coder, index: number) => {
|
||||
let name = coder.localName;
|
||||
if (!name || uniqueNames[name] !== 1) { return; }
|
||||
|
||||
if (name === "length") { name = "_length"; }
|
||||
|
||||
if (values[name] != null) { return; }
|
||||
|
||||
values[name] = values[index];
|
||||
});
|
||||
|
||||
return Object.freeze(values);
|
||||
}
|
||||
|
||||
encode(writer: Writer, _value: Array<any> | { [ name: string ]: any } | Typed): number {
|
||||
const value = Typed.dereference(_value, "tuple");
|
||||
return pack(writer, this.coders, value);
|
||||
}
|
||||
|
||||
decode(reader: Reader): any {
|
||||
return unpack(reader, this.coders);
|
||||
}
|
||||
}
|
||||
|
||||
1617
dev/env/node_modules/ethers/src.ts/abi/fragments.ts
generated
vendored
Executable file
1617
dev/env/node_modules/ethers/src.ts/abi/fragments.ts
generated
vendored
Executable file
File diff suppressed because it is too large
Load Diff
41
dev/env/node_modules/ethers/src.ts/abi/index.ts
generated
vendored
Executable file
41
dev/env/node_modules/ethers/src.ts/abi/index.ts
generated
vendored
Executable file
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* The Application Binary Interface (ABI) describes how method input
|
||||
* parameters should be encoded, their results decoded, and how to
|
||||
* decode events and errors.
|
||||
*
|
||||
* See [About ABIs](docs-abi) for more details how they are used.
|
||||
*
|
||||
* @_section api/abi:Application Binary Interface [about-abi]
|
||||
* @_navTitle: ABI
|
||||
*/
|
||||
|
||||
|
||||
//////
|
||||
export { AbiCoder } from "./abi-coder.js";
|
||||
|
||||
export { decodeBytes32String, encodeBytes32String } from "./bytes32.js";
|
||||
|
||||
export {
|
||||
ConstructorFragment, ErrorFragment, EventFragment, FallbackFragment,
|
||||
Fragment, FunctionFragment, NamedFragment, ParamType, StructFragment,
|
||||
} from "./fragments.js";
|
||||
|
||||
export {
|
||||
checkResultErrors,
|
||||
Indexed,
|
||||
Interface,
|
||||
ErrorDescription, LogDescription, TransactionDescription,
|
||||
Result
|
||||
} from "./interface.js";
|
||||
|
||||
export { Typed } from "./typed.js";
|
||||
|
||||
export type {
|
||||
JsonFragment, JsonFragmentType,
|
||||
FormatType, FragmentType, ParamTypeWalkAsyncFunc, ParamTypeWalkFunc
|
||||
} from "./fragments.js";
|
||||
|
||||
export type {
|
||||
InterfaceAbi,
|
||||
} from "./interface.js";
|
||||
|
||||
1271
dev/env/node_modules/ethers/src.ts/abi/interface.ts
generated
vendored
Executable file
1271
dev/env/node_modules/ethers/src.ts/abi/interface.ts
generated
vendored
Executable file
File diff suppressed because it is too large
Load Diff
796
dev/env/node_modules/ethers/src.ts/abi/typed.ts
generated
vendored
Executable file
796
dev/env/node_modules/ethers/src.ts/abi/typed.ts
generated
vendored
Executable file
@@ -0,0 +1,796 @@
|
||||
/**
|
||||
* A Typed object allows a value to have its type explicitly
|
||||
* specified.
|
||||
*
|
||||
* For example, in Solidity, the value ``45`` could represent a
|
||||
* ``uint8`` or a ``uint256``. The value ``0x1234`` could represent
|
||||
* a ``bytes2`` or ``bytes``.
|
||||
*
|
||||
* Since JavaScript has no meaningful way to explicitly inform any
|
||||
* APIs which what the type is, this allows transparent interoperation
|
||||
* with Soldity.
|
||||
*
|
||||
* @_subsection: api/abi:Typed Values
|
||||
*/
|
||||
|
||||
import { assertPrivate, defineProperties } from "../utils/index.js";
|
||||
|
||||
import type { Addressable } from "../address/index.js";
|
||||
import type { BigNumberish, BytesLike } from "../utils/index.js";
|
||||
|
||||
import type { Result } from "./coders/abstract-coder.js";
|
||||
|
||||
const _gaurd = { };
|
||||
|
||||
function n(value: BigNumberish, width: number): Typed {
|
||||
let signed = false;
|
||||
if (width < 0) {
|
||||
signed = true;
|
||||
width *= -1;
|
||||
}
|
||||
|
||||
// @TODO: Check range is valid for value
|
||||
return new Typed(_gaurd, `${ signed ? "": "u" }int${ width }`, value, { signed, width });
|
||||
}
|
||||
|
||||
function b(value: BytesLike, size?: number): Typed {
|
||||
// @TODO: Check range is valid for value
|
||||
return new Typed(_gaurd, `bytes${ (size) ? size: "" }`, value, { size });
|
||||
}
|
||||
|
||||
// @TODO: Remove this in v7, it was replaced by TypedBigInt
|
||||
/**
|
||||
* @_ignore:
|
||||
*/
|
||||
export interface TypedNumber extends Typed {
|
||||
value: number;
|
||||
defaultValue(): number;
|
||||
minValue(): number;
|
||||
maxValue(): number;
|
||||
}
|
||||
|
||||
/**
|
||||
* A **Typed** that represents a numeric value.
|
||||
*/
|
||||
export interface TypedBigInt extends Typed {
|
||||
/**
|
||||
* The value.
|
||||
*/
|
||||
value: bigint;
|
||||
|
||||
/**
|
||||
* The default value for all numeric types is ``0``.
|
||||
*/
|
||||
defaultValue(): bigint;
|
||||
|
||||
/**
|
||||
* The minimum value for this type, accounting for bit-width and signed-ness.
|
||||
*/
|
||||
minValue(): bigint;
|
||||
|
||||
/**
|
||||
* The minimum value for this type, accounting for bit-width.
|
||||
*/
|
||||
maxValue(): bigint;
|
||||
}
|
||||
|
||||
/**
|
||||
* A **Typed** that represents a binary sequence of data as bytes.
|
||||
*/
|
||||
export interface TypedData extends Typed {
|
||||
/**
|
||||
* The value.
|
||||
*/
|
||||
value: string;
|
||||
|
||||
/**
|
||||
* The default value for this type.
|
||||
*/
|
||||
defaultValue(): string;
|
||||
}
|
||||
|
||||
/**
|
||||
* A **Typed** that represents a UTF-8 sequence of bytes.
|
||||
*/
|
||||
export interface TypedString extends Typed {
|
||||
/**
|
||||
* The value.
|
||||
*/
|
||||
value: string;
|
||||
|
||||
/**
|
||||
* The default value for the string type is the empty string (i.e. ``""``).
|
||||
*/
|
||||
defaultValue(): string;
|
||||
}
|
||||
|
||||
const _typedSymbol = Symbol.for("_ethers_typed");
|
||||
|
||||
/**
|
||||
* The **Typed** class to wrap values providing explicit type information.
|
||||
*/
|
||||
export class Typed {
|
||||
|
||||
/**
|
||||
* The type, as a Solidity-compatible type.
|
||||
*/
|
||||
readonly type!: string;
|
||||
|
||||
/**
|
||||
* The actual value.
|
||||
*/
|
||||
readonly value!: any;
|
||||
|
||||
readonly #options: any;
|
||||
|
||||
/**
|
||||
* @_ignore:
|
||||
*/
|
||||
readonly _typedSymbol!: Symbol;
|
||||
|
||||
/**
|
||||
* @_ignore:
|
||||
*/
|
||||
constructor(gaurd: any, type: string, value: any, options?: any) {
|
||||
if (options == null) { options = null; }
|
||||
assertPrivate(_gaurd, gaurd, "Typed");
|
||||
defineProperties<Typed>(this, { _typedSymbol, type, value });
|
||||
this.#options = options;
|
||||
|
||||
// Check the value is valid
|
||||
this.format();
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the type as a Human-Readable type.
|
||||
*/
|
||||
format(): string {
|
||||
if (this.type === "array") {
|
||||
throw new Error("");
|
||||
} else if (this.type === "dynamicArray") {
|
||||
throw new Error("");
|
||||
} else if (this.type === "tuple") {
|
||||
return `tuple(${ this.value.map((v: Typed) => v.format()).join(",") })`
|
||||
}
|
||||
|
||||
return this.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* The default value returned by this type.
|
||||
*/
|
||||
defaultValue(): string | number | bigint | Result {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* The minimum value for numeric types.
|
||||
*/
|
||||
minValue(): string | number | bigint {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum value for numeric types.
|
||||
*/
|
||||
maxValue(): string | number | bigint {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns ``true`` and provides a type guard is this is a [[TypedBigInt]].
|
||||
*/
|
||||
isBigInt(): this is TypedBigInt {
|
||||
return !!(this.type.match(/^u?int[0-9]+$/));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns ``true`` and provides a type guard is this is a [[TypedData]].
|
||||
*/
|
||||
isData(): this is TypedData {
|
||||
return this.type.startsWith("bytes");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns ``true`` and provides a type guard is this is a [[TypedString]].
|
||||
*/
|
||||
isString(): this is TypedString {
|
||||
return (this.type === "string");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the tuple name, if this is a tuple. Throws otherwise.
|
||||
*/
|
||||
get tupleName(): null | string {
|
||||
if (this.type !== "tuple") { throw TypeError("not a tuple"); }
|
||||
return this.#options;
|
||||
}
|
||||
|
||||
// Returns the length of this type as an array
|
||||
// - `null` indicates the length is unforced, it could be dynamic
|
||||
// - `-1` indicates the length is dynamic
|
||||
// - any other value indicates it is a static array and is its length
|
||||
|
||||
/**
|
||||
* Returns the length of the array type or ``-1`` if it is dynamic.
|
||||
*
|
||||
* Throws if the type is not an array.
|
||||
*/
|
||||
get arrayLength(): null | number {
|
||||
if (this.type !== "array") { throw TypeError("not an array"); }
|
||||
if (this.#options === true) { return -1; }
|
||||
if (this.#options === false) { return (<Array<any>>(this.value)).length; }
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new **Typed** of %%type%% with the %%value%%.
|
||||
*/
|
||||
static from(type: string, value: any): Typed {
|
||||
return new Typed(_gaurd, type, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new ``uint8`` type for %%v%%.
|
||||
*/
|
||||
static uint8(v: BigNumberish): Typed { return n(v, 8); }
|
||||
|
||||
/**
|
||||
* Return a new ``uint16`` type for %%v%%.
|
||||
*/
|
||||
static uint16(v: BigNumberish): Typed { return n(v, 16); }
|
||||
|
||||
/**
|
||||
* Return a new ``uint24`` type for %%v%%.
|
||||
*/
|
||||
static uint24(v: BigNumberish): Typed { return n(v, 24); }
|
||||
|
||||
/**
|
||||
* Return a new ``uint32`` type for %%v%%.
|
||||
*/
|
||||
static uint32(v: BigNumberish): Typed { return n(v, 32); }
|
||||
|
||||
/**
|
||||
* Return a new ``uint40`` type for %%v%%.
|
||||
*/
|
||||
static uint40(v: BigNumberish): Typed { return n(v, 40); }
|
||||
|
||||
/**
|
||||
* Return a new ``uint48`` type for %%v%%.
|
||||
*/
|
||||
static uint48(v: BigNumberish): Typed { return n(v, 48); }
|
||||
|
||||
/**
|
||||
* Return a new ``uint56`` type for %%v%%.
|
||||
*/
|
||||
static uint56(v: BigNumberish): Typed { return n(v, 56); }
|
||||
|
||||
/**
|
||||
* Return a new ``uint64`` type for %%v%%.
|
||||
*/
|
||||
static uint64(v: BigNumberish): Typed { return n(v, 64); }
|
||||
|
||||
/**
|
||||
* Return a new ``uint72`` type for %%v%%.
|
||||
*/
|
||||
static uint72(v: BigNumberish): Typed { return n(v, 72); }
|
||||
|
||||
/**
|
||||
* Return a new ``uint80`` type for %%v%%.
|
||||
*/
|
||||
static uint80(v: BigNumberish): Typed { return n(v, 80); }
|
||||
|
||||
/**
|
||||
* Return a new ``uint88`` type for %%v%%.
|
||||
*/
|
||||
static uint88(v: BigNumberish): Typed { return n(v, 88); }
|
||||
|
||||
/**
|
||||
* Return a new ``uint96`` type for %%v%%.
|
||||
*/
|
||||
static uint96(v: BigNumberish): Typed { return n(v, 96); }
|
||||
|
||||
/**
|
||||
* Return a new ``uint104`` type for %%v%%.
|
||||
*/
|
||||
static uint104(v: BigNumberish): Typed { return n(v, 104); }
|
||||
|
||||
/**
|
||||
* Return a new ``uint112`` type for %%v%%.
|
||||
*/
|
||||
static uint112(v: BigNumberish): Typed { return n(v, 112); }
|
||||
|
||||
/**
|
||||
* Return a new ``uint120`` type for %%v%%.
|
||||
*/
|
||||
static uint120(v: BigNumberish): Typed { return n(v, 120); }
|
||||
|
||||
/**
|
||||
* Return a new ``uint128`` type for %%v%%.
|
||||
*/
|
||||
static uint128(v: BigNumberish): Typed { return n(v, 128); }
|
||||
|
||||
/**
|
||||
* Return a new ``uint136`` type for %%v%%.
|
||||
*/
|
||||
static uint136(v: BigNumberish): Typed { return n(v, 136); }
|
||||
|
||||
/**
|
||||
* Return a new ``uint144`` type for %%v%%.
|
||||
*/
|
||||
static uint144(v: BigNumberish): Typed { return n(v, 144); }
|
||||
|
||||
/**
|
||||
* Return a new ``uint152`` type for %%v%%.
|
||||
*/
|
||||
static uint152(v: BigNumberish): Typed { return n(v, 152); }
|
||||
|
||||
/**
|
||||
* Return a new ``uint160`` type for %%v%%.
|
||||
*/
|
||||
static uint160(v: BigNumberish): Typed { return n(v, 160); }
|
||||
|
||||
/**
|
||||
* Return a new ``uint168`` type for %%v%%.
|
||||
*/
|
||||
static uint168(v: BigNumberish): Typed { return n(v, 168); }
|
||||
|
||||
/**
|
||||
* Return a new ``uint176`` type for %%v%%.
|
||||
*/
|
||||
static uint176(v: BigNumberish): Typed { return n(v, 176); }
|
||||
|
||||
/**
|
||||
* Return a new ``uint184`` type for %%v%%.
|
||||
*/
|
||||
static uint184(v: BigNumberish): Typed { return n(v, 184); }
|
||||
|
||||
/**
|
||||
* Return a new ``uint192`` type for %%v%%.
|
||||
*/
|
||||
static uint192(v: BigNumberish): Typed { return n(v, 192); }
|
||||
|
||||
/**
|
||||
* Return a new ``uint200`` type for %%v%%.
|
||||
*/
|
||||
static uint200(v: BigNumberish): Typed { return n(v, 200); }
|
||||
|
||||
/**
|
||||
* Return a new ``uint208`` type for %%v%%.
|
||||
*/
|
||||
static uint208(v: BigNumberish): Typed { return n(v, 208); }
|
||||
|
||||
/**
|
||||
* Return a new ``uint216`` type for %%v%%.
|
||||
*/
|
||||
static uint216(v: BigNumberish): Typed { return n(v, 216); }
|
||||
|
||||
/**
|
||||
* Return a new ``uint224`` type for %%v%%.
|
||||
*/
|
||||
static uint224(v: BigNumberish): Typed { return n(v, 224); }
|
||||
|
||||
/**
|
||||
* Return a new ``uint232`` type for %%v%%.
|
||||
*/
|
||||
static uint232(v: BigNumberish): Typed { return n(v, 232); }
|
||||
|
||||
/**
|
||||
* Return a new ``uint240`` type for %%v%%.
|
||||
*/
|
||||
static uint240(v: BigNumberish): Typed { return n(v, 240); }
|
||||
|
||||
/**
|
||||
* Return a new ``uint248`` type for %%v%%.
|
||||
*/
|
||||
static uint248(v: BigNumberish): Typed { return n(v, 248); }
|
||||
|
||||
/**
|
||||
* Return a new ``uint256`` type for %%v%%.
|
||||
*/
|
||||
static uint256(v: BigNumberish): Typed { return n(v, 256); }
|
||||
|
||||
/**
|
||||
* Return a new ``uint256`` type for %%v%%.
|
||||
*/
|
||||
static uint(v: BigNumberish): Typed { return n(v, 256); }
|
||||
|
||||
/**
|
||||
* Return a new ``int8`` type for %%v%%.
|
||||
*/
|
||||
static int8(v: BigNumberish): Typed { return n(v, -8); }
|
||||
|
||||
/**
|
||||
* Return a new ``int16`` type for %%v%%.
|
||||
*/
|
||||
static int16(v: BigNumberish): Typed { return n(v, -16); }
|
||||
|
||||
/**
|
||||
* Return a new ``int24`` type for %%v%%.
|
||||
*/
|
||||
static int24(v: BigNumberish): Typed { return n(v, -24); }
|
||||
|
||||
/**
|
||||
* Return a new ``int32`` type for %%v%%.
|
||||
*/
|
||||
static int32(v: BigNumberish): Typed { return n(v, -32); }
|
||||
|
||||
/**
|
||||
* Return a new ``int40`` type for %%v%%.
|
||||
*/
|
||||
static int40(v: BigNumberish): Typed { return n(v, -40); }
|
||||
|
||||
/**
|
||||
* Return a new ``int48`` type for %%v%%.
|
||||
*/
|
||||
static int48(v: BigNumberish): Typed { return n(v, -48); }
|
||||
|
||||
/**
|
||||
* Return a new ``int56`` type for %%v%%.
|
||||
*/
|
||||
static int56(v: BigNumberish): Typed { return n(v, -56); }
|
||||
|
||||
/**
|
||||
* Return a new ``int64`` type for %%v%%.
|
||||
*/
|
||||
static int64(v: BigNumberish): Typed { return n(v, -64); }
|
||||
|
||||
/**
|
||||
* Return a new ``int72`` type for %%v%%.
|
||||
*/
|
||||
static int72(v: BigNumberish): Typed { return n(v, -72); }
|
||||
|
||||
/**
|
||||
* Return a new ``int80`` type for %%v%%.
|
||||
*/
|
||||
static int80(v: BigNumberish): Typed { return n(v, -80); }
|
||||
|
||||
/**
|
||||
* Return a new ``int88`` type for %%v%%.
|
||||
*/
|
||||
static int88(v: BigNumberish): Typed { return n(v, -88); }
|
||||
|
||||
/**
|
||||
* Return a new ``int96`` type for %%v%%.
|
||||
*/
|
||||
static int96(v: BigNumberish): Typed { return n(v, -96); }
|
||||
|
||||
/**
|
||||
* Return a new ``int104`` type for %%v%%.
|
||||
*/
|
||||
static int104(v: BigNumberish): Typed { return n(v, -104); }
|
||||
|
||||
/**
|
||||
* Return a new ``int112`` type for %%v%%.
|
||||
*/
|
||||
static int112(v: BigNumberish): Typed { return n(v, -112); }
|
||||
|
||||
/**
|
||||
* Return a new ``int120`` type for %%v%%.
|
||||
*/
|
||||
static int120(v: BigNumberish): Typed { return n(v, -120); }
|
||||
|
||||
/**
|
||||
* Return a new ``int128`` type for %%v%%.
|
||||
*/
|
||||
static int128(v: BigNumberish): Typed { return n(v, -128); }
|
||||
|
||||
/**
|
||||
* Return a new ``int136`` type for %%v%%.
|
||||
*/
|
||||
static int136(v: BigNumberish): Typed { return n(v, -136); }
|
||||
|
||||
/**
|
||||
* Return a new ``int144`` type for %%v%%.
|
||||
*/
|
||||
static int144(v: BigNumberish): Typed { return n(v, -144); }
|
||||
|
||||
/**
|
||||
* Return a new ``int52`` type for %%v%%.
|
||||
*/
|
||||
static int152(v: BigNumberish): Typed { return n(v, -152); }
|
||||
|
||||
/**
|
||||
* Return a new ``int160`` type for %%v%%.
|
||||
*/
|
||||
static int160(v: BigNumberish): Typed { return n(v, -160); }
|
||||
|
||||
/**
|
||||
* Return a new ``int168`` type for %%v%%.
|
||||
*/
|
||||
static int168(v: BigNumberish): Typed { return n(v, -168); }
|
||||
|
||||
/**
|
||||
* Return a new ``int176`` type for %%v%%.
|
||||
*/
|
||||
static int176(v: BigNumberish): Typed { return n(v, -176); }
|
||||
|
||||
/**
|
||||
* Return a new ``int184`` type for %%v%%.
|
||||
*/
|
||||
static int184(v: BigNumberish): Typed { return n(v, -184); }
|
||||
|
||||
/**
|
||||
* Return a new ``int92`` type for %%v%%.
|
||||
*/
|
||||
static int192(v: BigNumberish): Typed { return n(v, -192); }
|
||||
|
||||
/**
|
||||
* Return a new ``int200`` type for %%v%%.
|
||||
*/
|
||||
static int200(v: BigNumberish): Typed { return n(v, -200); }
|
||||
|
||||
/**
|
||||
* Return a new ``int208`` type for %%v%%.
|
||||
*/
|
||||
static int208(v: BigNumberish): Typed { return n(v, -208); }
|
||||
|
||||
/**
|
||||
* Return a new ``int216`` type for %%v%%.
|
||||
*/
|
||||
static int216(v: BigNumberish): Typed { return n(v, -216); }
|
||||
|
||||
/**
|
||||
* Return a new ``int224`` type for %%v%%.
|
||||
*/
|
||||
static int224(v: BigNumberish): Typed { return n(v, -224); }
|
||||
|
||||
/**
|
||||
* Return a new ``int232`` type for %%v%%.
|
||||
*/
|
||||
static int232(v: BigNumberish): Typed { return n(v, -232); }
|
||||
|
||||
/**
|
||||
* Return a new ``int240`` type for %%v%%.
|
||||
*/
|
||||
static int240(v: BigNumberish): Typed { return n(v, -240); }
|
||||
|
||||
/**
|
||||
* Return a new ``int248`` type for %%v%%.
|
||||
*/
|
||||
static int248(v: BigNumberish): Typed { return n(v, -248); }
|
||||
|
||||
/**
|
||||
* Return a new ``int256`` type for %%v%%.
|
||||
*/
|
||||
static int256(v: BigNumberish): Typed { return n(v, -256); }
|
||||
|
||||
/**
|
||||
* Return a new ``int256`` type for %%v%%.
|
||||
*/
|
||||
static int(v: BigNumberish): Typed { return n(v, -256); }
|
||||
|
||||
/**
|
||||
* Return a new ``bytes1`` type for %%v%%.
|
||||
*/
|
||||
static bytes1(v: BytesLike): Typed { return b(v, 1); }
|
||||
|
||||
/**
|
||||
* Return a new ``bytes2`` type for %%v%%.
|
||||
*/
|
||||
static bytes2(v: BytesLike): Typed { return b(v, 2); }
|
||||
|
||||
/**
|
||||
* Return a new ``bytes3`` type for %%v%%.
|
||||
*/
|
||||
static bytes3(v: BytesLike): Typed { return b(v, 3); }
|
||||
|
||||
/**
|
||||
* Return a new ``bytes4`` type for %%v%%.
|
||||
*/
|
||||
static bytes4(v: BytesLike): Typed { return b(v, 4); }
|
||||
|
||||
/**
|
||||
* Return a new ``bytes5`` type for %%v%%.
|
||||
*/
|
||||
static bytes5(v: BytesLike): Typed { return b(v, 5); }
|
||||
|
||||
/**
|
||||
* Return a new ``bytes6`` type for %%v%%.
|
||||
*/
|
||||
static bytes6(v: BytesLike): Typed { return b(v, 6); }
|
||||
|
||||
/**
|
||||
* Return a new ``bytes7`` type for %%v%%.
|
||||
*/
|
||||
static bytes7(v: BytesLike): Typed { return b(v, 7); }
|
||||
|
||||
/**
|
||||
* Return a new ``bytes8`` type for %%v%%.
|
||||
*/
|
||||
static bytes8(v: BytesLike): Typed { return b(v, 8); }
|
||||
|
||||
/**
|
||||
* Return a new ``bytes9`` type for %%v%%.
|
||||
*/
|
||||
static bytes9(v: BytesLike): Typed { return b(v, 9); }
|
||||
|
||||
/**
|
||||
* Return a new ``bytes10`` type for %%v%%.
|
||||
*/
|
||||
static bytes10(v: BytesLike): Typed { return b(v, 10); }
|
||||
|
||||
/**
|
||||
* Return a new ``bytes11`` type for %%v%%.
|
||||
*/
|
||||
static bytes11(v: BytesLike): Typed { return b(v, 11); }
|
||||
|
||||
/**
|
||||
* Return a new ``bytes12`` type for %%v%%.
|
||||
*/
|
||||
static bytes12(v: BytesLike): Typed { return b(v, 12); }
|
||||
|
||||
/**
|
||||
* Return a new ``bytes13`` type for %%v%%.
|
||||
*/
|
||||
static bytes13(v: BytesLike): Typed { return b(v, 13); }
|
||||
|
||||
/**
|
||||
* Return a new ``bytes14`` type for %%v%%.
|
||||
*/
|
||||
static bytes14(v: BytesLike): Typed { return b(v, 14); }
|
||||
|
||||
/**
|
||||
* Return a new ``bytes15`` type for %%v%%.
|
||||
*/
|
||||
static bytes15(v: BytesLike): Typed { return b(v, 15); }
|
||||
|
||||
/**
|
||||
* Return a new ``bytes16`` type for %%v%%.
|
||||
*/
|
||||
static bytes16(v: BytesLike): Typed { return b(v, 16); }
|
||||
|
||||
/**
|
||||
* Return a new ``bytes17`` type for %%v%%.
|
||||
*/
|
||||
static bytes17(v: BytesLike): Typed { return b(v, 17); }
|
||||
|
||||
/**
|
||||
* Return a new ``bytes18`` type for %%v%%.
|
||||
*/
|
||||
static bytes18(v: BytesLike): Typed { return b(v, 18); }
|
||||
|
||||
/**
|
||||
* Return a new ``bytes19`` type for %%v%%.
|
||||
*/
|
||||
static bytes19(v: BytesLike): Typed { return b(v, 19); }
|
||||
|
||||
/**
|
||||
* Return a new ``bytes20`` type for %%v%%.
|
||||
*/
|
||||
static bytes20(v: BytesLike): Typed { return b(v, 20); }
|
||||
|
||||
/**
|
||||
* Return a new ``bytes21`` type for %%v%%.
|
||||
*/
|
||||
static bytes21(v: BytesLike): Typed { return b(v, 21); }
|
||||
|
||||
/**
|
||||
* Return a new ``bytes22`` type for %%v%%.
|
||||
*/
|
||||
static bytes22(v: BytesLike): Typed { return b(v, 22); }
|
||||
|
||||
/**
|
||||
* Return a new ``bytes23`` type for %%v%%.
|
||||
*/
|
||||
static bytes23(v: BytesLike): Typed { return b(v, 23); }
|
||||
|
||||
/**
|
||||
* Return a new ``bytes24`` type for %%v%%.
|
||||
*/
|
||||
static bytes24(v: BytesLike): Typed { return b(v, 24); }
|
||||
|
||||
/**
|
||||
* Return a new ``bytes25`` type for %%v%%.
|
||||
*/
|
||||
static bytes25(v: BytesLike): Typed { return b(v, 25); }
|
||||
|
||||
/**
|
||||
* Return a new ``bytes26`` type for %%v%%.
|
||||
*/
|
||||
static bytes26(v: BytesLike): Typed { return b(v, 26); }
|
||||
|
||||
/**
|
||||
* Return a new ``bytes27`` type for %%v%%.
|
||||
*/
|
||||
static bytes27(v: BytesLike): Typed { return b(v, 27); }
|
||||
|
||||
/**
|
||||
* Return a new ``bytes28`` type for %%v%%.
|
||||
*/
|
||||
static bytes28(v: BytesLike): Typed { return b(v, 28); }
|
||||
|
||||
/**
|
||||
* Return a new ``bytes29`` type for %%v%%.
|
||||
*/
|
||||
static bytes29(v: BytesLike): Typed { return b(v, 29); }
|
||||
|
||||
/**
|
||||
* Return a new ``bytes30`` type for %%v%%.
|
||||
*/
|
||||
static bytes30(v: BytesLike): Typed { return b(v, 30); }
|
||||
|
||||
/**
|
||||
* Return a new ``bytes31`` type for %%v%%.
|
||||
*/
|
||||
static bytes31(v: BytesLike): Typed { return b(v, 31); }
|
||||
|
||||
/**
|
||||
* Return a new ``bytes32`` type for %%v%%.
|
||||
*/
|
||||
static bytes32(v: BytesLike): Typed { return b(v, 32); }
|
||||
|
||||
|
||||
/**
|
||||
* Return a new ``address`` type for %%v%%.
|
||||
*/
|
||||
static address(v: string | Addressable): Typed { return new Typed(_gaurd, "address", v); }
|
||||
|
||||
/**
|
||||
* Return a new ``bool`` type for %%v%%.
|
||||
*/
|
||||
static bool(v: any): Typed { return new Typed(_gaurd, "bool", !!v); }
|
||||
|
||||
/**
|
||||
* Return a new ``bytes`` type for %%v%%.
|
||||
*/
|
||||
static bytes(v: BytesLike): Typed { return new Typed(_gaurd, "bytes", v); }
|
||||
|
||||
/**
|
||||
* Return a new ``string`` type for %%v%%.
|
||||
*/
|
||||
static string(v: string): Typed { return new Typed(_gaurd, "string", v); }
|
||||
|
||||
|
||||
/**
|
||||
* Return a new ``array`` type for %%v%%, allowing %%dynamic%% length.
|
||||
*/
|
||||
static array(v: Array<any | Typed>, dynamic?: null | boolean): Typed {
|
||||
throw new Error("not implemented yet");
|
||||
return new Typed(_gaurd, "array", v, dynamic);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a new ``tuple`` type for %%v%%, with the optional %%name%%.
|
||||
*/
|
||||
static tuple(v: Array<any | Typed> | Record<string, any | Typed>, name?: string): Typed {
|
||||
throw new Error("not implemented yet");
|
||||
return new Typed(_gaurd, "tuple", v, name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a new ``uint8`` type for %%v%%.
|
||||
*/
|
||||
static overrides(v: Record<string, any>): Typed {
|
||||
return new Typed(_gaurd, "overrides", Object.assign({ }, v));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true only if %%value%% is a [[Typed]] instance.
|
||||
*/
|
||||
static isTyped(value: any): value is Typed {
|
||||
return (value
|
||||
&& typeof(value) === "object"
|
||||
&& "_typedSymbol" in value
|
||||
&& value._typedSymbol === _typedSymbol);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the value is a [[Typed]] instance, validates the underlying value
|
||||
* and returns it, otherwise returns value directly.
|
||||
*
|
||||
* This is useful for functions that with to accept either a [[Typed]]
|
||||
* object or values.
|
||||
*/
|
||||
static dereference<T>(value: Typed | T, type: string): T {
|
||||
if (Typed.isTyped(value)) {
|
||||
if (value.type !== type) {
|
||||
throw new Error(`invalid type: expecetd ${ type }, got ${ value.type }`);
|
||||
}
|
||||
return value.value;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user