Switched to assert instead of throwArgument.
This commit is contained in:
parent
e5c068c395
commit
3db5864041
@ -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
|
||||
|
@ -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)); }
|
||||
|
@ -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({
|
||||
|
@ -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); }
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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"
|
||||
});
|
||||
}
|
||||
|
@ -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> {
|
||||
|
@ -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)")
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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)"
|
||||
});
|
||||
|
||||
|
@ -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) })`
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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); }
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 }
|
||||
});
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
});
|
||||
}
|
||||
|
@ -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
|
||||
});
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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";
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
});
|
||||
|
@ -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);
|
||||
|
@ -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"
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user