mirror of
https://github.com/0xbow-io/privacy-pools-core.git
synced 2026-01-09 01:17:58 -05:00
feat: relayer data checks and sdk integration (#58)
The core functionality of the feature takes place at `packages/relayer/src/services/privacyPoolRelayer.service.ts` in the `validateWithdrawal` function. There we check in order: 1. Decode Withdrawal.data and check feeReceiver == CONFIGURED_FEE_RECEIVER && feeBPS == CONFIGURED_FEE_BPS 2. Hash (Withdrawal || Scope) and check hash == Proof.context 3. Verify proof with SDK.verifyProof(Proof) 4. Call Entrypoint.scopeToPool() to get asset pool 5. Call Pool.ASSET() to get withdrawn asset 6. Check proof.withdrawnAmount() >= CONFIGURED_MINIMUM_AMOUNT[withdrawn_asset] If everything is ok, we call the Entrypoint.relay() with the user's proof. I've added examples for the config files `env.example`, `withdraw_amount.example.json`. The first one are environment variables to be defined in the server's environment. The second one contains a mapping of the mimimum withdraw limits for the different supported assets. There's an env var that should contain a path to this file. Added a `Dockerfile` and a `docker-compose.yml` to the relayer to test it or use it in dev flows. The circuit artifacts are loaded as volumes, so before starting the docker-compose, you should run `yarn present` from the circuits package dir to group all the artifacts and make them easily accesible. Additionally added a small package in `/packages/relayer/test/integration/relay` that can be built and run to test the relayer.
This commit is contained in:
@@ -12,6 +12,9 @@
|
||||
"packages/sdk",
|
||||
"packages/relayer"
|
||||
],
|
||||
"scripts": {
|
||||
"docker:build:relayer": "docker build -f packages/relayer/Dockerfile -t privacy-pool/relayer ."
|
||||
},
|
||||
"devDependencies": {
|
||||
"@typescript-eslint/eslint-plugin": "7.18.0",
|
||||
"@typescript-eslint/parser": "7.18.0",
|
||||
@@ -19,6 +22,7 @@
|
||||
"eslint-config-prettier": "9.1.0",
|
||||
"eslint-plugin-prettier": "5.2.1",
|
||||
"prettier": "3.3.3",
|
||||
"typescript": "5.5.4",
|
||||
"typescript-eslint": "8.20.0"
|
||||
},
|
||||
"dependencies": {
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
"setup:withdraw": "npx circomkit setup withdraw ptau/powersOfTau28_hez_final_16.ptau",
|
||||
"setup:commitment": "npx circomkit setup commitment ptau/powersOfTau28_hez_final_16.ptau",
|
||||
"setup:merkle": "npx circomkit setup merkleTree ptau/powersOfTau28_hez_final_16.ptau",
|
||||
"present": "sh ./scripts/present.sh",
|
||||
"prove:withdraw": "npx circomkit prove withdraw default",
|
||||
"prove:commitment": "npx circomkit prove commitment default",
|
||||
"verify:withdraw": "npx circomkit verify withdraw default",
|
||||
|
||||
13
packages/circuits/scripts/present.sh
Normal file
13
packages/circuits/scripts/present.sh
Normal file
@@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
CIRCUITS=("merkleTree" "commitment" "withdraw")
|
||||
BUILD_DIR="build"
|
||||
DEST_DIR="artifacts"
|
||||
|
||||
mkdir -p "$DEST_DIR"
|
||||
for circuit in "${CIRCUITS[@]}"
|
||||
do
|
||||
cp "$BUILD_DIR/$circuit/groth16_pkey.zkey" "$DEST_DIR/${circuit}.zkey"
|
||||
cp "$BUILD_DIR/$circuit/groth16_vkey.json" "$DEST_DIR/${circuit}.vkey"
|
||||
cp "$BUILD_DIR/$circuit/${circuit}_js/${circuit}.wasm" "$DEST_DIR/"
|
||||
done
|
||||
1
packages/relayer/.gitignore
vendored
Normal file
1
packages/relayer/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
**/dist
|
||||
17
packages/relayer/Dockerfile
Normal file
17
packages/relayer/Dockerfile
Normal file
@@ -0,0 +1,17 @@
|
||||
FROM node:23 AS sdk-builder
|
||||
WORKDIR /build
|
||||
COPY ./package.json ./yarn.lock ./tsconfig.base.json .
|
||||
COPY ./packages/sdk/package.json ./packages/sdk/tsconfig.build.json ./packages/sdk/
|
||||
RUN yarn install
|
||||
COPY ./packages/sdk/configs/ ./packages/sdk/configs/
|
||||
COPY ./packages/sdk/src/ ./packages/sdk/src/
|
||||
RUN cd ./packages/sdk && yarn install && yarn build
|
||||
|
||||
FROM sdk-builder AS final
|
||||
COPY ./packages/relayer/package.json ./packages/relayer/tsconfig.build.json ./packages/relayer/
|
||||
RUN yarn install
|
||||
COPY ./packages/relayer/src/ ./packages/relayer/src/
|
||||
RUN cd ./packages/relayer && yarn install && yarn build
|
||||
WORKDIR packages/relayer
|
||||
EXPOSE 3000:3000
|
||||
ENTRYPOINT ["node", "./dist/src/index.js"]
|
||||
24
packages/relayer/docker-compose.yml
Normal file
24
packages/relayer/docker-compose.yml
Normal file
@@ -0,0 +1,24 @@
|
||||
services:
|
||||
relayer:
|
||||
network_mode: host
|
||||
user: 1000:1000
|
||||
build:
|
||||
context: ../../
|
||||
dockerfile: packages/relayer/Dockerfile
|
||||
environment:
|
||||
FEE_RECEIVER_ADDRESS: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
|
||||
PROVIDER_URL: http://0.0.0.0:8545
|
||||
FEE_BPS: 1000
|
||||
SIGNER_PRIVATE_KEY: 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
|
||||
SQLITE_DB_PATH: /tmp/pp_relayer.sqlite
|
||||
CONFIG_PATH: ./withdraw_amounts.example.json
|
||||
ENTRYPOINT_ADDRESS: 0xa513E6E4b8f2a923D98304ec87F64353C4D5C853
|
||||
POOL_ADDRESS: 0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6
|
||||
CHAIN: localhost
|
||||
CHAIN_ID: 31337
|
||||
volumes:
|
||||
- /tmp/pp_relayer.sqlite:/pp_relayer.sqlite
|
||||
- ./withdraw_amounts.example.json:/build/packages/relayer/withdraw_amounts.example.json
|
||||
- ../circuits/artifacts:/build/node_modules/@privacy-pool-core/sdk/dist/node/artifacts
|
||||
ports:
|
||||
- "3000:3000" # HOST:CONTAINER
|
||||
11
packages/relayer/env.example
Normal file
11
packages/relayer/env.example
Normal file
@@ -0,0 +1,11 @@
|
||||
# env example using anvil setup
|
||||
export FEE_RECEIVER_ADDRESS=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
|
||||
export PROVIDER_URL=http://127.0.0.1:8545
|
||||
export FEE_BPS=1000
|
||||
export SIGNER_PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
|
||||
export SQLITE_DB_PATH=/tmp/pp_relayer.sqlite
|
||||
export CONFIG_PATH=./withdraw_amounts.example.json
|
||||
export ENTRYPOINT_ADDRESS=0xa513E6E4b8f2a923D98304ec87F64353C4D5C853
|
||||
export POOL_ADDRESS=0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6
|
||||
export CHAIN=localhost
|
||||
export CHAIN_ID=31337
|
||||
@@ -31,7 +31,9 @@
|
||||
"test:cov": "vitest run --config vitest.config.ts --coverage"
|
||||
},
|
||||
"dependencies": {
|
||||
"@privacy-pool-core/sdk": "0.1.0",
|
||||
"ajv": "8.17.1",
|
||||
"body-parser": "1.20.3",
|
||||
"express": "4.21.2",
|
||||
"sqlite": "5.1.1",
|
||||
"sqlite3": "5.1.7",
|
||||
|
||||
@@ -17,10 +17,13 @@ const parseJsonMiddleware = bodyParser.json();
|
||||
app.use(parseJsonMiddleware);
|
||||
app.use(marshalResponseMiddleware);
|
||||
|
||||
// ping route
|
||||
app.use("/ping", (req: Request, res: Response, next: NextFunction) => {
|
||||
res.send("pong");
|
||||
next();
|
||||
});
|
||||
|
||||
// relayer route
|
||||
app.use("/relayer", relayerRouter);
|
||||
|
||||
// Error and 404 handling
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
import path from "node:path";
|
||||
import fs from "node:fs";
|
||||
import { getAddress } from "viem";
|
||||
import { Address, Chain, defineChain, getAddress, Hex, isHex } from "viem";
|
||||
import { ConfigError } from "./exceptions/base.exception.js";
|
||||
import { localhost, mainnet, sepolia } from "viem/chains";
|
||||
|
||||
const enum ConfigEnv {
|
||||
CONFIG_PATH = "CONFIG_PATH",
|
||||
FEE_RECEIVER_ADDRESS = "FEE_RECEIVER_ADDRESS",
|
||||
ENTRYPOINT_ADDRESS = "ENTRYPOINT_ADDRESS",
|
||||
PROVIDER_URL = "PROVIDER_URL",
|
||||
SIGNER_PRIVATE_KEY = "SIGNER_PRIVATE_KEY",
|
||||
FEE_BPS = "FEE_BPS",
|
||||
SQLITE_DB_PATH = "SQLITE_DB_PATH",
|
||||
CHAIN = "CHAIN",
|
||||
CHAIN_ID = "CHAIN_ID",
|
||||
}
|
||||
|
||||
type ConfigEnvString = `${ConfigEnv}`;
|
||||
@@ -31,17 +36,36 @@ function checkConfigVar(
|
||||
try {
|
||||
checker(varNameValue);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
throw ConfigError.default({
|
||||
context: `Environment variable \`${varName}\` has an incorrect format`,
|
||||
});
|
||||
if (error instanceof ConfigError) {
|
||||
throw error;
|
||||
} else {
|
||||
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 checkHex(v: string) {
|
||||
if (!isHex(v, { strict: true })) {
|
||||
throw ConfigError.default({
|
||||
context: `String ${v} is not a properly formatted hex string`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function getFeeReceiverAddress(): Address {
|
||||
return getAddress(
|
||||
checkConfigVar(ConfigEnv.FEE_RECEIVER_ADDRESS, (v) => getAddress(v)),
|
||||
);
|
||||
}
|
||||
|
||||
function getEntrypointAddress(): Address {
|
||||
return getAddress(
|
||||
checkConfigVar(ConfigEnv.ENTRYPOINT_ADDRESS, (v) => getAddress(v)),
|
||||
);
|
||||
}
|
||||
|
||||
function getProviderURL() {
|
||||
@@ -51,12 +75,17 @@ function getProviderURL() {
|
||||
|
||||
function getSignerPrivateKey() {
|
||||
// TODO: check pk format
|
||||
return checkConfigVar(ConfigEnv.SIGNER_PRIVATE_KEY);
|
||||
return checkConfigVar(ConfigEnv.SIGNER_PRIVATE_KEY, checkHex) as Hex;
|
||||
}
|
||||
|
||||
function getFeeBps() {
|
||||
// TODO: check feeBPS format
|
||||
return checkConfigVar(ConfigEnv.FEE_BPS);
|
||||
const feeBps = BigInt(checkConfigVar(ConfigEnv.FEE_BPS));
|
||||
// range validation
|
||||
if (feeBps > 10_000n || feeBps < 0) {
|
||||
throw ConfigError.feeBpsOutOfBounds();
|
||||
}
|
||||
return feeBps;
|
||||
}
|
||||
|
||||
function getSqliteDbPath() {
|
||||
@@ -69,8 +98,55 @@ function getSqliteDbPath() {
|
||||
});
|
||||
}
|
||||
|
||||
function getMinWithdrawAmounts(): Record<string, bigint> {
|
||||
const envVar = checkConfigVar(ConfigEnv.CONFIG_PATH, (v) => {
|
||||
const configPath = path.resolve(v);
|
||||
if (!fs.existsSync(v)) {
|
||||
throw ConfigError.default({
|
||||
context: `${configPath} does not exist.`,
|
||||
});
|
||||
}
|
||||
});
|
||||
const withdrawAmountsRaw = JSON.parse(
|
||||
fs.readFileSync(path.resolve(envVar), { encoding: "utf-8" }),
|
||||
);
|
||||
const withdrawAmounts: Record<string, bigint> = {};
|
||||
for (const entry of Object.entries(withdrawAmountsRaw)) {
|
||||
const [asset, amount] = entry;
|
||||
if (typeof amount === "string" || typeof amount === "number") {
|
||||
withdrawAmounts[asset] = BigInt(amount);
|
||||
} else {
|
||||
console.error(`Unable to parse asset ${asset} with value ${amount}`);
|
||||
}
|
||||
}
|
||||
return withdrawAmounts;
|
||||
}
|
||||
|
||||
function getChainConfig(): Chain {
|
||||
const chainName = checkConfigVar(ConfigEnv.CHAIN);
|
||||
const chainId = process.env[ConfigEnv.CHAIN_ID];
|
||||
return ((chainNameValue) => {
|
||||
switch (chainNameValue) {
|
||||
case "localhost":
|
||||
if (chainId) {
|
||||
return defineChain({ ...localhost, id: Number(chainId) });
|
||||
}
|
||||
return localhost;
|
||||
case "sepolia":
|
||||
return sepolia;
|
||||
case "mainnet":
|
||||
return mainnet;
|
||||
default:
|
||||
throw ConfigError.chainNotSupported();
|
||||
}
|
||||
})(chainName);
|
||||
}
|
||||
|
||||
export const FEE_RECEIVER_ADDRESS = getFeeReceiverAddress();
|
||||
export const ENTRYPOINT_ADDRESS = getEntrypointAddress();
|
||||
export const PROVIDER_URL = getProviderURL();
|
||||
export const SIGNER_PRIVATE_KEY = getSignerPrivateKey();
|
||||
export const FEE_BPS = getFeeBps();
|
||||
export const SQLITE_DB_PATH = getSqliteDbPath();
|
||||
export const WITHDRAW_AMOUNTS = getMinWithdrawAmounts();
|
||||
export const CHAIN = getChainConfig();
|
||||
|
||||
@@ -6,14 +6,27 @@ export enum ErrorCode {
|
||||
UNKNOWN = "UNKNOWN",
|
||||
INVALID_INPUT = "INVALID_INPUT",
|
||||
|
||||
// Withdrawal data assertions
|
||||
INVALID_DATA = "INVALID_DATA",
|
||||
INVALID_ABI = "INVALID_ABI",
|
||||
RECEIVER_MISMATCH = "RECEIVER_MISMATCH",
|
||||
FEE_MISMATCH = "FEE_MISMATCH",
|
||||
CONTEXT_MISMATCH = "CONTEXT_MISMATCH",
|
||||
INSUFFICIENT_WITHDRAWN_VALUE = "INSUFFICIENT_WITHDRAWN_VALUE",
|
||||
|
||||
// Config errors
|
||||
INVALID_CONFIG = "INVALID_CONFIG",
|
||||
FEE_BPS_OUT_OF_BOUNDS = "FEE_BPS_OUT_OF_BOUNDS",
|
||||
CHAIN_NOT_SUPPORTED = "CHAIN_NOT_SUPPORTED",
|
||||
|
||||
// Proof errors
|
||||
INVALID_PROOF = "INVALID_PROOF",
|
||||
|
||||
// Contract errors
|
||||
CONTRACT_ERROR = "CONTRACT_ERROR",
|
||||
|
||||
// SDK error. Wrapper for sdk's native errors
|
||||
SDK_ERROR = "SDK_ERROR",
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -24,7 +37,7 @@ export class RelayerError extends Error {
|
||||
constructor(
|
||||
message: string,
|
||||
public readonly code: ErrorCode = ErrorCode.UNKNOWN,
|
||||
public readonly details?: Record<string, unknown>,
|
||||
public readonly details?: Record<string, unknown> | string,
|
||||
) {
|
||||
super(message);
|
||||
this.name = this.constructor.name;
|
||||
@@ -44,6 +57,10 @@ export class RelayerError extends Error {
|
||||
details: this.details,
|
||||
};
|
||||
}
|
||||
|
||||
public static unknown(message?: string): RelayerError {
|
||||
return new RelayerError(message || "", ErrorCode.UNKNOWN);
|
||||
}
|
||||
}
|
||||
|
||||
export class ValidationError extends RelayerError {
|
||||
@@ -105,9 +122,95 @@ export class ConfigError extends RelayerError {
|
||||
return new ConfigError("Invalid config", ErrorCode.INVALID_CONFIG, details);
|
||||
}
|
||||
|
||||
public static unknown(message: string): ConfigError {
|
||||
public static feeBpsOutOfBounds(
|
||||
details?: Record<string, unknown>,
|
||||
): ConfigError {
|
||||
return new ConfigError(
|
||||
"Invalid config: FEE_BPS must be in range [0, 10_000]",
|
||||
ErrorCode.FEE_BPS_OUT_OF_BOUNDS,
|
||||
details,
|
||||
);
|
||||
}
|
||||
|
||||
public static chainNotSupported(
|
||||
details?: Record<string, unknown>,
|
||||
): ConfigError {
|
||||
return new ConfigError(
|
||||
"Invalid config: CHAIN must be one of `localhost`, `sepolia`, `mainnet`",
|
||||
ErrorCode.CHAIN_NOT_SUPPORTED,
|
||||
details,
|
||||
);
|
||||
}
|
||||
|
||||
public static override unknown(message: string): ConfigError {
|
||||
return new ConfigError("Invalid config", ErrorCode.INVALID_CONFIG, {
|
||||
context: `Unknown error for ${message}`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class WithdrawalValidationError extends RelayerError {
|
||||
constructor(
|
||||
message: string,
|
||||
code: ErrorCode = ErrorCode.INVALID_DATA,
|
||||
details?: Record<string, unknown> | string,
|
||||
) {
|
||||
super(message, code, details);
|
||||
this.name = this.constructor.name;
|
||||
}
|
||||
|
||||
public static invalidWithdrawalAbi(
|
||||
details?: Record<string, unknown>,
|
||||
): WithdrawalValidationError {
|
||||
return new WithdrawalValidationError(
|
||||
"Failed to parse withdrawal data",
|
||||
ErrorCode.INVALID_ABI,
|
||||
details,
|
||||
);
|
||||
}
|
||||
|
||||
public static feeReceiverMismatch(
|
||||
details: string,
|
||||
): WithdrawalValidationError {
|
||||
return new WithdrawalValidationError(
|
||||
"Fee receiver does not match relayer",
|
||||
ErrorCode.RECEIVER_MISMATCH,
|
||||
details,
|
||||
);
|
||||
}
|
||||
|
||||
public static feeMismatch(details: string) {
|
||||
return new WithdrawalValidationError(
|
||||
"Fee does not match relayer fee",
|
||||
ErrorCode.FEE_MISMATCH,
|
||||
details,
|
||||
);
|
||||
}
|
||||
|
||||
public static contextMismatch(details: string) {
|
||||
return new WithdrawalValidationError(
|
||||
"Context does not match public signal",
|
||||
ErrorCode.CONTEXT_MISMATCH,
|
||||
details,
|
||||
);
|
||||
}
|
||||
|
||||
public static withdrawnValueTooSmall(details: string) {
|
||||
return new WithdrawalValidationError(
|
||||
"Withdrawn value is too small",
|
||||
ErrorCode.INSUFFICIENT_WITHDRAWN_VALUE,
|
||||
details,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export class SdkError extends RelayerError {
|
||||
constructor(message: string, details?: Record<string, unknown> | string) {
|
||||
super(message, ErrorCode.SDK_ERROR, details);
|
||||
this.name = this.constructor.name;
|
||||
}
|
||||
|
||||
public static scopeDataError(error: Error) {
|
||||
return new SdkError(`SdkError: SCOPE_DATA_ERROR ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
// Add your external exports here
|
||||
@@ -1,24 +1,31 @@
|
||||
import { Hash, WithdrawalPayload } from "@privacy-pool-core/sdk";
|
||||
import { Hash } 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,
|
||||
WithdrawalPayload,
|
||||
} from "../../interfaces/relayer/request.js";
|
||||
import { validateRelayRequestBody } from "../../schemes/relayer/request.scheme.js";
|
||||
import { RequestMashall } from "../../types.js";
|
||||
import { PrivacyPoolRelayer } from "../../services/index.js";
|
||||
import { RequestMashall } from "../../types.js";
|
||||
|
||||
/**
|
||||
* Converts a RelayRequestBody into a WithdrawalPayload.
|
||||
*
|
||||
* @param {RelayRequestBody} body - The relay request body containing proof and withdrawal details.
|
||||
* @returns {WithdrawalPayload} - The formatted withdrawal payload.
|
||||
*/
|
||||
function relayRequestBodyToWithdrawalPayload(
|
||||
body: RelayRequestBody,
|
||||
): WithdrawalPayload {
|
||||
const proof = { ...body.proof, protocol: "groth16", curve: "bn128" };
|
||||
const publicSignals = body.publicSignals;
|
||||
const withdrawal = {
|
||||
procesooor: getAddress(body.withdrawal.procesooor),
|
||||
processooor: getAddress(body.withdrawal.processooor),
|
||||
scope: BigInt(body.withdrawal.scope) as Hash,
|
||||
data: Uint8Array.from(Buffer.from(body.withdrawal.data, "hex")),
|
||||
data: body.withdrawal.data as `0x{string}`,
|
||||
};
|
||||
const wp = {
|
||||
proof: {
|
||||
@@ -30,6 +37,13 @@ function relayRequestBodyToWithdrawalPayload(
|
||||
return wp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses and validates the withdrawal request body.
|
||||
*
|
||||
* @param {Request["body"]} body - The request body to parse.
|
||||
* @returns {WithdrawalPayload} - The validated and formatted withdrawal payload.
|
||||
* @throws {ValidationError} - If the input data is invalid.
|
||||
*/
|
||||
function parseWithdrawal(body: Request["body"]): WithdrawalPayload {
|
||||
if (validateRelayRequestBody(body)) {
|
||||
try {
|
||||
@@ -46,6 +60,13 @@ function parseWithdrawal(body: Request["body"]): WithdrawalPayload {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Express route handler for relaying requests.
|
||||
*
|
||||
* @param {Request} req - The incoming HTTP request.
|
||||
* @param {Response} res - The HTTP response object.
|
||||
* @param {NextFunction} next - The next middleware function.
|
||||
*/
|
||||
export async function relayRequestHandler(
|
||||
req: Request,
|
||||
res: Response,
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
export * from "./external.js";
|
||||
import { app } from "./app.js";
|
||||
import { db } from "./providers/db.provider.js";
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
import { Withdrawal, WithdrawalProof } from "@privacy-pool-core/sdk";
|
||||
|
||||
/**
|
||||
* Represents the proof payload for a relayer request.
|
||||
*/
|
||||
export interface ProofRelayerPayload {
|
||||
pi_a: string[];
|
||||
pi_b: string[][];
|
||||
@@ -5,39 +10,83 @@ export interface ProofRelayerPayload {
|
||||
}
|
||||
|
||||
/**
|
||||
* Withdrawal
|
||||
* Represents the public signals for a withdrawal operation.
|
||||
*/
|
||||
export interface WithdrawPublicSignals {
|
||||
/** Hash of new commitment */
|
||||
newCommitmentHash: bigint;
|
||||
/** Hash of the existing commitment nullifier */
|
||||
existingNullifierHash: bigint;
|
||||
/** Withdrawn value */
|
||||
withdrawnValue: bigint;
|
||||
/** State root */
|
||||
stateRoot: bigint;
|
||||
/** Depth of the state tree */
|
||||
stateTreeDepth: bigint;
|
||||
/** ASP root */
|
||||
ASPRoot: bigint;
|
||||
/** Depth of the ASP tree */
|
||||
ASPTreeDepth: bigint;
|
||||
/** Context value */
|
||||
context: bigint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the payload for a withdrawal relayer request.
|
||||
*/
|
||||
export interface WithdrawalRelayerPayload {
|
||||
/**
|
||||
* Relayer address (0xAdDrEsS)
|
||||
*/
|
||||
procesooor: string;
|
||||
/**
|
||||
* Relayer scope (bigint as string)
|
||||
*/
|
||||
/** Relayer address (0xAdDrEsS) */
|
||||
processooor: string;
|
||||
/** Relayer scope (bigint as string) */
|
||||
scope: string;
|
||||
/**
|
||||
* Tx data (hex encoded)
|
||||
*/
|
||||
/** Transaction data (hex encoded) */
|
||||
data: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the request body for a relayer operation.
|
||||
*/
|
||||
export interface RelayRequestBody {
|
||||
/** Withdrawal details */
|
||||
withdrawal: WithdrawalRelayerPayload;
|
||||
/** Public signals as string array */
|
||||
publicSignals: string[];
|
||||
/** Proof details */
|
||||
proof: ProofRelayerPayload;
|
||||
}
|
||||
|
||||
/**
|
||||
* Complete withdrawal payload including proof and public signals.
|
||||
*/
|
||||
export interface WithdrawalPayload {
|
||||
readonly proof: WithdrawalProof;
|
||||
readonly withdrawal: Withdrawal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the response from a relayer operation.
|
||||
*/
|
||||
export interface RelayerResponse {
|
||||
/** Indicates if the request was successful */
|
||||
success: boolean;
|
||||
/** Timestamp of the response */
|
||||
timestamp: number;
|
||||
/** Unique request identifier (UUID) */
|
||||
requestId: string;
|
||||
/** Optional transaction hash */
|
||||
txHash?: string;
|
||||
/** Optional error message */
|
||||
error?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum representing the possible statuses of a relayer request.
|
||||
*/
|
||||
export const enum RequestStatus {
|
||||
BROADCASTED = "BROADCASTED",
|
||||
FAILED = "FAILED",
|
||||
/** Request has been received */
|
||||
RECEIVED = "RECEIVED",
|
||||
/** Request has been broadcasted */
|
||||
BROADCASTED = "BROADCASTED",
|
||||
/** Request has failed */
|
||||
FAILED = "FAILED",
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
// Add your internal exports here
|
||||
64
packages/relayer/src/middlewares/base.ts
Normal file
64
packages/relayer/src/middlewares/base.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import { NextFunction, Request, Response } from "express";
|
||||
import { RelayerError } from "../exceptions/base.exception.js";
|
||||
import { RelayerMarshall } from "../types.js";
|
||||
|
||||
/**
|
||||
* Middleware to attach a marshaller function to the response locals.
|
||||
* This function formats the response data in a standardized way.
|
||||
*
|
||||
* @param {Request} _req - Express request object (unused).
|
||||
* @param {Response} res - Express response object.
|
||||
* @param {NextFunction} next - Express next function.
|
||||
*/
|
||||
export function marshalResponseMiddleware(
|
||||
_req: Request,
|
||||
res: Response,
|
||||
next: NextFunction,
|
||||
) {
|
||||
res.locals.marshalResponse = (data: RelayerMarshall) => ({
|
||||
...data.toJSON(),
|
||||
});
|
||||
next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Middleware to handle errors and send appropriate responses.
|
||||
*
|
||||
* @param {Error} err - The error object.
|
||||
* @param {Request} _req - Express request object (unused).
|
||||
* @param {Response} res - Express response object.
|
||||
* @param {NextFunction} next - Express next function.
|
||||
*/
|
||||
export function errorHandlerMiddleware(
|
||||
err: Error,
|
||||
_req: Request,
|
||||
res: Response,
|
||||
next: NextFunction,
|
||||
) {
|
||||
if (err instanceof RelayerError) {
|
||||
// TODO: error handling based on 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();
|
||||
}
|
||||
|
||||
/**
|
||||
* Middleware to handle 404 (Not Found) responses.
|
||||
* If no response has been sent, it returns a 404 error.
|
||||
*
|
||||
* @param {Request} _req - Express request object (unused).
|
||||
* @param {Response} res - Express response object.
|
||||
* @param {NextFunction} next - Express next function.
|
||||
*/
|
||||
export function notFoundMiddleware(
|
||||
_req: Request,
|
||||
res: Response,
|
||||
next: NextFunction,
|
||||
) {
|
||||
if (!res.writableFinished) {
|
||||
res.status(404).json({ error: "Route not found" });
|
||||
}
|
||||
next();
|
||||
}
|
||||
@@ -1,41 +1,2 @@
|
||||
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();
|
||||
}
|
||||
export * from "./base.js";
|
||||
export * from "./relayer/request.js";
|
||||
|
||||
@@ -1,24 +1,100 @@
|
||||
import {
|
||||
Circuits,
|
||||
PrivacyPoolSDK,
|
||||
WithdrawalPayload,
|
||||
WithdrawalProof,
|
||||
} from "@privacy-pool-core/sdk";
|
||||
/**
|
||||
* Provides an interface to interact with the Privacy Pool SDK.
|
||||
*/
|
||||
|
||||
import {
|
||||
calculateContext,
|
||||
Circuits,
|
||||
ContractInteractionsService,
|
||||
PrivacyPoolSDK,
|
||||
Withdrawal,
|
||||
WithdrawalProof,
|
||||
SDKError,
|
||||
} from "@privacy-pool-core/sdk";
|
||||
import { Address } from "viem";
|
||||
import {
|
||||
CHAIN,
|
||||
ENTRYPOINT_ADDRESS,
|
||||
PROVIDER_URL,
|
||||
SIGNER_PRIVATE_KEY,
|
||||
} from "../config.js";
|
||||
import { WithdrawalPayload } from "../interfaces/relayer/request.js";
|
||||
import { RelayerError, SdkError } from "../exceptions/base.exception.js";
|
||||
|
||||
/**
|
||||
* Class representing the SDK provider for interacting with Privacy Pool SDK.
|
||||
*/
|
||||
export class SdkProvider {
|
||||
/** Instance of the PrivacyPoolSDK. */
|
||||
private sdk: PrivacyPoolSDK;
|
||||
private contracts: ContractInteractionsService;
|
||||
|
||||
/**
|
||||
* Initializes a new instance of the SDK provider.
|
||||
*/
|
||||
constructor() {
|
||||
this.sdk = new PrivacyPoolSDK(new Circuits());
|
||||
this.contracts = this.sdk.createContractInstance(
|
||||
PROVIDER_URL,
|
||||
CHAIN,
|
||||
ENTRYPOINT_ADDRESS,
|
||||
SIGNER_PRIVATE_KEY,
|
||||
);
|
||||
}
|
||||
async verifyWithdrawal(withdrawalPayload: WithdrawalProof) {
|
||||
|
||||
/**
|
||||
* Verifies a withdrawal proof.
|
||||
*
|
||||
* @param {WithdrawalProof} withdrawalPayload - The withdrawal proof payload.
|
||||
* @returns {Promise<boolean>} - A promise resolving to a boolean indicating verification success.
|
||||
*/
|
||||
async verifyWithdrawal(withdrawalPayload: WithdrawalProof): Promise<boolean> {
|
||||
return await this.sdk.verifyWithdrawal(withdrawalPayload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcasts a withdrawal transaction.
|
||||
*
|
||||
* @param {WithdrawalPayload} withdrawalPayload - The withdrawal payload.
|
||||
* @returns {Promise<{ hash: string }>} - A promise resolving to an object containing the transaction hash.
|
||||
*/
|
||||
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
|
||||
withdrawalPayload: WithdrawalPayload,
|
||||
): Promise<{ hash: string }> {
|
||||
return {
|
||||
hash: "0x",
|
||||
};
|
||||
return this.contracts.relay(
|
||||
withdrawalPayload.withdrawal,
|
||||
withdrawalPayload.proof,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the context for a withdrawal.
|
||||
*
|
||||
* @param {Withdrawal} withdrawal - The withdrawal object.
|
||||
* @returns {string} - The calculated context.
|
||||
*/
|
||||
calculateContext(withdrawal: Withdrawal): string {
|
||||
return calculateContext(withdrawal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a scope value to an asset address.
|
||||
*
|
||||
* @param {bigint} scope - The scope value.
|
||||
* @returns {Promise<{ poolAddress: Address; assetAddress: Address; }>} - A promise resolving to the asset address.
|
||||
*/
|
||||
async scopeData(
|
||||
scope: bigint,
|
||||
): Promise<{ poolAddress: Address; assetAddress: Address }> {
|
||||
try {
|
||||
const data = await this.contracts.getScopeData(scope);
|
||||
return data;
|
||||
} catch (error) {
|
||||
if (error instanceof SDKError) {
|
||||
throw SdkError.scopeDataError(error);
|
||||
} else {
|
||||
throw RelayerError.unknown(JSON.stringify(error));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,28 @@
|
||||
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";
|
||||
import {
|
||||
RequestStatus,
|
||||
WithdrawalPayload,
|
||||
} from "../interfaces/relayer/request.js";
|
||||
|
||||
function replacer(key: string, value: unknown) {
|
||||
return typeof value === "bigint" ? { $bigint: value.toString() } : value;
|
||||
}
|
||||
|
||||
// TODO
|
||||
/**
|
||||
* Class representing an SQLite database for managing relayer requests.
|
||||
*/
|
||||
export class SqliteDatabase implements RelayerDatabase {
|
||||
/** Path to the SQLite database file. */
|
||||
readonly dbPath: string;
|
||||
|
||||
/** Indicates whether the database has been initialized. */
|
||||
private _initialized: boolean = false;
|
||||
|
||||
/** Database connection instance. */
|
||||
private db!: Database<sqlite3.Database, sqlite3.Statement>;
|
||||
|
||||
/** SQL statement for creating the requests table. */
|
||||
private createTableRequest = `
|
||||
CREATE TABLE IF NOT EXISTS requests (
|
||||
id UUID PRIMARY KEY,
|
||||
@@ -28,15 +34,28 @@ CREATE TABLE IF NOT EXISTS requests (
|
||||
);
|
||||
`;
|
||||
|
||||
/**
|
||||
* Initializes the database with the given path.
|
||||
*/
|
||||
constructor() {
|
||||
this.dbPath = path.resolve(SQLITE_DB_PATH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the database initialization status.
|
||||
*
|
||||
* @returns {boolean} - Whether the database is initialized.
|
||||
*/
|
||||
get initialized(): boolean {
|
||||
return this._initialized;
|
||||
}
|
||||
|
||||
async init() {
|
||||
/**
|
||||
* Initializes the database connection and creates necessary tables.
|
||||
*
|
||||
* @returns {Promise<void>} - A promise that resolves when initialization is complete.
|
||||
*/
|
||||
async init(): Promise<void> {
|
||||
try {
|
||||
this.db = await open({
|
||||
driver: sqlite3.Database,
|
||||
@@ -50,11 +69,19 @@ CREATE TABLE IF NOT EXISTS requests (
|
||||
console.log("sqlite db initialized");
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a new request record into the database.
|
||||
*
|
||||
* @param {string} requestId - Unique ID for the request.
|
||||
* @param {number} timestamp - Timestamp of the request.
|
||||
* @param {WithdrawalPayload} req - The withdrawal payload associated with the request.
|
||||
* @returns {Promise<void>} - A promise that resolves when the request is stored.
|
||||
*/
|
||||
async createNewRequest(
|
||||
requestId: string,
|
||||
timestamp: number,
|
||||
req: WithdrawalPayload,
|
||||
) {
|
||||
): Promise<void> {
|
||||
const strigifiedPayload = JSON.stringify(req, replacer);
|
||||
// Store initial request
|
||||
await this.db.run(
|
||||
@@ -66,7 +93,17 @@ CREATE TABLE IF NOT EXISTS requests (
|
||||
);
|
||||
}
|
||||
|
||||
async updateBroadcastedRequest(requestId: string, txHash: string) {
|
||||
/**
|
||||
* Updates a request record with broadcast status and transaction hash.
|
||||
*
|
||||
* @param {string} requestId - The ID of the request.
|
||||
* @param {string} txHash - The transaction hash.
|
||||
* @returns {Promise<void>} - A promise that resolves when the update is complete.
|
||||
*/
|
||||
async updateBroadcastedRequest(
|
||||
requestId: string,
|
||||
txHash: string,
|
||||
): Promise<void> {
|
||||
// Update database
|
||||
await this.db.run(
|
||||
`
|
||||
@@ -78,7 +115,17 @@ CREATE TABLE IF NOT EXISTS requests (
|
||||
);
|
||||
}
|
||||
|
||||
async updateFailedRequest(requestId: string, errorMessage: string) {
|
||||
/**
|
||||
* Updates a request record with failed status and error message.
|
||||
*
|
||||
* @param {string} requestId - The ID of the request.
|
||||
* @param {string} errorMessage - The error message.
|
||||
* @returns {Promise<void>} - A promise that resolves when the update is complete.
|
||||
*/
|
||||
async updateFailedRequest(
|
||||
requestId: string,
|
||||
errorMessage: string,
|
||||
): Promise<void> {
|
||||
// Update database with error
|
||||
await this.db.run(
|
||||
`
|
||||
@@ -90,3 +137,14 @@ CREATE TABLE IF NOT EXISTS requests (
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom JSON replacer function to handle BigInt serialization.
|
||||
*
|
||||
* @param {string} key - The JSON key.
|
||||
* @param {unknown} value - The JSON value.
|
||||
* @returns {unknown} - The transformed value.
|
||||
*/
|
||||
function replacer(key: string, value: unknown) {
|
||||
return typeof value === "bigint" ? { $bigint: value.toString() } : value;
|
||||
}
|
||||
|
||||
@@ -10,11 +10,11 @@ const relayRequestSchema: JSONSchemaType<RelayRequestBody> = {
|
||||
withdrawal: {
|
||||
type: "object",
|
||||
properties: {
|
||||
procesooor: { type: "string" },
|
||||
processooor: { type: "string" },
|
||||
scope: { type: "string" },
|
||||
data: { type: "string" },
|
||||
data: { type: "string", pattern: "0x[0-9a-fA-F]+" },
|
||||
},
|
||||
required: ["procesooor", "scope", "data"],
|
||||
required: ["processooor", "scope", "data"],
|
||||
},
|
||||
publicSignals: {
|
||||
type: "array",
|
||||
|
||||
@@ -1,42 +1,70 @@
|
||||
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";
|
||||
/**
|
||||
* Handles withdrawal requests within the Privacy Pool relayer.
|
||||
*/
|
||||
import { getAddress } from "viem";
|
||||
import {
|
||||
FEE_BPS,
|
||||
FEE_RECEIVER_ADDRESS,
|
||||
PROVIDER_URL,
|
||||
SIGNER_PRIVATE_KEY,
|
||||
WITHDRAW_AMOUNTS,
|
||||
} from "../config.js";
|
||||
import {
|
||||
RelayerError,
|
||||
WithdrawalValidationError,
|
||||
ZkError,
|
||||
} from "../exceptions/base.exception.js";
|
||||
import {
|
||||
RelayerResponse,
|
||||
WithdrawalPayload,
|
||||
} from "../interfaces/relayer/request.js";
|
||||
import { db, SdkProvider } from "../providers/index.js";
|
||||
import { RelayerDatabase } from "../types/db.types.js";
|
||||
import { decodeWithdrawalData, parseSignals } from "../utils.js";
|
||||
|
||||
/**
|
||||
* Class representing the Privacy Pool Relayer, responsible for processing withdrawal requests.
|
||||
*/
|
||||
export class PrivacyPoolRelayer {
|
||||
/** Database instance for storing and updating request states. */
|
||||
private db: RelayerDatabase;
|
||||
private sdkService: SdkProvider;
|
||||
/** SDK provider for handling blockchain interactions. */
|
||||
private sdkProvider: SdkProvider;
|
||||
/** RPC URL for blockchain communication. */
|
||||
private readonly rpcUrl: string = PROVIDER_URL;
|
||||
/** Private key for signing transactions. */
|
||||
private readonly privateKey: string = SIGNER_PRIVATE_KEY;
|
||||
|
||||
/**
|
||||
* Initializes a new instance of the Privacy Pool Relayer.
|
||||
*/
|
||||
constructor() {
|
||||
// Initialize database, provider, wallet, contract...
|
||||
this.db = db;
|
||||
this.sdkService = new SdkProvider();
|
||||
this.sdkProvider = new SdkProvider();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a withdrawal request.
|
||||
*
|
||||
* @param {WithdrawalPayload} req - The withdrawal request payload.
|
||||
* @returns {Promise<RelayerResponse>} - A promise resolving to the relayer response.
|
||||
*/
|
||||
async handleRequest(req: WithdrawalPayload): Promise<RelayerResponse> {
|
||||
const requestId = crypto.randomUUID();
|
||||
const timestamp = Date.now();
|
||||
|
||||
try {
|
||||
// Store initial request
|
||||
this.db.createNewRequest(requestId, timestamp, req);
|
||||
await this.validateWithdrawal(req);
|
||||
|
||||
// Verify commitment proof
|
||||
const isValidWithdrawal = await this.verifyProof(req.proof);
|
||||
if (!isValidWithdrawal) {
|
||||
const isValidWithdrawalProof = await this.verifyProof(req.proof);
|
||||
if (!isValidWithdrawalProof) {
|
||||
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,
|
||||
@@ -44,16 +72,9 @@ export class PrivacyPoolRelayer {
|
||||
requestId,
|
||||
};
|
||||
} catch (error) {
|
||||
let message: string;
|
||||
if (error instanceof RelayerError) {
|
||||
message = error.message;
|
||||
} else {
|
||||
message = JSON.stringify(error);
|
||||
}
|
||||
|
||||
// Update database with error
|
||||
const message: string =
|
||||
error instanceof RelayerError ? error.message : JSON.stringify(error);
|
||||
await this.db.updateFailedRequest(requestId, message);
|
||||
// Return error response
|
||||
return {
|
||||
success: false,
|
||||
error: message,
|
||||
@@ -63,17 +84,74 @@ export class PrivacyPoolRelayer {
|
||||
}
|
||||
}
|
||||
|
||||
// Helper methods
|
||||
/**
|
||||
* Verifies a withdrawal proof.
|
||||
*
|
||||
* @param {WithdrawalPayload["proof"]} proof - The proof to be verified.
|
||||
* @returns {Promise<boolean>} - A promise resolving to a boolean indicating verification success.
|
||||
*/
|
||||
private async verifyProof(
|
||||
proof: WithdrawalPayload["proof"],
|
||||
): Promise<boolean> {
|
||||
return this.sdkService.verifyWithdrawal(proof);
|
||||
return this.sdkProvider.verifyWithdrawal(proof);
|
||||
}
|
||||
|
||||
private async broadcastWithdrawal(withdrawal: WithdrawalPayload) {
|
||||
return this.sdkService.broadcastWithdrawal(withdrawal, {
|
||||
privateKey: this.privateKey,
|
||||
rpcUrl: this.rpcUrl,
|
||||
});
|
||||
/**
|
||||
* Broadcasts a withdrawal transaction.
|
||||
*
|
||||
* @param {WithdrawalPayload} withdrawal - The withdrawal payload.
|
||||
* @returns {Promise<{ hash: string }>} - A promise resolving to the transaction hash.
|
||||
*/
|
||||
private async broadcastWithdrawal(
|
||||
withdrawal: WithdrawalPayload,
|
||||
): Promise<{ hash: string }> {
|
||||
return this.sdkProvider.broadcastWithdrawal(withdrawal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a withdrawal request against relayer rules.
|
||||
*
|
||||
* @param {WithdrawalPayload} wp - The withdrawal payload.
|
||||
* @throws {WithdrawalValidationError} - If validation fails.
|
||||
* @throws {ValidationError} - If public signals are malformed.
|
||||
*/
|
||||
private async validateWithdrawal(wp: WithdrawalPayload) {
|
||||
const { feeRecipient, relayFeeBPS } = decodeWithdrawalData(
|
||||
wp.withdrawal.data,
|
||||
);
|
||||
const proofSignals = parseSignals(wp.proof.publicSignals);
|
||||
|
||||
if (getAddress(feeRecipient) !== FEE_RECEIVER_ADDRESS) {
|
||||
throw WithdrawalValidationError.feeReceiverMismatch(
|
||||
`Fee recipient mismatch: expected "${FEE_RECEIVER_ADDRESS}", got "${feeRecipient}".`,
|
||||
);
|
||||
}
|
||||
|
||||
if (relayFeeBPS !== FEE_BPS) {
|
||||
throw WithdrawalValidationError.feeMismatch(
|
||||
`Relay fee mismatch: expected "${FEE_BPS}", got "${relayFeeBPS}".`,
|
||||
);
|
||||
}
|
||||
|
||||
const withdrawalContext = BigInt(
|
||||
this.sdkProvider.calculateContext(wp.withdrawal),
|
||||
);
|
||||
if (proofSignals.context !== withdrawalContext) {
|
||||
throw WithdrawalValidationError.contextMismatch(
|
||||
`Context mismatch: expected "${withdrawalContext.toString(16)}", got "${proofSignals.context.toString(16)}".`,
|
||||
);
|
||||
}
|
||||
|
||||
const { assetAddress } = await this.sdkProvider.scopeData(
|
||||
wp.withdrawal.scope,
|
||||
);
|
||||
const MIN_WITHDRAW_DEFAULT = 100_000n;
|
||||
const minWithdrawAmount =
|
||||
WITHDRAW_AMOUNTS[assetAddress] ?? MIN_WITHDRAW_DEFAULT;
|
||||
if (proofSignals.withdrawnValue < minWithdrawAmount) {
|
||||
throw WithdrawalValidationError.withdrawnValueTooSmall(
|
||||
`Withdrawn value too small: expected minimum "${minWithdrawAmount}", got "${proofSignals.withdrawnValue}".`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
11
packages/relayer/src/types/abi.types.ts
Normal file
11
packages/relayer/src/types/abi.types.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
export const FeeDataAbi = [
|
||||
{
|
||||
name: "FeeData",
|
||||
type: "tuple",
|
||||
components: [
|
||||
{ name: "recipient", type: "address" },
|
||||
{ name: "feeRecipient", type: "address" },
|
||||
{ name: "relayFeeBPS", type: "uint256" },
|
||||
],
|
||||
},
|
||||
] as const;
|
||||
@@ -1,4 +1,4 @@
|
||||
import { WithdrawalPayload } from "@privacy-pool-core/sdk";
|
||||
import { WithdrawalPayload } from "../interfaces/relayer/request.js";
|
||||
|
||||
export interface RelayerDatabase {
|
||||
initialized: boolean;
|
||||
|
||||
50
packages/relayer/src/utils.ts
Normal file
50
packages/relayer/src/utils.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import { decodeAbiParameters, DecodeAbiParametersErrorType } from "viem";
|
||||
import {
|
||||
ValidationError,
|
||||
WithdrawalValidationError,
|
||||
} from "./exceptions/base.exception.js";
|
||||
import { FeeDataAbi } from "./types/abi.types.js";
|
||||
import {
|
||||
RelayRequestBody,
|
||||
WithdrawPublicSignals,
|
||||
} from "./interfaces/relayer/request.js";
|
||||
|
||||
export function decodeWithdrawalData(data: `0x${string}`) {
|
||||
try {
|
||||
const [{ recipient, feeRecipient, relayFeeBPS }] = decodeAbiParameters(
|
||||
FeeDataAbi,
|
||||
data,
|
||||
);
|
||||
return { recipient, feeRecipient, relayFeeBPS };
|
||||
} catch (e) {
|
||||
const error = e as DecodeAbiParametersErrorType;
|
||||
throw WithdrawalValidationError.invalidWithdrawalAbi({
|
||||
name: error.name,
|
||||
message: error.message,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function parseSignals(
|
||||
signals: RelayRequestBody["publicSignals"],
|
||||
): WithdrawPublicSignals {
|
||||
const badSignals = signals
|
||||
.map((x, i) => (x === undefined ? i : null))
|
||||
.filter((i) => i !== null);
|
||||
if (badSignals.length > 0) {
|
||||
throw ValidationError.invalidInput({
|
||||
details: `Signals ${badSignals.join(", ")} are undefined`,
|
||||
});
|
||||
}
|
||||
/// XXX: beware this signal distribution is based on how the circuits were compiled with circomkit, first 2 are the public outputs, next are the public inputs
|
||||
return {
|
||||
newCommitmentHash: BigInt(signals[0]!), // Hash of new commitment
|
||||
existingNullifierHash: BigInt(signals[1]!), // Hash of the existing commitment nullifier
|
||||
withdrawnValue: BigInt(signals[2]!),
|
||||
stateRoot: BigInt(signals[3]!),
|
||||
stateTreeDepth: BigInt(signals[4]!),
|
||||
ASPRoot: BigInt(signals[5]!),
|
||||
ASPTreeDepth: BigInt(signals[6]!),
|
||||
context: BigInt(signals[7]!),
|
||||
};
|
||||
}
|
||||
19
packages/relayer/test/integration/relay/package.json
Normal file
19
packages/relayer/test/integration/relay/package.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "api-test",
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"viem": "2.22.14"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc -p ./tsconfig.json",
|
||||
"main": "node dist/main.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@privacy-pool-core/sdk": "0.1.0",
|
||||
"@types/node": "^22.13.0",
|
||||
"typescript": "5.5.4"
|
||||
}
|
||||
}
|
||||
31
packages/relayer/test/integration/relay/src/api-test.js
Normal file
31
packages/relayer/test/integration/relay/src/api-test.js
Normal file
@@ -0,0 +1,31 @@
|
||||
export const ping = async () => {
|
||||
let r = await fetch("http://localhost:3000/ping", {
|
||||
method: "get",
|
||||
});
|
||||
console.log(JSON.stringify(await r.text(), null, 2));
|
||||
};
|
||||
|
||||
export const details = async () => {
|
||||
let r = await fetch("http://localhost:3000/relayer/details", {
|
||||
method: "get",
|
||||
});
|
||||
console.log(JSON.stringify(await r.json(), null, 2));
|
||||
};
|
||||
|
||||
export const notFound = async () => {
|
||||
let r = await fetch("http://localhost:3000/HOLA", {
|
||||
method: "get",
|
||||
});
|
||||
console.log(JSON.stringify(await r.json(), null, 2));
|
||||
};
|
||||
|
||||
export const request = async (requestBody) => {
|
||||
let r = await fetch("http://localhost:3000/relayer/request", {
|
||||
method: "post",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(requestBody),
|
||||
});
|
||||
console.log(JSON.stringify(await r.json(), null, 2));
|
||||
};
|
||||
171
packages/relayer/test/integration/relay/src/create-withdrawal.ts
Normal file
171
packages/relayer/test/integration/relay/src/create-withdrawal.ts
Normal file
@@ -0,0 +1,171 @@
|
||||
import {
|
||||
bigintToHash,
|
||||
calculateContext,
|
||||
Circuits,
|
||||
getCommitment,
|
||||
hashPrecommitment,
|
||||
LeanIMTMerkleProof,
|
||||
PrivacyPoolSDK,
|
||||
Secret,
|
||||
Withdrawal,
|
||||
WithdrawalProof,
|
||||
WithdrawalProofInput,
|
||||
} from "@privacy-pool-core/sdk";
|
||||
import { Address, defineChain, Hex } from "viem";
|
||||
import { localhost } from "viem/chains";
|
||||
|
||||
/*
|
||||
TestToken deployed at: 0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9
|
||||
Withdrawal Verifier deployed at: 0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9
|
||||
Ragequit Verifier deployed at: 0x5FC8d32690cc91D4c39d9d3abcBD16989F875707
|
||||
Entrypoint deployed at: 0xa513E6E4b8f2a923D98304ec87F64353C4D5C853
|
||||
ETH Pool deployed at: 0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6
|
||||
TST Pool deployed at: 0x610178dA211FEF7D417bC0e6FeD39F05609AD788
|
||||
*/
|
||||
|
||||
const LOCAL_ANVIL_RPC = "http://127.0.0.1:8545";
|
||||
const ENTRYPOINT_ADDRESS: Address =
|
||||
"0xa513E6E4b8f2a923D98304ec87F64353C4D5C853";
|
||||
// const PRIVACY_POOL_ADDRESS: Address = "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6";
|
||||
const PRIVATE_KEY: Hex =
|
||||
"0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80";
|
||||
|
||||
const anvilChain = defineChain({ ...localhost, id: 31337 });
|
||||
|
||||
const sdk = new PrivacyPoolSDK(new Circuits());
|
||||
|
||||
const contracts = sdk.createContractInstance(
|
||||
LOCAL_ANVIL_RPC,
|
||||
anvilChain,
|
||||
ENTRYPOINT_ADDRESS,
|
||||
PRIVATE_KEY,
|
||||
);
|
||||
|
||||
export async function deposit() {
|
||||
const existingValue = BigInt("5000000000000000000"); // 5 eth
|
||||
const existingNullifier = BigInt("2827991637673173") as Secret;
|
||||
const existingSecret = BigInt("7338940278733227") as Secret;
|
||||
const precommitment = {
|
||||
hash: hashPrecommitment(existingNullifier, existingSecret),
|
||||
nullifier: existingNullifier,
|
||||
secret: existingSecret,
|
||||
};
|
||||
return contracts.depositETH(existingValue, precommitment.hash);
|
||||
}
|
||||
|
||||
export async function proveWithdrawal(w: Withdrawal): Promise<WithdrawalProof> {
|
||||
try {
|
||||
console.log("🚀 Initializing PrivacyPoolSDK...");
|
||||
|
||||
// **Retrieve On-Chain Scope**
|
||||
console.log(
|
||||
"🔹 Retrieved Scope from Withdrawal:",
|
||||
`0x${w.scope.toString(16)}`,
|
||||
);
|
||||
|
||||
// **Load Valid Input Values**
|
||||
const withdrawnValue = BigInt("100000000000000000"); // 0.1 eth
|
||||
const stateRoot = BigInt(
|
||||
"11647068014638404411083963959916324311405860401109309104995569418439086324505",
|
||||
);
|
||||
const stateTreeDepth = BigInt("2");
|
||||
const aspRoot = BigInt(
|
||||
"17509119559942543382744731935952318540675152427220720285867932301410542597330",
|
||||
);
|
||||
const aspTreeDepth = BigInt("2");
|
||||
const label = BigInt("2310129299332319");
|
||||
|
||||
// **Commitment Data**
|
||||
const existingValue = BigInt("5000000000000000000");
|
||||
const existingNullifier = BigInt("2827991637673173") as Secret;
|
||||
const existingSecret = BigInt("7338940278733227") as Secret;
|
||||
const newNullifier = BigInt("1800210687471587") as Secret;
|
||||
const newSecret = BigInt("6593588285288381") as Secret;
|
||||
|
||||
console.log("🛠️ Generating commitments...");
|
||||
|
||||
const commitment = getCommitment(
|
||||
existingValue,
|
||||
label,
|
||||
existingNullifier,
|
||||
existingSecret,
|
||||
);
|
||||
|
||||
// **State Merkle Proof**
|
||||
const stateMerkleProof: LeanIMTMerkleProof = {
|
||||
root: stateRoot,
|
||||
leaf: commitment.hash,
|
||||
index: 3,
|
||||
siblings: [
|
||||
BigInt("6398878698952029"),
|
||||
BigInt(
|
||||
"13585012987205807684735841540436202984635744455909835202346884556845854938903",
|
||||
),
|
||||
...Array(30).fill(BigInt(0)),
|
||||
],
|
||||
};
|
||||
|
||||
// **ASP Merkle Proof**
|
||||
const aspMerkleProof: LeanIMTMerkleProof = {
|
||||
root: aspRoot,
|
||||
leaf: label,
|
||||
index: 3,
|
||||
siblings: [
|
||||
BigInt("3189334085279373"),
|
||||
BigInt(
|
||||
"1131383056830993841196498111009024161908281953428245130508088856824218714105",
|
||||
),
|
||||
...Array(30).fill(BigInt(0)),
|
||||
],
|
||||
};
|
||||
|
||||
// console.log("✅ State Merkle Proof:", stateMerkleProof);
|
||||
// console.log("✅ ASP Merkle Proof:", aspMerkleProof);
|
||||
|
||||
// **Correctly Compute Context Hash**
|
||||
const computedContext = calculateContext(w);
|
||||
console.log("🔹 Computed Context:", computedContext.toString());
|
||||
|
||||
// **Create Withdrawal Proof Input**
|
||||
const proofInput: WithdrawalProofInput = {
|
||||
context: BigInt(computedContext),
|
||||
withdrawalAmount: withdrawnValue,
|
||||
stateMerkleProof: stateMerkleProof,
|
||||
aspMerkleProof: aspMerkleProof,
|
||||
stateRoot: bigintToHash(stateRoot),
|
||||
stateTreeDepth: stateTreeDepth,
|
||||
aspRoot: bigintToHash(aspRoot),
|
||||
aspTreeDepth: aspTreeDepth,
|
||||
newSecret: newSecret,
|
||||
newNullifier: newNullifier,
|
||||
};
|
||||
|
||||
console.log("🚀 Generating withdrawal proof...");
|
||||
const proofPayload: WithdrawalProof = await sdk.proveWithdrawal(
|
||||
commitment,
|
||||
proofInput,
|
||||
);
|
||||
return proofPayload;
|
||||
|
||||
// if (!proofPayload) {
|
||||
// throw new Error("❌ Withdrawal proof generation failed: proofPayload is null or undefined");
|
||||
// }
|
||||
|
||||
// console.log("✅ Proof Payload:", proofPayload);
|
||||
|
||||
// console.log("🚀 Sending withdrawal transaction...");
|
||||
// const withdrawalTx = await sdk.getContractInteractions().withdraw(withdrawObj, proofPayload);
|
||||
|
||||
// console.log("✅ Withdrawal transaction sent:", withdrawalTx?.hash ?? "❌ No transaction hash returned");
|
||||
|
||||
// if (!withdrawalTx?.hash) {
|
||||
// throw new Error("❌ Withdrawal transaction failed: No transaction hash returned.");
|
||||
// }
|
||||
|
||||
// await withdrawalTx.wait();
|
||||
// console.log("🎉 Withdrawal transaction confirmed!");
|
||||
} catch (error) {
|
||||
console.error("❌ **Error running testWithdraw script**:", error);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
58
packages/relayer/test/integration/relay/src/main.ts
Normal file
58
packages/relayer/test/integration/relay/src/main.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import { encodeAbiParameters, getAddress, Hex } from "viem";
|
||||
import { request } from "./api-test.js";
|
||||
import { deposit, proveWithdrawal } from "./create-withdrawal.js";
|
||||
import { Hash, Withdrawal } from "@privacy-pool-core/sdk";
|
||||
|
||||
const FeeDataAbi = [
|
||||
{
|
||||
name: "FeeData",
|
||||
type: "tuple",
|
||||
components: [
|
||||
{ name: "recipient", type: "address" },
|
||||
{ name: "feeRecipient", type: "address" },
|
||||
{ name: "relayFeeBPS", type: "uint256" },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const recipient = getAddress("0x70997970C51812dc3A010C7d01b50e0d17dc79C8");
|
||||
const processooor = getAddress("0xa513E6E4b8f2a923D98304ec87F64353C4D5C853"); // when relaying processooor is the entrypoint
|
||||
const FEE_RECEIVER_ADDRESS = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266";
|
||||
|
||||
async function prove(w: Withdrawal) {
|
||||
return proveWithdrawal(w);
|
||||
}
|
||||
|
||||
async function depositEth() {
|
||||
const r = await deposit();
|
||||
console.log(r.hash);
|
||||
await r.wait();
|
||||
console.log("done");
|
||||
}
|
||||
|
||||
(async () => {
|
||||
const scope = BigInt(
|
||||
"0x0555c5fdc167f1f1519c1b21a690de24d9be5ff0bde19447a5f28958d9256e50",
|
||||
) as Hash;
|
||||
const data = encodeAbiParameters(FeeDataAbi, [
|
||||
{
|
||||
recipient,
|
||||
feeRecipient: FEE_RECEIVER_ADDRESS,
|
||||
relayFeeBPS: 1_000n,
|
||||
},
|
||||
]) as Hex;
|
||||
|
||||
const withdrawal = { processooor, scope, data };
|
||||
|
||||
await depositEth();
|
||||
|
||||
// prove
|
||||
const { proof, publicSignals } = await prove(withdrawal);
|
||||
const requestBody = {
|
||||
withdrawal: { ...withdrawal, scope: withdrawal.scope.toString() },
|
||||
publicSignals,
|
||||
proof,
|
||||
};
|
||||
|
||||
await request(requestBody);
|
||||
})();
|
||||
26
packages/relayer/test/integration/relay/tsconfig.base.json
Normal file
26
packages/relayer/test/integration/relay/tsconfig.base.json
Normal file
@@ -0,0 +1,26 @@
|
||||
/* Based on total-typescript no-dom app config */
|
||||
/* https://github.com/total-typescript/tsconfig */
|
||||
{
|
||||
"compilerOptions": {
|
||||
/* Base Options: */
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"target": "es2022",
|
||||
"allowJs": true,
|
||||
"resolveJsonModule": true,
|
||||
"moduleDetection": "force",
|
||||
"isolatedModules": true,
|
||||
"verbatimModuleSyntax": false,
|
||||
/* Strictness */
|
||||
"strict": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"useUnknownInCatchVariables": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noImplicitOverride": true,
|
||||
/* If transpiling with TypeScript: */
|
||||
"module": "NodeNext",
|
||||
"sourceMap": true,
|
||||
/* If your code doesn't run in the DOM: */
|
||||
"lib": ["es2022"]
|
||||
}
|
||||
}
|
||||
9
packages/relayer/test/integration/relay/tsconfig.json
Normal file
9
packages/relayer/test/integration/relay/tsconfig.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": "./tsconfig.base.json",
|
||||
"include": ["**/*", ".*.js"],
|
||||
"exclude": ["node_modules", "dist"],
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"lib": ["es2022"]
|
||||
}
|
||||
}
|
||||
106
packages/relayer/test/integration/relay/yarn.lock
Normal file
106
packages/relayer/test/integration/relay/yarn.lock
Normal file
@@ -0,0 +1,106 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@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.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.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/node@^22.13.0":
|
||||
version "22.13.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.13.0.tgz#d376dd9a0ee2f9382d86c2d5d7beb4d198b4ea8c"
|
||||
integrity sha512-ClIbNe36lawluuvq3+YYhnIN2CELi+6q8NpnM7PYp4hBn/TatfboPgVSm2rwKRfnV2M+Ty9GWDFI64KEe+kysA==
|
||||
dependencies:
|
||||
undici-types "~6.20.0"
|
||||
|
||||
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==
|
||||
|
||||
eventemitter3@5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4"
|
||||
integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==
|
||||
|
||||
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==
|
||||
|
||||
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"
|
||||
|
||||
typescript@5.5.4:
|
||||
version "5.5.4"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.5.4.tgz#d9852d6c82bad2d2eda4fd74a5762a8f5909e9ba"
|
||||
integrity sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==
|
||||
|
||||
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==
|
||||
|
||||
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.18.0:
|
||||
version "8.18.0"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc"
|
||||
integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==
|
||||
3
packages/relayer/withdraw_amounts.example.json
Normal file
3
packages/relayer/withdraw_amounts.example.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9": 100
|
||||
}
|
||||
@@ -1,757 +0,0 @@
|
||||
# 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==
|
||||
@@ -12,7 +12,8 @@ const outDirBrowser = path.join(rootOutDir, "esm");
|
||||
|
||||
const typescriptConfig = {
|
||||
tsconfig: path.resolve(`./tsconfig.build.json`),
|
||||
exclude: ["**/*spec.ts"],
|
||||
include: ["src/**/*.ts", "src/**/*.js"],
|
||||
exclude: ["**/*spec.ts", "__mocks__", "tests/*"],
|
||||
outputToFilesystem: false,
|
||||
}
|
||||
|
||||
@@ -79,7 +80,7 @@ export default [
|
||||
output: [
|
||||
{
|
||||
dir: path.join(rootOutDir, "types"),
|
||||
sourcemap: true,
|
||||
sourcemap: false,
|
||||
},
|
||||
],
|
||||
plugins: [
|
||||
@@ -100,7 +101,7 @@ export default [
|
||||
},
|
||||
|
||||
{
|
||||
input: path.join(rootOutDir, "types", "src", "index.d.ts"),
|
||||
input: path.join(rootOutDir, "types", "index.d.ts"),
|
||||
output: [{ file: path.join(rootOutDir, "index.d.mts"), format: "esm" }],
|
||||
plugins: [dts()],
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
"maci-crypto": "2.5.0",
|
||||
"snarkjs": "0.7.5",
|
||||
"@types/snarkjs": "0.7.9",
|
||||
"viem": "2.21.4"
|
||||
"viem": "2.22.14"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/config-conventional": "19.4.1",
|
||||
|
||||
@@ -1,532 +0,0 @@
|
||||
export const IPrivacyPoolSimpleABI = [
|
||||
{
|
||||
type: "function",
|
||||
name: "ASSET",
|
||||
inputs: [],
|
||||
outputs: [
|
||||
{
|
||||
name: "_asset",
|
||||
type: "address",
|
||||
internalType: "address",
|
||||
},
|
||||
],
|
||||
stateMutability: "view",
|
||||
},
|
||||
{
|
||||
type: "function",
|
||||
name: "ENTRYPOINT",
|
||||
inputs: [],
|
||||
outputs: [
|
||||
{
|
||||
name: "_entrypoint",
|
||||
type: "address",
|
||||
internalType: "contract IEntrypoint",
|
||||
},
|
||||
],
|
||||
stateMutability: "view",
|
||||
},
|
||||
{
|
||||
type: "function",
|
||||
name: "RAGEQUIT_VERIFIER",
|
||||
inputs: [],
|
||||
outputs: [
|
||||
{
|
||||
name: "_verifier",
|
||||
type: "address",
|
||||
internalType: "contract IVerifier",
|
||||
},
|
||||
],
|
||||
stateMutability: "view",
|
||||
},
|
||||
{
|
||||
type: "function",
|
||||
name: "ROOT_HISTORY_SIZE",
|
||||
inputs: [],
|
||||
outputs: [
|
||||
{
|
||||
name: "_size",
|
||||
type: "uint32",
|
||||
internalType: "uint32",
|
||||
},
|
||||
],
|
||||
stateMutability: "view",
|
||||
},
|
||||
{
|
||||
type: "function",
|
||||
name: "SCOPE",
|
||||
inputs: [],
|
||||
outputs: [
|
||||
{
|
||||
name: "_scope",
|
||||
type: "uint256",
|
||||
internalType: "uint256",
|
||||
},
|
||||
],
|
||||
stateMutability: "view",
|
||||
},
|
||||
{
|
||||
type: "function",
|
||||
name: "VERSION",
|
||||
inputs: [],
|
||||
outputs: [
|
||||
{
|
||||
name: "_version",
|
||||
type: "string",
|
||||
internalType: "string",
|
||||
},
|
||||
],
|
||||
stateMutability: "view",
|
||||
},
|
||||
{
|
||||
type: "function",
|
||||
name: "WITHDRAWAL_VERIFIER",
|
||||
inputs: [],
|
||||
outputs: [
|
||||
{
|
||||
name: "_verifier",
|
||||
type: "address",
|
||||
internalType: "contract IVerifier",
|
||||
},
|
||||
],
|
||||
stateMutability: "view",
|
||||
},
|
||||
{
|
||||
type: "function",
|
||||
name: "currentRootIndex",
|
||||
inputs: [],
|
||||
outputs: [
|
||||
{
|
||||
name: "_index",
|
||||
type: "uint32",
|
||||
internalType: "uint32",
|
||||
},
|
||||
],
|
||||
stateMutability: "view",
|
||||
},
|
||||
{
|
||||
type: "function",
|
||||
name: "dead",
|
||||
inputs: [],
|
||||
outputs: [
|
||||
{
|
||||
name: "_dead",
|
||||
type: "bool",
|
||||
internalType: "bool",
|
||||
},
|
||||
],
|
||||
stateMutability: "view",
|
||||
},
|
||||
{
|
||||
type: "function",
|
||||
name: "deposit",
|
||||
inputs: [
|
||||
{
|
||||
name: "_depositor",
|
||||
type: "address",
|
||||
internalType: "address",
|
||||
},
|
||||
{
|
||||
name: "_value",
|
||||
type: "uint256",
|
||||
internalType: "uint256",
|
||||
},
|
||||
{
|
||||
name: "_precommitment",
|
||||
type: "uint256",
|
||||
internalType: "uint256",
|
||||
},
|
||||
],
|
||||
outputs: [
|
||||
{
|
||||
name: "_commitment",
|
||||
type: "uint256",
|
||||
internalType: "uint256",
|
||||
},
|
||||
],
|
||||
stateMutability: "payable",
|
||||
},
|
||||
{
|
||||
type: "function",
|
||||
name: "deposits",
|
||||
inputs: [
|
||||
{
|
||||
name: "_label",
|
||||
type: "uint256",
|
||||
internalType: "uint256",
|
||||
},
|
||||
],
|
||||
outputs: [
|
||||
{
|
||||
name: "_depositor",
|
||||
type: "address",
|
||||
internalType: "address",
|
||||
},
|
||||
{
|
||||
name: "_amount",
|
||||
type: "uint256",
|
||||
internalType: "uint256",
|
||||
},
|
||||
{
|
||||
name: "_whenRagequitteable",
|
||||
type: "uint256",
|
||||
internalType: "uint256",
|
||||
},
|
||||
],
|
||||
stateMutability: "view",
|
||||
},
|
||||
{
|
||||
type: "function",
|
||||
name: "nonce",
|
||||
inputs: [],
|
||||
outputs: [
|
||||
{
|
||||
name: "_nonce",
|
||||
type: "uint256",
|
||||
internalType: "uint256",
|
||||
},
|
||||
],
|
||||
stateMutability: "view",
|
||||
},
|
||||
{
|
||||
type: "function",
|
||||
name: "nullifierHashes",
|
||||
inputs: [
|
||||
{
|
||||
name: "_nullifierHash",
|
||||
type: "uint256",
|
||||
internalType: "uint256",
|
||||
},
|
||||
],
|
||||
outputs: [
|
||||
{
|
||||
name: "_spent",
|
||||
type: "bool",
|
||||
internalType: "bool",
|
||||
},
|
||||
],
|
||||
stateMutability: "view",
|
||||
},
|
||||
{
|
||||
type: "function",
|
||||
name: "ragequit",
|
||||
inputs: [
|
||||
{
|
||||
name: "_p",
|
||||
type: "tuple",
|
||||
internalType: "struct ProofLib.RagequitProof",
|
||||
components: [
|
||||
{
|
||||
name: "pA",
|
||||
type: "uint256[2]",
|
||||
internalType: "uint256[2]",
|
||||
},
|
||||
{
|
||||
name: "pB",
|
||||
type: "uint256[2][2]",
|
||||
internalType: "uint256[2][2]",
|
||||
},
|
||||
{
|
||||
name: "pC",
|
||||
type: "uint256[2]",
|
||||
internalType: "uint256[2]",
|
||||
},
|
||||
{
|
||||
name: "pubSignals",
|
||||
type: "uint256[5]",
|
||||
internalType: "uint256[5]",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
outputs: [],
|
||||
stateMutability: "nonpayable",
|
||||
},
|
||||
{
|
||||
type: "function",
|
||||
name: "roots",
|
||||
inputs: [
|
||||
{
|
||||
name: "_index",
|
||||
type: "uint256",
|
||||
internalType: "uint256",
|
||||
},
|
||||
],
|
||||
outputs: [
|
||||
{
|
||||
name: "_root",
|
||||
type: "uint256",
|
||||
internalType: "uint256",
|
||||
},
|
||||
],
|
||||
stateMutability: "view",
|
||||
},
|
||||
{
|
||||
type: "function",
|
||||
name: "windDown",
|
||||
inputs: [],
|
||||
outputs: [],
|
||||
stateMutability: "nonpayable",
|
||||
},
|
||||
{
|
||||
type: "function",
|
||||
name: "withdraw",
|
||||
inputs: [
|
||||
{
|
||||
name: "_w",
|
||||
type: "tuple",
|
||||
internalType: "struct IPrivacyPool.Withdrawal",
|
||||
components: [
|
||||
{
|
||||
name: "processooor",
|
||||
type: "address",
|
||||
internalType: "address",
|
||||
},
|
||||
{
|
||||
name: "scope",
|
||||
type: "uint256",
|
||||
internalType: "uint256",
|
||||
},
|
||||
{
|
||||
name: "data",
|
||||
type: "bytes",
|
||||
internalType: "bytes",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "_p",
|
||||
type: "tuple",
|
||||
internalType: "struct ProofLib.WithdrawProof",
|
||||
components: [
|
||||
{
|
||||
name: "pA",
|
||||
type: "uint256[2]",
|
||||
internalType: "uint256[2]",
|
||||
},
|
||||
{
|
||||
name: "pB",
|
||||
type: "uint256[2][2]",
|
||||
internalType: "uint256[2][2]",
|
||||
},
|
||||
{
|
||||
name: "pC",
|
||||
type: "uint256[2]",
|
||||
internalType: "uint256[2]",
|
||||
},
|
||||
{
|
||||
name: "pubSignals",
|
||||
type: "uint256[8]",
|
||||
internalType: "uint256[8]",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
outputs: [],
|
||||
stateMutability: "nonpayable",
|
||||
},
|
||||
{
|
||||
type: "event",
|
||||
name: "Deposited",
|
||||
inputs: [
|
||||
{
|
||||
name: "_depositor",
|
||||
type: "address",
|
||||
indexed: true,
|
||||
internalType: "address",
|
||||
},
|
||||
{
|
||||
name: "_commitment",
|
||||
type: "uint256",
|
||||
indexed: false,
|
||||
internalType: "uint256",
|
||||
},
|
||||
{
|
||||
name: "_label",
|
||||
type: "uint256",
|
||||
indexed: false,
|
||||
internalType: "uint256",
|
||||
},
|
||||
{
|
||||
name: "_value",
|
||||
type: "uint256",
|
||||
indexed: false,
|
||||
internalType: "uint256",
|
||||
},
|
||||
{
|
||||
name: "_merkleRoot",
|
||||
type: "uint256",
|
||||
indexed: false,
|
||||
internalType: "uint256",
|
||||
},
|
||||
],
|
||||
anonymous: false,
|
||||
},
|
||||
{
|
||||
type: "event",
|
||||
name: "LeafInserted",
|
||||
inputs: [
|
||||
{
|
||||
name: "_index",
|
||||
type: "uint256",
|
||||
indexed: false,
|
||||
internalType: "uint256",
|
||||
},
|
||||
{
|
||||
name: "_leaf",
|
||||
type: "uint256",
|
||||
indexed: false,
|
||||
internalType: "uint256",
|
||||
},
|
||||
{
|
||||
name: "_root",
|
||||
type: "uint256",
|
||||
indexed: false,
|
||||
internalType: "uint256",
|
||||
},
|
||||
],
|
||||
anonymous: false,
|
||||
},
|
||||
{
|
||||
type: "event",
|
||||
name: "PoolDied",
|
||||
inputs: [],
|
||||
anonymous: false,
|
||||
},
|
||||
{
|
||||
type: "event",
|
||||
name: "Ragequit",
|
||||
inputs: [
|
||||
{
|
||||
name: "_ragequitter",
|
||||
type: "address",
|
||||
indexed: true,
|
||||
internalType: "address",
|
||||
},
|
||||
{
|
||||
name: "_commitment",
|
||||
type: "uint256",
|
||||
indexed: false,
|
||||
internalType: "uint256",
|
||||
},
|
||||
{
|
||||
name: "_label",
|
||||
type: "uint256",
|
||||
indexed: false,
|
||||
internalType: "uint256",
|
||||
},
|
||||
{
|
||||
name: "_value",
|
||||
type: "uint256",
|
||||
indexed: false,
|
||||
internalType: "uint256",
|
||||
},
|
||||
],
|
||||
anonymous: false,
|
||||
},
|
||||
{
|
||||
type: "event",
|
||||
name: "Withdrawn",
|
||||
inputs: [
|
||||
{
|
||||
name: "_processooor",
|
||||
type: "address",
|
||||
indexed: true,
|
||||
internalType: "address",
|
||||
},
|
||||
{
|
||||
name: "_value",
|
||||
type: "uint256",
|
||||
indexed: false,
|
||||
internalType: "uint256",
|
||||
},
|
||||
{
|
||||
name: "_spentNullifier",
|
||||
type: "uint256",
|
||||
indexed: false,
|
||||
internalType: "uint256",
|
||||
},
|
||||
{
|
||||
name: "_newCommitment",
|
||||
type: "uint256",
|
||||
indexed: false,
|
||||
internalType: "uint256",
|
||||
},
|
||||
],
|
||||
anonymous: false,
|
||||
},
|
||||
{
|
||||
type: "error",
|
||||
name: "ContextMismatch",
|
||||
inputs: [],
|
||||
},
|
||||
{
|
||||
type: "error",
|
||||
name: "FailedToSendETH",
|
||||
inputs: [],
|
||||
},
|
||||
{
|
||||
type: "error",
|
||||
name: "IncorrectASPRoot",
|
||||
inputs: [],
|
||||
},
|
||||
{
|
||||
type: "error",
|
||||
name: "InsufficientValue",
|
||||
inputs: [],
|
||||
},
|
||||
{
|
||||
type: "error",
|
||||
name: "InvalidCommitment",
|
||||
inputs: [],
|
||||
},
|
||||
{
|
||||
type: "error",
|
||||
name: "InvalidProcesooor",
|
||||
inputs: [],
|
||||
},
|
||||
{
|
||||
type: "error",
|
||||
name: "InvalidProof",
|
||||
inputs: [],
|
||||
},
|
||||
{
|
||||
type: "error",
|
||||
name: "NotYetRagequitteable",
|
||||
inputs: [],
|
||||
},
|
||||
{
|
||||
type: "error",
|
||||
name: "NullifierAlreadySpent",
|
||||
inputs: [],
|
||||
},
|
||||
{
|
||||
type: "error",
|
||||
name: "OnlyEntrypoint",
|
||||
inputs: [],
|
||||
},
|
||||
{
|
||||
type: "error",
|
||||
name: "OnlyOriginalDepositor",
|
||||
inputs: [],
|
||||
},
|
||||
{
|
||||
type: "error",
|
||||
name: "PoolIsDead",
|
||||
inputs: [],
|
||||
},
|
||||
{
|
||||
type: "error",
|
||||
name: "ScopeMismatch",
|
||||
inputs: [],
|
||||
},
|
||||
{
|
||||
type: "error",
|
||||
name: "UnknownStateRoot",
|
||||
inputs: [],
|
||||
},
|
||||
{
|
||||
type: "error",
|
||||
name: "ZeroAddress",
|
||||
inputs: [],
|
||||
},
|
||||
] as const;
|
||||
@@ -21,6 +21,7 @@ import { IPrivacyPoolABI } from "../abi/IPrivacyPool.js";
|
||||
import { privateKeyToAccount } from "viem/accounts";
|
||||
import { CommitmentProof } from "../types/commitment.js";
|
||||
import { bigintToHex } from "../crypto.js";
|
||||
import { ContractError } from "../errors/base.error.js";
|
||||
|
||||
export class ContractInteractionsService implements ContractInteractions {
|
||||
private publicClient: PublicClient;
|
||||
@@ -229,7 +230,7 @@ export class ContractInteractionsService implements ContractInteractions {
|
||||
|
||||
// if no pool throw error
|
||||
if (!poolAddress || poolAddress === "0x0000000000000000000000000000000000000000") {
|
||||
throw new Error(`No pool found for scope ${scope.toString()}`);
|
||||
throw ContractError.scopeNotFound(scope);
|
||||
}
|
||||
|
||||
// get asset adress from pool
|
||||
@@ -242,6 +243,8 @@ export class ContractInteractionsService implements ContractInteractions {
|
||||
|
||||
return { poolAddress: getAddress(poolAddress as string), assetAddress: getAddress(assetAddress as string) };
|
||||
} catch (error) {
|
||||
if (error instanceof ContractError)
|
||||
throw error;
|
||||
console.error(`Error resolving scope ${scope.toString()}:`, error);
|
||||
throw new Error(`Failed to resolve scope ${scope.toString()}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
||||
}
|
||||
|
||||
@@ -87,38 +87,6 @@ export class WithdrawalService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the context hash for a withdrawal.
|
||||
*/
|
||||
protected calculateContext(withdrawal: Withdrawal): string {
|
||||
const hashString = keccak256(
|
||||
encodeAbiParameters(
|
||||
[
|
||||
{
|
||||
name: "withdrawal",
|
||||
type: "tuple",
|
||||
components: [
|
||||
{ name: "processooor", type: "address" },
|
||||
{ name: "scope", type: "uint256" },
|
||||
{ name: "data", type: "bytes" },
|
||||
],
|
||||
},
|
||||
{ name: "scope", type: "uint256" },
|
||||
],
|
||||
[
|
||||
{
|
||||
processooor: withdrawal.processooor,
|
||||
scope: withdrawal.scope,
|
||||
data: withdrawal.data,
|
||||
},
|
||||
withdrawal.scope,
|
||||
],
|
||||
),
|
||||
);
|
||||
const hashBigint = hexToBigInt(hashString) % SNARK_SCALAR_FIELD;
|
||||
return numberToHex(hashBigint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares input signals for the withdrawal circuit.
|
||||
*/
|
||||
|
||||
@@ -7,7 +7,8 @@ import {
|
||||
PrivacyPoolError,
|
||||
} from "./exceptions/privacyPool.exception.js";
|
||||
import { Commitment, Hash, Secret, Withdrawal } from "./types/index.js";
|
||||
import { encodeAbiParameters, Hex, keccak256 } from "viem";
|
||||
import { encodeAbiParameters, Hex, keccak256, numberToHex } from "viem";
|
||||
import { SNARK_SCALAR_FIELD } from "./constants.js";
|
||||
|
||||
/**
|
||||
* Validates that a bigint value is not zero
|
||||
@@ -126,7 +127,7 @@ export function bigintToHex(num: bigint | string | undefined): Hex {
|
||||
* Calculates the context hash for a withdrawal.
|
||||
*/
|
||||
export function calculateContext(withdrawal: Withdrawal): string {
|
||||
return keccak256(
|
||||
const hash = BigInt(keccak256(
|
||||
encodeAbiParameters(
|
||||
[
|
||||
{
|
||||
@@ -149,5 +150,6 @@ export function calculateContext(withdrawal: Withdrawal): string {
|
||||
withdrawal.scope,
|
||||
],
|
||||
),
|
||||
);
|
||||
)) % SNARK_SCALAR_FIELD;
|
||||
return numberToHex(hash);
|
||||
}
|
||||
|
||||
@@ -103,3 +103,18 @@ export class ProofError extends SDKError {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export class ContractError extends SDKError {
|
||||
constructor(
|
||||
message: string,
|
||||
code: ErrorCode = ErrorCode.CONTRACT_ERROR,
|
||||
details?: Record<string, unknown>,
|
||||
) {
|
||||
super(message, code);
|
||||
this.name = "ContractError";
|
||||
}
|
||||
|
||||
public static scopeNotFound(scope: bigint): ContractError {
|
||||
return new ContractError(`No pool found for scope ${scope.toString()}`, ErrorCode.CONTRACT_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ export { BlockchainProvider } from "./internal.js";
|
||||
|
||||
export { Circuits } from "./circuits/index.js";
|
||||
|
||||
export { ContractInteractionsService } from "./core/contracts.service.js";
|
||||
|
||||
// This file is for re-exporting external dependencies that need to be available to consumers
|
||||
export type { LeanIMTMerkleProof } from "@zk-kit/lean-imt";
|
||||
export type { Address } from "viem";
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
export { binariesMock, CircuitsMock } from "./circuits.mock.js";
|
||||
export { WithdrawalServiceMock } from "./withdrawal.service.mock.js";
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
import { Withdrawal, WithdrawalService } from "../../src/index.js";
|
||||
|
||||
export class WithdrawalServiceMock extends WithdrawalService {
|
||||
override calculateContext(withdrawal: Withdrawal): string {
|
||||
return super.calculateContext(withdrawal);
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,14 @@ import {
|
||||
hashPrecommitment,
|
||||
getCommitment,
|
||||
generateMerkleProof,
|
||||
calculateContext,
|
||||
} from "../../src/crypto.js";
|
||||
import { poseidon } from "maci-crypto/build/ts/hashing.js";
|
||||
import { Secret } from "../../src/types/commitment.js";
|
||||
import { Hash, Secret } from "../../src/types/commitment.js";
|
||||
import { getAddress, Hex, keccak256 } from "viem";
|
||||
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
|
||||
import { SNARK_SCALAR_FIELD } from "../../src/constants.js";
|
||||
import { Withdrawal } from "../../src/index.js";
|
||||
|
||||
describe("Crypto Utilities", () => {
|
||||
describe("generateSecrets", () => {
|
||||
@@ -100,4 +105,27 @@ describe("Crypto Utilities", () => {
|
||||
}).toThrow("Leaf not found in the leaves array.");
|
||||
});
|
||||
});
|
||||
|
||||
describe("calculateContext", () => {
|
||||
it("calculates the context correctly", () => {
|
||||
|
||||
const withdrawal = {
|
||||
processooor: getAddress("0xa513E6E4b8f2a923D98304ec87F64353C4D5C853"),
|
||||
scope: BigInt("0x0555c5fdc167f1f1519c1b21a690de24d9be5ff0bde19447a5f28958d9256e50") as Hash,
|
||||
data: "0x00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000000000000000000000000000000000000000c350" as Hex,
|
||||
};
|
||||
expect(calculateContext(withdrawal)).toStrictEqual("0x21a25ae329bcce0ede103b5f8279c83b61b647dfd2bc8cfac3836456011cf3b6");
|
||||
})
|
||||
|
||||
it("calculates returns a scalar field bounded value", () => {
|
||||
const withdrawal: Withdrawal = {
|
||||
processooor: privateKeyToAccount(generatePrivateKey()).address,
|
||||
scope: BigInt(keccak256(generatePrivateKey())) as Hash,
|
||||
data: keccak256(generatePrivateKey()),
|
||||
};
|
||||
const result = calculateContext(withdrawal);
|
||||
expect(BigInt(result) % SNARK_SCALAR_FIELD).toStrictEqual(BigInt(result));
|
||||
})
|
||||
})
|
||||
|
||||
});
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
import { getAddress, hexToBytes, keccak256 } from "viem/utils";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { Hash, Withdrawal } from "../../src/types/index.js";
|
||||
import { CircuitsMock } from "../mocks/index.js";
|
||||
import { WithdrawalServiceMock } from "../mocks/withdrawal.service.mock.js";
|
||||
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
|
||||
import { SNARK_SCALAR_FIELD } from "../../src/internal.js";
|
||||
|
||||
describe("WithdrawalService", () => {
|
||||
let service: WithdrawalServiceMock;
|
||||
let circuits: CircuitsMock;
|
||||
|
||||
beforeEach(() => {
|
||||
circuits = new CircuitsMock();
|
||||
service = new WithdrawalServiceMock(circuits);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it("calculates the context correctly", () => {
|
||||
const withdrawal: Withdrawal = {
|
||||
processooor: getAddress("0x7359Ca02A152f8F466dc9A4cB3ad1ED62792F46A"),
|
||||
scope: BigInt("12345") as Hash,
|
||||
data: keccak256("0x123")
|
||||
};
|
||||
expect(service.calculateContext(withdrawal)).toStrictEqual(
|
||||
"0x127096bf8b62b2dea071de6617ca1893e1194d06ca4fb3bd3987f27c5c7c7352",
|
||||
);
|
||||
});
|
||||
|
||||
it("calculates returns a scalar field bounded value", () => {
|
||||
const withdrawal: Withdrawal = {
|
||||
processooor: privateKeyToAccount(generatePrivateKey()).address,
|
||||
scope: BigInt(keccak256(generatePrivateKey())) as Hash,
|
||||
data: keccak256(generatePrivateKey()),
|
||||
};
|
||||
const result = service.calculateContext(withdrawal);
|
||||
expect(BigInt(result) % SNARK_SCALAR_FIELD).toStrictEqual(BigInt(result));
|
||||
});
|
||||
});
|
||||
64
yarn.lock
64
yarn.lock
@@ -2,11 +2,6 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@adraffy/ens-normalize@1.10.0":
|
||||
version "1.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.0.tgz#d2a39395c587e092d77cbbc80acf956a54f38bf7"
|
||||
integrity sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==
|
||||
|
||||
"@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"
|
||||
@@ -682,13 +677,6 @@
|
||||
dependencies:
|
||||
"@noble/hashes" "1.3.2"
|
||||
|
||||
"@noble/curves@1.4.0":
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.4.0.tgz#f05771ef64da724997f69ee1261b2417a49522d6"
|
||||
integrity sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg==
|
||||
dependencies:
|
||||
"@noble/hashes" "1.4.0"
|
||||
|
||||
"@noble/curves@1.4.2", "@noble/curves@~1.4.0":
|
||||
version "1.4.2"
|
||||
resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.4.2.tgz#40309198c76ed71bc6dbf7ba24e81ceb4d0d1fe9"
|
||||
@@ -696,7 +684,7 @@
|
||||
dependencies:
|
||||
"@noble/hashes" "1.4.0"
|
||||
|
||||
"@noble/curves@1.8.1", "@noble/curves@^1.4.0", "@noble/curves@^1.6.0", "@noble/curves@~1.8.1":
|
||||
"@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==
|
||||
@@ -713,16 +701,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.4.0.tgz#45814aa329f30e4fe0ba49426f49dfccdd066426"
|
||||
integrity sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==
|
||||
|
||||
"@noble/hashes@1.7.1", "@noble/hashes@^1.4.0", "@noble/hashes@^1.5.0", "@noble/hashes@~1.7.1":
|
||||
"@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==
|
||||
|
||||
"@noble/hashes@~1.5.0":
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.5.0.tgz#abadc5ca20332db2b1b2aa3e496e9af1213570b0"
|
||||
integrity sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA==
|
||||
|
||||
"@nodelib/fs.scandir@2.1.5":
|
||||
version "2.1.5"
|
||||
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
|
||||
@@ -1044,7 +1027,7 @@
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.0.tgz#64c15d791d9b07ced7e89f735b2bd420a41c2e8e"
|
||||
integrity sha512-g2ASy1QwHP88y5KWvblUolJz9rN+i4ZOsYzkEwcNfaNooxNUXG+ON6F5xFo0NIItpHqxcdAyls05VXpBnludGw==
|
||||
|
||||
"@scure/base@~1.1.6", "@scure/base@~1.1.8":
|
||||
"@scure/base@~1.1.6":
|
||||
version "1.1.9"
|
||||
resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.9.tgz#e5e142fbbfe251091f9c5f1dd4c834ac04c3dbd1"
|
||||
integrity sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==
|
||||
@@ -1080,14 +1063,6 @@
|
||||
"@noble/hashes" "~1.4.0"
|
||||
"@scure/base" "~1.1.6"
|
||||
|
||||
"@scure/bip39@1.4.0":
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.4.0.tgz#664d4f851564e2e1d4bffa0339f9546ea55960a6"
|
||||
integrity sha512-BEEm6p8IueV/ZTfQLp/0vhw4NPnT9oWf5+28nvmeUICjP99f4vr2d+qc7AVGDDtwRep6ifR43Yed9ERVmiITzw==
|
||||
dependencies:
|
||||
"@noble/hashes" "~1.5.0"
|
||||
"@scure/base" "~1.1.8"
|
||||
|
||||
"@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"
|
||||
@@ -1561,11 +1536,6 @@ abitype@0.7.1:
|
||||
resolved "https://registry.yarnpkg.com/abitype/-/abitype-0.7.1.tgz#16db20abe67de80f6183cf75f3de1ff86453b745"
|
||||
integrity sha512-VBkRHTDZf9Myaek/dO3yMmOzB/y2s3Zo6nVU7yaw1G+TvCHAjwaJzNGN9yo4K5D8bU/VZXKP1EJpRhFr862PlQ==
|
||||
|
||||
abitype@1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/abitype/-/abitype-1.0.5.tgz#29d0daa3eea867ca90f7e4123144c1d1270774b6"
|
||||
integrity sha512-YzDhti7cjlfaBhHutMaboYB21Ha3rXR9QTkNJFzYC4kC8YclaiwPBBBJY8ejFdu2wnJeZCVZSMlQJ7fi8S6hsw==
|
||||
|
||||
abitype@1.0.8, abitype@^1.0.6:
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/abitype/-/abitype-1.0.8.tgz#3554f28b2e9d6e9f35eb59878193eabd1b9f46ba"
|
||||
@@ -3718,11 +3688,6 @@ isexe@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
|
||||
integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
|
||||
|
||||
isows@1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/isows/-/isows-1.0.4.tgz#810cd0d90cc4995c26395d2aa4cfa4037ebdf061"
|
||||
integrity sha512-hEzjY+x9u9hPmBom9IIAqdJCwNLax+xrPb51vEPpERoFlIxgmZcHzsT5jKG06nvInKOBGvReAVz80Umed5CczQ==
|
||||
|
||||
isows@1.0.6:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/isows/-/isows-1.0.6.tgz#0da29d706fa51551c663c627ace42769850f86e7"
|
||||
@@ -5902,21 +5867,6 @@ vary@~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.21.4:
|
||||
version "2.21.4"
|
||||
resolved "https://registry.yarnpkg.com/viem/-/viem-2.21.4.tgz#b413330f5e05d2ab9ed01bf6e6fe12bcb71788dd"
|
||||
integrity sha512-4E61XWhErjuXh5ObEoosKSy4iMvYnkuQq9jGLW5Isod68dNrENnyNV0QlVpn0LB3qunJ4ZMFMhYdfTjETqe7cQ==
|
||||
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.4.0"
|
||||
abitype "1.0.5"
|
||||
isows "1.0.4"
|
||||
webauthn-p256 "0.0.5"
|
||||
ws "8.17.1"
|
||||
|
||||
viem@2.22.14:
|
||||
version "2.22.14"
|
||||
resolved "https://registry.yarnpkg.com/viem/-/viem-2.22.14.tgz#acf1367704b29f0c00a58260702c9bee05c5dcbd"
|
||||
@@ -6066,14 +6016,6 @@ web3-validator@^2.0.6:
|
||||
web3-types "^1.6.0"
|
||||
zod "^3.21.4"
|
||||
|
||||
webauthn-p256@0.0.5:
|
||||
version "0.0.5"
|
||||
resolved "https://registry.yarnpkg.com/webauthn-p256/-/webauthn-p256-0.0.5.tgz#0baebd2ba8a414b21cc09c0d40f9dd0be96a06bd"
|
||||
integrity sha512-drMGNWKdaixZNobeORVIqq7k5DsRC9FnG201K2QjeOoQLmtSDaSsVZdkg6n5jUALJKcAG++zBPJXmv6hy0nWFg==
|
||||
dependencies:
|
||||
"@noble/curves" "^1.4.0"
|
||||
"@noble/hashes" "^1.4.0"
|
||||
|
||||
which-typed-array@^1.1.16, which-typed-array@^1.1.2:
|
||||
version "1.1.18"
|
||||
resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.18.tgz#df2389ebf3fbb246a71390e90730a9edb6ce17ad"
|
||||
|
||||
Reference in New Issue
Block a user