docs: added jsdocs

This commit is contained in:
Richard Moore 2022-12-30 11:28:26 -05:00
parent d190e654f8
commit 46ddc89441
18 changed files with 311 additions and 27 deletions

@ -10,30 +10,89 @@ import {
} from "../utils/index.js";
import { id } from "../hash/index.js";
/**
* A type description in a JSON API.
*/
export interface JsonFragmentType {
/**
* The parameter name.
*/
readonly name?: string;
/**
* If the parameter is indexed.
*/
readonly indexed?: boolean;
/**
* The type of the parameter.
*/
readonly type?: string;
/**
* The internal Solidity type.
*/
readonly internalType?: string;
/**
* The components for a tuple.
*/
readonly components?: ReadonlyArray<JsonFragmentType>;
}
/**
* A fragment for a method, event or error in a JSON API.
*/
export interface JsonFragment {
/**
* The name of the error, event, function, etc.
*/
readonly name?: string;
/**
* The type of the fragment (e.g. ``event``, ``"function"``, etc.)
*/
readonly type?: string;
/**
* If the event is anonymous.
*/
readonly anonymous?: boolean;
/**
* If the function is payable.
*/
readonly payable?: boolean;
/**
* If the function is constant.
*/
readonly constant?: boolean;
/**
* The mutability state of the function.
*/
readonly stateMutability?: string;
/**
* The input parameters.
*/
readonly inputs?: ReadonlyArray<JsonFragmentType>;
/**
* The output parameters.
*/
readonly outputs?: ReadonlyArray<JsonFragmentType>;
/**
* The gas limit to use when sending a transaction for this function.
*/
readonly gas?: string;
};
/**
* The format to serialize the output as.
*/
export type FormatType =
// Bare formatting, as is needed for computing a sighash of an event or function
"sighash" |
@ -429,8 +488,17 @@ function verifyBasicType(type: string): string {
const _guard = { };
export type FragmentWalkFunc = (type: string, value: any) => any;
export type FragmentWalkAsyncFunc = (type: string, value: any) => any | Promise<any>;
/**
* When [walking](ParamType-walk) a [[ParamType]], this is called
* on each component.
*/
export type ParamTypeWalkFunc = (type: string, value: any) => any;
/**
* When [walking asynchronously](ParamType-walkAsync) a [[ParamType]],
* this is called on each component.
*/
export type ParamTypeWalkAsyncFunc = (type: string, value: any) => any | Promise<any>;
const internal = Symbol.for("_ethers_internal");
@ -441,28 +509,54 @@ const ConstructorFragmentInternal = "_ConstructorInternal";
const FunctionFragmentInternal = "_FunctionInternal";
const StructFragmentInternal = "_StructInternal";
/**
* Each input and output of a [[Fragment]] is an Array of **PAramType**.
*/
export class ParamType {
// The local name of the parameter (of "" if unbound)
/**
* The local name of the parameter (or ``""`` if unbound)
*/
readonly name!: string;
// The fully qualified type (e.g. "address", "tuple(address)", "uint256[3][]"
/**
* The fully qualified type (e.g. ``"address"``, ``"tuple(address)"``,
* ``"uint256[3][]"``)
*/
readonly type!: string;
// The base type (e.g. "address", "tuple", "array")
/**
* The base type (e.g. ``"address"``, ``"tuple"``, ``"array"``)
*/
readonly baseType!: string;
// Indexable Paramters ONLY (otherwise null)
/**
* True if the parameters is indexed.
*
* For non-indexable types (see [[ParamType_isIndexable]]) this
* is ``null``.
*/
readonly indexed!: null | boolean;
// Tuples ONLY: (otherwise null)
// - sub-components
/**
* The components for the tuple.
*
* For non-tuple types (see [[ParamType_isTuple]]) this is ``null``.
*/
readonly components!: null | ReadonlyArray<ParamType>;
// Arrays ONLY: (otherwise null)
// - length of the array (-1 for dynamic length)
// - child type
/**
* The array length, or ``-1`` for dynamic-lengthed arrays.
*
* For non-array types (see [[ParamType_isArray]]) this is ``null``.
*/
readonly arrayLength!: null | number;
/**
* The type of each child in the array.
*
* For non-array types (see [[ParamType_isArray]]) this is ``null``.
*/
readonly arrayChildren!: null | ParamType;
@ -494,10 +588,17 @@ export class ParamType {
});
}
// Format the parameter fragment
// - sighash: "(uint256,address)"
// - minimal: "tuple(uint256,address) indexed"
// - full: "tuple(uint256 foo, address bar) indexed baz"
/**
* Return a string representation of this type.
*
* For example,
*
* ``sighash" => "(uint256,address)"``
*
* ``"minimal" => "tuple(uint256,address) indexed"``
*
* ``"full" => "tuple(uint256 foo, address bar) indexed baz"``
*/
format(format?: FormatType): string {
if (format == null) { format = "sighash"; }
if (format === "json") {
@ -539,23 +640,51 @@ export class ParamType {
return result;
}
static isArray(value: any): value is { arrayChildren: ParamType } {
return value && (value.baseType === "array")
}
/*
* Returns true if %%value%% is an Array type.
*
* This provides a type gaurd ensuring that the
* [[arrayChildren]] and [[arrayLength]] are non-null.
*/
//static isArray(value: any): value is { arrayChildren: ParamType, arrayLength: number } {
// return value && (value.baseType === "array")
//}
isArray(): this is (ParamType & { arrayLength: number, arrayChildren: ParamType }) {
/**
* Returns true if %%this%% is an Array type.
*
* This provides a type gaurd ensuring that [[arrayChildren]]
* and [[arrayLength]] are non-null.
*/
isArray(): this is (ParamType & { arrayChildren: ParamType, arrayLength: number }) {
return (this.baseType === "array")
}
/**
* Returns true if %%this%% is a Tuple type.
*
* This provides a type gaurd ensuring that [[components]]
* is non-null.
*/
isTuple(): this is (ParamType & { components: ReadonlyArray<ParamType> }) {
return (this.baseType === "tuple");
}
/**
* Returns true if %%this%% is an Indexable type.
*
* This provides a type gaurd ensuring that [[indexed]]
* is non-null.
*/
isIndexable(): this is (ParamType & { indexed: boolean }) {
return (this.indexed != null);
}
walk(value: any, process: FragmentWalkFunc): any {
/**
* Walks the **ParamType** with %%value%%, calling %%process%%
* on each type, destructing the %%value%% recursively.
*/
walk(value: any, process: ParamTypeWalkFunc): any {
if (this.isArray()) {
if (!Array.isArray(value)) { throw new Error("invlaid array value"); }
if (this.arrayLength !== -1 && value.length !== this.arrayLength) {
@ -577,7 +706,7 @@ export class ParamType {
return process(this.type, value);
}
#walkAsync(promises: Array<Promise<void>>, value: any, process: FragmentWalkAsyncFunc, setValue: (value: any) => void): void {
#walkAsync(promises: Array<Promise<void>>, value: any, process: ParamTypeWalkAsyncFunc, setValue: (value: any) => void): void {
if (this.isArray()) {
if (!Array.isArray(value)) { throw new Error("invlaid array value"); }
@ -639,7 +768,14 @@ export class ParamType {
}
}
async walkAsync(value: any, process: FragmentWalkAsyncFunc): Promise<any> {
/**
* Walks the **ParamType** with %%value%%, asynchronously calling
* %%process%% on each type, destructing the %%value%% recursively.
*
* This can be used to resolve ENS naes by walking and resolving each
* ``"address"`` type.
*/
async walkAsync(value: any, process: ParamTypeWalkAsyncFunc): Promise<any> {
const promises: Array<Promise<void>> = [ ];
const result: [ any ] = [ value ];
this.#walkAsync(promises, value, process, (value: any) => {
@ -649,6 +785,12 @@ export class ParamType {
return result[0];
}
/**
* Creates a new **ParamType** for %%obj%%.
*
* If %%allowIndexed%% then the ``indexed`` keyword is permitted,
* otherwise the ``indexed`` keyword will throw an error.
*/
static from(obj: any, allowIndexed?: boolean): ParamType {
if (ParamType.isParamType(obj)) { return obj; }
@ -732,15 +874,31 @@ export class ParamType {
return new ParamType(_guard, name, type, type, indexed, null, null, null);
}
/**
* Returns true if %%value%% is a **ParamType**.
*/
static isParamType(value: any): value is ParamType {
return (value && value[internal] === ParamTypeInternal);
}
}
/**
* The type of a [[Fragment]].
*/
export type FragmentType = "constructor" | "error" | "event" | "function" | "struct";
/**
* An abstract class to represent An individual fragment from a parse ABI.
*/
export abstract class Fragment {
/**
* The type of the fragment.
*/
readonly type!: FragmentType;
/**
* The inputs for the fragment.
*/
readonly inputs!: ReadonlyArray<ParamType>;
/**
@ -752,8 +910,15 @@ export abstract class Fragment {
defineProperties<Fragment>(this, { type, inputs });
}
/**
* Returns a string representation of this fragment.
*/
abstract format(format?: FormatType): string;
/**
* Creates a new **Fragment** for %%obj%%, wich can be any supported
* ABI frgament type.
*/
static from(obj: any): Fragment {
if (typeof(obj) === "string") {
try {
@ -791,28 +956,50 @@ export abstract class Fragment {
throw new Error(`unsupported type: ${ obj }`);
}
/**
* Returns true if %%value%% is a [[ConstructorFragment]].
*/
static isConstructor(value: any): value is ConstructorFragment {
return ConstructorFragment.isFragment(value);
}
/**
* Returns true if %%value%% is an [[ErrorFragment]].
*/
static isError(value: any): value is ErrorFragment {
return ErrorFragment.isFragment(value);
}
/**
* Returns true if %%value%% is an [[EventFragment]].
*/
static isEvent(value: any): value is EventFragment {
return EventFragment.isFragment(value);
}
/**
* Returns true if %%value%% is a [[FunctionFragment]].
*/
static isFunction(value: any): value is FunctionFragment {
return FunctionFragment.isFragment(value);
}
/**
* Returns true if %%value%% is a [[StructFragment]].
*/
static isStruct(value: any): value is StructFragment {
return StructFragment.isFragment(value);
}
}
/**
* An abstract class to represent An individual fragment
* which has a name from a parse ABI.
*/
export abstract class NamedFragment extends Fragment {
/**
* The name of the fragment.
*/
readonly name!: string;
/**
@ -831,6 +1018,9 @@ function joinParams(format: FormatType, params: ReadonlyArray<ParamType>): strin
return "(" + params.map((p) => p.format(format)).join((format === "full") ? ", ": ",") + ")";
}
/**
* A Fragment which represents a //Custom Error//.
*/
export class ErrorFragment extends NamedFragment {
/**
* @private
@ -840,6 +1030,9 @@ export class ErrorFragment extends NamedFragment {
Object.defineProperty(this, internal, { value: ErrorFragmentInternal });
}
/**
* The Custom Error selector.
*/
get selector(): string {
return id(this.format("sighash")).substring(0, 10);
}
@ -883,7 +1076,9 @@ export class ErrorFragment extends NamedFragment {
}
}
/**
* A Fragment which represents an Event.
*/
export class EventFragment extends NamedFragment {
readonly anonymous!: boolean;
@ -896,6 +1091,9 @@ export class EventFragment extends NamedFragment {
defineProperties<EventFragment>(this, { anonymous });
}
/**
* The Event topic hash.
*/
get topicHash(): string {
return id(this.format("sighash"));
}
@ -942,7 +1140,9 @@ export class EventFragment extends NamedFragment {
}
}
/**
* A Fragment which represents a constructor.
*/
export class ConstructorFragment extends Fragment {
readonly payable!: boolean;
readonly gas!: null | bigint;
@ -1002,12 +1202,34 @@ export class ConstructorFragment extends Fragment {
}
}
/**
* A Fragment which represents a method.
*/
export class FunctionFragment extends NamedFragment {
/**
* If the function is constant (e.g. ``pure`` or ``view`` functions).
*/
readonly constant!: boolean;
/**
* The returned types for the result of calling this function.
*/
readonly outputs!: ReadonlyArray<ParamType>;
/**
* The state mutability (e.g. ``payable``, ``nonpayable``, ``view``
* or ``pure``)
*/
readonly stateMutability!: string;
/**
* If the function can be send a value during invocation.
*/
readonly payable!: boolean;
/**
* The amount of gas to send when calling this function
*/
readonly gas!: null | bigint;
/**
@ -1022,6 +1244,9 @@ export class FunctionFragment extends NamedFragment {
defineProperties<FunctionFragment>(this, { constant, gas, outputs, payable, stateMutability });
}
/**
* The Function selector.
*/
get selector(): string {
return id(this.format("sighash")).substring(0, 10);
}
@ -1098,6 +1323,9 @@ export class FunctionFragment extends NamedFragment {
}
}
/**
* A Fragment which represents a structure.
*/
export class StructFragment extends NamedFragment {
/**

@ -28,7 +28,7 @@ export { Typed } from "./typed.js";
export type {
JsonFragment, JsonFragmentType,
FormatType, FragmentType, FragmentWalkAsyncFunc, FragmentWalkFunc
FormatType, FragmentType, ParamTypeWalkAsyncFunc, ParamTypeWalkFunc
} from "./fragments.js";
export type {

@ -36,6 +36,10 @@ let __keccak256: (data: Uint8Array) => BytesLike = _keccak256;
* keccak256(new Uint8Array([ 0x13, 0x37 ]))
* //_result:
*
* // Strings are assumed to be DataHexString, otherwise it will
* // throw. To hash UTF-8 data, see the note above.
* keccak256("Hello World")
* //_error:
*/
export function keccak256(_data: BytesLike): string {
const data = getBytes(_data, "data");

@ -127,6 +127,7 @@ export {
export type {
JsonFragment, JsonFragmentType,
InterfaceAbi,
ParamTypeWalkFunc, ParamTypeWalkAsyncFunc
} from "./abi/index.js";
export type { Addressable } from "./address/index.js";

@ -2,7 +2,7 @@
* The Application Programming Interface (API) is the collection of
* functions, classes and types offered by the Ethers library.
*
* @_section: api:API Specification [about-api]
* @_section: api:Application Programming Interface [about-api]
* @_navTitle: API
*/
import * as ethers from "./ethers.js";

@ -1,5 +1,5 @@
/**
* [Base64 encoding](link-base64) using 6-bit words to encode
* [Base64 encoding](link-wiki-base64) using 6-bit words to encode
* arbitrary bytes into a string using 65 printable symbols, the
* upper-case and lower-case alphabet, the digits ``0`` through ``9``,
* ``"+"`` and ``"/"`` with the ``"="`` used for padding.

@ -173,6 +173,12 @@ function zeroPad(data: BytesLike, length: number, left: boolean): string {
/**
* Return the [[DataHexString]] of %%data%% padded on the **left**
* to %%length%% bytes.
*
* If %%data%% already exceeds %%length%%, a [[BufferOverrun]] is
* thrown.
*
* This pads data the same as **values** are in Solidity
* (e.g. ``uint128``).
*/
export function zeroPadValue(data: BytesLike, length: number): string {
return zeroPad(data, length, true);
@ -181,6 +187,12 @@ export function zeroPadValue(data: BytesLike, length: number): string {
/**
* Return the [[DataHexString]] of %%data%% padded on the **right**
* to %%length%% bytes.
*
* If %%data%% already exceeds %%length%%, a [[BufferOverrun]] is
* thrown.
*
* This pads data the same as **bytes** are in Solidity
* (e.g. ``bytes16``).
*/
export function zeroPadBytes(data: BytesLike, length: number): string {
return zeroPad(data, length, false);

@ -1,3 +1,8 @@
/**
* Explain UUID and link to RFC here.
*
* @_subsection: api/utils:UUID [about-uuid]
*/
import { getBytes, hexlify } from "./data.js";
import type { BytesLike } from "./index.js";

@ -17,6 +17,8 @@ export class LangCz extends WordlistOwl {
*
* Using the constructor should be unnecessary, instead use the
* [[wordlist]] singleton method.
*
* @_ignore:
*/
constructor() { super("cz", words, checksum); }

@ -17,6 +17,8 @@ export class LangEn extends WordlistOwl {
*
* This should be unnecessary most of the time as the exported
* [[langEn]] should suffice.
*
* @_ignore:
*/
constructor() { super("en", words, checksum); }

@ -18,6 +18,8 @@ export class LangEs extends WordlistOwlA {
*
* This should be unnecessary most of the time as the exported
* [[langEs]] should suffice.
*
* @_ignore:
*/
constructor() { super("es", words, accents, checksum); }

@ -18,6 +18,8 @@ export class LangFr extends WordlistOwlA {
*
* This should be unnecessary most of the time as the exported
* [[langFr]] should suffice.
*
* @_ignore:
*/
constructor() { super("fr", words, accents, checksum); }

@ -17,6 +17,8 @@ export class LangIt extends WordlistOwl {
*
* This should be unnecessary most of the time as the exported
* [[langIt]] should suffice.
*
* @_ignore:
*/
constructor() { super("it", words, checksum); }

@ -145,6 +145,8 @@ export class LangJa extends Wordlist {
*
* This should be unnecessary most of the time as the exported
* [[langJa]] should suffice.
*
* @_ignore:
*/
constructor() { super("ja"); }

@ -75,6 +75,8 @@ export class LangKo extends Wordlist {
*
* This should be unnecessary most of the time as the exported
* [[langKo]] should suffice.
*
* @_ignore:
*/
constructor() {
super("ko");

@ -17,6 +17,8 @@ export class LangPt extends WordlistOwl {
*
* This should be unnecessary most of the time as the exported
* [[langPt]] should suffice.
*
* @_ignore:
*/
constructor() { super("pt", words, checksum); }

@ -75,6 +75,8 @@ export class LangZh extends Wordlist {
*
* This should be unnecessary most of the time as the exported
* [[langZhCn]] and [[langZhTw]] should suffice.
*
* @_ignore:
*/
constructor(dialect: string) { super("zh_" + dialect); }
@ -97,6 +99,9 @@ export class LangZh extends Wordlist {
/**
* Returns a singleton instance of a ``LangZh`` for %%dialect%%,
* creating it if this is the first time being called.
*
* Use the %%dialect%% ``"cn"`` or ``"tw"`` for simplified or
* traditional, respectively.
*/
static wordlist(dialect: string): LangZh {
if (wordlists[dialect] == null) {

@ -11,6 +11,19 @@ import { LangZh } from "./lang-zh.js";
import type { Wordlist } from "./wordlist.js";
/**
* The available Wordlists by their
* [ISO 639-1 Language Code](link-wiki-iso639).
*
* (**i.e.** [cz](LangCz), [en](LangEn), [es](LangEs), [fr](LangFr),
* [ja](LangJa), [ko](LangKo), [it](LangIt), [pt](LangPt),
* [zh_cn](LangZh), [zh_tw](LangZh))
*
* The dist files (in the ``/dist`` folder) have had all languages
* except English stripped out, which reduces the library size by
* about 80kb. If required, they are available by importing the
* included ``wordlists-extra.min.js`` file.
*/
export const wordlists: Record<string, Wordlist> = {
cz: LangCz.wordlist(),
en: LangEn.wordlist(),