diff --git a/apps/api/src/api.controller.spec.ts b/apps/api/src/api.controller.spec.ts deleted file mode 100644 index c1d1929..0000000 --- a/apps/api/src/api.controller.spec.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { createMock } from "@golevelup/ts-jest"; -import { Test, TestingModule } from "@nestjs/testing"; -import { EvmProviderService } from "@packages/providers"; - -import { ApiController } from "./api.controller"; - -describe("ApiController", () => { - let apiController: ApiController; - let evmProvider: EvmProviderService; - - beforeEach(async () => { - const app: TestingModule = await Test.createTestingModule({ - controllers: [ApiController], - providers: [ - { - provide: EvmProviderService, - useValue: createMock(), - }, - ], - }).compile(); - - apiController = app.get(ApiController); - evmProvider = app.get(EvmProviderService); - }); - - describe("root", () => { - it("should return 50", async () => { - jest.spyOn(evmProvider, "getTvl").mockResolvedValue(50); - expect(await apiController.getTvl()).toBe(50); - }); - }); -}); diff --git a/apps/api/src/api.controller.ts b/apps/api/src/api.controller.ts deleted file mode 100644 index b885252..0000000 --- a/apps/api/src/api.controller.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Controller, Get } from "@nestjs/common"; -import { ApiTags } from "@nestjs/swagger"; -import { EvmProviderService } from "@packages/providers"; - -@ApiTags("api") -@Controller() -export class ApiController { - constructor(private readonly evmProvider: EvmProviderService) {} - - @Get() - getTvl() { - return this.evmProvider.getTvl(); - } -} diff --git a/apps/api/src/api.module.ts b/apps/api/src/api.module.ts index 09ad70c..80964a0 100644 --- a/apps/api/src/api.module.ts +++ b/apps/api/src/api.module.ts @@ -1,7 +1,5 @@ import { MiddlewareConsumer, Module, NestModule } from "@nestjs/common"; -import { ProvidersModule } from "@packages/providers"; -import { ApiController } from "./api.controller"; import { RequestLoggerMiddleware } from "./common/middleware/request.middleware"; import { MetricsController } from "./metrics/metrics.controller"; @@ -10,8 +8,8 @@ import { MetricsController } from "./metrics/metrics.controller"; * Here we import all required modules and register the controllers for the ZKchainHub API. */ @Module({ - imports: [ProvidersModule], - controllers: [ApiController, MetricsController], + imports: [], + controllers: [MetricsController], providers: [], }) export class ApiModule implements NestModule { diff --git a/apps/api/test/app.e2e-spec.ts b/apps/api/test/app.e2e-spec.ts deleted file mode 100644 index d2c2dc3..0000000 --- a/apps/api/test/app.e2e-spec.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { INestApplication } from "@nestjs/common"; -import { Test, TestingModule } from "@nestjs/testing"; -import request from "supertest"; - -import { ApiModule } from "./../src/api.module"; - -describe("ApiController (e2e)", () => { - let app: INestApplication; - - beforeEach(async () => { - const moduleFixture: TestingModule = await Test.createTestingModule({ - imports: [ApiModule], - }).compile(); - - app = moduleFixture.createNestApplication(); - await app.init(); - }); - - it("/ (GET)", () => { - return request(app.getHttpServer()).get("/").expect(200).expect("1"); - }); -}); diff --git a/libs/providers/src/evmProvider.service.spec.ts b/libs/providers/src/evmProvider.service.spec.ts deleted file mode 100644 index b918c37..0000000 --- a/libs/providers/src/evmProvider.service.spec.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Test, TestingModule } from "@nestjs/testing"; - -import { EvmProviderService } from "./evmProvider.service"; - -describe("EvmProviderService", () => { - let service: EvmProviderService; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [EvmProviderService], - }).compile(); - - service = module.get(EvmProviderService); - }); - - it("should be defined", () => { - expect(service).toBeDefined(); - }); - - it("should return the correct TVL", async () => { - const tvl = await service.getTvl(); - expect(tvl).toBe(1); - }); -}); diff --git a/libs/providers/src/evmProvider.service.ts b/libs/providers/src/evmProvider.service.ts deleted file mode 100644 index 6bd3ea3..0000000 --- a/libs/providers/src/evmProvider.service.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Injectable } from "@nestjs/common"; - -/** - * EvmProviderService provides methods to interact with an EVM-based blockchain. - */ -@Injectable() -export class EvmProviderService { - /** - * Retrieves the total value locked (TVL) from the EVM-based blockchain. - * @returns {Promise} The TVL value. - */ - async getTvl() { - return 1; - } -} diff --git a/libs/providers/src/exceptions/index.ts b/libs/providers/src/exceptions/index.ts new file mode 100644 index 0000000..d342f04 --- /dev/null +++ b/libs/providers/src/exceptions/index.ts @@ -0,0 +1 @@ +export * from "./invalidArgument.exception"; diff --git a/libs/providers/src/exceptions/invalidArgument.exception.ts b/libs/providers/src/exceptions/invalidArgument.exception.ts new file mode 100644 index 0000000..84b6087 --- /dev/null +++ b/libs/providers/src/exceptions/invalidArgument.exception.ts @@ -0,0 +1,6 @@ +export class InvalidArgumentException extends Error { + constructor(message: string) { + super(message); + this.name = "InvalidArgumentException"; + } +} diff --git a/libs/providers/src/index.ts b/libs/providers/src/index.ts index 917ae50..d484cbe 100644 --- a/libs/providers/src/index.ts +++ b/libs/providers/src/index.ts @@ -1,2 +1,2 @@ +export * from "./providers"; export * from "./providers.module"; -export * from "./evmProvider.service"; diff --git a/libs/providers/src/providers.module.ts b/libs/providers/src/providers.module.ts index 726bca1..d5eaeb8 100644 --- a/libs/providers/src/providers.module.ts +++ b/libs/providers/src/providers.module.ts @@ -1,6 +1,6 @@ import { Module } from "@nestjs/common"; -import { EvmProviderService } from "./evmProvider.service"; +import { EvmProviderService } from "./providers"; /** * Module for managing provider services. diff --git a/libs/providers/src/providers/evmProvider.service.spec.ts b/libs/providers/src/providers/evmProvider.service.spec.ts new file mode 100644 index 0000000..f70d5b1 --- /dev/null +++ b/libs/providers/src/providers/evmProvider.service.spec.ts @@ -0,0 +1,150 @@ +import { createMock } from "@golevelup/ts-jest"; +import { Test, TestingModule } from "@nestjs/testing"; +import { parseAbi } from "abitype"; +import * as viem from "viem"; +import { localhost } from "viem/chains"; + +import { EvmProviderService } from "./evmProvider.service"; + +const mockClient = createMock>(); + +jest.mock("viem", () => ({ + ...jest.requireActual("viem"), + createPublicClient: jest.fn().mockImplementation(() => mockClient), + http: jest.fn(), +})); + +describe("EvmProviderService", () => { + let viemProvider: EvmProviderService; + const testAbi = parseAbi([ + "function balanceOf(address owner) view returns (uint256)", + "function tokenURI(uint256 tokenId) pure returns (string)", + ]); + + beforeEach(async () => { + const app: TestingModule = await Test.createTestingModule({ + providers: [ + { + provide: EvmProviderService, + useFactory: () => { + const rpcUrl = "http://localhost:8545"; + const chain = localhost; + return new EvmProviderService(rpcUrl, chain); + }, + }, + ], + }).compile(); + + viemProvider = app.get(EvmProviderService); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + describe("getBalance", () => { + it("should return the balance of the specified address", async () => { + const address = "0x123456789"; + const expectedBalance = 100n; + jest.spyOn(mockClient, "getBalance").mockResolvedValue(expectedBalance); + + const balance = await viemProvider.getBalance(address); + + expect(balance).toBe(expectedBalance); + expect(mockClient.getBalance).toHaveBeenCalledWith({ address }); + }); + }); + + describe("getBlockNumber", () => { + it("should return the current block number", async () => { + const expectedBlockNumber = 1000n; + jest.spyOn(mockClient, "getBlockNumber").mockResolvedValue(expectedBlockNumber); + + const blockNumber = await viemProvider.getBlockNumber(); + + expect(blockNumber).toBe(expectedBlockNumber); + }); + }); + + describe("getGasPrice", () => { + it("should return the current gas price", async () => { + const expectedGasPrice = BigInt(100); + + // Mock the getGasPrice method of the Viem client + jest.spyOn(viemProvider["client"], "getGasPrice").mockResolvedValue(expectedGasPrice); + + const gasPrice = await viemProvider.getGasPrice(); + + expect(gasPrice).toBe(expectedGasPrice); + }); + }); + + describe("getStorageAt", () => { + it("should return the value of the storage slot at the given address and slot number", async () => { + const address = "0x123456789"; + const slot = 1; + const expectedValue = "0xabcdef"; + jest.spyOn(mockClient, "getStorageAt").mockResolvedValue(expectedValue); + + const value = await viemProvider.getStorageAt(address, slot); + + expect(value).toBe(expectedValue); + expect(mockClient.getStorageAt).toHaveBeenCalledWith({ address, slot: "0x1" }); + }); + + it("should throw an error if the slot is not a positive integer", async () => { + const address = "0x123456789"; + const slot = -1; + + await expect(viemProvider.getStorageAt(address, slot)).rejects.toThrowError( + "Slot must be a positive integer number. Received: -1", + ); + }); + }); + + describe("readContract", () => { + it("should call the readContract method of the Viem client with the correct arguments", async () => { + const contractAddress = "0x123456789"; + const abi = testAbi; + const functionName = "balanceOf"; + const expectedReturnValue = 5n; + + // Mock the readContract method of the Viem client + jest.spyOn(mockClient, "readContract").mockResolvedValue(expectedReturnValue); + + const returnValue = await viemProvider.readContract(contractAddress, abi, functionName); + + expect(returnValue).toBe(expectedReturnValue); + expect(mockClient.readContract).toHaveBeenCalledWith({ + address: contractAddress, + abi, + functionName, + }); + }); + + it("should call the readContract method of the Viem client with the correct arguments when args are provided", async () => { + const contractAddress = "0x123456789"; + const functionName = "tokenURI"; + const args = [1n] as const; + const expectedReturnValue = "tokenUri"; + + // Mock the readContract method of the Viem client + jest.spyOn(mockClient, "readContract").mockResolvedValue(expectedReturnValue); + + const returnValue = await viemProvider.readContract( + contractAddress, + testAbi, + functionName, + args, + ); + + expect(returnValue).toBe(expectedReturnValue); + expect(mockClient.readContract).toHaveBeenCalledWith({ + address: contractAddress, + abi: testAbi, + functionName, + args, + }); + }); + }); +}); diff --git a/libs/providers/src/providers/evmProvider.service.ts b/libs/providers/src/providers/evmProvider.service.ts new file mode 100644 index 0000000..f0132f2 --- /dev/null +++ b/libs/providers/src/providers/evmProvider.service.ts @@ -0,0 +1,111 @@ +import { Injectable } from "@nestjs/common"; +import { InvalidArgumentException } from "@packages/providers/exceptions"; +import { + Abi, + Address, + Chain, + ContractFunctionArgs, + ContractFunctionName, + ContractFunctionReturnType, + createPublicClient, + Hex, + http, + HttpTransport, + toHex, +} from "viem"; + +/** + * Acts as a wrapper around Viem library to provide methods to interact with an EVM-based blockchain. + */ +@Injectable() +export class EvmProviderService { + private client: ReturnType>; + + constructor( + rpcUrl: string, + readonly chain: Chain, + ) { + this.client = createPublicClient({ + chain, + transport: http(rpcUrl), + }); + } + + /** + * Retrieves the balance of the specified address. + * @param {Address} address The address for which to retrieve the balance. + * @returns {Promise} A Promise that resolves to the balance of the address. + */ + async getBalance(address: Address): Promise { + return this.client.getBalance({ address }); + } + + /** + * Retrieves the current block number. + * @returns {Promise} A Promise that resolves to the latest block number. + */ + async getBlockNumber(): Promise { + return this.client.getBlockNumber(); + } + + /** + * Retrieves the current estimated gas price on the chain. + * @returns {Promise} A Promise that resolves to the current gas price. + */ + async getGasPrice(): Promise { + return this.client.getGasPrice(); + } + + /** + * Retrieves the value from a storage slot at a given address. + * @param {Address} address The address of the contract. + * @param {number} slot The slot number to read. + * @returns {Promise} A Promise that resolves to the value of the storage slot. + * @throws {InvalidArgumentException} If the slot is not a positive integer. + */ + async getStorageAt(address: Address, slot: number): Promise { + if (slot <= 0 || !Number.isInteger(slot)) { + throw new InvalidArgumentException( + `Slot must be a positive integer number. Received: ${slot}`, + ); + } + + return this.client.getStorageAt({ + address, + slot: toHex(slot), + }); + } + + /** + * Reads a contract "pure" or "view" function with the specified arguments using readContract from Viem. + * @param {Address} contractAddress - The address of the contract. + * @param {TAbi} abi - The ABI (Application Binary Interface) of the contract. + * @param {TFunctionName} functionName - The name of the function to call. + * @param {TArgs} [args] - The arguments to pass to the function (optional). + * @returns A promise that resolves to the return value of the contract function. + */ + async readContract< + TAbi extends Abi, + TFunctionName extends ContractFunctionName = ContractFunctionName< + TAbi, + "pure" | "view" + >, + TArgs extends ContractFunctionArgs< + TAbi, + "pure" | "view", + TFunctionName + > = ContractFunctionArgs, + >( + contractAddress: Address, + abi: TAbi, + functionName: TFunctionName, + args?: TArgs, + ): Promise> { + return this.client.readContract({ + address: contractAddress, + abi, + functionName, + args, + }); + } +} diff --git a/libs/providers/src/providers/index.ts b/libs/providers/src/providers/index.ts new file mode 100644 index 0000000..680028e --- /dev/null +++ b/libs/providers/src/providers/index.ts @@ -0,0 +1 @@ +export * from "./evmProvider.service"; diff --git a/package.json b/package.json index e7377eb..9933d47 100644 --- a/package.json +++ b/package.json @@ -26,8 +26,10 @@ "@nestjs/core": "10.0.0", "@nestjs/platform-express": "10.0.0", "@nestjs/swagger": "7.4.0", + "abitype": "1.0.5", "reflect-metadata": "0.1.13", - "rxjs": "7.8.1" + "rxjs": "7.8.1", + "viem": "2.17.5" }, "devDependencies": { "@commitlint/config-conventional": "19.2.2", diff --git a/packages/errors/README.md b/packages/errors/README.md deleted file mode 100644 index 7c1eaa8..0000000 --- a/packages/errors/README.md +++ /dev/null @@ -1 +0,0 @@ -## Errors package diff --git a/packages/errors/__test__/example.test.ts b/packages/errors/__test__/example.test.ts deleted file mode 100644 index 59d7aac..0000000 --- a/packages/errors/__test__/example.test.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { describe, expect, test } from "vitest"; - -describe("exampleHandler", () => { - test("Sample exampleHandler test", () => { - expect(true).toBe(true); - }); -}); diff --git a/packages/errors/eslint.config.js b/packages/errors/eslint.config.js deleted file mode 100644 index 45fa763..0000000 --- a/packages/errors/eslint.config.js +++ /dev/null @@ -1,12 +0,0 @@ -import parentConfig from "@zkchainhub/eslint-config"; - -/** @type {import('eslint').Linter.FlatConfig[]} */ -export default [ - ...parentConfig, - { - files: ["src/**/*.ts"], - rules: { - "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "_+" }], - }, - }, -]; diff --git a/packages/errors/package.json b/packages/errors/package.json deleted file mode 100644 index d4b6032..0000000 --- a/packages/errors/package.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "@zkchainhub/errors", - "version": "0.0.0", - "private": true, - "license": "MIT", - "type": "module", - "types": "./dist/index.d.ts", - "main": "./dist/index.js", - "module": "./dist/index.js", - "scripts": { - "test": "vitest", - "build": "tsc -p tsconfig.json", - "lint": "eslint --fix . --max-warnings 0" - }, - "publishConfig": { - "access": "public" - }, - "devDependencies": { - "@zkchainhub/eslint-config": "workspace:*", - "@zkchainhub/test-config": "workspace:*", - "eslint": "8.56.0", - "vitest": "1.6.0" - } -} diff --git a/packages/errors/src/index.ts b/packages/errors/src/index.ts deleted file mode 100644 index 4a77c5a..0000000 --- a/packages/errors/src/index.ts +++ /dev/null @@ -1,15 +0,0 @@ -export abstract class BaseError extends Error { - override readonly name: string; - readonly description: string; - - constructor({ name, description }: { name: string; description: string }) { - super(description); - this.name = name; - this.description = description; - Object.setPrototypeOf(this, BaseError.prototype); - } - - public getDescription(): string { - return this.description; - } -} diff --git a/packages/errors/tsconfig.json b/packages/errors/tsconfig.json deleted file mode 100644 index f3224ab..0000000 --- a/packages/errors/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "@total-typescript/tsconfig/tsc/no-dom/library-monorepo", - "compilerOptions": { - "rootDir": "./src", - "outDir": "./dist" - }, - "include": ["./src/**/*.ts"], - "exclude": ["dist", "node_modules"] -} diff --git a/packages/errors/vitest.config.ts b/packages/errors/vitest.config.ts deleted file mode 100644 index 9eb83d2..0000000 --- a/packages/errors/vitest.config.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { defineConfig, mergeConfig } from "vitest/config"; - -import { baseConfig } from "@zkchainhub/test-config"; - -export default mergeConfig( - baseConfig, - defineConfig({ - test: { - exclude: ["coverage/*"], - }, - }), -); diff --git a/packages/lib/coingecko/README.md b/packages/lib/coingecko/README.md deleted file mode 100644 index a692238..0000000 --- a/packages/lib/coingecko/README.md +++ /dev/null @@ -1,3 +0,0 @@ -## Coingecko Package - -Adds coingecko API utilities. diff --git a/packages/lib/coingecko/__test__/example.test.ts b/packages/lib/coingecko/__test__/example.test.ts deleted file mode 100644 index 59d7aac..0000000 --- a/packages/lib/coingecko/__test__/example.test.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { describe, expect, test } from "vitest"; - -describe("exampleHandler", () => { - test("Sample exampleHandler test", () => { - expect(true).toBe(true); - }); -}); diff --git a/packages/lib/coingecko/eslint.config.js b/packages/lib/coingecko/eslint.config.js deleted file mode 100644 index 45fa763..0000000 --- a/packages/lib/coingecko/eslint.config.js +++ /dev/null @@ -1,12 +0,0 @@ -import parentConfig from "@zkchainhub/eslint-config"; - -/** @type {import('eslint').Linter.FlatConfig[]} */ -export default [ - ...parentConfig, - { - files: ["src/**/*.ts"], - rules: { - "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "_+" }], - }, - }, -]; diff --git a/packages/lib/coingecko/package.json b/packages/lib/coingecko/package.json deleted file mode 100644 index 42fe027..0000000 --- a/packages/lib/coingecko/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "@zkchainhub/coingecko", - "private": true, - "version": "0.0.0", - "type": "module", - "scripts": { - "build": "tsc -p tsconfig.json", - "test": "vitest", - "lint": "eslint --fix . --max-warnings 0", - "coverage": "vitest run --coverage", - "tsc": "tsc --noEmit" - }, - "devDependencies": { - "@zkchainhub/errors": "workspace:*", - "@zkchainhub/eslint-config": "workspace:*", - "@zkchainhub/test-config": "workspace:*", - "eslint": "8.56.0", - "vitest": "1.6.0" - } -} diff --git a/packages/lib/coingecko/src/errors.ts b/packages/lib/coingecko/src/errors.ts deleted file mode 100644 index bfcf756..0000000 --- a/packages/lib/coingecko/src/errors.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { BaseError } from "@zkchainhub/errors"; - -export class CoingeckoError extends BaseError { - constructor(description: string) { - super({ name: "CoingeckoError", description }); - } -} diff --git a/packages/lib/coingecko/src/index.ts b/packages/lib/coingecko/src/index.ts deleted file mode 100644 index ca29028..0000000 --- a/packages/lib/coingecko/src/index.ts +++ /dev/null @@ -1,27 +0,0 @@ -import type { AxiosInstance, CreateAxiosDefaults } from "axios"; -import axios from "axios"; - -export default class CoingeckoService { - private instance: AxiosInstance; - - constructor( - private url: string, - private apiKey: string, - ) { - const config: CreateAxiosDefaults = { - baseURL: url, - headers: { - "x-cg-demo-api-key": this.apiKey, - }, - }; - - this.instance = axios.create(config); - } - - get(): AxiosInstance { - if (!this.instance) { - throw new Error("Client not initialized"); - } - return this.instance; - } -} diff --git a/packages/lib/coingecko/tsconfig.json b/packages/lib/coingecko/tsconfig.json deleted file mode 100644 index 530239c..0000000 --- a/packages/lib/coingecko/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "@total-typescript/tsconfig/tsc/no-dom/library-monorepo", - "include": ["./src/**/*.ts"], - "exclude": ["dist", "node_modules"], - "compilerOptions": { - "rootDir": "./src", - "outDir": "./dist" - } -} diff --git a/packages/lib/coingecko/vitest.config.ts b/packages/lib/coingecko/vitest.config.ts deleted file mode 100644 index 9eb83d2..0000000 --- a/packages/lib/coingecko/vitest.config.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { defineConfig, mergeConfig } from "vitest/config"; - -import { baseConfig } from "@zkchainhub/test-config"; - -export default mergeConfig( - baseConfig, - defineConfig({ - test: { - exclude: ["coverage/*"], - }, - }), -); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cfe46a8..8bf6b23 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,12 +20,18 @@ importers: '@nestjs/swagger': specifier: 7.4.0 version: 7.4.0(@nestjs/common@10.0.0(reflect-metadata@0.1.13)(rxjs@7.8.1))(@nestjs/core@10.0.0(@nestjs/common@10.0.0(reflect-metadata@0.1.13)(rxjs@7.8.1))(@nestjs/platform-express@10.0.0)(reflect-metadata@0.1.13)(rxjs@7.8.1))(reflect-metadata@0.1.13) + abitype: + specifier: 1.0.5 + version: 1.0.5(typescript@5.1.3) reflect-metadata: specifier: 0.1.13 version: 0.1.13 rxjs: specifier: 7.8.1 version: 7.8.1 + viem: + specifier: 2.17.5 + version: 2.17.5(typescript@5.1.3) devDependencies: '@commitlint/config-conventional': specifier: 19.2.2 @@ -114,6 +120,9 @@ importers: packages: + '@adraffy/ens-normalize@1.10.0': + resolution: {integrity: sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==} + '@ampproject/remapping@2.3.0': resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} @@ -625,6 +634,13 @@ packages: '@nestjs/platform-express': optional: true + '@noble/curves@1.4.0': + resolution: {integrity: sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg==} + + '@noble/hashes@1.4.0': + resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} + engines: {node: '>= 16'} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -646,6 +662,15 @@ packages: resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + '@scure/base@1.1.7': + resolution: {integrity: sha512-PPNYBslrLNNUQ/Yad37MHYsNQtK67EhWb6WtSvNLLPo7SdVZgkUjD6Dg+5On7zNwmskf8OX7I7Nx5oN+MIWE0g==} + + '@scure/bip32@1.4.0': + resolution: {integrity: sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==} + + '@scure/bip39@1.3.0': + resolution: {integrity: sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==} + '@sinclair/typebox@0.27.8': resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} @@ -960,6 +985,17 @@ packages: resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} hasBin: true + abitype@1.0.5: + resolution: {integrity: sha512-YzDhti7cjlfaBhHutMaboYB21Ha3rXR9QTkNJFzYC4kC8YclaiwPBBBJY8ejFdu2wnJeZCVZSMlQJ7fi8S6hsw==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + accepts@1.3.8: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} @@ -1995,6 +2031,11 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + isows@1.0.4: + resolution: {integrity: sha512-hEzjY+x9u9hPmBom9IIAqdJCwNLax+xrPb51vEPpERoFlIxgmZcHzsT5jKG06nvInKOBGvReAVz80Umed5CczQ==} + peerDependencies: + ws: '*' + istanbul-lib-coverage@3.2.2: resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} engines: {node: '>=8'} @@ -3147,6 +3188,14 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} + viem@2.17.5: + resolution: {integrity: sha512-m0QIKQF1uqTFWAYNeAdhNUBFMaIs0Mwhu2VmZuXmBMkzJ0IL0ViblLH13JRwbDnOaY82KYzNhCARmfnLBWVdkA==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + walker@1.0.8: resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} @@ -3209,6 +3258,18 @@ packages: resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + ws@8.17.1: + resolution: {integrity: sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==} + 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 + xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} @@ -3251,6 +3312,8 @@ packages: snapshots: + '@adraffy/ens-normalize@1.10.0': {} + '@ampproject/remapping@2.3.0': dependencies: '@jridgewell/gen-mapping': 0.3.5 @@ -3967,6 +4030,12 @@ snapshots: optionalDependencies: '@nestjs/platform-express': 10.0.0(@nestjs/common@10.0.0(reflect-metadata@0.1.13)(rxjs@7.8.1))(@nestjs/core@10.0.0) + '@noble/curves@1.4.0': + dependencies: + '@noble/hashes': 1.4.0 + + '@noble/hashes@1.4.0': {} + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -3989,6 +4058,19 @@ snapshots: '@pkgr/core@0.1.1': {} + '@scure/base@1.1.7': {} + + '@scure/bip32@1.4.0': + dependencies: + '@noble/curves': 1.4.0 + '@noble/hashes': 1.4.0 + '@scure/base': 1.1.7 + + '@scure/bip39@1.3.0': + dependencies: + '@noble/hashes': 1.4.0 + '@scure/base': 1.1.7 + '@sinclair/typebox@0.27.8': {} '@sinonjs/commons@3.0.1': @@ -4365,6 +4447,10 @@ snapshots: jsonparse: 1.3.1 through: 2.3.8 + abitype@1.0.5(typescript@5.1.3): + optionalDependencies: + typescript: 5.1.3 + accepts@1.3.8: dependencies: mime-types: 2.1.35 @@ -5483,6 +5569,10 @@ snapshots: isexe@2.0.0: {} + isows@1.0.4(ws@8.17.1): + dependencies: + ws: 8.17.1 + istanbul-lib-coverage@3.2.2: {} istanbul-lib-instrument@5.2.1: @@ -6745,6 +6835,23 @@ snapshots: vary@1.1.2: {} + viem@2.17.5(typescript@5.1.3): + dependencies: + '@adraffy/ens-normalize': 1.10.0 + '@noble/curves': 1.4.0 + '@noble/hashes': 1.4.0 + '@scure/bip32': 1.4.0 + '@scure/bip39': 1.3.0 + abitype: 1.0.5(typescript@5.1.3) + isows: 1.0.4(ws@8.17.1) + ws: 8.17.1 + optionalDependencies: + typescript: 5.1.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + walker@1.0.8: dependencies: makeerror: 1.0.12 @@ -6829,6 +6936,8 @@ snapshots: imurmurhash: 0.1.4 signal-exit: 3.0.7 + ws@8.17.1: {} + xtend@4.0.2: {} y18n@5.0.8: {}