From e2b905382fdbdcf330220fbd6f980f65f2fd4f01 Mon Sep 17 00:00:00 2001 From: ivan Date: Sun, 25 Feb 2024 23:53:57 +0100 Subject: [PATCH 01/12] Remove ethers dependency from the generated files --- evm/evm-typegen/package.json | 9 +- evm/evm-typegen/src/abi.support.ts | 140 ++++-- evm/evm-typegen/src/decodeAbiParameters.ts | 360 +++++++++++++++ evm/evm-typegen/src/encodeAbiParameters.ts | 318 +++++++++++++ evm/evm-typegen/src/main.ts | 49 +- evm/evm-typegen/src/multicall.ts | 424 +++++++++--------- evm/evm-typegen/src/typegen.ts | 66 ++- evm/evm-typegen/src/util/types.ts | 63 ++- .../test/decodeAbiParameters.test.ts | 43 ++ .../test/encodeAbiParameters.test.ts | 39 ++ evm/evm-typegen/test/logEvent.test.ts | 127 ++++++ evm/evm-typegen/tsconfig.build.json | 8 + evm/evm-typegen/tsconfig.json | 6 +- test/erc20-transfers/package.json | 2 +- test/erc20-transfers/src/abi/abi.support.ts | 149 ++++-- .../src/abi/decodeAbiParameters.ts | 360 +++++++++++++++ .../src/abi/encodeAbiParameters.ts | 318 +++++++++++++ test/erc20-transfers/src/abi/erc20.abi.ts | 210 --------- test/erc20-transfers/src/abi/erc20.ts | 65 +-- test/erc20-transfers/src/processor.ts | 2 +- 20 files changed, 2166 insertions(+), 592 deletions(-) create mode 100644 evm/evm-typegen/src/decodeAbiParameters.ts create mode 100644 evm/evm-typegen/src/encodeAbiParameters.ts create mode 100644 evm/evm-typegen/test/decodeAbiParameters.test.ts create mode 100644 evm/evm-typegen/test/encodeAbiParameters.test.ts create mode 100644 evm/evm-typegen/test/logEvent.test.ts create mode 100644 evm/evm-typegen/tsconfig.build.json create mode 100644 test/erc20-transfers/src/abi/decodeAbiParameters.ts create mode 100644 test/erc20-transfers/src/abi/encodeAbiParameters.ts delete mode 100644 test/erc20-transfers/src/abi/erc20.abi.ts diff --git a/evm/evm-typegen/package.json b/evm/evm-typegen/package.json index 8bb874ba6..dd1bdf06b 100644 --- a/evm/evm-typegen/package.json +++ b/evm/evm-typegen/package.json @@ -16,7 +16,7 @@ "squid-evm-typegen": "bin/run.js" }, "scripts": { - "build": "rm -rf lib && tsc" + "build": "rm -rf lib && tsc -p tsconfig.build.json" }, "dependencies": { "@subsquid/http-client": "^1.3.2", @@ -27,10 +27,13 @@ "commander": "^11.1.0" }, "peerDependencies": { - "ethers": "^6.9.0" + "abitype": "^1.0.0", + "ethers": "^6.9.0", + "viem": "^2.7.11" }, "devDependencies": { "@types/node": "^18.18.14", - "typescript": "~5.3.2" + "typescript": "~5.3.2", + "vitest": "^1.3.1" } } diff --git a/evm/evm-typegen/src/abi.support.ts b/evm/evm-typegen/src/abi.support.ts index deac8281b..7acfec7d3 100644 --- a/evm/evm-typegen/src/abi.support.ts +++ b/evm/evm-typegen/src/abi.support.ts @@ -1,5 +1,7 @@ -import assert from 'assert' -import * as ethers from 'ethers' +import {type AbiParameter, decodeAbiParameters, hasDynamicChild} from './decodeAbiParameters' +import {encodeFunctionData} from "./encodeAbiParameters"; + +type Hex = `0x${string}` export interface EventRecord { topics: string[] @@ -7,21 +9,90 @@ export interface EventRecord { } export type LogRecord = EventRecord -export class LogEvent { - private fragment: ethers.EventFragment +type EventType = { + type: 'tuple' + internalType?: string + indexed?: boolean + name: string + components: EventType[] +} | { + type: string + internalType?: string + indexed?: boolean + name: string +} + +type SecondElements = T extends [] ? [] : T extends [[any, infer U], ...infer Tail extends [any, any][]] ? [U, ...SecondElements] : never +type Args = { + [K in T[number] as K[0]]: K[1] +} & SecondElements + +function assertIsHex(val: unknown): asserts val is Hex { + if (typeof val !== 'string' || !val.startsWith('0x')) { + throw new Error('Not a hex string') + } +} - constructor(private abi: ethers.Interface, public readonly topic: string) { - let fragment = abi.getEvent(topic) - assert(fragment != null, 'Missing fragment') - this.fragment = fragment +export class LogEvent { + private indexedArgs: ((AbiParameter & {index: number}) | null)[] = []; + private nonIndexedArgs: (AbiParameter & {index: number})[] = []; + + constructor(public readonly topic: string, readonly types: readonly EventType[]) { + assertIsHex(topic) + let index = 0; + for (const type of types) { + if (!type.indexed) { + this.nonIndexedArgs.push({ + ...type, + index + }) + } else { + if (hasDynamicChild(type)) { + this.indexedArgs.push({ + ...type, + type: 'bytes32', + index + }) + } else { + this.indexedArgs.push({ + ...type, + index + }) + } + } + index++; + } } is(rec: EventRecord): boolean { return rec.topics[0] === this.topic } - decode(rec: EventRecord): Args { - return this.abi.decodeEventLog(this.fragment, rec.data, rec.topics) as any as Args + decode(rec: EventRecord) { + if (!this.is(rec)) { + throw new Error('Invalid event record') + } + assertIsHex(rec.data) + const result: any = [] + const parsedData = decodeAbiParameters(this.nonIndexedArgs, rec.data) + for (let i = 0; i < parsedData.length; i++) { + if (this.nonIndexedArgs[i].name) { + result[this.nonIndexedArgs[i].name!] = parsedData[i] + } + result[this.nonIndexedArgs[i].index] = parsedData[i] + } + rec.topics.slice(1).forEach((topic, i) => { + const type = this.indexedArgs[i] + if (type) { + assertIsHex(topic) + const [parsedData] = decodeAbiParameters([type], topic) + if (type.name) { + result[type.name] = parsedData + } + result[type.index] = parsedData + } + }) + return result as Args } } @@ -30,13 +101,11 @@ export interface FuncRecord { input: string } -export class Func { - private fragment: ethers.FunctionFragment - - constructor(private abi: ethers.Interface, public readonly sighash: string) { - let fragment = abi.getFunction(sighash) - assert(fragment != null, 'Missing fragment') - this.fragment = fragment +export class Func { + public readonly sighash: Hex + constructor(sighash: string, private readonly args: AbiParameter[], private readonly result: AbiParameter[]) { + assertIsHex(sighash) + this.sighash = sighash } is(rec: FuncRecord): boolean { @@ -44,23 +113,29 @@ export class Func { return sighash === this.sighash } - decode(input: ethers.BytesLike): Args & FieldArgs - decode(rec: FuncRecord): Args & FieldArgs - decode(inputOrRec: ethers.BytesLike | FuncRecord): Args & FieldArgs { - const input = ethers.isBytesLike(inputOrRec) ? inputOrRec : inputOrRec.input - return this.abi.decodeFunctionData(this.fragment, input) as any as Args & FieldArgs + decode(input: string): Args + decode(rec: FuncRecord): Args + decode(inputOrRec: string | FuncRecord): Args { + const input = typeof inputOrRec === 'string' ? inputOrRec : inputOrRec.input + assertIsHex(input) + if (!this.is({input})) { + throw new Error('Invalid event record') + } + + return decodeAbiParameters(this.args, `0x${input.slice(10)}`) as Args } - encode(args: Args): string { - return this.abi.encodeFunctionData(this.fragment, args) + encode(...args: SecondElements) { + return encodeFunctionData(this.sighash, this.args, args) } - decodeResult(output: ethers.BytesLike): Result { - const decoded = this.abi.decodeFunctionResult(this.fragment, output) + decodeResult(output: string): Result { + assertIsHex(output) + const decoded = decodeAbiParameters(this.result, output) return decoded.length > 1 ? decoded : decoded[0] } - tryDecodeResult(output: ethers.BytesLike): Result | undefined { + tryDecodeResult(output: string): Result | undefined { try { return this.decodeResult(output) } catch(err: any) { @@ -106,7 +181,7 @@ export interface Chain { export class ContractBase { private readonly _chain: Chain private readonly blockHeight: number - readonly address: string + readonly address: Hex constructor(ctx: BlockContext, address: string) constructor(ctx: ChainContext, block: Block, address: string) @@ -114,18 +189,19 @@ export class ContractBase { this._chain = ctx._chain if (typeof blockOrAddress === 'string') { this.blockHeight = ctx.block.height - this.address = ethers.getAddress(blockOrAddress) + this.address = blockOrAddress as Hex } else { if (address == null) { throw new Error('missing contract address') } this.blockHeight = blockOrAddress.height - this.address = ethers.getAddress(address) + this.address = address as Hex } + assertIsHex(this.address) } - async eth_call(func: Func, args: Args): Promise { - let data = func.encode(args) + async eth_call(func: Func, args: SecondElements): Promise { + let data = func.encode(...args) let result = await this._chain.client.call('eth_call', [ {to: this.address, data}, '0x'+this.blockHeight.toString(16) diff --git a/evm/evm-typegen/src/decodeAbiParameters.ts b/evm/evm-typegen/src/decodeAbiParameters.ts new file mode 100644 index 000000000..83f32a254 --- /dev/null +++ b/evm/evm-typegen/src/decodeAbiParameters.ts @@ -0,0 +1,360 @@ +export interface AbiParameter { + name?: string + type: string +} + +class Cursor { + bytes: Uint8Array + position: number + positionReadCount: Map + recursiveReadLimit: number + + constructor(bytes: Uint8Array) { + this.bytes = bytes + this.position = 0 + this.positionReadCount = new Map() + this.recursiveReadLimit = 8_192 + } + + inspectBytes(length: number) { + return this.bytes.subarray(this.position, this.position + length) + } + public readBytes(length: number, size?: number) { + const value = this.inspectBytes(length) + this.position += size ?? length + return value + } + public setPosition(position: number) { + const oldPosition = this.position + this.position = position + return () => (this.position = oldPosition) + } +} + +export function decodeAbiParameters( + params: AbiParameter[], + data: `0x${string}`, +) { + const bytes = Buffer.from(data.slice(2), 'hex') + const cursor = new Cursor(bytes) + + let consumed = 0 + const values = [] + for (let i = 0; i < params.length; ++i) { + const param = params[i] + cursor.setPosition(consumed) + const [data, consumed_] = decodeParameter(cursor, param, { + staticPosition: 0, + }) + consumed += consumed_ + values.push(data) + } + return values +} + +export function getArrayComponents( + type: string, +): [length: number | null, innerType: string] | undefined { + const matches = type.match(/^(.*)\[(\d+)?]$/) + return matches + ? // Return `null` if the array is dynamic. + [matches[2] ? Number(matches[2]) : null, matches[1]] + : undefined +} + +function decodeParameter( + cursor: Cursor, + param: AbiParameter, + { staticPosition }: { staticPosition: number }, +): readonly [any, number] { + const arrayComponents = getArrayComponents(param.type) + if (arrayComponents) { + const [length, type] = arrayComponents + return decodeArray(cursor, { ...param, type }, { length, staticPosition }) + } + if (param.type === 'tuple') + return decodeTuple(cursor, param as TupleAbiParameter, { staticPosition }) + + if (param.type === 'address') return decodeAddress(cursor) + if (param.type === 'bool') return decodeBool(cursor) + if (param.type.startsWith('bytes')) + return decodeBytes(cursor, param, { staticPosition }) + if (param.type.startsWith('uint') || param.type.startsWith('int')) + return decodeNumber(cursor, param) + if (param.type === 'string') return decodeString(cursor, { staticPosition }) + throw new Error(`Unknown type: ${param.type}`) +} + +//////////////////////////////////////////////////////////////////// +// Type Decoders + +const sizeOfLength = 32 +const sizeOfOffset = 32 + +function decodeAddress(cursor: Cursor) { + const value = cursor.readBytes(sizeOfOffset) + return [bytesToHex(value.slice(-20)), sizeOfLength] as const +} + +function decodeArray( + cursor: Cursor, + param: AbiParameter, + { length, staticPosition }: { length: number | null; staticPosition: number }, +) { + // If the length of the array is not known in advance (dynamic array), + // this means we will need to wonder off to the pointer and decode. + if (!length) { + // Dealing with a dynamic type, so get the offset of the array data. + const offset = bytesToNumber(cursor.readBytes(sizeOfOffset)) + + // Start is the static position of current slot + offset. + const start = staticPosition + offset + const startOfData = start + sizeOfLength + + // Get the length of the array from the offset. + cursor.setPosition(start) + const length = bytesToNumber(cursor.readBytes(sizeOfLength)) + + // Check if the array has any dynamic children. + const dynamicChild = hasDynamicChild(param) + + let consumed = 0 + const value: unknown[] = [] + for (let i = 0; i < length; ++i) { + // If any of the children is dynamic, then all elements will be offset pointer, thus size of one slot (32 bytes). + // Otherwise, elements will be the size of their encoding (consumed bytes). + cursor.setPosition(startOfData + (dynamicChild ? i * 32 : consumed)) + const [data, consumed_] = decodeParameter(cursor, param, { + staticPosition: startOfData, + }) + consumed += consumed_ + value.push(data) + } + + // As we have gone wondering, restore to the original position + next slot. + cursor.setPosition(staticPosition + 32) + return [value, 32] as const + } + + // If the length of the array is known in advance, + // and the length of an element deeply nested in the array is not known, + // we need to decode the offset of the array data. + if (hasDynamicChild(param)) { + // Dealing with dynamic types, so get the offset of the array data. + const offset = bytesToNumber(cursor.readBytes(sizeOfOffset)) + + // Start is the static position of current slot + offset. + const start = staticPosition + offset + + const value: unknown[] = [] + for (let i = 0; i < length; ++i) { + // Move cursor along to the next slot (next offset pointer). + cursor.setPosition(start + i * 32) + const [data] = decodeParameter(cursor, param, { + staticPosition: start, + }) + value.push(data) + } + + // As we have gone wondering, restore to the original position + next slot. + cursor.setPosition(staticPosition + 32) + return [value, 32] as const + } + + // If the length of the array is known in advance and the array is deeply static, + // then we can just decode each element in sequence. + let consumed = 0 + const value: unknown[] = [] + for (let i = 0; i < length; ++i) { + const [data, consumed_] = decodeParameter(cursor, param, { + staticPosition: staticPosition + consumed, + }) + consumed += consumed_ + value.push(data) + } + return [value, consumed] as const +} + +function decodeBool(cursor: Cursor) { + return [bytesToBool(cursor.readBytes(32), 32), 32] as const +} + +function decodeBytes( + cursor: Cursor, + param: AbiParameter, + { staticPosition }: { staticPosition: number }, +) { + const [_, size] = param.type.split('bytes') + if (!size) { + // Dealing with dynamic types, so get the offset of the bytes data. + const offset = bytesToNumber(cursor.readBytes(32)) + + // Set position of the cursor to start of bytes data. + cursor.setPosition(staticPosition + offset) + + const length = bytesToNumber(cursor.readBytes(32)) + + // If there is no length, we have zero data. + if (length === 0) { + // As we have gone wondering, restore to the original position + next slot. + cursor.setPosition(staticPosition + 32) + return ['0x', 32] as const + } + + const data = cursor.readBytes(length) + + // As we have gone wondering, restore to the original position + next slot. + cursor.setPosition(staticPosition + 32) + return [bytesToHex(data), 32] as const + } + + const value = bytesToHex(cursor.readBytes(parseInt(size), 32)) + return [value, 32] as const +} + +function decodeNumber(cursor: Cursor, param: AbiParameter) { + const signed = param.type.startsWith('int') + const size = parseInt(param.type.split('int')[1] || '256') + const value = cursor.readBytes(32) + return [ + size > 48 + ? bytesToBigInt(value, { signed }) + : bytesToNumber(value, { signed }), + 32, + ] as const +} + +type TupleAbiParameter = AbiParameter & { components: readonly AbiParameter[] } + +function decodeTuple( + cursor: Cursor, + param: TupleAbiParameter, + { staticPosition }: { staticPosition: number }, +) { + // Tuples can have unnamed components (i.e. they are arrays), so we must + // determine whether the tuple is named or unnamed. In the case of a named + // tuple, the value will be an object where each property is the name of the + // component. In the case of an unnamed tuple, the value will be an array. + const hasUnnamedChild = + param.components.length === 0 || param.components.some(({ name }) => !name) + + // Initialize the value to an object or an array, depending on whether the + // tuple is named or unnamed. + const value: any = hasUnnamedChild ? [] : {} + let consumed = 0 + + // If the tuple has a dynamic child, we must first decode the offset to the + // tuple data. + if (hasDynamicChild(param)) { + // Dealing with dynamic types, so get the offset of the tuple data. + const offset = bytesToNumber(cursor.readBytes(sizeOfOffset)) + + // Start is the static position of referencing slot + offset. + const start = staticPosition + offset + + for (let i = 0; i < param.components.length; ++i) { + const component = param.components[i] + cursor.setPosition(start + consumed) + const [data, consumed_] = decodeParameter(cursor, component, { + staticPosition: start, + }) + consumed += consumed_ + value[hasUnnamedChild ? i : component?.name!] = data + } + + // As we have gone wondering, restore to the original position + next slot. + cursor.setPosition(staticPosition + 32) + return [value, 32] as const + } + + // If the tuple has static children, we can just decode each component + // in sequence. + for (let i = 0; i < param.components.length; ++i) { + const component = param.components[i] + const [data, consumed_] = decodeParameter(cursor, component, { + staticPosition, + }) + value[hasUnnamedChild ? i : component?.name!] = data + consumed += consumed_ + } + return [value, consumed] as const +} + +function decodeString( + cursor: Cursor, + { staticPosition }: { staticPosition: number }, +) { + // Get offset to start of string data. + const offset = bytesToNumber(cursor.readBytes(32)) + + // Start is the static position of current slot + offset. + const start = staticPosition + offset + cursor.setPosition(start) + + const length = bytesToNumber(cursor.readBytes(32)) + + // If there is no length, we have zero data (empty string). + if (length === 0) { + cursor.setPosition(staticPosition + 32) + return ['', 32] as const + } + + const data = cursor.readBytes(length, 32) + const value = new TextDecoder().decode(data) + + // As we have gone wondering, restore to the original position + next slot. + cursor.setPosition(staticPosition + 32) + + return [value, 32] as const +} + +export function hasDynamicChild(param: AbiParameter) { + const { type } = param + if (type === 'string') return true + if (type === 'bytes') return true + if (type.endsWith('[]')) return true + + if (type === 'tuple') return (param as any).components?.some(hasDynamicChild) + + const arrayComponents = getArrayComponents(param.type) + if ( + arrayComponents && + hasDynamicChild({ ...param, type: arrayComponents[1] } as AbiParameter) + ) + return true + + return false +} + +//////////////////////////////////////////////////////////////////// +/// Bytes parsing + +const bytesToHex = (bytes: Uint8Array): `0x${string}` => { + return `0x${Array.from(bytes).map((byte) => byte.toString(16).padStart(2, '0')).join('')}` +} + +export function hexToBigInt(hex: `0x${string}`, opts: { signed?: boolean } = {}): bigint { + const {signed} = opts + const value = BigInt(hex) + if (!signed) return value + + const size = (hex.length - 2) / 2 + const max = (1n << (BigInt(size) * 8n - 1n)) - 1n + if (value <= max) return value + + return value - BigInt(`0x${'f'.padStart(size * 2, 'f')}`) - 1n +} + +function bytesToNumber(bytes: Uint8Array, opts: { signed?: boolean } = {}) { + const value = bytesToHex(bytes) + return Number(hexToBigInt(value, opts)) +} + +function bytesToBool(bytes: Uint8Array, size: number) { + return bytes[size - 1] !== 0 +} + +function bytesToBigInt(bytes: Uint8Array, opts: { signed?: boolean } = {}) { + const value = bytesToHex(bytes) + return hexToBigInt(value, opts) +} diff --git a/evm/evm-typegen/src/encodeAbiParameters.ts b/evm/evm-typegen/src/encodeAbiParameters.ts new file mode 100644 index 000000000..55eedd93c --- /dev/null +++ b/evm/evm-typegen/src/encodeAbiParameters.ts @@ -0,0 +1,318 @@ +import {AbiParameter} from "./decodeAbiParameters"; + +type Hex = `0x${string}` + +export function encodeFunctionData< + const TParams extends readonly AbiParameter[] | readonly unknown[], +>( + signature: Hex, + params: TParams, + values: any[] +) { + return concat([signature, encodeAbiParameters(params, values)]) +} + +/** + * @description Encodes a list of primitive values into an ABI-encoded hex value. + */ +export function encodeAbiParameters< + const TParams extends readonly AbiParameter[] | readonly unknown[], +>( + params: TParams, + values: any[] +): Hex { + // Prepare the parameters to determine dynamic types to encode. + const preparedParams = prepareParams({ + params: params as readonly AbiParameter[], + values, + }) + const data = encodeParams(preparedParams) + if (data.length === 0) return '0x' + return data +} + +///////////////////////////////////////////////////////////////// + +type PreparedParam = { dynamic: boolean; encoded: Hex } + +function prepareParams({ + params, + values, + }: { + params: TParams + values: any[] +}) { + const preparedParams: PreparedParam[] = [] + for (let i = 0; i < params.length; i++) { + preparedParams.push(prepareParam({param: params[i], value: values[i]})) + } + return preparedParams +} + +function prepareParam({ + param, + value, + }: { + param: TParam + value: any[] +}): PreparedParam { + const arrayComponents = getArrayComponents(param.type) + if (arrayComponents) { + const [length, type] = arrayComponents + return encodeArray(value, {length, param: {...param, type}}) + } + if (param.type === 'tuple') { + return encodeTuple(value as any, { + param, + } as any) + } + if (param.type === 'address') { + return encodeAddress(value as unknown as Hex) + } + if (param.type === 'bool') { + return encodeBool(value as unknown as boolean) + } + if (param.type.startsWith('uint') || param.type.startsWith('int')) { + const signed = param.type.startsWith('int') + return encodeNumber(value as unknown as number, signed) + } + if (param.type.startsWith('bytes')) { + return encodeBytes(value as unknown as Hex, {param}) + } + if (param.type === 'string') { + return encodeString(value as unknown as string) + } + throw new Error(`Unknown type: ${param.type}`); +} + +///////////////////////////////////////////////////////////////// + +export function size(value: Hex) { + return Math.ceil((value.length - 2) / 2) +} + +function pad(value: string, size: number = 32): Hex { + return `0x${value.padStart(size * 2, '0')}` +} + +function padRight(value: string, size: number = 32): Hex { + return `0x${value.padEnd(size * 2, '0')}` +} + +function padHex(value: Hex, opts?: {right?: boolean, size?: number}): Hex { + if (opts?.right) { + return padRight(value.slice(2), opts.size) + } + return pad(value.slice(2), opts?.size) +} + +export function numberToHex( + value_: number | bigint, + signed = false +): Hex { + const value = BigInt(value_) + const size = 32 + + let maxValue: bigint | number = 0 + if (typeof value_ === 'number') { + maxValue = BigInt(Number.MAX_SAFE_INTEGER) + } + + const minValue = typeof maxValue === 'bigint' && signed ? -maxValue - 1n : 0 + + if ((maxValue && value > maxValue) || value < minValue) { + throw new Error(`Number "${value}" is not in safe ${signed ? 'signed' : 'unsigned'} integer range [${minValue}, ${maxValue}]`); + } + + const hex = `0x${(signed && value < 0 + ? (1n << BigInt(size * 8)) + BigInt(value) + : value + ).toString(16)}` as Hex + return padHex(hex) as Hex +} + +const concat = (hexes: Hex[]): Hex => `0x${hexes.map((h) => h.slice(2)).join('')}` + +function encodeParams(preparedParams: PreparedParam[]): Hex { + // 1. Compute the size of the static part of the parameters. + let staticSize = 0 + for (let i = 0; i < preparedParams.length; i++) { + const {dynamic, encoded} = preparedParams[i] + if (dynamic) staticSize += 32 + else staticSize += size(encoded) + } + + // 2. Split the parameters into static and dynamic parts. + const staticParams: Hex[] = [] + const dynamicParams: Hex[] = [] + let dynamicSize = 0 + for (let i = 0; i < preparedParams.length; i++) { + const {dynamic, encoded} = preparedParams[i] + if (dynamic) { + staticParams.push(numberToHex(staticSize + dynamicSize)) + dynamicParams.push(encoded) + dynamicSize += size(encoded) + } else { + staticParams.push(encoded) + } + } + + // 3. Concatenate static and dynamic parts. + return concat([...staticParams, ...dynamicParams]) +} + +///////////////////////////////////////////////////////////////// + +function encodeAddress(value: Hex): PreparedParam { + if (!value.match(/^0x[0-9a-fA-F]{40}$/)) throw new Error(`Invalid address: ${value}`); + return {dynamic: false, encoded: padHex(value.toLowerCase() as Hex)} +} + +function encodeArray( + value: any, + { + length, + param, + }: { + length: number | null + param: TParam + }, +): PreparedParam { + const dynamic = length === null + + if (!Array.isArray(value)) throw new Error(`Invalid array: ${value}`); + if (!dynamic && value.length !== length) + throw new Error(`Invalid ${param.type}[${length}] array length: ${value.length}`); + + let dynamicChild = false + const preparedParams: PreparedParam[] = [] + for (let i = 0; i < value.length; i++) { + const preparedParam = prepareParam({param, value: value[i]}) + if (preparedParam.dynamic) dynamicChild = true + preparedParams.push(preparedParam) + } + + if (dynamic || dynamicChild) { + const data = encodeParams(preparedParams) + if (dynamic) { + const length = numberToHex(preparedParams.length) + return { + dynamic: true, + encoded: preparedParams.length > 0 ? concat([length, data]) : length, + } + } + if (dynamicChild) return {dynamic: true, encoded: data} + } + return { + dynamic: false, + encoded: concat(preparedParams.map(({encoded}) => encoded)), + } +} + +function encodeBytes( + value: Hex, + {param}: { param: TParam }, +): PreparedParam { + const [, paramSize] = param.type.split('bytes') + const bytesSize = size(value) + if (!paramSize) { + let value_ = value + // If the size is not divisible by 32 bytes, pad the end + // with empty bytes to the ceiling 32 bytes. + if (bytesSize % 32 !== 0) + value_ = padHex(value_, { + right: true, + size: Math.ceil((value.length - 2) / 2 / 32) * 32, + }) + return { + dynamic: true, + encoded: concat([padHex(numberToHex(bytesSize)), value_]), + } + } + if (bytesSize !== parseInt(paramSize)) + throw new Error(`Invalid bytes${paramSize} length: ${bytesSize}`); + + return {dynamic: false, encoded: padHex(value, {right: true})} +} + +function encodeBool(value: boolean): PreparedParam { + return {dynamic: false, encoded: pad(value ? '1' : '0')} +} + +function encodeNumber( + value: number, + signed: boolean, +): PreparedParam { + return { + dynamic: false, + encoded: numberToHex(value, signed), + } +} + +const hexes = /*#__PURE__*/ Array.from({ length: 256 }, (_v, i) => + i.toString(16).padStart(2, '0'), +) + +export function bytesToHex(value: Uint8Array): Hex { + let string = '' + for (let i = 0; i < value.length; i++) { + string += hexes[value[i]] + } + return `0x${string}` as const +} + +function encodeString(value: string): PreparedParam { + const encoded = new TextEncoder().encode(value) + const partsLength = Math.ceil(encoded.length / 32) + const parts: Hex[] = [] + for (let i = 0; i < partsLength; i++) { + parts.push( + padHex(bytesToHex(encoded.slice(i * 32, (i + 1) * 32)), { + right: true, + }), + ) + } + return { + dynamic: true, + encoded: concat([ + padHex(numberToHex(encoded.length)), + ...parts, + ]), + } +} + +function encodeTuple< + const TParam extends AbiParameter & { components: readonly AbiParameter[] }, +>( + value: any, + {param}: { param: TParam }, +): PreparedParam { + let dynamic = false + const preparedParams: PreparedParam[] = [] + for (let i = 0; i < param.components.length; i++) { + const param_ = param.components[i] + const index = Array.isArray(value) ? i : param_.name + const preparedParam = prepareParam({ + param: param_, + value: (value as any)[index!], + }) + preparedParams.push(preparedParam) + if (preparedParam.dynamic) dynamic = true + } + return { + dynamic, + encoded: dynamic + ? encodeParams(preparedParams) + : concat(preparedParams.map(({encoded}) => encoded)), + } +} + +export function getArrayComponents( + type: string, +): [length: number | null, innerType: string] | undefined { + const matches = type.match(/^(.*)\[(\d+)?]$/) + return matches + ? // Return `null` if the array is dynamic. + [matches[2] ? Number(matches[2]) : null, matches[1]] + : undefined +} diff --git a/evm/evm-typegen/src/main.ts b/evm/evm-typegen/src/main.ts index e8cdb78f5..69f4da1b5 100644 --- a/evm/evm-typegen/src/main.ts +++ b/evm/evm-typegen/src/main.ts @@ -1,5 +1,4 @@ import * as fs from 'fs' -import * as ethers from 'ethers' import path from 'path' import {InvalidArgumentError, program} from 'commander' import {createLogger} from '@subsquid/logger' @@ -8,6 +7,7 @@ import {OutDir} from '@subsquid/util-internal-code-printer' import * as validator from '@subsquid/util-internal-commander' import {Typegen} from './typegen' import {GET} from './util/fetch' +import {isAddress} from "viem"; const LOG = createLogger('sqd:evm-typegen') @@ -15,26 +15,26 @@ const LOG = createLogger('sqd:evm-typegen') runProgram(async function() { program - .description(` + .description(` Generates TypeScript facades for EVM transactions, logs and eth_call queries. The generated facades are assumed to be used by "squids" indexing EVM data. `.trim()) - .name('squid-evm-typegen') - .argument('', 'output directory for generated definitions') - .argument('[abi...]', 'ABI file', specArgument) - .option('--multicall', 'generate facade for MakerDAO multicall contract') - .option( - '--etherscan-api ', - 'etherscan API to fetch contract ABI by a known address', - validator.Url(['http:', 'https:']) - ) - .option( - '--etherscan-api-key ', - 'etherscan API key' - ) - .option('--clean', 'delete output directory before run') - .addHelpText('afterAll', ` + .name('squid-evm-typegen') + .argument('', 'output directory for generated definitions') + .argument('[abi...]', 'ABI file', specArgument) + .option('--multicall', 'generate facade for MakerDAO multicall contract') + .option( + '--etherscan-api ', + 'etherscan API to fetch contract ABI by a known address', + validator.Url(['http:', 'https:']) + ) + .option( + '--etherscan-api-key ', + 'etherscan API key' + ) + .option('--clean', 'delete output directory before run') + .addHelpText('afterAll', ` ABI file can be specified in three ways: 1. as a plain JSON file: @@ -78,6 +78,10 @@ squid-evm-typegen src/abi 0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413#contract dest.add('abi.support.ts', [__dirname, '../src/abi.support.ts']) LOG.info(`saved ${dest.path('abi.support.ts')}`) + dest.add('decodeAbiParameters.ts', [__dirname, '../src/decodeAbiParameters.ts']) + LOG.info(`saved ${dest.path('decodeAbiParameters.ts')}`) + dest.add('encodeAbiParameters.ts', [__dirname, '../src/encodeAbiParameters.ts']) + LOG.info(`saved ${dest.path('encodeAbiParameters.ts')}`) if (opts.multicall) { dest.add('multicall.ts', [__dirname, '../src/multicall.ts']) @@ -86,9 +90,8 @@ squid-evm-typegen src/abi 0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413#contract for (let spec of specs) { LOG.info(`processing ${spec.src}`) - let abi_json = await read(spec, opts) - let abi = new ethers.Interface(abi_json) - new Typegen(dest, abi, spec.name, LOG).generate() + const abi_json = await read(spec, opts) + new Typegen(dest, abi_json, spec.name, LOG).generate() } }, err => LOG.fatal(err)) @@ -159,7 +162,7 @@ function specArgument(value: string, prev?: Spec[]): Spec[] { function parseSpec(spec: string): Spec { let [src, fragment] = splitFragment(spec) if (src.startsWith('0x')) { - if (!ethers.isAddress(src)) throw new InvalidArgumentError('Invalid contract address') + if (!isAddress(src)) throw new InvalidArgumentError('Invalid contract address') return { kind: 'address', src, @@ -167,7 +170,7 @@ function parseSpec(spec: string): Spec { } } else if (src.includes('://')) { let u = new URL( - validator.Url(['http:', 'https:'])(src) + validator.Url(['http:', 'https:'])(src) ) return { kind: 'url', @@ -199,6 +202,6 @@ function basename(file: string): string { let name = path.parse(file).name if (name) return name throw new InvalidArgumentError( - `Can't derive target basename for output files. Use url fragment to specify it, e.g. #erc20` + `Can't derive target basename for output files. Use url fragment to specify it, e.g. #erc20` ) } diff --git a/evm/evm-typegen/src/multicall.ts b/evm/evm-typegen/src/multicall.ts index 4b20dca4f..13a86f6ac 100644 --- a/evm/evm-typegen/src/multicall.ts +++ b/evm/evm-typegen/src/multicall.ts @@ -1,212 +1,212 @@ -import * as ethers from 'ethers' -import {ContractBase, Func} from './abi.support' - - -const abi = new ethers.Interface([ - { - type: 'function', - name: 'aggregate', - stateMutability: 'nonpayable', - inputs: [ - { - name: 'calls', - type: 'tuple[]', - components: [ - {name: 'target', type: 'address'}, - {name: 'callData', type: 'bytes'}, - ] - } - ], - outputs: [ - {name: 'blockNumber', type: 'uint256'}, - {name: 'returnData', type: 'bytes[]'}, - ] - }, - { - name: 'tryAggregate', - type: 'function', - stateMutability: 'nonpayable', - inputs: [ - {name: 'requireSuccess', type: 'bool'}, - { - name: 'calls', - type: 'tuple[]', - components: [ - {name: 'target', type: 'address'}, - {name: 'callData', type: 'bytes'}, - ] - } - ], - outputs: [ - { - name: 'returnData', - type: 'tuple[]', - components: [ - {name: 'success', type: 'bool'}, - {name: 'returnData', type: 'bytes'}, - ] - }, - ] - } -]) - - -type AnyFunc = Func -type Call = [address: string, bytes: string] - - -const aggregate = new Func<[calls: Call[]], {}, {blockNumber: bigint, returnData: string[]}>( - abi, abi.getFunction('aggregate')!.selector -) - - -const try_aggregate = new Func<[requireSuccess: boolean, calls: Array<[target: string, callData: string]>], {}, Array<{success: boolean, returnData: string}>>( - abi, abi.getFunction('tryAggregate')!.selector -) - - -export type MulticallResult = { - success: true - value: T -} | { - success: false - returnData?: string - value?: undefined -} - - -export class Multicall extends ContractBase { - static aggregate = aggregate - static try_aggregate = try_aggregate - - aggregate( - func: Func, - address: string, - calls: Args[], - paging?: number - ): Promise - - aggregate( - func: Func, - calls: [address: string, args: Args][], - paging?: number - ): Promise - - aggregate( - calls: [func: AnyFunc, address: string, args: any[]][], - paging?: number - ): Promise - - async aggregate(...args: any[]): Promise { - let [calls, funcs, page] = this.makeCalls(args) - let size = calls.length - let results = new Array(size) - for (let [from, to] of splitIntoPages(size, page)) { - let {returnData} = await this.eth_call(aggregate, [calls.slice(from, to)]) - for (let i = from; i < to; i++) { - let data = returnData[i - from] - results[i] = funcs[i].decodeResult(data) - } - } - return results - } - - tryAggregate( - func: Func, - address: string, - calls: Args[], - paging?: number - ): Promise[]> - - tryAggregate( - func: Func, - calls: [address: string, args: Args][], - paging?: number - ): Promise[]> - - tryAggregate( - calls: [func: AnyFunc, address: string, args: any[]][], - paging?: number - ): Promise[]> - - async tryAggregate(...args: any[]): Promise { - let [calls, funcs, page] = this.makeCalls(args) - let size = calls.length - let results = new Array(size) - for (let [from, to] of splitIntoPages(size, page)) { - let response = await this.eth_call(try_aggregate, [false, calls.slice(from, to)]) - for (let i = from; i < to; i++) { - let res = response[i - from] - if (res.success) { - try { - results[i] = { - success: true, - value: funcs[i].decodeResult(res.returnData) - } - } catch(err: any) { - results[i] = {success: false, returnData: res.returnData} - } - } else { - results[i] = {success: false} - } - } - } - return results - } - - private makeCalls(args: any[]): [calls: Call[], funcs: AnyFunc[], page: number] { - let page = typeof args[args.length-1] == 'number' ? args.pop()! : Number.MAX_SAFE_INTEGER - switch(args.length) { - case 1: { - let list: [func: AnyFunc, address: string, args: any[]][] = args[0] - let calls = new Array(list.length) - let funcs = new Array(list.length) - for (let i = 0; i < list.length; i++) { - let [func, address, args] = list[i] - calls[i] = [address, func.encode(args)] - funcs[i] = func - } - return [calls, funcs, page] - } - case 2: { - let func: AnyFunc = args[0] - let list: [address: string, args: any[]][] = args[1] - let calls = new Array(list.length) - let funcs = new Array(list.length) - for (let i = 0; i < list.length; i++) { - let [address, args] = list[i] - calls[i] = [address, func.encode(args)] - funcs[i] = func - } - return [calls, funcs, page] - } - case 3: { - let func: AnyFunc = args[0] - let address: string = args[1] - let list: any[][] = args[2] - let calls = new Array(list.length) - let funcs = new Array(list.length) - for (let i = 0; i < list.length; i++) { - let args = list[i] - calls[i] = [address, func.encode(args)] - funcs[i] = func - } - return [calls, funcs, page] - } - default: - throw new Error('unexpected number of arguments') - } - } -} - - -function* splitIntoPages(size: number, page: number): Iterable<[from: number, to: number]> { - let from = 0 - while (size) { - let step = Math.min(page, size) - let to = from + step - yield [from, to] - size -= step - from = to - } -} +// import * as ethers from 'ethers' +// import {ContractBase, Func} from './abi.support' +// +// +// const abi = new ethers.Interface([ +// { +// type: 'function', +// name: 'aggregate', +// stateMutability: 'nonpayable', +// inputs: [ +// { +// name: 'calls', +// type: 'tuple[]', +// components: [ +// {name: 'target', type: 'address'}, +// {name: 'callData', type: 'bytes'}, +// ] +// } +// ], +// outputs: [ +// {name: 'blockNumber', type: 'uint256'}, +// {name: 'returnData', type: 'bytes[]'}, +// ] +// }, +// { +// name: 'tryAggregate', +// type: 'function', +// stateMutability: 'nonpayable', +// inputs: [ +// {name: 'requireSuccess', type: 'bool'}, +// { +// name: 'calls', +// type: 'tuple[]', +// components: [ +// {name: 'target', type: 'address'}, +// {name: 'callData', type: 'bytes'}, +// ] +// } +// ], +// outputs: [ +// { +// name: 'returnData', +// type: 'tuple[]', +// components: [ +// {name: 'success', type: 'bool'}, +// {name: 'returnData', type: 'bytes'}, +// ] +// }, +// ] +// } +// ]) +// +// +// type AnyFunc = Func +// type Call = [address: string, bytes: string] +// +// +// const aggregate = new Func<[calls: Call[]], {}, {blockNumber: bigint, returnData: string[]}>( +// abi, abi.getFunction('aggregate')!.selector +// ) +// +// +// const try_aggregate = new Func<[requireSuccess: boolean, calls: Array<[target: string, callData: string]>], {}, Array<{success: boolean, returnData: string}>>( +// abi, abi.getFunction('tryAggregate')!.selector +// ) +// +// +// export type MulticallResult = { +// success: true +// value: T +// } | { +// success: false +// returnData?: string +// value?: undefined +// } +// +// +// export class Multicall extends ContractBase { +// static aggregate = aggregate +// static try_aggregate = try_aggregate +// +// aggregate( +// func: Func, +// address: string, +// calls: Args[], +// paging?: number +// ): Promise +// +// aggregate( +// func: Func, +// calls: [address: string, args: Args][], +// paging?: number +// ): Promise +// +// aggregate( +// calls: [func: AnyFunc, address: string, args: any[]][], +// paging?: number +// ): Promise +// +// async aggregate(...args: any[]): Promise { +// let [calls, funcs, page] = this.makeCalls(args) +// let size = calls.length +// let results = new Array(size) +// for (let [from, to] of splitIntoPages(size, page)) { +// let {returnData} = await this.eth_call(aggregate, [calls.slice(from, to)]) +// for (let i = from; i < to; i++) { +// let data = returnData[i - from] +// results[i] = funcs[i].decodeResult(data) +// } +// } +// return results +// } +// +// tryAggregate( +// func: Func, +// address: string, +// calls: Args[], +// paging?: number +// ): Promise[]> +// +// tryAggregate( +// func: Func, +// calls: [address: string, args: Args][], +// paging?: number +// ): Promise[]> +// +// tryAggregate( +// calls: [func: AnyFunc, address: string, args: any[]][], +// paging?: number +// ): Promise[]> +// +// async tryAggregate(...args: any[]): Promise { +// let [calls, funcs, page] = this.makeCalls(args) +// let size = calls.length +// let results = new Array(size) +// for (let [from, to] of splitIntoPages(size, page)) { +// let response = await this.eth_call(try_aggregate, [false, calls.slice(from, to)]) +// for (let i = from; i < to; i++) { +// let res = response[i - from] +// if (res.success) { +// try { +// results[i] = { +// success: true, +// value: funcs[i].decodeResult(res.returnData) +// } +// } catch(err: any) { +// results[i] = {success: false, returnData: res.returnData} +// } +// } else { +// results[i] = {success: false} +// } +// } +// } +// return results +// } +// +// private makeCalls(args: any[]): [calls: Call[], funcs: AnyFunc[], page: number] { +// let page = typeof args[args.length-1] == 'number' ? args.pop()! : Number.MAX_SAFE_INTEGER +// switch(args.length) { +// case 1: { +// let list: [func: AnyFunc, address: string, args: any[]][] = args[0] +// let calls = new Array(list.length) +// let funcs = new Array(list.length) +// for (let i = 0; i < list.length; i++) { +// let [func, address, args] = list[i] +// calls[i] = [address, func.encode(args)] +// funcs[i] = func +// } +// return [calls, funcs, page] +// } +// case 2: { +// let func: AnyFunc = args[0] +// let list: [address: string, args: any[]][] = args[1] +// let calls = new Array(list.length) +// let funcs = new Array(list.length) +// for (let i = 0; i < list.length; i++) { +// let [address, args] = list[i] +// calls[i] = [address, func.encode(args)] +// funcs[i] = func +// } +// return [calls, funcs, page] +// } +// case 3: { +// let func: AnyFunc = args[0] +// let address: string = args[1] +// let list: any[][] = args[2] +// let calls = new Array(list.length) +// let funcs = new Array(list.length) +// for (let i = 0; i < list.length; i++) { +// let args = list[i] +// calls[i] = [address, func.encode(args)] +// funcs[i] = func +// } +// return [calls, funcs, page] +// } +// default: +// throw new Error('unexpected number of arguments') +// } +// } +// } +// +// +// function* splitIntoPages(size: number, page: number): Iterable<[from: number, to: number]> { +// let from = 0 +// while (size) { +// let step = Math.min(page, size) +// let to = from + step +// yield [from, to] +// size -= step +// from = to +// } +// } diff --git a/evm/evm-typegen/src/typegen.ts b/evm/evm-typegen/src/typegen.ts index ec0a4ed54..c71017cb5 100644 --- a/evm/evm-typegen/src/typegen.ts +++ b/evm/evm-typegen/src/typegen.ts @@ -1,42 +1,37 @@ -import * as ethers from 'ethers' +import {Abi, AbiEvent, AbiFunction} from 'abitype' import {Logger} from '@subsquid/logger' import {def} from '@subsquid/util-internal' import {FileOutput, OutDir} from '@subsquid/util-internal-code-printer' -import {getFullTupleType, getReturnType, getStructType, getTupleType, getType} from './util/types' +import { + getEventParamTypes, + getFullTupleType, + getReturnType, + getType, + stringifyParams +} from './util/types' +import {toEventHash, toFunctionHash, toFunctionSignature} from "viem"; +type AbiItem = AbiEvent | AbiFunction export class Typegen { private out: FileOutput - constructor(private dest: OutDir, private abi: ethers.Interface, private basename: string, private log: Logger) { + constructor(private dest: OutDir, private abi: Abi, private basename: string, private log: Logger) { this.out = dest.file(basename + '.ts') } generate(): void { - this.out.line("import * as ethers from 'ethers'") this.out.line("import {LogEvent, Func, ContractBase} from './abi.support'") - this.out.line(`import {ABI_JSON} from './${this.basename}.abi'`) this.out.line() - this.out.line("export const abi = new ethers.Interface(ABI_JSON);") this.generateEvents() this.generateFunctions() this.generateContract() - this.writeAbi() this.out.write() this.log.info(`saved ${this.out.file}`) } - private writeAbi() { - let out = this.dest.file(this.basename + '.abi.ts') - let json = this.abi.formatJson() - json = JSON.stringify(JSON.parse(json), null, 4) - out.line(`export const ABI_JSON = ${json}`) - out.write() - this.log.info(`saved ${out.file}`) - } - private generateEvents() { let events = this.getEvents() if (events.length == 0) { @@ -45,8 +40,8 @@ export class Typegen { this.out.line() this.out.block(`export const events =`, () => { for (let e of events) { - this.out.line(`${this.getPropName(e)}: new LogEvent<${getFullTupleType(e.inputs)}>(`) - this.out.indentation(() => this.out.line(`abi, '${e.topicHash}'`)) + this.out.line(`${this.getPropName(e)}: new LogEvent<${getEventParamTypes(e.inputs)}>(`) + this.out.indentation(() => this.out.line(`'${toEventHash(e)}', ${stringifyParams(e.inputs)}`)) this.out.line('),') } }) @@ -60,12 +55,13 @@ export class Typegen { this.out.line() this.out.block(`export const functions =`, () => { for (let f of functions) { - let sighash = f.selector - let pArgs = getTupleType(f.inputs) - let pArgStruct = getStructType(f.inputs) + let sighash = toFunctionHash(f).slice(0, 10) + let pArgs = getFullTupleType(f.inputs) let pResult = getReturnType(f.outputs) - this.out.line(`${this.getPropName(f)}: new Func<${pArgs}, ${pArgStruct}, ${pResult}>(`) - this.out.indentation(() => this.out.line(`abi, '${sighash}'`)) + this.out.line(`${this.getPropName(f)}: new Func<${pArgs}, ${pResult}>(`) + this.out.indentation(() => this.out.line(`'${sighash}',`)) + this.out.indentation(() => this.out.line(`${stringifyParams(f.inputs)},`)) + this.out.indentation(() => this.out.line(`${stringifyParams(f.outputs)}`)) this.out.line('),') } }) @@ -76,7 +72,7 @@ export class Typegen { this.out.block(`export class Contract extends ContractBase`, () => { let functions = this.getFunctions() for (let f of functions) { - if (f.constant && f.outputs?.length) { + if ((f.stateMutability === 'pure' || f.stateMutability === 'view') && f.outputs?.length) { this.out.line() let argNames = f.inputs.map((a, idx) => a.name || `arg${idx}`) let args = f.inputs.map((a, idx) => `${argNames[idx]}: ${getType(a)}`).join(', ') @@ -88,7 +84,7 @@ export class Typegen { }) } - private getRef(item: ethers.EventFragment | ethers.FunctionFragment): string { + private getRef(item: AbiItem): string { let key = this.getPropName(item) if (key[0] == "'") { return `[${key}]` @@ -97,19 +93,19 @@ export class Typegen { } } - private getPropName(item: ethers.EventFragment | ethers.FunctionFragment): string { + private getPropName(item: AbiItem): string { if (this.getOverloads(item) == 1) { return item.name } else { - return `'${item.format('sighash')}'` + return `'${toFunctionSignature(item)}'` } } - private getOverloads(item: ethers.EventFragment | ethers.FunctionFragment): number { - if (item instanceof ethers.EventFragment) { - return this.eventOverloads()[item.name] - } else { + private getOverloads(item: AbiItem): number { + if (item.type === 'function') { return this.functionOverloads()[item.name] + } else { + return this.eventOverloads()[item.name] } } @@ -132,12 +128,12 @@ export class Typegen { } @def - private getFunctions(): ethers.FunctionFragment[] { - return this.abi.fragments.filter(f => f.type === 'function') as ethers.FunctionFragment[] + private getFunctions() { + return this.abi.filter(f => f.type === 'function') as AbiFunction[] } @def - private getEvents(): ethers.EventFragment[] { - return this.abi.fragments.filter(f => f.type === 'event') as ethers.EventFragment[] + private getEvents() { + return this.abi.filter(f => f.type === 'event') as AbiEvent[] } } diff --git a/evm/evm-typegen/src/util/types.ts b/evm/evm-typegen/src/util/types.ts index 0c0d82212..93cee20ad 100644 --- a/evm/evm-typegen/src/util/types.ts +++ b/evm/evm-typegen/src/util/types.ts @@ -1,15 +1,38 @@ import assert from 'assert' -import type {ParamType} from 'ethers' +import {AbiEventParameter, AbiParameter, parseAbiParameter} from "abitype"; +import {hasDynamicChild} from "../decodeAbiParameters"; +function parseArray(param: AbiParameter): { baseType: string, arrayChildren: AbiParameter } | undefined { + let match = param.type.match(/^(.*)\[(\d*)]$/) + if (match) { + const baseType = match[1] + if (baseType === 'tuple' && 'components' in param) { + const arrayChildren = { + type: 'tuple', + components: param.components + } + return { baseType, arrayChildren } + } + const arrayChildren = parseAbiParameter(baseType) + return { baseType, arrayChildren } + } + return undefined +} // taken from: https://github.com/ethers-io/ethers.js/blob/948f77050dae884fe88932fd88af75560aac9d78/packages/cli/src.ts/typescript.ts#L10 -export function getType(param: ParamType): string { - if (param.baseType === 'array') { - assert(param.arrayChildren != null, 'Missing children for array type') - return 'Array<' + getType(param.arrayChildren) + '>' +export function getType(param: AbiParameter): string { + try { + const array = parseArray(param) + if (array) { + assert(array.arrayChildren != null, 'Missing children for array type') + return 'Array<' + getType(array.arrayChildren) + '>' + } + } catch (e) { + console.log(param) + throw e; } - if (param.baseType === 'tuple') { + if (param.type === 'tuple' && 'components' in param) { assert(param.components != null, 'Missing components for tuple type') return getFullTupleType(param.components) } @@ -35,18 +58,22 @@ export function getType(param: ParamType): string { } -export function getFullTupleType(params: ReadonlyArray): string { - let tuple = getTupleType(params) - let struct = getStructType(params) - if (struct == '{}') { - return tuple - } else { - return `(${tuple} & ${struct})` - } +export function getFullTupleType(params: readonly AbiParameter[]): string { + return `[${params.map(p => `['${p.name}',${getType(p)}]`).join(',')}]` +} + +export function getEventParamTypes(param: readonly AbiEventParameter[]): string { + return getFullTupleType(param.map(p => p.indexed ? hasDynamicChild(p) ? { + ...p, + type: 'bytes32' + } : p : p)) } +export function stringifyParams(inputs: readonly AbiParameter[]): string { + return JSON.stringify(inputs.map(({internalType, ...rest}) => rest)) +} -export function getTupleType(params: ReadonlyArray): string { +export function getTupleType(params: readonly AbiParameter[]): string { return '[' + params.map(p => { return p.name ? `${p.name}: ${getType(p)}` : `_: ${getType(p)}` }).join(', ') + ']' @@ -54,7 +81,7 @@ export function getTupleType(params: ReadonlyArray): string { // https://github.com/ethers-io/ethers.js/blob/278f84174409b470fa7992e1f8b5693e6e5d2dac/src.ts/abi/coders/tuple.ts#L36 -export function getStructType(params: ReadonlyArray): string { +export function getStructType(params: readonly AbiParameter[]): string { let array: any = [] let counts: Record = {} for (let p of params) { @@ -62,11 +89,11 @@ export function getStructType(params: ReadonlyArray): string { counts[p.name] = (counts[p.name] || 0) + 1 } } - let fields = params.filter(p => counts[p.name] == 1) + let fields = params.filter(p => counts[p.name ?? ''] == 1) return '{' + fields.map(f => `${f.name}: ${getType(f)}`).join(', ') + '}' } -export function getReturnType(outputs: ReadonlyArray) { +export function getReturnType(outputs: readonly AbiParameter[]) { return outputs.length == 1 ? getType(outputs[0]) : getFullTupleType(outputs) } diff --git a/evm/evm-typegen/test/decodeAbiParameters.test.ts b/evm/evm-typegen/test/decodeAbiParameters.test.ts new file mode 100644 index 000000000..efb987a2a --- /dev/null +++ b/evm/evm-typegen/test/decodeAbiParameters.test.ts @@ -0,0 +1,43 @@ +import {describe, expect, it} from "vitest"; +import {encodeAbiParameters} from "viem"; +import {decodeAbiParameters} from "../src/decodeAbiParameters"; + +describe("decodeAbiParameters", () => { + const t = (type: string) => ({type}) + + it("decodes static types", () => { + const types = [t('uint8'), t('bool'), t('bool'), t('uint256'), t('address'), t('int128')]; + const values = [2137, true, false, 10n ** 20n, '0x9401e5e6564db35c0f86573a9828df69fc778af1', -(10n ** 20n)]; + const data = encodeAbiParameters(types, values) + expect(decodeAbiParameters(types, data)).toStrictEqual(values) + }) + + it("decodes dynamic types", () => { + const types = [t('bytes'), t('string'), t('bytes4')]; + const values = ['0x1234', 'hello', '0xdeadbeef']; + const data = encodeAbiParameters(types, values) + expect(decodeAbiParameters(types, data)).toStrictEqual(values) + }) + + it("decodes nested tuples", () => { + const types = [{ + type: 'tuple', + components: [ + t('uint8'), + t('bool'), + { + type: 'tuple', + components: [ + t('string'), + ] + }, + t('address'), + ] + }]; + const values = [ + [1, true, ['hello'], '0x9401e5e6564db35c0f86573a9828df69fc778af1'], + ]; + const data = encodeAbiParameters(types, values) + expect(decodeAbiParameters(types, data)).toStrictEqual(values) + }) +}) diff --git a/evm/evm-typegen/test/encodeAbiParameters.test.ts b/evm/evm-typegen/test/encodeAbiParameters.test.ts new file mode 100644 index 000000000..18187b659 --- /dev/null +++ b/evm/evm-typegen/test/encodeAbiParameters.test.ts @@ -0,0 +1,39 @@ +import {describe, expect, it} from "vitest"; +import {decodeAbiParameters} from "../src/decodeAbiParameters"; +import {encodeAbiParameters as check} from "viem"; +import {encodeAbiParameters} from "../src/encodeAbiParameters"; + +describe("decodeAbiParameters", () => { + const t = (type: string) => ({type}) + + it("encodes strings", () => { + const types = [t('string')]; + const values = ['hello'.repeat(100)]; + const data = encodeAbiParameters(types, values) + expect(data).toBe(check(types, values)) + expect(decodeAbiParameters(types, data)).toStrictEqual(values) + }) + + it("decodes nested tuples", () => { + const types = [{ + type: 'tuple', + components: [ + t('uint8'), + t('bool'), + { + type: 'tuple', + components: [ + t('string'), + ] + }, + t('address'), + ] + }]; + const values = [ + [1, true, ['hello'], '0x9401e5e6564db35c0f86573a9828df69fc778af1'], + ]; + const data = encodeAbiParameters(types, values) + expect(data).toBe(check(types, values)) + expect(decodeAbiParameters(types, data)).toStrictEqual(values) + }) +}) diff --git a/evm/evm-typegen/test/logEvent.test.ts b/evm/evm-typegen/test/logEvent.test.ts new file mode 100644 index 000000000..c97fed9d8 --- /dev/null +++ b/evm/evm-typegen/test/logEvent.test.ts @@ -0,0 +1,127 @@ +import {describe, expect, it} from "vitest"; +import {encodeAbiParameters, encodeEventTopics, parseAbiItem, toEventSelector} from "viem"; +import {LogEvent} from "../src/abi.support"; + +describe("LogEvent", () => { + function createEvent(event: any) { + const topic = toEventSelector(event); + return new LogEvent(topic, event.inputs) + } + + function expectToContain(value: any, expected: any) { + if ('length' in expected) { + expect(value).toHaveLength(expected.length) + } + for (let i in expected) { + expect(value[i], `at index ${i}`).toStrictEqual(expected[i]) + } + } + + it('decodes params of simple event', () => { + const event = parseAbiItem('event Transfer(address indexed from, uint256 value, uint8 flag, bool success, address indexed to)'); + + const logEvent = createEvent< + [['from', string], ['value', bigint], ['flag', number], ['success', boolean], ['to', string]] + >(event); + const topics = encodeEventTopics({ + abi: [event], + args: { + from: '0x9401e5e6564db35c0f86573a9828df69fc778af1', + to: '0x1001e5e6564db35c0f86573a9828df69fc778af1', + } + }) + const data = encodeAbiParameters(event.inputs.slice(1, -1), [100n, 15, true]) + const t = logEvent.decode({topics, data}); + expectToContain(t, [ + '0x9401e5e6564db35c0f86573a9828df69fc778af1', + 100n, + 15, + true, + '0x1001e5e6564db35c0f86573a9828df69fc778af1', + ]) + expectToContain(t, { + value: 100n, + flag: 15, + success: true, + from: '0x9401e5e6564db35c0f86573a9828df69fc778af1', + to: '0x1001e5e6564db35c0f86573a9828df69fc778af1' + }) + }); + + it('decodes dynamic length params', () => { + const event = parseAbiItem('event SomethingBig(string a, string indexed indexedString, bytes b, bytes indexed indexedBytes, bytes4 indexed c)'); + + const logEvent = createEvent< + [['a', string], ['b', Uint8Array], ['c', string]] + >(event); + const topics = encodeEventTopics({ + abi: [event], + args: { + indexedString: 'world', + indexedBytes: '0x9876', + c: '0xdeadbeef' + } + }) + const data = encodeAbiParameters([event.inputs[0], event.inputs[2]], ['hello', '0x1234']); + const t = logEvent.decode({topics, data}); + expectToContain(t, [ + 'hello', + '0x8452c9b9140222b08593a26daa782707297be9f7b3e8281d7b4974769f19afd0', + '0x1234', + '0xe2f884a85df4ad7a73f7b7e4091f440e1597c9a36083444607c9e9d9163aeed2', + '0xdeadbeef', + ]) + expectToContain(t, { + a: 'hello', + indexedString: '0x8452c9b9140222b08593a26daa782707297be9f7b3e8281d7b4974769f19afd0', + b: '0x1234', + indexedBytes: '0xe2f884a85df4ad7a73f7b7e4091f440e1597c9a36083444607c9e9d9163aeed2', + c: '0xdeadbeef' + }) + }); + + it('decodes tuples', () => { + const event = parseAbiItem([ + 'event SomeEvent(Str foo)', + 'struct Str { string a; bool b; string c; Other d; }', + 'struct Other { uint256 bar; }', + ]); + + const logEvent = createEvent< + [['foo', { + a: string, + b: boolean, + c: string, + d: { + bar: bigint + } + }]] + >(event); + const topics = encodeEventTopics({ + abi: [event], + }) + const data = encodeAbiParameters(event.inputs, [{ + a: 'hello', + b: true, + c: 'world', + d: {bar: 100n} + }]); + const t = logEvent.decode({topics, data}); + expectToContain(t, [{ + a: 'hello', + b: true, + c: 'world', + d: {bar: 100n} + }]) + expectToContain(t, { + foo: { + a: 'hello', + b: true, + c: 'world', + d: { + bar: 100n + } + } + }) + }); +}) diff --git a/evm/evm-typegen/tsconfig.build.json b/evm/evm-typegen/tsconfig.build.json new file mode 100644 index 000000000..3a56256a1 --- /dev/null +++ b/evm/evm-typegen/tsconfig.build.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "include": ["src"], + "exclude": [ + "node_modules", + "test" + ], +} diff --git a/evm/evm-typegen/tsconfig.json b/evm/evm-typegen/tsconfig.json index deee9f66b..2ca9519df 100644 --- a/evm/evm-typegen/tsconfig.json +++ b/evm/evm-typegen/tsconfig.json @@ -14,8 +14,8 @@ "emitDecoratorMetadata": true, "skipLibCheck": true }, - "include": ["src"], + "include": ["src", "test"], "exclude": [ - "node_modules" - ] + "node_modules", + ], } diff --git a/test/erc20-transfers/package.json b/test/erc20-transfers/package.json index 295f44c3d..2e427aa98 100644 --- a/test/erc20-transfers/package.json +++ b/test/erc20-transfers/package.json @@ -16,7 +16,7 @@ "typeorm": "^0.3.17" }, "devDependencies": { - "@subsquid/evm-typegen": "^3.3.0", + "@subsquid/evm-typegen": "../../evm/evm-typegen", "@subsquid/typeorm-codegen": "^1.3.3", "@types/node": "^18.18.14", "typescript": "~5.3.2" diff --git a/test/erc20-transfers/src/abi/abi.support.ts b/test/erc20-transfers/src/abi/abi.support.ts index c9cb14fa8..7acfec7d3 100644 --- a/test/erc20-transfers/src/abi/abi.support.ts +++ b/test/erc20-transfers/src/abi/abi.support.ts @@ -1,51 +1,141 @@ -import assert from 'assert' -import * as ethers from 'ethers' +import {type AbiParameter, decodeAbiParameters, hasDynamicChild} from './decodeAbiParameters' +import {encodeFunctionData} from "./encodeAbiParameters"; +type Hex = `0x${string}` -export interface LogRecord { +export interface EventRecord { topics: string[] data: string } +export type LogRecord = EventRecord + +type EventType = { + type: 'tuple' + internalType?: string + indexed?: boolean + name: string + components: EventType[] +} | { + type: string + internalType?: string + indexed?: boolean + name: string +} +type SecondElements = T extends [] ? [] : T extends [[any, infer U], ...infer Tail extends [any, any][]] ? [U, ...SecondElements] : never +type Args = { + [K in T[number] as K[0]]: K[1] +} & SecondElements -export class LogEvent { - private fragment: ethers.EventFragment +function assertIsHex(val: unknown): asserts val is Hex { + if (typeof val !== 'string' || !val.startsWith('0x')) { + throw new Error('Not a hex string') + } +} - constructor(private abi: ethers.Interface, public readonly topic: string) { - let fragment = abi.getEvent(topic) - assert(fragment != null, 'Missing fragment') - this.fragment = fragment +export class LogEvent { + private indexedArgs: ((AbiParameter & {index: number}) | null)[] = []; + private nonIndexedArgs: (AbiParameter & {index: number})[] = []; + + constructor(public readonly topic: string, readonly types: readonly EventType[]) { + assertIsHex(topic) + let index = 0; + for (const type of types) { + if (!type.indexed) { + this.nonIndexedArgs.push({ + ...type, + index + }) + } else { + if (hasDynamicChild(type)) { + this.indexedArgs.push({ + ...type, + type: 'bytes32', + index + }) + } else { + this.indexedArgs.push({ + ...type, + index + }) + } + } + index++; + } } - decode(rec: LogRecord): Args { - return this.abi.decodeEventLog(this.fragment, rec.data, rec.topics) as any as Args + is(rec: EventRecord): boolean { + return rec.topics[0] === this.topic + } + + decode(rec: EventRecord) { + if (!this.is(rec)) { + throw new Error('Invalid event record') + } + assertIsHex(rec.data) + const result: any = [] + const parsedData = decodeAbiParameters(this.nonIndexedArgs, rec.data) + for (let i = 0; i < parsedData.length; i++) { + if (this.nonIndexedArgs[i].name) { + result[this.nonIndexedArgs[i].name!] = parsedData[i] + } + result[this.nonIndexedArgs[i].index] = parsedData[i] + } + rec.topics.slice(1).forEach((topic, i) => { + const type = this.indexedArgs[i] + if (type) { + assertIsHex(topic) + const [parsedData] = decodeAbiParameters([type], topic) + if (type.name) { + result[type.name] = parsedData + } + result[type.index] = parsedData + } + }) + return result as Args } } +export interface FuncRecord { + sighash?: string + input: string +} -export class Func { - private fragment: ethers.FunctionFragment +export class Func { + public readonly sighash: Hex + constructor(sighash: string, private readonly args: AbiParameter[], private readonly result: AbiParameter[]) { + assertIsHex(sighash) + this.sighash = sighash + } - constructor(private abi: ethers.Interface, public readonly sighash: string) { - let fragment = abi.getFunction(sighash) - assert(fragment != null, 'Missing fragment') - this.fragment = fragment + is(rec: FuncRecord): boolean { + let sighash = rec.sighash ? rec.sighash : rec.input.slice(0, 10) + return sighash === this.sighash } - decode(input: ethers.BytesLike): Args & FieldArgs { - return this.abi.decodeFunctionData(this.fragment, input) as any as Args & FieldArgs + decode(input: string): Args + decode(rec: FuncRecord): Args + decode(inputOrRec: string | FuncRecord): Args { + const input = typeof inputOrRec === 'string' ? inputOrRec : inputOrRec.input + assertIsHex(input) + if (!this.is({input})) { + throw new Error('Invalid event record') + } + + return decodeAbiParameters(this.args, `0x${input.slice(10)}`) as Args } - encode(args: Args): string { - return this.abi.encodeFunctionData(this.fragment, args) + encode(...args: SecondElements) { + return encodeFunctionData(this.sighash, this.args, args) } - decodeResult(output: ethers.BytesLike): Result { - const decoded = this.abi.decodeFunctionResult(this.fragment, output) + decodeResult(output: string): Result { + assertIsHex(output) + const decoded = decodeAbiParameters(this.result, output) return decoded.length > 1 ? decoded : decoded[0] } - tryDecodeResult(output: ethers.BytesLike): Result | undefined { + tryDecodeResult(output: string): Result | undefined { try { return this.decodeResult(output) } catch(err: any) { @@ -91,7 +181,7 @@ export interface Chain { export class ContractBase { private readonly _chain: Chain private readonly blockHeight: number - readonly address: string + readonly address: Hex constructor(ctx: BlockContext, address: string) constructor(ctx: ChainContext, block: Block, address: string) @@ -99,18 +189,19 @@ export class ContractBase { this._chain = ctx._chain if (typeof blockOrAddress === 'string') { this.blockHeight = ctx.block.height - this.address = ethers.getAddress(blockOrAddress) + this.address = blockOrAddress as Hex } else { if (address == null) { throw new Error('missing contract address') } this.blockHeight = blockOrAddress.height - this.address = ethers.getAddress(address) + this.address = address as Hex } + assertIsHex(this.address) } - async eth_call(func: Func, args: Args): Promise { - let data = func.encode(args) + async eth_call(func: Func, args: SecondElements): Promise { + let data = func.encode(...args) let result = await this._chain.client.call('eth_call', [ {to: this.address, data}, '0x'+this.blockHeight.toString(16) diff --git a/test/erc20-transfers/src/abi/decodeAbiParameters.ts b/test/erc20-transfers/src/abi/decodeAbiParameters.ts new file mode 100644 index 000000000..83f32a254 --- /dev/null +++ b/test/erc20-transfers/src/abi/decodeAbiParameters.ts @@ -0,0 +1,360 @@ +export interface AbiParameter { + name?: string + type: string +} + +class Cursor { + bytes: Uint8Array + position: number + positionReadCount: Map + recursiveReadLimit: number + + constructor(bytes: Uint8Array) { + this.bytes = bytes + this.position = 0 + this.positionReadCount = new Map() + this.recursiveReadLimit = 8_192 + } + + inspectBytes(length: number) { + return this.bytes.subarray(this.position, this.position + length) + } + public readBytes(length: number, size?: number) { + const value = this.inspectBytes(length) + this.position += size ?? length + return value + } + public setPosition(position: number) { + const oldPosition = this.position + this.position = position + return () => (this.position = oldPosition) + } +} + +export function decodeAbiParameters( + params: AbiParameter[], + data: `0x${string}`, +) { + const bytes = Buffer.from(data.slice(2), 'hex') + const cursor = new Cursor(bytes) + + let consumed = 0 + const values = [] + for (let i = 0; i < params.length; ++i) { + const param = params[i] + cursor.setPosition(consumed) + const [data, consumed_] = decodeParameter(cursor, param, { + staticPosition: 0, + }) + consumed += consumed_ + values.push(data) + } + return values +} + +export function getArrayComponents( + type: string, +): [length: number | null, innerType: string] | undefined { + const matches = type.match(/^(.*)\[(\d+)?]$/) + return matches + ? // Return `null` if the array is dynamic. + [matches[2] ? Number(matches[2]) : null, matches[1]] + : undefined +} + +function decodeParameter( + cursor: Cursor, + param: AbiParameter, + { staticPosition }: { staticPosition: number }, +): readonly [any, number] { + const arrayComponents = getArrayComponents(param.type) + if (arrayComponents) { + const [length, type] = arrayComponents + return decodeArray(cursor, { ...param, type }, { length, staticPosition }) + } + if (param.type === 'tuple') + return decodeTuple(cursor, param as TupleAbiParameter, { staticPosition }) + + if (param.type === 'address') return decodeAddress(cursor) + if (param.type === 'bool') return decodeBool(cursor) + if (param.type.startsWith('bytes')) + return decodeBytes(cursor, param, { staticPosition }) + if (param.type.startsWith('uint') || param.type.startsWith('int')) + return decodeNumber(cursor, param) + if (param.type === 'string') return decodeString(cursor, { staticPosition }) + throw new Error(`Unknown type: ${param.type}`) +} + +//////////////////////////////////////////////////////////////////// +// Type Decoders + +const sizeOfLength = 32 +const sizeOfOffset = 32 + +function decodeAddress(cursor: Cursor) { + const value = cursor.readBytes(sizeOfOffset) + return [bytesToHex(value.slice(-20)), sizeOfLength] as const +} + +function decodeArray( + cursor: Cursor, + param: AbiParameter, + { length, staticPosition }: { length: number | null; staticPosition: number }, +) { + // If the length of the array is not known in advance (dynamic array), + // this means we will need to wonder off to the pointer and decode. + if (!length) { + // Dealing with a dynamic type, so get the offset of the array data. + const offset = bytesToNumber(cursor.readBytes(sizeOfOffset)) + + // Start is the static position of current slot + offset. + const start = staticPosition + offset + const startOfData = start + sizeOfLength + + // Get the length of the array from the offset. + cursor.setPosition(start) + const length = bytesToNumber(cursor.readBytes(sizeOfLength)) + + // Check if the array has any dynamic children. + const dynamicChild = hasDynamicChild(param) + + let consumed = 0 + const value: unknown[] = [] + for (let i = 0; i < length; ++i) { + // If any of the children is dynamic, then all elements will be offset pointer, thus size of one slot (32 bytes). + // Otherwise, elements will be the size of their encoding (consumed bytes). + cursor.setPosition(startOfData + (dynamicChild ? i * 32 : consumed)) + const [data, consumed_] = decodeParameter(cursor, param, { + staticPosition: startOfData, + }) + consumed += consumed_ + value.push(data) + } + + // As we have gone wondering, restore to the original position + next slot. + cursor.setPosition(staticPosition + 32) + return [value, 32] as const + } + + // If the length of the array is known in advance, + // and the length of an element deeply nested in the array is not known, + // we need to decode the offset of the array data. + if (hasDynamicChild(param)) { + // Dealing with dynamic types, so get the offset of the array data. + const offset = bytesToNumber(cursor.readBytes(sizeOfOffset)) + + // Start is the static position of current slot + offset. + const start = staticPosition + offset + + const value: unknown[] = [] + for (let i = 0; i < length; ++i) { + // Move cursor along to the next slot (next offset pointer). + cursor.setPosition(start + i * 32) + const [data] = decodeParameter(cursor, param, { + staticPosition: start, + }) + value.push(data) + } + + // As we have gone wondering, restore to the original position + next slot. + cursor.setPosition(staticPosition + 32) + return [value, 32] as const + } + + // If the length of the array is known in advance and the array is deeply static, + // then we can just decode each element in sequence. + let consumed = 0 + const value: unknown[] = [] + for (let i = 0; i < length; ++i) { + const [data, consumed_] = decodeParameter(cursor, param, { + staticPosition: staticPosition + consumed, + }) + consumed += consumed_ + value.push(data) + } + return [value, consumed] as const +} + +function decodeBool(cursor: Cursor) { + return [bytesToBool(cursor.readBytes(32), 32), 32] as const +} + +function decodeBytes( + cursor: Cursor, + param: AbiParameter, + { staticPosition }: { staticPosition: number }, +) { + const [_, size] = param.type.split('bytes') + if (!size) { + // Dealing with dynamic types, so get the offset of the bytes data. + const offset = bytesToNumber(cursor.readBytes(32)) + + // Set position of the cursor to start of bytes data. + cursor.setPosition(staticPosition + offset) + + const length = bytesToNumber(cursor.readBytes(32)) + + // If there is no length, we have zero data. + if (length === 0) { + // As we have gone wondering, restore to the original position + next slot. + cursor.setPosition(staticPosition + 32) + return ['0x', 32] as const + } + + const data = cursor.readBytes(length) + + // As we have gone wondering, restore to the original position + next slot. + cursor.setPosition(staticPosition + 32) + return [bytesToHex(data), 32] as const + } + + const value = bytesToHex(cursor.readBytes(parseInt(size), 32)) + return [value, 32] as const +} + +function decodeNumber(cursor: Cursor, param: AbiParameter) { + const signed = param.type.startsWith('int') + const size = parseInt(param.type.split('int')[1] || '256') + const value = cursor.readBytes(32) + return [ + size > 48 + ? bytesToBigInt(value, { signed }) + : bytesToNumber(value, { signed }), + 32, + ] as const +} + +type TupleAbiParameter = AbiParameter & { components: readonly AbiParameter[] } + +function decodeTuple( + cursor: Cursor, + param: TupleAbiParameter, + { staticPosition }: { staticPosition: number }, +) { + // Tuples can have unnamed components (i.e. they are arrays), so we must + // determine whether the tuple is named or unnamed. In the case of a named + // tuple, the value will be an object where each property is the name of the + // component. In the case of an unnamed tuple, the value will be an array. + const hasUnnamedChild = + param.components.length === 0 || param.components.some(({ name }) => !name) + + // Initialize the value to an object or an array, depending on whether the + // tuple is named or unnamed. + const value: any = hasUnnamedChild ? [] : {} + let consumed = 0 + + // If the tuple has a dynamic child, we must first decode the offset to the + // tuple data. + if (hasDynamicChild(param)) { + // Dealing with dynamic types, so get the offset of the tuple data. + const offset = bytesToNumber(cursor.readBytes(sizeOfOffset)) + + // Start is the static position of referencing slot + offset. + const start = staticPosition + offset + + for (let i = 0; i < param.components.length; ++i) { + const component = param.components[i] + cursor.setPosition(start + consumed) + const [data, consumed_] = decodeParameter(cursor, component, { + staticPosition: start, + }) + consumed += consumed_ + value[hasUnnamedChild ? i : component?.name!] = data + } + + // As we have gone wondering, restore to the original position + next slot. + cursor.setPosition(staticPosition + 32) + return [value, 32] as const + } + + // If the tuple has static children, we can just decode each component + // in sequence. + for (let i = 0; i < param.components.length; ++i) { + const component = param.components[i] + const [data, consumed_] = decodeParameter(cursor, component, { + staticPosition, + }) + value[hasUnnamedChild ? i : component?.name!] = data + consumed += consumed_ + } + return [value, consumed] as const +} + +function decodeString( + cursor: Cursor, + { staticPosition }: { staticPosition: number }, +) { + // Get offset to start of string data. + const offset = bytesToNumber(cursor.readBytes(32)) + + // Start is the static position of current slot + offset. + const start = staticPosition + offset + cursor.setPosition(start) + + const length = bytesToNumber(cursor.readBytes(32)) + + // If there is no length, we have zero data (empty string). + if (length === 0) { + cursor.setPosition(staticPosition + 32) + return ['', 32] as const + } + + const data = cursor.readBytes(length, 32) + const value = new TextDecoder().decode(data) + + // As we have gone wondering, restore to the original position + next slot. + cursor.setPosition(staticPosition + 32) + + return [value, 32] as const +} + +export function hasDynamicChild(param: AbiParameter) { + const { type } = param + if (type === 'string') return true + if (type === 'bytes') return true + if (type.endsWith('[]')) return true + + if (type === 'tuple') return (param as any).components?.some(hasDynamicChild) + + const arrayComponents = getArrayComponents(param.type) + if ( + arrayComponents && + hasDynamicChild({ ...param, type: arrayComponents[1] } as AbiParameter) + ) + return true + + return false +} + +//////////////////////////////////////////////////////////////////// +/// Bytes parsing + +const bytesToHex = (bytes: Uint8Array): `0x${string}` => { + return `0x${Array.from(bytes).map((byte) => byte.toString(16).padStart(2, '0')).join('')}` +} + +export function hexToBigInt(hex: `0x${string}`, opts: { signed?: boolean } = {}): bigint { + const {signed} = opts + const value = BigInt(hex) + if (!signed) return value + + const size = (hex.length - 2) / 2 + const max = (1n << (BigInt(size) * 8n - 1n)) - 1n + if (value <= max) return value + + return value - BigInt(`0x${'f'.padStart(size * 2, 'f')}`) - 1n +} + +function bytesToNumber(bytes: Uint8Array, opts: { signed?: boolean } = {}) { + const value = bytesToHex(bytes) + return Number(hexToBigInt(value, opts)) +} + +function bytesToBool(bytes: Uint8Array, size: number) { + return bytes[size - 1] !== 0 +} + +function bytesToBigInt(bytes: Uint8Array, opts: { signed?: boolean } = {}) { + const value = bytesToHex(bytes) + return hexToBigInt(value, opts) +} diff --git a/test/erc20-transfers/src/abi/encodeAbiParameters.ts b/test/erc20-transfers/src/abi/encodeAbiParameters.ts new file mode 100644 index 000000000..55eedd93c --- /dev/null +++ b/test/erc20-transfers/src/abi/encodeAbiParameters.ts @@ -0,0 +1,318 @@ +import {AbiParameter} from "./decodeAbiParameters"; + +type Hex = `0x${string}` + +export function encodeFunctionData< + const TParams extends readonly AbiParameter[] | readonly unknown[], +>( + signature: Hex, + params: TParams, + values: any[] +) { + return concat([signature, encodeAbiParameters(params, values)]) +} + +/** + * @description Encodes a list of primitive values into an ABI-encoded hex value. + */ +export function encodeAbiParameters< + const TParams extends readonly AbiParameter[] | readonly unknown[], +>( + params: TParams, + values: any[] +): Hex { + // Prepare the parameters to determine dynamic types to encode. + const preparedParams = prepareParams({ + params: params as readonly AbiParameter[], + values, + }) + const data = encodeParams(preparedParams) + if (data.length === 0) return '0x' + return data +} + +///////////////////////////////////////////////////////////////// + +type PreparedParam = { dynamic: boolean; encoded: Hex } + +function prepareParams({ + params, + values, + }: { + params: TParams + values: any[] +}) { + const preparedParams: PreparedParam[] = [] + for (let i = 0; i < params.length; i++) { + preparedParams.push(prepareParam({param: params[i], value: values[i]})) + } + return preparedParams +} + +function prepareParam({ + param, + value, + }: { + param: TParam + value: any[] +}): PreparedParam { + const arrayComponents = getArrayComponents(param.type) + if (arrayComponents) { + const [length, type] = arrayComponents + return encodeArray(value, {length, param: {...param, type}}) + } + if (param.type === 'tuple') { + return encodeTuple(value as any, { + param, + } as any) + } + if (param.type === 'address') { + return encodeAddress(value as unknown as Hex) + } + if (param.type === 'bool') { + return encodeBool(value as unknown as boolean) + } + if (param.type.startsWith('uint') || param.type.startsWith('int')) { + const signed = param.type.startsWith('int') + return encodeNumber(value as unknown as number, signed) + } + if (param.type.startsWith('bytes')) { + return encodeBytes(value as unknown as Hex, {param}) + } + if (param.type === 'string') { + return encodeString(value as unknown as string) + } + throw new Error(`Unknown type: ${param.type}`); +} + +///////////////////////////////////////////////////////////////// + +export function size(value: Hex) { + return Math.ceil((value.length - 2) / 2) +} + +function pad(value: string, size: number = 32): Hex { + return `0x${value.padStart(size * 2, '0')}` +} + +function padRight(value: string, size: number = 32): Hex { + return `0x${value.padEnd(size * 2, '0')}` +} + +function padHex(value: Hex, opts?: {right?: boolean, size?: number}): Hex { + if (opts?.right) { + return padRight(value.slice(2), opts.size) + } + return pad(value.slice(2), opts?.size) +} + +export function numberToHex( + value_: number | bigint, + signed = false +): Hex { + const value = BigInt(value_) + const size = 32 + + let maxValue: bigint | number = 0 + if (typeof value_ === 'number') { + maxValue = BigInt(Number.MAX_SAFE_INTEGER) + } + + const minValue = typeof maxValue === 'bigint' && signed ? -maxValue - 1n : 0 + + if ((maxValue && value > maxValue) || value < minValue) { + throw new Error(`Number "${value}" is not in safe ${signed ? 'signed' : 'unsigned'} integer range [${minValue}, ${maxValue}]`); + } + + const hex = `0x${(signed && value < 0 + ? (1n << BigInt(size * 8)) + BigInt(value) + : value + ).toString(16)}` as Hex + return padHex(hex) as Hex +} + +const concat = (hexes: Hex[]): Hex => `0x${hexes.map((h) => h.slice(2)).join('')}` + +function encodeParams(preparedParams: PreparedParam[]): Hex { + // 1. Compute the size of the static part of the parameters. + let staticSize = 0 + for (let i = 0; i < preparedParams.length; i++) { + const {dynamic, encoded} = preparedParams[i] + if (dynamic) staticSize += 32 + else staticSize += size(encoded) + } + + // 2. Split the parameters into static and dynamic parts. + const staticParams: Hex[] = [] + const dynamicParams: Hex[] = [] + let dynamicSize = 0 + for (let i = 0; i < preparedParams.length; i++) { + const {dynamic, encoded} = preparedParams[i] + if (dynamic) { + staticParams.push(numberToHex(staticSize + dynamicSize)) + dynamicParams.push(encoded) + dynamicSize += size(encoded) + } else { + staticParams.push(encoded) + } + } + + // 3. Concatenate static and dynamic parts. + return concat([...staticParams, ...dynamicParams]) +} + +///////////////////////////////////////////////////////////////// + +function encodeAddress(value: Hex): PreparedParam { + if (!value.match(/^0x[0-9a-fA-F]{40}$/)) throw new Error(`Invalid address: ${value}`); + return {dynamic: false, encoded: padHex(value.toLowerCase() as Hex)} +} + +function encodeArray( + value: any, + { + length, + param, + }: { + length: number | null + param: TParam + }, +): PreparedParam { + const dynamic = length === null + + if (!Array.isArray(value)) throw new Error(`Invalid array: ${value}`); + if (!dynamic && value.length !== length) + throw new Error(`Invalid ${param.type}[${length}] array length: ${value.length}`); + + let dynamicChild = false + const preparedParams: PreparedParam[] = [] + for (let i = 0; i < value.length; i++) { + const preparedParam = prepareParam({param, value: value[i]}) + if (preparedParam.dynamic) dynamicChild = true + preparedParams.push(preparedParam) + } + + if (dynamic || dynamicChild) { + const data = encodeParams(preparedParams) + if (dynamic) { + const length = numberToHex(preparedParams.length) + return { + dynamic: true, + encoded: preparedParams.length > 0 ? concat([length, data]) : length, + } + } + if (dynamicChild) return {dynamic: true, encoded: data} + } + return { + dynamic: false, + encoded: concat(preparedParams.map(({encoded}) => encoded)), + } +} + +function encodeBytes( + value: Hex, + {param}: { param: TParam }, +): PreparedParam { + const [, paramSize] = param.type.split('bytes') + const bytesSize = size(value) + if (!paramSize) { + let value_ = value + // If the size is not divisible by 32 bytes, pad the end + // with empty bytes to the ceiling 32 bytes. + if (bytesSize % 32 !== 0) + value_ = padHex(value_, { + right: true, + size: Math.ceil((value.length - 2) / 2 / 32) * 32, + }) + return { + dynamic: true, + encoded: concat([padHex(numberToHex(bytesSize)), value_]), + } + } + if (bytesSize !== parseInt(paramSize)) + throw new Error(`Invalid bytes${paramSize} length: ${bytesSize}`); + + return {dynamic: false, encoded: padHex(value, {right: true})} +} + +function encodeBool(value: boolean): PreparedParam { + return {dynamic: false, encoded: pad(value ? '1' : '0')} +} + +function encodeNumber( + value: number, + signed: boolean, +): PreparedParam { + return { + dynamic: false, + encoded: numberToHex(value, signed), + } +} + +const hexes = /*#__PURE__*/ Array.from({ length: 256 }, (_v, i) => + i.toString(16).padStart(2, '0'), +) + +export function bytesToHex(value: Uint8Array): Hex { + let string = '' + for (let i = 0; i < value.length; i++) { + string += hexes[value[i]] + } + return `0x${string}` as const +} + +function encodeString(value: string): PreparedParam { + const encoded = new TextEncoder().encode(value) + const partsLength = Math.ceil(encoded.length / 32) + const parts: Hex[] = [] + for (let i = 0; i < partsLength; i++) { + parts.push( + padHex(bytesToHex(encoded.slice(i * 32, (i + 1) * 32)), { + right: true, + }), + ) + } + return { + dynamic: true, + encoded: concat([ + padHex(numberToHex(encoded.length)), + ...parts, + ]), + } +} + +function encodeTuple< + const TParam extends AbiParameter & { components: readonly AbiParameter[] }, +>( + value: any, + {param}: { param: TParam }, +): PreparedParam { + let dynamic = false + const preparedParams: PreparedParam[] = [] + for (let i = 0; i < param.components.length; i++) { + const param_ = param.components[i] + const index = Array.isArray(value) ? i : param_.name + const preparedParam = prepareParam({ + param: param_, + value: (value as any)[index!], + }) + preparedParams.push(preparedParam) + if (preparedParam.dynamic) dynamic = true + } + return { + dynamic, + encoded: dynamic + ? encodeParams(preparedParams) + : concat(preparedParams.map(({encoded}) => encoded)), + } +} + +export function getArrayComponents( + type: string, +): [length: number | null, innerType: string] | undefined { + const matches = type.match(/^(.*)\[(\d+)?]$/) + return matches + ? // Return `null` if the array is dynamic. + [matches[2] ? Number(matches[2]) : null, matches[1]] + : undefined +} diff --git a/test/erc20-transfers/src/abi/erc20.abi.ts b/test/erc20-transfers/src/abi/erc20.abi.ts deleted file mode 100644 index c813cc1f3..000000000 --- a/test/erc20-transfers/src/abi/erc20.abi.ts +++ /dev/null @@ -1,210 +0,0 @@ -export const ABI_JSON = [ - { - "type": "function", - "name": "name", - "constant": true, - "stateMutability": "view", - "payable": false, - "inputs": [], - "outputs": [ - { - "type": "string" - } - ] - }, - { - "type": "function", - "name": "approve", - "constant": false, - "payable": false, - "inputs": [ - { - "type": "address", - "name": "_spender" - }, - { - "type": "uint256", - "name": "_value" - } - ], - "outputs": [ - { - "type": "bool" - } - ] - }, - { - "type": "function", - "name": "totalSupply", - "constant": true, - "stateMutability": "view", - "payable": false, - "inputs": [], - "outputs": [ - { - "type": "uint256" - } - ] - }, - { - "type": "function", - "name": "transferFrom", - "constant": false, - "payable": false, - "inputs": [ - { - "type": "address", - "name": "_from" - }, - { - "type": "address", - "name": "_to" - }, - { - "type": "uint256", - "name": "_value" - } - ], - "outputs": [ - { - "type": "bool" - } - ] - }, - { - "type": "function", - "name": "decimals", - "constant": true, - "stateMutability": "view", - "payable": false, - "inputs": [], - "outputs": [ - { - "type": "uint8" - } - ] - }, - { - "type": "function", - "name": "balanceOf", - "constant": true, - "stateMutability": "view", - "payable": false, - "inputs": [ - { - "type": "address", - "name": "_owner" - } - ], - "outputs": [ - { - "type": "uint256", - "name": "balance" - } - ] - }, - { - "type": "function", - "name": "symbol", - "constant": true, - "stateMutability": "view", - "payable": false, - "inputs": [], - "outputs": [ - { - "type": "string" - } - ] - }, - { - "type": "function", - "name": "transfer", - "constant": false, - "payable": false, - "inputs": [ - { - "type": "address", - "name": "_to" - }, - { - "type": "uint256", - "name": "_value" - } - ], - "outputs": [ - { - "type": "bool" - } - ] - }, - { - "type": "function", - "name": "allowance", - "constant": true, - "stateMutability": "view", - "payable": false, - "inputs": [ - { - "type": "address", - "name": "_owner" - }, - { - "type": "address", - "name": "_spender" - } - ], - "outputs": [ - { - "type": "uint256" - } - ] - }, - { - "type": "fallback", - "stateMutability": "payable" - }, - { - "type": "event", - "anonymous": false, - "name": "Approval", - "inputs": [ - { - "type": "address", - "name": "owner", - "indexed": true - }, - { - "type": "address", - "name": "spender", - "indexed": true - }, - { - "type": "uint256", - "name": "value", - "indexed": false - } - ] - }, - { - "type": "event", - "anonymous": false, - "name": "Transfer", - "inputs": [ - { - "type": "address", - "name": "from", - "indexed": true - }, - { - "type": "address", - "name": "to", - "indexed": true - }, - { - "type": "uint256", - "name": "value", - "indexed": false - } - ] - } -] diff --git a/test/erc20-transfers/src/abi/erc20.ts b/test/erc20-transfers/src/abi/erc20.ts index 674cfb880..ec40e316f 100644 --- a/test/erc20-transfers/src/abi/erc20.ts +++ b/test/erc20-transfers/src/abi/erc20.ts @@ -1,45 +1,60 @@ -import * as ethers from 'ethers' import {LogEvent, Func, ContractBase} from './abi.support' -import {ABI_JSON} from './erc20.abi' -export const abi = new ethers.Interface(ABI_JSON); export const events = { - Approval: new LogEvent<([owner: string, spender: string, value: bigint] & {owner: string, spender: string, value: bigint})>( - abi, '0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925' + Approval: new LogEvent<[['owner',string],['spender',string],['value',bigint]]>( + '0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925', [{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}] ), - Transfer: new LogEvent<([from: string, to: string, value: bigint] & {from: string, to: string, value: bigint})>( - abi, '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef' + Transfer: new LogEvent<[['from',string],['to',string],['value',bigint]]>( + '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef', [{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}] ), } export const functions = { - name: new Func<[], {}, string>( - abi, '0x06fdde03' + name: new Func<[], string>( + '0x06fdde03', + [], + [{"name":"","type":"string"}] ), - approve: new Func<[_spender: string, _value: bigint], {_spender: string, _value: bigint}, boolean>( - abi, '0x095ea7b3' + approve: new Func<[['_spender',string],['_value',bigint]], boolean>( + '0x095ea7b3', + [{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}], + [{"name":"","type":"bool"}] ), - totalSupply: new Func<[], {}, bigint>( - abi, '0x18160ddd' + totalSupply: new Func<[], bigint>( + '0x18160ddd', + [], + [{"name":"","type":"uint256"}] ), - transferFrom: new Func<[_from: string, _to: string, _value: bigint], {_from: string, _to: string, _value: bigint}, boolean>( - abi, '0x23b872dd' + transferFrom: new Func<[['_from',string],['_to',string],['_value',bigint]], boolean>( + '0x23b872dd', + [{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}], + [{"name":"","type":"bool"}] ), - decimals: new Func<[], {}, number>( - abi, '0x313ce567' + decimals: new Func<[], number>( + '0x313ce567', + [], + [{"name":"","type":"uint8"}] ), - balanceOf: new Func<[_owner: string], {_owner: string}, bigint>( - abi, '0x70a08231' + balanceOf: new Func<[['_owner',string]], bigint>( + '0x70a08231', + [{"name":"_owner","type":"address"}], + [{"name":"balance","type":"uint256"}] ), - symbol: new Func<[], {}, string>( - abi, '0x95d89b41' + symbol: new Func<[], string>( + '0x95d89b41', + [], + [{"name":"","type":"string"}] ), - transfer: new Func<[_to: string, _value: bigint], {_to: string, _value: bigint}, boolean>( - abi, '0xa9059cbb' + transfer: new Func<[['_to',string],['_value',bigint]], boolean>( + '0xa9059cbb', + [{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}], + [{"name":"","type":"bool"}] ), - allowance: new Func<[_owner: string, _spender: string], {_owner: string, _spender: string}, bigint>( - abi, '0xdd62ed3e' + allowance: new Func<[['_owner',string],['_spender',string]], bigint>( + '0xdd62ed3e', + [{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}], + [{"name":"","type":"uint256"}] ), } diff --git a/test/erc20-transfers/src/processor.ts b/test/erc20-transfers/src/processor.ts index a446b5148..c528850b1 100644 --- a/test/erc20-transfers/src/processor.ts +++ b/test/erc20-transfers/src/processor.ts @@ -27,7 +27,7 @@ processor.run(new TypeormDatabase({supportHotBlocks: true}), async ctx => { for (let block of ctx.blocks) { for (let log of block.logs) { - if (log.address == CONTRACT && log.topics[0] === erc20.events.Transfer.topic) { + if (log.address == CONTRACT && erc20.events.Transfer.is(log)) { let {from, to, value} = erc20.events.Transfer.decode(log) transfers.push(new Transfer({ id: log.id, From abff66edb5813a3472ec6d902eecd7ceae1efb7f Mon Sep 17 00:00:00 2001 From: ivan Date: Thu, 29 Feb 2024 11:24:11 +0100 Subject: [PATCH 02/12] Load source files from etherscan and generate devdocs --- evm/evm-typegen/package.json | 4 +- evm/evm-typegen/src/devdoc.ts | 109 ++++++++++++++++++++++++++++ evm/evm-typegen/src/main.ts | 57 ++++++++++++--- evm/evm-typegen/src/typegen.ts | 15 +++- evm/evm-typegen/test/devdoc.test.ts | 30 ++++++++ 5 files changed, 203 insertions(+), 12 deletions(-) create mode 100644 evm/evm-typegen/src/devdoc.ts create mode 100644 evm/evm-typegen/test/devdoc.test.ts diff --git a/evm/evm-typegen/package.json b/evm/evm-typegen/package.json index dd1bdf06b..bd31a4333 100644 --- a/evm/evm-typegen/package.json +++ b/evm/evm-typegen/package.json @@ -24,7 +24,8 @@ "@subsquid/util-internal": "^3.0.0", "@subsquid/util-internal-code-printer": "^1.2.2", "@subsquid/util-internal-commander": "^1.3.2", - "commander": "^11.1.0" + "commander": "^11.1.0", + "solc": "^0.8.24" }, "peerDependencies": { "abitype": "^1.0.0", @@ -33,6 +34,7 @@ }, "devDependencies": { "@types/node": "^18.18.14", + "types-solc": "^1.0.1", "typescript": "~5.3.2", "vitest": "^1.3.1" } diff --git a/evm/evm-typegen/src/devdoc.ts b/evm/evm-typegen/src/devdoc.ts new file mode 100644 index 000000000..7a5ba6235 --- /dev/null +++ b/evm/evm-typegen/src/devdoc.ts @@ -0,0 +1,109 @@ +const solc = require("solc"); + +interface Devdoc { + details: string; + params: { + [name: string]: string; + }; + returns: { + [name: string]: string; + }; +} + +function formatDevdoc(devdoc: Devdoc) { + if (!devdoc.details && !devdoc.params && !devdoc.returns) { + return undefined; + } + const details = devdoc.details ? ` * ${devdoc.details}\n` : ""; + const params = devdoc.params + ? `${Object.entries(devdoc.params ?? []) + .map(([name, details]) => ` * @param ${name} ${details}`) + .join("\n")}\n` + : ""; + const returns = devdoc.returns + ? `${Object.entries(devdoc.returns ?? []) + .map( + ([name, details]) => + ` * @return ${name.match(/^_\d+$/) ? "" : name + " "}${details}` + ) + .join("\n")}\n` + : ""; + return `/** +${details}${params}${returns} */`; +} + +export async function devdoc( + source: string | object, + settings: any, + compilerVersion = 'latest' +) { + let sources: { + [name: string]: { + content: string; + }; + }; + if (typeof source === "string") { + sources = { + "Contract.sol": { + content: source, + }, + }; + } else { + sources = source as any; + } + const input = { + language: "Solidity", + sources, + settings: { + ...settings, + outputSelection: { + "*": { + "*": ["devdoc"], + }, + }, + }, + }; + + const output: any = await new Promise((resolve) => + solc.loadRemoteVersion(compilerVersion, (err: any, solcSnapshot: any) => { + if (err) { + console.log(err); + resolve(undefined); + } + const output = JSON.parse(solcSnapshot.compile(JSON.stringify(input))); + resolve(output); + }) + ); + + if (!output) { + return { + methods: {}, + events: {}, + }; + } + + const getDocs = (get: "events" | "methods") => + Object.values(output.contracts) + .map((x: any) => Object.values(x)) + .flatMap((x: any) => x?.[0]?.devdoc?.[get] ?? []) + .reduce((acc: any, x: any) => ({ + ...acc, + ...x, + })); + const events = getDocs('events') + const methods = getDocs('methods') + const formattedMethods = Object.fromEntries( + Object.entries(methods) + .map(([name, doc]) => [name, formatDevdoc(doc as any)]) + .filter(([_, doc]) => !!doc) + ) + const formattedEvents = Object.fromEntries( + Object.entries(events) + .map(([name, doc]) => [name, formatDevdoc(doc as any)]) + .filter(([_, doc]) => !!doc) + ) + return { + methods: formattedMethods, + events: formattedEvents, + } +} diff --git a/evm/evm-typegen/src/main.ts b/evm/evm-typegen/src/main.ts index 69f4da1b5..c5cd21c6c 100644 --- a/evm/evm-typegen/src/main.ts +++ b/evm/evm-typegen/src/main.ts @@ -8,6 +8,7 @@ import * as validator from '@subsquid/util-internal-commander' import {Typegen} from './typegen' import {GET} from './util/fetch' import {isAddress} from "viem"; +import {devdoc} from "./devdoc"; const LOG = createLogger('sqd:evm-typegen') @@ -90,15 +91,26 @@ squid-evm-typegen src/abi 0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413#contract for (let spec of specs) { LOG.info(`processing ${spec.src}`) - const abi_json = await read(spec, opts) - new Typegen(dest, abi_json, spec.name, LOG).generate() + const { abi, source } = await read(spec, opts); + let docs = {methods: {}, events: {}} + if (source) { + try { + docs = await devdoc(source.sources, source.settings, source.compiler) + } catch {} + } + new Typegen(dest, abi, spec.name, docs, LOG).generate() } }, err => LOG.fatal(err)) -async function read(spec: Spec, options?: {etherscanApi?: string, etherscanApiKey?: string}): Promise { +async function read(spec: Spec, options?: {etherscanApi?: string, etherscanApiKey?: string}): Promise<{ + abi: any, + source?: any +}> { if (spec.kind == 'address') { - return fetchFromEtherscan(spec.src, options?.etherscanApi, options?.etherscanApiKey) + const abi = await fetchAbiFromEtherscan(spec.src, options?.etherscanApi, options?.etherscanApiKey) + const source = await fetchSourceFromEtherscan(spec.src, options?.etherscanApi, options?.etherscanApiKey) + return {abi, source} } let abi: any if (spec.kind == 'url') { @@ -107,23 +119,24 @@ async function read(spec: Spec, options?: {etherscanApi?: string, etherscanApiKe abi = JSON.parse(fs.readFileSync(spec.src, 'utf-8')) } if (Array.isArray(abi)) { - return abi + return {abi} } else if (Array.isArray(abi?.abi)) { - return abi.abi + return { + abi: abi.abi + } } else { throw new Error('Unrecognized ABI format') } } -async function fetchFromEtherscan(address: string, api?: string, apiKey?: string): Promise { - api = api || 'https://api.etherscan.io/' - let url = new URL('api?module=contract&action=getabi', api) +async function fetchFromEtherscan(action: 'getabi' | 'getsourcecode', address: string, api = 'https://api.etherscan.io/', apiKey?: string) { + let url = new URL(`api?module=contract&action=${action}`, api) url.searchParams.set('address', address) if (apiKey) { url.searchParams.set('apiKey', apiKey) } - let response: {status: string, result: string} + let response: {status: string, result: any} let attempts = 0 while (true) { response = await GET(url.toString()) @@ -136,6 +149,13 @@ async function fetchFromEtherscan(address: string, api?: string, apiKey?: string break } } + + return response +} + +async function fetchAbiFromEtherscan(address: string, api?: string, apiKey?: string): Promise { + const response = await fetchFromEtherscan('getabi', address, api, apiKey) + if (response.status == '1') { return JSON.parse(response.result) } else { @@ -143,6 +163,23 @@ async function fetchFromEtherscan(address: string, api?: string, apiKey?: string } } +async function fetchSourceFromEtherscan(address: string, api?: string, apiKey?: string): Promise<{ + sources: any + compiler: string +} | undefined> { + const response = await fetchFromEtherscan('getsourcecode', address, api, apiKey) + const compiler = response.result[0].CompilerVersion + if (response.status == '1') { + return { + ...JSON.parse(((response as any).result[0].SourceCode.replace('{{', '{').replace('}}', '}'))), + compiler + } + } else { + LOG.warn(`Failed to fetch contract source from ${api}: ${response.result}`) + return undefined + } +} + interface Spec { kind: 'address' | 'url' | 'file' diff --git a/evm/evm-typegen/src/typegen.ts b/evm/evm-typegen/src/typegen.ts index c71017cb5..7bbb35973 100644 --- a/evm/evm-typegen/src/typegen.ts +++ b/evm/evm-typegen/src/typegen.ts @@ -13,10 +13,15 @@ import {toEventHash, toFunctionHash, toFunctionSignature} from "viem"; type AbiItem = AbiEvent | AbiFunction +type Docs = { + methods: Record + events: Record +} + export class Typegen { private out: FileOutput - constructor(private dest: OutDir, private abi: Abi, private basename: string, private log: Logger) { + constructor(private dest: OutDir, private abi: Abi, private basename: string, private docs: Docs, private log: Logger) { this.out = dest.file(basename + '.ts') } @@ -40,6 +45,10 @@ export class Typegen { this.out.line() this.out.block(`export const events =`, () => { for (let e of events) { + if (this.docs.events[toFunctionSignature(e)]) { + this.docs.events[toFunctionSignature(e)] + .split('\n').forEach(l => this.out.line(l)) + } this.out.line(`${this.getPropName(e)}: new LogEvent<${getEventParamTypes(e.inputs)}>(`) this.out.indentation(() => this.out.line(`'${toEventHash(e)}', ${stringifyParams(e.inputs)}`)) this.out.line('),') @@ -58,6 +67,10 @@ export class Typegen { let sighash = toFunctionHash(f).slice(0, 10) let pArgs = getFullTupleType(f.inputs) let pResult = getReturnType(f.outputs) + if (this.docs.methods[toFunctionSignature(f)]) { + this.docs.methods[toFunctionSignature(f)] + .split('\n').forEach(l => this.out.line(l)) + } this.out.line(`${this.getPropName(f)}: new Func<${pArgs}, ${pResult}>(`) this.out.indentation(() => this.out.line(`'${sighash}',`)) this.out.indentation(() => this.out.line(`${stringifyParams(f.inputs)},`)) diff --git a/evm/evm-typegen/test/devdoc.test.ts b/evm/evm-typegen/test/devdoc.test.ts new file mode 100644 index 000000000..a2dd6cc21 --- /dev/null +++ b/evm/evm-typegen/test/devdoc.test.ts @@ -0,0 +1,30 @@ +import {describe, expect, it} from "vitest"; +import {devdoc} from "../src/devdoc"; + +describe("Devdoc", () => { + const exampleContract = ` + contract Test { + /// @dev This is a test + event Test(uint256 a, uint256 b); + /** + * @dev Returns a + b + * @param a The first number + * @param b The second number + * @return The sum of a and b + */ + function plus(uint256 a, uint256 b) public returns (uint256) {} + } + ` + it("formats devdoc correctly", async () => { + const {methods, events} = await devdoc(exampleContract, {}) + expect(methods['plus(uint256,uint256)']).toBe('/**\n' + + ' * Returns a + b\n' + + ' * @param a The first number\n' + + ' * @param b The second number\n' + + ' * @return The sum of a and b\n' + + '*/') + expect(events['Test(uint256,uint256)']).toBe('/**\n' + + ' * This is a test\n' + + '*/') + }) +}) From b084489ba602626c3c3616b32fafe4b3678959b4 Mon Sep 17 00:00:00 2001 From: ivan Date: Thu, 29 Feb 2024 11:26:21 +0100 Subject: [PATCH 03/12] Remove console.logs --- evm/evm-typegen/src/devdoc.ts | 1 - evm/evm-typegen/src/util/types.ts | 1 - 2 files changed, 2 deletions(-) diff --git a/evm/evm-typegen/src/devdoc.ts b/evm/evm-typegen/src/devdoc.ts index 7a5ba6235..09ab3835d 100644 --- a/evm/evm-typegen/src/devdoc.ts +++ b/evm/evm-typegen/src/devdoc.ts @@ -67,7 +67,6 @@ export async function devdoc( const output: any = await new Promise((resolve) => solc.loadRemoteVersion(compilerVersion, (err: any, solcSnapshot: any) => { if (err) { - console.log(err); resolve(undefined); } const output = JSON.parse(solcSnapshot.compile(JSON.stringify(input))); diff --git a/evm/evm-typegen/src/util/types.ts b/evm/evm-typegen/src/util/types.ts index 93cee20ad..9e9617b59 100644 --- a/evm/evm-typegen/src/util/types.ts +++ b/evm/evm-typegen/src/util/types.ts @@ -28,7 +28,6 @@ export function getType(param: AbiParameter): string { return 'Array<' + getType(array.arrayChildren) + '>' } } catch (e) { - console.log(param) throw e; } From 1a4351453096fb2e97bda3dd0b34e24c19842a8b Mon Sep 17 00:00:00 2001 From: ivan Date: Sun, 3 Mar 2024 23:09:19 +0100 Subject: [PATCH 04/12] Extract types in generated files, rewrite multicall contract --- evm/evm-typegen/src/abi.support.ts | 52 ++-- evm/evm-typegen/src/devdoc.ts | 23 +- evm/evm-typegen/src/main.ts | 22 +- evm/evm-typegen/src/multicall.ts | 428 +++++++++++++++-------------- evm/evm-typegen/src/typegen.ts | 36 ++- evm/evm-typegen/src/util/types.ts | 38 +-- 6 files changed, 322 insertions(+), 277 deletions(-) diff --git a/evm/evm-typegen/src/abi.support.ts b/evm/evm-typegen/src/abi.support.ts index 7acfec7d3..bcffd7247 100644 --- a/evm/evm-typegen/src/abi.support.ts +++ b/evm/evm-typegen/src/abi.support.ts @@ -1,8 +1,15 @@ -import {type AbiParameter, decodeAbiParameters, hasDynamicChild} from './decodeAbiParameters' +import {decodeAbiParameters, hasDynamicChild} from './decodeAbiParameters' import {encodeFunctionData} from "./encodeAbiParameters"; type Hex = `0x${string}` +export interface AbiParameter { + name?: string + type: string, + components?: AbiParameter[] + internalType?: string +} + export interface EventRecord { topics: string[] data: string @@ -22,18 +29,13 @@ type EventType = { name: string } -type SecondElements = T extends [] ? [] : T extends [[any, infer U], ...infer Tail extends [any, any][]] ? [U, ...SecondElements] : never -type Args = { - [K in T[number] as K[0]]: K[1] -} & SecondElements - function assertIsHex(val: unknown): asserts val is Hex { if (typeof val !== 'string' || !val.startsWith('0x')) { throw new Error('Not a hex string') } } -export class LogEvent { +export class LogEvent { private indexedArgs: ((AbiParameter & {index: number}) | null)[] = []; private nonIndexedArgs: (AbiParameter & {index: number})[] = []; @@ -68,7 +70,7 @@ export class LogEvent { return rec.topics[0] === this.topic } - decode(rec: EventRecord) { + decode(rec: EventRecord): TEventArgs { if (!this.is(rec)) { throw new Error('Invalid event record') } @@ -78,8 +80,9 @@ export class LogEvent { for (let i = 0; i < parsedData.length; i++) { if (this.nonIndexedArgs[i].name) { result[this.nonIndexedArgs[i].name!] = parsedData[i] + } else { + result[`_${this.nonIndexedArgs[i].index}`] = parsedData[i] } - result[this.nonIndexedArgs[i].index] = parsedData[i] } rec.topics.slice(1).forEach((topic, i) => { const type = this.indexedArgs[i] @@ -88,11 +91,12 @@ export class LogEvent { const [parsedData] = decodeAbiParameters([type], topic) if (type.name) { result[type.name] = parsedData + } else { + result[`_${type.index}`] = parsedData } - result[type.index] = parsedData } }) - return result as Args + return result } } @@ -101,7 +105,7 @@ export interface FuncRecord { input: string } -export class Func { +export class Func { public readonly sighash: Hex constructor(sighash: string, private readonly args: AbiParameter[], private readonly result: AbiParameter[]) { assertIsHex(sighash) @@ -113,29 +117,37 @@ export class Func { return sighash === this.sighash } - decode(input: string): Args - decode(rec: FuncRecord): Args - decode(inputOrRec: string | FuncRecord): Args { + decode(input: string): TFunctionArgs + decode(rec: FuncRecord): TFunctionArgs + decode(inputOrRec: string | FuncRecord): TFunctionArgs { const input = typeof inputOrRec === 'string' ? inputOrRec : inputOrRec.input assertIsHex(input) if (!this.is({input})) { throw new Error('Invalid event record') } - return decodeAbiParameters(this.args, `0x${input.slice(10)}`) as Args + const decodedResult = decodeAbiParameters(this.args, `0x${input.slice(10)}`) + return this.toNamedArgs(decodedResult) as TFunctionArgs } - encode(...args: SecondElements) { + encode(...args: TFunctionArgs[keyof TFunctionArgs][]) { return encodeFunctionData(this.sighash, this.args, args) } - decodeResult(output: string): Result { + decodeResult(output: string): TResult { assertIsHex(output) const decoded = decodeAbiParameters(this.result, output) return decoded.length > 1 ? decoded : decoded[0] } - tryDecodeResult(output: string): Result | undefined { + private toNamedArgs(values: any[]) { + return Object.fromEntries(this.args.map((arg, i) => { + const name = arg.name || `_${i}` + return [name, values[i]] as const + })) + } + + tryDecodeResult(output: string): TResult | undefined { try { return this.decodeResult(output) } catch(err: any) { @@ -200,7 +212,7 @@ export class ContractBase { assertIsHex(this.address) } - async eth_call(func: Func, args: SecondElements): Promise { + async eth_call(func: Func, args: TFunctionArgs[keyof TFunctionArgs][]): Promise { let data = func.encode(...args) let result = await this._chain.client.call('eth_call', [ {to: this.address, data}, diff --git a/evm/evm-typegen/src/devdoc.ts b/evm/evm-typegen/src/devdoc.ts index 09ab3835d..1255f5e49 100644 --- a/evm/evm-typegen/src/devdoc.ts +++ b/evm/evm-typegen/src/devdoc.ts @@ -35,7 +35,7 @@ ${details}${params}${returns} */`; export async function devdoc( source: string | object, settings: any, - compilerVersion = 'latest' + compilerVersion = "latest" ) { let sources: { [name: string]: { @@ -85,24 +85,27 @@ export async function devdoc( Object.values(output.contracts) .map((x: any) => Object.values(x)) .flatMap((x: any) => x?.[0]?.devdoc?.[get] ?? []) - .reduce((acc: any, x: any) => ({ - ...acc, - ...x, - })); - const events = getDocs('events') - const methods = getDocs('methods') + .reduce( + (acc: any, x: any) => ({ + ...acc, + ...x, + }), + {} + ); + const events = getDocs("events"); + const methods = getDocs("methods"); const formattedMethods = Object.fromEntries( Object.entries(methods) .map(([name, doc]) => [name, formatDevdoc(doc as any)]) .filter(([_, doc]) => !!doc) - ) + ); const formattedEvents = Object.fromEntries( Object.entries(events) .map(([name, doc]) => [name, formatDevdoc(doc as any)]) .filter(([_, doc]) => !!doc) - ) + ); return { methods: formattedMethods, events: formattedEvents, - } + }; } diff --git a/evm/evm-typegen/src/main.ts b/evm/evm-typegen/src/main.ts index c5cd21c6c..7ddc6737c 100644 --- a/evm/evm-typegen/src/main.ts +++ b/evm/evm-typegen/src/main.ts @@ -96,7 +96,9 @@ squid-evm-typegen src/abi 0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413#contract if (source) { try { docs = await devdoc(source.sources, source.settings, source.compiler) - } catch {} + } catch (e: any) { + LOG.warn(e.message) + } } new Typegen(dest, abi, spec.name, docs, LOG).generate() } @@ -109,8 +111,13 @@ async function read(spec: Spec, options?: {etherscanApi?: string, etherscanApiKe }> { if (spec.kind == 'address') { const abi = await fetchAbiFromEtherscan(spec.src, options?.etherscanApi, options?.etherscanApiKey) - const source = await fetchSourceFromEtherscan(spec.src, options?.etherscanApi, options?.etherscanApiKey) - return {abi, source} + try { + const source = await fetchSourceFromEtherscan(spec.src, options?.etherscanApi, options?.etherscanApiKey) + return {abi, source} + } catch (e: any) { + LOG.warn(`Failed to fetch contract source from etherscan: ${e.message}`) + return {abi} + } } let abi: any if (spec.kind == 'url') { @@ -170,8 +177,15 @@ async function fetchSourceFromEtherscan(address: string, api?: string, apiKey?: const response = await fetchFromEtherscan('getsourcecode', address, api, apiKey) const compiler = response.result[0].CompilerVersion if (response.status == '1') { + const SourceCode = response.result[0].SourceCode + if (SourceCode.startsWith('{')) { + return { + ...JSON.parse(SourceCode.replace('{{', '{').replace('}}', '}')), + compiler + } + } return { - ...JSON.parse(((response as any).result[0].SourceCode.replace('{{', '{').replace('}}', '}'))), + sources: { [(response as any)?.[0]?.result?.ContractName || 'Contract.sol']: { content: SourceCode } }, compiler } } else { diff --git a/evm/evm-typegen/src/multicall.ts b/evm/evm-typegen/src/multicall.ts index 13a86f6ac..7e190d539 100644 --- a/evm/evm-typegen/src/multicall.ts +++ b/evm/evm-typegen/src/multicall.ts @@ -1,212 +1,216 @@ -// import * as ethers from 'ethers' -// import {ContractBase, Func} from './abi.support' -// -// -// const abi = new ethers.Interface([ -// { -// type: 'function', -// name: 'aggregate', -// stateMutability: 'nonpayable', -// inputs: [ -// { -// name: 'calls', -// type: 'tuple[]', -// components: [ -// {name: 'target', type: 'address'}, -// {name: 'callData', type: 'bytes'}, -// ] -// } -// ], -// outputs: [ -// {name: 'blockNumber', type: 'uint256'}, -// {name: 'returnData', type: 'bytes[]'}, -// ] -// }, -// { -// name: 'tryAggregate', -// type: 'function', -// stateMutability: 'nonpayable', -// inputs: [ -// {name: 'requireSuccess', type: 'bool'}, -// { -// name: 'calls', -// type: 'tuple[]', -// components: [ -// {name: 'target', type: 'address'}, -// {name: 'callData', type: 'bytes'}, -// ] -// } -// ], -// outputs: [ -// { -// name: 'returnData', -// type: 'tuple[]', -// components: [ -// {name: 'success', type: 'bool'}, -// {name: 'returnData', type: 'bytes'}, -// ] -// }, -// ] -// } -// ]) -// -// -// type AnyFunc = Func -// type Call = [address: string, bytes: string] -// -// -// const aggregate = new Func<[calls: Call[]], {}, {blockNumber: bigint, returnData: string[]}>( -// abi, abi.getFunction('aggregate')!.selector -// ) -// -// -// const try_aggregate = new Func<[requireSuccess: boolean, calls: Array<[target: string, callData: string]>], {}, Array<{success: boolean, returnData: string}>>( -// abi, abi.getFunction('tryAggregate')!.selector -// ) -// -// -// export type MulticallResult = { -// success: true -// value: T -// } | { -// success: false -// returnData?: string -// value?: undefined -// } -// -// -// export class Multicall extends ContractBase { -// static aggregate = aggregate -// static try_aggregate = try_aggregate -// -// aggregate( -// func: Func, -// address: string, -// calls: Args[], -// paging?: number -// ): Promise -// -// aggregate( -// func: Func, -// calls: [address: string, args: Args][], -// paging?: number -// ): Promise -// -// aggregate( -// calls: [func: AnyFunc, address: string, args: any[]][], -// paging?: number -// ): Promise -// -// async aggregate(...args: any[]): Promise { -// let [calls, funcs, page] = this.makeCalls(args) -// let size = calls.length -// let results = new Array(size) -// for (let [from, to] of splitIntoPages(size, page)) { -// let {returnData} = await this.eth_call(aggregate, [calls.slice(from, to)]) -// for (let i = from; i < to; i++) { -// let data = returnData[i - from] -// results[i] = funcs[i].decodeResult(data) -// } -// } -// return results -// } -// -// tryAggregate( -// func: Func, -// address: string, -// calls: Args[], -// paging?: number -// ): Promise[]> -// -// tryAggregate( -// func: Func, -// calls: [address: string, args: Args][], -// paging?: number -// ): Promise[]> -// -// tryAggregate( -// calls: [func: AnyFunc, address: string, args: any[]][], -// paging?: number -// ): Promise[]> -// -// async tryAggregate(...args: any[]): Promise { -// let [calls, funcs, page] = this.makeCalls(args) -// let size = calls.length -// let results = new Array(size) -// for (let [from, to] of splitIntoPages(size, page)) { -// let response = await this.eth_call(try_aggregate, [false, calls.slice(from, to)]) -// for (let i = from; i < to; i++) { -// let res = response[i - from] -// if (res.success) { -// try { -// results[i] = { -// success: true, -// value: funcs[i].decodeResult(res.returnData) -// } -// } catch(err: any) { -// results[i] = {success: false, returnData: res.returnData} -// } -// } else { -// results[i] = {success: false} -// } -// } -// } -// return results -// } -// -// private makeCalls(args: any[]): [calls: Call[], funcs: AnyFunc[], page: number] { -// let page = typeof args[args.length-1] == 'number' ? args.pop()! : Number.MAX_SAFE_INTEGER -// switch(args.length) { -// case 1: { -// let list: [func: AnyFunc, address: string, args: any[]][] = args[0] -// let calls = new Array(list.length) -// let funcs = new Array(list.length) -// for (let i = 0; i < list.length; i++) { -// let [func, address, args] = list[i] -// calls[i] = [address, func.encode(args)] -// funcs[i] = func -// } -// return [calls, funcs, page] -// } -// case 2: { -// let func: AnyFunc = args[0] -// let list: [address: string, args: any[]][] = args[1] -// let calls = new Array(list.length) -// let funcs = new Array(list.length) -// for (let i = 0; i < list.length; i++) { -// let [address, args] = list[i] -// calls[i] = [address, func.encode(args)] -// funcs[i] = func -// } -// return [calls, funcs, page] -// } -// case 3: { -// let func: AnyFunc = args[0] -// let address: string = args[1] -// let list: any[][] = args[2] -// let calls = new Array(list.length) -// let funcs = new Array(list.length) -// for (let i = 0; i < list.length; i++) { -// let args = list[i] -// calls[i] = [address, func.encode(args)] -// funcs[i] = func -// } -// return [calls, funcs, page] -// } -// default: -// throw new Error('unexpected number of arguments') -// } -// } -// } -// -// -// function* splitIntoPages(size: number, page: number): Iterable<[from: number, to: number]> { -// let from = 0 -// while (size) { -// let step = Math.min(page, size) -// let to = from + step -// yield [from, to] -// size -= step -// from = to -// } -// } +import { ContractBase, Func } from "./abi.support"; + +type Call = { target: string; callData: string }; + +const aggregate = new Func< + { calls: Array<{ target: string; callData: string }> }, + [blockNumber: bigint, returnData: Array] +>( + "0x252dba42", + [ + { + components: [ + { name: "target", type: "address" }, + { name: "callData", type: "bytes" }, + ], + name: "calls", + type: "tuple[]", + }, + ], + [ + { name: "blockNumber", type: "uint256" }, + { name: "returnData", type: "bytes[]" }, + ] +); + +const tryAggregate = new Func< + { + requireSuccess: boolean; + calls: Array<{ target: string; callData: string }>; + }, + { success: boolean; returnData: string }[] +>( + "0xbce38bd7", + [ + { name: "requireSuccess", type: "bool" }, + { + components: [ + { name: "target", type: "address" }, + { name: "callData", type: "bytes" }, + ], + name: "calls", + type: "tuple[]", + }, + ], + [ + { + components: [ + { name: "success", type: "bool" }, + { name: "returnData", type: "bytes" }, + ], + name: "returnData", + type: "tuple[]", + }, + ] +); + +export type MulticallResult = + | { + success: true; + value: T; + } + | { + success: false; + returnData?: string; + value?: undefined; + }; + +type AnyFunc = Func<{ [key: string]: any }, any>; + +export class Multicall extends ContractBase { + static aggregate = aggregate; + static tryAggregate = tryAggregate; + + aggregate( + func: Func, + address: string, + calls: Args[keyof Args][], + paging?: number + ): Promise; + + aggregate( + func: Func, + calls: [address: string, args: Args[keyof Args]][], + paging?: number + ): Promise; + + aggregate( + calls: [func: AnyFunc, address: string, args: any[]][], + paging?: number + ): Promise; + + async aggregate(...args: any[]): Promise { + let [calls, funcs, page] = this.makeCalls(args); + let size = calls.length; + let results = new Array(size); + for (let [from, to] of splitIntoPages(size, page)) { + let [, returnData] = await this.eth_call(aggregate, [ + calls.slice(from, to), + ]); + for (let i = from; i < to; i++) { + let data = returnData[i - from]; + results[i] = funcs[i].decodeResult(data); + } + } + return results; + } + + tryAggregate( + func: Func, + address: string, + calls: Args[], + paging?: number + ): Promise[]>; + + tryAggregate( + func: Func, + calls: [address: string, args: Args][], + paging?: number + ): Promise[]>; + + tryAggregate( + calls: [func: AnyFunc, address: string, args: any[]][], + paging?: number + ): Promise[]>; + + async tryAggregate(...args: any[]): Promise { + let [calls, funcs, page] = this.makeCalls(args); + let size = calls.length; + let results = new Array(size); + for (let [from, to] of splitIntoPages(size, page)) { + let response = await this.eth_call(tryAggregate, [ + false, + calls.slice(from, to), + ]); + for (let i = from; i < to; i++) { + const { success, returnData } = response[i - from]; + if (success) { + try { + results[i] = { + success: true, + value: funcs[i].decodeResult(returnData), + }; + } catch (err: any) { + results[i] = { success: false, returnData: returnData }; + } + } else { + results[i] = { success: false }; + } + } + } + return results; + } + + private makeCalls( + args: any[] + ): [calls: Call[], funcs: AnyFunc[], page: number] { + let page = + typeof args[args.length - 1] == "number" + ? args.pop()! + : Number.MAX_SAFE_INTEGER; + switch (args.length) { + case 1: { + let list: [func: AnyFunc, address: string, args: any[]][] = args[0]; + let calls = new Array(list.length); + let funcs = new Array(list.length); + for (let i = 0; i < list.length; i++) { + let [func, address, args] = list[i]; + calls[i] = { target: address, callData: func.encode(args) }; + funcs[i] = func; + } + return [calls, funcs, page]; + } + case 2: { + let func: AnyFunc = args[0]; + let list: [address: string, args: any[]][] = args[1]; + let calls = new Array(list.length); + let funcs = new Array(list.length); + for (let i = 0; i < list.length; i++) { + let [address, args] = list[i]; + calls[i] = [address, func.encode(args)]; + funcs[i] = func; + } + return [calls, funcs, page]; + } + case 3: { + let func: AnyFunc = args[0]; + let address: string = args[1]; + let list: any[][] = args[2]; + let calls = new Array(list.length); + let funcs = new Array(list.length); + for (let i = 0; i < list.length; i++) { + let args = list[i]; + calls[i] = [address, func.encode(args)]; + funcs[i] = func; + } + return [calls, funcs, page]; + } + default: + throw new Error("unexpected number of arguments"); + } + } +} + +function* splitIntoPages( + size: number, + page: number +): Iterable<[from: number, to: number]> { + let from = 0; + while (size) { + let step = Math.min(page, size); + let to = from + step; + yield [from, to]; + size -= step; + from = to; + } +} diff --git a/evm/evm-typegen/src/typegen.ts b/evm/evm-typegen/src/typegen.ts index 7bbb35973..8db029981 100644 --- a/evm/evm-typegen/src/typegen.ts +++ b/evm/evm-typegen/src/typegen.ts @@ -4,7 +4,7 @@ import {def} from '@subsquid/util-internal' import {FileOutput, OutDir} from '@subsquid/util-internal-code-printer' import { getEventParamTypes, - getFullTupleType, + getNamedType, getReturnType, getType, stringifyParams @@ -29,6 +29,7 @@ export class Typegen { this.out.line("import {LogEvent, Func, ContractBase} from './abi.support'") this.out.line() + this.generateTypes() this.generateEvents() this.generateFunctions() this.generateContract() @@ -37,6 +38,28 @@ export class Typegen { this.log.info(`saved ${this.out.file}`) } + private generateTypes() { + const events = this.getEvents() + const functions = this.getFunctions() + if (events.length > 0) { + this.out.line() + this.out.block(`export type EventTypes =`, () => { + for (let e of events) { + this.out.line(`${this.getPropName(e)}: ${getEventParamTypes(e.inputs)},`) + } + }) + } + if (functions.length > 0) { + this.out.line() + this.out.block(`export type FunctionTypes =`, () => { + for (let f of functions) { + this.out.line(`${this.getPropName(f)}: {args: ${getNamedType(f.inputs)}, return: ${getReturnType(f.outputs)}},`) + } + }) + } + } + + private generateEvents() { let events = this.getEvents() if (events.length == 0) { @@ -49,7 +72,7 @@ export class Typegen { this.docs.events[toFunctionSignature(e)] .split('\n').forEach(l => this.out.line(l)) } - this.out.line(`${this.getPropName(e)}: new LogEvent<${getEventParamTypes(e.inputs)}>(`) + this.out.line(`${this.getPropName(e)}: new LogEvent(`) this.out.indentation(() => this.out.line(`'${toEventHash(e)}', ${stringifyParams(e.inputs)}`)) this.out.line('),') } @@ -65,13 +88,12 @@ export class Typegen { this.out.block(`export const functions =`, () => { for (let f of functions) { let sighash = toFunctionHash(f).slice(0, 10) - let pArgs = getFullTupleType(f.inputs) - let pResult = getReturnType(f.outputs) + const propName = this.getPropName(f) if (this.docs.methods[toFunctionSignature(f)]) { this.docs.methods[toFunctionSignature(f)] .split('\n').forEach(l => this.out.line(l)) } - this.out.line(`${this.getPropName(f)}: new Func<${pArgs}, ${pResult}>(`) + this.out.line(`${propName}: new Func(`) this.out.indentation(() => this.out.line(`'${sighash}',`)) this.out.indentation(() => this.out.line(`${stringifyParams(f.inputs)},`)) this.out.indentation(() => this.out.line(`${stringifyParams(f.outputs)}`)) @@ -114,6 +136,10 @@ export class Typegen { } } + private trimPropName(name: string): string { + return name.replace(/^'/g, '').replace(/'$/g, '') + } + private getOverloads(item: AbiItem): number { if (item.type === 'function') { return this.functionOverloads()[item.name] diff --git a/evm/evm-typegen/src/util/types.ts b/evm/evm-typegen/src/util/types.ts index 9e9617b59..e55f725e2 100644 --- a/evm/evm-typegen/src/util/types.ts +++ b/evm/evm-typegen/src/util/types.ts @@ -33,7 +33,7 @@ export function getType(param: AbiParameter): string { if (param.type === 'tuple' && 'components' in param) { assert(param.components != null, 'Missing components for tuple type') - return getFullTupleType(param.components) + return getNamedType(param.components) } if (param.type === 'address' || param.type === 'string') { @@ -56,13 +56,20 @@ export function getType(param: AbiParameter): string { throw new Error('unknown type') } +function getName(param: AbiParameter, index: number): string { + return param.name || `_${index}` +} + +export function getNamedType(params: readonly AbiParameter[]): string { + return `{ ${params.map((p, index) => `${getName(p, index)}: ${getType(p)}`).join(', ')} }` +} -export function getFullTupleType(params: readonly AbiParameter[]): string { - return `[${params.map(p => `['${p.name}',${getType(p)}]`).join(',')}]` +export function geTupleType(params: readonly AbiParameter[]): string { + return `[${params.map((p, index) => `${getName(p, index)}: ${getType(p)}`).join(', ')}]` } export function getEventParamTypes(param: readonly AbiEventParameter[]): string { - return getFullTupleType(param.map(p => p.indexed ? hasDynamicChild(p) ? { + return getNamedType(param.map(p => p.indexed ? hasDynamicChild(p) ? { ...p, type: 'bytes32' } : p : p)) @@ -72,27 +79,6 @@ export function stringifyParams(inputs: readonly AbiParameter[]): string { return JSON.stringify(inputs.map(({internalType, ...rest}) => rest)) } -export function getTupleType(params: readonly AbiParameter[]): string { - return '[' + params.map(p => { - return p.name ? `${p.name}: ${getType(p)}` : `_: ${getType(p)}` - }).join(', ') + ']' -} - - -// https://github.com/ethers-io/ethers.js/blob/278f84174409b470fa7992e1f8b5693e6e5d2dac/src.ts/abi/coders/tuple.ts#L36 -export function getStructType(params: readonly AbiParameter[]): string { - let array: any = [] - let counts: Record = {} - for (let p of params) { - if (p.name && array[p.name] == null) { - counts[p.name] = (counts[p.name] || 0) + 1 - } - } - let fields = params.filter(p => counts[p.name ?? ''] == 1) - return '{' + fields.map(f => `${f.name}: ${getType(f)}`).join(', ') + '}' -} - - export function getReturnType(outputs: readonly AbiParameter[]) { - return outputs.length == 1 ? getType(outputs[0]) : getFullTupleType(outputs) + return outputs.length == 1 ? getType(outputs[0]) : geTupleType(outputs) } From 27f6b4074e22a38610fa7de87df73c6d0b0d8c9e Mon Sep 17 00:00:00 2001 From: ivan Date: Mon, 4 Mar 2024 09:33:43 +0100 Subject: [PATCH 05/12] Fix tests --- evm/evm-typegen/src/abi.support.ts | 2 +- evm/evm-typegen/src/decodeAbiParameters.ts | 313 +++++++++++---------- evm/evm-typegen/test/logEvent.test.ts | 57 ++-- 3 files changed, 184 insertions(+), 188 deletions(-) diff --git a/evm/evm-typegen/src/abi.support.ts b/evm/evm-typegen/src/abi.support.ts index bcffd7247..05b70be8f 100644 --- a/evm/evm-typegen/src/abi.support.ts +++ b/evm/evm-typegen/src/abi.support.ts @@ -75,7 +75,7 @@ export class LogEvent { throw new Error('Invalid event record') } assertIsHex(rec.data) - const result: any = [] + const result: any = {} const parsedData = decodeAbiParameters(this.nonIndexedArgs, rec.data) for (let i = 0; i < parsedData.length; i++) { if (this.nonIndexedArgs[i].name) { diff --git a/evm/evm-typegen/src/decodeAbiParameters.ts b/evm/evm-typegen/src/decodeAbiParameters.ts index 83f32a254..f7bab5125 100644 --- a/evm/evm-typegen/src/decodeAbiParameters.ts +++ b/evm/evm-typegen/src/decodeAbiParameters.ts @@ -1,139 +1,141 @@ export interface AbiParameter { - name?: string - type: string + name?: string; + type: string; } class Cursor { - bytes: Uint8Array - position: number - positionReadCount: Map - recursiveReadLimit: number + bytes: Uint8Array; + position: number; + positionReadCount: Map; + recursiveReadLimit: number; constructor(bytes: Uint8Array) { - this.bytes = bytes - this.position = 0 - this.positionReadCount = new Map() - this.recursiveReadLimit = 8_192 + this.bytes = bytes; + this.position = 0; + this.positionReadCount = new Map(); + this.recursiveReadLimit = 8_192; } inspectBytes(length: number) { - return this.bytes.subarray(this.position, this.position + length) + return this.bytes.subarray(this.position, this.position + length); } + public readBytes(length: number, size?: number) { - const value = this.inspectBytes(length) - this.position += size ?? length - return value + const value = this.inspectBytes(length); + this.position += size ?? length; + return value; } + public setPosition(position: number) { - const oldPosition = this.position - this.position = position - return () => (this.position = oldPosition) + const oldPosition = this.position; + this.position = position; + return () => (this.position = oldPosition); } } export function decodeAbiParameters( params: AbiParameter[], - data: `0x${string}`, + data: `0x${string}` ) { - const bytes = Buffer.from(data.slice(2), 'hex') - const cursor = new Cursor(bytes) + const bytes = Buffer.from(data.slice(2), "hex"); + const cursor = new Cursor(bytes); - let consumed = 0 - const values = [] + let consumed = 0; + const values = []; for (let i = 0; i < params.length; ++i) { - const param = params[i] - cursor.setPosition(consumed) + const param = params[i]; + cursor.setPosition(consumed); const [data, consumed_] = decodeParameter(cursor, param, { staticPosition: 0, - }) - consumed += consumed_ - values.push(data) + }); + consumed += consumed_; + values.push(data); } - return values + return values; } export function getArrayComponents( - type: string, + type: string ): [length: number | null, innerType: string] | undefined { - const matches = type.match(/^(.*)\[(\d+)?]$/) + const matches = type.match(/^(.*)\[(\d+)?]$/); return matches ? // Return `null` if the array is dynamic. - [matches[2] ? Number(matches[2]) : null, matches[1]] - : undefined + [matches[2] ? Number(matches[2]) : null, matches[1]] + : undefined; } function decodeParameter( cursor: Cursor, param: AbiParameter, - { staticPosition }: { staticPosition: number }, + { staticPosition }: { staticPosition: number } ): readonly [any, number] { - const arrayComponents = getArrayComponents(param.type) + const arrayComponents = getArrayComponents(param.type); if (arrayComponents) { - const [length, type] = arrayComponents - return decodeArray(cursor, { ...param, type }, { length, staticPosition }) + const [length, type] = arrayComponents; + return decodeArray(cursor, { ...param, type }, { length, staticPosition }); } - if (param.type === 'tuple') - return decodeTuple(cursor, param as TupleAbiParameter, { staticPosition }) - - if (param.type === 'address') return decodeAddress(cursor) - if (param.type === 'bool') return decodeBool(cursor) - if (param.type.startsWith('bytes')) - return decodeBytes(cursor, param, { staticPosition }) - if (param.type.startsWith('uint') || param.type.startsWith('int')) - return decodeNumber(cursor, param) - if (param.type === 'string') return decodeString(cursor, { staticPosition }) - throw new Error(`Unknown type: ${param.type}`) + if (param.type === "tuple") + return decodeTuple(cursor, param as TupleAbiParameter, { staticPosition }); + + if (param.type === "address") return decodeAddress(cursor); + if (param.type === "bool") return decodeBool(cursor); + if (param.type.startsWith("bytes")) + return decodeBytes(cursor, param, { staticPosition }); + if (param.type.startsWith("uint") || param.type.startsWith("int")) + return decodeNumber(cursor, param); + if (param.type === "string") return decodeString(cursor, { staticPosition }); + throw new Error(`Unknown type: ${param.type}`); } //////////////////////////////////////////////////////////////////// // Type Decoders -const sizeOfLength = 32 -const sizeOfOffset = 32 +const sizeOfLength = 32; +const sizeOfOffset = 32; function decodeAddress(cursor: Cursor) { - const value = cursor.readBytes(sizeOfOffset) - return [bytesToHex(value.slice(-20)), sizeOfLength] as const + const value = cursor.readBytes(sizeOfOffset); + return [bytesToHex(value.slice(-20)), sizeOfLength] as const; } function decodeArray( cursor: Cursor, param: AbiParameter, - { length, staticPosition }: { length: number | null; staticPosition: number }, + { length, staticPosition }: { length: number | null; staticPosition: number } ) { // If the length of the array is not known in advance (dynamic array), // this means we will need to wonder off to the pointer and decode. if (!length) { // Dealing with a dynamic type, so get the offset of the array data. - const offset = bytesToNumber(cursor.readBytes(sizeOfOffset)) + const offset = bytesToNumber(cursor.readBytes(sizeOfOffset)); // Start is the static position of current slot + offset. - const start = staticPosition + offset - const startOfData = start + sizeOfLength + const start = staticPosition + offset; + const startOfData = start + sizeOfLength; // Get the length of the array from the offset. - cursor.setPosition(start) - const length = bytesToNumber(cursor.readBytes(sizeOfLength)) + cursor.setPosition(start); + const length = bytesToNumber(cursor.readBytes(sizeOfLength)); // Check if the array has any dynamic children. - const dynamicChild = hasDynamicChild(param) + const dynamicChild = hasDynamicChild(param); - let consumed = 0 - const value: unknown[] = [] + let consumed = 0; + const value: unknown[] = []; for (let i = 0; i < length; ++i) { // If any of the children is dynamic, then all elements will be offset pointer, thus size of one slot (32 bytes). // Otherwise, elements will be the size of their encoding (consumed bytes). - cursor.setPosition(startOfData + (dynamicChild ? i * 32 : consumed)) + cursor.setPosition(startOfData + (dynamicChild ? i * 32 : consumed)); const [data, consumed_] = decodeParameter(cursor, param, { staticPosition: startOfData, - }) - consumed += consumed_ - value.push(data) + }); + consumed += consumed_; + value.push(data); } // As we have gone wondering, restore to the original position + next slot. - cursor.setPosition(staticPosition + 32) - return [value, 32] as const + cursor.setPosition(staticPosition + 32); + return [value, 32] as const; } // If the length of the array is known in advance, @@ -141,220 +143,225 @@ function decodeArray( // we need to decode the offset of the array data. if (hasDynamicChild(param)) { // Dealing with dynamic types, so get the offset of the array data. - const offset = bytesToNumber(cursor.readBytes(sizeOfOffset)) + const offset = bytesToNumber(cursor.readBytes(sizeOfOffset)); // Start is the static position of current slot + offset. - const start = staticPosition + offset + const start = staticPosition + offset; - const value: unknown[] = [] + const value: unknown[] = []; for (let i = 0; i < length; ++i) { // Move cursor along to the next slot (next offset pointer). - cursor.setPosition(start + i * 32) + cursor.setPosition(start + i * 32); const [data] = decodeParameter(cursor, param, { staticPosition: start, - }) - value.push(data) + }); + value.push(data); } // As we have gone wondering, restore to the original position + next slot. - cursor.setPosition(staticPosition + 32) - return [value, 32] as const + cursor.setPosition(staticPosition + 32); + return [value, 32] as const; } // If the length of the array is known in advance and the array is deeply static, // then we can just decode each element in sequence. - let consumed = 0 - const value: unknown[] = [] + let consumed = 0; + const value: unknown[] = []; for (let i = 0; i < length; ++i) { const [data, consumed_] = decodeParameter(cursor, param, { staticPosition: staticPosition + consumed, - }) - consumed += consumed_ - value.push(data) + }); + consumed += consumed_; + value.push(data); } - return [value, consumed] as const + return [value, consumed] as const; } function decodeBool(cursor: Cursor) { - return [bytesToBool(cursor.readBytes(32), 32), 32] as const + return [bytesToBool(cursor.readBytes(32), 32), 32] as const; } function decodeBytes( cursor: Cursor, param: AbiParameter, - { staticPosition }: { staticPosition: number }, + { staticPosition }: { staticPosition: number } ) { - const [_, size] = param.type.split('bytes') + const [_, size] = param.type.split("bytes"); if (!size) { // Dealing with dynamic types, so get the offset of the bytes data. - const offset = bytesToNumber(cursor.readBytes(32)) + const offset = bytesToNumber(cursor.readBytes(32)); // Set position of the cursor to start of bytes data. - cursor.setPosition(staticPosition + offset) + cursor.setPosition(staticPosition + offset); - const length = bytesToNumber(cursor.readBytes(32)) + const length = bytesToNumber(cursor.readBytes(32)); // If there is no length, we have zero data. if (length === 0) { // As we have gone wondering, restore to the original position + next slot. - cursor.setPosition(staticPosition + 32) - return ['0x', 32] as const + cursor.setPosition(staticPosition + 32); + return ["0x", 32] as const; } - const data = cursor.readBytes(length) + const data = cursor.readBytes(length); // As we have gone wondering, restore to the original position + next slot. - cursor.setPosition(staticPosition + 32) - return [bytesToHex(data), 32] as const + cursor.setPosition(staticPosition + 32); + return [bytesToHex(data), 32] as const; } - const value = bytesToHex(cursor.readBytes(parseInt(size), 32)) - return [value, 32] as const + const value = bytesToHex(cursor.readBytes(parseInt(size), 32)); + return [value, 32] as const; } function decodeNumber(cursor: Cursor, param: AbiParameter) { - const signed = param.type.startsWith('int') - const size = parseInt(param.type.split('int')[1] || '256') - const value = cursor.readBytes(32) + const signed = param.type.startsWith("int"); + const size = parseInt(param.type.split("int")[1] || "256"); + const value = cursor.readBytes(32); return [ size > 48 ? bytesToBigInt(value, { signed }) : bytesToNumber(value, { signed }), 32, - ] as const + ] as const; } -type TupleAbiParameter = AbiParameter & { components: readonly AbiParameter[] } +type TupleAbiParameter = AbiParameter & { components: readonly AbiParameter[] }; function decodeTuple( cursor: Cursor, param: TupleAbiParameter, - { staticPosition }: { staticPosition: number }, + { staticPosition }: { staticPosition: number } ) { // Tuples can have unnamed components (i.e. they are arrays), so we must // determine whether the tuple is named or unnamed. In the case of a named // tuple, the value will be an object where each property is the name of the // component. In the case of an unnamed tuple, the value will be an array. const hasUnnamedChild = - param.components.length === 0 || param.components.some(({ name }) => !name) + param.components.length === 0 || param.components.some(({ name }) => !name); // Initialize the value to an object or an array, depending on whether the // tuple is named or unnamed. - const value: any = hasUnnamedChild ? [] : {} - let consumed = 0 + const value: any = hasUnnamedChild ? [] : {}; + let consumed = 0; // If the tuple has a dynamic child, we must first decode the offset to the // tuple data. if (hasDynamicChild(param)) { // Dealing with dynamic types, so get the offset of the tuple data. - const offset = bytesToNumber(cursor.readBytes(sizeOfOffset)) + const offset = bytesToNumber(cursor.readBytes(sizeOfOffset)); // Start is the static position of referencing slot + offset. - const start = staticPosition + offset + const start = staticPosition + offset; for (let i = 0; i < param.components.length; ++i) { - const component = param.components[i] - cursor.setPosition(start + consumed) + const component = param.components[i]; + cursor.setPosition(start + consumed); const [data, consumed_] = decodeParameter(cursor, component, { staticPosition: start, - }) - consumed += consumed_ - value[hasUnnamedChild ? i : component?.name!] = data + }); + consumed += consumed_; + value[hasUnnamedChild ? i : component?.name!] = data; } // As we have gone wondering, restore to the original position + next slot. - cursor.setPosition(staticPosition + 32) - return [value, 32] as const + cursor.setPosition(staticPosition + 32); + return [value, 32] as const; } // If the tuple has static children, we can just decode each component // in sequence. for (let i = 0; i < param.components.length; ++i) { - const component = param.components[i] + const component = param.components[i]; const [data, consumed_] = decodeParameter(cursor, component, { staticPosition, - }) - value[hasUnnamedChild ? i : component?.name!] = data - consumed += consumed_ + }); + value[hasUnnamedChild ? i : component?.name!] = data; + consumed += consumed_; } - return [value, consumed] as const + return [value, consumed] as const; } function decodeString( cursor: Cursor, - { staticPosition }: { staticPosition: number }, + { staticPosition }: { staticPosition: number } ) { // Get offset to start of string data. - const offset = bytesToNumber(cursor.readBytes(32)) + const offset = bytesToNumber(cursor.readBytes(32)); // Start is the static position of current slot + offset. - const start = staticPosition + offset - cursor.setPosition(start) + const start = staticPosition + offset; + cursor.setPosition(start); - const length = bytesToNumber(cursor.readBytes(32)) + const length = bytesToNumber(cursor.readBytes(32)); // If there is no length, we have zero data (empty string). if (length === 0) { - cursor.setPosition(staticPosition + 32) - return ['', 32] as const + cursor.setPosition(staticPosition + 32); + return ["", 32] as const; } - const data = cursor.readBytes(length, 32) - const value = new TextDecoder().decode(data) + const data = cursor.readBytes(length, 32); + const value = new TextDecoder().decode(data); // As we have gone wondering, restore to the original position + next slot. - cursor.setPosition(staticPosition + 32) + cursor.setPosition(staticPosition + 32); - return [value, 32] as const + return [value, 32] as const; } export function hasDynamicChild(param: AbiParameter) { - const { type } = param - if (type === 'string') return true - if (type === 'bytes') return true - if (type.endsWith('[]')) return true + const { type } = param; + if (type === "string") return true; + if (type === "bytes") return true; + if (type.endsWith("[]")) return true; - if (type === 'tuple') return (param as any).components?.some(hasDynamicChild) + if (type === "tuple") return (param as any).components?.some(hasDynamicChild); - const arrayComponents = getArrayComponents(param.type) + const arrayComponents = getArrayComponents(param.type); if ( arrayComponents && hasDynamicChild({ ...param, type: arrayComponents[1] } as AbiParameter) ) - return true + return true; - return false + return false; } //////////////////////////////////////////////////////////////////// /// Bytes parsing const bytesToHex = (bytes: Uint8Array): `0x${string}` => { - return `0x${Array.from(bytes).map((byte) => byte.toString(16).padStart(2, '0')).join('')}` -} - -export function hexToBigInt(hex: `0x${string}`, opts: { signed?: boolean } = {}): bigint { - const {signed} = opts - const value = BigInt(hex) - if (!signed) return value - - const size = (hex.length - 2) / 2 - const max = (1n << (BigInt(size) * 8n - 1n)) - 1n - if (value <= max) return value - - return value - BigInt(`0x${'f'.padStart(size * 2, 'f')}`) - 1n + return `0x${Array.from(bytes) + .map((byte) => byte.toString(16).padStart(2, "0")) + .join("")}`; +}; + +export function hexToBigInt( + hex: `0x${string}`, + opts: { signed?: boolean } = {} +): bigint { + const { signed } = opts; + const value = BigInt(hex); + if (!signed) return value; + + const size = (hex.length - 2) / 2; + const max = (1n << (BigInt(size) * 8n - 1n)); + if (value < max) return value; + + return value - max - 1n; } function bytesToNumber(bytes: Uint8Array, opts: { signed?: boolean } = {}) { - const value = bytesToHex(bytes) - return Number(hexToBigInt(value, opts)) + const value = bytesToHex(bytes); + return Number(hexToBigInt(value, opts)); } function bytesToBool(bytes: Uint8Array, size: number) { - return bytes[size - 1] !== 0 + return bytes[size - 1] !== 0; } function bytesToBigInt(bytes: Uint8Array, opts: { signed?: boolean } = {}) { - const value = bytesToHex(bytes) - return hexToBigInt(value, opts) + const value = bytesToHex(bytes); + return hexToBigInt(value, opts); } diff --git a/evm/evm-typegen/test/logEvent.test.ts b/evm/evm-typegen/test/logEvent.test.ts index c97fed9d8..ab5e868b5 100644 --- a/evm/evm-typegen/test/logEvent.test.ts +++ b/evm/evm-typegen/test/logEvent.test.ts @@ -3,7 +3,7 @@ import {encodeAbiParameters, encodeEventTopics, parseAbiItem, toEventSelector} f import {LogEvent} from "../src/abi.support"; describe("LogEvent", () => { - function createEvent(event: any) { + function createEvent(event: any) { const topic = toEventSelector(event); return new LogEvent(topic, event.inputs) } @@ -20,9 +20,13 @@ describe("LogEvent", () => { it('decodes params of simple event', () => { const event = parseAbiItem('event Transfer(address indexed from, uint256 value, uint8 flag, bool success, address indexed to)'); - const logEvent = createEvent< - [['from', string], ['value', bigint], ['flag', number], ['success', boolean], ['to', string]] - >(event); + const logEvent = createEvent<{ + from: string, + value: bigint, + flag: number, + success: boolean, + to: string + }>(event); const topics = encodeEventTopics({ abi: [event], args: { @@ -32,14 +36,7 @@ describe("LogEvent", () => { }) const data = encodeAbiParameters(event.inputs.slice(1, -1), [100n, 15, true]) const t = logEvent.decode({topics, data}); - expectToContain(t, [ - '0x9401e5e6564db35c0f86573a9828df69fc778af1', - 100n, - 15, - true, - '0x1001e5e6564db35c0f86573a9828df69fc778af1', - ]) - expectToContain(t, { + expect(t).toStrictEqual({ value: 100n, flag: 15, success: true, @@ -51,9 +48,13 @@ describe("LogEvent", () => { it('decodes dynamic length params', () => { const event = parseAbiItem('event SomethingBig(string a, string indexed indexedString, bytes b, bytes indexed indexedBytes, bytes4 indexed c)'); - const logEvent = createEvent< - [['a', string], ['b', Uint8Array], ['c', string]] - >(event); + const logEvent = createEvent<{ + a: string, + indexedString: string, + b: string, + indexedBytes: string, + c: string + }>(event); const topics = encodeEventTopics({ abi: [event], args: { @@ -64,14 +65,7 @@ describe("LogEvent", () => { }) const data = encodeAbiParameters([event.inputs[0], event.inputs[2]], ['hello', '0x1234']); const t = logEvent.decode({topics, data}); - expectToContain(t, [ - 'hello', - '0x8452c9b9140222b08593a26daa782707297be9f7b3e8281d7b4974769f19afd0', - '0x1234', - '0xe2f884a85df4ad7a73f7b7e4091f440e1597c9a36083444607c9e9d9163aeed2', - '0xdeadbeef', - ]) - expectToContain(t, { + expect(t).toStrictEqual({ a: 'hello', indexedString: '0x8452c9b9140222b08593a26daa782707297be9f7b3e8281d7b4974769f19afd0', b: '0x1234', @@ -87,16 +81,17 @@ describe("LogEvent", () => { 'struct Other { uint256 bar; }', ]); - const logEvent = createEvent< - [['foo', { + const logEvent = createEvent<{ + foo: { a: string, b: boolean, c: string, d: { bar: bigint } - }]] - >(event); + } + }>(event); + const topics = encodeEventTopics({ abi: [event], }) @@ -107,13 +102,7 @@ describe("LogEvent", () => { d: {bar: 100n} }]); const t = logEvent.decode({topics, data}); - expectToContain(t, [{ - a: 'hello', - b: true, - c: 'world', - d: {bar: 100n} - }]) - expectToContain(t, { + expect(t).toStrictEqual({ foo: { a: 'hello', b: true, From 5bfb8344b05a068ec580db9d7389082b01e676a4 Mon Sep 17 00:00:00 2001 From: ivan Date: Mon, 4 Mar 2024 11:40:36 +0100 Subject: [PATCH 06/12] Introduce separate package --- evm/evm-typegen/package.json | 8 +- evm/evm-typegen/src/abi.support.ts | 3 +- evm/evm-typegen/src/encodeAbiParameters.ts | 318 ------------------ evm/evm-typegen/src/main.ts | 4 - evm/evm-typegen/src/util/types.ts | 2 +- evm/evm-utils/package.json | 26 ++ .../src/decodeAbiParameters.ts | 17 +- evm/evm-utils/src/encodeAbiParameters.ts | 313 +++++++++++++++++ evm/evm-utils/src/index.ts | 3 + evm/evm-utils/src/types.ts | 6 + .../test/decodeAbiParameters.test.ts | 0 .../test/encodeAbiParameters.test.ts | 0 evm/evm-utils/test/hexToBigInt.test.ts | 54 +++ evm/evm-utils/tsconfig.build.json | 8 + evm/evm-utils/tsconfig.json | 24 ++ 15 files changed, 445 insertions(+), 341 deletions(-) delete mode 100644 evm/evm-typegen/src/encodeAbiParameters.ts create mode 100644 evm/evm-utils/package.json rename evm/{evm-typegen => evm-utils}/src/decodeAbiParameters.ts (97%) create mode 100644 evm/evm-utils/src/encodeAbiParameters.ts create mode 100644 evm/evm-utils/src/index.ts create mode 100644 evm/evm-utils/src/types.ts rename evm/{evm-typegen => evm-utils}/test/decodeAbiParameters.test.ts (100%) rename evm/{evm-typegen => evm-utils}/test/encodeAbiParameters.test.ts (100%) create mode 100644 evm/evm-utils/test/hexToBigInt.test.ts create mode 100644 evm/evm-utils/tsconfig.build.json create mode 100644 evm/evm-utils/tsconfig.json diff --git a/evm/evm-typegen/package.json b/evm/evm-typegen/package.json index bd31a4333..7ea7a4b07 100644 --- a/evm/evm-typegen/package.json +++ b/evm/evm-typegen/package.json @@ -25,13 +25,13 @@ "@subsquid/util-internal-code-printer": "^1.2.2", "@subsquid/util-internal-commander": "^1.3.2", "commander": "^11.1.0", - "solc": "^0.8.24" - }, - "peerDependencies": { + "solc": "^0.8.24", "abitype": "^1.0.0", - "ethers": "^6.9.0", "viem": "^2.7.11" }, + "peerDependencies": { + "@subsquid/evm-utils": "1.0.0" + }, "devDependencies": { "@types/node": "^18.18.14", "types-solc": "^1.0.1", diff --git a/evm/evm-typegen/src/abi.support.ts b/evm/evm-typegen/src/abi.support.ts index 05b70be8f..fd7b3d60e 100644 --- a/evm/evm-typegen/src/abi.support.ts +++ b/evm/evm-typegen/src/abi.support.ts @@ -1,5 +1,4 @@ -import {decodeAbiParameters, hasDynamicChild} from './decodeAbiParameters' -import {encodeFunctionData} from "./encodeAbiParameters"; +import {decodeAbiParameters, hasDynamicChild, encodeFunctionData} from '@subsquid/evm-utils' type Hex = `0x${string}` diff --git a/evm/evm-typegen/src/encodeAbiParameters.ts b/evm/evm-typegen/src/encodeAbiParameters.ts deleted file mode 100644 index 55eedd93c..000000000 --- a/evm/evm-typegen/src/encodeAbiParameters.ts +++ /dev/null @@ -1,318 +0,0 @@ -import {AbiParameter} from "./decodeAbiParameters"; - -type Hex = `0x${string}` - -export function encodeFunctionData< - const TParams extends readonly AbiParameter[] | readonly unknown[], ->( - signature: Hex, - params: TParams, - values: any[] -) { - return concat([signature, encodeAbiParameters(params, values)]) -} - -/** - * @description Encodes a list of primitive values into an ABI-encoded hex value. - */ -export function encodeAbiParameters< - const TParams extends readonly AbiParameter[] | readonly unknown[], ->( - params: TParams, - values: any[] -): Hex { - // Prepare the parameters to determine dynamic types to encode. - const preparedParams = prepareParams({ - params: params as readonly AbiParameter[], - values, - }) - const data = encodeParams(preparedParams) - if (data.length === 0) return '0x' - return data -} - -///////////////////////////////////////////////////////////////// - -type PreparedParam = { dynamic: boolean; encoded: Hex } - -function prepareParams({ - params, - values, - }: { - params: TParams - values: any[] -}) { - const preparedParams: PreparedParam[] = [] - for (let i = 0; i < params.length; i++) { - preparedParams.push(prepareParam({param: params[i], value: values[i]})) - } - return preparedParams -} - -function prepareParam({ - param, - value, - }: { - param: TParam - value: any[] -}): PreparedParam { - const arrayComponents = getArrayComponents(param.type) - if (arrayComponents) { - const [length, type] = arrayComponents - return encodeArray(value, {length, param: {...param, type}}) - } - if (param.type === 'tuple') { - return encodeTuple(value as any, { - param, - } as any) - } - if (param.type === 'address') { - return encodeAddress(value as unknown as Hex) - } - if (param.type === 'bool') { - return encodeBool(value as unknown as boolean) - } - if (param.type.startsWith('uint') || param.type.startsWith('int')) { - const signed = param.type.startsWith('int') - return encodeNumber(value as unknown as number, signed) - } - if (param.type.startsWith('bytes')) { - return encodeBytes(value as unknown as Hex, {param}) - } - if (param.type === 'string') { - return encodeString(value as unknown as string) - } - throw new Error(`Unknown type: ${param.type}`); -} - -///////////////////////////////////////////////////////////////// - -export function size(value: Hex) { - return Math.ceil((value.length - 2) / 2) -} - -function pad(value: string, size: number = 32): Hex { - return `0x${value.padStart(size * 2, '0')}` -} - -function padRight(value: string, size: number = 32): Hex { - return `0x${value.padEnd(size * 2, '0')}` -} - -function padHex(value: Hex, opts?: {right?: boolean, size?: number}): Hex { - if (opts?.right) { - return padRight(value.slice(2), opts.size) - } - return pad(value.slice(2), opts?.size) -} - -export function numberToHex( - value_: number | bigint, - signed = false -): Hex { - const value = BigInt(value_) - const size = 32 - - let maxValue: bigint | number = 0 - if (typeof value_ === 'number') { - maxValue = BigInt(Number.MAX_SAFE_INTEGER) - } - - const minValue = typeof maxValue === 'bigint' && signed ? -maxValue - 1n : 0 - - if ((maxValue && value > maxValue) || value < minValue) { - throw new Error(`Number "${value}" is not in safe ${signed ? 'signed' : 'unsigned'} integer range [${minValue}, ${maxValue}]`); - } - - const hex = `0x${(signed && value < 0 - ? (1n << BigInt(size * 8)) + BigInt(value) - : value - ).toString(16)}` as Hex - return padHex(hex) as Hex -} - -const concat = (hexes: Hex[]): Hex => `0x${hexes.map((h) => h.slice(2)).join('')}` - -function encodeParams(preparedParams: PreparedParam[]): Hex { - // 1. Compute the size of the static part of the parameters. - let staticSize = 0 - for (let i = 0; i < preparedParams.length; i++) { - const {dynamic, encoded} = preparedParams[i] - if (dynamic) staticSize += 32 - else staticSize += size(encoded) - } - - // 2. Split the parameters into static and dynamic parts. - const staticParams: Hex[] = [] - const dynamicParams: Hex[] = [] - let dynamicSize = 0 - for (let i = 0; i < preparedParams.length; i++) { - const {dynamic, encoded} = preparedParams[i] - if (dynamic) { - staticParams.push(numberToHex(staticSize + dynamicSize)) - dynamicParams.push(encoded) - dynamicSize += size(encoded) - } else { - staticParams.push(encoded) - } - } - - // 3. Concatenate static and dynamic parts. - return concat([...staticParams, ...dynamicParams]) -} - -///////////////////////////////////////////////////////////////// - -function encodeAddress(value: Hex): PreparedParam { - if (!value.match(/^0x[0-9a-fA-F]{40}$/)) throw new Error(`Invalid address: ${value}`); - return {dynamic: false, encoded: padHex(value.toLowerCase() as Hex)} -} - -function encodeArray( - value: any, - { - length, - param, - }: { - length: number | null - param: TParam - }, -): PreparedParam { - const dynamic = length === null - - if (!Array.isArray(value)) throw new Error(`Invalid array: ${value}`); - if (!dynamic && value.length !== length) - throw new Error(`Invalid ${param.type}[${length}] array length: ${value.length}`); - - let dynamicChild = false - const preparedParams: PreparedParam[] = [] - for (let i = 0; i < value.length; i++) { - const preparedParam = prepareParam({param, value: value[i]}) - if (preparedParam.dynamic) dynamicChild = true - preparedParams.push(preparedParam) - } - - if (dynamic || dynamicChild) { - const data = encodeParams(preparedParams) - if (dynamic) { - const length = numberToHex(preparedParams.length) - return { - dynamic: true, - encoded: preparedParams.length > 0 ? concat([length, data]) : length, - } - } - if (dynamicChild) return {dynamic: true, encoded: data} - } - return { - dynamic: false, - encoded: concat(preparedParams.map(({encoded}) => encoded)), - } -} - -function encodeBytes( - value: Hex, - {param}: { param: TParam }, -): PreparedParam { - const [, paramSize] = param.type.split('bytes') - const bytesSize = size(value) - if (!paramSize) { - let value_ = value - // If the size is not divisible by 32 bytes, pad the end - // with empty bytes to the ceiling 32 bytes. - if (bytesSize % 32 !== 0) - value_ = padHex(value_, { - right: true, - size: Math.ceil((value.length - 2) / 2 / 32) * 32, - }) - return { - dynamic: true, - encoded: concat([padHex(numberToHex(bytesSize)), value_]), - } - } - if (bytesSize !== parseInt(paramSize)) - throw new Error(`Invalid bytes${paramSize} length: ${bytesSize}`); - - return {dynamic: false, encoded: padHex(value, {right: true})} -} - -function encodeBool(value: boolean): PreparedParam { - return {dynamic: false, encoded: pad(value ? '1' : '0')} -} - -function encodeNumber( - value: number, - signed: boolean, -): PreparedParam { - return { - dynamic: false, - encoded: numberToHex(value, signed), - } -} - -const hexes = /*#__PURE__*/ Array.from({ length: 256 }, (_v, i) => - i.toString(16).padStart(2, '0'), -) - -export function bytesToHex(value: Uint8Array): Hex { - let string = '' - for (let i = 0; i < value.length; i++) { - string += hexes[value[i]] - } - return `0x${string}` as const -} - -function encodeString(value: string): PreparedParam { - const encoded = new TextEncoder().encode(value) - const partsLength = Math.ceil(encoded.length / 32) - const parts: Hex[] = [] - for (let i = 0; i < partsLength; i++) { - parts.push( - padHex(bytesToHex(encoded.slice(i * 32, (i + 1) * 32)), { - right: true, - }), - ) - } - return { - dynamic: true, - encoded: concat([ - padHex(numberToHex(encoded.length)), - ...parts, - ]), - } -} - -function encodeTuple< - const TParam extends AbiParameter & { components: readonly AbiParameter[] }, ->( - value: any, - {param}: { param: TParam }, -): PreparedParam { - let dynamic = false - const preparedParams: PreparedParam[] = [] - for (let i = 0; i < param.components.length; i++) { - const param_ = param.components[i] - const index = Array.isArray(value) ? i : param_.name - const preparedParam = prepareParam({ - param: param_, - value: (value as any)[index!], - }) - preparedParams.push(preparedParam) - if (preparedParam.dynamic) dynamic = true - } - return { - dynamic, - encoded: dynamic - ? encodeParams(preparedParams) - : concat(preparedParams.map(({encoded}) => encoded)), - } -} - -export function getArrayComponents( - type: string, -): [length: number | null, innerType: string] | undefined { - const matches = type.match(/^(.*)\[(\d+)?]$/) - return matches - ? // Return `null` if the array is dynamic. - [matches[2] ? Number(matches[2]) : null, matches[1]] - : undefined -} diff --git a/evm/evm-typegen/src/main.ts b/evm/evm-typegen/src/main.ts index 7ddc6737c..9e3d658c8 100644 --- a/evm/evm-typegen/src/main.ts +++ b/evm/evm-typegen/src/main.ts @@ -79,10 +79,6 @@ squid-evm-typegen src/abi 0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413#contract dest.add('abi.support.ts', [__dirname, '../src/abi.support.ts']) LOG.info(`saved ${dest.path('abi.support.ts')}`) - dest.add('decodeAbiParameters.ts', [__dirname, '../src/decodeAbiParameters.ts']) - LOG.info(`saved ${dest.path('decodeAbiParameters.ts')}`) - dest.add('encodeAbiParameters.ts', [__dirname, '../src/encodeAbiParameters.ts']) - LOG.info(`saved ${dest.path('encodeAbiParameters.ts')}`) if (opts.multicall) { dest.add('multicall.ts', [__dirname, '../src/multicall.ts']) diff --git a/evm/evm-typegen/src/util/types.ts b/evm/evm-typegen/src/util/types.ts index e55f725e2..84bfe954c 100644 --- a/evm/evm-typegen/src/util/types.ts +++ b/evm/evm-typegen/src/util/types.ts @@ -1,6 +1,6 @@ import assert from 'assert' import {AbiEventParameter, AbiParameter, parseAbiParameter} from "abitype"; -import {hasDynamicChild} from "../decodeAbiParameters"; +import {hasDynamicChild} from "@subsquid/evm-utils"; function parseArray(param: AbiParameter): { baseType: string, arrayChildren: AbiParameter } | undefined { let match = param.type.match(/^(.*)\[(\d*)]$/) diff --git a/evm/evm-utils/package.json b/evm/evm-utils/package.json new file mode 100644 index 000000000..d96296673 --- /dev/null +++ b/evm/evm-utils/package.json @@ -0,0 +1,26 @@ +{ + "name": "@subsquid/evm-utils", + "version": "1.0.0", + "description": "Utils for EVM encoding", + "license": "GPL-3.0-or-later", + "repository": "git@github.com:subsquid/squid.git", + "publishConfig": { + "access": "public" + }, + "files": [ + "lib", + "src" + ], + "main": "lib/index.js", + "scripts": { + "build": "rm -rf lib && tsc -p tsconfig.build.json", + "test": "vitest" + }, + "dependencies": {}, + "devDependencies": { + "@types/node": "^18.18.14", + "typescript": "~5.3.2", + "viem": "^2.7.11", + "vitest": "^1.3.1" + } +} diff --git a/evm/evm-typegen/src/decodeAbiParameters.ts b/evm/evm-utils/src/decodeAbiParameters.ts similarity index 97% rename from evm/evm-typegen/src/decodeAbiParameters.ts rename to evm/evm-utils/src/decodeAbiParameters.ts index f7bab5125..9f2ccc247 100644 --- a/evm/evm-typegen/src/decodeAbiParameters.ts +++ b/evm/evm-utils/src/decodeAbiParameters.ts @@ -1,19 +1,12 @@ -export interface AbiParameter { - name?: string; - type: string; -} +import {AbiParameter} from "./types"; class Cursor { bytes: Uint8Array; position: number; - positionReadCount: Map; - recursiveReadLimit: number; constructor(bytes: Uint8Array) { this.bytes = bytes; this.position = 0; - this.positionReadCount = new Map(); - this.recursiveReadLimit = 8_192; } inspectBytes(length: number) { @@ -346,10 +339,10 @@ export function hexToBigInt( if (!signed) return value; const size = (hex.length - 2) / 2; - const max = (1n << (BigInt(size) * 8n - 1n)); - if (value < max) return value; - - return value - max - 1n; + const max = (1n << (BigInt(size) * 8n - 1n)) - 1n; + if (value <= max) return value; + const mask = (1n << (BigInt(size) * 8n)); + return value - mask; } function bytesToNumber(bytes: Uint8Array, opts: { signed?: boolean } = {}) { diff --git a/evm/evm-utils/src/encodeAbiParameters.ts b/evm/evm-utils/src/encodeAbiParameters.ts new file mode 100644 index 000000000..415ae1fed --- /dev/null +++ b/evm/evm-utils/src/encodeAbiParameters.ts @@ -0,0 +1,313 @@ +import { AbiParameter, Hex } from "./types"; + +export function encodeFunctionData< + const TParams extends readonly AbiParameter[] | readonly unknown[] +>(signature: Hex, params: TParams, values: any[]) { + return concat([signature, encodeAbiParameters(params, values)]); +} + +/** + * @description Encodes a list of primitive values into an ABI-encoded hex value. + */ +export function encodeAbiParameters< + const TParams extends readonly AbiParameter[] | readonly unknown[] +>(params: TParams, values: any[]): Hex { + // Prepare the parameters to determine dynamic types to encode. + const preparedParams = prepareParams({ + params: params as readonly AbiParameter[], + values, + }); + const data = encodeParams(preparedParams); + if (data.length === 0) return "0x"; + return data; +} + +///////////////////////////////////////////////////////////////// + +type PreparedParam = { dynamic: boolean; encoded: Hex }; + +function prepareParams({ + params, + values, +}: { + params: TParams; + values: any[]; +}) { + const preparedParams: PreparedParam[] = []; + for (let i = 0; i < params.length; i++) { + preparedParams.push(prepareParam({ param: params[i], value: values[i] })); + } + return preparedParams; +} + +function prepareParam({ + param, + value, +}: { + param: TParam; + value: any[]; +}): PreparedParam { + const arrayComponents = getArrayComponents(param.type); + if (arrayComponents) { + const [length, type] = arrayComponents; + return encodeArray(value, { length, param: { ...param, type } }); + } + if (param.type === "tuple") { + return encodeTuple( + value as any, + { + param, + } as any + ); + } + if (param.type === "address") { + return encodeAddress(value as unknown as Hex); + } + if (param.type === "bool") { + return encodeBool(value as unknown as boolean); + } + if (param.type.startsWith("uint") || param.type.startsWith("int")) { + const signed = param.type.startsWith("int"); + return encodeNumber(value as unknown as number, signed); + } + if (param.type.startsWith("bytes")) { + return encodeBytes(value as unknown as Hex, { param }); + } + if (param.type === "string") { + return encodeString(value as unknown as string); + } + throw new Error(`Unknown type: ${param.type}`); +} + +///////////////////////////////////////////////////////////////// + +export function size(value: Hex) { + return Math.ceil((value.length - 2) / 2); +} + +function pad(value: string, size: number = 32): Hex { + return `0x${value.padStart(size * 2, "0")}`; +} + +function padRight(value: string, size: number = 32): Hex { + return `0x${value.padEnd(size * 2, "0")}`; +} + +function padHex(value: Hex, opts?: { right?: boolean; size?: number }): Hex { + if (opts?.right) { + return padRight(value.slice(2), opts.size); + } + return pad(value.slice(2), opts?.size); +} + +export function numberToHex(value_: number | bigint, signed = false): Hex { + const value = BigInt(value_); + const size = 32; + + let maxValue: bigint = 1n << 256n; + if (typeof value_ === "number") { + maxValue = BigInt(Number.MAX_SAFE_INTEGER); + } + + let minValue = 0n; + if (typeof value_ === "number" && signed) { + minValue = BigInt(Number.MIN_SAFE_INTEGER); + } else if (signed) { + minValue = -(1n << 255n); + } + + if ((maxValue && value > maxValue) || value < minValue) { + throw new Error( + `Number "${value}" is not in safe ${ + signed ? "signed" : "unsigned" + } integer range [${minValue}, ${maxValue}]` + ); + } + + const hex = `0x${(signed && value < 0 + ? (1n << BigInt(size * 8)) + BigInt(value) + : value + ).toString(16)}` as Hex; + return padHex(hex) as Hex; +} + +const concat = (hexes: Hex[]): Hex => + `0x${hexes.map((h) => h.slice(2)).join("")}`; + +function encodeParams(preparedParams: PreparedParam[]): Hex { + // 1. Compute the size of the static part of the parameters. + let staticSize = 0; + for (let i = 0; i < preparedParams.length; i++) { + const { dynamic, encoded } = preparedParams[i]; + if (dynamic) staticSize += 32; + else staticSize += size(encoded); + } + + // 2. Split the parameters into static and dynamic parts. + const staticParams: Hex[] = []; + const dynamicParams: Hex[] = []; + let dynamicSize = 0; + for (let i = 0; i < preparedParams.length; i++) { + const { dynamic, encoded } = preparedParams[i]; + if (dynamic) { + staticParams.push(numberToHex(staticSize + dynamicSize)); + dynamicParams.push(encoded); + dynamicSize += size(encoded); + } else { + staticParams.push(encoded); + } + } + + // 3. Concatenate static and dynamic parts. + return concat([...staticParams, ...dynamicParams]); +} + +///////////////////////////////////////////////////////////////// + +function encodeAddress(value: Hex): PreparedParam { + if (!value.match(/^0x[0-9a-fA-F]{40}$/)) + throw new Error(`Invalid address: ${value}`); + return { dynamic: false, encoded: padHex(value.toLowerCase() as Hex) }; +} + +function encodeArray( + value: any, + { + length, + param, + }: { + length: number | null; + param: TParam; + } +): PreparedParam { + const dynamic = length === null; + + if (!Array.isArray(value)) throw new Error(`Invalid array: ${value}`); + if (!dynamic && value.length !== length) + throw new Error( + `Invalid ${param.type}[${length}] array length: ${value.length}` + ); + + let dynamicChild = false; + const preparedParams: PreparedParam[] = []; + for (let i = 0; i < value.length; i++) { + const preparedParam = prepareParam({ param, value: value[i] }); + if (preparedParam.dynamic) dynamicChild = true; + preparedParams.push(preparedParam); + } + + if (dynamic || dynamicChild) { + const data = encodeParams(preparedParams); + if (dynamic) { + const length = numberToHex(preparedParams.length); + return { + dynamic: true, + encoded: preparedParams.length > 0 ? concat([length, data]) : length, + }; + } + if (dynamicChild) return { dynamic: true, encoded: data }; + } + return { + dynamic: false, + encoded: concat(preparedParams.map(({ encoded }) => encoded)), + }; +} + +function encodeBytes( + value: Hex, + { param }: { param: TParam } +): PreparedParam { + const [, paramSize] = param.type.split("bytes"); + const bytesSize = size(value); + if (!paramSize) { + let value_ = value; + // If the size is not divisible by 32 bytes, pad the end + // with empty bytes to the ceiling 32 bytes. + if (bytesSize % 32 !== 0) + value_ = padHex(value_, { + right: true, + size: Math.ceil((value.length - 2) / 2 / 32) * 32, + }); + return { + dynamic: true, + encoded: concat([padHex(numberToHex(bytesSize)), value_]), + }; + } + if (bytesSize !== parseInt(paramSize)) + throw new Error(`Invalid bytes${paramSize} length: ${bytesSize}`); + + return { dynamic: false, encoded: padHex(value, { right: true }) }; +} + +function encodeBool(value: boolean): PreparedParam { + return { dynamic: false, encoded: pad(value ? "1" : "0") }; +} + +function encodeNumber(value: number, signed: boolean): PreparedParam { + return { + dynamic: false, + encoded: numberToHex(value, signed), + }; +} + +const hexes = /*#__PURE__*/ Array.from({ length: 256 }, (_v, i) => + i.toString(16).padStart(2, "0") +); + +export function bytesToHex(value: Uint8Array): Hex { + let string = ""; + for (let i = 0; i < value.length; i++) { + string += hexes[value[i]]; + } + return `0x${string}` as const; +} + +function encodeString(value: string): PreparedParam { + const encoded = new TextEncoder().encode(value); + const partsLength = Math.ceil(encoded.length / 32); + const parts: Hex[] = []; + for (let i = 0; i < partsLength; i++) { + parts.push( + padHex(bytesToHex(encoded.slice(i * 32, (i + 1) * 32)), { + right: true, + }) + ); + } + return { + dynamic: true, + encoded: concat([padHex(numberToHex(encoded.length)), ...parts]), + }; +} + +function encodeTuple< + const TParam extends AbiParameter & { components: readonly AbiParameter[] } +>(value: any, { param }: { param: TParam }): PreparedParam { + let dynamic = false; + const preparedParams: PreparedParam[] = []; + for (let i = 0; i < param.components.length; i++) { + const param_ = param.components[i]; + const index = Array.isArray(value) ? i : param_.name; + const preparedParam = prepareParam({ + param: param_, + value: (value as any)[index!], + }); + preparedParams.push(preparedParam); + if (preparedParam.dynamic) dynamic = true; + } + return { + dynamic, + encoded: dynamic + ? encodeParams(preparedParams) + : concat(preparedParams.map(({ encoded }) => encoded)), + }; +} + +export function getArrayComponents( + type: string +): [length: number | null, innerType: string] | undefined { + const matches = type.match(/^(.*)\[(\d+)?]$/); + return matches + ? // Return `null` if the array is dynamic. + [matches[2] ? Number(matches[2]) : null, matches[1]] + : undefined; +} diff --git a/evm/evm-utils/src/index.ts b/evm/evm-utils/src/index.ts new file mode 100644 index 000000000..f6ddb9981 --- /dev/null +++ b/evm/evm-utils/src/index.ts @@ -0,0 +1,3 @@ +export {decodeAbiParameters, hasDynamicChild} from "./decodeAbiParameters"; +export {encodeAbiParameters, encodeFunctionData} from "./encodeAbiParameters"; +export * from "./types"; diff --git a/evm/evm-utils/src/types.ts b/evm/evm-utils/src/types.ts new file mode 100644 index 000000000..ccada31cb --- /dev/null +++ b/evm/evm-utils/src/types.ts @@ -0,0 +1,6 @@ +export interface AbiParameter { + name?: string; + type: string; +} + +export type Hex = `0x${string}` diff --git a/evm/evm-typegen/test/decodeAbiParameters.test.ts b/evm/evm-utils/test/decodeAbiParameters.test.ts similarity index 100% rename from evm/evm-typegen/test/decodeAbiParameters.test.ts rename to evm/evm-utils/test/decodeAbiParameters.test.ts diff --git a/evm/evm-typegen/test/encodeAbiParameters.test.ts b/evm/evm-utils/test/encodeAbiParameters.test.ts similarity index 100% rename from evm/evm-typegen/test/encodeAbiParameters.test.ts rename to evm/evm-utils/test/encodeAbiParameters.test.ts diff --git a/evm/evm-utils/test/hexToBigInt.test.ts b/evm/evm-utils/test/hexToBigInt.test.ts new file mode 100644 index 000000000..271642062 --- /dev/null +++ b/evm/evm-utils/test/hexToBigInt.test.ts @@ -0,0 +1,54 @@ +import { expect, describe, it } from "vitest"; +import { hexToBigInt } from "../src/decodeAbiParameters"; +import { encodeAbiParameters } from "viem"; +import { numberToHex } from "../src/encodeAbiParameters"; + +describe("hexToBigint", () => { + it("decodes positive numbers", () => { + expect( + hexToBigInt( + "0x0000000000000000000000000000000000000000000000000000000000001234", + { signed: true } + ) + ).toBe(0x1234n); + expect(hexToBigInt("0x00", { signed: true })).toBe(0n); + }); + + it("decodes negative numbers", () => { + const check = (neg: bigint) => + expect( + hexToBigInt(encodeAbiParameters([{ type: "int256" }], [neg]), { + signed: true, + }) + ).toBe(neg); + check(-1n); + check(-63n); + check(-64n); + check((-1n << 64n) - 1n); + check(-1n << 64n); + check(-1n << 255n); + }); +}); + +describe("bigIntToHex", () => { + it("encodes positive numbers", () => { + expect(numberToHex(0x1234n, true)).toBe( + "0x0000000000000000000000000000000000000000000000000000000000001234" + ); + expect(numberToHex(0n, true)).toBe( + "0x0000000000000000000000000000000000000000000000000000000000000000" + ); + }); + + it("encodes negative numbers", () => { + expect(numberToHex(-1n, true)).toBe( + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + ); + expect(numberToHex(-1, true)).toBe( + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + ); + expect(numberToHex(-1n << 255n, true)).toBe( + "0x8000000000000000000000000000000000000000000000000000000000000000" + ); + }); +}); diff --git a/evm/evm-utils/tsconfig.build.json b/evm/evm-utils/tsconfig.build.json new file mode 100644 index 000000000..3a56256a1 --- /dev/null +++ b/evm/evm-utils/tsconfig.build.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "include": ["src"], + "exclude": [ + "node_modules", + "test" + ], +} diff --git a/evm/evm-utils/tsconfig.json b/evm/evm-utils/tsconfig.json new file mode 100644 index 000000000..64b1b2857 --- /dev/null +++ b/evm/evm-utils/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es2020", + "outDir": "lib", + "rootDir": "src", + "allowJs": true, + "strict": true, + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "esModuleInterop": true, + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "skipLibCheck": true + }, + "include": [ + "src", + "test" + ], + "exclude": [ + "node_modules" + ] +} From 031c5c8a85f36eb4c610111aa41e43a76f0f0551 Mon Sep 17 00:00:00 2001 From: ivan Date: Mon, 4 Mar 2024 11:47:18 +0100 Subject: [PATCH 07/12] Update example --- test/erc20-transfers/package.json | 3 +- test/erc20-transfers/src/abi/abi.support.ts | 55 +-- .../src/abi/decodeAbiParameters.ts | 360 ------------------ .../src/abi/encodeAbiParameters.ts | 318 ---------------- test/erc20-transfers/src/abi/erc20.ts | 39 +- 5 files changed, 63 insertions(+), 712 deletions(-) delete mode 100644 test/erc20-transfers/src/abi/decodeAbiParameters.ts delete mode 100644 test/erc20-transfers/src/abi/encodeAbiParameters.ts diff --git a/test/erc20-transfers/package.json b/test/erc20-transfers/package.json index 2e427aa98..1cdd43ec4 100644 --- a/test/erc20-transfers/package.json +++ b/test/erc20-transfers/package.json @@ -6,8 +6,9 @@ "build": "rm -rf lib && tsc" }, "dependencies": { - "@subsquid/graphql-server": "^4.5.0", "@subsquid/evm-processor": "^1.16.0", + "@subsquid/evm-utils": "../../evm/evm-utils", + "@subsquid/graphql-server": "^4.5.0", "@subsquid/typeorm-migration": "^1.3.0", "@subsquid/typeorm-store": "^1.2.6", "dotenv": "^16.3.1", diff --git a/test/erc20-transfers/src/abi/abi.support.ts b/test/erc20-transfers/src/abi/abi.support.ts index 7acfec7d3..fd7b3d60e 100644 --- a/test/erc20-transfers/src/abi/abi.support.ts +++ b/test/erc20-transfers/src/abi/abi.support.ts @@ -1,8 +1,14 @@ -import {type AbiParameter, decodeAbiParameters, hasDynamicChild} from './decodeAbiParameters' -import {encodeFunctionData} from "./encodeAbiParameters"; +import {decodeAbiParameters, hasDynamicChild, encodeFunctionData} from '@subsquid/evm-utils' type Hex = `0x${string}` +export interface AbiParameter { + name?: string + type: string, + components?: AbiParameter[] + internalType?: string +} + export interface EventRecord { topics: string[] data: string @@ -22,18 +28,13 @@ type EventType = { name: string } -type SecondElements = T extends [] ? [] : T extends [[any, infer U], ...infer Tail extends [any, any][]] ? [U, ...SecondElements] : never -type Args = { - [K in T[number] as K[0]]: K[1] -} & SecondElements - function assertIsHex(val: unknown): asserts val is Hex { if (typeof val !== 'string' || !val.startsWith('0x')) { throw new Error('Not a hex string') } } -export class LogEvent { +export class LogEvent { private indexedArgs: ((AbiParameter & {index: number}) | null)[] = []; private nonIndexedArgs: (AbiParameter & {index: number})[] = []; @@ -68,18 +69,19 @@ export class LogEvent { return rec.topics[0] === this.topic } - decode(rec: EventRecord) { + decode(rec: EventRecord): TEventArgs { if (!this.is(rec)) { throw new Error('Invalid event record') } assertIsHex(rec.data) - const result: any = [] + const result: any = {} const parsedData = decodeAbiParameters(this.nonIndexedArgs, rec.data) for (let i = 0; i < parsedData.length; i++) { if (this.nonIndexedArgs[i].name) { result[this.nonIndexedArgs[i].name!] = parsedData[i] + } else { + result[`_${this.nonIndexedArgs[i].index}`] = parsedData[i] } - result[this.nonIndexedArgs[i].index] = parsedData[i] } rec.topics.slice(1).forEach((topic, i) => { const type = this.indexedArgs[i] @@ -88,11 +90,12 @@ export class LogEvent { const [parsedData] = decodeAbiParameters([type], topic) if (type.name) { result[type.name] = parsedData + } else { + result[`_${type.index}`] = parsedData } - result[type.index] = parsedData } }) - return result as Args + return result } } @@ -101,7 +104,7 @@ export interface FuncRecord { input: string } -export class Func { +export class Func { public readonly sighash: Hex constructor(sighash: string, private readonly args: AbiParameter[], private readonly result: AbiParameter[]) { assertIsHex(sighash) @@ -113,29 +116,37 @@ export class Func { return sighash === this.sighash } - decode(input: string): Args - decode(rec: FuncRecord): Args - decode(inputOrRec: string | FuncRecord): Args { + decode(input: string): TFunctionArgs + decode(rec: FuncRecord): TFunctionArgs + decode(inputOrRec: string | FuncRecord): TFunctionArgs { const input = typeof inputOrRec === 'string' ? inputOrRec : inputOrRec.input assertIsHex(input) if (!this.is({input})) { throw new Error('Invalid event record') } - return decodeAbiParameters(this.args, `0x${input.slice(10)}`) as Args + const decodedResult = decodeAbiParameters(this.args, `0x${input.slice(10)}`) + return this.toNamedArgs(decodedResult) as TFunctionArgs } - encode(...args: SecondElements) { + encode(...args: TFunctionArgs[keyof TFunctionArgs][]) { return encodeFunctionData(this.sighash, this.args, args) } - decodeResult(output: string): Result { + decodeResult(output: string): TResult { assertIsHex(output) const decoded = decodeAbiParameters(this.result, output) return decoded.length > 1 ? decoded : decoded[0] } - tryDecodeResult(output: string): Result | undefined { + private toNamedArgs(values: any[]) { + return Object.fromEntries(this.args.map((arg, i) => { + const name = arg.name || `_${i}` + return [name, values[i]] as const + })) + } + + tryDecodeResult(output: string): TResult | undefined { try { return this.decodeResult(output) } catch(err: any) { @@ -200,7 +211,7 @@ export class ContractBase { assertIsHex(this.address) } - async eth_call(func: Func, args: SecondElements): Promise { + async eth_call(func: Func, args: TFunctionArgs[keyof TFunctionArgs][]): Promise { let data = func.encode(...args) let result = await this._chain.client.call('eth_call', [ {to: this.address, data}, diff --git a/test/erc20-transfers/src/abi/decodeAbiParameters.ts b/test/erc20-transfers/src/abi/decodeAbiParameters.ts deleted file mode 100644 index 83f32a254..000000000 --- a/test/erc20-transfers/src/abi/decodeAbiParameters.ts +++ /dev/null @@ -1,360 +0,0 @@ -export interface AbiParameter { - name?: string - type: string -} - -class Cursor { - bytes: Uint8Array - position: number - positionReadCount: Map - recursiveReadLimit: number - - constructor(bytes: Uint8Array) { - this.bytes = bytes - this.position = 0 - this.positionReadCount = new Map() - this.recursiveReadLimit = 8_192 - } - - inspectBytes(length: number) { - return this.bytes.subarray(this.position, this.position + length) - } - public readBytes(length: number, size?: number) { - const value = this.inspectBytes(length) - this.position += size ?? length - return value - } - public setPosition(position: number) { - const oldPosition = this.position - this.position = position - return () => (this.position = oldPosition) - } -} - -export function decodeAbiParameters( - params: AbiParameter[], - data: `0x${string}`, -) { - const bytes = Buffer.from(data.slice(2), 'hex') - const cursor = new Cursor(bytes) - - let consumed = 0 - const values = [] - for (let i = 0; i < params.length; ++i) { - const param = params[i] - cursor.setPosition(consumed) - const [data, consumed_] = decodeParameter(cursor, param, { - staticPosition: 0, - }) - consumed += consumed_ - values.push(data) - } - return values -} - -export function getArrayComponents( - type: string, -): [length: number | null, innerType: string] | undefined { - const matches = type.match(/^(.*)\[(\d+)?]$/) - return matches - ? // Return `null` if the array is dynamic. - [matches[2] ? Number(matches[2]) : null, matches[1]] - : undefined -} - -function decodeParameter( - cursor: Cursor, - param: AbiParameter, - { staticPosition }: { staticPosition: number }, -): readonly [any, number] { - const arrayComponents = getArrayComponents(param.type) - if (arrayComponents) { - const [length, type] = arrayComponents - return decodeArray(cursor, { ...param, type }, { length, staticPosition }) - } - if (param.type === 'tuple') - return decodeTuple(cursor, param as TupleAbiParameter, { staticPosition }) - - if (param.type === 'address') return decodeAddress(cursor) - if (param.type === 'bool') return decodeBool(cursor) - if (param.type.startsWith('bytes')) - return decodeBytes(cursor, param, { staticPosition }) - if (param.type.startsWith('uint') || param.type.startsWith('int')) - return decodeNumber(cursor, param) - if (param.type === 'string') return decodeString(cursor, { staticPosition }) - throw new Error(`Unknown type: ${param.type}`) -} - -//////////////////////////////////////////////////////////////////// -// Type Decoders - -const sizeOfLength = 32 -const sizeOfOffset = 32 - -function decodeAddress(cursor: Cursor) { - const value = cursor.readBytes(sizeOfOffset) - return [bytesToHex(value.slice(-20)), sizeOfLength] as const -} - -function decodeArray( - cursor: Cursor, - param: AbiParameter, - { length, staticPosition }: { length: number | null; staticPosition: number }, -) { - // If the length of the array is not known in advance (dynamic array), - // this means we will need to wonder off to the pointer and decode. - if (!length) { - // Dealing with a dynamic type, so get the offset of the array data. - const offset = bytesToNumber(cursor.readBytes(sizeOfOffset)) - - // Start is the static position of current slot + offset. - const start = staticPosition + offset - const startOfData = start + sizeOfLength - - // Get the length of the array from the offset. - cursor.setPosition(start) - const length = bytesToNumber(cursor.readBytes(sizeOfLength)) - - // Check if the array has any dynamic children. - const dynamicChild = hasDynamicChild(param) - - let consumed = 0 - const value: unknown[] = [] - for (let i = 0; i < length; ++i) { - // If any of the children is dynamic, then all elements will be offset pointer, thus size of one slot (32 bytes). - // Otherwise, elements will be the size of their encoding (consumed bytes). - cursor.setPosition(startOfData + (dynamicChild ? i * 32 : consumed)) - const [data, consumed_] = decodeParameter(cursor, param, { - staticPosition: startOfData, - }) - consumed += consumed_ - value.push(data) - } - - // As we have gone wondering, restore to the original position + next slot. - cursor.setPosition(staticPosition + 32) - return [value, 32] as const - } - - // If the length of the array is known in advance, - // and the length of an element deeply nested in the array is not known, - // we need to decode the offset of the array data. - if (hasDynamicChild(param)) { - // Dealing with dynamic types, so get the offset of the array data. - const offset = bytesToNumber(cursor.readBytes(sizeOfOffset)) - - // Start is the static position of current slot + offset. - const start = staticPosition + offset - - const value: unknown[] = [] - for (let i = 0; i < length; ++i) { - // Move cursor along to the next slot (next offset pointer). - cursor.setPosition(start + i * 32) - const [data] = decodeParameter(cursor, param, { - staticPosition: start, - }) - value.push(data) - } - - // As we have gone wondering, restore to the original position + next slot. - cursor.setPosition(staticPosition + 32) - return [value, 32] as const - } - - // If the length of the array is known in advance and the array is deeply static, - // then we can just decode each element in sequence. - let consumed = 0 - const value: unknown[] = [] - for (let i = 0; i < length; ++i) { - const [data, consumed_] = decodeParameter(cursor, param, { - staticPosition: staticPosition + consumed, - }) - consumed += consumed_ - value.push(data) - } - return [value, consumed] as const -} - -function decodeBool(cursor: Cursor) { - return [bytesToBool(cursor.readBytes(32), 32), 32] as const -} - -function decodeBytes( - cursor: Cursor, - param: AbiParameter, - { staticPosition }: { staticPosition: number }, -) { - const [_, size] = param.type.split('bytes') - if (!size) { - // Dealing with dynamic types, so get the offset of the bytes data. - const offset = bytesToNumber(cursor.readBytes(32)) - - // Set position of the cursor to start of bytes data. - cursor.setPosition(staticPosition + offset) - - const length = bytesToNumber(cursor.readBytes(32)) - - // If there is no length, we have zero data. - if (length === 0) { - // As we have gone wondering, restore to the original position + next slot. - cursor.setPosition(staticPosition + 32) - return ['0x', 32] as const - } - - const data = cursor.readBytes(length) - - // As we have gone wondering, restore to the original position + next slot. - cursor.setPosition(staticPosition + 32) - return [bytesToHex(data), 32] as const - } - - const value = bytesToHex(cursor.readBytes(parseInt(size), 32)) - return [value, 32] as const -} - -function decodeNumber(cursor: Cursor, param: AbiParameter) { - const signed = param.type.startsWith('int') - const size = parseInt(param.type.split('int')[1] || '256') - const value = cursor.readBytes(32) - return [ - size > 48 - ? bytesToBigInt(value, { signed }) - : bytesToNumber(value, { signed }), - 32, - ] as const -} - -type TupleAbiParameter = AbiParameter & { components: readonly AbiParameter[] } - -function decodeTuple( - cursor: Cursor, - param: TupleAbiParameter, - { staticPosition }: { staticPosition: number }, -) { - // Tuples can have unnamed components (i.e. they are arrays), so we must - // determine whether the tuple is named or unnamed. In the case of a named - // tuple, the value will be an object where each property is the name of the - // component. In the case of an unnamed tuple, the value will be an array. - const hasUnnamedChild = - param.components.length === 0 || param.components.some(({ name }) => !name) - - // Initialize the value to an object or an array, depending on whether the - // tuple is named or unnamed. - const value: any = hasUnnamedChild ? [] : {} - let consumed = 0 - - // If the tuple has a dynamic child, we must first decode the offset to the - // tuple data. - if (hasDynamicChild(param)) { - // Dealing with dynamic types, so get the offset of the tuple data. - const offset = bytesToNumber(cursor.readBytes(sizeOfOffset)) - - // Start is the static position of referencing slot + offset. - const start = staticPosition + offset - - for (let i = 0; i < param.components.length; ++i) { - const component = param.components[i] - cursor.setPosition(start + consumed) - const [data, consumed_] = decodeParameter(cursor, component, { - staticPosition: start, - }) - consumed += consumed_ - value[hasUnnamedChild ? i : component?.name!] = data - } - - // As we have gone wondering, restore to the original position + next slot. - cursor.setPosition(staticPosition + 32) - return [value, 32] as const - } - - // If the tuple has static children, we can just decode each component - // in sequence. - for (let i = 0; i < param.components.length; ++i) { - const component = param.components[i] - const [data, consumed_] = decodeParameter(cursor, component, { - staticPosition, - }) - value[hasUnnamedChild ? i : component?.name!] = data - consumed += consumed_ - } - return [value, consumed] as const -} - -function decodeString( - cursor: Cursor, - { staticPosition }: { staticPosition: number }, -) { - // Get offset to start of string data. - const offset = bytesToNumber(cursor.readBytes(32)) - - // Start is the static position of current slot + offset. - const start = staticPosition + offset - cursor.setPosition(start) - - const length = bytesToNumber(cursor.readBytes(32)) - - // If there is no length, we have zero data (empty string). - if (length === 0) { - cursor.setPosition(staticPosition + 32) - return ['', 32] as const - } - - const data = cursor.readBytes(length, 32) - const value = new TextDecoder().decode(data) - - // As we have gone wondering, restore to the original position + next slot. - cursor.setPosition(staticPosition + 32) - - return [value, 32] as const -} - -export function hasDynamicChild(param: AbiParameter) { - const { type } = param - if (type === 'string') return true - if (type === 'bytes') return true - if (type.endsWith('[]')) return true - - if (type === 'tuple') return (param as any).components?.some(hasDynamicChild) - - const arrayComponents = getArrayComponents(param.type) - if ( - arrayComponents && - hasDynamicChild({ ...param, type: arrayComponents[1] } as AbiParameter) - ) - return true - - return false -} - -//////////////////////////////////////////////////////////////////// -/// Bytes parsing - -const bytesToHex = (bytes: Uint8Array): `0x${string}` => { - return `0x${Array.from(bytes).map((byte) => byte.toString(16).padStart(2, '0')).join('')}` -} - -export function hexToBigInt(hex: `0x${string}`, opts: { signed?: boolean } = {}): bigint { - const {signed} = opts - const value = BigInt(hex) - if (!signed) return value - - const size = (hex.length - 2) / 2 - const max = (1n << (BigInt(size) * 8n - 1n)) - 1n - if (value <= max) return value - - return value - BigInt(`0x${'f'.padStart(size * 2, 'f')}`) - 1n -} - -function bytesToNumber(bytes: Uint8Array, opts: { signed?: boolean } = {}) { - const value = bytesToHex(bytes) - return Number(hexToBigInt(value, opts)) -} - -function bytesToBool(bytes: Uint8Array, size: number) { - return bytes[size - 1] !== 0 -} - -function bytesToBigInt(bytes: Uint8Array, opts: { signed?: boolean } = {}) { - const value = bytesToHex(bytes) - return hexToBigInt(value, opts) -} diff --git a/test/erc20-transfers/src/abi/encodeAbiParameters.ts b/test/erc20-transfers/src/abi/encodeAbiParameters.ts deleted file mode 100644 index 55eedd93c..000000000 --- a/test/erc20-transfers/src/abi/encodeAbiParameters.ts +++ /dev/null @@ -1,318 +0,0 @@ -import {AbiParameter} from "./decodeAbiParameters"; - -type Hex = `0x${string}` - -export function encodeFunctionData< - const TParams extends readonly AbiParameter[] | readonly unknown[], ->( - signature: Hex, - params: TParams, - values: any[] -) { - return concat([signature, encodeAbiParameters(params, values)]) -} - -/** - * @description Encodes a list of primitive values into an ABI-encoded hex value. - */ -export function encodeAbiParameters< - const TParams extends readonly AbiParameter[] | readonly unknown[], ->( - params: TParams, - values: any[] -): Hex { - // Prepare the parameters to determine dynamic types to encode. - const preparedParams = prepareParams({ - params: params as readonly AbiParameter[], - values, - }) - const data = encodeParams(preparedParams) - if (data.length === 0) return '0x' - return data -} - -///////////////////////////////////////////////////////////////// - -type PreparedParam = { dynamic: boolean; encoded: Hex } - -function prepareParams({ - params, - values, - }: { - params: TParams - values: any[] -}) { - const preparedParams: PreparedParam[] = [] - for (let i = 0; i < params.length; i++) { - preparedParams.push(prepareParam({param: params[i], value: values[i]})) - } - return preparedParams -} - -function prepareParam({ - param, - value, - }: { - param: TParam - value: any[] -}): PreparedParam { - const arrayComponents = getArrayComponents(param.type) - if (arrayComponents) { - const [length, type] = arrayComponents - return encodeArray(value, {length, param: {...param, type}}) - } - if (param.type === 'tuple') { - return encodeTuple(value as any, { - param, - } as any) - } - if (param.type === 'address') { - return encodeAddress(value as unknown as Hex) - } - if (param.type === 'bool') { - return encodeBool(value as unknown as boolean) - } - if (param.type.startsWith('uint') || param.type.startsWith('int')) { - const signed = param.type.startsWith('int') - return encodeNumber(value as unknown as number, signed) - } - if (param.type.startsWith('bytes')) { - return encodeBytes(value as unknown as Hex, {param}) - } - if (param.type === 'string') { - return encodeString(value as unknown as string) - } - throw new Error(`Unknown type: ${param.type}`); -} - -///////////////////////////////////////////////////////////////// - -export function size(value: Hex) { - return Math.ceil((value.length - 2) / 2) -} - -function pad(value: string, size: number = 32): Hex { - return `0x${value.padStart(size * 2, '0')}` -} - -function padRight(value: string, size: number = 32): Hex { - return `0x${value.padEnd(size * 2, '0')}` -} - -function padHex(value: Hex, opts?: {right?: boolean, size?: number}): Hex { - if (opts?.right) { - return padRight(value.slice(2), opts.size) - } - return pad(value.slice(2), opts?.size) -} - -export function numberToHex( - value_: number | bigint, - signed = false -): Hex { - const value = BigInt(value_) - const size = 32 - - let maxValue: bigint | number = 0 - if (typeof value_ === 'number') { - maxValue = BigInt(Number.MAX_SAFE_INTEGER) - } - - const minValue = typeof maxValue === 'bigint' && signed ? -maxValue - 1n : 0 - - if ((maxValue && value > maxValue) || value < minValue) { - throw new Error(`Number "${value}" is not in safe ${signed ? 'signed' : 'unsigned'} integer range [${minValue}, ${maxValue}]`); - } - - const hex = `0x${(signed && value < 0 - ? (1n << BigInt(size * 8)) + BigInt(value) - : value - ).toString(16)}` as Hex - return padHex(hex) as Hex -} - -const concat = (hexes: Hex[]): Hex => `0x${hexes.map((h) => h.slice(2)).join('')}` - -function encodeParams(preparedParams: PreparedParam[]): Hex { - // 1. Compute the size of the static part of the parameters. - let staticSize = 0 - for (let i = 0; i < preparedParams.length; i++) { - const {dynamic, encoded} = preparedParams[i] - if (dynamic) staticSize += 32 - else staticSize += size(encoded) - } - - // 2. Split the parameters into static and dynamic parts. - const staticParams: Hex[] = [] - const dynamicParams: Hex[] = [] - let dynamicSize = 0 - for (let i = 0; i < preparedParams.length; i++) { - const {dynamic, encoded} = preparedParams[i] - if (dynamic) { - staticParams.push(numberToHex(staticSize + dynamicSize)) - dynamicParams.push(encoded) - dynamicSize += size(encoded) - } else { - staticParams.push(encoded) - } - } - - // 3. Concatenate static and dynamic parts. - return concat([...staticParams, ...dynamicParams]) -} - -///////////////////////////////////////////////////////////////// - -function encodeAddress(value: Hex): PreparedParam { - if (!value.match(/^0x[0-9a-fA-F]{40}$/)) throw new Error(`Invalid address: ${value}`); - return {dynamic: false, encoded: padHex(value.toLowerCase() as Hex)} -} - -function encodeArray( - value: any, - { - length, - param, - }: { - length: number | null - param: TParam - }, -): PreparedParam { - const dynamic = length === null - - if (!Array.isArray(value)) throw new Error(`Invalid array: ${value}`); - if (!dynamic && value.length !== length) - throw new Error(`Invalid ${param.type}[${length}] array length: ${value.length}`); - - let dynamicChild = false - const preparedParams: PreparedParam[] = [] - for (let i = 0; i < value.length; i++) { - const preparedParam = prepareParam({param, value: value[i]}) - if (preparedParam.dynamic) dynamicChild = true - preparedParams.push(preparedParam) - } - - if (dynamic || dynamicChild) { - const data = encodeParams(preparedParams) - if (dynamic) { - const length = numberToHex(preparedParams.length) - return { - dynamic: true, - encoded: preparedParams.length > 0 ? concat([length, data]) : length, - } - } - if (dynamicChild) return {dynamic: true, encoded: data} - } - return { - dynamic: false, - encoded: concat(preparedParams.map(({encoded}) => encoded)), - } -} - -function encodeBytes( - value: Hex, - {param}: { param: TParam }, -): PreparedParam { - const [, paramSize] = param.type.split('bytes') - const bytesSize = size(value) - if (!paramSize) { - let value_ = value - // If the size is not divisible by 32 bytes, pad the end - // with empty bytes to the ceiling 32 bytes. - if (bytesSize % 32 !== 0) - value_ = padHex(value_, { - right: true, - size: Math.ceil((value.length - 2) / 2 / 32) * 32, - }) - return { - dynamic: true, - encoded: concat([padHex(numberToHex(bytesSize)), value_]), - } - } - if (bytesSize !== parseInt(paramSize)) - throw new Error(`Invalid bytes${paramSize} length: ${bytesSize}`); - - return {dynamic: false, encoded: padHex(value, {right: true})} -} - -function encodeBool(value: boolean): PreparedParam { - return {dynamic: false, encoded: pad(value ? '1' : '0')} -} - -function encodeNumber( - value: number, - signed: boolean, -): PreparedParam { - return { - dynamic: false, - encoded: numberToHex(value, signed), - } -} - -const hexes = /*#__PURE__*/ Array.from({ length: 256 }, (_v, i) => - i.toString(16).padStart(2, '0'), -) - -export function bytesToHex(value: Uint8Array): Hex { - let string = '' - for (let i = 0; i < value.length; i++) { - string += hexes[value[i]] - } - return `0x${string}` as const -} - -function encodeString(value: string): PreparedParam { - const encoded = new TextEncoder().encode(value) - const partsLength = Math.ceil(encoded.length / 32) - const parts: Hex[] = [] - for (let i = 0; i < partsLength; i++) { - parts.push( - padHex(bytesToHex(encoded.slice(i * 32, (i + 1) * 32)), { - right: true, - }), - ) - } - return { - dynamic: true, - encoded: concat([ - padHex(numberToHex(encoded.length)), - ...parts, - ]), - } -} - -function encodeTuple< - const TParam extends AbiParameter & { components: readonly AbiParameter[] }, ->( - value: any, - {param}: { param: TParam }, -): PreparedParam { - let dynamic = false - const preparedParams: PreparedParam[] = [] - for (let i = 0; i < param.components.length; i++) { - const param_ = param.components[i] - const index = Array.isArray(value) ? i : param_.name - const preparedParam = prepareParam({ - param: param_, - value: (value as any)[index!], - }) - preparedParams.push(preparedParam) - if (preparedParam.dynamic) dynamic = true - } - return { - dynamic, - encoded: dynamic - ? encodeParams(preparedParams) - : concat(preparedParams.map(({encoded}) => encoded)), - } -} - -export function getArrayComponents( - type: string, -): [length: number | null, innerType: string] | undefined { - const matches = type.match(/^(.*)\[(\d+)?]$/) - return matches - ? // Return `null` if the array is dynamic. - [matches[2] ? Number(matches[2]) : null, matches[1]] - : undefined -} diff --git a/test/erc20-transfers/src/abi/erc20.ts b/test/erc20-transfers/src/abi/erc20.ts index ec40e316f..2ea14a2dc 100644 --- a/test/erc20-transfers/src/abi/erc20.ts +++ b/test/erc20-transfers/src/abi/erc20.ts @@ -1,57 +1,74 @@ import {LogEvent, Func, ContractBase} from './abi.support' +export type EventTypes = { + Approval: { owner: string, spender: string, value: bigint }, + Transfer: { from: string, to: string, value: bigint }, +} + +export type FunctionTypes = { + name: {args: { }, return: string}, + approve: {args: { _spender: string, _value: bigint }, return: boolean}, + totalSupply: {args: { }, return: bigint}, + transferFrom: {args: { _from: string, _to: string, _value: bigint }, return: boolean}, + decimals: {args: { }, return: number}, + balanceOf: {args: { _owner: string }, return: bigint}, + symbol: {args: { }, return: string}, + transfer: {args: { _to: string, _value: bigint }, return: boolean}, + allowance: {args: { _owner: string, _spender: string }, return: bigint}, +} + export const events = { - Approval: new LogEvent<[['owner',string],['spender',string],['value',bigint]]>( + Approval: new LogEvent( '0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925', [{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}] ), - Transfer: new LogEvent<[['from',string],['to',string],['value',bigint]]>( + Transfer: new LogEvent( '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef', [{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}] ), } export const functions = { - name: new Func<[], string>( + name: new Func( '0x06fdde03', [], [{"name":"","type":"string"}] ), - approve: new Func<[['_spender',string],['_value',bigint]], boolean>( + approve: new Func( '0x095ea7b3', [{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}], [{"name":"","type":"bool"}] ), - totalSupply: new Func<[], bigint>( + totalSupply: new Func( '0x18160ddd', [], [{"name":"","type":"uint256"}] ), - transferFrom: new Func<[['_from',string],['_to',string],['_value',bigint]], boolean>( + transferFrom: new Func( '0x23b872dd', [{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}], [{"name":"","type":"bool"}] ), - decimals: new Func<[], number>( + decimals: new Func( '0x313ce567', [], [{"name":"","type":"uint8"}] ), - balanceOf: new Func<[['_owner',string]], bigint>( + balanceOf: new Func( '0x70a08231', [{"name":"_owner","type":"address"}], [{"name":"balance","type":"uint256"}] ), - symbol: new Func<[], string>( + symbol: new Func( '0x95d89b41', [], [{"name":"","type":"string"}] ), - transfer: new Func<[['_to',string],['_value',bigint]], boolean>( + transfer: new Func( '0xa9059cbb', [{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}], [{"name":"","type":"bool"}] ), - allowance: new Func<[['_owner',string],['_spender',string]], bigint>( + allowance: new Func( '0xdd62ed3e', [{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}], [{"name":"","type":"uint256"}] From 1d7bdbfb0acbafad68de2a7e765aebf8778a3294 Mon Sep 17 00:00:00 2001 From: ivan Date: Mon, 4 Mar 2024 11:56:53 +0100 Subject: [PATCH 08/12] Add package to rush --- rush.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rush.json b/rush.json index 1554a1af3..3cff88481 100644 --- a/rush.json +++ b/rush.json @@ -462,6 +462,12 @@ "shouldPublish": true, "versionPolicyName": "npm" }, + { + "packageName": "@subsquid/evm-utils", + "projectFolder": "evm/evm-utils", + "shouldPublish": true, + "versionPolicyName": "npm" + }, { "packageName": "@subsquid/graphql-server", "projectFolder": "graphql/graphql-server", From 9f0ccdeb962109ce8c91ff1a6575ddb9534a05d6 Mon Sep 17 00:00:00 2001 From: ivan Date: Mon, 4 Mar 2024 12:08:20 +0100 Subject: [PATCH 09/12] update lockfiles --- common/config/rush/pnpm-lock.yaml | 3414 +++++++++++++++++++---------- evm/evm-typegen/package.json | 2 +- test/erc20-transfers/package.json | 4 +- 3 files changed, 2212 insertions(+), 1208 deletions(-) diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 0616aeb23..a2f7c9c60 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -13,19 +13,19 @@ dependencies: version: 1.0.2 '@aws-sdk/client-s3': specifier: ^3.462.0 - version: 3.462.0 + version: 3.525.0 '@exodus/schemasafe': specifier: ^1.3.0 version: 1.3.0 '@graphql-tools/merge': specifier: ^9.0.1 - version: 9.0.1(graphql@15.8.0) + version: 9.0.3(graphql@15.8.0) '@graphql-tools/schema': specifier: ^10.0.2 - version: 10.0.2(graphql@15.8.0) + version: 10.0.3(graphql@15.8.0) '@graphql-tools/utils': specifier: ^10.0.11 - version: 10.0.11(graphql@15.8.0) + version: 10.1.0(graphql@15.8.0) '@keyv/redis': specifier: ~2.5.8 version: 2.5.8(supports-color@8.1.1) @@ -55,7 +55,10 @@ dependencies: version: file:projects/evm-processor.tgz '@rush-temp/evm-typegen': specifier: file:./projects/evm-typegen.tgz - version: file:projects/evm-typegen.tgz + version: file:projects/evm-typegen.tgz(supports-color@8.1.1) + '@rush-temp/evm-utils': + specifier: file:./projects/evm-utils.tgz + version: file:projects/evm-utils.tgz(supports-color@8.1.1) '@rush-temp/frontier': specifier: file:./projects/frontier.tgz version: file:projects/frontier.tgz @@ -212,6 +215,9 @@ dependencies: '@rush-temp/workspace': specifier: file:./projects/workspace.tgz version: file:projects/workspace.tgz + '@subsquid/evm-typegen': + specifier: ^3.3.0 + version: 3.3.0(ethers@6.11.1) '@subsquid/graphiql-console': specifier: ^0.3.0 version: 0.3.0 @@ -232,13 +238,13 @@ dependencies: version: 10.0.6 '@types/node': specifier: ^18.18.14 - version: 18.18.14 + version: 18.19.21 '@types/pg': specifier: ^8.10.9 - version: 8.10.9 + version: 8.11.2 '@types/semver': specifier: ^7.5.6 - version: 7.5.6 + version: 7.5.8 '@types/stoppable': specifier: ^1.1.3 version: 1.1.3 @@ -254,6 +260,9 @@ dependencies: '@types/xxhashjs': specifier: ^0.2.4 version: 0.2.4 + abitype: + specifier: ^1.0.0 + version: 1.0.1(typescript@5.3.3) ajv: specifier: ^8.12.0 version: 8.12.0 @@ -262,7 +271,7 @@ dependencies: version: 3.13.0(graphql@15.8.0) apollo-server-express: specifier: ^3.13.0 - version: 3.13.0(express@4.18.2)(graphql@15.8.0) + version: 3.13.0(express@4.18.3)(graphql@15.8.0) apollo-server-plugin-response-cache: specifier: ~3.7.1 version: 3.7.1(graphql@15.8.0) @@ -286,19 +295,19 @@ dependencies: version: 2.2.3 dotenv: specifier: ^16.3.1 - version: 16.3.1 + version: 16.4.5 ethers: specifier: ^6.9.0 - version: 6.9.0 + version: 6.11.1 expect: specifier: ^29.7.0 version: 29.7.0 express: specifier: ^4.18.2 - version: 4.18.2 + version: 4.18.3 fast-check: specifier: ^3.14.0 - version: 3.14.0 + version: 3.16.0 glob: specifier: ^10.3.10 version: 10.3.10 @@ -310,13 +319,13 @@ dependencies: version: 4.14.0(graphql@15.8.0)(supports-color@8.1.1) graphql-ws: specifier: ^5.14.2 - version: 5.14.2(graphql@15.8.0) + version: 5.15.0(graphql@15.8.0) inflected: specifier: ^2.1.0 version: 2.1.0 jsonc-parser: specifier: ^3.2.0 - version: 3.2.0 + version: 3.2.1 keyv: specifier: ~4.5.4 version: 4.5.4 @@ -325,7 +334,7 @@ dependencies: version: 5.1.0 mocha: specifier: ^10.2.0 - version: 10.2.0 + version: 10.3.0 node-fetch: specifier: ^3.3.2 version: 3.3.2 @@ -337,7 +346,10 @@ dependencies: version: 14.2.0 semver: specifier: ^7.5.4 - version: 7.5.4 + version: 7.6.0 + solc: + specifier: ^0.8.24 + version: 0.8.24 stoppable: specifier: ^1.1.0 version: 1.1.0 @@ -346,25 +358,34 @@ dependencies: version: 8.1.1 ts-node: specifier: ^10.9.2 - version: 10.9.2(@types/node@18.18.14)(typescript@5.3.3) + version: 10.9.2(@types/node@18.19.21)(typescript@5.3.3) type-fest: specifier: ^2.19.0 version: 2.19.0 typeorm: specifier: ^0.3.17 - version: 0.3.17(pg@8.11.3)(supports-color@8.1.1)(ts-node@10.9.2) + version: 0.3.20(pg@8.11.3)(supports-color@8.1.1)(ts-node@10.9.2) + types-solc: + specifier: ^1.0.1 + version: 1.0.1 typescript: - specifier: ~5.3.3 + specifier: ~5.3.2 version: 5.3.3 upath: specifier: ^2.0.1 version: 2.0.1 + viem: + specifier: ^2.7.11 + version: 2.7.19(typescript@5.3.3) + vitest: + specifier: ^1.3.1 + version: 1.3.1(@types/node@18.19.21)(supports-color@8.1.1) websocket: specifier: ^1.0.34 version: 1.0.34 ws: specifier: ^8.14.2 - version: 8.14.2 + version: 8.16.0 xxhash-wasm: specifier: ^1.0.2 version: 1.0.2 @@ -378,6 +399,10 @@ packages: resolution: {integrity: sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==} dev: false + /@adraffy/ens-normalize@1.10.1: + resolution: {integrity: sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==} + dev: false + /@apollo/protobufjs@1.2.6: resolution: {integrity: sha512-Wqo1oSHNUj/jxmsVp4iR3I480p6qdqHikn38lKrFhfzcDJ7lwd7Ck7cHRl4JE81tWNArl77xhnG/OkZhxKBYOw==} hasBin: true @@ -515,14 +540,14 @@ packages: /@apollographql/graphql-playground-html@1.6.29: resolution: {integrity: sha512-xCcXpoz52rI4ksJSdOCxeOCn2DLocxwHf9dVT/Q90Pte1LX+LY+91SFtJF3KXVHH8kEin+g1KKCQPKBjZJfWNA==} dependencies: - xss: 1.0.14 + xss: 1.0.15 dev: false /@aws-crypto/crc32@3.0.0: resolution: {integrity: sha512-IzSgsrxUcsrejQbPVilIKy16kAT52EwB6zSaI+M3xxIhKh5+aldEyvI+z6erM7TCLB2BJsFrtHjp6/4/sr+3dA==} dependencies: '@aws-crypto/util': 3.0.0 - '@aws-sdk/types': 3.460.0 + '@aws-sdk/types': 3.523.0 tslib: 1.14.1 dev: false @@ -530,7 +555,7 @@ packages: resolution: {integrity: sha512-ENNPPManmnVJ4BTXlOjAgD7URidbAznURqD0KvfREyc4o20DPYdEldU1f5cQ7Jbj0CJJSPaMIk/9ZshdB3210w==} dependencies: '@aws-crypto/util': 3.0.0 - '@aws-sdk/types': 3.460.0 + '@aws-sdk/types': 3.523.0 tslib: 1.14.1 dev: false @@ -546,8 +571,8 @@ packages: '@aws-crypto/ie11-detection': 3.0.0 '@aws-crypto/supports-web-crypto': 3.0.0 '@aws-crypto/util': 3.0.0 - '@aws-sdk/types': 3.460.0 - '@aws-sdk/util-locate-window': 3.310.0 + '@aws-sdk/types': 3.523.0 + '@aws-sdk/util-locate-window': 3.495.0 '@aws-sdk/util-utf8-browser': 3.259.0 tslib: 1.14.1 dev: false @@ -559,8 +584,8 @@ packages: '@aws-crypto/sha256-js': 3.0.0 '@aws-crypto/supports-web-crypto': 3.0.0 '@aws-crypto/util': 3.0.0 - '@aws-sdk/types': 3.460.0 - '@aws-sdk/util-locate-window': 3.310.0 + '@aws-sdk/types': 3.523.0 + '@aws-sdk/util-locate-window': 3.495.0 '@aws-sdk/util-utf8-browser': 3.259.0 tslib: 1.14.1 dev: false @@ -569,7 +594,7 @@ packages: resolution: {integrity: sha512-PnNN7os0+yd1XvXAy23CFOmTbMaDxgxXtTKHybrJ39Y8kGzBATgBFibWJKH6BhytLI/Zyszs87xCOBNyBig6vQ==} dependencies: '@aws-crypto/util': 3.0.0 - '@aws-sdk/types': 3.460.0 + '@aws-sdk/types': 3.523.0 tslib: 1.14.1 dev: false @@ -582,502 +607,546 @@ packages: /@aws-crypto/util@3.0.0: resolution: {integrity: sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==} dependencies: - '@aws-sdk/types': 3.460.0 + '@aws-sdk/types': 3.523.0 '@aws-sdk/util-utf8-browser': 3.259.0 tslib: 1.14.1 dev: false - /@aws-sdk/client-s3@3.462.0: - resolution: {integrity: sha512-nyBmsS45b5/YI926dtJp6OA8Fx7yItcdK8lqJq5bgfbskyEqycFCXzykog1AkIBETOeUn3Saztw7HCGZKRad0g==} + /@aws-sdk/client-s3@3.525.0: + resolution: {integrity: sha512-hoMGH8G9rezZDiJPsMjsyRVNfVHHa4u6lcZ09SQMmtFHWK0FUcC0DIKR5ripV5qGDbnV54i2JotXlLzAv0aNCQ==} engines: {node: '>=14.0.0'} dependencies: '@aws-crypto/sha1-browser': 3.0.0 '@aws-crypto/sha256-browser': 3.0.0 '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/client-sts': 3.462.0 - '@aws-sdk/core': 3.451.0 - '@aws-sdk/credential-provider-node': 3.460.0 - '@aws-sdk/middleware-bucket-endpoint': 3.460.0 - '@aws-sdk/middleware-expect-continue': 3.460.0 - '@aws-sdk/middleware-flexible-checksums': 3.461.0 - '@aws-sdk/middleware-host-header': 3.460.0 - '@aws-sdk/middleware-location-constraint': 3.461.0 - '@aws-sdk/middleware-logger': 3.460.0 - '@aws-sdk/middleware-recursion-detection': 3.460.0 - '@aws-sdk/middleware-sdk-s3': 3.461.0 - '@aws-sdk/middleware-signing': 3.461.0 - '@aws-sdk/middleware-ssec': 3.460.0 - '@aws-sdk/middleware-user-agent': 3.460.0 - '@aws-sdk/region-config-resolver': 3.451.0 - '@aws-sdk/signature-v4-multi-region': 3.461.0 - '@aws-sdk/types': 3.460.0 - '@aws-sdk/util-endpoints': 3.460.0 - '@aws-sdk/util-user-agent-browser': 3.460.0 - '@aws-sdk/util-user-agent-node': 3.460.0 - '@aws-sdk/xml-builder': 3.310.0 - '@smithy/config-resolver': 2.0.19 - '@smithy/eventstream-serde-browser': 2.0.14 - '@smithy/eventstream-serde-config-resolver': 2.0.14 - '@smithy/eventstream-serde-node': 2.0.14 - '@smithy/fetch-http-handler': 2.2.7 - '@smithy/hash-blob-browser': 2.0.15 - '@smithy/hash-node': 2.0.16 - '@smithy/hash-stream-node': 2.0.16 - '@smithy/invalid-dependency': 2.0.14 - '@smithy/md5-js': 2.0.16 - '@smithy/middleware-content-length': 2.0.16 - '@smithy/middleware-endpoint': 2.2.1 - '@smithy/middleware-retry': 2.0.21 - '@smithy/middleware-serde': 2.0.14 - '@smithy/middleware-stack': 2.0.8 - '@smithy/node-config-provider': 2.1.6 - '@smithy/node-http-handler': 2.1.10 - '@smithy/protocol-http': 3.0.10 - '@smithy/smithy-client': 2.1.16 - '@smithy/types': 2.6.0 - '@smithy/url-parser': 2.0.14 - '@smithy/util-base64': 2.0.1 - '@smithy/util-body-length-browser': 2.0.0 - '@smithy/util-body-length-node': 2.1.0 - '@smithy/util-defaults-mode-browser': 2.0.20 - '@smithy/util-defaults-mode-node': 2.0.26 - '@smithy/util-endpoints': 1.0.5 - '@smithy/util-retry': 2.0.7 - '@smithy/util-stream': 2.0.21 - '@smithy/util-utf8': 2.0.2 - '@smithy/util-waiter': 2.0.14 + '@aws-sdk/client-sts': 3.525.0(@aws-sdk/credential-provider-node@3.525.0) + '@aws-sdk/core': 3.525.0 + '@aws-sdk/credential-provider-node': 3.525.0 + '@aws-sdk/middleware-bucket-endpoint': 3.525.0 + '@aws-sdk/middleware-expect-continue': 3.523.0 + '@aws-sdk/middleware-flexible-checksums': 3.523.0 + '@aws-sdk/middleware-host-header': 3.523.0 + '@aws-sdk/middleware-location-constraint': 3.523.0 + '@aws-sdk/middleware-logger': 3.523.0 + '@aws-sdk/middleware-recursion-detection': 3.523.0 + '@aws-sdk/middleware-sdk-s3': 3.525.0 + '@aws-sdk/middleware-signing': 3.523.0 + '@aws-sdk/middleware-ssec': 3.523.0 + '@aws-sdk/middleware-user-agent': 3.525.0 + '@aws-sdk/region-config-resolver': 3.525.0 + '@aws-sdk/signature-v4-multi-region': 3.525.0 + '@aws-sdk/types': 3.523.0 + '@aws-sdk/util-endpoints': 3.525.0 + '@aws-sdk/util-user-agent-browser': 3.523.0 + '@aws-sdk/util-user-agent-node': 3.525.0 + '@aws-sdk/xml-builder': 3.523.0 + '@smithy/config-resolver': 2.1.4 + '@smithy/core': 1.3.5 + '@smithy/eventstream-serde-browser': 2.1.3 + '@smithy/eventstream-serde-config-resolver': 2.1.3 + '@smithy/eventstream-serde-node': 2.1.3 + '@smithy/fetch-http-handler': 2.4.3 + '@smithy/hash-blob-browser': 2.1.3 + '@smithy/hash-node': 2.1.3 + '@smithy/hash-stream-node': 2.1.3 + '@smithy/invalid-dependency': 2.1.3 + '@smithy/md5-js': 2.1.3 + '@smithy/middleware-content-length': 2.1.3 + '@smithy/middleware-endpoint': 2.4.4 + '@smithy/middleware-retry': 2.1.4 + '@smithy/middleware-serde': 2.1.3 + '@smithy/middleware-stack': 2.1.3 + '@smithy/node-config-provider': 2.2.4 + '@smithy/node-http-handler': 2.4.1 + '@smithy/protocol-http': 3.2.1 + '@smithy/smithy-client': 2.4.2 + '@smithy/types': 2.10.1 + '@smithy/url-parser': 2.1.3 + '@smithy/util-base64': 2.1.1 + '@smithy/util-body-length-browser': 2.1.1 + '@smithy/util-body-length-node': 2.2.1 + '@smithy/util-defaults-mode-browser': 2.1.4 + '@smithy/util-defaults-mode-node': 2.2.3 + '@smithy/util-endpoints': 1.1.4 + '@smithy/util-retry': 2.1.3 + '@smithy/util-stream': 2.1.3 + '@smithy/util-utf8': 2.1.1 + '@smithy/util-waiter': 2.1.3 fast-xml-parser: 4.2.5 tslib: 2.6.2 transitivePeerDependencies: - aws-crt dev: false - /@aws-sdk/client-sso@3.460.0: - resolution: {integrity: sha512-p5D9C8LKJs5yoBn5cCs2Wqzrp5YP5BYcP774bhGMFEu/LCIUyWzudwN3+/AObSiq8R8SSvBY2zQD4h+k3NjgTQ==} + /@aws-sdk/client-sso-oidc@3.525.0(@aws-sdk/credential-provider-node@3.525.0): + resolution: {integrity: sha512-zz13k/6RkjPSLmReSeGxd8wzGiiZa4Odr2Tv3wTcxClM4wOjD+zOgGv4Fe32b9AMqaueiCdjbvdu7AKcYxFA4A==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@aws-sdk/credential-provider-node': ^3.525.0 + dependencies: + '@aws-crypto/sha256-browser': 3.0.0 + '@aws-crypto/sha256-js': 3.0.0 + '@aws-sdk/client-sts': 3.525.0(@aws-sdk/credential-provider-node@3.525.0) + '@aws-sdk/core': 3.525.0 + '@aws-sdk/credential-provider-node': 3.525.0 + '@aws-sdk/middleware-host-header': 3.523.0 + '@aws-sdk/middleware-logger': 3.523.0 + '@aws-sdk/middleware-recursion-detection': 3.523.0 + '@aws-sdk/middleware-user-agent': 3.525.0 + '@aws-sdk/region-config-resolver': 3.525.0 + '@aws-sdk/types': 3.523.0 + '@aws-sdk/util-endpoints': 3.525.0 + '@aws-sdk/util-user-agent-browser': 3.523.0 + '@aws-sdk/util-user-agent-node': 3.525.0 + '@smithy/config-resolver': 2.1.4 + '@smithy/core': 1.3.5 + '@smithy/fetch-http-handler': 2.4.3 + '@smithy/hash-node': 2.1.3 + '@smithy/invalid-dependency': 2.1.3 + '@smithy/middleware-content-length': 2.1.3 + '@smithy/middleware-endpoint': 2.4.4 + '@smithy/middleware-retry': 2.1.4 + '@smithy/middleware-serde': 2.1.3 + '@smithy/middleware-stack': 2.1.3 + '@smithy/node-config-provider': 2.2.4 + '@smithy/node-http-handler': 2.4.1 + '@smithy/protocol-http': 3.2.1 + '@smithy/smithy-client': 2.4.2 + '@smithy/types': 2.10.1 + '@smithy/url-parser': 2.1.3 + '@smithy/util-base64': 2.1.1 + '@smithy/util-body-length-browser': 2.1.1 + '@smithy/util-body-length-node': 2.2.1 + '@smithy/util-defaults-mode-browser': 2.1.4 + '@smithy/util-defaults-mode-node': 2.2.3 + '@smithy/util-endpoints': 1.1.4 + '@smithy/util-middleware': 2.1.3 + '@smithy/util-retry': 2.1.3 + '@smithy/util-utf8': 2.1.1 + tslib: 2.6.2 + transitivePeerDependencies: + - aws-crt + dev: false + + /@aws-sdk/client-sso@3.525.0: + resolution: {integrity: sha512-6KwGQWFoNLH1UupdWPFdKPfTgjSz1kN8/r8aCzuvvXBe4Pz+iDUZ6FEJzGWNc9AapjvZDNO1hs23slomM9rTaA==} engines: {node: '>=14.0.0'} dependencies: '@aws-crypto/sha256-browser': 3.0.0 '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/core': 3.451.0 - '@aws-sdk/middleware-host-header': 3.460.0 - '@aws-sdk/middleware-logger': 3.460.0 - '@aws-sdk/middleware-recursion-detection': 3.460.0 - '@aws-sdk/middleware-user-agent': 3.460.0 - '@aws-sdk/region-config-resolver': 3.451.0 - '@aws-sdk/types': 3.460.0 - '@aws-sdk/util-endpoints': 3.460.0 - '@aws-sdk/util-user-agent-browser': 3.460.0 - '@aws-sdk/util-user-agent-node': 3.460.0 - '@smithy/config-resolver': 2.0.19 - '@smithy/fetch-http-handler': 2.2.7 - '@smithy/hash-node': 2.0.16 - '@smithy/invalid-dependency': 2.0.14 - '@smithy/middleware-content-length': 2.0.16 - '@smithy/middleware-endpoint': 2.2.1 - '@smithy/middleware-retry': 2.0.21 - '@smithy/middleware-serde': 2.0.14 - '@smithy/middleware-stack': 2.0.8 - '@smithy/node-config-provider': 2.1.6 - '@smithy/node-http-handler': 2.1.10 - '@smithy/protocol-http': 3.0.10 - '@smithy/smithy-client': 2.1.16 - '@smithy/types': 2.6.0 - '@smithy/url-parser': 2.0.14 - '@smithy/util-base64': 2.0.1 - '@smithy/util-body-length-browser': 2.0.0 - '@smithy/util-body-length-node': 2.1.0 - '@smithy/util-defaults-mode-browser': 2.0.20 - '@smithy/util-defaults-mode-node': 2.0.26 - '@smithy/util-endpoints': 1.0.5 - '@smithy/util-retry': 2.0.7 - '@smithy/util-utf8': 2.0.2 + '@aws-sdk/core': 3.525.0 + '@aws-sdk/middleware-host-header': 3.523.0 + '@aws-sdk/middleware-logger': 3.523.0 + '@aws-sdk/middleware-recursion-detection': 3.523.0 + '@aws-sdk/middleware-user-agent': 3.525.0 + '@aws-sdk/region-config-resolver': 3.525.0 + '@aws-sdk/types': 3.523.0 + '@aws-sdk/util-endpoints': 3.525.0 + '@aws-sdk/util-user-agent-browser': 3.523.0 + '@aws-sdk/util-user-agent-node': 3.525.0 + '@smithy/config-resolver': 2.1.4 + '@smithy/core': 1.3.5 + '@smithy/fetch-http-handler': 2.4.3 + '@smithy/hash-node': 2.1.3 + '@smithy/invalid-dependency': 2.1.3 + '@smithy/middleware-content-length': 2.1.3 + '@smithy/middleware-endpoint': 2.4.4 + '@smithy/middleware-retry': 2.1.4 + '@smithy/middleware-serde': 2.1.3 + '@smithy/middleware-stack': 2.1.3 + '@smithy/node-config-provider': 2.2.4 + '@smithy/node-http-handler': 2.4.1 + '@smithy/protocol-http': 3.2.1 + '@smithy/smithy-client': 2.4.2 + '@smithy/types': 2.10.1 + '@smithy/url-parser': 2.1.3 + '@smithy/util-base64': 2.1.1 + '@smithy/util-body-length-browser': 2.1.1 + '@smithy/util-body-length-node': 2.2.1 + '@smithy/util-defaults-mode-browser': 2.1.4 + '@smithy/util-defaults-mode-node': 2.2.3 + '@smithy/util-endpoints': 1.1.4 + '@smithy/util-middleware': 2.1.3 + '@smithy/util-retry': 2.1.3 + '@smithy/util-utf8': 2.1.1 tslib: 2.6.2 transitivePeerDependencies: - aws-crt dev: false - /@aws-sdk/client-sts@3.462.0: - resolution: {integrity: sha512-oO6SVGB9kR0dwc4T/M3++TcioBVv26cEpxZGS4BcKMDxSjkCLqJ/jE37aCNNPGTlCAhnuOAwqGjFqYrsehsI1Q==} + /@aws-sdk/client-sts@3.525.0(@aws-sdk/credential-provider-node@3.525.0): + resolution: {integrity: sha512-a8NUGRvO6rkfTZCbMaCsjDjLbERCwIUU9dIywFYcRgbFhkupJ7fSaZz3Het98U51M9ZbTEpaTa3fz0HaJv8VJw==} engines: {node: '>=14.0.0'} + peerDependencies: + '@aws-sdk/credential-provider-node': ^3.525.0 dependencies: '@aws-crypto/sha256-browser': 3.0.0 '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/core': 3.451.0 - '@aws-sdk/credential-provider-node': 3.460.0 - '@aws-sdk/middleware-host-header': 3.460.0 - '@aws-sdk/middleware-logger': 3.460.0 - '@aws-sdk/middleware-recursion-detection': 3.460.0 - '@aws-sdk/middleware-sdk-sts': 3.461.0 - '@aws-sdk/middleware-signing': 3.461.0 - '@aws-sdk/middleware-user-agent': 3.460.0 - '@aws-sdk/region-config-resolver': 3.451.0 - '@aws-sdk/types': 3.460.0 - '@aws-sdk/util-endpoints': 3.460.0 - '@aws-sdk/util-user-agent-browser': 3.460.0 - '@aws-sdk/util-user-agent-node': 3.460.0 - '@smithy/config-resolver': 2.0.19 - '@smithy/fetch-http-handler': 2.2.7 - '@smithy/hash-node': 2.0.16 - '@smithy/invalid-dependency': 2.0.14 - '@smithy/middleware-content-length': 2.0.16 - '@smithy/middleware-endpoint': 2.2.1 - '@smithy/middleware-retry': 2.0.21 - '@smithy/middleware-serde': 2.0.14 - '@smithy/middleware-stack': 2.0.8 - '@smithy/node-config-provider': 2.1.6 - '@smithy/node-http-handler': 2.1.10 - '@smithy/protocol-http': 3.0.10 - '@smithy/smithy-client': 2.1.16 - '@smithy/types': 2.6.0 - '@smithy/url-parser': 2.0.14 - '@smithy/util-base64': 2.0.1 - '@smithy/util-body-length-browser': 2.0.0 - '@smithy/util-body-length-node': 2.1.0 - '@smithy/util-defaults-mode-browser': 2.0.20 - '@smithy/util-defaults-mode-node': 2.0.26 - '@smithy/util-endpoints': 1.0.5 - '@smithy/util-retry': 2.0.7 - '@smithy/util-utf8': 2.0.2 + '@aws-sdk/core': 3.525.0 + '@aws-sdk/credential-provider-node': 3.525.0 + '@aws-sdk/middleware-host-header': 3.523.0 + '@aws-sdk/middleware-logger': 3.523.0 + '@aws-sdk/middleware-recursion-detection': 3.523.0 + '@aws-sdk/middleware-user-agent': 3.525.0 + '@aws-sdk/region-config-resolver': 3.525.0 + '@aws-sdk/types': 3.523.0 + '@aws-sdk/util-endpoints': 3.525.0 + '@aws-sdk/util-user-agent-browser': 3.523.0 + '@aws-sdk/util-user-agent-node': 3.525.0 + '@smithy/config-resolver': 2.1.4 + '@smithy/core': 1.3.5 + '@smithy/fetch-http-handler': 2.4.3 + '@smithy/hash-node': 2.1.3 + '@smithy/invalid-dependency': 2.1.3 + '@smithy/middleware-content-length': 2.1.3 + '@smithy/middleware-endpoint': 2.4.4 + '@smithy/middleware-retry': 2.1.4 + '@smithy/middleware-serde': 2.1.3 + '@smithy/middleware-stack': 2.1.3 + '@smithy/node-config-provider': 2.2.4 + '@smithy/node-http-handler': 2.4.1 + '@smithy/protocol-http': 3.2.1 + '@smithy/smithy-client': 2.4.2 + '@smithy/types': 2.10.1 + '@smithy/url-parser': 2.1.3 + '@smithy/util-base64': 2.1.1 + '@smithy/util-body-length-browser': 2.1.1 + '@smithy/util-body-length-node': 2.2.1 + '@smithy/util-defaults-mode-browser': 2.1.4 + '@smithy/util-defaults-mode-node': 2.2.3 + '@smithy/util-endpoints': 1.1.4 + '@smithy/util-middleware': 2.1.3 + '@smithy/util-retry': 2.1.3 + '@smithy/util-utf8': 2.1.1 fast-xml-parser: 4.2.5 tslib: 2.6.2 transitivePeerDependencies: - aws-crt dev: false - /@aws-sdk/core@3.451.0: - resolution: {integrity: sha512-SamWW2zHEf1ZKe3j1w0Piauryl8BQIlej0TBS18A4ACzhjhWXhCs13bO1S88LvPR5mBFXok3XOT6zPOnKDFktw==} + /@aws-sdk/core@3.525.0: + resolution: {integrity: sha512-E3LtEtMWCriQOFZpVKpLYzbdw/v2PAOEAMhn2VRRZ1g0/g1TXzQrfhEU2yd8l/vQEJaCJ82ooGGg7YECviBUxA==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/core': 1.3.5 + '@smithy/protocol-http': 3.2.1 + '@smithy/signature-v4': 2.1.3 + '@smithy/smithy-client': 2.4.2 + '@smithy/types': 2.10.1 + tslib: 2.6.2 + dev: false + + /@aws-sdk/credential-provider-env@3.523.0: + resolution: {integrity: sha512-Y6DWdH6/OuMDoNKVzZlNeBc6f1Yjk1lYMjANKpIhMbkRCvLJw/PYZKOZa8WpXbTYdgg9XLjKybnLIb3ww3uuzA==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/smithy-client': 2.1.16 + '@aws-sdk/types': 3.523.0 + '@smithy/property-provider': 2.1.3 + '@smithy/types': 2.10.1 tslib: 2.6.2 dev: false - /@aws-sdk/credential-provider-env@3.460.0: - resolution: {integrity: sha512-WWdaRJFuYRc2Ue9NKDy2NIf8pQRNx/QRVmrsk6EkIID8uWlQIOePk3SWTVV0TZIyPrbfSEaSnJRZoShphJ6PAg==} + /@aws-sdk/credential-provider-http@3.525.0: + resolution: {integrity: sha512-RNWQGuSBQZhl3iqklOslUEfQ4br1V3DCPboMpeqFtddUWJV3m2u2extFur9/4Uy+1EHVF120IwZUKtd8dF+ibw==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/types': 3.460.0 - '@smithy/property-provider': 2.0.11 - '@smithy/types': 2.6.0 + '@aws-sdk/types': 3.523.0 + '@smithy/fetch-http-handler': 2.4.3 + '@smithy/node-http-handler': 2.4.1 + '@smithy/property-provider': 2.1.3 + '@smithy/protocol-http': 3.2.1 + '@smithy/smithy-client': 2.4.2 + '@smithy/types': 2.10.1 + '@smithy/util-stream': 2.1.3 tslib: 2.6.2 dev: false - /@aws-sdk/credential-provider-ini@3.460.0: - resolution: {integrity: sha512-1IEUmyaWzt2M3mONO8QyZtPy0f9ccaEjCo48ZQLgptWxUI+Ohga9gPK0mqu1kTJOjv4JJGACYHzLwEnnpltGlA==} + /@aws-sdk/credential-provider-ini@3.525.0(@aws-sdk/credential-provider-node@3.525.0): + resolution: {integrity: sha512-JDnccfK5JRb9jcgpc9lirL9PyCwGIqY0nKdw3LlX5WL5vTpTG4E1q7rLAlpNh7/tFD1n66Itarfv2tsyHMIqCw==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/credential-provider-env': 3.460.0 - '@aws-sdk/credential-provider-process': 3.460.0 - '@aws-sdk/credential-provider-sso': 3.460.0 - '@aws-sdk/credential-provider-web-identity': 3.460.0 - '@aws-sdk/types': 3.460.0 - '@smithy/credential-provider-imds': 2.0.13 - '@smithy/property-provider': 2.0.11 - '@smithy/shared-ini-file-loader': 2.0.12 - '@smithy/types': 2.6.0 + '@aws-sdk/client-sts': 3.525.0(@aws-sdk/credential-provider-node@3.525.0) + '@aws-sdk/credential-provider-env': 3.523.0 + '@aws-sdk/credential-provider-process': 3.523.0 + '@aws-sdk/credential-provider-sso': 3.525.0(@aws-sdk/credential-provider-node@3.525.0) + '@aws-sdk/credential-provider-web-identity': 3.525.0(@aws-sdk/credential-provider-node@3.525.0) + '@aws-sdk/types': 3.523.0 + '@smithy/credential-provider-imds': 2.2.4 + '@smithy/property-provider': 2.1.3 + '@smithy/shared-ini-file-loader': 2.3.4 + '@smithy/types': 2.10.1 tslib: 2.6.2 transitivePeerDependencies: + - '@aws-sdk/credential-provider-node' - aws-crt dev: false - /@aws-sdk/credential-provider-node@3.460.0: - resolution: {integrity: sha512-PbPo92WIgNlF6V4eWKehYGYjTqf0gU9vr09LeQUc3bTm1DJhJw1j+HU/3PfQ8LwTkBQePO7MbJ5A2n6ckMwfMg==} + /@aws-sdk/credential-provider-node@3.525.0: + resolution: {integrity: sha512-RJXlO8goGXpnoHQAyrCcJ0QtWEOFa34LSbfdqBIjQX/fwnjUuEmiGdXTV3AZmwYQ7juk49tfBneHbtOP3AGqsQ==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/credential-provider-env': 3.460.0 - '@aws-sdk/credential-provider-ini': 3.460.0 - '@aws-sdk/credential-provider-process': 3.460.0 - '@aws-sdk/credential-provider-sso': 3.460.0 - '@aws-sdk/credential-provider-web-identity': 3.460.0 - '@aws-sdk/types': 3.460.0 - '@smithy/credential-provider-imds': 2.0.13 - '@smithy/property-provider': 2.0.11 - '@smithy/shared-ini-file-loader': 2.0.12 - '@smithy/types': 2.6.0 + '@aws-sdk/credential-provider-env': 3.523.0 + '@aws-sdk/credential-provider-http': 3.525.0 + '@aws-sdk/credential-provider-ini': 3.525.0(@aws-sdk/credential-provider-node@3.525.0) + '@aws-sdk/credential-provider-process': 3.523.0 + '@aws-sdk/credential-provider-sso': 3.525.0(@aws-sdk/credential-provider-node@3.525.0) + '@aws-sdk/credential-provider-web-identity': 3.525.0(@aws-sdk/credential-provider-node@3.525.0) + '@aws-sdk/types': 3.523.0 + '@smithy/credential-provider-imds': 2.2.4 + '@smithy/property-provider': 2.1.3 + '@smithy/shared-ini-file-loader': 2.3.4 + '@smithy/types': 2.10.1 tslib: 2.6.2 transitivePeerDependencies: - aws-crt dev: false - /@aws-sdk/credential-provider-process@3.460.0: - resolution: {integrity: sha512-ng+0FMc4EaxLAwdttCwf2nzNf4AgcqAHZ8pKXUf8qF/KVkoyTt3UZKW7P2FJI01zxwP+V4yAwVt95PBUKGn4YQ==} + /@aws-sdk/credential-provider-process@3.523.0: + resolution: {integrity: sha512-f0LP9KlFmMvPWdKeUKYlZ6FkQAECUeZMmISsv6NKtvPCI9e4O4cLTeR09telwDK8P0HrgcRuZfXM7E30m8re0Q==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/types': 3.460.0 - '@smithy/property-provider': 2.0.11 - '@smithy/shared-ini-file-loader': 2.0.12 - '@smithy/types': 2.6.0 + '@aws-sdk/types': 3.523.0 + '@smithy/property-provider': 2.1.3 + '@smithy/shared-ini-file-loader': 2.3.4 + '@smithy/types': 2.10.1 tslib: 2.6.2 dev: false - /@aws-sdk/credential-provider-sso@3.460.0: - resolution: {integrity: sha512-KnrQieOw17+aHEzE3SwfxjeSQ5ZTe2HeAzxkaZF++GxhNul/PkVnLzjGpIuB9bn71T9a2oNfG3peDUA+m2l2kw==} + /@aws-sdk/credential-provider-sso@3.525.0(@aws-sdk/credential-provider-node@3.525.0): + resolution: {integrity: sha512-7V7ybtufxdD3plxeIeB6aqHZeFIUlAyPphXIUgXrGY10iNcosL970rQPBeggsohe4gCM6UvY2TfMeEcr+ZE8FA==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/client-sso': 3.460.0 - '@aws-sdk/token-providers': 3.460.0 - '@aws-sdk/types': 3.460.0 - '@smithy/property-provider': 2.0.11 - '@smithy/shared-ini-file-loader': 2.0.12 - '@smithy/types': 2.6.0 + '@aws-sdk/client-sso': 3.525.0 + '@aws-sdk/token-providers': 3.525.0(@aws-sdk/credential-provider-node@3.525.0) + '@aws-sdk/types': 3.523.0 + '@smithy/property-provider': 2.1.3 + '@smithy/shared-ini-file-loader': 2.3.4 + '@smithy/types': 2.10.1 tslib: 2.6.2 transitivePeerDependencies: + - '@aws-sdk/credential-provider-node' - aws-crt dev: false - /@aws-sdk/credential-provider-web-identity@3.460.0: - resolution: {integrity: sha512-7OeaZgC3HmJZGE0I0ZiKInUMF2LyA0IZiW85AYFnAZzAIfv1cXk/1UnDAoFIQhOZfnUBXivStagz892s480ryw==} + /@aws-sdk/credential-provider-web-identity@3.525.0(@aws-sdk/credential-provider-node@3.525.0): + resolution: {integrity: sha512-sAukOjR1oKb2JXG4nPpuBFpSwGUhrrY17PG/xbTy8NAoLLhrqRwnErcLfdTfmj6tH+3094k6ws/Sh8a35ae7fA==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/types': 3.460.0 - '@smithy/property-provider': 2.0.11 - '@smithy/types': 2.6.0 + '@aws-sdk/client-sts': 3.525.0(@aws-sdk/credential-provider-node@3.525.0) + '@aws-sdk/types': 3.523.0 + '@smithy/property-provider': 2.1.3 + '@smithy/types': 2.10.1 tslib: 2.6.2 + transitivePeerDependencies: + - '@aws-sdk/credential-provider-node' + - aws-crt dev: false - /@aws-sdk/middleware-bucket-endpoint@3.460.0: - resolution: {integrity: sha512-AmrCDT/r+m7q3OogZ3UeWpVdllMeR4Wdo+3YEfefPfcZc6SilnP2uCBUHletxbw3tXhNt56bUMUzQ+SUhyuUmA==} + /@aws-sdk/middleware-bucket-endpoint@3.525.0: + resolution: {integrity: sha512-nYfQ2Xspfef7j8mZO7varUWLPH6HQlXateH7tBVtBNUAazyQE4UJEvC0fbQ+Y01e+FKlirim/m2umkdMXqAlTg==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/types': 3.460.0 - '@aws-sdk/util-arn-parser': 3.310.0 - '@smithy/node-config-provider': 2.1.6 - '@smithy/protocol-http': 3.0.10 - '@smithy/types': 2.6.0 - '@smithy/util-config-provider': 2.0.0 + '@aws-sdk/types': 3.523.0 + '@aws-sdk/util-arn-parser': 3.495.0 + '@smithy/node-config-provider': 2.2.4 + '@smithy/protocol-http': 3.2.1 + '@smithy/types': 2.10.1 + '@smithy/util-config-provider': 2.2.1 tslib: 2.6.2 dev: false - /@aws-sdk/middleware-expect-continue@3.460.0: - resolution: {integrity: sha512-8VxMFTR+IszcMZLUZvxVCBOO1CUBmIWmDIQKd7w/U9xyMEXmBA0cx6ZEfMOIZF9NNh9OGCzTvwK+++8OTGBwAw==} + /@aws-sdk/middleware-expect-continue@3.523.0: + resolution: {integrity: sha512-E5DyRAHU39VHaAlQLqXYS/IKpgk3vsryuU6kkOcIIK8Dgw0a2tjoh5AOCaNa8pD+KgAGrFp35JIMSX1zui5diA==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/types': 3.460.0 - '@smithy/protocol-http': 3.0.10 - '@smithy/types': 2.6.0 + '@aws-sdk/types': 3.523.0 + '@smithy/protocol-http': 3.2.1 + '@smithy/types': 2.10.1 tslib: 2.6.2 dev: false - /@aws-sdk/middleware-flexible-checksums@3.461.0: - resolution: {integrity: sha512-MNY7xMl2Qzoinj6Pos23TgD+WQtC9/G/VkNW/v8Ky5faRAt7bbS+ZEkkK3KcCrjnb8x4Bl/FzYNTCZRzRoQOtA==} + /@aws-sdk/middleware-flexible-checksums@3.523.0: + resolution: {integrity: sha512-lIa1TdWY9q4zsDFarfSnYcdrwPR+nypaU4n6hb95i620/1F5M5s6H8P0hYtwTNNvx+slrR8F3VBML9pjBtzAHw==} engines: {node: '>=14.0.0'} dependencies: '@aws-crypto/crc32': 3.0.0 '@aws-crypto/crc32c': 3.0.0 - '@aws-sdk/types': 3.460.0 - '@smithy/is-array-buffer': 2.0.0 - '@smithy/protocol-http': 3.0.10 - '@smithy/types': 2.6.0 - '@smithy/util-utf8': 2.0.2 + '@aws-sdk/types': 3.523.0 + '@smithy/is-array-buffer': 2.1.1 + '@smithy/protocol-http': 3.2.1 + '@smithy/types': 2.10.1 + '@smithy/util-utf8': 2.1.1 tslib: 2.6.2 dev: false - /@aws-sdk/middleware-host-header@3.460.0: - resolution: {integrity: sha512-qBeDyuJkEuHe87Xk6unvFO9Zg5j6zM8bQOOZITocTLfu9JN0u5V4GQ/yopvpv+nQHmC/MGr0G7p+kIXMrg/Q2A==} + /@aws-sdk/middleware-host-header@3.523.0: + resolution: {integrity: sha512-4g3q7Ta9sdD9TMUuohBAkbx/e3I/juTqfKi7TPgP+8jxcYX72MOsgemAMHuP6CX27eyj4dpvjH+w4SIVDiDSmg==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/types': 3.460.0 - '@smithy/protocol-http': 3.0.10 - '@smithy/types': 2.6.0 + '@aws-sdk/types': 3.523.0 + '@smithy/protocol-http': 3.2.1 + '@smithy/types': 2.10.1 tslib: 2.6.2 dev: false - /@aws-sdk/middleware-location-constraint@3.461.0: - resolution: {integrity: sha512-dibimciNOV2kuhBBmHbS+29X559xNw4BdZviGzjGAQPkqPx+7Adgvp5BHqSDgh7FIJpgN2+QGbrubIQ+V1Bn4A==} + /@aws-sdk/middleware-location-constraint@3.523.0: + resolution: {integrity: sha512-1QAUXX3U0jkARnU0yyjk81EO4Uw5dCeQOtvUY5s3bUOHatR3ThosQeIr6y9BCsbXHzNnDe1ytCjqAPyo8r/bYw==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/types': 3.460.0 - '@smithy/types': 2.6.0 + '@aws-sdk/types': 3.523.0 + '@smithy/types': 2.10.1 tslib: 2.6.2 dev: false - /@aws-sdk/middleware-logger@3.460.0: - resolution: {integrity: sha512-w2AJ6HOJ+Ggx9+VDKuWBHk5S0ZxYEo2EY2IFh0qtCQ1RDix/ur1QEzOOL5vNjHlZKPv/dseIwhgsTCac8UHXbQ==} + /@aws-sdk/middleware-logger@3.523.0: + resolution: {integrity: sha512-PeDNJNhfiaZx54LBaLTXzUaJ9LXFwDFFIksipjqjvxMafnoVcQwKbkoPUWLe5ytT4nnL1LogD3s55mERFUsnwg==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/types': 3.460.0 - '@smithy/types': 2.6.0 + '@aws-sdk/types': 3.523.0 + '@smithy/types': 2.10.1 tslib: 2.6.2 dev: false - /@aws-sdk/middleware-recursion-detection@3.460.0: - resolution: {integrity: sha512-wmzm1/2NzpcCVCAsGqqiTBK+xNyLmQwTOq63rcW6eeq6gYOO0cyTZROOkVRrrsKWPBigrSFFHvDrEvonOMtKAg==} + /@aws-sdk/middleware-recursion-detection@3.523.0: + resolution: {integrity: sha512-nZ3Vt7ehfSDYnrcg/aAfjjvpdE+61B3Zk68i6/hSUIegT3IH9H1vSW67NDKVp+50hcEfzWwM2HMPXxlzuyFyrw==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/types': 3.460.0 - '@smithy/protocol-http': 3.0.10 - '@smithy/types': 2.6.0 + '@aws-sdk/types': 3.523.0 + '@smithy/protocol-http': 3.2.1 + '@smithy/types': 2.10.1 tslib: 2.6.2 dev: false - /@aws-sdk/middleware-sdk-s3@3.461.0: - resolution: {integrity: sha512-sOFUBWROq0xQxNoXp+3eepXrUAuMc/JPH+sI/r5QOznk7JVemYoBj99lknbTzJ4ssSK0yVrSUxxwGiGvDQb0Gg==} + /@aws-sdk/middleware-sdk-s3@3.525.0: + resolution: {integrity: sha512-ewFyyFM6wdFTOqCiId5GQNi7owDdLEonQhB4h8tF6r3HV52bRlDvZA4aDos+ft6N/XY2J6L0qlFTFq+/oiurXw==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/types': 3.460.0 - '@aws-sdk/util-arn-parser': 3.310.0 - '@smithy/node-config-provider': 2.1.6 - '@smithy/protocol-http': 3.0.10 - '@smithy/signature-v4': 2.0.10 - '@smithy/smithy-client': 2.1.16 - '@smithy/types': 2.6.0 - '@smithy/util-config-provider': 2.0.0 + '@aws-sdk/types': 3.523.0 + '@aws-sdk/util-arn-parser': 3.495.0 + '@smithy/node-config-provider': 2.2.4 + '@smithy/protocol-http': 3.2.1 + '@smithy/signature-v4': 2.1.3 + '@smithy/smithy-client': 2.4.2 + '@smithy/types': 2.10.1 + '@smithy/util-config-provider': 2.2.1 tslib: 2.6.2 dev: false - /@aws-sdk/middleware-sdk-sts@3.461.0: - resolution: {integrity: sha512-sgNxkwKdJ/NZm7SJZBnbYPkbspmzn3lDyRSJH7PTCvyzDBzY2PB6yS/dfnGkitR+PYwromuOYMha37W4su2SOw==} + /@aws-sdk/middleware-signing@3.523.0: + resolution: {integrity: sha512-pFXV4don6qcmew/OvEjLUr2foVjzoJ8o5k57Oz9yAHz8INx3RHK8MP/K4mVhHo6n0SquRcWrm4kY/Tw+89gkEA==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/middleware-signing': 3.461.0 - '@aws-sdk/types': 3.460.0 - '@smithy/types': 2.6.0 + '@aws-sdk/types': 3.523.0 + '@smithy/property-provider': 2.1.3 + '@smithy/protocol-http': 3.2.1 + '@smithy/signature-v4': 2.1.3 + '@smithy/types': 2.10.1 + '@smithy/util-middleware': 2.1.3 tslib: 2.6.2 dev: false - /@aws-sdk/middleware-signing@3.461.0: - resolution: {integrity: sha512-aM/7VupHlsgeRG1UZSAQMWJX+2Jam4GG8ZGVAbLfBr9yh9cBwnUUndpUpYI9rU7atA8n+vISr162EbR7WTiFhQ==} + /@aws-sdk/middleware-ssec@3.523.0: + resolution: {integrity: sha512-FaqAZQeF5cQzZLOIboIJRaWVOQ2F2pJZAXGF5D7nJsxYNFChotA0O0iWimBRxU35RNn7yirVxz35zQzs20ddIw==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/types': 3.460.0 - '@smithy/property-provider': 2.0.11 - '@smithy/protocol-http': 3.0.10 - '@smithy/signature-v4': 2.0.10 - '@smithy/types': 2.6.0 - '@smithy/util-middleware': 2.0.7 + '@aws-sdk/types': 3.523.0 + '@smithy/types': 2.10.1 tslib: 2.6.2 dev: false - /@aws-sdk/middleware-ssec@3.460.0: - resolution: {integrity: sha512-1PSCmkq9BRX8isxyDyf785xvjldtwhdUzI+37oZ1qfDXGmRyB+KjtRBNnz5Fz+VSiOfVzfhp3sjrc4fs4BfJ0w==} + /@aws-sdk/middleware-user-agent@3.525.0: + resolution: {integrity: sha512-4al/6uO+t/QIYXK2OgqzDKQzzLAYJza1vWFS+S0lJ3jLNGyLB5BMU5KqWjDzevYZ4eCnz2Nn7z0FveUTNz8YdQ==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/types': 3.460.0 - '@smithy/types': 2.6.0 + '@aws-sdk/types': 3.523.0 + '@aws-sdk/util-endpoints': 3.525.0 + '@smithy/protocol-http': 3.2.1 + '@smithy/types': 2.10.1 tslib: 2.6.2 dev: false - /@aws-sdk/middleware-user-agent@3.460.0: - resolution: {integrity: sha512-0gBSOCr+RtwRUCSRLn9H3RVnj9ercvk/QKTHIr33CgfEdyZtIGpHWUSs6uqiQydPTRzjCm5SfUa6ESGhRVMM6A==} + /@aws-sdk/region-config-resolver@3.525.0: + resolution: {integrity: sha512-8kFqXk6UyKgTMi7N7QlhA6qM4pGPWbiUXqEY2RgUWngtxqNFGeM9JTexZeuavQI+qLLe09VPShPNX71fEDcM6w==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/types': 3.460.0 - '@aws-sdk/util-endpoints': 3.460.0 - '@smithy/protocol-http': 3.0.10 - '@smithy/types': 2.6.0 + '@aws-sdk/types': 3.523.0 + '@smithy/node-config-provider': 2.2.4 + '@smithy/types': 2.10.1 + '@smithy/util-config-provider': 2.2.1 + '@smithy/util-middleware': 2.1.3 tslib: 2.6.2 dev: false - /@aws-sdk/region-config-resolver@3.451.0: - resolution: {integrity: sha512-3iMf4OwzrFb4tAAmoROXaiORUk2FvSejnHIw/XHvf/jjR4EqGGF95NZP/n/MeFZMizJWVssrwS412GmoEyoqhg==} + /@aws-sdk/signature-v4-multi-region@3.525.0: + resolution: {integrity: sha512-j8gkdfiokaherRgokfZBl2azYBMHlegT7pOnR/3Y79TSz6G+bJeIkuNk8aUbJArr6R8nvAM1j4dt1rBM+efolQ==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/node-config-provider': 2.1.6 - '@smithy/types': 2.6.0 - '@smithy/util-config-provider': 2.0.0 - '@smithy/util-middleware': 2.0.7 + '@aws-sdk/middleware-sdk-s3': 3.525.0 + '@aws-sdk/types': 3.523.0 + '@smithy/protocol-http': 3.2.1 + '@smithy/signature-v4': 2.1.3 + '@smithy/types': 2.10.1 tslib: 2.6.2 dev: false - /@aws-sdk/signature-v4-multi-region@3.461.0: - resolution: {integrity: sha512-9tsdJ5KMPZzJN1x28AZKoS9J3xfwftFwutqcU1qsXXeouck0CztLfX+wr3etO4acPQO2zU305fnR2ulSsnns4g==} + /@aws-sdk/token-providers@3.525.0(@aws-sdk/credential-provider-node@3.525.0): + resolution: {integrity: sha512-puVjbxuK0Dq7PTQ2HdddHy2eQjOH8GZbump74yWJa6JVpRW84LlOcNmP+79x4Kscvz2ldWB8XDFw/pcCiSDe5A==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/middleware-sdk-s3': 3.461.0 - '@aws-sdk/types': 3.460.0 - '@smithy/protocol-http': 3.0.10 - '@smithy/signature-v4': 2.0.10 - '@smithy/types': 2.6.0 - tslib: 2.6.2 - dev: false - - /@aws-sdk/token-providers@3.460.0: - resolution: {integrity: sha512-EvSIPMI1gXk3gEkdtbZCW+p3Bjmt2gOR1m7ibQD7qLj4l0dKXhp4URgTqB1ExH3S4qUq0M/XSGKbGLZpvunHNg==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-crypto/sha256-browser': 3.0.0 - '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/middleware-host-header': 3.460.0 - '@aws-sdk/middleware-logger': 3.460.0 - '@aws-sdk/middleware-recursion-detection': 3.460.0 - '@aws-sdk/middleware-user-agent': 3.460.0 - '@aws-sdk/region-config-resolver': 3.451.0 - '@aws-sdk/types': 3.460.0 - '@aws-sdk/util-endpoints': 3.460.0 - '@aws-sdk/util-user-agent-browser': 3.460.0 - '@aws-sdk/util-user-agent-node': 3.460.0 - '@smithy/config-resolver': 2.0.19 - '@smithy/fetch-http-handler': 2.2.7 - '@smithy/hash-node': 2.0.16 - '@smithy/invalid-dependency': 2.0.14 - '@smithy/middleware-content-length': 2.0.16 - '@smithy/middleware-endpoint': 2.2.1 - '@smithy/middleware-retry': 2.0.21 - '@smithy/middleware-serde': 2.0.14 - '@smithy/middleware-stack': 2.0.8 - '@smithy/node-config-provider': 2.1.6 - '@smithy/node-http-handler': 2.1.10 - '@smithy/property-provider': 2.0.11 - '@smithy/protocol-http': 3.0.10 - '@smithy/shared-ini-file-loader': 2.0.12 - '@smithy/smithy-client': 2.1.16 - '@smithy/types': 2.6.0 - '@smithy/url-parser': 2.0.14 - '@smithy/util-base64': 2.0.1 - '@smithy/util-body-length-browser': 2.0.0 - '@smithy/util-body-length-node': 2.1.0 - '@smithy/util-defaults-mode-browser': 2.0.20 - '@smithy/util-defaults-mode-node': 2.0.26 - '@smithy/util-endpoints': 1.0.5 - '@smithy/util-retry': 2.0.7 - '@smithy/util-utf8': 2.0.2 + '@aws-sdk/client-sso-oidc': 3.525.0(@aws-sdk/credential-provider-node@3.525.0) + '@aws-sdk/types': 3.523.0 + '@smithy/property-provider': 2.1.3 + '@smithy/shared-ini-file-loader': 2.3.4 + '@smithy/types': 2.10.1 tslib: 2.6.2 transitivePeerDependencies: + - '@aws-sdk/credential-provider-node' - aws-crt dev: false - /@aws-sdk/types@3.460.0: - resolution: {integrity: sha512-MyZSWS/FV8Bnux5eD9en7KLgVxevlVrGNEP3X2D7fpnUlLhl0a7k8+OpSI2ozEQB8hIU2DLc/XXTKRerHSefxQ==} + /@aws-sdk/types@3.523.0: + resolution: {integrity: sha512-AqGIu4u+SxPiUuNBp2acCVcq80KDUFjxe6e3cMTvKWTzCbrVk1AXv0dAaJnCmdkWIha6zJDWxpIk/aL4EGhZ9A==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/types': 2.6.0 + '@smithy/types': 2.10.1 tslib: 2.6.2 dev: false - /@aws-sdk/util-arn-parser@3.310.0: - resolution: {integrity: sha512-jL8509owp/xB9+Or0pvn3Fe+b94qfklc2yPowZZIFAkFcCSIdkIglz18cPDWnYAcy9JGewpMS1COXKIUhZkJsA==} + /@aws-sdk/util-arn-parser@3.495.0: + resolution: {integrity: sha512-hwdA3XAippSEUxs7jpznwD63YYFR+LtQvlEcebPTgWR9oQgG9TfS+39PUfbnEeje1ICuOrN3lrFqFbmP9uzbMg==} engines: {node: '>=14.0.0'} dependencies: tslib: 2.6.2 dev: false - /@aws-sdk/util-endpoints@3.460.0: - resolution: {integrity: sha512-myH6kM5WP4IWULHDHMYf2Q+BCYVGlzqJgiBmO10kQEtJSeAGZZ49eoFFYgKW8ZAYB5VnJ+XhXVB1TRA+vR4l5A==} + /@aws-sdk/util-endpoints@3.525.0: + resolution: {integrity: sha512-DIW7WWU5tIGkeeKX6NJUyrEIdWMiqjLQG3XBzaUj+ufIENwNjdAHhlD8l2vX7Yr3JZRT6yN/84wBCj7Tw1xd1g==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/types': 3.460.0 - '@smithy/util-endpoints': 1.0.5 + '@aws-sdk/types': 3.523.0 + '@smithy/types': 2.10.1 + '@smithy/util-endpoints': 1.1.4 tslib: 2.6.2 dev: false - /@aws-sdk/util-locate-window@3.310.0: - resolution: {integrity: sha512-qo2t/vBTnoXpjKxlsC2e1gBrRm80M3bId27r0BRB2VniSSe7bL1mmzM+/HFtujm0iAxtPM+aLEflLJlJeDPg0w==} + /@aws-sdk/util-locate-window@3.495.0: + resolution: {integrity: sha512-MfaPXT0kLX2tQaR90saBT9fWQq2DHqSSJRzW+MZWsmF+y5LGCOhO22ac/2o6TKSQm7h0HRc2GaADqYYYor62yg==} engines: {node: '>=14.0.0'} dependencies: tslib: 2.6.2 dev: false - /@aws-sdk/util-user-agent-browser@3.460.0: - resolution: {integrity: sha512-FRCzW+TyjKnvxsargPVrjayBfp/rvObYHZyZ2OSqrVw8lkkPCb4e/WZOeIiXZuhdhhoah7wMuo6zGwtFF3bYKg==} + /@aws-sdk/util-user-agent-browser@3.523.0: + resolution: {integrity: sha512-6ZRNdGHX6+HQFqTbIA5+i8RWzxFyxsZv8D3soRfpdyWIKkzhSz8IyRKXRciwKBJDaC7OX2jzGE90wxRQft27nA==} dependencies: - '@aws-sdk/types': 3.460.0 - '@smithy/types': 2.6.0 + '@aws-sdk/types': 3.523.0 + '@smithy/types': 2.10.1 bowser: 2.11.0 tslib: 2.6.2 dev: false - /@aws-sdk/util-user-agent-node@3.460.0: - resolution: {integrity: sha512-+kSoR9ABGpJ5Xc7v0VwpgTQbgyI4zuezC8K4pmKAGZsSsVWg4yxptoy2bDqoFL7qfRlWviMVTkQRMvR4D44WxA==} + /@aws-sdk/util-user-agent-node@3.525.0: + resolution: {integrity: sha512-88Wjt4efyUSBGcyIuh1dvoMqY1k15jpJc5A/3yi67clBQEFsu9QCodQCQPqmRjV3VRcMtBOk+jeCTiUzTY5dRQ==} engines: {node: '>=14.0.0'} peerDependencies: aws-crt: '>=1.0.0' @@ -1085,9 +1154,9 @@ packages: aws-crt: optional: true dependencies: - '@aws-sdk/types': 3.460.0 - '@smithy/node-config-provider': 2.1.6 - '@smithy/types': 2.6.0 + '@aws-sdk/types': 3.523.0 + '@smithy/node-config-provider': 2.2.4 + '@smithy/types': 2.10.1 tslib: 2.6.2 dev: false @@ -1097,18 +1166,19 @@ packages: tslib: 2.6.2 dev: false - /@aws-sdk/xml-builder@3.310.0: - resolution: {integrity: sha512-TqELu4mOuSIKQCqj63fGVs86Yh+vBx5nHRpWKNUNhB2nPTpfbziTs5c1X358be3peVWA4wPxW7Nt53KIg1tnNw==} + /@aws-sdk/xml-builder@3.523.0: + resolution: {integrity: sha512-wfvyVymj2TUw7SuDor9IuFcAzJZvWRBZotvY/wQJOlYa3UP3Oezzecy64N4FWfBJEsZdrTN+HOZFl+IzTWWnUA==} engines: {node: '>=14.0.0'} dependencies: + '@smithy/types': 2.10.1 tslib: 2.6.2 dev: false - /@babel/code-frame@7.22.13: - resolution: {integrity: sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==} + /@babel/code-frame@7.23.5: + resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/highlight': 7.22.20 + '@babel/highlight': 7.23.4 chalk: 2.4.2 dev: false @@ -1117,8 +1187,8 @@ packages: engines: {node: '>=6.9.0'} dev: false - /@babel/highlight@7.22.20: - resolution: {integrity: sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==} + /@babel/highlight@7.23.4: + resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==} engines: {node: '>=6.9.0'} dependencies: '@babel/helper-validator-identifier': 7.22.20 @@ -1126,13 +1196,6 @@ packages: js-tokens: 4.0.0 dev: false - /@babel/runtime@7.23.1: - resolution: {integrity: sha512-hC2v6p8ZSI/W0HUzh3V8C5g+NwSKzKPtJwSpTjwl0o297GP9+ZLQSkdvHz46CM3LqyoXxq+5G9komY+eSqSO0g==} - engines: {node: '>=6.9.0'} - dependencies: - regenerator-runtime: 0.14.0 - dev: false - /@cspotcode/source-map-support@0.8.1: resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} @@ -1140,6 +1203,213 @@ packages: '@jridgewell/trace-mapping': 0.3.9 dev: false + /@esbuild/aix-ppc64@0.19.12: + resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + requiresBuild: true + dev: false + optional: true + + /@esbuild/android-arm64@0.19.12: + resolution: {integrity: sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@esbuild/android-arm@0.19.12: + resolution: {integrity: sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@esbuild/android-x64@0.19.12: + resolution: {integrity: sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@esbuild/darwin-arm64@0.19.12: + resolution: {integrity: sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@esbuild/darwin-x64@0.19.12: + resolution: {integrity: sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@esbuild/freebsd-arm64@0.19.12: + resolution: {integrity: sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: false + optional: true + + /@esbuild/freebsd-x64@0.19.12: + resolution: {integrity: sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-arm64@0.19.12: + resolution: {integrity: sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-arm@0.19.12: + resolution: {integrity: sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-ia32@0.19.12: + resolution: {integrity: sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-loong64@0.19.12: + resolution: {integrity: sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-mips64el@0.19.12: + resolution: {integrity: sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-ppc64@0.19.12: + resolution: {integrity: sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-riscv64@0.19.12: + resolution: {integrity: sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-s390x@0.19.12: + resolution: {integrity: sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-x64@0.19.12: + resolution: {integrity: sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/netbsd-x64@0.19.12: + resolution: {integrity: sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: false + optional: true + + /@esbuild/openbsd-x64@0.19.12: + resolution: {integrity: sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: false + optional: true + + /@esbuild/sunos-x64@0.19.12: + resolution: {integrity: sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: false + optional: true + + /@esbuild/win32-arm64@0.19.12: + resolution: {integrity: sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@esbuild/win32-ia32@0.19.12: + resolution: {integrity: sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@esbuild/win32-x64@0.19.12: + resolution: {integrity: sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + /@exodus/schemasafe@1.3.0: resolution: {integrity: sha512-5Aap/GaRupgNx/feGBwLLTVv8OQFfv3pq2lPRzPg9R+IOBnDgghTGW7l7EuVXOvg5cc/xSAlRW8rBrjIC3Nvqw==} dev: false @@ -1164,13 +1434,13 @@ packages: tslib: 2.6.2 dev: false - /@graphql-tools/merge@9.0.1(graphql@15.8.0): - resolution: {integrity: sha512-hIEExWO9fjA6vzsVjJ3s0cCQ+Q/BEeMVJZtMXd7nbaVefVy0YDyYlEkeoYYNV3NVVvu1G9lr6DM1Qd0DGo9Caw==} + /@graphql-tools/merge@9.0.3(graphql@15.8.0): + resolution: {integrity: sha512-FeKv9lKLMwqDu0pQjPpF59GY3HReUkWXKsMIuMuJQOKh9BETu7zPEFUELvcw8w+lwZkl4ileJsHXC9+AnsT2Lw==} engines: {node: '>=16.0.0'} peerDependencies: graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 dependencies: - '@graphql-tools/utils': 10.0.11(graphql@15.8.0) + '@graphql-tools/utils': 10.1.0(graphql@15.8.0) graphql: 15.8.0 tslib: 2.6.2 dev: false @@ -1187,14 +1457,14 @@ packages: tslib: 2.6.2 dev: false - /@graphql-tools/schema@10.0.2(graphql@15.8.0): - resolution: {integrity: sha512-TbPsIZnWyDCLhgPGnDjt4hosiNU2mF/rNtSk5BVaXWnZqvKJ6gzJV4fcHcvhRIwtscDMW2/YTnK6dLVnk8pc4w==} + /@graphql-tools/schema@10.0.3(graphql@15.8.0): + resolution: {integrity: sha512-p28Oh9EcOna6i0yLaCFOnkcBDQECVf3SCexT6ktb86QNj9idnkhI+tCxnwZDh58Qvjd2nURdkbevvoZkvxzCog==} engines: {node: '>=16.0.0'} peerDependencies: graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 dependencies: - '@graphql-tools/merge': 9.0.1(graphql@15.8.0) - '@graphql-tools/utils': 10.0.11(graphql@15.8.0) + '@graphql-tools/merge': 9.0.3(graphql@15.8.0) + '@graphql-tools/utils': 10.1.0(graphql@15.8.0) graphql: 15.8.0 tslib: 2.6.2 value-or-promise: 1.0.12 @@ -1224,15 +1494,15 @@ packages: value-or-promise: 1.0.12 dev: false - /@graphql-tools/utils@10.0.11(graphql@15.8.0): - resolution: {integrity: sha512-vVjXgKn6zjXIlYBd7yJxCVMYGb5j18gE3hx3Qw3mNsSEsYQXbJbPdlwb7Fc9FogsJei5AaqiQerqH4kAosp1nQ==} + /@graphql-tools/utils@10.1.0(graphql@15.8.0): + resolution: {integrity: sha512-wLPqhgeZ9BZJPRoaQbsDN/CtJDPd/L4qmmtPkjI3NuYJ39x+Eqz1Sh34EAGMuDh+xlOHqBwHczkZUpoK9tvzjw==} engines: {node: '>=16.0.0'} peerDependencies: graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 dependencies: '@graphql-typed-document-node/core': 3.2.0(graphql@15.8.0) cross-inspect: 1.0.0 - dset: 3.1.2 + dset: 3.1.3 graphql: 15.8.0 tslib: 2.6.2 dev: false @@ -1299,10 +1569,10 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/schemas': 29.6.3 - '@types/istanbul-lib-coverage': 2.0.4 - '@types/istanbul-reports': 3.0.2 - '@types/node': 18.18.14 - '@types/yargs': 17.0.25 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 18.19.21 + '@types/yargs': 17.0.32 chalk: 4.1.2 dev: false @@ -1310,8 +1580,8 @@ packages: resolution: {integrity: sha512-CtzORUwWTTOTqfVtHaKRJ0I1kNQd1bpn3sUh8I3nJDVY+5/M/Oe1DnEWzPQvqq/xPIIkzzzIP7mfCoAjFRvDhg==} dev: false - /@jridgewell/resolve-uri@3.1.1: - resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} + /@jridgewell/resolve-uri@3.1.2: + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} dev: false @@ -1322,7 +1592,7 @@ packages: /@jridgewell/trace-mapping@0.3.9: resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} dependencies: - '@jridgewell/resolve-uri': 3.1.1 + '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.4.15 dev: false @@ -1396,6 +1666,129 @@ packages: resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} dev: false + /@rollup/rollup-android-arm-eabi@4.12.0: + resolution: {integrity: sha512-+ac02NL/2TCKRrJu2wffk1kZ+RyqxVUlbjSagNgPm94frxtr+XDL12E5Ll1enWskLrtrZ2r8L3wED1orIibV/w==} + cpu: [arm] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-android-arm64@4.12.0: + resolution: {integrity: sha512-OBqcX2BMe6nvjQ0Nyp7cC90cnumt8PXmO7Dp3gfAju/6YwG0Tj74z1vKrfRz7qAv23nBcYM8BCbhrsWqO7PzQQ==} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-darwin-arm64@4.12.0: + resolution: {integrity: sha512-X64tZd8dRE/QTrBIEs63kaOBG0b5GVEd3ccoLtyf6IdXtHdh8h+I56C2yC3PtC9Ucnv0CpNFJLqKFVgCYe0lOQ==} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-darwin-x64@4.12.0: + resolution: {integrity: sha512-cc71KUZoVbUJmGP2cOuiZ9HSOP14AzBAThn3OU+9LcA1+IUqswJyR1cAJj3Mg55HbjZP6OLAIscbQsQLrpgTOg==} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-linux-arm-gnueabihf@4.12.0: + resolution: {integrity: sha512-a6w/Y3hyyO6GlpKL2xJ4IOh/7d+APaqLYdMf86xnczU3nurFTaVN9s9jOXQg97BE4nYm/7Ga51rjec5nfRdrvA==} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-linux-arm64-gnu@4.12.0: + resolution: {integrity: sha512-0fZBq27b+D7Ar5CQMofVN8sggOVhEtzFUwOwPppQt0k+VR+7UHMZZY4y+64WJ06XOhBTKXtQB/Sv0NwQMXyNAA==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-linux-arm64-musl@4.12.0: + resolution: {integrity: sha512-eTvzUS3hhhlgeAv6bfigekzWZjaEX9xP9HhxB0Dvrdbkk5w/b+1Sxct2ZuDxNJKzsRStSq1EaEkVSEe7A7ipgQ==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-linux-riscv64-gnu@4.12.0: + resolution: {integrity: sha512-ix+qAB9qmrCRiaO71VFfY8rkiAZJL8zQRXveS27HS+pKdjwUfEhqo2+YF2oI+H/22Xsiski+qqwIBxVewLK7sw==} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-linux-x64-gnu@4.12.0: + resolution: {integrity: sha512-TenQhZVOtw/3qKOPa7d+QgkeM6xY0LtwzR8OplmyL5LrgTWIXpTQg2Q2ycBf8jm+SFW2Wt/DTn1gf7nFp3ssVA==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-linux-x64-musl@4.12.0: + resolution: {integrity: sha512-LfFdRhNnW0zdMvdCb5FNuWlls2WbbSridJvxOvYWgSBOYZtgBfW9UGNJG//rwMqTX1xQE9BAodvMH9tAusKDUw==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-win32-arm64-msvc@4.12.0: + resolution: {integrity: sha512-JPDxovheWNp6d7AHCgsUlkuCKvtu3RB55iNEkaQcf0ttsDU/JZF+iQnYcQJSk/7PtT4mjjVG8N1kpwnI9SLYaw==} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-win32-ia32-msvc@4.12.0: + resolution: {integrity: sha512-fjtuvMWRGJn1oZacG8IPnzIV6GF2/XG+h71FKn76OYFqySXInJtseAqdprVTDTyqPxQOG9Exak5/E9Z3+EJ8ZA==} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-win32-x64-msvc@4.12.0: + resolution: {integrity: sha512-ZYmr5mS2wd4Dew/JjT0Fqi2NPB/ZhZ2VvPp7SmvPZb4Y1CG/LRcS6tcRo2cYU7zLK5A7cdbhWnnWmUjoI4qapg==} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@scure/base@1.1.5: + resolution: {integrity: sha512-Brj9FiG2W1MRQSTB212YVPRrcbjkv48FoZi/u4l/zds/ieRrqsh7aUf6CLwkAq61oKXr/ZlTzlY66gLIj3TFTQ==} + dev: false + + /@scure/bip32@1.3.2: + resolution: {integrity: sha512-N1ZhksgwD3OBlwTv3R6KFEcPojl/W4ElJOeCZdi+vuI5QmTFwLq3OFf2zd2ROpKvxFdgZ6hUpb0dx9bVNEwYCA==} + dependencies: + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@scure/base': 1.1.5 + dev: false + + /@scure/bip39@1.2.1: + resolution: {integrity: sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==} + dependencies: + '@noble/hashes': 1.3.2 + '@scure/base': 1.1.5 + dev: false + /@sinclair/typebox@0.27.8: resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} dev: false @@ -1405,485 +1798,458 @@ packages: engines: {node: '>=6'} dev: false - /@smithy/abort-controller@2.0.14: - resolution: {integrity: sha512-zXtteuYLWbSXnzI3O6xq3FYvigYZFW8mdytGibfarLL2lxHto9L3ILtGVnVGmFZa7SDh62l39EnU5hesLN87Fw==} + /@smithy/abort-controller@2.1.3: + resolution: {integrity: sha512-c2aYH2Wu1RVE3rLlVgg2kQOBJGM0WbjReQi5DnPTm2Zb7F0gk7J2aeQeaX2u/lQZoHl6gv8Oac7mt9alU3+f4A==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/types': 2.6.0 + '@smithy/types': 2.10.1 tslib: 2.6.2 dev: false - /@smithy/chunked-blob-reader-native@2.0.1: - resolution: {integrity: sha512-N2oCZRglhWKm7iMBu7S6wDzXirjAofi7tAd26cxmgibRYOBS4D3hGfmkwCpHdASZzwZDD8rluh0Rcqw1JeZDRw==} + /@smithy/chunked-blob-reader-native@2.1.1: + resolution: {integrity: sha512-zNW+43dltfNMUrBEYLMWgI8lQr0uhtTcUyxkgC9EP4j17WREzgSFMPUFVrVV6Rc2+QtWERYjb4tzZnQGa7R9fQ==} dependencies: - '@smithy/util-base64': 2.0.1 + '@smithy/util-base64': 2.1.1 tslib: 2.6.2 dev: false - /@smithy/chunked-blob-reader@2.0.0: - resolution: {integrity: sha512-k+J4GHJsMSAIQPChGBrjEmGS+WbPonCXesoqP9fynIqjn7rdOThdH8FAeCmokP9mxTYKQAKoHCLPzNlm6gh7Wg==} + /@smithy/chunked-blob-reader@2.1.1: + resolution: {integrity: sha512-NjNFCKxC4jVvn+lUr3Yo4/PmUJj3tbyqH6GNHueyTGS5Q27vlEJ1MkNhUDV8QGxJI7Bodnc2pD18lU2zRfhHlQ==} dependencies: tslib: 2.6.2 dev: false - /@smithy/config-resolver@2.0.19: - resolution: {integrity: sha512-JsghnQ5zjWmjEVY8TFOulLdEOCj09SjRLugrHlkPZTIBBm7PQitCFVLThbsKPZQOP7N3ME1DU1nKUc1UaVnBog==} + /@smithy/config-resolver@2.1.4: + resolution: {integrity: sha512-AW2WUZmBAzgO3V3ovKtsUbI3aBNMeQKFDumoqkNxaVDWF/xfnxAWqBKDr/NuG7c06N2Rm4xeZLPiJH/d+na0HA==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/node-config-provider': 2.1.6 - '@smithy/types': 2.6.0 - '@smithy/util-config-provider': 2.0.0 - '@smithy/util-middleware': 2.0.7 + '@smithy/node-config-provider': 2.2.4 + '@smithy/types': 2.10.1 + '@smithy/util-config-provider': 2.2.1 + '@smithy/util-middleware': 2.1.3 tslib: 2.6.2 dev: false - /@smithy/credential-provider-imds@2.0.13: - resolution: {integrity: sha512-/xe3wNoC4j+BeTemH9t2gSKLBfyZmk8LXB2pQm/TOEYi+QhBgT+PSolNDfNAhrR68eggNE17uOimsrnwSkCt4w==} + /@smithy/core@1.3.5: + resolution: {integrity: sha512-Rrc+e2Jj6Gu7Xbn0jvrzZlSiP2CZocIOfZ9aNUA82+1sa6GBnxqL9+iZ9EKHeD9aqD1nU8EK4+oN2EiFpSv7Yw==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/node-config-provider': 2.1.6 - '@smithy/property-provider': 2.0.11 - '@smithy/types': 2.6.0 - '@smithy/url-parser': 2.0.14 + '@smithy/middleware-endpoint': 2.4.4 + '@smithy/middleware-retry': 2.1.4 + '@smithy/middleware-serde': 2.1.3 + '@smithy/protocol-http': 3.2.1 + '@smithy/smithy-client': 2.4.2 + '@smithy/types': 2.10.1 + '@smithy/util-middleware': 2.1.3 tslib: 2.6.2 dev: false - /@smithy/credential-provider-imds@2.1.2: - resolution: {integrity: sha512-Y62jBWdoLPSYjr9fFvJf+KwTa1EunjVr6NryTEWCnwIY93OJxwV4t0qxjwdPl/XMsUkq79ppNJSEQN6Ohnhxjw==} + /@smithy/credential-provider-imds@2.2.4: + resolution: {integrity: sha512-DdatjmBZQnhGe1FhI8gO98f7NmvQFSDiZTwC3WMvLTCKQUY+Y1SVkhJqIuLu50Eb7pTheoXQmK+hKYUgpUWsNA==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/node-config-provider': 2.1.6 - '@smithy/property-provider': 2.0.15 - '@smithy/types': 2.6.0 - '@smithy/url-parser': 2.0.14 - tslib: 2.6.2 - dev: false - - /@smithy/eventstream-codec@2.0.10: - resolution: {integrity: sha512-3SSDgX2nIsFwif6m+I4+ar4KDcZX463Noes8ekBgQHitULiWvaDZX8XqPaRQSQ4bl1vbeVXHklJfv66MnVO+lw==} - dependencies: - '@aws-crypto/crc32': 3.0.0 - '@smithy/types': 2.6.0 - '@smithy/util-hex-encoding': 2.0.0 + '@smithy/node-config-provider': 2.2.4 + '@smithy/property-provider': 2.1.3 + '@smithy/types': 2.10.1 + '@smithy/url-parser': 2.1.3 tslib: 2.6.2 dev: false - /@smithy/eventstream-codec@2.0.14: - resolution: {integrity: sha512-g/OU/MeWGfHDygoXgMWfG/Xb0QqDnAGcM9t2FRrVAhleXYRddGOEnfanR5cmHgB9ue52MJsyorqFjckzXsylaA==} + /@smithy/eventstream-codec@2.1.3: + resolution: {integrity: sha512-rGlCVuwSDv6qfKH4/lRxFjcZQnIE0LZ3D4lkMHg7ZSltK9rA74r0VuGSvWVQ4N/d70VZPaniFhp4Z14QYZsa+A==} dependencies: '@aws-crypto/crc32': 3.0.0 - '@smithy/types': 2.6.0 - '@smithy/util-hex-encoding': 2.0.0 + '@smithy/types': 2.10.1 + '@smithy/util-hex-encoding': 2.1.1 tslib: 2.6.2 dev: false - /@smithy/eventstream-serde-browser@2.0.14: - resolution: {integrity: sha512-41wmYE9smDGJi1ZXp+LogH6BR7MkSsQD91wneIFISF/mupKULvoOJUkv/Nf0NMRxWlM3Bf1Vvi9FlR2oV4KU8Q==} + /@smithy/eventstream-serde-browser@2.1.3: + resolution: {integrity: sha512-qAgKbZ9m2oBfSyJWWurX/MvQFRPrYypj79cDSleEgDwBoez6Tfd+FTpu2L/j3ZeC3mDlDHIKWksoeaXZpLLAHw==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/eventstream-serde-universal': 2.0.14 - '@smithy/types': 2.6.0 + '@smithy/eventstream-serde-universal': 2.1.3 + '@smithy/types': 2.10.1 tslib: 2.6.2 dev: false - /@smithy/eventstream-serde-config-resolver@2.0.14: - resolution: {integrity: sha512-43IyRIzQ82s+5X+t/3Ood00CcWtAXQdmUIUKMed2Qg9REPk8SVIHhpm3rwewLwg+3G2Nh8NOxXlEQu6DsPUcMw==} + /@smithy/eventstream-serde-config-resolver@2.1.3: + resolution: {integrity: sha512-48rvsNv/MgAFCxOE0qwR7ZwKhaEdDoTxqH5HM+T6SDxICmPGb7gEuQzjTxQhcieCPgqyXeZFW8cU0QJxdowuIg==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/types': 2.6.0 + '@smithy/types': 2.10.1 tslib: 2.6.2 dev: false - /@smithy/eventstream-serde-node@2.0.14: - resolution: {integrity: sha512-jVh9E2qAr6DxH5tWfCAl9HV6tI0pEQ3JVmu85JknDvYTC66djcjDdhctPV2EHuKWf2kjRiFJcMIn0eercW4THA==} + /@smithy/eventstream-serde-node@2.1.3: + resolution: {integrity: sha512-RPJWWDhj8isk3NtGfm3Xt1WdHyX9ZE42V+m1nLU1I0zZ1hEol/oawHsTnhva/VR5bn+bJ2zscx+BYr0cEPRtmg==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/eventstream-serde-universal': 2.0.14 - '@smithy/types': 2.6.0 + '@smithy/eventstream-serde-universal': 2.1.3 + '@smithy/types': 2.10.1 tslib: 2.6.2 dev: false - /@smithy/eventstream-serde-universal@2.0.14: - resolution: {integrity: sha512-Ie35+AISNn1NmEjn5b2SchIE49pvKp4Q74bE9ME5RULWI1MgXyGkQUajWd5E6OBSr/sqGcs+rD3IjPErXnCm9g==} + /@smithy/eventstream-serde-universal@2.1.3: + resolution: {integrity: sha512-ssvSMk1LX2jRhiOVgVLGfNJXdB8SvyjieKcJDHq698Gi3LOog6g/+l7ggrN+hZxyjUiDF4cUxgKaZTBUghzhLw==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/eventstream-codec': 2.0.14 - '@smithy/types': 2.6.0 + '@smithy/eventstream-codec': 2.1.3 + '@smithy/types': 2.10.1 tslib: 2.6.2 dev: false - /@smithy/fetch-http-handler@2.2.7: - resolution: {integrity: sha512-iSDBjxuH9TgrtMYAr7j5evjvkvgwLY3y+9D547uep+JNkZ1ZT+BaeU20j6I/bO/i26ilCWFImrlXTPsfQtZdIQ==} + /@smithy/fetch-http-handler@2.4.3: + resolution: {integrity: sha512-Fn/KYJFo6L5I4YPG8WQb2hOmExgRmNpVH5IK2zU3JKrY5FKW7y9ar5e0BexiIC9DhSKqKX+HeWq/Y18fq7Dkpw==} dependencies: - '@smithy/protocol-http': 3.0.10 - '@smithy/querystring-builder': 2.0.14 - '@smithy/types': 2.6.0 - '@smithy/util-base64': 2.0.1 + '@smithy/protocol-http': 3.2.1 + '@smithy/querystring-builder': 2.1.3 + '@smithy/types': 2.10.1 + '@smithy/util-base64': 2.1.1 tslib: 2.6.2 dev: false - /@smithy/hash-blob-browser@2.0.15: - resolution: {integrity: sha512-HX/7GIyPUT/HDWVYe2HYQu0iRnSYpF4uZVNhAhZsObPRawk5Mv0PbyluBgIFI2DDCCKgL/tloCYYwycff1GtQg==} + /@smithy/hash-blob-browser@2.1.3: + resolution: {integrity: sha512-sHLTM5xQYw5Wxz07DFo+eh1PVC6P5+kazQRF1k5nsvOhZG5VnkIy4LZ7N0ZNWqJx16g9otGd5MvqUOpb3WWtgA==} dependencies: - '@smithy/chunked-blob-reader': 2.0.0 - '@smithy/chunked-blob-reader-native': 2.0.1 - '@smithy/types': 2.6.0 + '@smithy/chunked-blob-reader': 2.1.1 + '@smithy/chunked-blob-reader-native': 2.1.1 + '@smithy/types': 2.10.1 tslib: 2.6.2 dev: false - /@smithy/hash-node@2.0.16: - resolution: {integrity: sha512-Wbi9A0PacMYUOwjAulQP90Wl3mQ6NDwnyrZQzFjDz+UzjXOSyQMgBrTkUBz+pVoYVlX3DUu24gWMZBcit+wOGg==} + /@smithy/hash-node@2.1.3: + resolution: {integrity: sha512-FsAPCUj7VNJIdHbSxMd5uiZiF20G2zdSDgrgrDrHqIs/VMxK85Vqk5kMVNNDMCZmMezp6UKnac0B4nAyx7HJ9g==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/types': 2.6.0 - '@smithy/util-buffer-from': 2.0.0 - '@smithy/util-utf8': 2.0.2 + '@smithy/types': 2.10.1 + '@smithy/util-buffer-from': 2.1.1 + '@smithy/util-utf8': 2.1.1 tslib: 2.6.2 dev: false - /@smithy/hash-stream-node@2.0.16: - resolution: {integrity: sha512-4x24GFdeWos1Z49MC5sYdM1j+z32zcUr6oWM9Ggm3WudFAcRIcbG9uDQ1XgJ0Kl+ZTjpqLKniG0iuWvQb2Ud1A==} + /@smithy/hash-stream-node@2.1.3: + resolution: {integrity: sha512-fWpUx2ca/u5lcD5RhNJogEG5FD7H0RDDpYmfQgxFqIUv3Ow7bZsapMukh8uzQPVO8R+NDAvSdxmgXoy4Hz8sFw==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/types': 2.6.0 - '@smithy/util-utf8': 2.0.2 + '@smithy/types': 2.10.1 + '@smithy/util-utf8': 2.1.1 tslib: 2.6.2 dev: false - /@smithy/invalid-dependency@2.0.14: - resolution: {integrity: sha512-d8ohpwZo9RzTpGlAfsWtfm1SHBSU7+N4iuZ6MzR10xDTujJJWtmXYHK1uzcr7rggbpUTaWyHpPFgnf91q0EFqQ==} + /@smithy/invalid-dependency@2.1.3: + resolution: {integrity: sha512-wkra7d/G4CbngV4xsjYyAYOvdAhahQje/WymuQdVEnXFExJopEu7fbL5AEAlBPgWHXwu94VnCSG00gVzRfExyg==} dependencies: - '@smithy/types': 2.6.0 + '@smithy/types': 2.10.1 tslib: 2.6.2 dev: false - /@smithy/is-array-buffer@2.0.0: - resolution: {integrity: sha512-z3PjFjMyZNI98JFRJi/U0nGoLWMSJlDjAW4QUX2WNZLas5C0CmVV6LJ01JI0k90l7FvpmixjWxPFmENSClQ7ug==} + /@smithy/is-array-buffer@2.1.1: + resolution: {integrity: sha512-xozSQrcUinPpNPNPds4S7z/FakDTh1MZWtRP/2vQtYB/u3HYrX2UXuZs+VhaKBd6Vc7g2XPr2ZtwGBNDN6fNKQ==} engines: {node: '>=14.0.0'} dependencies: tslib: 2.6.2 dev: false - /@smithy/md5-js@2.0.16: - resolution: {integrity: sha512-YhWt9aKl+EMSNXyUTUo7I01WHf3HcCkPu/Hl2QmTNwrHT49eWaY7hptAMaERZuHFH0V5xHgPKgKZo2I93DFtgQ==} + /@smithy/md5-js@2.1.3: + resolution: {integrity: sha512-zmn3M6+mP4IJlSmXBN9964AztgkIO8b5lRzAgdJn9AdCFwA6xLkcW2B6uEnpBjvotxtQMmXTUP19tIO7NmFPpw==} dependencies: - '@smithy/types': 2.6.0 - '@smithy/util-utf8': 2.0.2 + '@smithy/types': 2.10.1 + '@smithy/util-utf8': 2.1.1 tslib: 2.6.2 dev: false - /@smithy/middleware-content-length@2.0.16: - resolution: {integrity: sha512-9ddDia3pp1d3XzLXKcm7QebGxLq9iwKf+J1LapvlSOhpF8EM9SjMeSrMOOFgG+2TfW5K3+qz4IAJYYm7INYCng==} + /@smithy/middleware-content-length@2.1.3: + resolution: {integrity: sha512-aJduhkC+dcXxdnv5ZpM3uMmtGmVFKx412R1gbeykS5HXDmRU6oSsyy2SoHENCkfOGKAQOjVE2WVqDJibC0d21g==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/protocol-http': 3.0.10 - '@smithy/types': 2.6.0 + '@smithy/protocol-http': 3.2.1 + '@smithy/types': 2.10.1 tslib: 2.6.2 dev: false - /@smithy/middleware-endpoint@2.2.1: - resolution: {integrity: sha512-dVDS7HNJl/wb0lpByXor6whqDbb1YlLoaoWYoelyYzLHioXOE7y/0iDwJWtDcN36/tVCw9EPBFZ3aans84jLpg==} + /@smithy/middleware-endpoint@2.4.4: + resolution: {integrity: sha512-4yjHyHK2Jul4JUDBo2sTsWY9UshYUnXeb/TAK/MTaPEb8XQvDmpwSFnfIRDU45RY1a6iC9LCnmJNg/yHyfxqkw==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/middleware-serde': 2.0.14 - '@smithy/node-config-provider': 2.1.6 - '@smithy/shared-ini-file-loader': 2.2.5 - '@smithy/types': 2.6.0 - '@smithy/url-parser': 2.0.14 - '@smithy/util-middleware': 2.0.7 + '@smithy/middleware-serde': 2.1.3 + '@smithy/node-config-provider': 2.2.4 + '@smithy/shared-ini-file-loader': 2.3.4 + '@smithy/types': 2.10.1 + '@smithy/url-parser': 2.1.3 + '@smithy/util-middleware': 2.1.3 tslib: 2.6.2 dev: false - /@smithy/middleware-retry@2.0.21: - resolution: {integrity: sha512-EZS1EXv1k6IJX6hyu/0yNQuPcPaXwG8SWljQHYueyRbOxmqYgoWMWPtfZj0xRRQ4YtLawQSpBgAeiJltq8/MPw==} + /@smithy/middleware-retry@2.1.4: + resolution: {integrity: sha512-Cyolv9YckZTPli1EkkaS39UklonxMd08VskiuMhURDjC0HHa/AD6aK/YoD21CHv9s0QLg0WMLvk9YeLTKkXaFQ==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/node-config-provider': 2.1.6 - '@smithy/protocol-http': 3.0.10 - '@smithy/service-error-classification': 2.0.7 - '@smithy/types': 2.6.0 - '@smithy/util-middleware': 2.0.7 - '@smithy/util-retry': 2.0.7 + '@smithy/node-config-provider': 2.2.4 + '@smithy/protocol-http': 3.2.1 + '@smithy/service-error-classification': 2.1.3 + '@smithy/smithy-client': 2.4.2 + '@smithy/types': 2.10.1 + '@smithy/util-middleware': 2.1.3 + '@smithy/util-retry': 2.1.3 tslib: 2.6.2 uuid: 8.3.2 dev: false - /@smithy/middleware-serde@2.0.14: - resolution: {integrity: sha512-hFi3FqoYWDntCYA2IGY6gJ6FKjq2gye+1tfxF2HnIJB5uW8y2DhpRNBSUMoqP+qvYzRqZ6ntv4kgbG+o3pX57g==} + /@smithy/middleware-serde@2.1.3: + resolution: {integrity: sha512-s76LId+TwASrHhUa9QS4k/zeXDUAuNuddKklQzRgumbzge5BftVXHXIqL4wQxKGLocPwfgAOXWx+HdWhQk9hTg==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/types': 2.6.0 + '@smithy/types': 2.10.1 tslib: 2.6.2 dev: false - /@smithy/middleware-stack@2.0.8: - resolution: {integrity: sha512-7/N59j0zWqVEKExJcA14MrLDZ/IeN+d6nbkN8ucs+eURyaDUXWYlZrQmMOd/TyptcQv0+RDlgag/zSTTV62y/Q==} + /@smithy/middleware-stack@2.1.3: + resolution: {integrity: sha512-opMFufVQgvBSld/b7mD7OOEBxF6STyraVr1xel1j0abVILM8ALJvRoFbqSWHGmaDlRGIiV9Q5cGbWi0sdiEaLQ==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/types': 2.6.0 + '@smithy/types': 2.10.1 tslib: 2.6.2 dev: false - /@smithy/node-config-provider@2.1.6: - resolution: {integrity: sha512-HLqTs6O78m3M3z1cPLFxddxhEPv5MkVatfPuxoVO3A+cHZanNd/H5I6btcdHy6N2CB1MJ/lihJC92h30SESsBA==} + /@smithy/node-config-provider@2.2.4: + resolution: {integrity: sha512-nqazHCp8r4KHSFhRQ+T0VEkeqvA0U+RhehBSr1gunUuNW3X7j0uDrWBxB2gE9eutzy6kE3Y7L+Dov/UXT871vg==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/property-provider': 2.0.15 - '@smithy/shared-ini-file-loader': 2.2.5 - '@smithy/types': 2.6.0 + '@smithy/property-provider': 2.1.3 + '@smithy/shared-ini-file-loader': 2.3.4 + '@smithy/types': 2.10.1 tslib: 2.6.2 dev: false - /@smithy/node-http-handler@2.1.10: - resolution: {integrity: sha512-lkALAwtN6odygIM4nB8aHDahINM6WXXjNrZmWQAh0RSossySRT2qa31cFv0ZBuAYVWeprskRk13AFvvLmf1WLw==} + /@smithy/node-http-handler@2.4.1: + resolution: {integrity: sha512-HCkb94soYhJMxPCa61wGKgmeKpJ3Gftx1XD6bcWEB2wMV1L9/SkQu/6/ysKBnbOzWRE01FGzwrTxucHypZ8rdg==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/abort-controller': 2.0.14 - '@smithy/protocol-http': 3.0.10 - '@smithy/querystring-builder': 2.0.14 - '@smithy/types': 2.6.0 + '@smithy/abort-controller': 2.1.3 + '@smithy/protocol-http': 3.2.1 + '@smithy/querystring-builder': 2.1.3 + '@smithy/types': 2.10.1 tslib: 2.6.2 dev: false - /@smithy/property-provider@2.0.11: - resolution: {integrity: sha512-kzuOadu6XvrnlF1iXofpKXYmo4oe19st9/DE8f5gHNaFepb4eTkR8gD8BSdTnNnv7lxfv6uOwZPg4VS6hemX1w==} + /@smithy/property-provider@2.1.3: + resolution: {integrity: sha512-bMz3se+ySKWNrgm7eIiQMa2HO/0fl2D0HvLAdg9pTMcpgp4SqOAh6bz7Ik6y7uQqSrk4rLjIKgbQ6yzYgGehCQ==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/types': 2.6.0 + '@smithy/types': 2.10.1 tslib: 2.6.2 dev: false - /@smithy/property-provider@2.0.15: - resolution: {integrity: sha512-YbRFBn8oiiC3o1Kn3a4KjGa6k47rCM9++5W9cWqYn9WnkyH+hBWgfJAckuxpyA2Hq6Ys4eFrWzXq6fqHEw7iew==} + /@smithy/protocol-http@3.2.1: + resolution: {integrity: sha512-KLrQkEw4yJCeAmAH7hctE8g9KwA7+H2nSJwxgwIxchbp/L0B5exTdOQi9D5HinPLlothoervGmhpYKelZ6AxIA==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/types': 2.6.0 + '@smithy/types': 2.10.1 tslib: 2.6.2 dev: false - /@smithy/protocol-http@3.0.10: - resolution: {integrity: sha512-6+tjNk7rXW7YTeGo9qwxXj/2BFpJTe37kTj3EnZCoX/nH+NP/WLA7O83fz8XhkGqsaAhLUPo/bB12vvd47nsmg==} + /@smithy/querystring-builder@2.1.3: + resolution: {integrity: sha512-kFD3PnNqKELe6m9GRHQw/ftFFSZpnSeQD4qvgDB6BQN6hREHELSosVFUMPN4M3MDKN2jAwk35vXHLoDrNfKu0A==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/types': 2.6.0 + '@smithy/types': 2.10.1 + '@smithy/util-uri-escape': 2.1.1 tslib: 2.6.2 dev: false - /@smithy/querystring-builder@2.0.14: - resolution: {integrity: sha512-lQ4pm9vTv9nIhl5jt6uVMPludr6syE2FyJmHsIJJuOD7QPIJnrf9HhUGf1iHh9KJ4CUv21tpOU3X6s0rB6uJ0g==} + /@smithy/querystring-parser@2.1.3: + resolution: {integrity: sha512-3+CWJoAqcBMR+yvz6D+Fc5VdoGFtfenW6wqSWATWajrRMGVwJGPT3Vy2eb2bnMktJc4HU4bpjeovFa566P3knQ==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/types': 2.6.0 - '@smithy/util-uri-escape': 2.0.0 + '@smithy/types': 2.10.1 tslib: 2.6.2 dev: false - /@smithy/querystring-parser@2.0.14: - resolution: {integrity: sha512-+cbtXWI9tNtQjlgQg3CA+pvL3zKTAxPnG3Pj6MP89CR3vi3QMmD0SOWoq84tqZDnJCxlsusbgIXk1ngMReXo+A==} + /@smithy/service-error-classification@2.1.3: + resolution: {integrity: sha512-iUrpSsem97bbXHHT/v3s7vaq8IIeMo6P6cXdeYHrx0wOJpMeBGQF7CB0mbJSiTm3//iq3L55JiEm8rA7CTVI8A==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/types': 2.6.0 - tslib: 2.6.2 + '@smithy/types': 2.10.1 dev: false - /@smithy/service-error-classification@2.0.7: - resolution: {integrity: sha512-LLxgW12qGz8doYto15kZ4x1rHjtXl0BnCG6T6Wb8z2DI4PT9cJfOSvzbuLzy7+5I24PAepKgFeWHRd9GYy3Z9w==} + /@smithy/shared-ini-file-loader@2.3.4: + resolution: {integrity: sha512-CiZmPg9GeDKbKmJGEFvJBsJcFnh0AQRzOtQAzj1XEa8N/0/uSN/v1LYzgO7ry8hhO8+9KB7+DhSW0weqBra4Aw==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/types': 2.6.0 - dev: false - - /@smithy/shared-ini-file-loader@2.0.12: - resolution: {integrity: sha512-umi0wc4UBGYullAgYNUVfGLgVpxQyES47cnomTqzCKeKO5oudO4hyDNj+wzrOjqDFwK2nWYGVgS8Y0JgGietrw==} - engines: {node: '>=14.0.0'} - dependencies: - '@smithy/types': 2.6.0 + '@smithy/types': 2.10.1 tslib: 2.6.2 dev: false - /@smithy/shared-ini-file-loader@2.2.5: - resolution: {integrity: sha512-LHA68Iu7SmNwfAVe8egmjDCy648/7iJR/fK1UnVw+iAOUJoEYhX2DLgVd5pWllqdDiRbQQzgaHLcRokM+UFR1w==} + /@smithy/signature-v4@2.1.3: + resolution: {integrity: sha512-Jq4iPPdCmJojZTsPePn4r1ULShh6ONkokLuxp1Lnk4Sq7r7rJp4HlA1LbPBq4bD64TIzQezIpr1X+eh5NYkNxw==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/types': 2.6.0 + '@smithy/eventstream-codec': 2.1.3 + '@smithy/is-array-buffer': 2.1.1 + '@smithy/types': 2.10.1 + '@smithy/util-hex-encoding': 2.1.1 + '@smithy/util-middleware': 2.1.3 + '@smithy/util-uri-escape': 2.1.1 + '@smithy/util-utf8': 2.1.1 tslib: 2.6.2 dev: false - /@smithy/signature-v4@2.0.10: - resolution: {integrity: sha512-S6gcP4IXfO/VMswovrhxPpqvQvMal7ZRjM4NvblHSPpE5aNBYx67UkHFF3kg0hR3tJKqNpBGbxwq0gzpdHKLRA==} + /@smithy/smithy-client@2.4.2: + resolution: {integrity: sha512-ntAFYN51zu3N3mCd95YFcFi/8rmvm//uX+HnK24CRbI6k5Rjackn0JhgKz5zOx/tbNvOpgQIwhSX+1EvEsBLbA==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/eventstream-codec': 2.0.10 - '@smithy/is-array-buffer': 2.0.0 - '@smithy/types': 2.6.0 - '@smithy/util-hex-encoding': 2.0.0 - '@smithy/util-middleware': 2.0.3 - '@smithy/util-uri-escape': 2.0.0 - '@smithy/util-utf8': 2.0.2 + '@smithy/middleware-endpoint': 2.4.4 + '@smithy/middleware-stack': 2.1.3 + '@smithy/protocol-http': 3.2.1 + '@smithy/types': 2.10.1 + '@smithy/util-stream': 2.1.3 tslib: 2.6.2 dev: false - /@smithy/smithy-client@2.1.16: - resolution: {integrity: sha512-Lw67+yQSpLl4YkDLUzI2KgS8TXclXmbzSeOJUmRFS4ueT56B4pw3RZRF/SRzvgyxM/HxgkUan8oSHXCujPDafQ==} + /@smithy/types@2.10.1: + resolution: {integrity: sha512-hjQO+4ru4cQ58FluQvKKiyMsFg0A6iRpGm2kqdH8fniyNd2WyanoOsYJfMX/IFLuLxEoW6gnRkNZy1y6fUUhtA==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/middleware-stack': 2.0.8 - '@smithy/types': 2.6.0 - '@smithy/util-stream': 2.0.21 tslib: 2.6.2 dev: false - /@smithy/types@2.6.0: - resolution: {integrity: sha512-PgqxJq2IcdMF9iAasxcqZqqoOXBHufEfmbEUdN1pmJrJltT42b0Sc8UiYSWWzKkciIp9/mZDpzYi4qYG1qqg6g==} - engines: {node: '>=14.0.0'} + /@smithy/url-parser@2.1.3: + resolution: {integrity: sha512-X1NRA4WzK/ihgyzTpeGvI9Wn45y8HmqF4AZ/FazwAv8V203Ex+4lXqcYI70naX9ETqbqKVzFk88W6WJJzCggTQ==} dependencies: + '@smithy/querystring-parser': 2.1.3 + '@smithy/types': 2.10.1 tslib: 2.6.2 dev: false - /@smithy/url-parser@2.0.14: - resolution: {integrity: sha512-kbu17Y1AFXi5lNlySdDj7ZzmvupyWKCX/0jNZ8ffquRyGdbDZb+eBh0QnWqsSmnZa/ctyWaTf7n4l/pXLExrnw==} - dependencies: - '@smithy/querystring-parser': 2.0.14 - '@smithy/types': 2.6.0 - tslib: 2.6.2 - dev: false - - /@smithy/util-base64@2.0.1: - resolution: {integrity: sha512-DlI6XFYDMsIVN+GH9JtcRp3j02JEVuWIn/QOZisVzpIAprdsxGveFed0bjbMRCqmIFe8uetn5rxzNrBtIGrPIQ==} + /@smithy/util-base64@2.1.1: + resolution: {integrity: sha512-UfHVpY7qfF/MrgndI5PexSKVTxSZIdz9InghTFa49QOvuu9I52zLPLUHXvHpNuMb1iD2vmc6R+zbv/bdMipR/g==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/util-buffer-from': 2.0.0 + '@smithy/util-buffer-from': 2.1.1 tslib: 2.6.2 dev: false - /@smithy/util-body-length-browser@2.0.0: - resolution: {integrity: sha512-JdDuS4ircJt+FDnaQj88TzZY3+njZ6O+D3uakS32f2VNnDo3vyEuNdBOh/oFd8Df1zSZOuH1HEChk2AOYDezZg==} + /@smithy/util-body-length-browser@2.1.1: + resolution: {integrity: sha512-ekOGBLvs1VS2d1zM2ER4JEeBWAvIOUKeaFch29UjjJsxmZ/f0L3K3x0dEETgh3Q9bkZNHgT+rkdl/J/VUqSRag==} dependencies: tslib: 2.6.2 dev: false - /@smithy/util-body-length-node@2.1.0: - resolution: {integrity: sha512-/li0/kj/y3fQ3vyzn36NTLGmUwAICb7Jbe/CsWCktW363gh1MOcpEcSO3mJ344Gv2dqz8YJCLQpb6hju/0qOWw==} + /@smithy/util-body-length-node@2.2.1: + resolution: {integrity: sha512-/ggJG+ta3IDtpNVq4ktmEUtOkH1LW64RHB5B0hcr5ZaWBmo96UX2cIOVbjCqqDickTXqBWZ4ZO0APuaPrD7Abg==} engines: {node: '>=14.0.0'} dependencies: tslib: 2.6.2 dev: false - /@smithy/util-buffer-from@2.0.0: - resolution: {integrity: sha512-/YNnLoHsR+4W4Vf2wL5lGv0ksg8Bmk3GEGxn2vEQt52AQaPSCuaO5PM5VM7lP1K9qHRKHwrPGktqVoAHKWHxzw==} + /@smithy/util-buffer-from@2.1.1: + resolution: {integrity: sha512-clhNjbyfqIv9Md2Mg6FffGVrJxw7bgK7s3Iax36xnfVj6cg0fUG7I4RH0XgXJF8bxi+saY5HR21g2UPKSxVCXg==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/is-array-buffer': 2.0.0 + '@smithy/is-array-buffer': 2.1.1 tslib: 2.6.2 dev: false - /@smithy/util-config-provider@2.0.0: - resolution: {integrity: sha512-xCQ6UapcIWKxXHEU4Mcs2s7LcFQRiU3XEluM2WcCjjBtQkUN71Tb+ydGmJFPxMUrW/GWMgQEEGipLym4XG0jZg==} + /@smithy/util-config-provider@2.2.1: + resolution: {integrity: sha512-50VL/tx9oYYcjJn/qKqNy7sCtpD0+s8XEBamIFo4mFFTclKMNp+rsnymD796uybjiIquB7VCB/DeafduL0y2kw==} engines: {node: '>=14.0.0'} dependencies: tslib: 2.6.2 dev: false - /@smithy/util-defaults-mode-browser@2.0.20: - resolution: {integrity: sha512-QJtnbTIl0/BbEASkx1MUFf6EaoWqWW1/IM90N++8NNscePvPf77GheYfpoPis6CBQawUWq8QepTP2QUSAdrVkw==} + /@smithy/util-defaults-mode-browser@2.1.4: + resolution: {integrity: sha512-J6XAVY+/g7jf03QMnvqPyU+8jqGrrtXoKWFVOS+n1sz0Lg8HjHJ1ANqaDN+KTTKZRZlvG8nU5ZrJOUL6VdwgcQ==} engines: {node: '>= 10.0.0'} dependencies: - '@smithy/property-provider': 2.0.15 - '@smithy/smithy-client': 2.1.16 - '@smithy/types': 2.6.0 + '@smithy/property-provider': 2.1.3 + '@smithy/smithy-client': 2.4.2 + '@smithy/types': 2.10.1 bowser: 2.11.0 tslib: 2.6.2 dev: false - /@smithy/util-defaults-mode-node@2.0.26: - resolution: {integrity: sha512-lGFPOFCHv1ql019oegYqa54BZH7HREw6EBqjDLbAr0wquMX0BDi2sg8TJ6Eq+JGLijkZbJB73m4+aK8OFAapMg==} + /@smithy/util-defaults-mode-node@2.2.3: + resolution: {integrity: sha512-ttUISrv1uVOjTlDa3nznX33f0pthoUlP+4grhTvOzcLhzArx8qHB94/untGACOG3nlf8vU20nI2iWImfzoLkYA==} engines: {node: '>= 10.0.0'} dependencies: - '@smithy/config-resolver': 2.0.19 - '@smithy/credential-provider-imds': 2.1.2 - '@smithy/node-config-provider': 2.1.6 - '@smithy/property-provider': 2.0.15 - '@smithy/smithy-client': 2.1.16 - '@smithy/types': 2.6.0 + '@smithy/config-resolver': 2.1.4 + '@smithy/credential-provider-imds': 2.2.4 + '@smithy/node-config-provider': 2.2.4 + '@smithy/property-provider': 2.1.3 + '@smithy/smithy-client': 2.4.2 + '@smithy/types': 2.10.1 tslib: 2.6.2 dev: false - /@smithy/util-endpoints@1.0.5: - resolution: {integrity: sha512-K7qNuCOD5K/90MjHvHm9kJldrfm40UxWYQxNEShMFxV/lCCCRIg8R4uu1PFAxRvPxNpIdcrh1uK6I1ISjDXZJw==} + /@smithy/util-endpoints@1.1.4: + resolution: {integrity: sha512-/qAeHmK5l4yQ4/bCIJ9p49wDe9rwWtOzhPHblu386fwPNT3pxmodgcs9jDCV52yK9b4rB8o9Sj31P/7Vzka1cg==} engines: {node: '>= 14.0.0'} dependencies: - '@smithy/node-config-provider': 2.1.6 - '@smithy/types': 2.6.0 + '@smithy/node-config-provider': 2.2.4 + '@smithy/types': 2.10.1 tslib: 2.6.2 dev: false - /@smithy/util-hex-encoding@2.0.0: - resolution: {integrity: sha512-c5xY+NUnFqG6d7HFh1IFfrm3mGl29lC+vF+geHv4ToiuJCBmIfzx6IeHLg+OgRdPFKDXIw6pvi+p3CsscaMcMA==} + /@smithy/util-hex-encoding@2.1.1: + resolution: {integrity: sha512-3UNdP2pkYUUBGEXzQI9ODTDK+Tcu1BlCyDBaRHwyxhA+8xLP8agEKQq4MGmpjqb4VQAjq9TwlCQX0kP6XDKYLg==} engines: {node: '>=14.0.0'} dependencies: tslib: 2.6.2 dev: false - /@smithy/util-middleware@2.0.3: - resolution: {integrity: sha512-+FOCFYOxd2HO7v/0hkFSETKf7FYQWa08wh/x/4KUeoVBnLR4juw8Qi+TTqZI6E2h5LkzD9uOaxC9lAjrpVzaaA==} + /@smithy/util-middleware@2.1.3: + resolution: {integrity: sha512-/+2fm7AZ2ozl5h8wM++ZP0ovE9/tiUUAHIbCfGfb3Zd3+Dyk17WODPKXBeJ/TnK5U+x743QmA0xHzlSm8I/qhw==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/types': 2.6.0 + '@smithy/types': 2.10.1 tslib: 2.6.2 dev: false - /@smithy/util-middleware@2.0.7: - resolution: {integrity: sha512-tRINOTlf1G9B0ECarFQAtTgMhpnrMPSa+5j4ZEwEawCLfTFTavk6757sxhE4RY5RMlD/I3x+DCS8ZUiR8ho9Pw==} - engines: {node: '>=14.0.0'} - dependencies: - '@smithy/types': 2.6.0 - tslib: 2.6.2 - dev: false - - /@smithy/util-retry@2.0.7: - resolution: {integrity: sha512-fIe5yARaF0+xVT1XKcrdnHKTJ1Vc4+3e3tLDjCuIcE9b6fkBzzGFY7AFiX4M+vj6yM98DrwkuZeHf7/hmtVp0Q==} + /@smithy/util-retry@2.1.3: + resolution: {integrity: sha512-Kbvd+GEMuozbNUU3B89mb99tbufwREcyx2BOX0X2+qHjq6Gvsah8xSDDgxISDwcOHoDqUWO425F0Uc/QIRhYkg==} engines: {node: '>= 14.0.0'} dependencies: - '@smithy/service-error-classification': 2.0.7 - '@smithy/types': 2.6.0 + '@smithy/service-error-classification': 2.1.3 + '@smithy/types': 2.10.1 tslib: 2.6.2 dev: false - /@smithy/util-stream@2.0.21: - resolution: {integrity: sha512-0BUE16d7n1x7pi1YluXJdB33jOTyBChT0j/BlOkFa9uxfg6YqXieHxjHNuCdJRARa7AZEj32LLLEPJ1fSa4inA==} + /@smithy/util-stream@2.1.3: + resolution: {integrity: sha512-HvpEQbP8raTy9n86ZfXiAkf3ezp1c3qeeO//zGqwZdrfaoOpGKQgF2Sv1IqZp7wjhna7pvczWaGUHjcOPuQwKw==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/fetch-http-handler': 2.2.7 - '@smithy/node-http-handler': 2.1.10 - '@smithy/types': 2.6.0 - '@smithy/util-base64': 2.0.1 - '@smithy/util-buffer-from': 2.0.0 - '@smithy/util-hex-encoding': 2.0.0 - '@smithy/util-utf8': 2.0.2 + '@smithy/fetch-http-handler': 2.4.3 + '@smithy/node-http-handler': 2.4.1 + '@smithy/types': 2.10.1 + '@smithy/util-base64': 2.1.1 + '@smithy/util-buffer-from': 2.1.1 + '@smithy/util-hex-encoding': 2.1.1 + '@smithy/util-utf8': 2.1.1 tslib: 2.6.2 dev: false - /@smithy/util-uri-escape@2.0.0: - resolution: {integrity: sha512-ebkxsqinSdEooQduuk9CbKcI+wheijxEb3utGXkCoYQkJnwTnLbH1JXGimJtUkQwNQbsbuYwG2+aFVyZf5TLaw==} + /@smithy/util-uri-escape@2.1.1: + resolution: {integrity: sha512-saVzI1h6iRBUVSqtnlOnc9ssU09ypo7n+shdQ8hBTZno/9rZ3AuRYvoHInV57VF7Qn7B+pFJG7qTzFiHxWlWBw==} engines: {node: '>=14.0.0'} dependencies: tslib: 2.6.2 dev: false - /@smithy/util-utf8@2.0.2: - resolution: {integrity: sha512-qOiVORSPm6Ce4/Yu6hbSgNHABLP2VMv8QOC3tTDNHHlWY19pPyc++fBTbZPtx6egPXi4HQxKDnMxVxpbtX2GoA==} + /@smithy/util-utf8@2.1.1: + resolution: {integrity: sha512-BqTpzYEcUMDwAKr7/mVRUtHDhs6ZoXDi9NypMvMfOr/+u1NW7JgqodPDECiiLboEm6bobcPcECxzjtQh865e9A==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/util-buffer-from': 2.0.0 + '@smithy/util-buffer-from': 2.1.1 tslib: 2.6.2 dev: false - /@smithy/util-waiter@2.0.14: - resolution: {integrity: sha512-Q6gSz4GUNjNGhrfNg+2Mjy+7K4pEI3r82x1b/+3dSc03MQqobMiUrRVN/YK/4nHVagvBELCoXsiHAFQJNQ5BeA==} + /@smithy/util-waiter@2.1.3: + resolution: {integrity: sha512-3R0wNFAQQoH9e4m+bVLDYNOst2qNxtxFgq03WoNHWTBOqQT3jFnOBRj1W51Rf563xDA5kwqjziksxn6RKkHB+Q==} engines: {node: '>=14.0.0'} dependencies: - '@smithy/abort-controller': 2.0.14 - '@smithy/types': 2.6.0 + '@smithy/abort-controller': 2.1.3 + '@smithy/types': 2.10.1 tslib: 2.6.2 dev: false @@ -1891,10 +2257,67 @@ packages: resolution: {integrity: sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw==} dev: false + /@subsquid/evm-typegen@3.3.0(ethers@6.11.1): + resolution: {integrity: sha512-xSBa4B5dsvcazXZk2ufzsF94Hz/dcOkwT8zRs2kTcaozLAfI11SasvjaD9ClhqYDr8z7kc/xEgu2Gle0hLRvtg==} + hasBin: true + peerDependencies: + ethers: ^6.9.0 + dependencies: + '@subsquid/http-client': 1.3.2 + '@subsquid/logger': 1.3.3 + '@subsquid/util-internal': 3.0.0 + '@subsquid/util-internal-code-printer': 1.2.2 + '@subsquid/util-internal-commander': 1.3.2(commander@11.1.0) + commander: 11.1.0 + ethers: 6.11.1 + dev: false + /@subsquid/graphiql-console@0.3.0: resolution: {integrity: sha512-C89mus6IXnNi0xMQrZqUFBZwLj8tbuq9lye8Gq/lHmmERAUpi6UsWEyLdJLx2mneZzF3JtY8eNiiZ16jmjtvfw==} dev: false + /@subsquid/http-client@1.3.2: + resolution: {integrity: sha512-N9fXB2TCYzzT4CNoTibpgk4lMFNU463/ZQcSstPPMIpZA9QdDjY+mNdjLTi8L+4DzimgjEbwYfLQX5aINYvkMA==} + dependencies: + '@subsquid/logger': 1.3.3 + '@subsquid/util-internal': 3.0.0 + node-fetch: 3.3.2 + dev: false + + /@subsquid/logger@1.3.3: + resolution: {integrity: sha512-BdoRVIOrIRzKdMZPoJxzJzPLulf5Q09GeLtJn0whP+rhDV5nQ4ANDAzjPg9jmgH9WkMYAr2XH4lny/4PjhQUNA==} + dependencies: + '@subsquid/util-internal-hex': 1.2.2 + '@subsquid/util-internal-json': 1.2.2 + supports-color: 8.1.1 + dev: false + + /@subsquid/util-internal-code-printer@1.2.2: + resolution: {integrity: sha512-uerf8T/FU4bxxhat09MgRrdmwifLwV+tO7QvlMvZ5ccwaVrJjHs+0/LY/h1e9YowH3+ZtwPqjYrd5tNOHWX8wA==} + dev: false + + /@subsquid/util-internal-commander@1.3.2(commander@11.1.0): + resolution: {integrity: sha512-9/1vI1dmGQMp5wjN6hb94VCnSosT+caob33tAesFaIdqLzqQlDtlTSRq1TFFossAgtsEJFi7GiQ8i31L/gaxSQ==} + peerDependencies: + commander: ^11.1.0 + dependencies: + commander: 11.1.0 + dev: false + + /@subsquid/util-internal-hex@1.2.2: + resolution: {integrity: sha512-E43HVqf23jP5hvtWF9GsiN8luANjnJ1daR2SVTwaIUAYU/uNjv1Bi6tHz2uexlflBhyxAgBDmHgunXZ45wQTIw==} + dev: false + + /@subsquid/util-internal-json@1.2.2: + resolution: {integrity: sha512-+axQnlkIzscdy0T/vR1Dez/2NVCryWgB3OocMGJcx2GjhHVkmuJSLFqOdk9o90OocfQFC57NTZx22oa2yd+4Yw==} + dependencies: + '@subsquid/util-internal-hex': 1.2.2 + dev: false + + /@subsquid/util-internal@3.0.0: + resolution: {integrity: sha512-aGPTiLF21N9f67DgHS4PBR8d6mdvXHTOIhr2mFQPX7GQCgZhNlCZDM/1Sqn+teJawCy3w6Y9f6KOtVbN4T5SFQ==} + dev: false + /@substrate/calc@0.2.8: resolution: {integrity: sha512-1c3mxf35FBeOswduhy0Wil9s4exHahXFo974qa0Ci2AORX8JTxmwhBb10+3Ls9iWoTFwvgOaFr9v1HeRL5tCig==} dev: false @@ -1922,30 +2345,30 @@ packages: resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} dev: false - /@types/accepts@1.3.5: - resolution: {integrity: sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==} + /@types/accepts@1.3.7: + resolution: {integrity: sha512-Pay9fq2lM2wXPWbteBsRAGiWH2hig4ZE2asK+mm7kUzlxRTfL961rj89I6zV/E3PcIkDqyuBEcMxFT7rccugeQ==} dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 dev: false /@types/body-parser@1.19.2: resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==} dependencies: - '@types/connect': 3.4.36 - '@types/node': 18.18.14 + '@types/connect': 3.4.38 + '@types/node': 18.19.21 dev: false - /@types/body-parser@1.19.3: - resolution: {integrity: sha512-oyl4jvAfTGX9Bt6Or4H9ni1Z447/tQuxnZsytsCaExKlmJiU8sFgnIBRzJUpKwB5eWn9HuBYlUlVA74q/yN0eQ==} + /@types/body-parser@1.19.5: + resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} dependencies: - '@types/connect': 3.4.36 - '@types/node': 18.18.14 + '@types/connect': 3.4.38 + '@types/node': 18.19.21 dev: false - /@types/connect@3.4.36: - resolution: {integrity: sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w==} + /@types/connect@3.4.38: + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 dev: false /@types/cors@2.8.12: @@ -1956,89 +2379,86 @@ packages: resolution: {integrity: sha512-tqdiS4otQP4KmY0PR3u6KbZ5EWvhNdUoS/jc93UuK23C220lOZ/9TvjfxdPcKvqwwDVtmtSCrnr0p/2dirAxkA==} dev: false + /@types/estree@1.0.5: + resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + dev: false + /@types/express-serve-static-core@4.17.31: resolution: {integrity: sha512-DxMhY+NAsTwMMFHBTtJFNp5qiHKJ7TeqOo23zVEM9alT1Ml27Q3xcTH0xwxn7Q0BbMcVEJOs/7aQtUWupUQN3Q==} dependencies: - '@types/node': 18.18.14 - '@types/qs': 6.9.8 - '@types/range-parser': 1.2.5 + '@types/node': 18.19.21 + '@types/qs': 6.9.12 + '@types/range-parser': 1.2.7 dev: false - /@types/express-serve-static-core@4.17.37: - resolution: {integrity: sha512-ZohaCYTgGFcOP7u6aJOhY9uIZQgZ2vxC2yWoArY+FeDXlqeH66ZVBjgvg+RLVAS/DWNq4Ap9ZXu1+SUQiiWYMg==} + /@types/express-serve-static-core@4.17.43: + resolution: {integrity: sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==} dependencies: - '@types/node': 18.18.14 - '@types/qs': 6.9.8 - '@types/range-parser': 1.2.5 - '@types/send': 0.17.2 + '@types/node': 18.19.21 + '@types/qs': 6.9.12 + '@types/range-parser': 1.2.7 + '@types/send': 0.17.4 dev: false /@types/express@4.17.14: resolution: {integrity: sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg==} dependencies: - '@types/body-parser': 1.19.3 - '@types/express-serve-static-core': 4.17.37 - '@types/qs': 6.9.8 - '@types/serve-static': 1.15.3 + '@types/body-parser': 1.19.2 + '@types/express-serve-static-core': 4.17.31 + '@types/qs': 6.9.12 + '@types/serve-static': 1.15.5 dev: false /@types/express@4.17.21: resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} dependencies: - '@types/body-parser': 1.19.3 - '@types/express-serve-static-core': 4.17.37 - '@types/qs': 6.9.8 - '@types/serve-static': 1.15.3 + '@types/body-parser': 1.19.5 + '@types/express-serve-static-core': 4.17.43 + '@types/qs': 6.9.12 + '@types/serve-static': 1.15.5 dev: false /@types/glob@7.2.0: resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} dependencies: '@types/minimatch': 5.1.2 - '@types/node': 18.18.14 + '@types/node': 18.19.21 dev: false - /@types/glob@8.1.0: - resolution: {integrity: sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==} - dependencies: - '@types/minimatch': 5.1.2 - '@types/node': 18.18.0 - dev: false - - /@types/http-errors@2.0.2: - resolution: {integrity: sha512-lPG6KlZs88gef6aD85z3HNkztpj7w2R7HmR3gygjfXCQmsLloWNARFkMuzKiiY8FGdh1XDpgBdrSf4aKDiA7Kg==} + /@types/http-errors@2.0.4: + resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} dev: false /@types/inflected@2.1.3: resolution: {integrity: sha512-qEllJ4fo4Cn8sPu/6+2Iw6ouxcFuQIfj3PDRO8cvzvUaJ5udD2IGwFm6xrzOQSJm4MzXRcvZkR3rqwWxvxP8eQ==} dev: false - /@types/istanbul-lib-coverage@2.0.4: - resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} + /@types/istanbul-lib-coverage@2.0.6: + resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} dev: false - /@types/istanbul-lib-report@3.0.1: - resolution: {integrity: sha512-gPQuzaPR5h/djlAv2apEG1HVOyj1IUs7GpfMZixU0/0KXT3pm64ylHuMUI1/Akh+sq/iikxg6Z2j+fcMDXaaTQ==} + /@types/istanbul-lib-report@3.0.3: + resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} dependencies: - '@types/istanbul-lib-coverage': 2.0.4 + '@types/istanbul-lib-coverage': 2.0.6 dev: false - /@types/istanbul-reports@3.0.2: - resolution: {integrity: sha512-kv43F9eb3Lhj+lr/Hn6OcLCs/sSM8bt+fIaP11rCYngfV6NVjzWXJ17owQtDQTL9tQ8WSLUrGsSJ6rJz0F1w1A==} + /@types/istanbul-reports@3.0.4: + resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} dependencies: - '@types/istanbul-lib-report': 3.0.1 + '@types/istanbul-lib-report': 3.0.3 dev: false /@types/long@4.0.2: resolution: {integrity: sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==} dev: false - /@types/mime@1.3.3: - resolution: {integrity: sha512-Ys+/St+2VF4+xuY6+kDIXGxbNRO0mesVg0bbxEfB97Od1Vjpjx9KD1qxs64Gcb3CWPirk9Xe+PT4YiiHQ9T+eg==} + /@types/mime@1.3.5: + resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} dev: false - /@types/mime@3.0.2: - resolution: {integrity: sha512-Wj+fqpTLtTbG7c0tH47dkahefpLKEbB+xAZuLq7b4/IDHPl/n6VoXcyUQ2bypFlbSwvCr0y+bD4euTTqTJsPxQ==} + /@types/mime@3.0.4: + resolution: {integrity: sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw==} dev: false /@types/minimatch@5.1.2: @@ -2057,95 +2477,158 @@ packages: resolution: {integrity: sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==} dev: false - /@types/node@18.18.0: - resolution: {integrity: sha512-3xA4X31gHT1F1l38ATDIL9GpRLdwVhnEFC8Uikv5ZLlXATwrCYyPq7ZWHxzxc3J/30SUiwiYT+bQe0/XvKlWbw==} - dev: false - - /@types/node@18.18.14: - resolution: {integrity: sha512-iSOeNeXYNYNLLOMDSVPvIFojclvMZ/HDY2dU17kUlcsOsSQETbWIslJbYLZgA+ox8g2XQwSHKTkght1a5X26lQ==} + /@types/node@18.19.21: + resolution: {integrity: sha512-2Q2NeB6BmiTFQi4DHBzncSoq/cJMLDdhPaAoJFnFCyD9a8VPZRf7a1GAwp1Edb7ROaZc5Jz/tnZyL6EsWMRaqw==} dependencies: undici-types: 5.26.5 dev: false - /@types/pg@8.10.9: - resolution: {integrity: sha512-UksbANNE/f8w0wOMxVKKIrLCbEMV+oM1uKejmwXr39olg4xqcfBDbXxObJAt6XxHbDa4XTKOlUEcEltXDX+XLQ==} + /@types/pg@8.11.2: + resolution: {integrity: sha512-G2Mjygf2jFMU/9hCaTYxJrwdObdcnuQde1gndooZSOHsNSaCehAuwc7EIuSA34Do8Jx2yZ19KtvW8P0j4EuUXw==} dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 pg-protocol: 1.6.0 - pg-types: 4.0.1 + pg-types: 4.0.2 dev: false - /@types/qs@6.9.8: - resolution: {integrity: sha512-u95svzDlTysU5xecFNTgfFG5RUWu1A9P0VzgpcIiGZA9iraHOdSzcxMxQ55DyeRaGCSxQi7LxXDI4rzq/MYfdg==} + /@types/qs@6.9.12: + resolution: {integrity: sha512-bZcOkJ6uWrL0Qb2NAWKa7TBU+mJHPzhx9jjLL1KHF+XpzEcR7EXHvjbHlGtR/IsP1vyPrehuS6XqkmaePy//mg==} dev: false - /@types/range-parser@1.2.5: - resolution: {integrity: sha512-xrO9OoVPqFuYyR/loIHjnbvvyRZREYKLjxV4+dY6v3FQR3stQ9ZxIGkaclF7YhI9hfjpuTbu14hZEy94qKLtOA==} + /@types/range-parser@1.2.7: + resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} dev: false - /@types/semver@7.5.6: - resolution: {integrity: sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==} + /@types/semver@7.5.8: + resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} dev: false - /@types/send@0.17.2: - resolution: {integrity: sha512-aAG6yRf6r0wQ29bkS+x97BIs64ZLxeE/ARwyS6wrldMm3C1MdKwCcnnEwMC1slI8wuxJOpiUH9MioC0A0i+GJw==} + /@types/send@0.17.4: + resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} dependencies: - '@types/mime': 1.3.3 - '@types/node': 18.18.14 + '@types/mime': 1.3.5 + '@types/node': 18.19.21 dev: false - /@types/serve-static@1.15.3: - resolution: {integrity: sha512-yVRvFsEMrv7s0lGhzrggJjNOSmZCdgCjw9xWrPr/kNNLp6FaDfMC1KaYl3TSJ0c58bECwNBMoQrZJ8hA8E1eFg==} + /@types/serve-static@1.15.5: + resolution: {integrity: sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==} dependencies: - '@types/http-errors': 2.0.2 - '@types/mime': 3.0.2 - '@types/node': 18.18.14 + '@types/http-errors': 2.0.4 + '@types/mime': 3.0.4 + '@types/node': 18.19.21 dev: false - /@types/stack-utils@2.0.1: - resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==} + /@types/stack-utils@2.0.3: + resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} dev: false /@types/stoppable@1.1.3: resolution: {integrity: sha512-7wGKIBJGE4ZxFjk9NkjAxZMLlIXroETqP1FJCdoSvKmEznwmBxQFmTB1dsCkAvVcNemuSZM5qkkd9HE/NL2JTw==} dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 dev: false /@types/supports-color@8.1.3: resolution: {integrity: sha512-Hy6UMpxhE3j1tLpl27exp1XqHD7n8chAiNPzWfz16LPZoMMoSc4dzLl6w9qijkEb/r5O1ozdu1CWGA2L83ZeZg==} dev: false - /@types/validator@13.11.2: - resolution: {integrity: sha512-nIKVVQKT6kGKysnNt+xLobr+pFJNssJRi2s034wgWeFBUx01fI8BeHTW2TcRp7VcFu9QCYG8IlChTuovcm0oKQ==} + /@types/validator@13.11.9: + resolution: {integrity: sha512-FCTsikRozryfayPuiI46QzH3fnrOoctTjvOYZkho9BTFLCOZ2rgZJHMOVgCOfttjPJcgOx52EpkY0CMfy87MIw==} dev: false /@types/websocket@1.0.10: resolution: {integrity: sha512-svjGZvPB7EzuYS94cI7a+qhwgGU1y89wUgjT6E2wVUfmAGIvRfT7obBvRtnhXCSsoMdlG4gBFGE7MfkIXZLoww==} dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 dev: false /@types/ws@8.5.10: resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==} dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 dev: false /@types/xxhashjs@0.2.4: resolution: {integrity: sha512-E2+ZoJY2JjmVPN0iQM5gJvZkk98O2PYXSi6HrciEk3EKF34+mauEk/HgwTeCz+2r8HXHMKpucrwy4qTT12OPaQ==} dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 dev: false - /@types/yargs-parser@21.0.1: - resolution: {integrity: sha512-axdPBuLuEJt0c4yI5OZssC19K2Mq1uKdrfZBzuxLvaztgqUtFYZUNw7lETExPYJR9jdEoIg4mb7RQKRQzOkeGQ==} + /@types/yargs-parser@21.0.3: + resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} dev: false - /@types/yargs@17.0.25: - resolution: {integrity: sha512-gy7iPgwnzNvxgAEi2bXOHWCVOG6f7xsprVJH4MjlAWeBmJ7vh/Y1kwMtUrs64ztf24zVIRCpr3n/z6gm9QIkgg==} + /@types/yargs@17.0.32: + resolution: {integrity: sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==} dependencies: - '@types/yargs-parser': 21.0.1 + '@types/yargs-parser': 21.0.3 + dev: false + + /@vitest/expect@1.3.1: + resolution: {integrity: sha512-xofQFwIzfdmLLlHa6ag0dPV8YsnKOCP1KdAeVVh34vSjN2dcUiXYCD9htu/9eM7t8Xln4v03U9HLxLpPlsXdZw==} + dependencies: + '@vitest/spy': 1.3.1 + '@vitest/utils': 1.3.1 + chai: 4.4.1 + dev: false + + /@vitest/runner@1.3.1: + resolution: {integrity: sha512-5FzF9c3jG/z5bgCnjr8j9LNq/9OxV2uEBAITOXfoe3rdZJTdO7jzThth7FXv/6b+kdY65tpRQB7WaKhNZwX+Kg==} + dependencies: + '@vitest/utils': 1.3.1 + p-limit: 5.0.0 + pathe: 1.1.2 + dev: false + + /@vitest/snapshot@1.3.1: + resolution: {integrity: sha512-EF++BZbt6RZmOlE3SuTPu/NfwBF6q4ABS37HHXzs2LUVPBLx2QoY/K0fKpRChSo8eLiuxcbCVfqKgx/dplCDuQ==} + dependencies: + magic-string: 0.30.8 + pathe: 1.1.2 + pretty-format: 29.7.0 + dev: false + + /@vitest/spy@1.3.1: + resolution: {integrity: sha512-xAcW+S099ylC9VLU7eZfdT9myV67Nor9w9zhf0mGCYJSO+zM2839tOeROTdikOi/8Qeusffvxb/MyBSOja1Uig==} + dependencies: + tinyspy: 2.2.1 + dev: false + + /@vitest/utils@1.3.1: + resolution: {integrity: sha512-d3Waie/299qqRyHTm2DjADeTaNdNSVsnwHPWrs20JMpjh6eiVq7ggggweO8rc4arhf6rRkWuHKwvxGvejUXZZQ==} + dependencies: + diff-sequences: 29.6.3 + estree-walker: 3.0.3 + loupe: 2.3.7 + pretty-format: 29.7.0 + dev: false + + /abitype@1.0.0(typescript@5.3.3): + resolution: {integrity: sha512-NMeMah//6bJ56H5XRj8QCV4AwuW6hB6zqz2LnhhLdcWVQOsXki6/Pn3APeqxCma62nXIcmZWdu1DlHWS74umVQ==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + dependencies: + typescript: 5.3.3 + dev: false + + /abitype@1.0.1(typescript@5.3.3): + resolution: {integrity: sha512-HyHCfBwNYvHPGWsdv5PiKj8b1LnZUCuALyUWg5iP/wbK8FpdmTI4Qk9CYzjNgmsWwRw5j/DCruOltrnUGQdBeQ==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + dependencies: + typescript: 5.3.3 dev: false /accepts@1.3.8: @@ -2156,13 +2639,13 @@ packages: negotiator: 0.6.3 dev: false - /acorn-walk@8.3.1: - resolution: {integrity: sha512-TgUZgYvqZprrl7YldZNoa9OciCAyZR+Ejm9eXzKCmjsF5IKp/wgQ7Z/ZpjpGTIUPwrHQIcYeI8qDh4PsEwxMbw==} + /acorn-walk@8.3.2: + resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} engines: {node: '>=0.4.0'} dev: false - /acorn@8.11.2: - resolution: {integrity: sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==} + /acorn@8.11.3: + resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} engines: {node: '>=0.4.0'} hasBin: true dev: false @@ -2273,7 +2756,7 @@ packages: fast-json-stable-stringify: 2.1.0 graphql: 15.8.0 graphql-tag: 2.12.6(graphql@15.8.0) - loglevel: 1.8.1 + loglevel: 1.9.1 lru-cache: 6.0.0 node-abort-controller: 3.1.1 sha.js: 2.4.11 @@ -2303,14 +2786,14 @@ packages: graphql: 15.8.0 dev: false - /apollo-server-express@3.13.0(express@4.18.2)(graphql@15.8.0): + /apollo-server-express@3.13.0(express@4.18.3)(graphql@15.8.0): resolution: {integrity: sha512-iSxICNbDUyebOuM8EKb3xOrpIwOQgKxGbR2diSr4HP3IW8T3njKFOoMce50vr+moOCe1ev8BnLcw9SNbuUtf7g==} engines: {node: '>=12.0'} peerDependencies: express: ^4.17.1 graphql: ^15.3.0 || ^16.0.0 dependencies: - '@types/accepts': 1.3.5 + '@types/accepts': 1.3.7 '@types/body-parser': 1.19.2 '@types/cors': 2.8.12 '@types/express': 4.17.14 @@ -2320,7 +2803,7 @@ packages: apollo-server-types: 3.8.0(graphql@15.8.0) body-parser: 1.20.2 cors: 2.8.5 - express: 4.18.2 + express: 4.18.3 graphql: 15.8.0 parseurl: 1.3.3 transitivePeerDependencies: @@ -2384,30 +2867,37 @@ packages: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} dev: false - /array-buffer-byte-length@1.0.0: - resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==} + /array-buffer-byte-length@1.0.1: + resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} + engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 - is-array-buffer: 3.0.2 + call-bind: 1.0.7 + is-array-buffer: 3.0.4 dev: false /array-flatten@1.1.1: resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} dev: false + /assertion-error@1.1.0: + resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + dev: false + /async-retry@1.3.3: resolution: {integrity: sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==} dependencies: retry: 0.13.1 dev: false - /available-typed-arrays@1.0.5: - resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} + /available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} + dependencies: + possible-typed-array-names: 1.0.0 dev: false - /b4a@1.6.4: - resolution: {integrity: sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==} + /b4a@1.6.6: + resolution: {integrity: sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==} dev: false /balanced-match@1.0.2: @@ -2438,7 +2928,7 @@ packages: /blake2b-wasm@2.4.0: resolution: {integrity: sha512-S1kwmW2ZhZFFFOghcx73+ZajEfKBqhP82JMssxtLVMxlaPea1p9uoLiUZ5WYyHn0KddwbLc+0vh4wR0KBNoT5w==} dependencies: - b4a: 1.6.4 + b4a: 1.6.6 nanoassert: 2.0.0 dev: false @@ -2449,24 +2939,6 @@ packages: nanoassert: 2.0.0 dev: false - /body-parser@1.20.1: - resolution: {integrity: sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - dependencies: - bytes: 3.1.2 - content-type: 1.0.5 - debug: 2.6.9 - depd: 2.0.0 - destroy: 1.2.0 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - on-finished: 2.4.1 - qs: 6.11.0 - raw-body: 2.5.1 - type-is: 1.6.18 - unpipe: 1.0.0 - dev: false - /body-parser@1.20.2: resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} @@ -2525,12 +2997,12 @@ packages: ieee754: 1.2.1 dev: false - /bufferutil@4.0.7: - resolution: {integrity: sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw==} + /bufferutil@4.0.8: + resolution: {integrity: sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==} engines: {node: '>=6.14.2'} requiresBuild: true dependencies: - node-gyp-build: 4.6.1 + node-gyp-build: 4.8.0 dev: false /bytes@3.1.2: @@ -2538,6 +3010,11 @@ packages: engines: {node: '>= 0.8'} dev: false + /cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + dev: false + /cacheable-request@6.1.0: resolution: {integrity: sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==} engines: {node: '>=8'} @@ -2551,19 +3028,15 @@ packages: responselike: 1.0.2 dev: false - /call-bind@1.0.2: - resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} - dependencies: - function-bind: 1.1.1 - get-intrinsic: 1.2.1 - dev: false - - /call-bind@1.0.5: - resolution: {integrity: sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==} + /call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 function-bind: 1.1.2 - get-intrinsic: 1.2.2 - set-function-length: 1.1.1 + get-intrinsic: 1.2.4 + set-function-length: 1.2.1 dev: false /camelcase@6.3.0: @@ -2571,6 +3044,19 @@ packages: engines: {node: '>=10'} dev: false + /chai@4.4.1: + resolution: {integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==} + engines: {node: '>=4'} + dependencies: + assertion-error: 1.1.0 + check-error: 1.0.3 + deep-eql: 4.1.3 + get-func-name: 2.0.2 + loupe: 2.3.7 + pathval: 1.1.1 + type-detect: 4.0.8 + dev: false + /chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} @@ -2588,6 +3074,12 @@ packages: supports-color: 7.2.0 dev: false + /check-error@1.0.3: + resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + dependencies: + get-func-name: 2.0.2 + dev: false + /chokidar@3.5.3: resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} engines: {node: '>= 8.10.0'} @@ -2603,16 +3095,16 @@ packages: fsevents: 2.3.3 dev: false - /ci-info@3.8.0: - resolution: {integrity: sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==} + /ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} dev: false - /class-validator@0.14.0: - resolution: {integrity: sha512-ct3ltplN8I9fOwUd8GrP8UQixwff129BkEtuWDKL5W45cQuLd19xqmTLu5ge78YDm/fdje6FMt0hGOhl0lii3A==} + /class-validator@0.14.1: + resolution: {integrity: sha512-2VEG9JICxIqTpoK1eMzZqaV+u/EiwEJkMGzTrZf6sU/fwsnOITVgYJ8yojSy6CaXtO9V0Cc6ZQZ8h8m4UBuLwQ==} dependencies: - '@types/validator': 13.11.2 - libphonenumber-js: 1.10.45 + '@types/validator': 13.11.9 + libphonenumber-js: 1.10.57 validator: 13.11.0 dev: false @@ -2678,6 +3170,10 @@ packages: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} dev: false + /command-exists@1.2.9: + resolution: {integrity: sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==} + dev: false + /commander@11.1.0: resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} engines: {node: '>=16'} @@ -2687,6 +3183,11 @@ packages: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} dev: false + /commander@8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + dev: false + /concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} dev: false @@ -2748,11 +3249,12 @@ packages: resolution: {integrity: sha512-d4ZVpCW31eWwCMe1YT3ur7mUDnTXbgwyzaL320DrcRT45rfjYxkt5QWLrmOJ+/UEAI2+fQgKe/fCjR8l4TpRgw==} dev: false - /d@1.0.1: - resolution: {integrity: sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==} + /d@1.0.2: + resolution: {integrity: sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==} + engines: {node: '>=0.12'} dependencies: - es5-ext: 0.10.62 - type: 1.2.0 + es5-ext: 0.10.64 + type: 2.7.2 dev: false /data-uri-to-buffer@4.0.1: @@ -2764,11 +3266,8 @@ packages: resolution: {integrity: sha512-8YnDaaf7N3k/q5HnTJVuzSyLETjoZjVmHc4AeKAzOvKHEFQKcn64OKBfzHYtE9zGjctNM7V9I0MfnUVLpi7M5g==} dev: false - /date-fns@2.30.0: - resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==} - engines: {node: '>=0.11'} - dependencies: - '@babel/runtime': 7.23.1 + /dayjs@1.11.10: + resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==} dev: false /debug@2.6.9: @@ -2802,28 +3301,35 @@ packages: mimic-response: 1.0.1 dev: false + /deep-eql@4.1.3: + resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==} + engines: {node: '>=6'} + dependencies: + type-detect: 4.0.8 + dev: false + /deep-equal@2.2.3: resolution: {integrity: sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==} engines: {node: '>= 0.4'} dependencies: - array-buffer-byte-length: 1.0.0 - call-bind: 1.0.5 + array-buffer-byte-length: 1.0.1 + call-bind: 1.0.7 es-get-iterator: 1.1.3 - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.4 is-arguments: 1.1.1 - is-array-buffer: 3.0.2 + is-array-buffer: 3.0.4 is-date-object: 1.0.5 is-regex: 1.1.4 - is-shared-array-buffer: 1.0.2 + is-shared-array-buffer: 1.0.3 isarray: 2.0.5 - object-is: 1.1.5 + object-is: 1.1.6 object-keys: 1.1.1 - object.assign: 4.1.4 - regexp.prototype.flags: 1.5.1 - side-channel: 1.0.4 + object.assign: 4.1.5 + regexp.prototype.flags: 1.5.2 + side-channel: 1.0.6 which-boxed-primitive: 1.0.2 which-collection: 1.0.1 - which-typed-array: 1.1.13 + which-typed-array: 1.1.14 dev: false /deep-extend@0.6.0: @@ -2835,30 +3341,21 @@ packages: resolution: {integrity: sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==} dev: false - /define-data-property@1.1.0: - resolution: {integrity: sha512-UzGwzcjyv3OtAvolTj1GoyNYzfFR+iqbGjcnBEENZVCpM4/Ng1yhGNvS3lR/xDS74Tb2wGG9WzNSNIOS9UVb2g==} - engines: {node: '>= 0.4'} - dependencies: - get-intrinsic: 1.2.2 - gopd: 1.0.1 - has-property-descriptors: 1.0.0 - dev: false - - /define-data-property@1.1.1: - resolution: {integrity: sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==} + /define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} engines: {node: '>= 0.4'} dependencies: - get-intrinsic: 1.2.2 + es-define-property: 1.0.0 + es-errors: 1.3.0 gopd: 1.0.1 - has-property-descriptors: 1.0.0 dev: false /define-properties@1.2.1: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} dependencies: - define-data-property: 1.1.0 - has-property-descriptors: 1.0.0 + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 object-keys: 1.1.1 dev: false @@ -2892,13 +3389,13 @@ packages: engines: {node: '>=0.3.1'} dev: false - /dotenv@16.3.1: - resolution: {integrity: sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==} + /dotenv@16.4.5: + resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} engines: {node: '>=12'} dev: false - /dset@3.1.2: - resolution: {integrity: sha512-g/M9sqy3oHe477Ar4voQxWtaPIFw1jTdKZuomOjhCcBx9nHUNn0pu6NopuFFrTh/TRZIKEj+76vLWFu9BNKk+Q==} + /dset@3.1.3: + resolution: {integrity: sha512-20TuZZHCEZ2O71q9/+8BwKwZ0QtD9D8ObhrihJPr+vLLYlSuAU3/zL4cSlgbfeoGHTjCSJBa7NGcrF9/Bx/WJQ==} engines: {node: '>=4'} dev: false @@ -2933,11 +3430,23 @@ packages: once: 1.4.0 dev: false + /es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.4 + dev: false + + /es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + dev: false + /es-get-iterator@1.1.3: resolution: {integrity: sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==} dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 has-symbols: 1.0.3 is-arguments: 1.1.1 is-map: 2.0.2 @@ -2947,33 +3456,66 @@ packages: stop-iteration-iterator: 1.0.0 dev: false - /es5-ext@0.10.62: - resolution: {integrity: sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==} + /es5-ext@0.10.64: + resolution: {integrity: sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==} engines: {node: '>=0.10'} requiresBuild: true dependencies: es6-iterator: 2.0.3 - es6-symbol: 3.1.3 + es6-symbol: 3.1.4 + esniff: 2.0.1 next-tick: 1.1.0 dev: false /es6-iterator@2.0.3: resolution: {integrity: sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==} dependencies: - d: 1.0.1 - es5-ext: 0.10.62 - es6-symbol: 3.1.3 + d: 1.0.2 + es5-ext: 0.10.64 + es6-symbol: 3.1.4 dev: false - /es6-symbol@3.1.3: - resolution: {integrity: sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==} + /es6-symbol@3.1.4: + resolution: {integrity: sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==} + engines: {node: '>=0.12'} dependencies: - d: 1.0.1 + d: 1.0.2 ext: 1.7.0 dev: false - /escalade@3.1.1: - resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} + /esbuild@0.19.12: + resolution: {integrity: sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/aix-ppc64': 0.19.12 + '@esbuild/android-arm': 0.19.12 + '@esbuild/android-arm64': 0.19.12 + '@esbuild/android-x64': 0.19.12 + '@esbuild/darwin-arm64': 0.19.12 + '@esbuild/darwin-x64': 0.19.12 + '@esbuild/freebsd-arm64': 0.19.12 + '@esbuild/freebsd-x64': 0.19.12 + '@esbuild/linux-arm': 0.19.12 + '@esbuild/linux-arm64': 0.19.12 + '@esbuild/linux-ia32': 0.19.12 + '@esbuild/linux-loong64': 0.19.12 + '@esbuild/linux-mips64el': 0.19.12 + '@esbuild/linux-ppc64': 0.19.12 + '@esbuild/linux-riscv64': 0.19.12 + '@esbuild/linux-s390x': 0.19.12 + '@esbuild/linux-x64': 0.19.12 + '@esbuild/netbsd-x64': 0.19.12 + '@esbuild/openbsd-x64': 0.19.12 + '@esbuild/sunos-x64': 0.19.12 + '@esbuild/win32-arm64': 0.19.12 + '@esbuild/win32-ia32': 0.19.12 + '@esbuild/win32-x64': 0.19.12 + dev: false + + /escalade@3.1.2: + resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} engines: {node: '>=6'} dev: false @@ -2996,16 +3538,32 @@ packages: engines: {node: '>=10'} dev: false + /esniff@2.0.1: + resolution: {integrity: sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==} + engines: {node: '>=0.10'} + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + event-emitter: 0.3.5 + type: 2.7.2 + dev: false + + /estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + dependencies: + '@types/estree': 1.0.5 + dev: false + /etag@1.8.1: resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} engines: {node: '>= 0.6'} dev: false - /ethers@6.9.0: - resolution: {integrity: sha512-pmfNyQzc2mseLe91FnT2vmNaTt8dDzhxZ/xItAV7uGsF4dI4ek2ufMu3rAkgQETL/TIs0GS5A+U05g9QyWnv3Q==} + /ethers@6.11.1: + resolution: {integrity: sha512-mxTAE6wqJQAbp5QAe/+o+rXOID7Nw91OZXvgpjDa1r4fAbq2Nu314oEZSbjoRLacuCzs7kUC3clEvkCQowffGg==} engines: {node: '>=14.0.0'} dependencies: - '@adraffy/ens-normalize': 1.10.0 + '@adraffy/ens-normalize': 1.10.1 '@noble/curves': 1.2.0 '@noble/hashes': 1.3.2 '@types/node': 18.15.13 @@ -3017,6 +3575,28 @@ packages: - utf-8-validate dev: false + /event-emitter@0.3.5: + resolution: {integrity: sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==} + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + dev: false + + /execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + dev: false + /expect@29.7.0: resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -3028,13 +3608,13 @@ packages: jest-util: 29.7.0 dev: false - /express@4.18.2: - resolution: {integrity: sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==} + /express@4.18.3: + resolution: {integrity: sha512-6VyCijWQ+9O7WuVMTRBTl+cjNNIzD5cY5mQ1WM8r/LEkI2u8EYpOotESNwzNlyCn3g+dmjKYI6BmNneSr/FSRw==} engines: {node: '>= 0.10.0'} dependencies: accepts: 1.3.8 array-flatten: 1.1.1 - body-parser: 1.20.1 + body-parser: 1.20.2 content-disposition: 0.5.4 content-type: 1.0.5 cookie: 0.5.0 @@ -3071,8 +3651,8 @@ packages: type: 2.7.2 dev: false - /fast-check@3.14.0: - resolution: {integrity: sha512-9Z0zqASzDNjXBox/ileV/fd+4P+V/f3o4shM6QawvcdLFh8yjPG4h5BrHUZ8yzY6amKGDTAmRMyb/JZqe+dCgw==} + /fast-check@3.16.0: + resolution: {integrity: sha512-k8GtQHi4pJoRQ1gVDFQno+/FVkowo/ehiz/aCj9O/D7HRWb1sSFzNrw+iPVU8QlWtH+jNwbuN+dDVg3QkS56DQ==} engines: {node: '>=8.0.0'} dependencies: pure-rand: 6.0.4 @@ -3098,7 +3678,7 @@ packages: engines: {node: ^12.20 || >= 14.13} dependencies: node-domexception: 1.0.0 - web-streams-polyfill: 3.2.1 + web-streams-polyfill: 3.3.3 dev: false /fill-range@7.0.1: @@ -3134,6 +3714,16 @@ packages: hasBin: true dev: false + /follow-redirects@1.15.5: + resolution: {integrity: sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + dev: false + /for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} dependencies: @@ -3177,10 +3767,6 @@ packages: dev: false optional: true - /function-bind@1.1.1: - resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} - dev: false - /function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} dev: false @@ -3194,22 +3780,19 @@ packages: engines: {node: 6.* || 8.* || >= 10.*} dev: false - /get-intrinsic@1.2.1: - resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==} - dependencies: - function-bind: 1.1.1 - has: 1.0.3 - has-proto: 1.0.1 - has-symbols: 1.0.3 + /get-func-name@2.0.2: + resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} dev: false - /get-intrinsic@1.2.2: - resolution: {integrity: sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==} + /get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} dependencies: + es-errors: 1.3.0 function-bind: 1.1.2 - has-proto: 1.0.1 + has-proto: 1.0.3 has-symbols: 1.0.3 - hasown: 2.0.0 + hasown: 2.0.1 dev: false /get-stream@4.1.0: @@ -3226,6 +3809,11 @@ packages: pump: 3.0.0 dev: false + /get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + dev: false + /glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -3241,12 +3829,12 @@ packages: foreground-child: 3.1.1 jackspeak: 2.3.6 minimatch: 9.0.3 - minipass: 7.0.3 + minipass: 7.0.4 path-scurry: 1.10.1 dev: false - /glob@7.2.0: - resolution: {integrity: sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==} + /glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} dependencies: fs.realpath: 1.0.0 inflight: 1.0.6 @@ -3263,14 +3851,14 @@ packages: fs.realpath: 1.0.0 inflight: 1.0.6 inherits: 2.0.4 - minimatch: 5.1.6 + minimatch: 5.0.1 once: 1.4.0 dev: false /gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} dependencies: - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.4 dev: false /got@9.6.0: @@ -3335,8 +3923,8 @@ packages: tslib: 2.6.2 dev: false - /graphql-ws@5.14.2(graphql@15.8.0): - resolution: {integrity: sha512-LycmCwhZ+Op2GlHz4BZDsUYHKRiiUz+3r9wbhBATMETNlORQJAaFlAgTFoeRh6xQoQegwYwIylVD1Qns9/DA3w==} + /graphql-ws@5.15.0(graphql@15.8.0): + resolution: {integrity: sha512-xWGAtm3fig9TIhSaNsg0FaDZ8Pyn/3re3RFlP4rhQcmjRDIPpk1EhRuNB+YSJtLzttyuToaDiNhwT1OMoGnJnw==} engines: {node: '>=10'} peerDependencies: graphql: '>=0.11 <=16' @@ -3363,14 +3951,14 @@ packages: engines: {node: '>=8'} dev: false - /has-property-descriptors@1.0.0: - resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==} + /has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} dependencies: - get-intrinsic: 1.2.2 + es-define-property: 1.0.0 dev: false - /has-proto@1.0.1: - resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} + /has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} engines: {node: '>= 0.4'} dev: false @@ -3379,22 +3967,15 @@ packages: engines: {node: '>= 0.4'} dev: false - /has-tostringtag@1.0.0: - resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} + /has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} dependencies: has-symbols: 1.0.3 dev: false - /has@1.0.3: - resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} - engines: {node: '>= 0.4.0'} - dependencies: - function-bind: 1.1.1 - dev: false - - /hasown@2.0.0: - resolution: {integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==} + /hasown@2.0.1: + resolution: {integrity: sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==} engines: {node: '>= 0.4'} dependencies: function-bind: 1.1.2 @@ -3424,6 +4005,11 @@ packages: toidentifier: 1.0.1 dev: false + /human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + dev: false + /iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} @@ -3454,13 +4040,13 @@ packages: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} dev: false - /internal-slot@1.0.5: - resolution: {integrity: sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==} + /internal-slot@1.0.7: + resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} engines: {node: '>= 0.4'} dependencies: - get-intrinsic: 1.2.2 - has: 1.0.3 - side-channel: 1.0.4 + es-errors: 1.3.0 + hasown: 2.0.1 + side-channel: 1.0.6 dev: false /ioredis@5.3.2(supports-color@8.1.1): @@ -3489,16 +4075,16 @@ packages: resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 - has-tostringtag: 1.0.0 + call-bind: 1.0.7 + has-tostringtag: 1.0.2 dev: false - /is-array-buffer@3.0.2: - resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} + /is-array-buffer@3.0.4: + resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} + engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 - is-typed-array: 1.1.12 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 dev: false /is-bigint@1.0.4: @@ -3518,8 +4104,8 @@ packages: resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 - has-tostringtag: 1.0.0 + call-bind: 1.0.7 + has-tostringtag: 1.0.2 dev: false /is-callable@1.2.7: @@ -3531,7 +4117,7 @@ packages: resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} engines: {node: '>= 0.4'} dependencies: - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 dev: false /is-extglob@2.1.1: @@ -3559,7 +4145,7 @@ packages: resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} engines: {node: '>= 0.4'} dependencies: - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 dev: false /is-number@7.0.0: @@ -3576,25 +4162,31 @@ packages: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 - has-tostringtag: 1.0.0 + call-bind: 1.0.7 + has-tostringtag: 1.0.2 dev: false /is-set@2.0.2: resolution: {integrity: sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==} dev: false - /is-shared-array-buffer@1.0.2: - resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} + /is-shared-array-buffer@1.0.3: + resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} + engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 + dev: false + + /is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dev: false /is-string@1.0.7: resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} engines: {node: '>= 0.4'} dependencies: - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 dev: false /is-symbol@1.0.4: @@ -3604,13 +4196,6 @@ packages: has-symbols: 1.0.3 dev: false - /is-typed-array@1.1.12: - resolution: {integrity: sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==} - engines: {node: '>= 0.4'} - dependencies: - which-typed-array: 1.1.13 - dev: false - /is-typedarray@1.0.0: resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} dev: false @@ -3627,8 +4212,8 @@ packages: /is-weakset@2.0.2: resolution: {integrity: sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==} dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 dev: false /isarray@2.0.5: @@ -3639,6 +4224,14 @@ packages: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} dev: false + /isows@1.0.3(ws@8.13.0): + resolution: {integrity: sha512-2cKei4vlmg2cxEjm3wVSqn8pcoRF/LX/wpifuuNquFO4SQmPwarClT+SUCA2lt+l581tTeZIPIZuIDo2jWN1fg==} + peerDependencies: + ws: '*' + dependencies: + ws: 8.13.0 + dev: false + /iterall@1.3.0: resolution: {integrity: sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==} dev: false @@ -3681,9 +4274,9 @@ packages: resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@babel/code-frame': 7.22.13 + '@babel/code-frame': 7.23.5 '@jest/types': 29.6.3 - '@types/stack-utils': 2.0.1 + '@types/stack-utils': 2.0.3 chalk: 4.1.2 graceful-fs: 4.2.11 micromatch: 4.0.5 @@ -3697,17 +4290,25 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 18.18.14 + '@types/node': 18.19.21 chalk: 4.1.2 - ci-info: 3.8.0 + ci-info: 3.9.0 graceful-fs: 4.2.11 picomatch: 2.3.1 dev: false + /js-sha3@0.8.0: + resolution: {integrity: sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==} + dev: false + /js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} dev: false + /js-tokens@8.0.3: + resolution: {integrity: sha512-UfJMcSJc+SEXEl9lH/VLHSZbThQyLpw1vLO1Lb+j4RWDvG3N2f7yj3PVQA3cmkTBNldJ9eFnM+xEXxHIXrYiJw==} + dev: false + /js-yaml@4.1.0: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true @@ -3727,8 +4328,8 @@ packages: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} dev: false - /jsonc-parser@3.2.0: - resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} + /jsonc-parser@3.2.1: + resolution: {integrity: sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==} dev: false /keyv@3.1.0: @@ -3750,8 +4351,16 @@ packages: package-json: 6.5.0 dev: false - /libphonenumber-js@1.10.45: - resolution: {integrity: sha512-eeHcvGafEYCaKB4fo2uBINfG7j7PcGwBHUaTVfbwl/6KcjCgIKNlIOsSXVRp9BH10NQwmvvk+nQ1e/Yp4BGB7w==} + /libphonenumber-js@1.10.57: + resolution: {integrity: sha512-OjsEd9y4LgcX+Ig09SbxWqcGESxliDDFNVepFhB9KEsQZTrnk3UdEU+cO0sW1APvLprHstQpS23OQpZ3bwxy6Q==} + dev: false + + /local-pkg@0.5.0: + resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} + engines: {node: '>=14'} + dependencies: + mlly: 1.6.1 + pkg-types: 1.0.3 dev: false /locate-path@6.0.0: @@ -3785,8 +4394,8 @@ packages: is-unicode-supported: 0.1.0 dev: false - /loglevel@1.8.1: - resolution: {integrity: sha512-tCRIJM51SHjAayKwC+QAg8hT8vg6z7GSgLJKGvzuPb1Wc+hLzqtuVLxp6/HzSPOozuK+8ErAhy7U/sVzw8Dgfg==} + /loglevel@1.9.1: + resolution: {integrity: sha512-hP3I3kCrDIMuRwAwHltphhDM1r8i55H33GgqjXbrisuJhF4kRhW1dNuxsRklp4bXl8DSdLaNLuiL4A/LWRfxvg==} engines: {node: '>= 0.6.0'} dev: false @@ -3794,6 +4403,12 @@ packages: resolution: {integrity: sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==} dev: false + /loupe@2.3.7: + resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} + dependencies: + get-func-name: 2.0.2 + dev: false + /lowercase-keys@1.0.1: resolution: {integrity: sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==} engines: {node: '>=0.10.0'} @@ -3804,8 +4419,8 @@ packages: engines: {node: '>=8'} dev: false - /lru-cache@10.0.1: - resolution: {integrity: sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==} + /lru-cache@10.2.0: + resolution: {integrity: sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==} engines: {node: 14 || >=16.14} dev: false @@ -3821,6 +4436,13 @@ packages: engines: {node: '>=12'} dev: false + /magic-string@0.30.8: + resolution: {integrity: sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + dev: false + /make-error@1.3.6: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} dev: false @@ -3830,10 +4452,19 @@ packages: engines: {node: '>= 0.6'} dev: false + /memorystream@0.3.1: + resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} + engines: {node: '>= 0.10.0'} + dev: false + /merge-descriptors@1.0.1: resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} dev: false + /merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + dev: false + /methods@1.1.2: resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} engines: {node: '>= 0.6'} @@ -3865,6 +4496,11 @@ packages: hasBin: true dev: false + /mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + dev: false + /mimic-response@1.0.1: resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} engines: {node: '>=4'} @@ -3883,13 +4519,6 @@ packages: brace-expansion: 2.0.1 dev: false - /minimatch@5.1.6: - resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} - engines: {node: '>=10'} - dependencies: - brace-expansion: 2.0.1 - dev: false - /minimatch@9.0.3: resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} engines: {node: '>=16 || 14 >=14.17'} @@ -3901,8 +4530,8 @@ packages: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} dev: false - /minipass@7.0.3: - resolution: {integrity: sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg==} + /minipass@7.0.4: + resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==} engines: {node: '>=16 || 14 >=14.17'} dev: false @@ -3912,8 +4541,17 @@ packages: hasBin: true dev: false - /mocha@10.2.0: - resolution: {integrity: sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==} + /mlly@1.6.1: + resolution: {integrity: sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA==} + dependencies: + acorn: 8.11.3 + pathe: 1.1.2 + pkg-types: 1.0.3 + ufo: 1.4.0 + dev: false + + /mocha@10.3.0: + resolution: {integrity: sha512-uF2XJs+7xSLsrmIvn37i/wnc91nw7XjOQB8ccyx5aEgdnohr7n+rEiZP23WkCYHjilR6+EboEnbq/ZQDz4LSbg==} engines: {node: '>= 14.0.0'} hasBin: true dependencies: @@ -3924,13 +4562,12 @@ packages: diff: 5.0.0 escape-string-regexp: 4.0.0 find-up: 5.0.0 - glob: 7.2.0 + glob: 8.1.0 he: 1.2.0 js-yaml: 4.1.0 log-symbols: 4.1.0 minimatch: 5.0.1 ms: 2.1.3 - nanoid: 3.3.3 serialize-javascript: 6.0.0 strip-json-comments: 3.1.1 supports-color: 8.1.1 @@ -3964,8 +4601,8 @@ packages: resolution: {integrity: sha512-7vO7n28+aYO4J+8w96AzhmU8G+Y/xpPDJz/se19ICsqj/momRbb9mh9ZUtkoJ5X3nTnPdhEJyc0qnM6yAsHBaA==} dev: false - /nanoid@3.3.3: - resolution: {integrity: sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==} + /nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true dev: false @@ -4009,8 +4646,8 @@ packages: formdata-polyfill: 4.0.10 dev: false - /node-gyp-build@4.6.1: - resolution: {integrity: sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ==} + /node-gyp-build@4.8.0: + resolution: {integrity: sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og==} hasBin: true dev: false @@ -4024,20 +4661,27 @@ packages: engines: {node: '>=8'} dev: false + /npm-run-path@5.3.0: + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + path-key: 4.0.0 + dev: false + /object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} dev: false - /object-inspect@1.12.3: - resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} + /object-inspect@1.13.1: + resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} dev: false - /object-is@1.1.5: - resolution: {integrity: sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==} + /object-is@1.1.6: + resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 dev: false @@ -4046,11 +4690,11 @@ packages: engines: {node: '>= 0.4'} dev: false - /object.assign@4.1.4: - resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} + /object.assign@4.1.5: + resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 has-symbols: 1.0.3 object-keys: 1.1.1 @@ -4073,6 +4717,18 @@ packages: wrappy: 1.0.2 dev: false + /onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + dependencies: + mimic-fn: 4.0.0 + dev: false + + /os-tmpdir@1.0.2: + resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} + engines: {node: '>=0.10.0'} + dev: false + /p-cancelable@1.1.0: resolution: {integrity: sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==} engines: {node: '>=6'} @@ -4085,6 +4741,13 @@ packages: yocto-queue: 0.1.0 dev: false + /p-limit@5.0.0: + resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==} + engines: {node: '>=18'} + dependencies: + yocto-queue: 1.0.0 + dev: false + /p-locate@5.0.0: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} @@ -4140,18 +4803,31 @@ packages: engines: {node: '>=8'} dev: false + /path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + dev: false + /path-scurry@1.10.1: resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==} engines: {node: '>=16 || 14 >=14.17'} dependencies: - lru-cache: 10.0.1 - minipass: 7.0.3 + lru-cache: 10.2.0 + minipass: 7.0.4 dev: false /path-to-regexp@0.1.7: resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} dev: false + /pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + dev: false + + /pathval@1.1.1: + resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + dev: false + /pg-cloudflare@1.1.1: resolution: {integrity: sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==} requiresBuild: true @@ -4195,17 +4871,17 @@ packages: postgres-interval: 1.2.0 dev: false - /pg-types@4.0.1: - resolution: {integrity: sha512-hRCSDuLII9/LE3smys1hRHcu5QGcLs9ggT7I/TCs0IE+2Eesxi9+9RWAAwZ0yaGjxoWICF/YHLOEjydGujoJ+g==} + /pg-types@4.0.2: + resolution: {integrity: sha512-cRL3JpS3lKMGsKaWndugWQoLOCoP+Cic8oseVcbr0qhPzYD5DWXK+RZ9LY9wxRf7RQia4SCwQlXk0q6FCPrVng==} engines: {node: '>=10'} dependencies: pg-int8: 1.0.1 pg-numeric: 1.0.2 postgres-array: 3.0.2 postgres-bytea: 3.0.0 - postgres-date: 2.0.1 + postgres-date: 2.1.0 postgres-interval: 3.0.0 - postgres-range: 1.1.3 + postgres-range: 1.1.4 dev: false /pg@8.11.3: @@ -4234,11 +4910,37 @@ packages: split2: 4.2.0 dev: false + /picocolors@1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + dev: false + /picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} dev: false + /pkg-types@1.0.3: + resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==} + dependencies: + jsonc-parser: 3.2.1 + mlly: 1.6.1 + pathe: 1.1.2 + dev: false + + /possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + engines: {node: '>= 0.4'} + dev: false + + /postcss@8.4.35: + resolution: {integrity: sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.0 + source-map-js: 1.0.2 + dev: false + /postgres-array@2.0.0: resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} engines: {node: '>=4'} @@ -4266,8 +4968,8 @@ packages: engines: {node: '>=0.10.0'} dev: false - /postgres-date@2.0.1: - resolution: {integrity: sha512-YtMKdsDt5Ojv1wQRvUhnyDJNSr2dGIC96mQVKz7xufp07nfuFONzdaowrMHjlAzY6GDLd4f+LUHHAAM1h4MdUw==} + /postgres-date@2.1.0: + resolution: {integrity: sha512-K7Juri8gtgXVcDfZttFKVmhglp7epKb1K4pgrkLxehjqkrgPhfG6OO8LHLkfaqkbpjNRnra018XwAr1yQFWGcA==} engines: {node: '>=12'} dev: false @@ -4283,8 +4985,8 @@ packages: engines: {node: '>=12'} dev: false - /postgres-range@1.1.3: - resolution: {integrity: sha512-VdlZoocy5lCP0c/t66xAfclglEapXPCIVhqqJRncYpvbCgImF0w67aPKfbqUMr72tO2k5q0TdTZwCLjPTI6C9g==} + /postgres-range@1.1.4: + resolution: {integrity: sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w==} dev: false /prepend-http@2.0.0: @@ -4323,8 +5025,8 @@ packages: once: 1.4.0 dev: false - /punycode@2.3.0: - resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} + /punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} dev: false @@ -4336,7 +5038,7 @@ packages: resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} engines: {node: '>=0.6'} dependencies: - side-channel: 1.0.4 + side-channel: 1.0.6 dev: false /randombytes@2.1.0: @@ -4350,16 +5052,6 @@ packages: engines: {node: '>= 0.6'} dev: false - /raw-body@2.5.1: - resolution: {integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==} - engines: {node: '>= 0.8'} - dependencies: - bytes: 3.1.2 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - unpipe: 1.0.0 - dev: false - /raw-body@2.5.2: resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} engines: {node: '>= 0.8'} @@ -4403,21 +5095,18 @@ packages: redis-errors: 1.2.0 dev: false - /reflect-metadata@0.1.13: - resolution: {integrity: sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==} - dev: false - - /regenerator-runtime@0.14.0: - resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==} + /reflect-metadata@0.2.1: + resolution: {integrity: sha512-i5lLI6iw9AU3Uu4szRNPPEkomnkjRTaVt9hy/bn5g/oSzekBSMeLZblcjP74AW0vBabqERLLIrz+gR8QYR54Tw==} dev: false - /regexp.prototype.flags@1.5.1: - resolution: {integrity: sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==} + /regexp.prototype.flags@1.5.2: + resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - set-function-name: 2.0.1 + es-errors: 1.3.0 + set-function-name: 2.0.2 dev: false /registry-auth-token@4.2.2: @@ -4455,6 +5144,29 @@ packages: engines: {node: '>= 4'} dev: false + /rollup@4.12.0: + resolution: {integrity: sha512-wz66wn4t1OHIJw3+XU7mJJQV/2NAfw5OAk6G6Hoo3zcvz/XOfQ52Vgi+AN4Uxoxi0KBBwk2g8zPrTDA4btSB/Q==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + dependencies: + '@types/estree': 1.0.5 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.12.0 + '@rollup/rollup-android-arm64': 4.12.0 + '@rollup/rollup-darwin-arm64': 4.12.0 + '@rollup/rollup-darwin-x64': 4.12.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.12.0 + '@rollup/rollup-linux-arm64-gnu': 4.12.0 + '@rollup/rollup-linux-arm64-musl': 4.12.0 + '@rollup/rollup-linux-riscv64-gnu': 4.12.0 + '@rollup/rollup-linux-x64-gnu': 4.12.0 + '@rollup/rollup-linux-x64-musl': 4.12.0 + '@rollup/rollup-win32-arm64-msvc': 4.12.0 + '@rollup/rollup-win32-ia32-msvc': 4.12.0 + '@rollup/rollup-win32-x64-msvc': 4.12.0 + fsevents: 2.3.3 + dev: false + /safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} dev: false @@ -4463,13 +5175,18 @@ packages: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} dev: false + /semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + dev: false + /semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true dev: false - /semver@7.5.4: - resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + /semver@7.6.0: + resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==} engines: {node: '>=10'} hasBin: true dependencies: @@ -4511,23 +5228,26 @@ packages: send: 0.18.0 dev: false - /set-function-length@1.1.1: - resolution: {integrity: sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==} + /set-function-length@1.2.1: + resolution: {integrity: sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==} engines: {node: '>= 0.4'} dependencies: - define-data-property: 1.1.1 - get-intrinsic: 1.2.2 + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 gopd: 1.0.1 - has-property-descriptors: 1.0.0 + has-property-descriptors: 1.0.2 dev: false - /set-function-name@2.0.1: - resolution: {integrity: sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==} + /set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} engines: {node: '>= 0.4'} dependencies: - define-data-property: 1.1.0 + define-data-property: 1.1.4 + es-errors: 1.3.0 functions-have-names: 1.2.3 - has-property-descriptors: 1.0.0 + has-property-descriptors: 1.0.2 dev: false /setprototypeof@1.2.0: @@ -4554,12 +5274,18 @@ packages: engines: {node: '>=8'} dev: false - /side-channel@1.0.4: - resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} + /side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 - object-inspect: 1.12.3 + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + object-inspect: 1.13.1 + dev: false + + /siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} dev: false /signal-exit@4.1.0: @@ -4572,6 +5298,27 @@ packages: engines: {node: '>=8'} dev: false + /solc@0.8.24: + resolution: {integrity: sha512-G5yUqjTUPc8Np74sCFwfsevhBPlUifUOfhYrgyu6CmYlC6feSw0YS6eZW47XDT23k3JYdKx5nJ+Q7whCEmNcoA==} + engines: {node: '>=10.0.0'} + hasBin: true + dependencies: + command-exists: 1.2.9 + commander: 8.3.0 + follow-redirects: 1.15.5 + js-sha3: 0.8.0 + memorystream: 0.3.1 + semver: 5.7.2 + tmp: 0.0.33 + transitivePeerDependencies: + - debug + dev: false + + /source-map-js@1.0.2: + resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} + engines: {node: '>=0.10.0'} + dev: false + /split2@4.2.0: resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} engines: {node: '>= 10.x'} @@ -4584,6 +5331,10 @@ packages: escape-string-regexp: 2.0.0 dev: false + /stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + dev: false + /standard-as-callback@2.1.0: resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} dev: false @@ -4593,11 +5344,15 @@ packages: engines: {node: '>= 0.8'} dev: false + /std-env@3.7.0: + resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} + dev: false + /stop-iteration-iterator@1.0.0: resolution: {integrity: sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==} engines: {node: '>= 0.4'} dependencies: - internal-slot: 1.0.5 + internal-slot: 1.0.7 dev: false /stoppable@1.1.0: @@ -4637,6 +5392,11 @@ packages: ansi-regex: 6.0.1 dev: false + /strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + dev: false + /strip-json-comments@2.0.1: resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} engines: {node: '>=0.10.0'} @@ -4647,6 +5407,12 @@ packages: engines: {node: '>=8'} dev: false + /strip-literal@2.0.0: + resolution: {integrity: sha512-f9vHgsCWBq2ugHAkGMiiYY+AYG0D/cbloKKg0nhaaaSNsujdGIpVXCNsrJpCKr5M0f4aI31mr13UjY6GAuXCKA==} + dependencies: + js-tokens: 8.0.3 + dev: false + /strnum@1.0.5: resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==} dev: false @@ -4691,6 +5457,27 @@ packages: any-promise: 1.3.0 dev: false + /tinybench@2.6.0: + resolution: {integrity: sha512-N8hW3PG/3aOoZAN5V/NSAEDz0ZixDSSt5b/a05iqtpgfLWMSVuCo7w0k2vVvEjdrIoeGqZzweX2WlyioNIHchA==} + dev: false + + /tinypool@0.8.2: + resolution: {integrity: sha512-SUszKYe5wgsxnNOVlBYO6IC+8VGWdVGZWAqUxp3UErNBtptZvWbwyUOyzNL59zigz2rCA92QiL3wvG+JDSdJdQ==} + engines: {node: '>=14.0.0'} + dev: false + + /tinyspy@2.2.1: + resolution: {integrity: sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==} + engines: {node: '>=14.0.0'} + dev: false + + /tmp@0.0.33: + resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} + engines: {node: '>=0.6.0'} + dependencies: + os-tmpdir: 1.0.2 + dev: false + /to-readable-stream@1.0.0: resolution: {integrity: sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==} engines: {node: '>=6'} @@ -4712,7 +5499,7 @@ packages: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} dev: false - /ts-node@10.9.2(@types/node@18.18.14)(typescript@5.3.3): + /ts-node@10.9.2(@types/node@18.19.21)(typescript@5.3.3): resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} hasBin: true peerDependencies: @@ -4731,9 +5518,9 @@ packages: '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 18.18.14 - acorn: 8.11.2 - acorn-walk: 8.3.1 + '@types/node': 18.19.21 + acorn: 8.11.3 + acorn-walk: 8.3.2 arg: 4.1.3 create-require: 1.1.1 diff: 4.0.2 @@ -4755,12 +5542,17 @@ packages: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} dev: false + /type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + dev: false + /type-fest@2.19.0: resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} engines: {node: '>=12.20'} dev: false - /type-graphql@1.2.0-rc.1(class-validator@0.14.0)(graphql@15.8.0): + /type-graphql@1.2.0-rc.1(class-validator@0.14.1)(graphql@15.8.0): resolution: {integrity: sha512-W1p51DN+n/zX4ilunMC6/FcyGlx/ND3hreQ0ARDhfhyR9oGtfKzQNnkHhk8uXlYm2zzyTEd1LkRHJr8bbnRlIA==} engines: {node: '>= 10.13'} requiresBuild: true @@ -4769,14 +5561,14 @@ packages: graphql: ^15.5.0 dependencies: '@types/glob': 7.2.0 - '@types/node': 18.18.14 - '@types/semver': 7.5.6 - class-validator: 0.14.0 - glob: 7.2.0 + '@types/node': 18.19.21 + '@types/semver': 7.5.8 + class-validator: 0.14.1 + glob: 7.2.3 graphql: 15.8.0 graphql-query-complexity: 0.7.2(graphql@15.8.0) graphql-subscriptions: 1.2.1(graphql@15.8.0) - semver: 7.5.4 + semver: 7.6.0 tslib: 2.6.2 dev: false @@ -4788,10 +5580,6 @@ packages: mime-types: 2.1.35 dev: false - /type@1.2.0: - resolution: {integrity: sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==} - dev: false - /type@2.7.2: resolution: {integrity: sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==} dev: false @@ -4802,20 +5590,20 @@ packages: is-typedarray: 1.0.0 dev: false - /typeorm@0.3.17(pg@8.11.3)(supports-color@8.1.1)(ts-node@10.9.2): - resolution: {integrity: sha512-UDjUEwIQalO9tWw9O2A4GU+sT3oyoUXheHJy4ft+RFdnRdQctdQ34L9SqE2p7LdwzafHx1maxT+bqXON+Qnmig==} - engines: {node: '>= 12.9.0'} + /typeorm@0.3.20(pg@8.11.3)(supports-color@8.1.1)(ts-node@10.9.2): + resolution: {integrity: sha512-sJ0T08dV5eoZroaq9uPKBoNcGslHBR4E4y+EBHs//SiGbblGe7IeduP/IH4ddCcj0qp3PHwDwGnuvqEAnKlq/Q==} + engines: {node: '>=16.13.0'} hasBin: true peerDependencies: '@google-cloud/spanner': ^5.18.0 '@sap/hana-client': ^2.12.25 - better-sqlite3: ^7.1.2 || ^8.0.0 + better-sqlite3: ^7.1.2 || ^8.0.0 || ^9.0.0 hdb-pool: ^0.1.6 ioredis: ^5.0.4 - mongodb: ^5.2.0 - mssql: ^9.1.1 + mongodb: ^5.8.0 + mssql: ^9.1.1 || ^10.0.1 mysql2: ^2.2.5 || ^3.0.1 - oracledb: ^5.1.0 + oracledb: ^6.3.0 pg: ^8.5.1 pg-native: ^3.0.0 pg-query-stream: ^4.0.0 @@ -4865,15 +5653,15 @@ packages: buffer: 6.0.3 chalk: 4.1.2 cli-highlight: 2.1.11 - date-fns: 2.30.0 + dayjs: 1.11.10 debug: 4.3.4(supports-color@8.1.1) - dotenv: 16.3.1 - glob: 8.1.0 + dotenv: 16.4.5 + glob: 10.3.10 mkdirp: 2.1.6 pg: 8.11.3 - reflect-metadata: 0.1.13 + reflect-metadata: 0.2.1 sha.js: 2.4.11 - ts-node: 10.9.2(@types/node@18.18.14)(typescript@5.3.3) + ts-node: 10.9.2(@types/node@18.19.21)(typescript@5.3.3) tslib: 2.6.2 uuid: 9.0.1 yargs: 17.7.2 @@ -4881,12 +5669,20 @@ packages: - supports-color dev: false + /types-solc@1.0.1: + resolution: {integrity: sha512-nNuhDWJ40qewIchJw+ddyIwi9HbpLo0F5K45aLO5r264Sod1jU8Vs7yKUO/+O6Mmr6rg4veD/FXBRvSO2m0Xlg==} + dev: false + /typescript@5.3.3: resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} engines: {node: '>=14.17'} hasBin: true dev: false + /ufo@1.4.0: + resolution: {integrity: sha512-Hhy+BhRBleFjpJ2vchUNN40qgkh0366FWJGqVLYBHev0vpHTrXSA0ryT+74UiW6KWsldNurQMKGqCm1M2zBciQ==} + dev: false + /undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} dev: false @@ -4904,7 +5700,7 @@ packages: /uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: - punycode: 2.3.0 + punycode: 2.3.1 dev: false /url-parse-lax@3.0.0: @@ -4919,7 +5715,7 @@ packages: engines: {node: '>=6.14.2'} requiresBuild: true dependencies: - node-gyp-build: 4.6.1 + node-gyp-build: 4.8.0 dev: false /utils-merge@1.0.1: @@ -4961,8 +5757,144 @@ packages: engines: {node: '>= 0.8'} dev: false - /web-streams-polyfill@3.2.1: - resolution: {integrity: sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==} + /viem@2.7.19(typescript@5.3.3): + resolution: {integrity: sha512-UOMeqy+8p2709ra2j9HEOL1NfjsXZzlJ8gwR6YO/zXH8KIZvyzW07t4iQARF5+ShVZ/7+/1ec8oPjVi1M//33A==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@adraffy/ens-normalize': 1.10.0 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@scure/bip32': 1.3.2 + '@scure/bip39': 1.2.1 + abitype: 1.0.0(typescript@5.3.3) + isows: 1.0.3(ws@8.13.0) + typescript: 5.3.3 + ws: 8.13.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + dev: false + + /vite-node@1.3.1(@types/node@18.19.21)(supports-color@8.1.1): + resolution: {integrity: sha512-azbRrqRxlWTJEVbzInZCTchx0X69M/XPTCz4H+TLvlTcR/xH/3hkRqhOakT41fMJCMzXTu4UvegkZiEoJAWvng==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + dependencies: + cac: 6.7.14 + debug: 4.3.4(supports-color@8.1.1) + pathe: 1.1.2 + picocolors: 1.0.0 + vite: 5.1.4(@types/node@18.19.21) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + dev: false + + /vite@5.1.4(@types/node@18.19.21): + resolution: {integrity: sha512-n+MPqzq+d9nMVTKyewqw6kSt+R3CkvF9QAKY8obiQn8g1fwTscKxyfaYnC632HtBXAQGc1Yjomphwn1dtwGAHg==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + '@types/node': 18.19.21 + esbuild: 0.19.12 + postcss: 8.4.35 + rollup: 4.12.0 + optionalDependencies: + fsevents: 2.3.3 + dev: false + + /vitest@1.3.1(@types/node@18.19.21)(supports-color@8.1.1): + resolution: {integrity: sha512-/1QJqXs8YbCrfv/GPQ05wAZf2eakUPLPa18vkJAKE7RXOKfVHqMZZ1WlTjiwl6Gcn65M5vpNUB6EFLnEdRdEXQ==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 1.3.1 + '@vitest/ui': 1.3.1 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + dependencies: + '@types/node': 18.19.21 + '@vitest/expect': 1.3.1 + '@vitest/runner': 1.3.1 + '@vitest/snapshot': 1.3.1 + '@vitest/spy': 1.3.1 + '@vitest/utils': 1.3.1 + acorn-walk: 8.3.2 + chai: 4.4.1 + debug: 4.3.4(supports-color@8.1.1) + execa: 8.0.1 + local-pkg: 0.5.0 + magic-string: 0.30.8 + pathe: 1.1.2 + picocolors: 1.0.0 + std-env: 3.7.0 + strip-literal: 2.0.0 + tinybench: 2.6.0 + tinypool: 0.8.2 + vite: 5.1.4(@types/node@18.19.21) + vite-node: 1.3.1(@types/node@18.19.21)(supports-color@8.1.1) + why-is-node-running: 2.2.2 + transitivePeerDependencies: + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + dev: false + + /web-streams-polyfill@3.3.3: + resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} engines: {node: '>= 8'} dev: false @@ -4974,9 +5906,9 @@ packages: resolution: {integrity: sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==} engines: {node: '>=4.0.0'} dependencies: - bufferutil: 4.0.7 + bufferutil: 4.0.8 debug: 2.6.9 - es5-ext: 0.10.62 + es5-ext: 0.10.64 typedarray-to-buffer: 3.1.5 utf-8-validate: 5.0.10 yaeti: 0.0.6 @@ -5013,15 +5945,15 @@ packages: is-weakset: 2.0.2 dev: false - /which-typed-array@1.1.13: - resolution: {integrity: sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==} + /which-typed-array@1.1.14: + resolution: {integrity: sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==} engines: {node: '>= 0.4'} dependencies: - available-typed-arrays: 1.0.5 - call-bind: 1.0.5 + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 for-each: 0.3.3 gopd: 1.0.1 - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 dev: false /which@2.0.2: @@ -5032,6 +5964,15 @@ packages: isexe: 2.0.0 dev: false + /why-is-node-running@2.2.2: + resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==} + engines: {node: '>=8'} + hasBin: true + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + dev: false + /workerpool@6.2.1: resolution: {integrity: sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==} dev: false @@ -5058,8 +5999,21 @@ packages: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} dev: false - /ws@8.14.2: - resolution: {integrity: sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==} + /ws@8.13.0: + resolution: {integrity: sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: false + + /ws@8.16.0: + resolution: {integrity: sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -5084,8 +6038,8 @@ packages: optional: true dev: false - /xss@1.0.14: - resolution: {integrity: sha512-og7TEJhXvn1a7kzZGQ7ETjdQVS2UfZyTlsEdDOqvQF7GoxNfY+0YLCzBy1kPdsDDx4QuNAonQPddpsn6Xl/7sw==} + /xss@1.0.15: + resolution: {integrity: sha512-FVdlVVC67WOIPvfOwhoMETV72f6GbW7aOabBC3WxN/oUdoEMDyLz4OgRv5/gck2ZeNqEQu+Tb0kloovXOfpYVg==} engines: {node: '>= 0.10.0'} hasBin: true dependencies: @@ -5147,7 +6101,7 @@ packages: engines: {node: '>=10'} dependencies: cliui: 7.0.4 - escalade: 3.1.1 + escalade: 3.1.2 get-caller-file: 2.0.5 require-directory: 2.1.1 string-width: 4.2.3 @@ -5160,7 +6114,7 @@ packages: engines: {node: '>=12'} dependencies: cliui: 8.0.1 - escalade: 3.1.1 + escalade: 3.1.2 get-caller-file: 2.0.5 require-directory: 2.1.1 string-width: 4.2.3 @@ -5178,17 +6132,23 @@ packages: engines: {node: '>=10'} dev: false + /yocto-queue@1.0.0: + resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} + engines: {node: '>=12.20'} + dev: false + file:projects/astar-erc20.tgz(supports-color@8.1.1)(ts-node@10.9.2): - resolution: {integrity: sha512-Jcvtam3C+7hM6+Gs5Lf+pwxOabPpHbeHHt0eMy7SKDsvr8cyo8XZF2zp0MedJj2IeIgL7E4wLPF82DjSTsjv1g==, tarball: file:projects/astar-erc20.tgz} + resolution: {integrity: sha512-eJqDwTsAnOwe0oNmLntSdrhPDoQx0lbVPGC7xuRTPcMc+ydWhDmX4QSg84qo463mgHwtQ16WyJ+W1AoC/Pq0EQ==, tarball: file:projects/astar-erc20.tgz} id: file:projects/astar-erc20.tgz name: '@rush-temp/astar-erc20' version: 0.0.0 dependencies: - '@types/node': 18.18.14 - dotenv: 16.3.1 - ethers: 6.9.0 + '@subsquid/evm-typegen': 3.3.0(ethers@6.11.1) + '@types/node': 18.19.21 + dotenv: 16.4.5 + ethers: 6.11.1 pg: 8.11.3 - typeorm: 0.3.17(pg@8.11.3)(supports-color@8.1.1)(ts-node@10.9.2) + typeorm: 0.3.20(pg@8.11.3)(supports-color@8.1.1)(ts-node@10.9.2) typescript: 5.3.3 transitivePeerDependencies: - '@google-cloud/spanner' @@ -5213,16 +6173,16 @@ packages: dev: false file:projects/balances.tgz(supports-color@8.1.1): - resolution: {integrity: sha512-sx5qc1sFoFX5HMVi82AI3CwHGcfPEHv7SdjpnoOV52cMyAy701WaMsFyfcTUXr+Z0ZR+kv3WtgK5Zd4db2v/CA==, tarball: file:projects/balances.tgz} + resolution: {integrity: sha512-7w+YPGI23efgDsuH99BPeD2FQUnssjfLgkUzf/5hlLQgkTjTspMAfnornxDkQ+HeILMdtk3+s/dWe1p4jDIA8Q==, tarball: file:projects/balances.tgz} id: file:projects/balances.tgz name: '@rush-temp/balances' version: 0.0.0 dependencies: - '@types/node': 18.18.14 - dotenv: 16.3.1 + '@types/node': 18.19.21 + dotenv: 16.4.5 pg: 8.11.3 - ts-node: 10.9.2(@types/node@18.18.14)(typescript@5.3.3) - typeorm: 0.3.17(pg@8.11.3)(supports-color@8.1.1)(ts-node@10.9.2) + ts-node: 10.9.2(@types/node@18.19.21)(typescript@5.3.3) + typeorm: 0.3.20(pg@8.11.3)(supports-color@8.1.1)(ts-node@10.9.2) typescript: 5.3.3 transitivePeerDependencies: - '@google-cloud/spanner' @@ -5246,7 +6206,7 @@ packages: dev: false file:projects/big-decimal.tgz: - resolution: {integrity: sha512-/Er4O4+BTjIgMcLL/oy3KUDz5o/97kqUHu1HGrIvixflTucO3M2Dm/GnwE1d81EtsEaCR57yWvZ7u07HLEU3og==, tarball: file:projects/big-decimal.tgz} + resolution: {integrity: sha512-S6B1X7Hu9b+KPnj+yYHceoBBPOayTUGtA/V+8BsezCola/PGe2BsA30qhTX+vIA3NKUMqF3fue8ZJdSoPDtFsg==, tarball: file:projects/big-decimal.tgz} name: '@rush-temp/big-decimal' version: 0.0.0 dependencies: @@ -5254,23 +6214,22 @@ packages: dev: false file:projects/chain-status-service.tgz: - resolution: {integrity: sha512-u9nP0ZDDbmIcHUlL/48v3r8c6PD7T9RPWm62r2bo6l4QoTGxkwoV0dEnpZYMkhfMCg1mzWHXadGOixd2Wy3rQA==, tarball: file:projects/chain-status-service.tgz} + resolution: {integrity: sha512-+YJZrEu4Km+SxhIdKGDBxM+PMoeZoSExJKWu/HDjmbqQvzgo5+pvQ3ZFE0VEHxgGR5fo+qQAy9zNpcNPIrYsFg==, tarball: file:projects/chain-status-service.tgz} name: '@rush-temp/chain-status-service' version: 0.0.0 dependencies: '@types/express': 4.17.21 - '@types/node': 18.18.14 - express: 4.18.2 + '@types/node': 18.19.21 + express: 4.18.3 typescript: 5.3.3 dev: false file:projects/commands.tgz: - resolution: {integrity: sha512-Vjv4SxiS4oe6Oee/jc+ATb9jHThZApVjXXiYrtsgo+FZYBDCc9oG1QQbZRnbSpk8f4z+DtxwparDTNNKXg5WzQ==, tarball: file:projects/commands.tgz} + resolution: {integrity: sha512-QCqPIFqTpHcZ1AlklwdhheGL3uVXYnb1sq4C3gfS5E90+5NXaHvQZAt+T0KU9QBGO1pI/cxQ/Cer1ECTHH5+9w==, tarball: file:projects/commands.tgz} name: '@rush-temp/commands' version: 0.0.0 dependencies: - '@types/glob': 8.1.0 - '@types/node': 18.18.14 + '@types/node': 18.19.21 '@types/supports-color': 8.1.3 glob: 10.3.10 supports-color: 8.1.1 @@ -5278,12 +6237,12 @@ packages: dev: false file:projects/data-test.tgz: - resolution: {integrity: sha512-4iprYmrs8MG5M/cpfdUN60+PX8PaW7ieCPsVyQwgdGCWe9rmU1T1PjC80aEX3dDqpV++yhlo6adLZKmAzzOSYw==, tarball: file:projects/data-test.tgz} + resolution: {integrity: sha512-a0O0wNwCLwc0dltavJ9NTJY822EIVn6QPWpu/5fnDnHRwX+ZuQWiLYesAESFlHOR3HtQFVP2eV8YaY4eRQmPdA==, tarball: file:projects/data-test.tgz} name: '@rush-temp/data-test' version: 0.0.0 dependencies: - '@types/node': 18.18.14 - '@types/pg': 8.10.9 + '@types/node': 18.19.21 + '@types/pg': 8.11.2 expect: 29.7.0 pg: 8.11.3 typescript: 5.3.3 @@ -5292,16 +6251,16 @@ packages: dev: false file:projects/erc20-transfers.tgz(supports-color@8.1.1)(ts-node@10.9.2): - resolution: {integrity: sha512-EyEP+FNyDpAjfB20barecYMAZSWHWDJx0T3fm8Lr0sHhu5H2Hw7zW2oGXxOh3SXZHHWh476w+J3Yn2//IZwg0Q==, tarball: file:projects/erc20-transfers.tgz} + resolution: {integrity: sha512-e0rzTRNEOI6+teW309Kefd31OF3PSi7rVhyEXgwIBWtgMaCm8rBJFNRbnXIcZ111kuNJRHh7NT1LRG2gDNQkSg==, tarball: file:projects/erc20-transfers.tgz} id: file:projects/erc20-transfers.tgz name: '@rush-temp/erc20-transfers' version: 0.0.0 dependencies: - '@types/node': 18.18.14 - dotenv: 16.3.1 - ethers: 6.9.0 + '@types/node': 18.19.21 + dotenv: 16.4.5 + ethers: 6.11.1 pg: 8.11.3 - typeorm: 0.3.17(pg@8.11.3)(supports-color@8.1.1)(ts-node@10.9.2) + typeorm: 0.3.20(pg@8.11.3)(supports-color@8.1.1)(ts-node@10.9.2) typescript: 5.3.3 transitivePeerDependencies: - '@google-cloud/spanner' @@ -5326,37 +6285,82 @@ packages: dev: false file:projects/evm-processor.tgz: - resolution: {integrity: sha512-ygmTedEUttOIydZtMucvQDpnQbMvDMaarCHl98DpHHcYwyRGYr21iqY8A62lerspLrePbXECH44C867CN/0xgg==, tarball: file:projects/evm-processor.tgz} + resolution: {integrity: sha512-A5d7UxYCSqmC1sTA3A+rI/CzHKWzjfSXPHRDIDSi4nYy/TJ0FA6aughG4DxuBosetTKRBHoqIw+xTWMvMzRPjQ==, tarball: file:projects/evm-processor.tgz} name: '@rush-temp/evm-processor' version: 0.0.0 dependencies: - '@exodus/schemasafe': 1.3.0 - '@types/node': 18.18.14 - ajv: 8.12.0 + '@types/node': 18.19.21 typescript: 5.3.3 dev: false - file:projects/evm-typegen.tgz: - resolution: {integrity: sha512-6RhckTpgBmpTyk3oDmc8yfLyPW5RqTlb+g6FUSHr8Sd1CKN2dUi0fHdOYrH52NwvcYoVdZdK9Zs5/PCcSW3NOw==, tarball: file:projects/evm-typegen.tgz} + file:projects/evm-typegen.tgz(supports-color@8.1.1): + resolution: {integrity: sha512-F0b892OrDsBvsi2fig+j1dFQRnE2E29Lj8jJ/ONGyU8WZzHgr+CjP48gMAsy8WEi31PXygdCpab0uiV+ka0lBg==, tarball: file:projects/evm-typegen.tgz} + id: file:projects/evm-typegen.tgz name: '@rush-temp/evm-typegen' version: 0.0.0 dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 + abitype: 1.0.1(typescript@5.3.3) commander: 11.1.0 - ethers: 6.9.0 + solc: 0.8.24 + types-solc: 1.0.1 + typescript: 5.3.3 + viem: 2.7.19(typescript@5.3.3) + vitest: 1.3.1(@types/node@18.19.21)(supports-color@8.1.1) + transitivePeerDependencies: + - '@edge-runtime/vm' + - '@vitest/browser' + - '@vitest/ui' + - bufferutil + - debug + - happy-dom + - jsdom + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + - utf-8-validate + - zod + dev: false + + file:projects/evm-utils.tgz(supports-color@8.1.1): + resolution: {integrity: sha512-KEFeflx08SlWSWGcpepvwoy0Q3MeTFWeVVZ0gz6KFN7KWBSCvEXZmPuuGnD+XAilem0W2NFBun/aGlKxO1DVCg==, tarball: file:projects/evm-utils.tgz} + id: file:projects/evm-utils.tgz + name: '@rush-temp/evm-utils' + version: 0.0.0 + dependencies: + '@types/node': 18.19.21 typescript: 5.3.3 + viem: 2.7.19(typescript@5.3.3) + vitest: 1.3.1(@types/node@18.19.21)(supports-color@8.1.1) transitivePeerDependencies: + - '@edge-runtime/vm' + - '@vitest/browser' + - '@vitest/ui' - bufferutil + - happy-dom + - jsdom + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser - utf-8-validate + - zod dev: false file:projects/frontier.tgz: - resolution: {integrity: sha512-ycHZOjvPEgNEEZIX13/8V8cZDmpSLBmJWKwHp2HXakO2nzF1lBn4sCAqs+qLvCVdwjc7zCnN/VU4S1oJhV1gYQ==, tarball: file:projects/frontier.tgz} + resolution: {integrity: sha512-x2FHfKBt3Zef2nbv3CQa7bLepgS8F4a4JY9qddxrObn5I2jpqIOt1igmxL9lTeFfNbsMCxlcDK7Xo8+5bFeAlQ==, tarball: file:projects/frontier.tgz} name: '@rush-temp/frontier' version: 0.0.0 dependencies: - '@types/node': 18.18.14 - ethers: 6.9.0 + '@types/node': 18.19.21 + ethers: 6.11.1 typescript: 5.3.3 transitivePeerDependencies: - bufferutil @@ -5364,17 +6368,17 @@ packages: dev: false file:projects/gql-test-client.tgz(graphql@15.8.0): - resolution: {integrity: sha512-77y7s6kNlv5103IDhhu4NHJtJBH8g37YcieynMGA5qv6tcqtuMks2gDL4zfQ4b5jjxWUYFZfFrqmLKy+2NtqDg==, tarball: file:projects/gql-test-client.tgz} + resolution: {integrity: sha512-T619E9WRr9GW/ocSN36ZMRr2x4RDcfrWg+neoaU0yi9beG8POy1GiQ8lpSnnrdsAoguydA/8ZhrEAzRctfUrmw==, tarball: file:projects/gql-test-client.tgz} id: file:projects/gql-test-client.tgz name: '@rush-temp/gql-test-client' version: 0.0.0 dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 '@types/ws': 8.5.10 expect: 29.7.0 - graphql-ws: 5.14.2(graphql@15.8.0) + graphql-ws: 5.15.0(graphql@15.8.0) typescript: 5.3.3 - ws: 8.14.2 + ws: 8.16.0 transitivePeerDependencies: - bufferutil - graphql @@ -5382,39 +6386,39 @@ packages: dev: false file:projects/graphql-server.tgz(supports-color@8.1.1)(ts-node@10.9.2): - resolution: {integrity: sha512-hE3H/OL+ezLJ7gCr1hiI/LeVx8ji9YJPXw2rAbKYnoAmIOwIKgcmHZELVTnkISChy5BXW0yJNft4m7YdE5DIvA==, tarball: file:projects/graphql-server.tgz} + resolution: {integrity: sha512-106TA7r4SRi0ziXUtopHZZmnzU251N8Ye+WTckUQD9tN6+h+4bA4G+10Y0i0+lI0vN1Xd/wZXV8RdREZUEpz/w==, tarball: file:projects/graphql-server.tgz} id: file:projects/graphql-server.tgz name: '@rush-temp/graphql-server' version: 0.0.0 dependencies: '@apollo/utils.keyvadapter': 1.1.2 '@apollo/utils.keyvaluecache': 1.0.2 - '@graphql-tools/merge': 9.0.1(graphql@15.8.0) - '@graphql-tools/schema': 10.0.2(graphql@15.8.0) - '@graphql-tools/utils': 10.0.11(graphql@15.8.0) + '@graphql-tools/merge': 9.0.3(graphql@15.8.0) + '@graphql-tools/schema': 10.0.3(graphql@15.8.0) + '@graphql-tools/utils': 10.1.0(graphql@15.8.0) '@keyv/redis': 2.5.8(supports-color@8.1.1) '@types/express': 4.17.21 '@types/mocha': 10.0.6 - '@types/node': 18.18.14 - '@types/pg': 8.10.9 + '@types/node': 18.19.21 + '@types/pg': 8.11.2 '@types/ws': 8.5.10 apollo-server-core: 3.13.0(graphql@15.8.0) - apollo-server-express: 3.13.0(express@4.18.2)(graphql@15.8.0) + apollo-server-express: 3.13.0(express@4.18.3)(graphql@15.8.0) apollo-server-plugin-response-cache: 3.7.1(graphql@15.8.0) - class-validator: 0.14.0 + class-validator: 0.14.1 commander: 11.1.0 - dotenv: 16.3.1 + dotenv: 16.4.5 expect: 29.7.0 - express: 4.18.2 + express: 4.18.3 graphql: 15.8.0 - graphql-ws: 5.14.2(graphql@15.8.0) + graphql-ws: 5.15.0(graphql@15.8.0) keyv: 4.5.4 - mocha: 10.2.0 + mocha: 10.3.0 pg: 8.11.3 - type-graphql: 1.2.0-rc.1(class-validator@0.14.0)(graphql@15.8.0) - typeorm: 0.3.17(pg@8.11.3)(supports-color@8.1.1)(ts-node@10.9.2) + type-graphql: 1.2.0-rc.1(class-validator@0.14.1)(graphql@15.8.0) + typeorm: 0.3.20(pg@8.11.3)(supports-color@8.1.1)(ts-node@10.9.2) typescript: 5.3.3 - ws: 8.14.2 + ws: 8.16.0 transitivePeerDependencies: - '@google-cloud/spanner' - '@sap/hana-client' @@ -5439,80 +6443,80 @@ packages: dev: false file:projects/http-client.tgz: - resolution: {integrity: sha512-n68Piu0C/GRwj1bEw3eFOVZ+DkNUhwMDElr6AN+Xmk1pLmB1QbbZan+8buKZvjQ+5VQYZB4VnO6zbyKo4RE8FA==, tarball: file:projects/http-client.tgz} + resolution: {integrity: sha512-WzaONtQ8Ux1HssiDOelXhJI9DXNG4TMspeIZOeLUol/5bZob/XQ2euq7Ul2J8At7igCe4Zdgz16Q+19j16g1aQ==, tarball: file:projects/http-client.tgz} name: '@rush-temp/http-client' version: 0.0.0 dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 node-fetch: 3.3.2 typescript: 5.3.3 dev: false file:projects/ink-abi.tgz: - resolution: {integrity: sha512-ILZve2Qn0FBrxqY3Xr1J6n2CEHDfb0DgoffcltcJzKvFUa648KnuJpkzHhPdGTu7z4aR3tlVz+WIC7YuA9QLjg==, tarball: file:projects/ink-abi.tgz} + resolution: {integrity: sha512-1SwZzcQ8FTg6e391ap4Cmm08waSsA5L7KOCR9XgGN6Q4X+EHaOjhZ11QvdAAr4Mbfc+2S2vXljamjo8ICT4PtA==, tarball: file:projects/ink-abi.tgz} name: '@rush-temp/ink-abi' version: 0.0.0 dependencies: '@types/mocha': 10.0.6 - '@types/node': 18.18.14 + '@types/node': 18.19.21 ajv: 8.12.0 expect: 29.7.0 - mocha: 10.2.0 + mocha: 10.3.0 typescript: 5.3.3 dev: false file:projects/ink-typegen.tgz: - resolution: {integrity: sha512-C02ToD9x7wNBiaPRjkl1d8ExyJ5Md7r9U7x/PtVm1xM/JO5kr6Ut3jjJAIqn2kkZMuRNz3ysGVOVMouXsybiZA==, tarball: file:projects/ink-typegen.tgz} + resolution: {integrity: sha512-jLLka8M+GhRdK7ZwoXQUxPA9Tw3nqPz5LCtnUNNLa9JPNaK1QfA5S2F4o102nFMLFoT7/MXRLeYRlJexDHW4Gg==, tarball: file:projects/ink-typegen.tgz} name: '@rush-temp/ink-typegen' version: 0.0.0 dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 commander: 11.1.0 typescript: 5.3.3 dev: false file:projects/logger.tgz: - resolution: {integrity: sha512-C70VIV8dswSiFcdiXqTUuYPFViF8SaLZWhWzlZNuw/Jv5Cz1ItfO/5L6JUkJq44rx0OR1se9TBbW1or0LHGgew==, tarball: file:projects/logger.tgz} + resolution: {integrity: sha512-uVVLIEVkr/bmTeG1WK31C3IYHYzoOxvYo5/OYLDCI4mj1JjsUDyGbbdmhV8Mv4l2G8kMK75EiYOV/mCy1hD9Qw==, tarball: file:projects/logger.tgz} name: '@rush-temp/logger' version: 0.0.0 dependencies: '@types/mocha': 10.0.6 - '@types/node': 18.18.14 + '@types/node': 18.19.21 '@types/supports-color': 8.1.3 expect: 29.7.0 - mocha: 10.2.0 + mocha: 10.3.0 supports-color: 8.1.1 typescript: 5.3.3 dev: false file:projects/openreader.tgz(supports-color@8.1.1): - resolution: {integrity: sha512-bNF+hKiLlUCoqeUzz4b7J3jyIjJYv8y+uji4auj++zMmHbr4jFR7WLU+NFppGGtSrBdE60sl3lz0TNmCd8OMow==, tarball: file:projects/openreader.tgz} + resolution: {integrity: sha512-kVR6KaWHEFjpbKW3WjR7UZSfoOBMF8xfo+o+9vzsRwQHp34lHO3WS7kRmFTSj+7HDnHuolV5b1MKlf/iygJTCg==, tarball: file:projects/openreader.tgz} id: file:projects/openreader.tgz name: '@rush-temp/openreader' version: 0.0.0 dependencies: - '@graphql-tools/merge': 9.0.1(graphql@15.8.0) + '@graphql-tools/merge': 9.0.3(graphql@15.8.0) '@subsquid/graphiql-console': 0.3.0 '@types/deep-equal': 1.0.4 '@types/express': 4.17.21 '@types/mocha': 10.0.6 - '@types/node': 18.18.14 - '@types/pg': 8.10.9 + '@types/node': 18.19.21 + '@types/pg': 8.11.2 '@types/ws': 8.5.10 apollo-server-core: 3.13.0(graphql@15.8.0) - apollo-server-express: 3.13.0(express@4.18.2)(graphql@15.8.0) + apollo-server-express: 3.13.0(express@4.18.3)(graphql@15.8.0) commander: 11.1.0 deep-equal: 2.2.3 - dotenv: 16.3.1 + dotenv: 16.4.5 expect: 29.7.0 - express: 4.18.2 + express: 4.18.3 graphql: 15.8.0 graphql-parse-resolve-info: 4.14.0(graphql@15.8.0)(supports-color@8.1.1) - graphql-ws: 5.14.2(graphql@15.8.0) - mocha: 10.2.0 + graphql-ws: 5.15.0(graphql@15.8.0) + mocha: 10.3.0 pg: 8.11.3 typescript: 5.3.3 - ws: 8.14.2 + ws: 8.16.0 transitivePeerDependencies: - bufferutil - encoding @@ -5522,53 +6526,53 @@ packages: dev: false file:projects/ops-xcm-typegen.tgz: - resolution: {integrity: sha512-3pIzk+D+eI4jtpSL3pkq6PxxHX3fisyCIP2ui3tWrFy3FZEwazYW4Awjf3wmq65TT/fWGjt6gJxsFj7RHjRxEw==, tarball: file:projects/ops-xcm-typegen.tgz} + resolution: {integrity: sha512-r7AGMLlcVJi5fj8teUdhSyLuq9ZwlROCj9lBNKRc8I2b00NtTi4uXUuMY/Z6gYmDMpWumC39S4NWZMZTHSp0OA==, tarball: file:projects/ops-xcm-typegen.tgz} name: '@rush-temp/ops-xcm-typegen' version: 0.0.0 dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 typescript: 5.3.3 dev: false file:projects/rpc-client.tgz: - resolution: {integrity: sha512-eQuTjhdHYsBylV0Y0W4cUnVPVwkvPet9LLOuZzlR+2dpmmcKW5/J74yRv3XXXD357lLO8zA3RcVsuM+6MLFcxw==, tarball: file:projects/rpc-client.tgz} + resolution: {integrity: sha512-InfM8jjyEDnDsn5MD8nf4S0INs7zIn3maxMNAlQzCi44FiOWSaLf4ZoW80S+dtvAMDQIuSsCuvMtPlmuhOpwAg==, tarball: file:projects/rpc-client.tgz} name: '@rush-temp/rpc-client' version: 0.0.0 dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 '@types/websocket': 1.0.10 typescript: 5.3.3 websocket: 1.0.34 dev: false file:projects/scale-codec.tgz: - resolution: {integrity: sha512-JP3f7tKqsK5LZ6Uer/ExgFx8CGcZRXJmKovkWAiBTemA5DmNAoqTVPaXc7ZwS3Cr2jFJt4s21dhhn2SH9/3JYw==, tarball: file:projects/scale-codec.tgz} + resolution: {integrity: sha512-5pXoOcJhXmBp+hxm3G84ljvKxGUAW0JZXLz3pm/JLkLSze+hUa0NRZU1Ujy2Whoz7eKX0fWyypkp+6JyAcQyjg==, tarball: file:projects/scale-codec.tgz} name: '@rush-temp/scale-codec' version: 0.0.0 dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 typescript: 5.3.3 dev: false file:projects/scale-type-system.tgz: - resolution: {integrity: sha512-GdCe+3XkY3BfNxymE2ZqUq6lhM2dkUOijwzwDJ9+44h7icWPVL5be0l65wUSko5yljFpnn6yVslpHcTvrigctA==, tarball: file:projects/scale-type-system.tgz} + resolution: {integrity: sha512-QqYx3bzoQOJP7jA9WoJ/w1CkYc1j8NkN7eeWwDwnwNfDO+j5N8rAc9PfRc7rwM5ctXtZyYoQ05Gn7DoaFTS80w==, tarball: file:projects/scale-type-system.tgz} name: '@rush-temp/scale-type-system' version: 0.0.0 dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 typescript: 5.3.3 dev: false file:projects/shibuya-psp22.tgz(supports-color@8.1.1)(ts-node@10.9.2): - resolution: {integrity: sha512-0w1bZkcxV/JwQ3uS7wJpWhWga/hq4D0p+eIgtpo2wYrxgURM+lU1s+VQWc9hvGLSCheNFB7MuJIHCwkt8prZkw==, tarball: file:projects/shibuya-psp22.tgz} + resolution: {integrity: sha512-0aGb7rGg90MTxT2cSRKw6I66jTr2vaeY92xWwnSu0ek5xwSMhO+OHqp2AuM2GaIx9Y9AgspHQtW1qnNzTCr16Q==, tarball: file:projects/shibuya-psp22.tgz} id: file:projects/shibuya-psp22.tgz name: '@rush-temp/shibuya-psp22' version: 0.0.0 dependencies: - '@types/node': 18.18.14 - dotenv: 16.3.1 + '@types/node': 18.19.21 + dotenv: 16.4.5 pg: 8.11.3 - typeorm: 0.3.17(pg@8.11.3)(supports-color@8.1.1)(ts-node@10.9.2) + typeorm: 0.3.20(pg@8.11.3)(supports-color@8.1.1)(ts-node@10.9.2) typescript: 5.3.3 transitivePeerDependencies: - '@google-cloud/spanner' @@ -5591,137 +6595,137 @@ packages: dev: false file:projects/ss58-codec.tgz: - resolution: {integrity: sha512-xQr72eeX60HOvdoAaL8yt/o6bmtQ+wgsjset4Ar01RhO2x5bMYndbqQIynpt1bFY2iNC62Ggbcb4L89jqTccmQ==, tarball: file:projects/ss58-codec.tgz} + resolution: {integrity: sha512-G+BI7A9WM3g0x3OQssM5UD9W+brQNdAvKGjDDhjCFP1zVcjppXhTHcrywalRFQTZ7Vzmx8DMslFchHte5gUdUw==, tarball: file:projects/ss58-codec.tgz} name: '@rush-temp/ss58-codec' version: 0.0.0 dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 base-x: 4.0.0 blake2b: 2.1.4 typescript: 5.3.3 dev: false file:projects/ss58.tgz: - resolution: {integrity: sha512-J5y807QuAJsNxUnIjTY6AL/Ko+nOUW8IkZMNhAHXBc/FSc2rDlxOx/nx2E8gLDOfnlZdIekfQBnqdq8i7ixEXA==, tarball: file:projects/ss58.tgz} + resolution: {integrity: sha512-mpLeHKG1t6cKpp/kzW4op1Xvebj0lSAEmzhHYUSoqhKCtXG45xGONRMWTCAhhwobLLtvXHfz7ZJQuuoDG1gCFw==, tarball: file:projects/ss58.tgz} name: '@rush-temp/ss58' version: 0.0.0 dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 typescript: 5.3.3 dev: false file:projects/substrate-data-raw.tgz: - resolution: {integrity: sha512-5Ax0OrpGZsZj82DNUaM4y/DMtX71W2r7tTmCWJOOcoY8mGAXgYd22AA6xIb/Zwz10p0rFUPniBIEWbpzVmC3rQ==, tarball: file:projects/substrate-data-raw.tgz} + resolution: {integrity: sha512-cJKIBdAl3WjaMBowA1Sey1nlbHgbP9oaM+8ym4uRS/11mXTCkYBw8MmgDXFxrBS7M0ldU2tWvbXgYUeHSWDWxg==, tarball: file:projects/substrate-data-raw.tgz} name: '@rush-temp/substrate-data-raw' version: 0.0.0 dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 typescript: 5.3.3 dev: false file:projects/substrate-data.tgz: - resolution: {integrity: sha512-Y+hbIZDKeWJjbl4Y29rxV//cwJnmCA0eZBkYriFCO916BK3Or997UMymJ+HKvj/IfpIIMH9UKrZISaF8ITjSAg==, tarball: file:projects/substrate-data.tgz} + resolution: {integrity: sha512-LWIABkiM41dTB/tmRRc3dLIIUQ6miw2SvUSge5bE4/efIkJas4Vs2V3gVotzAx91wrTSPU5Eul4s1I8mvELPXg==, tarball: file:projects/substrate-data.tgz} name: '@rush-temp/substrate-data' version: 0.0.0 dependencies: '@substrate/calc': 0.2.8 - '@types/node': 18.18.14 + '@types/node': 18.19.21 blake2b: 2.1.4 typescript: 5.3.3 dev: false file:projects/substrate-dump.tgz: - resolution: {integrity: sha512-wRuR1TLMHtnJnCB2UoN45a58gddgJtgzMY3T/pbhFflqumq55eJTDU8T58cQ6zyZjIqcWQc+Ag2QOZa9ITE3cQ==, tarball: file:projects/substrate-dump.tgz} + resolution: {integrity: sha512-L5USkqhb9Lrlx2mUdVhUTRmDpBDYIF1GFt0YT96MotzyP3BVYov4y5UyYBN9/PkWxV6JHwiFT7ODn6Cbdk2fcA==, tarball: file:projects/substrate-dump.tgz} name: '@rush-temp/substrate-dump' version: 0.0.0 dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 commander: 11.1.0 prom-client: 14.2.0 typescript: 5.3.3 dev: false file:projects/substrate-ingest.tgz: - resolution: {integrity: sha512-EnfPOtsq93To1r+hGXgbXktgkkphl+e5cdks8MA6Q10Q3S7a2Qh/jPJycRXsV8ai85myMIwH0EVsfZCuU7HO5g==, tarball: file:projects/substrate-ingest.tgz} + resolution: {integrity: sha512-f1O4yD4R/RpwT6txUSysjTKdp6WrMNaco1Egg9+b0jnC9/LSr3hX4+UttMdeR153nsM9Ir2e64CXTkgB2mSEfA==, tarball: file:projects/substrate-ingest.tgz} name: '@rush-temp/substrate-ingest' version: 0.0.0 dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 commander: 11.1.0 dev: false file:projects/substrate-metadata-explorer.tgz: - resolution: {integrity: sha512-A+ZRFqMo+HyRzTq3aly0pK+ASfanWvh0zD4+JHbN2SSYS+GsLCBMsGPM+ntKNZ+HnzyeLdgps5lG+D0OanWXYw==, tarball: file:projects/substrate-metadata-explorer.tgz} + resolution: {integrity: sha512-ucKgO+Ber3H2NtF8STlvWP4Yh2nTeifPbOCURPNW+6PzH3G/i+Cn76Lirp0Ik+s/reglzNm/0y8AUEn6JDHlpA==, tarball: file:projects/substrate-metadata-explorer.tgz} name: '@rush-temp/substrate-metadata-explorer' version: 0.0.0 dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 commander: 11.1.0 typescript: 5.3.3 dev: false file:projects/substrate-metadata-service.tgz: - resolution: {integrity: sha512-9I8gf69oxL+zlS2L4C2pQFSWF28GT2Q5Ric72O5Gqa5b507YhMG+MKQ+LLrsVyhoyuJot22wR19BzqLRpnru3w==, tarball: file:projects/substrate-metadata-service.tgz} + resolution: {integrity: sha512-6mR2/ROXVmI+rMdHDO1xImHN8SUcU5X4FoVVtltVihCuftNIa0HP6Tnt8tiw7HpQhB0ytsFoIVJWtI9Q67p2SA==, tarball: file:projects/substrate-metadata-service.tgz} name: '@rush-temp/substrate-metadata-service' version: 0.0.0 dependencies: '@types/express': 4.17.21 - '@types/node': 18.18.14 + '@types/node': 18.19.21 commander: 11.1.0 - express: 4.18.2 + express: 4.18.3 typescript: 5.3.3 dev: false file:projects/substrate-processor.tgz: - resolution: {integrity: sha512-HkeiG8wRXq9L9bRUHFVPKIN8oe7aES17BtlSXm51X10eC//vnJkJJpgeNS9r+BD11X1lhLLlg8eylnb2T+1NHg==, tarball: file:projects/substrate-processor.tgz} + resolution: {integrity: sha512-kyQ1He7N1w4ecIC1EN+JjhBrfEQojjJvnCTgkUjtfeDTk7/8FyVbDw63f8ectjxr6Ocp53iNExs0MjGPWp8WvA==, tarball: file:projects/substrate-processor.tgz} name: '@rush-temp/substrate-processor' version: 0.0.0 dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 typescript: 5.3.3 dev: false file:projects/substrate-runtime.tgz: - resolution: {integrity: sha512-JxC7mi36FAgcfOSiyfcr2EgdZ9siSCaRvOF3IADR1lvCYCM73wzzNQU8HbXR2lp7J/6iuvKmgt5ioiWXW36gnA==, tarball: file:projects/substrate-runtime.tgz} + resolution: {integrity: sha512-uOkzZPsj4C3NlDYeqB7PB6IXVl2lgNd4RpqGNZ3WIhKFrnruAeO412Xmq4ZgifYzkct2odVJF2ZAIp+BUoFTBg==, tarball: file:projects/substrate-runtime.tgz} name: '@rush-temp/substrate-runtime' version: 0.0.0 dependencies: '@types/mocha': 10.0.6 - '@types/node': 18.18.14 + '@types/node': 18.19.21 blake2b: 2.1.4 expect: 29.7.0 - mocha: 10.2.0 + mocha: 10.3.0 typescript: 5.3.3 dev: false file:projects/substrate-typegen.tgz: - resolution: {integrity: sha512-G3gWfTUH75GvNuvlv35YwgTnTj3aIjmbonBQlHHdrQpn91efLMz2SZd3I45f35xxeg21XYiU3o0oH/kY2dcJUg==, tarball: file:projects/substrate-typegen.tgz} + resolution: {integrity: sha512-0T7ITzUvMiSfEOQDv7JRr/vrgWMOebTfY++3AaLQuT6xyMRcRv14x0StqDhxWP8Tt+V/77ONdz0dg5FHrI9u0w==, tarball: file:projects/substrate-typegen.tgz} name: '@rush-temp/substrate-typegen' version: 0.0.0 dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 commander: 11.1.0 typescript: 5.3.3 dev: false file:projects/typeorm-codegen.tgz: - resolution: {integrity: sha512-ACcp0p2YF4RLjgFBM9y2GjY2lGrYtvlYcDuysbgAL1lN+9VOUdHaQfXmMpO/gsGoW+GI0GRJXzQvg8RxYtEN9Q==, tarball: file:projects/typeorm-codegen.tgz} + resolution: {integrity: sha512-4Woy/XGTqvBbSr/GNQ67mk6Oq49+KNCyFqw643JHinCqwCsUSiSst1M/6KY773Cluw1gMq4N4cks7YzjTdpFjA==, tarball: file:projects/typeorm-codegen.tgz} name: '@rush-temp/typeorm-codegen' version: 0.0.0 dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 commander: 11.1.0 typescript: 5.3.3 dev: false file:projects/typeorm-config.tgz(pg@8.11.3)(supports-color@8.1.1)(ts-node@10.9.2): - resolution: {integrity: sha512-y9eE4v626PD3bDV4xiALL7hEDtnG+90/FzZFncGYVTh9tEumia+zWQlGpJnjrM44AdR7KJk9MmSA+qeWdqeWng==, tarball: file:projects/typeorm-config.tgz} + resolution: {integrity: sha512-wKT5CJd1nmlelB6/N9XlgRr89zsY3ZUZ0hxeWxflFK0CXHEpoCAuH9NOue6qpVdTFDDCSVuzgW2pHJhcbHLRwQ==, tarball: file:projects/typeorm-config.tgz} id: file:projects/typeorm-config.tgz name: '@rush-temp/typeorm-config' version: 0.0.0 dependencies: - '@types/node': 18.18.14 - typeorm: 0.3.17(pg@8.11.3)(supports-color@8.1.1)(ts-node@10.9.2) + '@types/node': 18.19.21 + typeorm: 0.3.20(pg@8.11.3)(supports-color@8.1.1)(ts-node@10.9.2) typescript: 5.3.3 transitivePeerDependencies: - '@google-cloud/spanner' @@ -5745,15 +6749,15 @@ packages: dev: false file:projects/typeorm-migration.tgz(pg@8.11.3)(supports-color@8.1.1)(ts-node@10.9.2): - resolution: {integrity: sha512-Gidxia5ARgPjH0+Ug43l5rZp2Uvp50EwQ19OcgfMVtxPatnb7oryUi5fkggced4vSXiJg9HR4I2Hp/UXwLbWRQ==, tarball: file:projects/typeorm-migration.tgz} + resolution: {integrity: sha512-VCDa0mHrzQkoHNEbPquqQjWVhRPIp+TXxqGn9XFJrTRjZUe9qNVfoDCbbT1Ih9x1/WG3M3Sjb7tTpgAGc09trA==, tarball: file:projects/typeorm-migration.tgz} id: file:projects/typeorm-migration.tgz name: '@rush-temp/typeorm-migration' version: 0.0.0 dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 commander: 11.1.0 - dotenv: 16.3.1 - typeorm: 0.3.17(pg@8.11.3)(supports-color@8.1.1)(ts-node@10.9.2) + dotenv: 16.4.5 + typeorm: 0.3.20(pg@8.11.3)(supports-color@8.1.1)(ts-node@10.9.2) typescript: 5.3.3 transitivePeerDependencies: - '@google-cloud/spanner' @@ -5777,18 +6781,18 @@ packages: dev: false file:projects/typeorm-store.tgz(supports-color@8.1.1)(ts-node@10.9.2): - resolution: {integrity: sha512-br5EJkp4mEAae1g2WFfW6vYuZMfLLZMaE4es0BeHlP9rHQjpHdFQwpjdl4CaDPiK+g9vew9GBfDm7LX8h6y+Xg==, tarball: file:projects/typeorm-store.tgz} + resolution: {integrity: sha512-EIf5d7WQ5F+8201ZtaDqLNWtHus7mx6kw0J0j24ORc8jM8eq8WgBetc5oJN0NUPKDo8ptIUbKGTKWydvMg7jnw==, tarball: file:projects/typeorm-store.tgz} id: file:projects/typeorm-store.tgz name: '@rush-temp/typeorm-store' version: 0.0.0 dependencies: '@types/mocha': 10.0.6 - '@types/node': 18.18.14 - '@types/pg': 8.10.9 + '@types/node': 18.19.21 + '@types/pg': 8.11.2 expect: 29.7.0 - mocha: 10.2.0 + mocha: 10.3.0 pg: 8.11.3 - typeorm: 0.3.17(pg@8.11.3)(supports-color@8.1.1)(ts-node@10.9.2) + typeorm: 0.3.20(pg@8.11.3)(supports-color@8.1.1)(ts-node@10.9.2) typescript: 5.3.3 transitivePeerDependencies: - '@google-cloud/spanner' @@ -5811,84 +6815,84 @@ packages: dev: false file:projects/types-test.tgz: - resolution: {integrity: sha512-EiCVl4VlBVmwUa5plW1wGHodCuLD6QUc05x2aB+07tlfqLzbD3qkVDyRRyJxLrBKNGq+p+r6kqbWL1PM4FtTWQ==, tarball: file:projects/types-test.tgz} + resolution: {integrity: sha512-yefFCEnRHA2hwo8HazWp4VsAB6oqkiyBqvdNKSshsNKKwdc0KdXbHIsqbw2CAm8mec5uKqoqoCpf+BkK8O0vVA==, tarball: file:projects/types-test.tgz} name: '@rush-temp/types-test' version: 0.0.0 dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 typescript: 5.3.3 dev: false file:projects/util-internal-archive-client.tgz: - resolution: {integrity: sha512-VNZk5a16PUc+RHzvkZefDvw6DkzshhWhRXg68e+9CErlTPKddHtCLd6aBrk4tkuscTCg/7f4hJBXtec1ax2Wag==, tarball: file:projects/util-internal-archive-client.tgz} + resolution: {integrity: sha512-SPWgZpT4PFvPb95t5MnnpuOsfl7A109uEIx70+uFMd61W4CMSyiSxa6KxXtcETgdxmZ4jmDzJiNGvc6FfwD+1Q==, tarball: file:projects/util-internal-archive-client.tgz} name: '@rush-temp/util-internal-archive-client' version: 0.0.0 dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 typescript: 5.3.3 dev: false file:projects/util-internal-archive-layout.tgz: - resolution: {integrity: sha512-iEUYxEdlu6R9yHNMFq58nvI7OJxgFR0o9jzBsDsOOmh4tLxXzzTl/opIJzksvL6YvOTRT6/ZEsq4YJNyF4RZeA==, tarball: file:projects/util-internal-archive-layout.tgz} + resolution: {integrity: sha512-AuXK5N088FtjtwbDX74td9ACAVAYu5ySA1qTdN7XfvAOgZ8hhmVzaFRrmrqnTDnGTuHBWtb7/dbzhKDgnaHkLQ==, tarball: file:projects/util-internal-archive-layout.tgz} name: '@rush-temp/util-internal-archive-layout' version: 0.0.0 dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 typescript: 5.3.3 dev: false file:projects/util-internal-binary-heap.tgz: - resolution: {integrity: sha512-FuCabuHvxL94nHw4H0bzUVMgMOwsr+BOhczLUhneQijzQAQpGhq/uYBbzQgjsY/AtqMBe2hciv0Xq0kf2DcI1g==, tarball: file:projects/util-internal-binary-heap.tgz} + resolution: {integrity: sha512-ySQbSVAEksbM/fIDa9Ze8c5xmo7GoKCaI5ox7AB7vAxFSb0oQ+KQelUdJIzA2I4kWnJ3K7dCbPCZlADICAUO/w==, tarball: file:projects/util-internal-binary-heap.tgz} name: '@rush-temp/util-internal-binary-heap' version: 0.0.0 dev: false file:projects/util-internal-code-printer.tgz: - resolution: {integrity: sha512-J1Ng3LP8p05mj5gMdXOCMAyR+GoiV0G3R2IRozCh54nfTHEdUdEwp3GhXiRkkCS7/0zBAIZENZfJNldK9JzKTg==, tarball: file:projects/util-internal-code-printer.tgz} + resolution: {integrity: sha512-+7eXJC2cnu4nSRXHrzd3t4DQ1r03wj1FA8T1YPBlNOngf3oUrpqEdKTewO3D0+zrsFQAH+VdJdhvzUMvsp6aiw==, tarball: file:projects/util-internal-code-printer.tgz} name: '@rush-temp/util-internal-code-printer' version: 0.0.0 dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 typescript: 5.3.3 dev: false file:projects/util-internal-commander.tgz: - resolution: {integrity: sha512-mrUaWpZyiwll53NKSdR835qZcKJ7/AgsvhiAbwEcC5o0EMKjK+8ibSaHdh/QycVOdUAG1iAPPA0pRyi/jYKImA==, tarball: file:projects/util-internal-commander.tgz} + resolution: {integrity: sha512-LNHl1Q2ZASz2JwUj+nP6laiKFTa0s7r58RXTaSaMUtwl9InHTSJMMZCjsg+5CjjhDcTghHk/9vkr73GxQz3DHg==, tarball: file:projects/util-internal-commander.tgz} name: '@rush-temp/util-internal-commander' version: 0.0.0 dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 commander: 11.1.0 typescript: 5.3.3 dev: false file:projects/util-internal-config.tgz: - resolution: {integrity: sha512-34azTxxy4KwZyE5pmOPRWGC9zXZ2OrTr2J1JSmeHks0OMeK6Zj9YnKwkefJEjxjpyTehiyhE5Q0TwA4nU3gexw==, tarball: file:projects/util-internal-config.tgz} + resolution: {integrity: sha512-LE37R3QmK+pUzTSQKtzFX48dhcrnXs1axmdMYQ3eWI08WrBRNKXAnpFLPaADHi6/mBl+Yat8ezt6DZohk7JSew==, tarball: file:projects/util-internal-config.tgz} name: '@rush-temp/util-internal-config' version: 0.0.0 dependencies: '@exodus/schemasafe': 1.3.0 - '@types/node': 18.18.14 - jsonc-parser: 3.2.0 + '@types/node': 18.19.21 + jsonc-parser: 3.2.1 typescript: 5.3.3 dev: false file:projects/util-internal-counters.tgz: - resolution: {integrity: sha512-TxYLDX1wjSmReW2mBYx4H5Fwwp31FnFEJJ8KqUhYjq9zzwXw5iE6ciXM4Sz7jqrYVnSU11br793NXb9GFFg4fA==, tarball: file:projects/util-internal-counters.tgz} + resolution: {integrity: sha512-H+OT4ekb3y2dRIXL73zdnT0d4VICY48sQ9eT4/o6P9zBfMLMLh/F0EvSsh3x+0uXkNac5Vf40ls7Y/eETspI+Q==, tarball: file:projects/util-internal-counters.tgz} name: '@rush-temp/util-internal-counters' version: 0.0.0 dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 typescript: 5.3.3 dev: false file:projects/util-internal-fs.tgz: - resolution: {integrity: sha512-m9wLSWRu1K1qM9y7zA/Dyguu5NXlEzYHuhCcPQHI0S2b5q0QBPDgjRly4UsrgnmAiSsirkKLm63WCNTTlJHoqw==, tarball: file:projects/util-internal-fs.tgz} + resolution: {integrity: sha512-evaThx+v+qBIt+TFt3HrpDpHxqCoCyyMDzvpOML7IfUb1BghSjlYte/BH+HnVPL7ADX2Mn/7c25PQswtmL1M9g==, tarball: file:projects/util-internal-fs.tgz} name: '@rush-temp/util-internal-fs' version: 0.0.0 dependencies: - '@aws-sdk/client-s3': 3.462.0 - '@types/node': 18.18.14 + '@aws-sdk/client-s3': 3.525.0 + '@types/node': 18.19.21 typescript: 5.3.3 upath: 2.0.1 transitivePeerDependencies: @@ -5896,136 +6900,136 @@ packages: dev: false file:projects/util-internal-hex.tgz: - resolution: {integrity: sha512-IeyUl8yzFxUBR1y2/NZFxuroLEtKFCWHE1aEvpF/E++Cnx0e+DinrwojlJjYckC9bqjRvbEAKBZiFf4RGzi1KA==, tarball: file:projects/util-internal-hex.tgz} + resolution: {integrity: sha512-6in6m1mDAH/fouuhMUjrEJKHnmgFsxieL+6l0lS+i5sFPRXc4FyNGfi0S+zqZo59xRsqYUQVO0s6GydAuHQsmQ==, tarball: file:projects/util-internal-hex.tgz} name: '@rush-temp/util-internal-hex' version: 0.0.0 dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 typescript: 5.3.3 dev: false file:projects/util-internal-http-server.tgz: - resolution: {integrity: sha512-qVPCAnuwQM+0up8J6EQTwtzU/R7HqH8ePcXDxbCVYwUWwtayflK9jkYK7Eu1yCKfqYCcoejrWl08WFU9LKVVtQ==, tarball: file:projects/util-internal-http-server.tgz} + resolution: {integrity: sha512-Ox5wnELibJ01dizByj8rj9bZVRU7pct6YkkHPmpeLzzQfFjWmg7coCgzxSKrkR8S9b9YLAVIjRVLVGQfpPqp/A==, tarball: file:projects/util-internal-http-server.tgz} name: '@rush-temp/util-internal-http-server' version: 0.0.0 dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 '@types/stoppable': 1.1.3 stoppable: 1.1.0 typescript: 5.3.3 dev: false file:projects/util-internal-ingest-tools.tgz: - resolution: {integrity: sha512-7QIXYlrFfvXcNdEi72w5nMGFEcR1tH3++aon0acv3s14X6jh0ZvaimVfTm8LPBqKPc4RUsRhliwiM3E3eyHmPA==, tarball: file:projects/util-internal-ingest-tools.tgz} + resolution: {integrity: sha512-knFvddIEEVp5CBVEh961uCfXtgOVxBZlyUD0eDXmMJiR7nyqOHSxCnbPPd1+Ou6CqzDpXlHqmNi5lOYfDd2ndw==, tarball: file:projects/util-internal-ingest-tools.tgz} name: '@rush-temp/util-internal-ingest-tools' version: 0.0.0 dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 typescript: 5.3.3 dev: false file:projects/util-internal-json.tgz: - resolution: {integrity: sha512-uzZ7YGOFKZxE6DkaHKDNWZ2Htut/Kv1/UQw/PQg4PdvGxpZNUJLtcG9r9dA4lfxDGOHtlb2jDk2Es8DfPRq5uQ==, tarball: file:projects/util-internal-json.tgz} + resolution: {integrity: sha512-DqSQ6DqGIKp+5PXkEKUpKrrzF4728UX5PJwqKOcpCCf3MZKJLfLm3IOHsAx/fQKz2/Io8NHXNYpepMnBewaZ7w==, tarball: file:projects/util-internal-json.tgz} name: '@rush-temp/util-internal-json' version: 0.0.0 dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 typescript: 5.3.3 dev: false file:projects/util-internal-processor-tools.tgz: - resolution: {integrity: sha512-C//t0hArnTsX68idjYa47zOaog/+QpBffRuyAwUj2PBZr+oLdgYjOpzWujDrJTFaKtZQYw4BjRwginRYrrUVbw==, tarball: file:projects/util-internal-processor-tools.tgz} + resolution: {integrity: sha512-BXk4GIxk6oxl7HIO8FvJLdS/9ofyvcZq9jLIfQ9oUwoR264vwxBBlgVrPUaou92LxpCCQj8b8Vtc0lNl8YbI6A==, tarball: file:projects/util-internal-processor-tools.tgz} name: '@rush-temp/util-internal-processor-tools' version: 0.0.0 dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 prom-client: 14.2.0 typescript: 5.3.3 dev: false file:projects/util-internal-prometheus-server.tgz: - resolution: {integrity: sha512-h2JTGFhrhwAytuqPVCF7zIgn4fMJLmp32nPd21P8uxmX9xfeNwLW//rY3hSCqzr657Z3tI2A3jd+mAZaBAM1ig==, tarball: file:projects/util-internal-prometheus-server.tgz} + resolution: {integrity: sha512-/Xm+epjzPvzSUOeixEuXyjheG4vj14JFI6fdfjAw2yEJJCSub1bR2d00xKovedN+E/CpUXiPUXoK0SRLAoi5wQ==, tarball: file:projects/util-internal-prometheus-server.tgz} name: '@rush-temp/util-internal-prometheus-server' version: 0.0.0 dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 prom-client: 14.2.0 typescript: 5.3.3 dev: false file:projects/util-internal-range.tgz: - resolution: {integrity: sha512-n+3j2dvwitdqdgR8hWXa+hcjUMW7F8LQvn2PIK92YAmsExmdN3k0sX+9rCu8gw1vAq5Kmo4EorxjZb5QBSVbkg==, tarball: file:projects/util-internal-range.tgz} + resolution: {integrity: sha512-RttrYMkE0lUrkKmx7ZBsKu4qBgwyVfegKzJ/pIiy7OdrEZtoiw8jtaAfrSo7kNPibpPS/1nSzjsCIUhycY8tCg==, tarball: file:projects/util-internal-range.tgz} name: '@rush-temp/util-internal-range' version: 0.0.0 dependencies: - '@types/node': 18.18.14 - fast-check: 3.14.0 + '@types/node': 18.19.21 + fast-check: 3.16.0 typescript: 5.3.3 dev: false file:projects/util-internal-read-lines.tgz: - resolution: {integrity: sha512-VVinazzOderQcW3cLD0KUPstTv1ea16MVkfHydQf6SO6LvwVLWYEOsfBSnItlof3wMkoqPq0SgexYa9QoBjVkQ==, tarball: file:projects/util-internal-read-lines.tgz} + resolution: {integrity: sha512-cZ+/wV7mHLmtjinxKcT5nm4p6Bao7dP/C0QelVPcGPm8xtj7OmShIKQ1FzZiu9ULy8XqMxyBfNUamq1FARbBEw==, tarball: file:projects/util-internal-read-lines.tgz} name: '@rush-temp/util-internal-read-lines' version: 0.0.0 dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 typescript: 5.3.3 dev: false file:projects/util-internal-ts-node.tgz: - resolution: {integrity: sha512-cCrozeBOdLsqh7V7LDuv2i1UmH8z41+H6svNhCQFY/V3DzsJxOF+4ys6iwpRt3NJJ9NHmkURXAo9CeUgzyTB/g==, tarball: file:projects/util-internal-ts-node.tgz} + resolution: {integrity: sha512-a/jCj2qurKv8VA1VMlj0DHxEMp1yhwMj+qbxotiHUEWFYnph/Ewx6BajBCXqE1GNc7PoMKOmVQyuJ2Og9bl1+w==, tarball: file:projects/util-internal-ts-node.tgz} name: '@rush-temp/util-internal-ts-node' version: 0.0.0 dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 typescript: 5.3.3 dev: false file:projects/util-internal-validation.tgz: - resolution: {integrity: sha512-p0INY03ZSLfO53YV+FBoxwfmz+WEEWt7cbov1ZwD2GRWEsQGN6Wrpg7sf05/uOYdpvxkwXomLFqZB36IuA/06w==, tarball: file:projects/util-internal-validation.tgz} + resolution: {integrity: sha512-UEDOzXnuWfeCqeHvFQjWxwZedpvt4CvjbDgaa2H4CR3tRYLFuGCtwmKtwkb/maMyUyup9hdNSE0OsZtLpP/ksw==, tarball: file:projects/util-internal-validation.tgz} name: '@rush-temp/util-internal-validation' version: 0.0.0 dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 typescript: 5.3.3 dev: false file:projects/util-internal.tgz: - resolution: {integrity: sha512-h8jh0lCjMxDKenweNtBrEmC3JhqttxN6JvNHj+F13zAU69x8wRvCsdnXLFNpuuBF0RCbeKuL/zsavhUFTxTXPw==, tarball: file:projects/util-internal.tgz} + resolution: {integrity: sha512-/qXYy9MwYAnk+ZcMniYbgkIkDuLQCHVz4qFVHqpig2EalE9kNvm6SE3GHKEHBTRcMpwv14uPDtPyhYQAUURp2w==, tarball: file:projects/util-internal.tgz} name: '@rush-temp/util-internal' version: 0.0.0 dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 typescript: 5.3.3 dev: false file:projects/util-naming.tgz: - resolution: {integrity: sha512-WUHaO5x2BjCfMId3XbSIRgGwqijZc+twlgj47fdPvx88nuee9NhpRH8l/oYBjtOb130mrYaCsusGNyDOGpz2dA==, tarball: file:projects/util-naming.tgz} + resolution: {integrity: sha512-Bzmg3bQcqCNvkrX3tzYzrVKUEO6Ij+K0l3VvmSFBaUfTBi+Rf4TbYhYqjUsG9ISTyDqQdFu7b+aQmvLCm8fTiA==, tarball: file:projects/util-naming.tgz} name: '@rush-temp/util-naming' version: 0.0.0 dependencies: '@types/inflected': 2.1.3 - '@types/node': 18.18.14 + '@types/node': 18.19.21 camelcase: 6.3.0 inflected: 2.1.0 typescript: 5.3.3 dev: false file:projects/util-timeout.tgz: - resolution: {integrity: sha512-YzH89o6jkRXWtQ7Zcb3NZnu+6MGcArezO616z/pyoUlgLC0HNw0cSszkB0AZ2Bl3/13jVueBS9c3IPYC3T8gpQ==, tarball: file:projects/util-timeout.tgz} + resolution: {integrity: sha512-Q1f6wg3zBfyg+KEc4LFhzpD5MQS6WS+rl9DcP927ZOYsow9GdnB6D8HSBYmPq8aIDl9jdfhJCIQ24iInNB52OQ==, tarball: file:projects/util-timeout.tgz} name: '@rush-temp/util-timeout' version: 0.0.0 dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 typescript: 5.3.3 dev: false file:projects/util-xxhash.tgz: - resolution: {integrity: sha512-PqnwpEp6cQk8vpuwmTBfk7YqAQ+2M63SxpzLz9UeqgtU1IVD0S+hisp0o0KPlJOy6IgHx+dIQh0+GHrF39E/6g==, tarball: file:projects/util-xxhash.tgz} + resolution: {integrity: sha512-GGh0hvVKAnw3JZqEwa/XYjBkazdYKjM3DB/8K+VnNS9Qpriq8MbOE9QtbP7WvDnVPbt0gUBKSkA5P6g9jyficg==, tarball: file:projects/util-xxhash.tgz} name: '@rush-temp/util-xxhash' version: 0.0.0 dependencies: - '@types/node': 18.18.14 + '@types/node': 18.19.21 '@types/xxhashjs': 0.2.4 typescript: 5.3.3 xxhash-wasm: 1.0.2 @@ -6033,16 +7037,16 @@ packages: dev: false file:projects/workspace.tgz: - resolution: {integrity: sha512-wJzDo/ygGpbQnxLN13cmPyH2b6vOrsaYsTLomc0uQ75LjB9F4RgnZhPRqpcghGNdQeVJdHMow426922O9SsYeA==, tarball: file:projects/workspace.tgz} + resolution: {integrity: sha512-Me34mjq0Tb2mpntbgjmHS7W2oGK3DefI3M0TLRxSSRqU6QLCMsHkrPJnR+JLmBpOuJm6HkKNqXIB6UvjHBCaYQ==, tarball: file:projects/workspace.tgz} name: '@rush-temp/workspace' version: 0.0.0 dependencies: - '@types/node': 18.18.14 - '@types/semver': 7.5.6 + '@types/node': 18.19.21 + '@types/semver': 7.5.8 commander: 11.1.0 - jsonc-parser: 3.2.0 + jsonc-parser: 3.2.1 latest-version: 5.1.0 - semver: 7.5.4 + semver: 7.6.0 type-fest: 2.19.0 typescript: 5.3.3 dev: false diff --git a/evm/evm-typegen/package.json b/evm/evm-typegen/package.json index 693e1d973..2113de15a 100644 --- a/evm/evm-typegen/package.json +++ b/evm/evm-typegen/package.json @@ -1,6 +1,6 @@ { "name": "@subsquid/evm-typegen", - "version": "3.3.0", + "version": "4.0.0", "description": "CLI for generating typescript types and decode implementations for evm logs", "license": "GPL-3.0-or-later", "repository": "git@github.com:subsquid/squid.git", diff --git a/test/erc20-transfers/package.json b/test/erc20-transfers/package.json index b8040ea42..3741dbdf5 100644 --- a/test/erc20-transfers/package.json +++ b/test/erc20-transfers/package.json @@ -7,7 +7,7 @@ }, "dependencies": { "@subsquid/graphql-server": "^4.5.0", - "@subsquid/evm-utils": "../../evm/evm-utils", + "@subsquid/evm-utils": "1.0.0", "@subsquid/evm-processor": "^1.17.0", "@subsquid/typeorm-migration": "^1.3.0", "@subsquid/typeorm-store": "^1.2.6", @@ -17,7 +17,7 @@ "typeorm": "^0.3.17" }, "devDependencies": { - "@subsquid/evm-typegen": "../../evm/evm-typegen", + "@subsquid/evm-typegen": "4.0.0", "@subsquid/typeorm-codegen": "^1.3.3", "@types/node": "^18.18.14", "typescript": "~5.3.2" From f8f4c2a02f7efc61bc479a987354b15fc5456716 Mon Sep 17 00:00:00 2001 From: ivan Date: Mon, 4 Mar 2024 13:49:56 +0100 Subject: [PATCH 10/12] fix CI --- evm/evm-utils/package.json | 2 +- graphql/openreader/src/server.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/evm/evm-utils/package.json b/evm/evm-utils/package.json index d96296673..d90870602 100644 --- a/evm/evm-utils/package.json +++ b/evm/evm-utils/package.json @@ -14,7 +14,7 @@ "main": "lib/index.js", "scripts": { "build": "rm -rf lib && tsc -p tsconfig.build.json", - "test": "vitest" + "test": "vitest run" }, "dependencies": {}, "devDependencies": { diff --git a/graphql/openreader/src/server.ts b/graphql/openreader/src/server.ts index 4bcbee0e7..46170fb98 100644 --- a/graphql/openreader/src/server.ts +++ b/graphql/openreader/src/server.ts @@ -180,7 +180,7 @@ export async function runApollo(options: ApolloOptions): Promise apollo.stop()) apollo.applyMiddleware({ - app, + app: app as any, bodyParserConfig: { limit: maxRequestSizeBytes } From 9980f54bf9b18f3c06517082f1b9638c6ddcf218 Mon Sep 17 00:00:00 2001 From: ivan Date: Mon, 4 Mar 2024 15:25:52 +0100 Subject: [PATCH 11/12] Stop generating abi.support file --- evm/evm-typegen/package.json | 4 +- evm/evm-typegen/src/main.ts | 3 - evm/evm-typegen/src/multicall.ts | 2 +- evm/evm-typegen/src/typegen.ts | 2 +- evm/evm-typegen/src/util/types.ts | 4 +- evm/evm-utils/src/abi.support.ts | 213 ++++++++++++++++++++++++++++++ evm/evm-utils/src/index.ts | 1 + evm/evm-utils/src/types.ts | 6 +- test/erc20-transfers/package.json | 4 +- 9 files changed, 226 insertions(+), 13 deletions(-) create mode 100644 evm/evm-utils/src/abi.support.ts diff --git a/evm/evm-typegen/package.json b/evm/evm-typegen/package.json index 2113de15a..417f6f31a 100644 --- a/evm/evm-typegen/package.json +++ b/evm/evm-typegen/package.json @@ -19,6 +19,7 @@ "build": "rm -rf lib && tsc -p tsconfig.build.json" }, "dependencies": { + "@subsquid/evm-utils": "1.0.0", "@subsquid/http-client": "^1.3.2", "@subsquid/logger": "^1.3.3", "@subsquid/util-internal": "^3.0.0", @@ -29,9 +30,6 @@ "abitype": "^1.0.0", "viem": "^2.7.11" }, - "peerDependencies": { - "@subsquid/evm-utils": "1.0.0" - }, "devDependencies": { "@types/node": "^18.18.14", "types-solc": "^1.0.1", diff --git a/evm/evm-typegen/src/main.ts b/evm/evm-typegen/src/main.ts index 9e3d658c8..3d17641a1 100644 --- a/evm/evm-typegen/src/main.ts +++ b/evm/evm-typegen/src/main.ts @@ -77,9 +77,6 @@ squid-evm-typegen src/abi 0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413#contract return } - dest.add('abi.support.ts', [__dirname, '../src/abi.support.ts']) - LOG.info(`saved ${dest.path('abi.support.ts')}`) - if (opts.multicall) { dest.add('multicall.ts', [__dirname, '../src/multicall.ts']) LOG.info(`saved ${dest.path('multicall.ts')}`) diff --git a/evm/evm-typegen/src/multicall.ts b/evm/evm-typegen/src/multicall.ts index 7e190d539..c4f171568 100644 --- a/evm/evm-typegen/src/multicall.ts +++ b/evm/evm-typegen/src/multicall.ts @@ -1,4 +1,4 @@ -import { ContractBase, Func } from "./abi.support"; +import { ContractBase, Func } from "@subsquid/evm-utils"; type Call = { target: string; callData: string }; diff --git a/evm/evm-typegen/src/typegen.ts b/evm/evm-typegen/src/typegen.ts index 8db029981..cb7a6eaf8 100644 --- a/evm/evm-typegen/src/typegen.ts +++ b/evm/evm-typegen/src/typegen.ts @@ -26,7 +26,7 @@ export class Typegen { } generate(): void { - this.out.line("import {LogEvent, Func, ContractBase} from './abi.support'") + this.out.line("import {LogEvent, Func, ContractBase} from '@subsquid/evm-utils'") this.out.line() this.generateTypes() diff --git a/evm/evm-typegen/src/util/types.ts b/evm/evm-typegen/src/util/types.ts index 84bfe954c..1a5c001b1 100644 --- a/evm/evm-typegen/src/util/types.ts +++ b/evm/evm-typegen/src/util/types.ts @@ -64,7 +64,7 @@ export function getNamedType(params: readonly AbiParameter[]): string { return `{ ${params.map((p, index) => `${getName(p, index)}: ${getType(p)}`).join(', ')} }` } -export function geTupleType(params: readonly AbiParameter[]): string { +export function getTupleType(params: readonly AbiParameter[]): string { return `[${params.map((p, index) => `${getName(p, index)}: ${getType(p)}`).join(', ')}]` } @@ -80,5 +80,5 @@ export function stringifyParams(inputs: readonly AbiParameter[]): string { } export function getReturnType(outputs: readonly AbiParameter[]) { - return outputs.length == 1 ? getType(outputs[0]) : geTupleType(outputs) + return outputs.length == 1 ? getType(outputs[0]) : getTupleType(outputs) } diff --git a/evm/evm-utils/src/abi.support.ts b/evm/evm-utils/src/abi.support.ts new file mode 100644 index 000000000..a740aea3f --- /dev/null +++ b/evm/evm-utils/src/abi.support.ts @@ -0,0 +1,213 @@ +import {type AbiParameter, type Hex, decodeAbiParameters, hasDynamicChild, encodeFunctionData} from '.' + +export interface EventRecord { + topics: string[] + data: string +} +export type LogRecord = EventRecord + +type EventType = { + type: 'tuple' + internalType?: string + indexed?: boolean + name: string + components: EventType[] +} | { + type: string + internalType?: string + indexed?: boolean + name: string +} + +function assertIsHex(val: unknown): asserts val is Hex { + if (typeof val !== 'string' || !val.startsWith('0x')) { + throw new Error('Not a hex string') + } +} + +export class LogEvent { + private indexedArgs: ((AbiParameter & {index: number}) | null)[] = []; + private nonIndexedArgs: (AbiParameter & {index: number})[] = []; + + constructor(public readonly topic: string, readonly types: readonly EventType[]) { + assertIsHex(topic) + let index = 0; + for (const type of types) { + if (!type.indexed) { + this.nonIndexedArgs.push({ + ...type, + index + }) + } else { + if (hasDynamicChild(type)) { + this.indexedArgs.push({ + ...type, + type: 'bytes32', + index + }) + } else { + this.indexedArgs.push({ + ...type, + index + }) + } + } + index++; + } + } + + is(rec: EventRecord): boolean { + return rec.topics[0] === this.topic + } + + decode(rec: EventRecord): TEventArgs { + if (!this.is(rec)) { + throw new Error('Invalid event record') + } + assertIsHex(rec.data) + const result: any = {} + const parsedData = decodeAbiParameters(this.nonIndexedArgs, rec.data) + for (let i = 0; i < parsedData.length; i++) { + if (this.nonIndexedArgs[i].name) { + result[this.nonIndexedArgs[i].name!] = parsedData[i] + } else { + result[`_${this.nonIndexedArgs[i].index}`] = parsedData[i] + } + } + rec.topics.slice(1).forEach((topic, i) => { + const type = this.indexedArgs[i] + if (type) { + assertIsHex(topic) + const [parsedData] = decodeAbiParameters([type], topic) + if (type.name) { + result[type.name] = parsedData + } else { + result[`_${type.index}`] = parsedData + } + } + }) + return result + } +} + +export interface FuncRecord { + sighash?: string + input: string +} + +export class Func { + public readonly sighash: Hex + constructor(sighash: string, private readonly args: AbiParameter[], private readonly result: AbiParameter[]) { + assertIsHex(sighash) + this.sighash = sighash + } + + is(rec: FuncRecord): boolean { + let sighash = rec.sighash ? rec.sighash : rec.input.slice(0, 10) + return sighash === this.sighash + } + + decode(input: string): TFunctionArgs + decode(rec: FuncRecord): TFunctionArgs + decode(inputOrRec: string | FuncRecord): TFunctionArgs { + const input = typeof inputOrRec === 'string' ? inputOrRec : inputOrRec.input + assertIsHex(input) + if (!this.is({input})) { + throw new Error('Invalid event record') + } + + const decodedResult = decodeAbiParameters(this.args, `0x${input.slice(10)}`) + return this.toNamedArgs(decodedResult) as TFunctionArgs + } + + encode(...args: TFunctionArgs[keyof TFunctionArgs][]) { + return encodeFunctionData(this.sighash, this.args, args) + } + + decodeResult(output: string): TResult { + assertIsHex(output) + const decoded = decodeAbiParameters(this.result, output) + return decoded.length > 1 ? decoded : decoded[0] + } + + private toNamedArgs(values: any[]) { + return Object.fromEntries(this.args.map((arg, i) => { + const name = arg.name || `_${i}` + return [name, values[i]] as const + })) + } + + tryDecodeResult(output: string): TResult | undefined { + try { + return this.decodeResult(output) + } catch(err: any) { + return undefined + } + } +} + + +export function isFunctionResultDecodingError(val: unknown): val is Error & {data: string} { + if (!(val instanceof Error)) return false + let err = val as any + return err.code == 'CALL_EXCEPTION' + && typeof err.data == 'string' + && !err.errorArgs + && !err.errorName +} + + +export interface ChainContext { + _chain: Chain +} + + +export interface BlockContext { + _chain: Chain + block: Block +} + + +export interface Block { + height: number +} + + +export interface Chain { + client: { + call: (method: string, params?: unknown[]) => Promise + } +} + + +export class ContractBase { + private readonly _chain: Chain + private readonly blockHeight: number + readonly address: Hex + + constructor(ctx: BlockContext, address: string) + constructor(ctx: ChainContext, block: Block, address: string) + constructor(ctx: BlockContext, blockOrAddress: Block | string, address?: string) { + this._chain = ctx._chain + if (typeof blockOrAddress === 'string') { + this.blockHeight = ctx.block.height + this.address = blockOrAddress as Hex + } else { + if (address == null) { + throw new Error('missing contract address') + } + this.blockHeight = blockOrAddress.height + this.address = address as Hex + } + assertIsHex(this.address) + } + + async eth_call(func: Func, args: TFunctionArgs[keyof TFunctionArgs][]): Promise { + let data = func.encode(...args) + let result = await this._chain.client.call('eth_call', [ + {to: this.address, data}, + '0x'+this.blockHeight.toString(16) + ]) + return func.decodeResult(result) + } +} diff --git a/evm/evm-utils/src/index.ts b/evm/evm-utils/src/index.ts index f6ddb9981..5d069959f 100644 --- a/evm/evm-utils/src/index.ts +++ b/evm/evm-utils/src/index.ts @@ -1,3 +1,4 @@ export {decodeAbiParameters, hasDynamicChild} from "./decodeAbiParameters"; export {encodeAbiParameters, encodeFunctionData} from "./encodeAbiParameters"; +export * from "./abi.support"; export * from "./types"; diff --git a/evm/evm-utils/src/types.ts b/evm/evm-utils/src/types.ts index ccada31cb..c5852563b 100644 --- a/evm/evm-utils/src/types.ts +++ b/evm/evm-utils/src/types.ts @@ -1,6 +1,8 @@ export interface AbiParameter { - name?: string; - type: string; + name?: string + type: string, + components?: readonly AbiParameter[] + internalType?: string } export type Hex = `0x${string}` diff --git a/test/erc20-transfers/package.json b/test/erc20-transfers/package.json index 3741dbdf5..699e0803c 100644 --- a/test/erc20-transfers/package.json +++ b/test/erc20-transfers/package.json @@ -7,7 +7,6 @@ }, "dependencies": { "@subsquid/graphql-server": "^4.5.0", - "@subsquid/evm-utils": "1.0.0", "@subsquid/evm-processor": "^1.17.0", "@subsquid/typeorm-migration": "^1.3.0", "@subsquid/typeorm-store": "^1.2.6", @@ -16,6 +15,9 @@ "pg": "^8.11.3", "typeorm": "^0.3.17" }, + "peerDependencies": { + "@subsquid/evm-utils": "1.0.0" + }, "devDependencies": { "@subsquid/evm-typegen": "4.0.0", "@subsquid/typeorm-codegen": "^1.3.3", From 3f06e22469a8f1ab35825df40765d9904ce208c6 Mon Sep 17 00:00:00 2001 From: ivan Date: Tue, 5 Mar 2024 09:51:10 +0100 Subject: [PATCH 12/12] Remove unused file --- evm/evm-typegen/src/abi.support.ts | 222 ----------------------------- 1 file changed, 222 deletions(-) delete mode 100644 evm/evm-typegen/src/abi.support.ts diff --git a/evm/evm-typegen/src/abi.support.ts b/evm/evm-typegen/src/abi.support.ts deleted file mode 100644 index fd7b3d60e..000000000 --- a/evm/evm-typegen/src/abi.support.ts +++ /dev/null @@ -1,222 +0,0 @@ -import {decodeAbiParameters, hasDynamicChild, encodeFunctionData} from '@subsquid/evm-utils' - -type Hex = `0x${string}` - -export interface AbiParameter { - name?: string - type: string, - components?: AbiParameter[] - internalType?: string -} - -export interface EventRecord { - topics: string[] - data: string -} -export type LogRecord = EventRecord - -type EventType = { - type: 'tuple' - internalType?: string - indexed?: boolean - name: string - components: EventType[] -} | { - type: string - internalType?: string - indexed?: boolean - name: string -} - -function assertIsHex(val: unknown): asserts val is Hex { - if (typeof val !== 'string' || !val.startsWith('0x')) { - throw new Error('Not a hex string') - } -} - -export class LogEvent { - private indexedArgs: ((AbiParameter & {index: number}) | null)[] = []; - private nonIndexedArgs: (AbiParameter & {index: number})[] = []; - - constructor(public readonly topic: string, readonly types: readonly EventType[]) { - assertIsHex(topic) - let index = 0; - for (const type of types) { - if (!type.indexed) { - this.nonIndexedArgs.push({ - ...type, - index - }) - } else { - if (hasDynamicChild(type)) { - this.indexedArgs.push({ - ...type, - type: 'bytes32', - index - }) - } else { - this.indexedArgs.push({ - ...type, - index - }) - } - } - index++; - } - } - - is(rec: EventRecord): boolean { - return rec.topics[0] === this.topic - } - - decode(rec: EventRecord): TEventArgs { - if (!this.is(rec)) { - throw new Error('Invalid event record') - } - assertIsHex(rec.data) - const result: any = {} - const parsedData = decodeAbiParameters(this.nonIndexedArgs, rec.data) - for (let i = 0; i < parsedData.length; i++) { - if (this.nonIndexedArgs[i].name) { - result[this.nonIndexedArgs[i].name!] = parsedData[i] - } else { - result[`_${this.nonIndexedArgs[i].index}`] = parsedData[i] - } - } - rec.topics.slice(1).forEach((topic, i) => { - const type = this.indexedArgs[i] - if (type) { - assertIsHex(topic) - const [parsedData] = decodeAbiParameters([type], topic) - if (type.name) { - result[type.name] = parsedData - } else { - result[`_${type.index}`] = parsedData - } - } - }) - return result - } -} - -export interface FuncRecord { - sighash?: string - input: string -} - -export class Func { - public readonly sighash: Hex - constructor(sighash: string, private readonly args: AbiParameter[], private readonly result: AbiParameter[]) { - assertIsHex(sighash) - this.sighash = sighash - } - - is(rec: FuncRecord): boolean { - let sighash = rec.sighash ? rec.sighash : rec.input.slice(0, 10) - return sighash === this.sighash - } - - decode(input: string): TFunctionArgs - decode(rec: FuncRecord): TFunctionArgs - decode(inputOrRec: string | FuncRecord): TFunctionArgs { - const input = typeof inputOrRec === 'string' ? inputOrRec : inputOrRec.input - assertIsHex(input) - if (!this.is({input})) { - throw new Error('Invalid event record') - } - - const decodedResult = decodeAbiParameters(this.args, `0x${input.slice(10)}`) - return this.toNamedArgs(decodedResult) as TFunctionArgs - } - - encode(...args: TFunctionArgs[keyof TFunctionArgs][]) { - return encodeFunctionData(this.sighash, this.args, args) - } - - decodeResult(output: string): TResult { - assertIsHex(output) - const decoded = decodeAbiParameters(this.result, output) - return decoded.length > 1 ? decoded : decoded[0] - } - - private toNamedArgs(values: any[]) { - return Object.fromEntries(this.args.map((arg, i) => { - const name = arg.name || `_${i}` - return [name, values[i]] as const - })) - } - - tryDecodeResult(output: string): TResult | undefined { - try { - return this.decodeResult(output) - } catch(err: any) { - return undefined - } - } -} - - -export function isFunctionResultDecodingError(val: unknown): val is Error & {data: string} { - if (!(val instanceof Error)) return false - let err = val as any - return err.code == 'CALL_EXCEPTION' - && typeof err.data == 'string' - && !err.errorArgs - && !err.errorName -} - - -export interface ChainContext { - _chain: Chain -} - - -export interface BlockContext { - _chain: Chain - block: Block -} - - -export interface Block { - height: number -} - - -export interface Chain { - client: { - call: (method: string, params?: unknown[]) => Promise - } -} - - -export class ContractBase { - private readonly _chain: Chain - private readonly blockHeight: number - readonly address: Hex - - constructor(ctx: BlockContext, address: string) - constructor(ctx: ChainContext, block: Block, address: string) - constructor(ctx: BlockContext, blockOrAddress: Block | string, address?: string) { - this._chain = ctx._chain - if (typeof blockOrAddress === 'string') { - this.blockHeight = ctx.block.height - this.address = blockOrAddress as Hex - } else { - if (address == null) { - throw new Error('missing contract address') - } - this.blockHeight = blockOrAddress.height - this.address = address as Hex - } - assertIsHex(this.address) - } - - async eth_call(func: Func, args: TFunctionArgs[keyof TFunctionArgs][]): Promise { - let data = func.encode(...args) - let result = await this._chain.client.call('eth_call', [ - {to: this.address, data}, - '0x'+this.blockHeight.toString(16) - ]) - return func.decodeResult(result) - } -}