Switched to assert instead of throwArgument.

This commit is contained in:
Richard Moore 2022-11-04 18:08:37 -04:00
parent e5c068c395
commit 3db5864041
32 changed files with 227 additions and 343 deletions

View File

@ -2,7 +2,7 @@
import {
defineProperties, concat, getBytesCopy, getNumber, hexlify,
toArray, toBigInt, toNumber,
assertPrivate, assertArgument, throwError
assert, assertPrivate, assertArgument
} from "../../utils/index.js";
import type { BigNumberish, BytesLike } from "../../utils/index.js";
@ -152,13 +152,8 @@ export function checkResultErrors(result: Result): Array<{ path: Array<string |
function getValue(value: BigNumberish): Uint8Array {
let bytes = toArray(value);
if (bytes.length > WordSize) {
throwError("value out-of-bounds", "BUFFER_OVERRUN", {
buffer: bytes,
length: WordSize,
offset: bytes.length
});
}
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 ]));
@ -284,7 +279,7 @@ export class Reader {
if (this.allowLoose && loose && this.#offset + length <= this.#data.length) {
alignedLength = length;
} else {
throwError("data out-of-bounds", "BUFFER_OVERRUN", {
assert(false, "data out-of-bounds", "BUFFER_OVERRUN", {
buffer: getBytesCopy(this.#data),
length: this.#data.length,
offset: this.#offset + alignedLength

View File

@ -1,5 +1,5 @@
import {
defineProperties, isError, assertArgument, assertArgumentCount, throwError
defineProperties, isError, assert, assertArgument, assertArgumentCount
} from "../../utils/index.js";
import { Typed } from "../typed.js";
@ -21,21 +21,11 @@ export function pack(writer: Writer, coders: ReadonlyArray<Coder>, values: Array
arrayValues = coders.map((coder) => {
const name = coder.localName;
if (!name) {
throwError("cannot encode object for signature with missing names", "INVALID_ARGUMENT", {
argument: "values",
info: { coder },
value: values
});
}
assert(name, "cannot encode object for signature with missing names",
"INVALID_ARGUMENT", { argument: "values", info: { coder }, value: values });
if (unique[name]) {
throwError("cannot encode object for signature with duplicate 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;
@ -161,7 +151,7 @@ export class ArrayCoder extends Coder {
encode(writer: Writer, _value: Array<any> | Typed): number {
const value = Typed.dereference(_value, "array");
if (!Array.isArray(value)) {
if(!Array.isArray(value)) {
this._throwError("expected array value", value);
}
@ -190,13 +180,8 @@ export class ArrayCoder extends Coder {
// 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.
if (count * WordSize > reader.dataLength) {
throwError("insufficient data length", "BUFFER_OVERRUN", {
buffer: reader.bytes,
offset: count * WordSize,
length: reader.dataLength
});
}
assert(count * WordSize <= reader.dataLength, "insufficient data length",
"BUFFER_OVERRUN", { buffer: reader.bytes, offset: count * WordSize, length: reader.dataLength });
}
let coders = [];
for (let i = 0; i < count; i++) { coders.push(new AnonymousCoder(this.coder)); }

View File

@ -1,6 +1,6 @@
import {
defineProperties, getBigInt, getNumber,
assertPrivate, assertArgument, throwError
assert, assertPrivate, assertArgument
} from "../utils/index.js";
import { id } from "../hash/index.js";
@ -930,11 +930,8 @@ export class ConstructorFragment extends Fragment {
}
format(format: FormatType = "sighash"): string {
if (format === "sighash") {
throwError("cannot format a constructor for sighash", "UNSUPPORTED_OPERATION", {
operation: "format(sighash)"
});
}
assert(format !== "sighash", "cannot format a constructor for sighash",
"UNSUPPORTED_OPERATION", { operation: "format(sighash)" });
if (format === "json") {
return JSON.stringify({

View File

@ -3,7 +3,7 @@ import { id } from "../hash/index.js"
import {
concat, dataSlice, getBigInt, getBytes, getBytesCopy,
hexlify, zeroPadValue, isHexString, defineProperties, assertArgument, toHex,
throwError
assert
} from "../utils/index.js";
import { AbiCoder, defaultAbiCoder, getBuiltinCallException } from "./abi-coder.js";
@ -652,7 +652,7 @@ export class Interface {
}
// Call returned data with no error, but the data is junk
return throwError(message, "BAD_DATA", {
assert(false, message, "BAD_DATA", {
value: hexlify(bytes),
info: { method: fragment.name, signature: fragment.format() }
});
@ -747,12 +747,8 @@ export class Interface {
eventFragment = this.getEvent(eventFragment);
}
if (values.length > eventFragment.inputs.length) {
throwError("too many arguments for " + eventFragment.format(), "UNEXPECTED_ARGUMENT", {
count: values.length,
expectedCount: eventFragment.inputs.length
})
}
assert(values.length <= eventFragment.inputs.length, `too many arguments for ${ eventFragment.format() }`,
"UNEXPECTED_ARGUMENT", { count: values.length, expectedCount: eventFragment.inputs.length })
const topics: Array<null | string | Array<string>> = [];
if (!eventFragment.anonymous) { topics.push(eventFragment.topicHash); }

View File

@ -1,4 +1,4 @@
import { assertArgument, throwError } from "../utils/index.js";
import { assert, assertArgument } from "../utils/index.js";
import { getAddress } from "./address.js";
@ -20,9 +20,7 @@ export function isAddress(value: any): boolean {
async function checkAddress(target: any, promise: Promise<null | string>): Promise<string> {
const result = await promise;
if (result == null || result === "0x0000000000000000000000000000000000000000") {
if (typeof(target) === "string") {
return throwError("unconfigured name", "UNCONFIGURED_NAME", { value: target });
}
assert(typeof(target) !== "string", "unconfigured name", "UNCONFIGURED_NAME", { value: target });
assertArgument(false, "invalid AddressLike value; did not resolve to a value address", "target", target);
}
return getAddress(result);
@ -35,11 +33,8 @@ export function resolveAddress(target: AddressLike, resolver?: null | NameResolv
if (typeof(target) === "string") {
if (target.match(/^0x[0-9a-f]{40}$/i)) { return getAddress(target); }
if (resolver == null) {
return throwError("ENS resolution requires a provider", "UNSUPPORTED_OPERATION", {
operation: "resolveName",
});
}
assert(resolver != null, "ENS resolution requires a provider",
"UNSUPPORTED_OPERATION", { operation: "resolveName" });
return checkAddress(target, resolver.resolveName(target));

View File

@ -3,7 +3,7 @@ import { Interface } from "../abi/index.js";
import { getCreateAddress } from "../address/index.js";
import {
concat, defineProperties, getBytes, hexlify,
assertArgument, throwError
assert, assertArgument
} from "../utils/index.js";
import { BaseContract, copyOverrides, resolveArgs } from "./contract.js";
@ -64,11 +64,9 @@ export class ContractFactory<A extends Array<any> = Array<any>, I = BaseContract
async deploy(...args: ContractMethodArgs<A>): Promise<BaseContract & { deploymentTransaction(): ContractTransactionResponse } & Omit<I, keyof BaseContract>> {
const tx = await this.getDeployTransaction(...args);
if (!this.runner || typeof(this.runner.sendTransaction) !== "function") {
return throwError("factory runner does not support sending transactions", "UNSUPPORTED_OPERATION", {
operation: "sendTransaction"
});
}
assert(this.runner && typeof(this.runner.sendTransaction) === "function",
"factory runner does not support sending transactions", "UNSUPPORTED_OPERATION", {
operation: "sendTransaction" });
const sentTx = await this.runner.sendTransaction(tx);
const address = getCreateAddress(sentTx);

View File

@ -5,7 +5,7 @@ import { pbkdf2 } from "@noble/hashes/pbkdf2";
import { sha256 } from "@noble/hashes/sha256";
import { sha512 } from "@noble/hashes/sha512";
import { assertArgument, throwError } from "../utils/index.js";
import { assert, assertArgument } from "../utils/index.js";
declare global {
@ -53,11 +53,8 @@ export function pbkdf2Sync(password: Uint8Array, salt: Uint8Array, iterations: n
}
export function randomBytes(length: number): Uint8Array {
if (crypto == null) {
return throwError("platform does not support secure random numbers", "UNSUPPORTED_OPERATION", {
operation: "randomBytes"
});
}
assert(crypto != null, "platform does not support secure random numbers", "UNSUPPORTED_OPERATION", {
operation: "randomBytes" });
assertArgument(Number.isInteger(length) && length > 0 && length <= 1024, "invalid length", "length", length);

View File

@ -54,6 +54,8 @@ export {
} from "./hash/index.js";
export {
Block, FeeData, Log, TransactionReceipt, TransactionResponse,
AbstractProvider,
FallbackProvider,
@ -80,8 +82,8 @@ export {
decodeBase64, encodeBase64,
concat, dataLength, dataSlice, getBytes, getBytesCopy, hexlify,
isHexString, isBytesLike, stripZerosLeft, zeroPadBytes, zeroPadValue,
assertArgument, assertArgumentCount, assertNormalize, assertPrivate,
makeError, throwError,
assert, assertArgument, assertArgumentCount, assertNormalize, assertPrivate,
makeError,
isCallException, isError,
getIpfsGatewayFunc, FetchRequest, FetchResponse, FetchCancelSignal,
FixedFormat, FixedNumber, formatFixed, parseFixed,

View File

@ -11,7 +11,7 @@ import { Transaction } from "../transaction/index.js";
import {
concat, dataLength, dataSlice, hexlify, isHexString,
getBigInt, getBytes, getNumber,
isCallException, makeError, throwError, assertArgument,
isCallException, makeError, assert, assertArgument,
FetchRequest,
toArray, toQuantity,
defineProperties, EventPayload, resolveProperties,
@ -185,7 +185,6 @@ async function getSubscription(_event: ProviderEvent, provider: AbstractProvider
}
}
if (Array.isArray(event.address)) {
event.address.forEach(addAddress);
} else {
@ -416,18 +415,14 @@ export class AbstractProvider implements Provider {
} catch (error) { }
// 4xx indicates the result is not present; stop
if (resp.statusCode >= 400 && resp.statusCode < 500) {
return throwError(`response not found during CCIP fetch: ${ errorMessage }`, "OFFCHAIN_FAULT", {
reason: "404_MISSING_RESOURCE",
transaction: tx, info: { url, errorMessage }
});
}
assert(resp.statusCode < 400 || resp.statusCode >= 500, `response not found during CCIP fetch: ${ errorMessage }`,
"OFFCHAIN_FAULT", { reason: "404_MISSING_RESOURCE", transaction: tx, info: { url, errorMessage } });
// 5xx indicates server issue; try the next url
errorMessages.push(errorMessage);
}
return throwError(`error encountered during CCIP fetch: ${ errorMessages.map((m) => JSON.stringify(m)).join(", ") }`, "OFFCHAIN_FAULT", {
assert(false, `error encountered during CCIP fetch: ${ errorMessages.map((m) => JSON.stringify(m)).join(", ") }`, "OFFCHAIN_FAULT", {
reason: "500_SERVER_ERROR",
transaction: tx, info: { urls, errorMessages }
});
@ -454,7 +449,7 @@ export class AbstractProvider implements Provider {
}
_detectNetwork(): Promise<Network> {
return throwError("sub-classes must implement this", "UNSUPPORTED_OPERATION", {
assert(false, "sub-classes must implement this", "UNSUPPORTED_OPERATION", {
operation: "_detectNetwork"
});
}
@ -462,7 +457,7 @@ export class AbstractProvider implements Provider {
// Sub-classes should override this and handle PerformActionRequest requests, calling
// the super for any unhandled actions.
async _perform<T = any>(req: PerformActionRequest): Promise<T> {
return throwError(`unsupported method: ${ req.method }`, "UNSUPPORTED_OPERATION", {
assert(false, `unsupported method: ${ req.method }`, "UNSUPPORTED_OPERATION", {
operation: req.method,
info: req
});
@ -645,7 +640,7 @@ export class AbstractProvider implements Provider {
}
} else {
// Otherwise, we do not allow changes to the underlying network
throwError(`network changed: ${ expected.chainId } => ${ actual.chainId } `, "NETWORK_ERROR", {
assert(false, `network changed: ${ expected.chainId } => ${ actual.chainId } `, "NETWORK_ERROR", {
event: "changed"
});
}
@ -695,12 +690,10 @@ export class AbstractProvider implements Provider {
}
async #call(tx: PerformActionTransaction, blockTag: string, attempt: number): Promise<string> {
if (attempt >= MAX_CCIP_REDIRECTS) {
throwError("CCIP read exceeded maximum redirections", "OFFCHAIN_FAULT", {
reason: "TOO_MANY_REDIRECTS",
transaction: Object.assign({ }, tx, { blockTag, enableCcipRead: true })
});
}
assert (attempt < MAX_CCIP_REDIRECTS, "CCIP read exceeded maximum redirections", "OFFCHAIN_FAULT", {
reason: "TOO_MANY_REDIRECTS",
transaction: Object.assign({ }, tx, { blockTag, enableCcipRead: true })
});
// This came in as a PerformActionTransaction, so to/from are safe; we can cast
const transaction = <PerformActionTransaction>copyRequest(tx);
@ -720,15 +713,13 @@ export class AbstractProvider implements Provider {
try {
ccipArgs = parseOffchainLookup(dataSlice(error.data, 4));
} catch (error: any) {
return throwError(error.message, "OFFCHAIN_FAULT", {
reason: "BAD_DATA",
transaction, info: { data }
});
assert(false, error.message, "OFFCHAIN_FAULT", {
reason: "BAD_DATA", transaction, info: { data } });
}
// Check the sender of the OffchainLookup matches the transaction
if (ccipArgs.sender.toLowerCase() !== txSender.toLowerCase()) {
return throwError("CCIP Read sender mismatch", "CALL_EXCEPTION", {
assert(ccipArgs.sender.toLowerCase() === txSender.toLowerCase(),
"CCIP Read sender mismatch", "CALL_EXCEPTION", {
action: "call",
data,
reason: "OffchainLookup",
@ -740,15 +731,10 @@ export class AbstractProvider implements Provider {
args: ccipArgs.errorArgs
}
});
}
const ccipResult = await this.ccipReadFetch(transaction, ccipArgs.calldata, ccipArgs.urls);
if (ccipResult == null) {
return throwError("CCIP Read failed to fetch data", "OFFCHAIN_FAULT", {
reason: "FETCH_FAILED",
transaction, info: { data: error.data, errorArgs: ccipArgs.errorArgs }
});
}
assert(ccipResult != null, "CCIP Read failed to fetch data", "OFFCHAIN_FAULT", {
reason: "FETCH_FAILED", transaction, info: { data: error.data, errorArgs: ccipArgs.errorArgs } });
return this.#call({
to: txSender,
@ -916,7 +902,7 @@ export class AbstractProvider implements Provider {
// ENS
_getProvider(chainId: number): AbstractProvider {
return throwError("provider cannot connect to target network", "UNSUPPORTED_OPERATION", {
assert(false, "provider cannot connect to target network", "UNSUPPORTED_OPERATION", {
operation: "_getProvider()"
});
}
@ -1079,11 +1065,13 @@ export class AbstractProvider implements Provider {
let sub = this.#subs.get(tag);
if (!sub) {
const subscriber = this._getSubscriber(subscription);
const addressableMap = new WeakMap();
const nameMap = new Map();
sub = { subscriber, tag, addressableMap, nameMap, started: false, listeners: [ ] };
this.#subs.set(tag, sub);
}
return sub;
}
@ -1226,7 +1214,7 @@ export class AbstractProvider implements Provider {
if (this.#pausedState != null) {
if (this.#pausedState == !!dropWhilePaused) { return; }
return throwError("cannot change pause type; resume first", "UNSUPPORTED_OPERATION", {
assert(false, "cannot change pause type; resume first", "UNSUPPORTED_OPERATION", {
operation: "pause"
});
}

View File

@ -1,7 +1,7 @@
import { Transaction } from "../transaction/index.js";
import {
defineProperties, getBigInt, resolveProperties,
assertArgument, throwError
assert, assertArgument
} from "../utils/index.js";
import type { TypedDataDomain, TypedDataField } from "../hash/index.js";
@ -25,7 +25,7 @@ export abstract class AbstractSigner<P extends null | Provider = null | Provider
#checkProvider(operation: string): Provider {
if (this.provider) { return this.provider; }
return throwError("missing provider", "UNSUPPORTED_OPERATION", { operation });
assert(false, "missing provider", "UNSUPPORTED_OPERATION", { operation });
}
async getNonce(blockTag?: BlockTag): Promise<number> {
@ -104,11 +104,8 @@ export abstract class AbstractSigner<P extends null | Provider = null | Provider
// We need to get fee data to determine things
const feeData = await provider.getFeeData();
if (feeData.gasPrice == null) {
throwError("network does not support gasPrice", "UNSUPPORTED_OPERATION", {
operation: "getGasPrice"
});
}
assert(feeData.gasPrice != null, "network does not support gasPrice", "UNSUPPORTED_OPERATION", {
operation: "getGasPrice" });
// Populate missing gasPrice
if (pop.gasPrice == null) { pop.gasPrice = feeData.gasPrice; }
@ -151,11 +148,8 @@ export abstract class AbstractSigner<P extends null | Provider = null | Provider
// Network doesn't support EIP-1559...
// ...but they are trying to use EIP-1559 properties
if (hasEip1559) {
throwError("network does not support EIP-1559", "UNSUPPORTED_OPERATION", {
operation: "populateTransaction"
});
}
assert(hasEip1559, "network does not support EIP-1559", "UNSUPPORTED_OPERATION", {
operation: "populateTransaction" });
// Populate missing fee data
if (pop.gasPrice == null) {
@ -168,9 +162,8 @@ export abstract class AbstractSigner<P extends null | Provider = null | Provider
} else {
// getFeeData has failed us.
throwError("failed to get consistent fee data", "UNSUPPORTED_OPERATION", {
operation: "signer.getFeeData"
});
assert(false, "failed to get consistent fee data", "UNSUPPORTED_OPERATION", {
operation: "signer.getFeeData" });
}
} else if (pop.type === 2) {
@ -233,9 +226,7 @@ export class VoidSigner extends AbstractSigner {
}
#throwUnsupported(suffix: string, operation: string): never {
return throwError(`VoidSigner cannot sign ${ suffix }`, "UNSUPPORTED_OPERATION", {
operation
});
assert(false, `VoidSigner cannot sign ${ suffix }`, "UNSUPPORTED_OPERATION", { operation });
}
async signTransaction(tx: TransactionRequest): Promise<string> {

View File

@ -5,7 +5,7 @@ import {
concat, dataSlice, getBytes, hexlify, zeroPadValue,
defineProperties, encodeBase58, getBigInt, toArray,
toNumber, toUtf8Bytes, toUtf8String,
assertArgument, throwError,
assert, assertArgument,
FetchRequest
} from "../utils/index.js";
@ -212,12 +212,11 @@ export class EnsResolver {
try {
let data = await this.provider.call(tx);
if ((getBytes(data).length % 32) === 4) {
return throwError("execution reverted during JSON-RPC call (could not parse reason; invalid data length)", "CALL_EXCEPTION", {
action: "call", data, reason: null, transaction: <any>tx,
invocation: null, revert: null
});
}
assert((getBytes(data).length % 32) !== 4, "execution reverted during JSON-RPC call (could not parse reason; invalid data length)", "CALL_EXCEPTION", {
action: "call", data, reason: null, transaction: <any>tx,
invocation: null, revert: null
});
if (wrapped) { return parseBytes(data, 0); }
return data;
} catch (error: any) {
@ -265,7 +264,7 @@ export class EnsResolver {
if (address != null) { return address; }
return throwError(`invalid coin data`, "UNSUPPORTED_OPERATION", {
assert(false, `invalid coin data`, "UNSUPPORTED_OPERATION", {
operation: `getAddress(${ coinType })`,
info: { coinType, data }
});
@ -308,7 +307,7 @@ export class EnsResolver {
return `bzz:/\/${ swarm[1] }`;
}
return throwError(`invalid or unsupported content hash data`, "UNSUPPORTED_OPERATION", {
assert(false, `invalid or unsupported content hash data`, "UNSUPPORTED_OPERATION", {
operation: "getContentHash()",
info: { data: hexBytes }
});
@ -485,11 +484,8 @@ export class EnsResolver {
const ensPlugin = network.getPlugin<EnsPlugin>("org.ethers.network-plugins.ens");
// No ENS...
if (!ensPlugin) {
return throwError("network does not support ENS", "UNSUPPORTED_OPERATION", {
operation: "getResolver", info: { network: network.name }
});
}
assert(ensPlugin, "network does not support ENS", "UNSUPPORTED_OPERATION", {
operation: "getResolver", info: { network: network.name } });
try {
// keccak256("resolver(bytes32)")

View File

@ -4,7 +4,7 @@ import { Signature } from "../crypto/index.js"
import { accessListify } from "../transaction/index.js";
import {
getBigInt, getNumber, hexlify, isHexString, zeroPadValue,
assertArgument, throwError
assert, assertArgument
} from "../utils/index.js";
@ -49,7 +49,7 @@ export function object(format: Record<string, FormatFunc>, altNames?: Record<str
if (nv !== undefined) { result[key] = nv; }
} catch (error) {
const message = (error instanceof Error) ? error.message: "not-an-error";
throwError(`invalid value for value.${ key } (${ message })`, "BAD_DATA", { value })
assert(false, `invalid value for value.${ key } (${ message })`, "BAD_DATA", { value })
}
}
return result;

View File

@ -1,6 +1,6 @@
import {
defineProperties, resolveProperties, assertArgument, throwError,
defineProperties, resolveProperties, assert, assertArgument,
FetchRequest
} from "../utils/index.js";
@ -77,20 +77,18 @@ export class AlchemyProvider extends JsonRpcProvider implements CommunityResourc
} catch (error) { }
if (data) {
if (error) {
throwError("an error occurred during transaction executions", "CALL_EXCEPTION", {
action: "getTransactionResult",
data,
reason: null,
transaction: tx,
invocation: null,
revert: null // @TODO
});
}
assert(!error, "an error occurred during transaction executions", "CALL_EXCEPTION", {
action: "getTransactionResult",
data,
reason: null,
transaction: tx,
invocation: null,
revert: null // @TODO
});
return data;
}
return throwError("could not parse trace result", "BAD_DATA", { value: trace });
assert(false, "could not parse trace result", "BAD_DATA", { value: trace });
}
return await super._perform(req);

View File

@ -4,7 +4,7 @@ import {
defineProperties,
hexlify, toQuantity,
FetchRequest,
assertArgument, throwError,
assert, assertArgument,
toUtf8String
} from "../utils/index.js";
@ -395,7 +395,7 @@ export class BaseEtherscanProvider extends AbstractProvider {
});
}
return throwError("getBlock by blockHash not supported by Etherscan", "UNSUPPORTED_OPERATION", {
assert(false, "getBlock by blockHash not supported by Etherscan", "UNSUPPORTED_OPERATION", {
operation: "getBlock(blockHash)"
});

View File

@ -1,6 +1,6 @@
import {
getBigInt, getNumber, hexlify, throwError, assertArgument
getBigInt, getNumber, hexlify, assert, assertArgument
} from "../utils/index.js";
import { AbstractProvider } from "./abstract-provider.js";
@ -32,6 +32,15 @@ function stall(duration: number): Promise<void> {
function getTime(): number { return (new Date()).getTime(); }
function stringify(value: any): string {
return JSON.stringify(value, (key, value) => {
if (typeof(value) === "bigint") {
return { type: "bigint", value: value.toString() };
}
return value;
});
}
export interface FallbackProviderConfig {
// The provider
@ -152,24 +161,23 @@ function normalize(provider: AbstractProvider, value: any, req: PerformActionReq
return hexlify(value);
case "getBlock":
if (req.includeTransactions) {
return JSON.stringify(formatBlockWithTransactions(value));
return stringify(formatBlockWithTransactions(value));
}
return JSON.stringify(formatBlock(value));
return stringify(formatBlock(value));
case "getTransaction":
return JSON.stringify(formatTransactionResponse(value));
return stringify(formatTransactionResponse(value));
case "getTransactionReceipt":
return JSON.stringify(formatTransactionReceipt(value));
return stringify(formatTransactionReceipt(value));
case "call":
return hexlify(value);
case "estimateGas":
return getBigInt(value).toString();
case "getLogs":
return JSON.stringify(value.map((v: any) => formatLog(v)));
return stringify(value.map((v: any) => formatLog(v)));
}
return throwError("unsupported method", "UNSUPPORTED_OPERATION", {
operation: `_perform(${ JSON.stringify(req.method) })`
});
assert(false, "unsupported method", "UNSUPPORTED_OPERATION", {
operation: `_perform(${ stringify(req.method) })` });
}
type TallyResult = {
@ -384,7 +392,7 @@ export class FallbackProvider extends AbstractProvider {
if (chainId == null) {
chainId = network.chainId;
} else if (network.chainId !== chainId) {
throwError("cannot mix providers on different networks", "UNSUPPORTED_OPERATION", {
assert(false, "cannot mix providers on different networks", "UNSUPPORTED_OPERATION", {
operation: "new FallbackProvider"
});
}
@ -463,8 +471,8 @@ export class FallbackProvider extends AbstractProvider {
throw new Error("TODO");
}
return throwError("unsupported method", "UNSUPPORTED_OPERATION", {
operation: `_perform(${ JSON.stringify((<any>req).method) })`
assert(false, "unsupported method", "UNSUPPORTED_OPERATION", {
operation: `_perform(${ stringify((<any>req).method) })`
});
}

View File

@ -1,5 +1,5 @@
import {
defineProperties, FetchRequest, assertArgument, throwError
defineProperties, FetchRequest, assert, assertArgument
} from "../utils/index.js";
import { showThrottleMessage } from "./community.js";
@ -48,11 +48,8 @@ export class InfuraWebSocketProvider extends WebSocketProvider implements Commun
const provider = new InfuraProvider(network, apiKey);
const req = provider._getConnection();
if (req.credentials) {
throwError("INFURA WebSocket project secrets unsupported", "UNSUPPORTED_OPERATION", {
operation: "InfuraProvider.getWebSocketProvider()"
});
}
assert(!req.credentials, "INFURA WebSocket project secrets unsupported",
"UNSUPPORTED_OPERATION", { operation: "InfuraProvider.getWebSocketProvider()" });
const url = req.url.replace(/^http/i, "ws").replace("/v3/", "/ws/v3/");
super(url, network);

View File

@ -9,7 +9,7 @@ import { TypedDataEncoder } from "../hash/index.js";
import { accessListify } from "../transaction/index.js";
import {
defineProperties, getBigInt, hexlify, isHexString, toQuantity, toUtf8Bytes,
makeError, assertArgument, throwError,
makeError, assert, assertArgument,
FetchRequest, resolveProperties
} from "../utils/index.js";
@ -194,7 +194,7 @@ export class JsonRpcSigner extends AbstractSigner<JsonRpcApiProvider> {
}
connect(provider: null | Provider): Signer {
return throwError("cannot reconnect JsonRpcSigner", "UNSUPPORTED_OPERATION", {
assert(false, "cannot reconnect JsonRpcSigner", "UNSUPPORTED_OPERATION", {
operation: "signer.connect"
});
}
@ -478,10 +478,7 @@ export class JsonRpcApiProvider extends AbstractProvider {
* is detected, and if it has changed, the call will reject.
*/
get _network(): Network {
if (!this.#network) {
throwError("network is not available yet", "NETWORK_ERROR");
}
assert (this.#network, "network is not available yet", "NETWORK_ERROR");
return this.#network;
}
@ -491,7 +488,7 @@ export class JsonRpcApiProvider extends AbstractProvider {
* Sub-classes **MUST** override this.
*/
_send(payload: JsonRpcPayload | Array<JsonRpcPayload>): Promise<Array<JsonRpcResult | JsonRpcError>> {
return throwError("sub-classes must override _send", "UNSUPPORTED_OPERATION", {
assert(false, "sub-classes must override _send", "UNSUPPORTED_OPERATION", {
operation: "jsonRpcApiProvider._send"
});
}
@ -619,6 +616,7 @@ export class JsonRpcApiProvider extends AbstractProvider {
* subscription management.
*/
_getSubscriber(sub: Subscription): Subscriber {
// Pending Filters aren't availble via polling
if (sub.type === "pending") { return new FilterIdPendingSubscriber(this); }

View File

@ -10,7 +10,7 @@
*/
import { UnmanagedSubscriber } from "./abstract-provider.js";
import { assertArgument, throwError } from "../utils/index.js";
import { assert, assertArgument } from "../utils/index.js";
import { JsonRpcApiProvider } from "./provider-jsonrpc.js";
import type { Subscriber, Subscription } from "./abstract-provider.js";
@ -63,11 +63,8 @@ export class SocketSubscriber implements Subscriber {
// @TODO: pause should trap the current blockNumber, unsub, and on resume use getLogs
// and resume
pause(dropWhilePaused?: boolean): void {
if (!dropWhilePaused) {
throwError("preserve logs while paused not supported by SocketSubscriber yet", "UNSUPPORTED_OPERATION", {
operation: "pause(false)"
});
}
assert(dropWhilePaused, "preserve logs while paused not supported by SocketSubscriber yet",
"UNSUPPORTED_OPERATION", { operation: "pause(false)" });
this.#paused = !!dropWhilePaused;
}

View File

@ -1,7 +1,7 @@
//import { resolveAddress } from "@ethersproject/address";
import {
defineProperties, getBigInt, getNumber, hexlify, resolveProperties,
assertArgument, isError, makeError, throwError
assert, assertArgument, isError, makeError
} from "../utils/index.js";
import { accessListify } from "../transaction/index.js";
@ -586,10 +586,8 @@ export class TransactionReceipt implements TransactionReceiptParams, Iterable<Lo
}
reorderedEvent(other?: TransactionResponse): OrphanFilter {
if (other && !other.isMined()) {
return throwError("unmined 'other' transction cannot be orphaned", "UNSUPPORTED_OPERATION", {
operation: "reorderedEvent(other)" });
}
assert(!other || other.isMined(), "unmined 'other' transction cannot be orphaned",
"UNSUPPORTED_OPERATION", { operation: "reorderedEvent(other)" });
return createReorderedTransactionFilter(this, other);
}
}
@ -814,7 +812,7 @@ export class TransactionResponse implements TransactionLike<string>, Transaction
reason = "cancelled"
}
throwError("transaction was replaced", "TRANSACTION_REPLACED", {
assert(false, "transaction was replaced", "TRANSACTION_REPLACED", {
cancelled: (reason === "replaced" || reason === "cancelled"),
reason,
replacement: tx.replaceableTransaction(startBlock),
@ -913,22 +911,18 @@ export class TransactionResponse implements TransactionLike<string>, Transaction
}
removedEvent(): OrphanFilter {
if (!this.isMined()) {
return throwError("unmined transaction canot be orphaned", "UNSUPPORTED_OPERATION", {
operation: "removeEvent()" });
}
assert(this.isMined(), "unmined transaction canot be orphaned",
"UNSUPPORTED_OPERATION", { operation: "removeEvent()" });
return createRemovedTransactionFilter(this);
}
reorderedEvent(other?: TransactionResponse): OrphanFilter {
if (!this.isMined()) {
return throwError("unmined transaction canot be orphaned", "UNSUPPORTED_OPERATION", {
operation: "removeEvent()" });
}
if (other && !other.isMined()) {
return throwError("unmined 'other' transaction canot be orphaned", "UNSUPPORTED_OPERATION", {
operation: "removeEvent()" });
}
assert(this.isMined(), "unmined transaction canot be orphaned",
"UNSUPPORTED_OPERATION", { operation: "removeEvent()" });
assert(!other || other.isMined(), "unmined 'other' transaction canot be orphaned",
"UNSUPPORTED_OPERATION", { operation: "removeEvent()" });
return createReorderedTransactionFilter(this, other);
}

View File

@ -104,7 +104,6 @@ export class FilterIdEventSubscriber extends FilterIdSubscriber {
async _subscribe(provider: JsonRpcApiProvider): Promise<string> {
const filterId = await provider.send("eth_newFilter", [ this.#event ]);
console.log("____SUB", filterId);
return filterId;
}

View File

@ -1,4 +1,4 @@
import { isHexString, throwError } from "../utils/index.js";
import { assert, isHexString } from "../utils/index.js";
import type { AbstractProvider, Subscriber } from "./abstract-provider.js";
import type { EventFilter, OrphanFilter, ProviderEvent } from "./provider.js";
@ -11,7 +11,7 @@ export function getPollingSubscriber(provider: AbstractProvider, event: Provider
if (event === "block") { return new PollingBlockSubscriber(provider); }
if (isHexString(event, 32)) { return new PollingTransactionSubscriber(provider, event); }
return throwError("unsupported polling event", "UNSUPPORTED_OPERATION", {
assert(false, "unsupported polling event", "UNSUPPORTED_OPERATION", {
operation: "getPollingSubscriber", info: { event }
});
}

View File

@ -1,4 +1,4 @@
import { assertArgument, throwError } from "./errors.js";
import { assert, assertArgument } from "./errors.js";
export type BytesLike = string | Uint8Array;
@ -114,9 +114,11 @@ export function dataLength(data: BytesLike): number {
*/
export function dataSlice(data: BytesLike, start?: number, end?: number): string {
const bytes = getBytes(data);
if (end != null && end > bytes.length) { throwError("cannot slice beyond data bounds", "BUFFER_OVERRUN", {
buffer: bytes, length: bytes.length, offset: end
}); }
if (end != null && end > bytes.length) {
assert(false, "cannot slice beyond data bounds", "BUFFER_OVERRUN", {
buffer: bytes, length: bytes.length, offset: end
});
}
return hexlify(bytes.slice((start == null) ? 0: start, (end == null) ? bytes.length: end));
}
@ -132,13 +134,11 @@ export function stripZerosLeft(data: BytesLike): string {
function zeroPad(data: BytesLike, length: number, left: boolean): string {
const bytes = getBytes(data);
if (length < bytes.length) {
throwError("padding exceeds data length", "BUFFER_OVERRUN", {
buffer: new Uint8Array(bytes),
length: length,
offset: length + 1
});
}
assert(length >= bytes.length, "padding exceeds data length", "BUFFER_OVERRUN", {
buffer: new Uint8Array(bytes),
length: length,
offset: length + 1
});
const result = new Uint8Array(length);
result.fill(0);

View File

@ -319,12 +319,12 @@ export function makeError<K extends ErrorCode, T extends CodedEthersError<K>>(me
/**
* Throws an EthersError with %%message%%, %%code%% and additional error
* info.
* %%info%% when %%check%% is falsish..
*
* @see [[api:makeError]]
*/
export function throwError<K extends ErrorCode, T extends CodedEthersError<K>>(message: string, code: K, info?: ErrorInfo<T>): never {
throw makeError(message, code, info);
export function assert<K extends ErrorCode, T extends CodedEthersError<K>>(check: unknown, message: string, code: K, info?: ErrorInfo<T>): asserts check {
if (!check) { throw makeError(message, code, info); }
}
@ -336,27 +336,21 @@ export function throwError<K extends ErrorCode, T extends CodedEthersError<K>>(m
* any further code does not need additional compile-time checks.
*/
export function assertArgument(check: unknown, message: string, name: string, value: unknown): asserts check {
if (!check) {
throwError(message, "INVALID_ARGUMENT", { argument: name, value: value });
}
assert(check, message, "INVALID_ARGUMENT", { argument: name, value: value });
}
export function assertArgumentCount(count: number, expectedCount: number, message: string = ""): void {
if (message) { message = ": " + message; }
if (count < expectedCount) {
throwError("missing arguemnt" + message, "MISSING_ARGUMENT", {
count: count,
expectedCount: expectedCount
});
}
assert(count >= expectedCount, "missing arguemnt" + message, "MISSING_ARGUMENT", {
count: count,
expectedCount: expectedCount
});
if (count > expectedCount) {
throwError("too many arguemnts" + message, "UNEXPECTED_ARGUMENT", {
count: count,
expectedCount: expectedCount
});
}
assert(count <= expectedCount, "too many arguemnts" + message, "UNEXPECTED_ARGUMENT", {
count: count,
expectedCount: expectedCount
});
}
const _normalizeForms = ["NFD", "NFC", "NFKD", "NFKC"].reduce((accum, form) => {
@ -384,11 +378,9 @@ const _normalizeForms = ["NFD", "NFC", "NFKD", "NFKC"].reduce((accum, form) => {
* Throws if the normalization %%form%% is not supported.
*/
export function assertNormalize(form: string): void {
if (_normalizeForms.indexOf(form) === -1) {
throwError("platform missing String.prototype.normalize", "UNSUPPORTED_OPERATION", {
operation: "String.prototype.normalize", info: { form }
});
}
assert(_normalizeForms.indexOf(form) >= 0, "platform missing String.prototype.normalize", "UNSUPPORTED_OPERATION", {
operation: "String.prototype.normalize", info: { form }
});
}
/**
@ -404,7 +396,7 @@ export function assertPrivate(givenGuard: any, guard: any, className: string = "
method += ".";
operation += " " + className;
}
throwError(`private constructor; use ${ method }from* methods`, "UNSUPPORTED_OPERATION", {
assert(false, `private constructor; use ${ method }from* methods`, "UNSUPPORTED_OPERATION", {
operation
});
}

View File

@ -1,6 +1,6 @@
import { decodeBase64, encodeBase64 } from "./base64.js";
import { hexlify } from "./data.js";
import { assertArgument, throwError } from "./errors.js";
import { assert, assertArgument } from "./errors.js";
import { defineProperties } from "./properties.js";
import { toUtf8Bytes, toUtf8String } from "./utf8.js"
@ -117,11 +117,9 @@ export class FetchCancelSignal {
}
addListener(listener: () => void): void {
if (this.#cancelled) {
throwError("singal already cancelled", "UNSUPPORTED_OPERATION", {
operation: "fetchCancelSignal.addCancelListener"
});
}
assert(this.#cancelled, "singal already cancelled", "UNSUPPORTED_OPERATION", {
operation: "fetchCancelSignal.addCancelListener"
});
this.#listeners.push(listener);
}
@ -129,7 +127,7 @@ export class FetchCancelSignal {
checkSignal(): void {
if (!this.cancelled) { return; }
throwError("cancelled", "CANCELLED", { });
assert(false, "cancelled", "CANCELLED", { });
}
}
@ -414,11 +412,9 @@ export class FetchRequest implements Iterable<[ key: string, value: string ]> {
return _response.makeServerError("exceeded maximum retry limit");
}
if (getTime() > expires) {
return throwError("timeout", "TIMEOUT", {
operation: "request.send", reason: "timeout", request: _request
});
}
assert(getTime() <= expires, "timeout", "TIMEOUT", {
operation: "request.send", reason: "timeout", request: _request
});
if (delay > 0) { await wait(delay); }
@ -507,9 +503,7 @@ export class FetchRequest implements Iterable<[ key: string, value: string ]> {
* Resolves to the response by sending the request.
*/
send(): Promise<FetchResponse> {
if (this.#signal != null) {
return throwError("request already sent", "UNSUPPORTED_OPERATION", { operation: "fetchRequest.send" });
}
assert(this.#signal == null, "request already sent", "UNSUPPORTED_OPERATION", { operation: "fetchRequest.send" });
this.#signal = new FetchCancelSignal(this);
return this.#send(0, getTime() + this.timeout, 0, this, new FetchResponse(0, "", { }, null, this));
}
@ -519,9 +513,7 @@ export class FetchRequest implements Iterable<[ key: string, value: string ]> {
* error to be rejected from the [[send]].
*/
cancel(): void {
if (this.#signal == null) {
return throwError("request has not been sent", "UNSUPPORTED_OPERATION", { operation: "fetchRequest.cancel" });
}
assert(this.#signal != null, "request has not been sent", "UNSUPPORTED_OPERATION", { operation: "fetchRequest.cancel" });
const signal = fetchSignals.get(this);
if (!signal) { throw new Error("missing signal; should not happen"); }
signal();
@ -540,11 +532,9 @@ export class FetchRequest implements Iterable<[ key: string, value: string ]> {
// - non-GET requests
// - downgrading the security (e.g. https => http)
// - to non-HTTP (or non-HTTPS) protocols [this could be relaxed?]
if (this.method !== "GET" || (current === "https" && target === "http") || !location.match(/^https?:/)) {
return throwError(`unsupported redirect`, "UNSUPPORTED_OPERATION", {
operation: `redirect(${ this.method } ${ JSON.stringify(this.url) } => ${ JSON.stringify(location) })`
});
}
assert(this.method === "GET" && (current !== "https" || target !== "http") && location.match(/^https?:/), `unsupported redirect`, "UNSUPPORTED_OPERATION", {
operation: `redirect(${ this.method } ${ JSON.stringify(this.url) } => ${ JSON.stringify(location) })`
});
// Create a copy of this request, with a new URL
const req = new FetchRequest(location);
@ -683,7 +673,7 @@ export class FetchResponse implements Iterable<[ key: string, value: string ]> {
try {
return (this.#body == null) ? "": toUtf8String(this.#body);
} catch (error) {
return throwError("response body is not valid UTF-8 data", "UNSUPPORTED_OPERATION", {
assert(false, "response body is not valid UTF-8 data", "UNSUPPORTED_OPERATION", {
operation: "bodyText", info: { response: this }
});
}
@ -698,7 +688,7 @@ export class FetchResponse implements Iterable<[ key: string, value: string ]> {
try {
return JSON.parse(this.bodyText);
} catch (error) {
return throwError("response body is not valid JSON", "UNSUPPORTED_OPERATION", {
assert(false, "response body is not valid JSON", "UNSUPPORTED_OPERATION", {
operation: "bodyJson", info: { response: this }
});
}
@ -806,7 +796,7 @@ export class FetchResponse implements Iterable<[ key: string, value: string ]> {
if (message === "") {
message = `server response ${ this.statusCode } ${ this.statusMessage }`;
}
throwError(message, "SERVER_ERROR", {
assert(false, message, "SERVER_ERROR", {
request: (this.request || "unknown request"), response: this, error
});
}

View File

@ -1,18 +1,18 @@
import { getBytes } from "./data.js";
import { assertArgument, throwError } from "./errors.js";
import { assert, assertArgument, assertPrivate } from "./errors.js";
import { getBigInt, getNumber, fromTwos, toBigInt, toHex, toTwos } from "./maths.js";
import type { BigNumberish, BytesLike, Numeric } from "./index.js";
const _constructorGuard = { };
const _guard = { };
const NegativeOne = BigInt(-1);
function throwFault(message: string, fault: string, operation: string, value?: any): never {
const params: any = { fault: fault, operation: operation };
if (value !== undefined) { params.value = value; }
return throwError(message, "NUMERIC_FAULT", params);
assert(false, message, "NUMERIC_FAULT", params);
}
// Constant to pull zeros from for multipliers
@ -113,12 +113,8 @@ export class FixedFormat {
readonly _multiplier: bigint;
constructor(constructorGuard: any, signed: boolean, width: number, decimals: number) {
if (constructorGuard !== _constructorGuard) {
throwError("cannot use FixedFormat constructor; use FixedFormat.from", "UNSUPPORTED_OPERATION", {
operation: "new FixedFormat"
});
}
constructor(guard: any, signed: boolean, width: number, decimals: number) {
assertPrivate(guard, _guard, "FixedFormat");
this.signed = signed;
this.width = width;
@ -169,7 +165,7 @@ export class FixedFormat {
assertArgument((width % 8) === 0, "invalid fixed format width (not byte aligned)", "format.width", width);
assertArgument(decimals <= 80, "invalid fixed format (decimals too large)", "format.decimals", decimals);
return new FixedFormat(_constructorGuard, signed, width, decimals);
return new FixedFormat(_guard, signed, width, decimals);
}
}
@ -184,12 +180,8 @@ export class FixedNumber {
//#hex: string;
#value: string;
constructor(constructorGuard: any, hex: string, value: string, format?: FixedFormat) {
if (constructorGuard !== _constructorGuard) {
throwError("cannot use FixedNumber constructor; use FixedNumber.from", "UNSUPPORTED_OPERATION", {
operation: "new FixedFormat"
});
}
constructor(guard: any, hex: string, value: string, format?: FixedFormat) {
assertPrivate(guard, _guard, "FixedNumber");
this.format = FixedFormat.from(format);
//this.#hex = hex;
@ -337,7 +329,7 @@ export class FixedNumber {
const decimal = formatFixed(numeric, fixedFormat.decimals);
return new FixedNumber(_constructorGuard, hex, decimal, fixedFormat);
return new FixedNumber(_guard, hex, decimal, fixedFormat);
}
static fromBytes(_value: BytesLike, format: FixedFormat | string | number = "fixed"): FixedNumber {
@ -354,7 +346,7 @@ export class FixedNumber {
const hex = toHex(toTwos(numeric, (fixedFormat.signed ? 0: 1) + fixedFormat.width));
const decimal = formatFixed(numeric, fixedFormat.decimals);
return new FixedNumber(_constructorGuard, hex, decimal, fixedFormat);
return new FixedNumber(_guard, hex, decimal, fixedFormat);
}
static from(value: any, format?: FixedFormat | string | number): FixedNumber {

View File

@ -1,4 +1,4 @@
import { throwError } from "./errors.js";
import { assert } from "./errors.js";
import type { FetchRequest, FetchCancelSignal, GetUrlResponse } from "./fetch.js";
@ -30,18 +30,14 @@ declare global {
export async function getUrl(req: FetchRequest, _signal?: FetchCancelSignal): Promise<GetUrlResponse> {
const protocol = req.url.split(":")[0].toLowerCase();
if (protocol !== "http" && protocol !== "https") {
throwError(`unsupported protocol ${ protocol }`, "UNSUPPORTED_OPERATION", {
info: { protocol },
operation: "request"
});
}
assert(protocol === "http" || protocol === "https", `unsupported protocol ${ protocol }`, "UNSUPPORTED_OPERATION", {
info: { protocol },
operation: "request"
});
if (req.credentials && !req.allowInsecureAuthentication) {
throwError("insecure authorized connections unsupported", "UNSUPPORTED_OPERATION", {
operation: "request"
});
}
assert(!req.credentials || req.allowInsecureAuthentication, "insecure authorized connections unsupported", "UNSUPPORTED_OPERATION", {
operation: "request"
});
let signal: undefined | AbortSignal = undefined;
if (_signal) {

View File

@ -2,7 +2,7 @@ import http from "http";
import https from "https";
import { gunzipSync } from "zlib";
import { throwError } from "./errors.js";
import { assert } from "./errors.js";
import { getBytes } from "./data.js";
import type { FetchRequest, FetchCancelSignal, GetUrlResponse } from "./fetch.js";
@ -12,18 +12,14 @@ export async function getUrl(req: FetchRequest, signal?: FetchCancelSignal): Pro
const protocol = req.url.split(":")[0].toLowerCase();
if (protocol !== "http" && protocol !== "https") {
throwError(`unsupported protocol ${ protocol }`, "UNSUPPORTED_OPERATION", {
info: { protocol },
operation: "request"
});
}
assert(protocol === "http" || protocol === "https", `unsupported protocol ${ protocol }`, "UNSUPPORTED_OPERATION", {
info: { protocol },
operation: "request"
});
if (req.credentials && !req.allowInsecureAuthentication) {
throwError("insecure authorized connections unsupported", "UNSUPPORTED_OPERATION", {
operation: "request"
});
}
assert(!req.credentials || req.allowInsecureAuthentication, "insecure authorized connections unsupported", "UNSUPPORTED_OPERATION", {
operation: "request"
});
const method = req.method;
const headers = Object.assign({ }, req.headers);

View File

@ -25,8 +25,7 @@ export {
export {
isCallException, isError,
makeError, throwError,
assertArgument, assertArgumentCount, assertPrivate, assertNormalize
assert, assertArgument, assertArgumentCount, assertPrivate, assertNormalize, makeError
} from "./errors.js"
export { EventPayload } from "./events.js";

View File

@ -1,7 +1,7 @@
//See: https://github.com/ethereum/wiki/wiki/RLP
import { hexlify } from "./data.js";
import { assertArgument, throwError } from "./errors.js";
import { assert, assertArgument } from "./errors.js";
import { getBytes } from "./data.js";
import type { BytesLike, RlpStructuredData } from "./index.js";
@ -35,11 +35,9 @@ function _decodeChildren(data: Uint8Array, offset: number, childOffset: number,
result.push(decoded.result);
childOffset += decoded.consumed;
if (childOffset > offset + 1 + length) {
throwError("child data too short", "BUFFER_OVERRUN", {
buffer: data, length, offset
});
}
assert(childOffset <= offset + 1 + length, "child data too short", "BUFFER_OVERRUN", {
buffer: data, length, offset
});
}
return {consumed: (1 + length), result: result};
@ -47,18 +45,14 @@ function _decodeChildren(data: Uint8Array, offset: number, childOffset: number,
// returns { consumed: number, result: Object }
function _decode(data: Uint8Array, offset: number): { consumed: number, result: any } {
if (data.length === 0) {
throwError("data too short", "BUFFER_OVERRUN", {
buffer: data, length: 0, offset: 1
});
}
assert(data.length !== 0, "data too short", "BUFFER_OVERRUN", {
buffer: data, length: 0, offset: 1
});
const checkOffset = (offset: number) => {
if (offset > data.length) {
throwError("data short segment too short", "BUFFER_OVERRUN", {
buffer: data, length: data.length, offset
});
}
assert(offset <= data.length, "data short segment too short", "BUFFER_OVERRUN", {
buffer: data, length: data.length, offset
});
};
// Array with extra length prefix

View File

@ -3,7 +3,7 @@ import { hashMessage, TypedDataEncoder } from "../hash/index.js";
import { AbstractSigner } from "../providers/index.js";
import { computeAddress, Transaction } from "../transaction/index.js";
import {
defineProperties, resolveProperties, assertArgument, throwError
defineProperties, resolveProperties, assert, assertArgument
} from "../utils/index.js";
import type { SigningKey } from "../crypto/index.js";
@ -72,19 +72,15 @@ export class BaseWallet extends AbstractSigner {
// Populate any ENS names
const populated = await TypedDataEncoder.resolveNames(domain, types, value, async (name: string) => {
if (this.provider == null) {
return throwError("cannot resolve ENS names without a provider", "UNSUPPORTED_OPERATION", {
operation: "resolveName",
info: { name }
});
}
assert(this.provider != null, "cannot resolve ENS names without a provider", "UNSUPPORTED_OPERATION", {
operation: "resolveName",
info: { name }
});
const address = await this.provider.resolveName(name);
if (address == null) {
return throwError("unconfigured ENS name", "UNCONFIGURED_NAME", {
value: name
});
}
assert(address != null, "unconfigured ENS name", "UNCONFIGURED_NAME", {
value: name
});
return address;
});

View File

@ -5,7 +5,7 @@ import {
concat, dataSlice, decodeBase58, defineProperties, encodeBase58,
getBytes, hexlify,
getNumber, toBigInt, toHex,
assertPrivate, assertArgument, throwError
assertPrivate, assert, assertArgument
} from "../utils/index.js";
import { langEn } from "../wordlists/lang-en.js";
@ -51,11 +51,9 @@ function ser_I(index: number, chainCode: string, publicKey: string, privateKey:
const data = new Uint8Array(37);
if (index & HardenedBit) {
if (privateKey == null) {
return throwError("cannot derive child of neutered node", "UNSUPPORTED_OPERATION", {
operation: "deriveChild"
});
}
assert(privateKey != null, "cannot derive child of neutered node", "UNSUPPORTED_OPERATION", {
operation: "deriveChild"
});
// Data = 0x00 || ser_256(k_par)
data.set(getBytes(privateKey), 1);

View File

@ -4,7 +4,7 @@ import { getAddress } from "../address/index.js";
import { keccak256, pbkdf2, randomBytes, scrypt, scryptSync } from "../crypto/index.js";
import { computeAddress } from "../transaction/index.js";
import {
concat, getBytes, hexlify, assertArgument, throwError
concat, getBytes, hexlify, assert, assertArgument
} from "../utils/index.js";
import { getPassword, spelunk, uuidV4, zpad } from "./utils.js";
@ -67,7 +67,7 @@ function decrypt(data: any, key: Uint8Array, ciphertext: Uint8Array): string {
return hexlify(aesCtr.decrypt(ciphertext));
}
return throwError("unsupported cipher", "UNSUPPORTED_OPERATION", {
assert(false, "unsupported cipher", "UNSUPPORTED_OPERATION", {
operation: "decrypt"
});
}