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:
2026-03-30 17:09:06 +02:00
parent bf730dcb4a
commit 816e258d4c
11734 changed files with 2001707 additions and 0 deletions

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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);
}
}