feat: relayer basic implementation (#53)

There are a lot of TODOs related to code quality, mostly happy path
assumptions, input sanitization, error handling and tests. Feature wise
it's missing the contract interaction (should be straight forward once
it's implemented in the SDK) and the sqlite database for request
tracking.
This commit is contained in:
bezze
2025-01-31 16:01:11 -03:00
committed by GitHub
parent 9a437ba628
commit cc4cd8f13f
37 changed files with 2929 additions and 50 deletions

View File

@@ -5,8 +5,9 @@ import tseslint from "typescript-eslint";
/** @type {import('eslint').Linter.Config[]} */
export default [
{files: ["**/*.{js,mjs,cjs,ts}"]},
{languageOptions: { globals: {...globals.browser, ...globals.node} }},
{ ignores: ["**/dist/**"] },
{ files: ["**/*.{js,mjs,cjs,ts}"] },
{ languageOptions: { globals: { ...globals.browser, ...globals.node } } },
pluginJs.configs.recommended,
...tseslint.configs.recommended,
];
];

View File

@@ -9,6 +9,16 @@
"workspaces": [
"packages/circuits",
"packages/contracts",
"packages/sdk"
]
"packages/sdk",
"packages/relayer"
],
"devDependencies": {
"prettier": "3.3.3",
"@typescript-eslint/eslint-plugin": "7.18.0",
"@typescript-eslint/parser": "7.18.0",
"eslint": "9.18.0",
"eslint-config-prettier": "9.1.0",
"eslint-plugin-prettier": "5.2.1",
"typescript-eslint": "8.20.0"
}
}

View File

@@ -0,0 +1,35 @@
# ts-turborepo-boilerplate: relayer package
Description of your package goes here.
## Setup
1. Install dependencies running `pnpm install`
## Available Scripts
Available scripts that can be run using `pnpm`:
| Script | Description |
| ------------- | ------------------------------------------------------- |
| `build` | Build library using tsc |
| `check-types` | Check types issues using tsc |
| `clean` | Remove `dist` folder |
| `lint` | Run ESLint to check for coding standards |
| `lint:fix` | Run linter and automatically fix code formatting issues |
| `format` | Check code formatting and style using Prettier |
| `format:fix` | Run formatter and automatically fix issues |
| `test` | Run tests using vitest |
| `test:cov` | Run tests with coverage report |
## Usage
Describe how to use your package here.
## API
Describe your package's API here.
## References
Add any relevant references here.

View File

@@ -0,0 +1,43 @@
{
"name": "@privacy-pool-core/relayer",
"version": "0.1.0",
"private": true,
"description": "A simple note relayer",
"license": "MIT",
"author": "Wonderland",
"type": "module",
"main": "./dist/src/index.js",
"types": "./dist/src/index.d.ts",
"directories": {
"src": "src"
},
"files": [
"dist/*",
"package.json",
"!**/*.tsbuildinfo"
],
"scripts": {
"build": "tsc -p tsconfig.build.json",
"start": "node ./dist/src/index.js",
"build:start": "yarn build && yarn start",
"start:ts": "node --no-warnings=ExperimentalWarning --loader ts-node/esm src/index.ts",
"check-types": "tsc --noEmit -p ./tsconfig.json",
"clean": "rm -rf dist/",
"format": "prettier --check \"{src,test}/**/*.{js,ts,json}\"",
"format:fix": "prettier --write \"{src,test}/**/*.{js,ts,json}\"",
"lint": "eslint \"{src,test}/**/*.{js,ts,json}\"",
"lint:fix": "eslint \"{src,test}/**/*.{js,ts,json}\" --fix",
"test": "vitest run --config vitest.config.ts --passWithNoTests",
"test:cov": "vitest run --config vitest.config.ts --coverage"
},
"dependencies": {
"ajv": "8.17.1",
"express": "4.21.2",
"sqlite": "5.1.1",
"sqlite3": "5.1.7",
"viem": "2.22.14"
},
"devDependencies": {
"@types/express": "5.0.0"
}
}

View File

@@ -0,0 +1,29 @@
import bodyParser from "body-parser";
import express, { NextFunction, Request, Response } from "express";
import {
errorHandlerMiddleware,
marshalResponseMiddleware,
notFoundMiddleware,
} from "./middlewares/index.js";
import { relayerRouter } from "./routes/index.js";
// Initialize the express app
const app = express();
// Middleware functions
const parseJsonMiddleware = bodyParser.json();
// Apply middleware and routes
app.use(parseJsonMiddleware);
app.use(marshalResponseMiddleware);
app.use("/ping", (req: Request, res: Response, next: NextFunction) => {
res.send("pong");
next();
});
app.use("/relayer", relayerRouter);
// Error and 404 handling
app.use([errorHandlerMiddleware, notFoundMiddleware]);
export { app };

View File

@@ -0,0 +1,76 @@
import path from "node:path";
import fs from "node:fs";
import { getAddress } from "viem";
import { ConfigError } from "./exceptions/base.exception.js";
const enum ConfigEnv {
FEE_RECEIVER_ADDRESS = "FEE_RECEIVER_ADDRESS",
PROVIDER_URL = "PROVIDER_URL",
SIGNER_PRIVATE_KEY = "SIGNER_PRIVATE_KEY",
FEE_BPS = "FEE_BPS",
SQLITE_DB_PATH = "SQLITE_DB_PATH",
}
type ConfigEnvString = `${ConfigEnv}`;
interface ConfigEnvVarChecker {
(varNameValue: string): void;
}
function checkConfigVar(
varName: ConfigEnvString,
checker?: ConfigEnvVarChecker,
) {
const varNameValue = process.env[varName];
if (varNameValue === undefined) {
throw ConfigError.default({
context: `Environment variable \`${varName}\` is undefined`,
});
}
if (checker) {
try {
checker(varNameValue);
} catch (error) {
console.error(error);
throw ConfigError.default({
context: `Environment variable \`${varName}\` has an incorrect format`,
});
}
}
return varNameValue;
}
function getFeeReceiverAddress(): string {
return checkConfigVar(ConfigEnv.FEE_RECEIVER_ADDRESS, (v) => getAddress(v));
}
function getProviderURL() {
// TODO: check provider url format
return checkConfigVar(ConfigEnv.PROVIDER_URL);
}
function getSignerPrivateKey() {
// TODO: check pk format
return checkConfigVar(ConfigEnv.SIGNER_PRIVATE_KEY);
}
function getFeeBps() {
// TODO: check feeBPS format
return checkConfigVar(ConfigEnv.FEE_BPS);
}
function getSqliteDbPath() {
// check path exists of warn of new one
return checkConfigVar(ConfigEnv.SQLITE_DB_PATH, (v) => {
const dbPath = path.resolve(v);
if (!fs.existsSync(v)) {
console.log("Creating new DB at", dbPath);
}
});
}
export const FEE_RECEIVER_ADDRESS = getFeeReceiverAddress();
export const PROVIDER_URL = getProviderURL();
export const SIGNER_PRIVATE_KEY = getSignerPrivateKey();
export const FEE_BPS = getFeeBps();
export const SQLITE_DB_PATH = getSqliteDbPath();

View File

@@ -0,0 +1,113 @@
/**
* Unified error codes for the Relayer.
*/
export enum ErrorCode {
// Base errors
UNKNOWN = "UNKNOWN",
INVALID_INPUT = "INVALID_INPUT",
// Config errors
INVALID_CONFIG = "INVALID_CONFIG",
// Proof errors
INVALID_PROOF = "INVALID_PROOF",
// Contract errors
CONTRACT_ERROR = "CONTRACT_ERROR",
}
/**
* Base error class for the Relayer.
* All other error classes should extend this.
*/
export class RelayerError extends Error {
constructor(
message: string,
public readonly code: ErrorCode = ErrorCode.UNKNOWN,
public readonly details?: Record<string, unknown>,
) {
super(message);
this.name = this.constructor.name;
// Maintains proper stack trace
Error.captureStackTrace(this, this.constructor);
}
/**
* Creates a JSON representation of the error.
*/
public toJSON(): Record<string, unknown> {
return {
name: this.name,
message: this.message,
code: this.code,
details: this.details,
};
}
}
export class ValidationError extends RelayerError {
constructor(
message: string,
code: ErrorCode = ErrorCode.INVALID_INPUT,
details?: Record<string, unknown>,
) {
super(message, code, details);
this.name = this.constructor.name;
}
/**
* Creates an error for input validation failures.
*/
public static invalidInput(
details?: Record<string, unknown>,
): ValidationError {
return new ValidationError(
"Failed to parse request payload",
ErrorCode.INVALID_INPUT,
details,
);
}
}
export class ZkError extends RelayerError {
constructor(
message: string,
code: ErrorCode = ErrorCode.INVALID_PROOF,
details?: Record<string, unknown>,
) {
super(message, code, details);
this.name = this.constructor.name;
}
/**
* Creates an error for input validation failures.
*/
public static invalidProof(details?: Record<string, unknown>): ZkError {
return new ZkError("Invalid proof", ErrorCode.INVALID_PROOF, details);
}
}
export class ConfigError extends RelayerError {
constructor(
message: string,
code: ErrorCode = ErrorCode.INVALID_CONFIG,
details?: Record<string, unknown>,
) {
super(message, code, details);
this.name = this.constructor.name;
}
/**
* Creates an error for input validation failures.
*/
public static default(details?: Record<string, unknown>): ConfigError {
return new ConfigError("Invalid config", ErrorCode.INVALID_CONFIG, details);
}
public static unknown(message: string): ConfigError {
return new ConfigError("Invalid config", ErrorCode.INVALID_CONFIG, {
context: `Unknown error for ${message}`,
});
}
}

View File

View File

@@ -0,0 +1 @@
// Add your external exports here

View File

@@ -0,0 +1,2 @@
export * from "./relayer/details.js";
export * from "./relayer/request.js";

View File

@@ -0,0 +1,21 @@
import { NextFunction, Request, Response } from "express";
import { DetailsMarshall } from "../../types.js";
import { getAddress } from "viem/utils";
import { FEE_BPS, FEE_RECEIVER_ADDRESS } from "../../config.js";
export function relayerDetailsHandler(
req: Request,
res: Response,
next: NextFunction,
) {
const feeBPS = BigInt(FEE_BPS);
const feeReceiverAddress = getAddress(FEE_RECEIVER_ADDRESS);
res
.status(200)
.json(
res.locals.marshalResponse(
new DetailsMarshall(feeBPS, feeReceiverAddress),
),
);
next();
}

View File

@@ -0,0 +1,66 @@
import { Hash, WithdrawalPayload } from "@privacy-pool-core/sdk";
import { NextFunction, Request, Response } from "express";
import { getAddress } from "viem";
import { ValidationError } from "../../exceptions/base.exception.js";
import {
RelayerResponse,
RelayRequestBody,
} from "../../interfaces/relayer/request.js";
import { validateRelayRequestBody } from "../../schemes/relayer/request.scheme.js";
import { RequestMashall } from "../../types.js";
import { PrivacyPoolRelayer } from "../../services/index.js";
function relayRequestBodyToWithdrawalPayload(
body: RelayRequestBody,
): WithdrawalPayload {
const proof = { ...body.proof, protocol: "groth16", curve: "bn128" };
const publicSignals = body.publicSignals;
const withdrawal = {
procesooor: getAddress(body.withdrawal.procesooor),
scope: BigInt(body.withdrawal.scope) as Hash,
data: Uint8Array.from(Buffer.from(body.withdrawal.data, "hex")),
};
const wp = {
proof: {
proof,
publicSignals,
},
withdrawal,
};
return wp;
}
function parseWithdrawal(body: Request["body"]): WithdrawalPayload {
if (validateRelayRequestBody(body)) {
try {
return relayRequestBodyToWithdrawalPayload(body);
} catch (error) {
console.error(error);
// TODO: extend this catch to return more details about the issue (viem error, node error, etc)
throw ValidationError.invalidInput({
message: "Can't parse payload into SDK structure",
});
}
} else {
throw ValidationError.invalidInput({ message: "Payload format error" });
}
}
export async function relayRequestHandler(
req: Request,
res: Response,
next: NextFunction,
) {
try {
const privacyPoolRelayer = new PrivacyPoolRelayer();
const withdrawalPayload = parseWithdrawal(req.body);
const requestResponse: RelayerResponse =
await privacyPoolRelayer.handleRequest(withdrawalPayload);
res
.status(200)
.json(res.locals.marshalResponse(new RequestMashall(requestResponse)));
next();
} catch (error) {
next(error);
}
}

View File

@@ -0,0 +1,18 @@
export * from "./external.js";
import { app } from "./app.js";
import { db } from "./providers/db.provider.js";
const port = 3000;
async function main() {
await db.init();
// Start the server
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
}
main().catch((e) => {
console.error(e);
process.exit(1);
});

View File

@@ -0,0 +1,43 @@
export interface ProofRelayerPayload {
pi_a: string[];
pi_b: string[][];
pi_c: string[];
}
/**
* Withdrawal
*/
export interface WithdrawalRelayerPayload {
/**
* Relayer address (0xAdDrEsS)
*/
procesooor: string;
/**
* Relayer scope (bigint as string)
*/
scope: string;
/**
* Tx data (hex encoded)
*/
data: string;
}
export interface RelayRequestBody {
withdrawal: WithdrawalRelayerPayload;
publicSignals: string[];
proof: ProofRelayerPayload;
}
export interface RelayerResponse {
success: boolean;
timestamp: number;
requestId: string;
txHash?: string;
error?: string;
}
export const enum RequestStatus {
BROADCASTED = "BROADCASTED",
FAILED = "FAILED",
RECEIVED = "RECEIVED",
}

View File

@@ -0,0 +1 @@
// Add your internal exports here

View File

@@ -0,0 +1,41 @@
import { NextFunction, Request, Response } from "express";
import { RelayerError } from "../exceptions/base.exception.js";
import { RelayerMarshall } from "../types.js";
export function marshalResponseMiddleware(
_req: Request,
res: Response,
next: NextFunction,
) {
res.locals.marshalResponse = (data: RelayerMarshall) => ({
success: true,
data: data.toJSON(),
});
next();
}
export function errorHandlerMiddleware(
err: Error,
_req: Request,
res: Response,
next: NextFunction,
) {
if (err instanceof RelayerError) {
// TODO: error handling based in RelayerError subtypes should be done by checking `err.name`
res.status(400).json({ error: err.toJSON() });
} else {
res.status(500).json({ error: "Internal Server Error" });
}
next();
}
export function notFoundMiddleware(
_req: Request,
res: Response,
next: NextFunction,
) {
if (!res.writableFinished) {
res.status(404).json({ error: "Route not found" });
}
next();
}

View File

@@ -0,0 +1,19 @@
import { NextFunction, Request, Response } from "express";
import { validateRelayRequestBody } from "../../schemes/relayer/request.scheme.js";
// Middleware to validate the relay-request body
export function validateRelayRequestMiddleware(
req: Request,
res: Response,
next: NextFunction,
) {
const isValid = validateRelayRequestBody(req.body);
if (!isValid) {
res.status(400).json({
error: "Validation Error",
details: validateRelayRequestBody.errors,
});
return;
}
next();
}

View File

@@ -0,0 +1,3 @@
import { SqliteDatabase } from "./sqlite.provider.js";
export const db = new SqliteDatabase();

View File

@@ -0,0 +1,3 @@
export { SdkProvider } from "./sdk.provider.js";
export { SqliteDatabase } from "./sqlite.provider.js";
export { db } from "./db.provider.js";

View File

@@ -0,0 +1,24 @@
import {
Circuits,
PrivacyPoolSDK,
WithdrawalPayload,
WithdrawalProof,
} from "@privacy-pool-core/sdk";
export class SdkProvider {
private sdk: PrivacyPoolSDK;
constructor() {
this.sdk = new PrivacyPoolSDK(new Circuits());
}
async verifyWithdrawal(withdrawalPayload: WithdrawalProof) {
return await this.sdk.verifyWithdrawal(withdrawalPayload);
}
async broadcastWithdrawal(
_withdrawalPayload: WithdrawalPayload, // eslint-disable-line @typescript-eslint/no-unused-vars
_brodacastDetails: { privateKey: string; rpcUrl: string }, // eslint-disable-line @typescript-eslint/no-unused-vars
): Promise<{ hash: string }> {
return {
hash: "0x",
};
}
}

View File

@@ -0,0 +1,92 @@
import sqlite3 from "sqlite3";
import { open, Database } from "sqlite";
import { WithdrawalPayload } from "@privacy-pool-core/sdk";
import path from "path";
import { SQLITE_DB_PATH } from "../config.js";
import { RelayerDatabase } from "../types/db.types.js";
import { RequestStatus } from "../interfaces/relayer/request.js";
function replacer(key: string, value: unknown) {
return typeof value === "bigint" ? { $bigint: value.toString() } : value;
}
// TODO
export class SqliteDatabase implements RelayerDatabase {
readonly dbPath: string;
private _initialized: boolean = false;
private db!: Database<sqlite3.Database, sqlite3.Statement>;
private createTableRequest = `
CREATE TABLE IF NOT EXISTS requests (
id UUID PRIMARY KEY,
timestamp INTEGER NOT NULL,
request JSON,
status TEXT CHECK(status IN ('BROADCASTED', 'FAILED', 'RECEIVED')) NOT NULL,
txHash TEXT,
error TEXT
);
`;
constructor() {
this.dbPath = path.resolve(SQLITE_DB_PATH);
}
get initialized(): boolean {
return this._initialized;
}
async init() {
try {
this.db = await open({
driver: sqlite3.Database,
filename: this.dbPath,
});
await this.db.run(this.createTableRequest);
} catch (error) {
console.log(error);
}
this._initialized = true;
console.log("sqlite db initialized");
}
async createNewRequest(
requestId: string,
timestamp: number,
req: WithdrawalPayload,
) {
const strigifiedPayload = JSON.stringify(req, replacer);
// Store initial request
await this.db.run(
`
INSERT INTO requests (id, timestamp, request, status)
VALUES (?, ?, ?, ?)
`,
[requestId, timestamp, strigifiedPayload, RequestStatus.RECEIVED],
);
}
async updateBroadcastedRequest(requestId: string, txHash: string) {
// Update database
await this.db.run(
`
UPDATE requests
SET status = ?, txHash = ?
WHERE id = ?
`,
[RequestStatus.BROADCASTED, txHash, requestId],
);
}
async updateFailedRequest(requestId: string, errorMessage: string) {
// Update database with error
await this.db.run(
`
UPDATE requests
SET status = ?, error = ?
WHERE id = ?
`,
[RequestStatus.FAILED, errorMessage, requestId],
);
}
}

View File

@@ -0,0 +1,17 @@
import { Router } from "express";
import {
relayerDetailsHandler,
relayRequestHandler,
} from "../handlers/index.js";
import { validateRelayRequestMiddleware } from "../middlewares/relayer/request.js";
// Router setup
const relayerRouter = Router();
relayerRouter.get("/details", [relayerDetailsHandler]);
relayerRouter.post("/request", [
validateRelayRequestMiddleware,
relayRequestHandler,
]);
export { relayerRouter };

View File

@@ -0,0 +1,48 @@
import { Ajv, JSONSchemaType } from "ajv";
import { RelayRequestBody } from "../../interfaces/relayer/request.js";
// AJV schema for validation
const ajv = new Ajv();
const relayRequestSchema: JSONSchemaType<RelayRequestBody> = {
type: "object",
properties: {
withdrawal: {
type: "object",
properties: {
procesooor: { type: "string" },
scope: { type: "string" },
data: { type: "string" },
},
required: ["procesooor", "scope", "data"],
},
publicSignals: {
type: "array",
items: { type: "string" },
minItems: 8,
maxItems: 8,
},
proof: {
type: "object",
properties: {
protocol: { type: "string" },
curve: { type: "string" },
pi_a: { type: "array", items: { type: "string" }, minItems: 1 },
pi_b: {
type: "array",
items: {
type: "array",
items: { type: "string" },
minItems: 1,
},
minItems: 1,
},
pi_c: { type: "array", items: { type: "string" }, minItems: 1 },
},
required: ["pi_a", "pi_b", "pi_c"],
},
},
required: ["withdrawal", "proof", "publicSignals"],
} as const;
export const validateRelayRequestBody = ajv.compile(relayRequestSchema);

View File

@@ -0,0 +1 @@
export { PrivacyPoolRelayer } from "./privacyPoolRelayer.service.js";

View File

@@ -0,0 +1,79 @@
import { WithdrawalPayload } from "@privacy-pool-core/sdk";
import { PROVIDER_URL, SIGNER_PRIVATE_KEY } from "../config.js";
import { RelayerError, ZkError } from "../exceptions/base.exception.js";
import { RelayerResponse } from "../interfaces/relayer/request.js";
import { db, SdkProvider } from "../providers/index.js";
import { RelayerDatabase } from "../types/db.types.js";
export class PrivacyPoolRelayer {
private db: RelayerDatabase;
private sdkService: SdkProvider;
private readonly rpcUrl: string = PROVIDER_URL;
private readonly privateKey: string = SIGNER_PRIVATE_KEY;
constructor() {
// Initialize database, provider, wallet, contract...
this.db = db;
this.sdkService = new SdkProvider();
}
async handleRequest(req: WithdrawalPayload): Promise<RelayerResponse> {
const requestId = crypto.randomUUID();
const timestamp = Date.now();
try {
// Store initial request
this.db.createNewRequest(requestId, timestamp, req);
// Verify commitment proof
const isValidWithdrawal = await this.verifyProof(req.proof);
if (!isValidWithdrawal) {
throw ZkError.invalidProof();
}
const response = await this.broadcastWithdrawal(req);
// Update database
await this.db.updateBroadcastedRequest(requestId, response.hash);
// Return success response
return {
success: true,
txHash: response.hash,
timestamp,
requestId,
};
} catch (error) {
let message: string;
if (error instanceof RelayerError) {
message = error.message;
} else {
message = JSON.stringify(error);
}
// Update database with error
await this.db.updateFailedRequest(requestId, message);
// Return error response
return {
success: false,
error: message,
timestamp,
requestId,
};
}
}
// Helper methods
private async verifyProof(
proof: WithdrawalPayload["proof"],
): Promise<boolean> {
return this.sdkService.verifyWithdrawal(proof);
}
private async broadcastWithdrawal(withdrawal: WithdrawalPayload) {
return this.sdkService.broadcastWithdrawal(withdrawal, {
privateKey: this.privateKey,
rpcUrl: this.rpcUrl,
});
}
}

View File

@@ -0,0 +1,30 @@
import { Address } from "viem/accounts";
import { RelayerResponse } from "./interfaces/relayer/request.js";
export abstract class RelayerMarshall {
abstract toJSON(): object;
}
export class DetailsMarshall extends RelayerMarshall {
constructor(
private feeBPS: bigint,
private feeReceiverAddress: Address,
) {
super();
}
override toJSON(): object {
return {
feeBPS: this.feeBPS.toString(),
feeReceiverAddress: this.feeReceiverAddress.toString(),
};
}
}
export class RequestMashall extends RelayerMarshall {
constructor(readonly response: RelayerResponse) {
super();
}
override toJSON(): object {
return this.response;
}
}

View File

@@ -0,0 +1,12 @@
import { WithdrawalPayload } from "@privacy-pool-core/sdk";
export interface RelayerDatabase {
initialized: boolean;
createNewRequest(
requestId: string,
timestamp: number,
req: WithdrawalPayload,
): Promise<void>;
updateBroadcastedRequest(requestId: string, txHash: string): Promise<void>;
updateFailedRequest(requestId: string, errorMessage: string): Promise<void>;
}

View File

@@ -0,0 +1,5 @@
import { describe, it } from "vitest";
describe("dummy", () => {
it.skip("dummy", () => {});
});

View File

@@ -0,0 +1,11 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"declarationMap": true,
"declaration": true,
"outDir": "dist"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "test"]
}

View File

@@ -0,0 +1,4 @@
{
"extends": "../../tsconfig.base.json",
"include": ["src/**/*"]
}

View File

@@ -0,0 +1,21 @@
import path from "path";
import { configDefaults, defineConfig } from "vitest/config";
export default defineConfig({
test: {
globals: true,
environment: "node",
include: ["test/**/*.spec.ts"],
exclude: ["node_modules", "dist"],
coverage: {
provider: "v8",
reporter: ["text", "json", "html"],
exclude: ["node_modules", "dist", "src/index.ts", ...configDefaults.exclude],
},
},
resolve: {
alias: {
"@": path.resolve(__dirname, "src"),
},
},
});

757
packages/relayer/yarn.lock Normal file
View File

@@ -0,0 +1,757 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@adraffy/ens-normalize@1.10.1":
version "1.10.1"
resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz#63430d04bd8c5e74f8d7d049338f1cd9d4f02069"
integrity sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==
"@adraffy/ens-normalize@^1.10.1":
version "1.11.0"
resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.11.0.tgz#42cc67c5baa407ac25059fcd7d405cc5ecdb0c33"
integrity sha512-/3DDPKHqqIqxUULp8yP4zODUY1i+2xvVWsv8A79xGWdCAG+8sb0hRh0Rk2QyOJUnnbyPUAZYcpBuRe3nS2OIUg==
"@noble/curves@1.2.0":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.2.0.tgz#92d7e12e4e49b23105a2555c6984d41733d65c35"
integrity sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==
dependencies:
"@noble/hashes" "1.3.2"
"@noble/curves@1.8.1", "@noble/curves@^1.6.0", "@noble/curves@~1.8.1":
version "1.8.1"
resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.8.1.tgz#19bc3970e205c99e4bdb1c64a4785706bce497ff"
integrity sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ==
dependencies:
"@noble/hashes" "1.7.1"
"@noble/hashes@1.3.2":
version "1.3.2"
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39"
integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==
"@noble/hashes@1.7.1", "@noble/hashes@^1.5.0", "@noble/hashes@~1.7.1":
version "1.7.1"
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.7.1.tgz#5738f6d765710921e7a751e00c20ae091ed8db0f"
integrity sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==
"@scure/base@~1.2.2", "@scure/base@~1.2.4":
version "1.2.4"
resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.2.4.tgz#002eb571a35d69bdb4c214d0995dff76a8dcd2a9"
integrity sha512-5Yy9czTO47mqz+/J8GM6GIId4umdCk1wc1q8rKERQulIoc8VP9pzDcghv10Tl2E7R96ZUx/PhND3ESYUQX8NuQ==
"@scure/bip32@1.6.2", "@scure/bip32@^1.5.0":
version "1.6.2"
resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.6.2.tgz#093caa94961619927659ed0e711a6e4bf35bffd0"
integrity sha512-t96EPDMbtGgtb7onKKqxRLfE5g05k7uHnHRM2xdE6BP/ZmxaLtPek4J4KfVn/90IQNrU1IOAqMgiDtUdtbe3nw==
dependencies:
"@noble/curves" "~1.8.1"
"@noble/hashes" "~1.7.1"
"@scure/base" "~1.2.2"
"@scure/bip39@1.5.4", "@scure/bip39@^1.4.0":
version "1.5.4"
resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.5.4.tgz#07fd920423aa671be4540d59bdd344cc1461db51"
integrity sha512-TFM4ni0vKvCfBpohoh+/lY05i9gRbSwXWngAsF4CABQxoaOHijxuaZ2R6cStDQ5CHtHO9aGJTr4ksVJASRRyMA==
dependencies:
"@noble/hashes" "~1.7.1"
"@scure/base" "~1.2.4"
"@types/body-parser@*":
version "1.19.5"
resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.5.tgz#04ce9a3b677dc8bd681a17da1ab9835dc9d3ede4"
integrity sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==
dependencies:
"@types/connect" "*"
"@types/node" "*"
"@types/connect@*":
version "3.4.38"
resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.38.tgz#5ba7f3bc4fbbdeaff8dded952e5ff2cc53f8d858"
integrity sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==
dependencies:
"@types/node" "*"
"@types/express-serve-static-core@^5.0.0":
version "5.0.5"
resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-5.0.5.tgz#f6a851c7fd512e5da087f6f20d29f44b162a6a95"
integrity sha512-GLZPrd9ckqEBFMcVM/qRFAP0Hg3qiVEojgEFsx/N/zKXsBzbGF6z5FBDpZ0+Xhp1xr+qRZYjfGr1cWHB9oFHSA==
dependencies:
"@types/node" "*"
"@types/qs" "*"
"@types/range-parser" "*"
"@types/send" "*"
"@types/express@5.0.0":
version "5.0.0"
resolved "https://registry.yarnpkg.com/@types/express/-/express-5.0.0.tgz#13a7d1f75295e90d19ed6e74cab3678488eaa96c"
integrity sha512-DvZriSMehGHL1ZNLzi6MidnsDhUZM/x2pRdDIKdwbUNqqwHxMlRdkxtn6/EPKyqKpHqTl/4nRZsRNLpZxZRpPQ==
dependencies:
"@types/body-parser" "*"
"@types/express-serve-static-core" "^5.0.0"
"@types/qs" "*"
"@types/serve-static" "*"
"@types/http-errors@*":
version "2.0.4"
resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.4.tgz#7eb47726c391b7345a6ec35ad7f4de469cf5ba4f"
integrity sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==
"@types/mime@^1":
version "1.3.5"
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690"
integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==
"@types/node@*":
version "22.10.10"
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.10.10.tgz#85fe89f8bf459dc57dfef1689bd5b52ad1af07e6"
integrity sha512-X47y/mPNzxviAGY5TcYPtYL8JsY3kAq2n8fMmKoRCxq/c4v4pyGNCzM2R6+M5/umG4ZfHuT+sgqDYqWc9rJ6ww==
dependencies:
undici-types "~6.20.0"
"@types/node@22.7.5":
version "22.7.5"
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.7.5.tgz#cfde981727a7ab3611a481510b473ae54442b92b"
integrity sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==
dependencies:
undici-types "~6.19.2"
"@types/qs@*":
version "6.9.18"
resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.18.tgz#877292caa91f7c1b213032b34626505b746624c2"
integrity sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA==
"@types/range-parser@*":
version "1.2.7"
resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.7.tgz#50ae4353eaaddc04044279812f52c8c65857dbcb"
integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==
"@types/send@*":
version "0.17.4"
resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.4.tgz#6619cd24e7270793702e4e6a4b958a9010cfc57a"
integrity sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==
dependencies:
"@types/mime" "^1"
"@types/node" "*"
"@types/serve-static@*":
version "1.15.7"
resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.7.tgz#22174bbd74fb97fe303109738e9b5c2f3064f714"
integrity sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==
dependencies:
"@types/http-errors" "*"
"@types/node" "*"
"@types/send" "*"
abitype@1.0.8, abitype@^1.0.6:
version "1.0.8"
resolved "https://registry.yarnpkg.com/abitype/-/abitype-1.0.8.tgz#3554f28b2e9d6e9f35eb59878193eabd1b9f46ba"
integrity sha512-ZeiI6h3GnW06uYDLx0etQtX/p8E24UaHHBj57RSjK7YBFe7iuVn07EDpOeP451D06sF27VOz9JJPlIKJmXgkEg==
accepts@~1.3.8:
version "1.3.8"
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e"
integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==
dependencies:
mime-types "~2.1.34"
negotiator "0.6.3"
aes-js@4.0.0-beta.5:
version "4.0.0-beta.5"
resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-4.0.0-beta.5.tgz#8d2452c52adedebc3a3e28465d858c11ca315873"
integrity sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==
ajv@8.17.1:
version "8.17.1"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.17.1.tgz#37d9a5c776af6bc92d7f4f9510eba4c0a60d11a6"
integrity sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==
dependencies:
fast-deep-equal "^3.1.3"
fast-uri "^3.0.1"
json-schema-traverse "^1.0.0"
require-from-string "^2.0.2"
array-flatten@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==
body-parser@1.20.3:
version "1.20.3"
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.3.tgz#1953431221c6fb5cd63c4b36d53fab0928e548c6"
integrity sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==
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.13.0"
raw-body "2.5.2"
type-is "~1.6.18"
unpipe "1.0.0"
bytes@3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5"
integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==
call-bind-apply-helpers@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz#32e5892e6361b29b0b545ba6f7763378daca2840"
integrity sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==
dependencies:
es-errors "^1.3.0"
function-bind "^1.1.2"
call-bound@^1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/call-bound/-/call-bound-1.0.3.tgz#41cfd032b593e39176a71533ab4f384aa04fd681"
integrity sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==
dependencies:
call-bind-apply-helpers "^1.0.1"
get-intrinsic "^1.2.6"
content-disposition@0.5.4:
version "0.5.4"
resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe"
integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==
dependencies:
safe-buffer "5.2.1"
content-type@~1.0.4, content-type@~1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918"
integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==
cookie-signature@1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==
cookie@0.7.1:
version "0.7.1"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.1.tgz#2f73c42142d5d5cf71310a74fc4ae61670e5dbc9"
integrity sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==
debug@2.6.9:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
dependencies:
ms "2.0.0"
depd@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==
destroy@1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015"
integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==
dunder-proto@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a"
integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==
dependencies:
call-bind-apply-helpers "^1.0.1"
es-errors "^1.3.0"
gopd "^1.2.0"
ee-first@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==
encodeurl@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==
encodeurl@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58"
integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==
es-define-property@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa"
integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==
es-errors@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f"
integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==
es-object-atoms@^1.0.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz#1c4f2c4837327597ce69d2ca190a7fdd172338c1"
integrity sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==
dependencies:
es-errors "^1.3.0"
escape-html@~1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==
etag@~1.8.1:
version "1.8.1"
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==
ethers@6.13.5:
version "6.13.5"
resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.13.5.tgz#8c1d6ac988ac08abc3c1d8fabbd4b8b602851ac4"
integrity sha512-+knKNieu5EKRThQJWwqaJ10a6HE9sSehGeqWN65//wE7j47ZpFhKAnHB/JJFibwwg61I/koxaPsXbXpD/skNOQ==
dependencies:
"@adraffy/ens-normalize" "1.10.1"
"@noble/curves" "1.2.0"
"@noble/hashes" "1.3.2"
"@types/node" "22.7.5"
aes-js "4.0.0-beta.5"
tslib "2.7.0"
ws "8.17.1"
eventemitter3@5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4"
integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==
express@4.21.2:
version "4.21.2"
resolved "https://registry.yarnpkg.com/express/-/express-4.21.2.tgz#cf250e48362174ead6cea4a566abef0162c1ec32"
integrity sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==
dependencies:
accepts "~1.3.8"
array-flatten "1.1.1"
body-parser "1.20.3"
content-disposition "0.5.4"
content-type "~1.0.4"
cookie "0.7.1"
cookie-signature "1.0.6"
debug "2.6.9"
depd "2.0.0"
encodeurl "~2.0.0"
escape-html "~1.0.3"
etag "~1.8.1"
finalhandler "1.3.1"
fresh "0.5.2"
http-errors "2.0.0"
merge-descriptors "1.0.3"
methods "~1.1.2"
on-finished "2.4.1"
parseurl "~1.3.3"
path-to-regexp "0.1.12"
proxy-addr "~2.0.7"
qs "6.13.0"
range-parser "~1.2.1"
safe-buffer "5.2.1"
send "0.19.0"
serve-static "1.16.2"
setprototypeof "1.2.0"
statuses "2.0.1"
type-is "~1.6.18"
utils-merge "1.0.1"
vary "~1.1.2"
fast-deep-equal@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
fast-uri@^3.0.1:
version "3.0.6"
resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.0.6.tgz#88f130b77cfaea2378d56bf970dea21257a68748"
integrity sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==
finalhandler@1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.3.1.tgz#0c575f1d1d324ddd1da35ad7ece3df7d19088019"
integrity sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==
dependencies:
debug "2.6.9"
encodeurl "~2.0.0"
escape-html "~1.0.3"
on-finished "2.4.1"
parseurl "~1.3.3"
statuses "2.0.1"
unpipe "~1.0.0"
forwarded@0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811"
integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==
fresh@0.5.2:
version "0.5.2"
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==
function-bind@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c"
integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
get-intrinsic@^1.2.5, get-intrinsic@^1.2.6:
version "1.2.7"
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.7.tgz#dcfcb33d3272e15f445d15124bc0a216189b9044"
integrity sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==
dependencies:
call-bind-apply-helpers "^1.0.1"
es-define-property "^1.0.1"
es-errors "^1.3.0"
es-object-atoms "^1.0.0"
function-bind "^1.1.2"
get-proto "^1.0.0"
gopd "^1.2.0"
has-symbols "^1.1.0"
hasown "^2.0.2"
math-intrinsics "^1.1.0"
get-proto@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1"
integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==
dependencies:
dunder-proto "^1.0.1"
es-object-atoms "^1.0.0"
gopd@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1"
integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==
has-symbols@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338"
integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==
hasown@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003"
integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==
dependencies:
function-bind "^1.1.2"
http-errors@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3"
integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==
dependencies:
depd "2.0.0"
inherits "2.0.4"
setprototypeof "1.2.0"
statuses "2.0.1"
toidentifier "1.0.1"
iconv-lite@0.4.24:
version "0.4.24"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
dependencies:
safer-buffer ">= 2.1.2 < 3"
inherits@2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
ipaddr.js@1.9.1:
version "1.9.1"
resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3"
integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==
isows@1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/isows/-/isows-1.0.6.tgz#0da29d706fa51551c663c627ace42769850f86e7"
integrity sha512-lPHCayd40oW98/I0uvgaHKWCSvkzY27LjWLbtzOm64yQ+G3Q5npjjbdppU65iZXkK1Zt+kH9pfegli0AYfwYYw==
json-schema-traverse@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2"
integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==
math-intrinsics@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9"
integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==
media-typer@0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==
merge-descriptors@1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.3.tgz#d80319a65f3c7935351e5cfdac8f9318504dbed5"
integrity sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==
methods@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==
mime-db@1.52.0:
version "1.52.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
mime-types@~2.1.24, mime-types@~2.1.34:
version "2.1.35"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
dependencies:
mime-db "1.52.0"
mime@1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==
ms@2.1.3:
version "2.1.3"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
negotiator@0.6.3:
version "0.6.3"
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd"
integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==
object-inspect@^1.13.3:
version "1.13.3"
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.3.tgz#f14c183de51130243d6d18ae149375ff50ea488a"
integrity sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==
on-finished@2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f"
integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==
dependencies:
ee-first "1.1.1"
ox@0.6.7:
version "0.6.7"
resolved "https://registry.yarnpkg.com/ox/-/ox-0.6.7.tgz#afd53f2ecef68b8526660e9d29dee6e6b599a832"
integrity sha512-17Gk/eFsFRAZ80p5eKqv89a57uXjd3NgIf1CaXojATPBuujVc/fQSVhBeAU9JCRB+k7J50WQAyWTxK19T9GgbA==
dependencies:
"@adraffy/ens-normalize" "^1.10.1"
"@noble/curves" "^1.6.0"
"@noble/hashes" "^1.5.0"
"@scure/bip32" "^1.5.0"
"@scure/bip39" "^1.4.0"
abitype "^1.0.6"
eventemitter3 "5.0.1"
parseurl@~1.3.3:
version "1.3.3"
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==
path-to-regexp@0.1.12:
version "0.1.12"
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.12.tgz#d5e1a12e478a976d432ef3c58d534b9923164bb7"
integrity sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==
proxy-addr@~2.0.7:
version "2.0.7"
resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025"
integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==
dependencies:
forwarded "0.2.0"
ipaddr.js "1.9.1"
qs@6.13.0:
version "6.13.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.0.tgz#6ca3bd58439f7e245655798997787b0d88a51906"
integrity sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==
dependencies:
side-channel "^1.0.6"
range-parser@~1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
raw-body@2.5.2:
version "2.5.2"
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a"
integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==
dependencies:
bytes "3.1.2"
http-errors "2.0.0"
iconv-lite "0.4.24"
unpipe "1.0.0"
require-from-string@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909"
integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
safe-buffer@5.2.1:
version "5.2.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
"safer-buffer@>= 2.1.2 < 3":
version "2.1.2"
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
send@0.19.0:
version "0.19.0"
resolved "https://registry.yarnpkg.com/send/-/send-0.19.0.tgz#bbc5a388c8ea6c048967049dbeac0e4a3f09d7f8"
integrity sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==
dependencies:
debug "2.6.9"
depd "2.0.0"
destroy "1.2.0"
encodeurl "~1.0.2"
escape-html "~1.0.3"
etag "~1.8.1"
fresh "0.5.2"
http-errors "2.0.0"
mime "1.6.0"
ms "2.1.3"
on-finished "2.4.1"
range-parser "~1.2.1"
statuses "2.0.1"
serve-static@1.16.2:
version "1.16.2"
resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.16.2.tgz#b6a5343da47f6bdd2673848bf45754941e803296"
integrity sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==
dependencies:
encodeurl "~2.0.0"
escape-html "~1.0.3"
parseurl "~1.3.3"
send "0.19.0"
setprototypeof@1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424"
integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==
side-channel-list@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/side-channel-list/-/side-channel-list-1.0.0.tgz#10cb5984263115d3b7a0e336591e290a830af8ad"
integrity sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==
dependencies:
es-errors "^1.3.0"
object-inspect "^1.13.3"
side-channel-map@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/side-channel-map/-/side-channel-map-1.0.1.tgz#d6bb6b37902c6fef5174e5f533fab4c732a26f42"
integrity sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==
dependencies:
call-bound "^1.0.2"
es-errors "^1.3.0"
get-intrinsic "^1.2.5"
object-inspect "^1.13.3"
side-channel-weakmap@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz#11dda19d5368e40ce9ec2bdc1fb0ecbc0790ecea"
integrity sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==
dependencies:
call-bound "^1.0.2"
es-errors "^1.3.0"
get-intrinsic "^1.2.5"
object-inspect "^1.13.3"
side-channel-map "^1.0.1"
side-channel@^1.0.6:
version "1.1.0"
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.1.0.tgz#c3fcff9c4da932784873335ec9765fa94ff66bc9"
integrity sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==
dependencies:
es-errors "^1.3.0"
object-inspect "^1.13.3"
side-channel-list "^1.0.0"
side-channel-map "^1.0.1"
side-channel-weakmap "^1.0.2"
statuses@2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63"
integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==
toidentifier@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35"
integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==
tslib@2.7.0:
version "2.7.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01"
integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==
type-is@~1.6.18:
version "1.6.18"
resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131"
integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==
dependencies:
media-typer "0.3.0"
mime-types "~2.1.24"
undici-types@~6.19.2:
version "6.19.8"
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02"
integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==
undici-types@~6.20.0:
version "6.20.0"
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.20.0.tgz#8171bf22c1f588d1554d55bf204bc624af388433"
integrity sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==
unpipe@1.0.0, unpipe@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==
utils-merge@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==
vary@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==
viem@2.22.14:
version "2.22.14"
resolved "https://registry.yarnpkg.com/viem/-/viem-2.22.14.tgz#acf1367704b29f0c00a58260702c9bee05c5dcbd"
integrity sha512-HfWnMmSPHNY+F3+I01ZKvIbwdn8qZUEhV/rzBi094F6gmqHA1KBXdF7P9po5/OYkvBjzxduUlLBgownyZkV+uA==
dependencies:
"@noble/curves" "1.8.1"
"@noble/hashes" "1.7.1"
"@scure/bip32" "1.6.2"
"@scure/bip39" "1.5.4"
abitype "1.0.8"
isows "1.0.6"
ox "0.6.7"
ws "8.18.0"
ws@8.17.1:
version "8.17.1"
resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b"
integrity sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==
ws@8.18.0:
version "8.18.0"
resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc"
integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==

View File

@@ -69,24 +69,17 @@
"@rollup/plugin-wasm": "6.2.2",
"@types/node": "20.3.1",
"@types/snarkjs": "0.7.9",
"@typescript-eslint/eslint-plugin": "7.18.0",
"@typescript-eslint/parser": "7.18.0",
"@vitest/coverage-v8": "2.0.5",
"commitlint": "19.4.1",
"eslint": "9.18.0",
"eslint-config-prettier": "9.1.0",
"eslint-plugin-prettier": "5.2.1",
"globals": "15.14.0",
"husky": "9.1.5",
"lint-staged": "15.2.10",
"memfs": "4.17.0",
"prettier": "3.3.3",
"rollup": "4.30.1",
"rollup-plugin-dts": "6.1.1",
"snarkjs": "0.7.5",
"sort-package-json": "2.10.1",
"typescript": "5.5.4",
"typescript-eslint": "8.20.0",
"vitest": "2.0.5"
}
}

View File

@@ -5,6 +5,7 @@ import { Commitment, CommitmentProof } from "../types/commitment.js";
import {
Withdrawal,
WithdrawalPayload,
WithdrawalProof,
WithdrawalProofInput,
} from "../types/withdrawal.js";
@@ -62,18 +63,19 @@ export class PrivacyPoolSDK {
public async proveWithdrawal(
commitment: Commitment,
input: WithdrawalProofInput,
): Promise<WithdrawalPayload> {
return this.withdrawalService.proveWithdrawal(commitment, input);
): Promise<WithdrawalProof> {
const withdrawalProof = await this.withdrawalService.proveWithdrawal(commitment, input);
return withdrawalProof;
}
/**
* Verifies a withdrawal proof.
*
* @param withdrawalPayload - The withdrawal payload to verify
* @param withdrawalProof - The withdrawal payload to verify
*/
public async verifyWithdrawal(
withdrawalPayload: WithdrawalPayload,
withdrawalProof: WithdrawalProof,
): Promise<boolean> {
return this.withdrawalService.verifyWithdrawal(withdrawalPayload);
return this.withdrawalService.verifyWithdrawal(withdrawalProof);
}
}

View File

@@ -8,9 +8,10 @@ import {
} from "../interfaces/circuits.interface.js";
import { Commitment } from "../types/commitment.js";
import {
Withdrawal,
WithdrawalPayload,
WithdrawalProofInput,
Withdrawal,
WithdrawalPayload,
WithdrawalProof,
WithdrawalProofInput,
} from "../types/withdrawal.js";
/**
@@ -31,7 +32,7 @@ export class WithdrawalService {
public async proveWithdrawal(
commitment: Commitment,
input: WithdrawalProofInput,
): Promise<WithdrawalPayload> {
): Promise<WithdrawalProof> {
try {
const inputSignals = this.prepareInputSignals(commitment, input);
@@ -63,14 +64,13 @@ export class WithdrawalService {
* @throws {ProofError} If verification fails
*/
public async verifyWithdrawal(
withdrawalPayload: WithdrawalPayload,
withdrawalPayload: WithdrawalProof,
): Promise<boolean> {
try {
const vkeyBin = await this.circuits.getVerificationKey(
CircuitName.Withdraw,
);
const vkey = JSON.parse(new TextDecoder("utf-8").decode(vkeyBin));
return await snarkjs.groth16.verify(
vkey,
withdrawalPayload.publicSignals,

View File

@@ -12,12 +12,17 @@ export interface Withdrawal {
readonly data: Uint8Array;
}
export interface WithdrawalProof {
readonly proof: Groth16Proof;
readonly publicSignals: PublicSignals;
}
/**
* Complete withdrawal payload including proof and public signals.
*/
export interface WithdrawalPayload {
readonly proof: Groth16Proof;
readonly publicSignals: PublicSignals;
readonly proof: WithdrawalProof;
readonly withdrawal: Withdrawal;
}
/**

1303
yarn.lock

File diff suppressed because it is too large Load Diff