diff --git a/Dockerfile.interface b/Dockerfile.interface deleted file mode 100644 index 286ec11..0000000 --- a/Dockerfile.interface +++ /dev/null @@ -1,49 +0,0 @@ -# Stage 1: Build -FROM node:22-slim AS builder - -# Install pnpm -RUN npm install -g pnpm - -# Set working directory -WORKDIR /app - -# Copy monorepo files -COPY package.json pnpm-lock.yaml pnpm-workspace.yaml turbo.json ./ - -# Copy all packages and apps -COPY packages ./packages -COPY apps ./apps - -# Install dependencies -RUN pnpm install --frozen-lockfile - -# Build all packages using Turbo -RUN pnpm build - -# Stage 2: Runtime -FROM node:22-slim - -# Install pnpm -RUN npm install -g pnpm - -# Set working directory -WORKDIR /app - -# Copy package.json files and turbo config -COPY package.json pnpm-lock.yaml pnpm-workspace.yaml turbo.json ./ - -# Copy built packages and apps from builder -COPY --from=builder /app/packages ./packages -COPY --from=builder /app/apps/web ./apps/web - -# Install production dependencies only -RUN pnpm install --prod --frozen-lockfile - -# Expose port -EXPOSE 3002 - -# Set environment to production -ENV NODE_ENV=production - -# Start the application -CMD ["pnpm", "--filter=web", "start"] diff --git a/apps/example/package.json b/apps/example/package.json index ac23920..c8e9f47 100644 --- a/apps/example/package.json +++ b/apps/example/package.json @@ -12,25 +12,23 @@ "check-circular-imports": "dpdm --no-warning --no-tree src" }, "devDependencies": { - "@repo/eslint-config": "workspace:*", "@repo/typescript-config": "workspace:*", "@types/json-bigint": "^1.0.4", "@types/node": "^22.15.3", - "dpdm": "^3.14.0", - "eslint": "^9.31.0", + "dpdm": "^3.15.1", "typescript": "5.8.2" }, "dependencies": { "@cardano-ogmios/client": "^6.11.0", - "@minswap/tiny-invariant": "^1.2.0", + "@minswap/felis-dex-v2": "workspace:*", "@minswap/felis-ledger-core": "workspace:*", "@minswap/felis-ledger-utils": "workspace:*", - "@minswap/felis-dex-v2": "workspace:*", + "@minswap/felis-provider": "workspace:*", "@minswap/felis-sundaeswap-v1": "workspace:*", "@minswap/felis-sundaeswap-v3": "workspace:*", "@minswap/felis-syncer": "workspace:*", - "@minswap/felis-provider": "workspace:*", "@minswap/felis-tx-builder": "workspace:*", + "@minswap/tiny-invariant": "^1.2.0", "socket.io-client": "^4.8.3" } } diff --git a/apps/long-short-backend/documents/api-endpoints.md b/apps/long-short-backend/documents/api-endpoints.md new file mode 100644 index 0000000..6b49665 --- /dev/null +++ b/apps/long-short-backend/documents/api-endpoints.md @@ -0,0 +1,70 @@ +# API Endpoints + +## Routes + +| Endpoint | Method | Auth | Purpose | +|----------|--------|------|---------| +| `/health` | GET | No | Health check, silent logging | +| `/metadata` | GET | No | List all enabled markets + Liqwid APYs | +| `/position/get` | GET | No | Fetch user's open position by address | +| `/position/create` | POST | CIP-8 | Create new leveraged position | +| `/position/build-tx` | POST | CIP-8 | Build next transaction in order sequence | +| `/position/close` | POST | CIP-8 | Initiate closing of open position | +| `/liqwid/submit` | POST | CIP-8 | Submit signed Liqwid transaction | + +## Authentication (CIP-8) + +Authenticated endpoints require a signed payload: + +```json +{ + "data": { /* order data */ }, + "user_address": "addr1q...", + "witness": { + "key": "a40101...", + "signature": "844da2..." + } +} +``` + +Verification flow (in `src/api/helper.ts`): +- SHA256 hash of `JSON.stringify(data)` must match the CIP-8 signature +- The `key` field is a COSEKey hex +- The `signature` field is a COSESign1 hex + +## Endpoint Details + +### GET /metadata + +Returns all enabled market configs with Liqwid APY data. No authentication required. + +### GET /position/get + +Query params: `user_address` + +Returns the user's open position (if any) for the given address. + +### POST /position/create + +Creates a new leveraged position. Inserts the position record and pre-creates all order steps for the position lifecycle. + +- LONG positions: 4 opening orders (LONG_BUY, LONG_SUPPLY, LONG_BORROW, LONG_BUY_MORE) +- SHORT positions: 3 opening orders (SHORT_SUPPLY, SHORT_BORROW, SHORT_SELL) + +### POST /position/build-tx + +Core endpoint. Builds the next transaction in the order sequence: +1. Checks for waiting orders (awaiting on-chain confirmation) +2. Finds next unhandled order +3. Builds or rebuilds the transaction as needed +4. Returns `tx_raw` for client to sign and submit + +### POST /position/close + +Initiates closing of an open position. Creates closing order steps: +- LONG: LONG_SELL, LONG_REPAY, LONG_WITHDRAW, LONG_SELL_ALL +- SHORT: SHORT_BUY, SHORT_REPAY, SHORT_WITHDRAW + +### POST /liqwid/submit + +Submits a signed Liqwid transaction to the blockchain. diff --git a/apps/long-short-backend/documents/configuration.md b/apps/long-short-backend/documents/configuration.md new file mode 100644 index 0000000..a41daa5 --- /dev/null +++ b/apps/long-short-backend/documents/configuration.md @@ -0,0 +1,56 @@ +# Configuration & Environment + +## Environment Variables + +| Variable | Required | Default | Description | +|----------|----------|---------|-------------| +| `DATABASE_URL` | Yes | -- | PostgreSQL connection string | +| `CARDANOSCAN_API_KEY` | Yes | -- | Cardanoscan API key | +| `NETWORK` | No | `"mainnet"` | `"mainnet"` or `"testnet_preview"` | +| `API_PORT` | No | `9999` | HTTP server port | +| `API_HOST` | No | `0.0.0.0` | HTTP server host | + +## Market Configuration + +Loaded from the `market_config` database table at startup and cached in memory. + +```typescript +type MarketConfig = { + marketId: string; // e.g. "ADA-NIGHT" + assetA: Asset; // Base asset (lovelace for ADA) + assetB: Asset; // Quote asset + ammLpAsset: string; // Minswap LP token + assetAQTokenTicker: string; // e.g. "qAda" + assetAQTokenRaw: string; // policyId of qToken + assetBQTokenTicker: string; // e.g. "qNIGHT" + assetBQTokenRaw: string; + longCollateralMarketId: string; // Liqwid market ID for long collateral + shortCollateralMarketId: string; // Liqwid market ID for short collateral + borrowMarketIdLong: string; // Liqwid market ID for long borrow + borrowMarketIdShort: string; // Liqwid market ID for short borrow + longLeverage: number; // e.g. 1.5 + shortLeverage: number; // e.g. 0.5 + minCollateral: bigint; // Minimum collateral in lovelace + enable: boolean; +}; +``` + +Hot reload available via `reloadMarketConfigs(db)`. + +## Dependencies + +Key runtime dependencies: + +- **Fastify** v5 -- HTTP server +- **Kysely** v0.28 -- PostgreSQL query builder / ORM +- **TypeBox** v0.34 -- JSON schema validation +- **pg** v8 -- PostgreSQL driver + +Cardano-specific: +- `@cardano-ogmios/client` -- Ogmios client +- `@emurgo/cardano-message-signing-nodejs` -- CIP-8 message signing +- Felis workspace packages (see external-integrations.md) + +## Docker + +PostgreSQL and Redis are available via `docker-compose.yml` at the repo root. diff --git a/apps/long-short-backend/documents/database-schema.md b/apps/long-short-backend/documents/database-schema.md new file mode 100644 index 0000000..b02ef97 --- /dev/null +++ b/apps/long-short-backend/documents/database-schema.md @@ -0,0 +1,86 @@ +# Database Schema + +Technology: **Kysely ORM + PostgreSQL** + +Migrations located in `.config/migrations/` (12 migration files). + +## Tables + +### `position` + +```sql +CREATE TABLE position ( + id BIGSERIAL PRIMARY KEY, + market_id VARCHAR(64) NOT NULL, -- FK -> market_config.market_id + user_address VARCHAR(128) NOT NULL, + side VARCHAR(8) NOT NULL, -- LONG | SHORT + status VARCHAR(16) NOT NULL DEFAULT 'PENDING', -- PENDING | OPEN | CLOSING | CLOSED + amount_in NUMERIC NOT NULL, -- Collateral (lovelace) + amount_borrow NUMERIC NOT NULL, -- Borrow amount + created_at TIMESTAMP NOT NULL DEFAULT now(), + closed_at TIMESTAMP +); + +-- Unique constraint: (user_address, market_id) WHERE closed_at IS NULL +-- Indexes: (market_id), (user_address), (closed_at) +``` + +### `order` + +```sql +CREATE TABLE "order" ( + id BIGSERIAL PRIMARY KEY, + position_id BIGINT NOT NULL, + order_type VARCHAR(32) NOT NULL, -- LONG_BUY, SHORT_SUPPLY, etc. + asset_in VARCHAR(128), + amount_in NUMERIC, + asset_out VARCHAR(128), + amount_out NUMERIC, + built_tx_id VARCHAR(64), -- Hash after local build + built_valid_to TIMESTAMP, -- Transaction expiry + created_tx_id VARCHAR(64), -- Hash when confirmed on-chain + created_tx_index INTEGER, -- Output index + waiting BOOLEAN DEFAULT FALSE -- True while awaiting confirmation +); + +-- Indexes: (position_id), (created_tx_id) +``` + +### `market_config` + +```sql +CREATE TABLE market_config ( + market_id VARCHAR(64) PRIMARY KEY, + asset_a VARCHAR(128) NOT NULL, + asset_b VARCHAR(128) NOT NULL, + amm_lp_asset VARCHAR(128) NOT NULL, + asset_a_q_token_ticker VARCHAR(32) NOT NULL, + asset_a_q_token_raw VARCHAR(128) NOT NULL, + asset_b_q_token_ticker VARCHAR(32) NOT NULL, + asset_b_q_token_raw VARCHAR(128) NOT NULL, + long_collateral_market_id VARCHAR(64) NOT NULL, + short_collateral_market_id VARCHAR(64), + borrow_market_id_long VARCHAR(64), + borrow_market_id_short VARCHAR(64), + long_leverage NUMERIC NOT NULL, + short_leverage NUMERIC NOT NULL, + min_collateral NUMERIC NOT NULL, + enable BOOLEAN DEFAULT TRUE +); + +-- Index: (enable) +``` + +## Migration Commands + +```bash +pnpm --filter=long-short-backend run migrate:latest # Apply all pending migrations +pnpm --filter=long-short-backend run migrate:down # Rollback last migration +pnpm --filter=long-short-backend run codegen # Regenerate src/database/db.d.ts +``` + +## Notes + +- Position IDs are `BIGSERIAL` -- always use `BigInt(row.id)` when mapping rows +- DB types are defined in `src/database/db.d.ts`, use `Generated` for columns with defaults +- `json-bigint` is used for JSON serialization with BigInt values (never native `JSON.stringify`) diff --git a/apps/long-short-backend/documents/external-integrations.md b/apps/long-short-backend/documents/external-integrations.md new file mode 100644 index 0000000..98e42b0 --- /dev/null +++ b/apps/long-short-backend/documents/external-integrations.md @@ -0,0 +1,57 @@ +# External Integrations + +## Cardanoscan Provider + +**File:** `src/provider/cardanoscan.ts` + +On-chain transaction queries to confirm built transactions. + +- `getTransactionList(options)` -- Fetch transactions for an address + +**URLs:** +- Mainnet: `https://api.cardanoscan.io/api/v1` +- Preview: `https://api-preview.cardanoscan.io/api/v1` + +**Auth:** Header `apiKey: {CARDANOSCAN_API_KEY}` + +**Note:** Use `address.toHex()` (not bech32) for Cardanoscan API calls. + +## Liqwid V2 Provider + +**Package:** `@minswap/felis-lending-market` + +Lending protocol integration for supply, borrow, repay, and withdraw operations. + +Key methods: +- `LiqwidProviderV2.Transactions.borrow()` -- Build borrow transaction +- `LiqwidProviderV2.Data.markets()` -- Fetch market APY data +- `LiqwidProviderV2.Data.loansForUser()` -- Fetch active loans + +Legacy `LiqwidProvider` (V1) used for supply transactions. + +## Minswap Aggregator + +**File:** `src/provider/minswap-aggregator.ts` + +Price estimation for swaps. + +- `estimate(request)` -- GET swap output amount + +**URLs:** +- Mainnet: `https://aggr-monorepo-mainnet-prod.minswap.org/aggregator/estimate` +- Preview: `https://aggr.dev-3.minswap.org/aggregator/estimate` + +Used to estimate SHORT borrow amounts: `amount_in * shortLeverage` ADA worth of asset B. + +## Felis Workspace Libraries + +Core Cardano and trading infrastructure from the monorepo: + +| Package | Purpose | +|---------|---------| +| `@minswap/felis-ledger-core` | Address, Asset, Utxo, NetworkEnvironment | +| `@minswap/felis-ledger-utils` | RustModule, Duration, Result, crypto | +| `@minswap/felis-tx-builder` | TxBuilder, CoinSelectionAlgorithm | +| `@minswap/felis-build-tx` | DEXOrderTransaction for Minswap orders | +| `@minswap/felis-dex-v2` | OrderV2, DexVersion, swap direction enums | +| `@minswap/felis-lending-market` | LiqwidProviderV2 for Liqwid lending | diff --git a/apps/long-short-backend/documents/overview.md b/apps/long-short-backend/documents/overview.md new file mode 100644 index 0000000..799e191 --- /dev/null +++ b/apps/long-short-backend/documents/overview.md @@ -0,0 +1,41 @@ +# Long-Short Backend Overview + +A **Fastify API** that orchestrates leveraged long/short positions on Cardano by coordinating DEX swaps (Minswap) with lending (Liqwid) through a multi-step order state machine. + +## Architecture + +``` +src/ +├── cmd/run-api.ts # Entry point +├── api/ +│ ├── server.ts # Fastify setup & route registration +│ ├── routes/ # position, liqwid, metadata endpoints +│ ├── schemas.ts # TypeBox request/response schemas +│ ├── helper.ts # CIP-8 authentication +│ └── state-machine.ts # Order building & waiting logic (CORE) +├── config/market.ts # Market config loading & caching +├── database/ # Kysely types, Postgres, Redis +├── provider/ # Cardanoscan, Kupo, Minswap Aggregator +├── repository/ # Position, Order, MarketConfig repos +├── services/position-service.ts # Business logic orchestration +└── utils/ # Logger, CIP-8 signature, helpers +``` + +## Startup Sequence + +Entry point: `src/cmd/run-api.ts` + +1. Validate environment: `DATABASE_URL`, `CARDANOSCAN_API_KEY`, `NETWORK` +2. Parse network: `"mainnet"` -> MAINNET; else -> TESTNET_PREVIEW +3. Load WASM: `await RustModule.load()` (required for crypto operations) +4. Connect to PostgreSQL via `newKyselyClient(DATABASE_URL)` +5. Load market configs: `loadMarketConfigs(db)` -> in-memory cache +6. Initialize providers: CardanoscanProvider, MinswapAggregatorProvider +7. Start Fastify server: `createApiServer({ port, host, db, networkEnv, cardanoscanProvider })` + +Start commands: + +```bash +npm start # node --import tsx src/cmd/run-api.ts +npm run dev # node --import tsx --watch src/cmd/run-api.ts +``` diff --git a/apps/long-short-backend/documents/services-and-repositories.md b/apps/long-short-backend/documents/services-and-repositories.md new file mode 100644 index 0000000..3eba7a2 --- /dev/null +++ b/apps/long-short-backend/documents/services-and-repositories.md @@ -0,0 +1,77 @@ +# Services & Repositories + +## PositionService + +**File:** `src/services/position-service.ts` + +Business logic orchestration layer. Main methods: + +### createPosition(input) +Creates a position record and pre-creates all order steps: +- LONG: 4 orders (LONG_BUY, LONG_SUPPLY, LONG_BORROW, LONG_BUY_MORE) +- SHORT: 3 orders (SHORT_SUPPLY, SHORT_BORROW, SHORT_SELL) + +### buildTx(input) +Core workflow: +1. Check for waiting order -> confirm or return waiting status +2. Find next unhandled order -> build or rebuild transaction +3. Return `tx_raw` for client signing + +### closePosition(input) +Initiates closing order sequence: +- LONG: LONG_SELL, LONG_REPAY, LONG_WITHDRAW, LONG_SELL_ALL +- SHORT: SHORT_BUY, SHORT_REPAY, SHORT_WITHDRAW + +### getPositionMetrics(position) +Calculates: entry_price, liquidation_price, interest, unrealized_pnl, health. + +--- + +## Repositories + +### OrderRepository + +**File:** `src/repository/order-repository.ts` + +| Method | Description | +|--------|-------------| +| `createOrder(s)` | Insert order(s) into DB | +| `getOrdersByPositionId` | Fetch all orders for a position | +| `getNextUnhandledOrder` | Find next order to execute (has asset_in, no created_tx_id) | +| `getWaitingOrder` | Find order with waiting = true | +| `updateOrderBuiltTx` | Set built_tx_id, built_valid_to after building | +| `updateOrderCreatedTx` | Set created_tx_id, created_tx_index when confirmed on-chain | +| `updateOrderNextDetails` | Update asset_in/amount_in from previous order's output | + +### PositionRepository + +**File:** `src/repository/position-repository.ts` + +| Method | Description | +|--------|-------------| +| `createPosition` | Insert position with status PENDING | +| `getOpenPositionByUser` | Find user's open position | +| `getOpenPositionByUserAndMarket` | Find position for specific market | +| `updatePositionStatus` | Transition status (auto-sets closed_at if CLOSED) | + +### MarketConfigRepository + +**File:** `src/repository/market-config-repository.ts` + +Handles CRUD for the `market_config` table. + +--- + +## Market Config Cache + +**File:** `src/config/market.ts` + +In-memory cache for market configurations: + +| Function | Description | +|----------|-------------| +| `loadMarketConfigs(db)` | Load all markets into cache (called at startup) | +| `getEnabledMarketConfigs()` | Returns enabled markets only | +| `getMarketConfig(marketId)` | Get single market from cache | +| `isSupportedMarket(marketId)` | Check if market is enabled | +| `reloadMarketConfigs(db)` | Hot reload cache | diff --git a/apps/long-short-backend/documents/state-machine.md b/apps/long-short-backend/documents/state-machine.md new file mode 100644 index 0000000..64a35d6 --- /dev/null +++ b/apps/long-short-backend/documents/state-machine.md @@ -0,0 +1,118 @@ +# Order State Machine + +## Position Status Flow + +``` +PENDING -> OPEN -> CLOSING -> CLOSED +``` + +## LONG Position Lifecycle + +### Opening Sequence (4 orders) + +``` +1. LONG_BUY -> Swap ADA -> Asset B (DEX swap A_TO_B) +2. LONG_SUPPLY -> Supply Asset B to Liqwid -> receive qB collateral +3. LONG_BORROW -> Borrow ADA using qB as collateral (Liqwid V2) +4. LONG_BUY_MORE -> Swap borrowed ADA -> Asset B (DEX swap A_TO_B) + -> Position status transitions to OPEN +``` + +### Closing Sequence (4 orders) + +``` +1. LONG_SELL -> Swap Asset B -> ADA (DEX swap B_TO_A) +2. LONG_REPAY -> Repay ADA loan, redeem qB collateral +3. LONG_WITHDRAW -> Withdraw Asset B from Liqwid +4. LONG_SELL_ALL -> Swap remaining Asset B -> ADA (DEX swap B_TO_A) + -> Position status transitions to CLOSED +``` + +## SHORT Position Lifecycle + +### Opening Sequence (3 orders) + +``` +1. SHORT_SUPPLY -> Supply ADA to Liqwid -> receive qADA collateral +2. SHORT_BORROW -> Borrow Asset B using qADA as collateral +3. SHORT_SELL -> Swap Asset B -> ADA (DEX swap B_TO_A) + -> Position status transitions to OPEN +``` + +### Closing Sequence (3 orders) + +``` +1. SHORT_BUY -> Swap ADA -> Asset B (DEX swap A_TO_B) to buy back +2. SHORT_REPAY -> Repay Asset B loan, redeem qADA collateral +3. SHORT_WITHDRAW -> Withdraw ADA from Liqwid + -> Position status transitions to CLOSED +``` + +## Transaction Lifecycle (per order) + +``` +1. build-tx called + -> StateMachine handler builds tx -> built_tx_id set + +2. Client signs & submits tx to blockchain + +3. Next build-tx call + -> Cardanoscan API finds tx on-chain + -> created_tx_id set, waiting = true + +4. Next build-tx call + -> waiting function checks if output is spent + -> If spent: extract amounts, update next order's asset_in/amount_in + -> If not spent: return "waiting" status with remaining time +``` + +## buildTx() Algorithm + +``` +1. Check for waiting order (created_tx_id set, waiting = true) + a. Call waiting function for order type (e.g., waitingLongBuy) + b. If confirmed: transition to next order or complete position + c. If not confirmed: return waiting message + +2. Find next unhandled order + (has assetIn/amountIn/assetOut, created_tx_id is null/empty) + +3. If order has built_tx_id: + a. Search for it on Cardanoscan + b. If found: set created_tx_id, return waiting + c. If not found & expired: rebuild + d. If not found & not expired: return waiting with time remaining + +4. Build new transaction + a. Call appropriate StateMachine handler + b. Set built_tx_id and built_valid_to + c. Return tx_raw for client to sign +``` + +## State Machine Handlers + +Located in `src/api/state-machine.ts`. Each handler returns `BuiltResult = { txRaw, txId, validTo }`. + +**LONG handlers:** +- `handleLongBuy` / `waitingLongBuy` +- `handleLongSupply` / `waitingLongSupply` +- `handleLongBorrow` / `waitingLongBorrow` +- `handleLongBuyMore` / `waitingLongBuyMore` +- `handleLongSell` / `waitingLongSell` +- `handleLongRepay` / `waitingLongRepay` +- `handleLongWithdraw` / `waitingLongWithdraw` + +**SHORT handlers:** +- `handleShortSupply` / `waitingShortSupply` +- `handleShortBorrow` / `waitingShortBorrow` +- `handleShortSell` / `waitingShortSell` +- `handleShortBuy` / `waitingShortBuy` +- `handleShortRepay` / `waitingShortRepay` +- `handleShortWithdraw` / `waitingShortWithdraw` + +## Leverage Calculation + +- **LONG**: `amountBorrow = amountIn * (longLeverage - 1) + 4_000_000` (lovelace) + - Example: 600 ADA at 1.5x -> borrow 304 ADA +- **SHORT**: `amountBorrow = aggregator.estimate(amountIn * shortLeverage)` (in asset B units) + - Example: 600 ADA at 0.5x -> estimate 300 ADA worth of asset B -> borrow that amount diff --git a/apps/long-short-backend/package.json b/apps/long-short-backend/package.json index d012608..7c10486 100644 --- a/apps/long-short-backend/package.json +++ b/apps/long-short-backend/package.json @@ -16,14 +16,12 @@ }, "devDependencies": { "@cardano-ogmios/schema": "^6.11.0", - "@repo/eslint-config": "workspace:*", "@repo/typescript-config": "workspace:*", "@types/crypto-js": "^4.2.2", "@types/json-bigint": "^1.0.4", "@types/node": "^22.15.3", "@types/pg": "^8.16.0", - "dpdm": "^3.14.0", - "eslint": "^9.31.0", + "dpdm": "^3.15.1", "kysely-codegen": "^0.19.0", "kysely-ctl": "^0.19.0", "tsx": "^4.19.4", @@ -34,6 +32,8 @@ "@cardano-ogmios/client": "^6.14.0", "@emurgo/cardano-message-signing-nodejs": "^1.0.1", "@fastify/cors": "^10.0.2", + "@fastify/helmet": "^13.0.2", + "@fastify/rate-limit": "^10.3.0", "@minswap/felis-build-tx": "workspace:*", "@minswap/felis-cip": "workspace:*", "@minswap/felis-dex-v1": "workspace:*", @@ -52,7 +52,7 @@ "fastify": "^5.2.2", "ioredis": "^5.9.0", "json-bigint": "^1.0.0", - "kysely": "^0.28.11", + "kysely": "^0.28.14", "p-timeout": "^7.0.1", "pg": "^8.16.3", "remeda": "^2.33.1", diff --git a/apps/long-short-backend/src/api/routes/metadata.ts b/apps/long-short-backend/src/api/routes/metadata.ts index d96f2e7..1d00474 100644 --- a/apps/long-short-backend/src/api/routes/metadata.ts +++ b/apps/long-short-backend/src/api/routes/metadata.ts @@ -6,9 +6,10 @@ import { API_ENDPOINTS } from "../../constants"; import { logger } from "../../utils"; import { type MarketConfigResponseType, MetadataResponseSchema, type MetadataResponseType } from "../schemas"; -type LiqwidMarketApyMap = Map; +type LiqwidMarketData = { borrowAPY: number; supplyAPY: number; minValue: string }; +type LiqwidMarketDataMap = Map; -function marketConfigToResponse(config: MarketConfig, liqwidApys: LiqwidMarketApyMap): MarketConfigResponseType { +function marketConfigToResponse(config: MarketConfig, liqwidApys: LiqwidMarketDataMap): MarketConfigResponseType { const assetAApys = liqwidApys.get(config.borrowMarketIdLong); const assetBApys = liqwidApys.get(config.borrowMarketIdShort); @@ -28,18 +29,21 @@ function marketConfigToResponse(config: MarketConfig, liqwidApys: LiqwidMarketAp min_collateral: config.minCollateral.toString(), asset_a_borrow_apy: assetAApys?.borrowAPY ?? null, asset_a_supply_apy: assetAApys?.supplyAPY ?? null, + asset_a_min_value: assetAApys?.minValue ?? null, asset_b_borrow_apy: assetBApys?.borrowAPY ?? null, asset_b_supply_apy: assetBApys?.supplyAPY ?? null, + asset_b_min_value: assetBApys?.minValue ?? null, }; } -async function fetchLiqwidMarketApys(networkEnv: NetworkEnvironment): Promise { - const apyMap: LiqwidMarketApyMap = new Map(); +async function fetchLiqwidMarketApys(networkEnv: NetworkEnvironment): Promise { + const apyMap: LiqwidMarketDataMap = new Map(); const config = LiqwidProviderV2.createConfig(networkEnv); const result = await LiqwidProviderV2.Data.markets(config); if (result.type === "ok") { for (const market of result.value.results) { - apyMap.set(market.id, { borrowAPY: market.borrowAPY, supplyAPY: market.supplyAPY }); + const minValue = (market.parameters.minValue * 1_000_000).toString(); + apyMap.set(market.id, { borrowAPY: market.borrowAPY, supplyAPY: market.supplyAPY, minValue }); } } else { logger.error("Failed to fetch Liqwid market data", { error: result.error }); diff --git a/apps/long-short-backend/src/api/routes/position.ts b/apps/long-short-backend/src/api/routes/position.ts index e562481..91b9ead 100644 --- a/apps/long-short-backend/src/api/routes/position.ts +++ b/apps/long-short-backend/src/api/routes/position.ts @@ -18,6 +18,10 @@ import { CreatePositionResponseSchema, type CreatePositionResponseType, ErrorResponseSchema, + GetDebtQuerySchema, + type GetDebtQueryType, + GetDebtResponseSchema, + type GetDebtResponseType, GetPositionQuerySchema, type GetPositionQueryType, GetPositionResponseSchema, @@ -247,4 +251,31 @@ export function registerPositionRoutes(fastify: FastifyInstance, positionService }); }, ); + + // GET /position/debt?user_address=...&market_id=... + fastify.get<{ + Querystring: GetDebtQueryType; + Reply: GetDebtResponseType; + }>( + API_ENDPOINTS.POSITION_DEBT, + { + schema: { + querystring: GetDebtQuerySchema, + response: { + 200: GetDebtResponseSchema, + 400: ErrorResponseSchema, + }, + }, + }, + async (request, reply) => { + const { user_address, market_id } = request.query; + + const debt = await positionService.getDebt(user_address, market_id); + + return reply.status(200).send({ + success: true, + data: debt, + }); + }, + ); } diff --git a/apps/long-short-backend/src/api/schemas.ts b/apps/long-short-backend/src/api/schemas.ts index 7831c38..09756ff 100644 --- a/apps/long-short-backend/src/api/schemas.ts +++ b/apps/long-short-backend/src/api/schemas.ts @@ -83,6 +83,28 @@ export const GetPositionResponseSchema = Type.Object({ export type GetPositionResponseType = Static; +// Debt schemas +export const GetDebtQuerySchema = Type.Object({ + user_address: Type.String({ minLength: 1, description: "User's Cardano address (bech32)" }), + market_id: Type.String({ minLength: 1, description: "Market ID (e.g., ADA-MIN)" }), +}); + +export type GetDebtQueryType = Static; + +export const GetDebtResponseSchema = Type.Object({ + success: Type.Boolean(), + data: Type.Union([ + Type.Object({ + amount: Type.String({ description: "Debt amount in raw units (with decimals 1e6)" }), + asset: Type.String({ description: "Debt asset identifier" }), + }), + Type.Null(), + ]), + error: Type.Optional(Type.String()), +}); + +export type GetDebtResponseType = Static; + // Build TX schemas export const BuildTxDataSchema = Type.Object({ market_id: Type.String({ description: "Market identifier (e.g., ADA-MIN)" }), @@ -183,12 +205,18 @@ export const MarketConfigResponseSchema = Type.Object({ asset_a_supply_apy: Type.Union([Type.Number(), Type.Null()], { description: "Liqwid supply APY for asset A", }), + asset_a_min_value: Type.Union([Type.String(), Type.Null()], { + description: "Liqwid minimum value for asset A in lovelace", + }), asset_b_borrow_apy: Type.Union([Type.Number(), Type.Null()], { description: "Liqwid borrow APY for asset B", }), asset_b_supply_apy: Type.Union([Type.Number(), Type.Null()], { description: "Liqwid supply APY for asset B", }), + asset_b_min_value: Type.Union([Type.String(), Type.Null()], { + description: "Liqwid minimum value for asset B in lovelace", + }), }); export type MarketConfigResponseType = Static; diff --git a/apps/long-short-backend/src/api/server.ts b/apps/long-short-backend/src/api/server.ts index 7170851..c3eaa70 100644 --- a/apps/long-short-backend/src/api/server.ts +++ b/apps/long-short-backend/src/api/server.ts @@ -1,10 +1,12 @@ import cors from "@fastify/cors"; +import helmet from "@fastify/helmet"; +import rateLimit from "@fastify/rate-limit"; import type { NetworkEnvironment } from "@minswap/felis-ledger-core"; -import Fastify, { type FastifyInstance } from "fastify"; +import Fastify, { type FastifyError, type FastifyInstance } from "fastify"; import type { Kysely } from "kysely"; import { API_ENDPOINTS } from "../constants"; import type { DB } from "../database"; -import { type CardanoscanProvider, MinswapAggregatorProvider } from "../provider"; +import { type CardanoscanProvider, type KupoService, MinswapAggregatorProvider } from "../provider"; import { PositionService } from "../services/position-service"; import { logger } from "../utils"; import { registerLiqwidRoutes } from "./routes/liqwid"; @@ -16,16 +18,31 @@ export type ApiServerOptions = { host: string; db: Kysely; cardanoscanProvider: CardanoscanProvider; + kupoService: KupoService; networkEnv: NetworkEnvironment; }; export async function createApiServer(options: ApiServerOptions): Promise { - const { port, host, db, networkEnv, cardanoscanProvider } = options; + const { port, host, db, networkEnv, cardanoscanProvider, kupoService } = options; const fastify = Fastify({ logger: { level: "info", }, + requestTimeout: 30_000, + connectionTimeout: 10_000, + }); + + // Security headers + await fastify.register(helmet, { + contentSecurityPolicy: false, // Disable CSP for API-only server + }); + + // Rate limiting + await fastify.register(rateLimit, { + max: 200, + timeWindow: "1 minute", + allowList: ["127.0.0.1", "::1"], }); // Register CORS @@ -34,14 +51,42 @@ export async function createApiServer(options: ApiServerOptions): Promise { + // Validation errors (schema validation failures) + if (error.validation) { + return reply.status(400).send({ + success: false, + error: error.message, + }); + } + + // Rate limit errors + if (error.statusCode === 429) { + return reply.status(429).send({ + success: false, + error: "Too many requests, please try again later", + }); + } + + // Log unexpected errors + request.log.error({ err: error, url: request.url, method: request.method }, "Unhandled error"); + + const statusCode = error.statusCode && error.statusCode >= 400 ? error.statusCode : 500; + return reply.status(statusCode).send({ + success: false, + error: statusCode >= 500 ? "Internal server error" : error.message, + }); + }); + // Health check endpoint (disable logging to reduce noise) - fastify.get(API_ENDPOINTS.HEALTH, { logLevel: "silent" }, async () => { + fastify.get(API_ENDPOINTS.HEALTH, { logLevel: "silent", config: { rateLimit: false } }, async () => { return { status: "ok" }; }); // Create services const aggregatorProvider = new MinswapAggregatorProvider(networkEnv); - const positionService = new PositionService(db, networkEnv, cardanoscanProvider, aggregatorProvider); + const positionService = new PositionService(db, networkEnv, cardanoscanProvider, aggregatorProvider, kupoService); // Register routes registerLiqwidRoutes(fastify, networkEnv); diff --git a/apps/long-short-backend/src/api/state-machine.ts b/apps/long-short-backend/src/api/state-machine.ts index 864b25f..a5bc093 100644 --- a/apps/long-short-backend/src/api/state-machine.ts +++ b/apps/long-short-backend/src/api/state-machine.ts @@ -6,7 +6,9 @@ import { LiqwidProvider, LiqwidProviderV2 } from "@minswap/felis-lending-market" import { CoinSelectionAlgorithm, EmulatorProvider } from "@minswap/felis-tx-builder"; import invariant from "@minswap/tiny-invariant"; import type { MarketConfig } from "../config"; +import { DEFAULT_DENOMINATOR, ERROR_BUILD_TX_CODE, REPAY_MIN_VALUE_THRESHOLD_NUM } from "../constants"; import { CardanoscanProvider } from "../provider"; +import type { KupoService } from "../provider/kupo"; import { logger } from "../utils"; export namespace StateMachine { export enum PositionSide { @@ -41,6 +43,9 @@ export namespace StateMachine { SHORT_SELL = "SHORT_SELL", SHORT_BUY = "SHORT_BUY", SHORT_REPAY = "SHORT_REPAY", + SHORT_REPAY_FRACTION = "SHORT_REPAY_FRACTION", + SHORT_WITHDRAW_FRACTION = "SHORT_WITHDRAW_FRACTION", + SHORT_BUY_FREED = "SHORT_BUY_FREED", SHORT_WITHDRAW = "SHORT_WITHDRAW", } @@ -48,6 +53,19 @@ export namespace StateMachine { txRaw: string; txId: string; validTo: number; + /** When set, position-service should switch from fractional to full repay flow */ + redirectToFullRepay?: { + /** The order type to update (e.g. SHORT_REPAY) */ + targetOrderType: string; + /** Amount in for the full repay order */ + amountIn: string; + /** Asset in for the full repay order */ + assetIn: string; + /** Expected output asset for the full repay order */ + assetOut: string; + /** Fractional order types to delete */ + deleteOrderTypes: string[]; + }; }; // Common order data type for all Handle functions @@ -73,6 +91,8 @@ export namespace StateMachine { loanOutputIndex?: number; /** Collateral qToken amount (used for SHORT_REPAY to redeem collateral) */ collateralAmount?: string; + /** Kupo service for querying user wallet balance */ + kupoService: KupoService; }; export const handleLongBuy = async (options: HandleBuildTxOptions): Promise => { @@ -266,7 +286,7 @@ export namespace StateMachine { userAddress: string, marketConfig: MarketConfig, availableADA: number, - ): Promise<{ canFullRepay: boolean; loan: LiqwidProviderV2.Loan; loanAmount: bigint }> => { + ): Promise<{ canFullRepay: boolean; canRepay: boolean; loan: LiqwidProviderV2.Loan; loanAmount: bigint }> => { const apiConfig = LiqwidProviderV2.createConfig(networkEnv); const userAddr = Address.fromBech32(userAddress); const pkh = userAddr.toPubKeyHash()?.keyHash.hex; @@ -277,8 +297,23 @@ export namespace StateMachine { } const loan = loansResult.value.find((l) => l.marketId === marketConfig.borrowMarketIdLong); invariant(loan, `No active loan found for market ${marketConfig.borrowMarketIdLong}`); - const loanAmount = BigInt(Math.round(loan.amount * 1_000_000)); // ADA → Lovelace (Math.round avoids BigInt non-integer rejection) - return { canFullRepay: BigInt(availableADA) >= loanAmount, loan, loanAmount }; + const loanAmount = BigInt(Math.round(loan.amount * 1_000_000)); + const canFullRepay = BigInt(availableADA) >= loanAmount; + + let canRepay = true; + const marketsResult = await LiqwidProviderV2.Data.markets(apiConfig, { + ids: [marketConfig.borrowMarketIdLong], + }); + if (marketsResult.type === "ok" && marketsResult.value.results.length > 0) { + const liqwidMarket = marketsResult.value.results[0]; + const minValueRaw = BigInt(Math.round(liqwidMarket.parameters.minValue * 1_000_000)); + const minThreshold = (minValueRaw * REPAY_MIN_VALUE_THRESHOLD_NUM) / DEFAULT_DENOMINATOR; + if (!canFullRepay && loanAmount <= minThreshold) { + canRepay = false; + } + } + + return { canFullRepay, canRepay, loan, loanAmount }; }; /** @@ -287,7 +322,7 @@ export namespace StateMachine { * Fetches loan from Liqwid API to get current UTXO and collateral info. */ export const handleLongRepay = async (options: HandleBuildTxOptions): Promise => { - const { order, marketConfig, userAddress, networkEnv, utxos } = options; + const { order, marketConfig, userAddress, networkEnv, utxos, kupoService } = options; invariant(order.orderType === LongOrderType.LONG_REPAY, "Invalid order type for handleLongRepay"); invariant(order.assetIn, "assetIn is required for LONG_REPAY order"); invariant(order.amountIn, "amountIn is required for LONG_REPAY order"); @@ -305,6 +340,14 @@ export namespace StateMachine { const loan = loansResult.value.find((l) => l.marketId === marketConfig.borrowMarketIdLong); invariant(loan, `No active loan found for market ${marketConfig.borrowMarketIdLong}`); + // Check if the user has enough ADA in wallet to cover the full debt + const loanAmountRaw = BigInt(Math.round(loan.amount * 1_000_000)); + const walletBalance = await kupoService.getBalanceOfPubKeyAddress(userAddress); + const availableAda = walletBalance.get(marketConfig.assetA); + if (availableAda < loanAmountRaw) { + throw new Error(ERROR_BUILD_TX_CODE.ERROR_CANNOT_REPAY); + } + const loanUtxoId = `${loan.transactionId}-${loan.transactionIndex}`; // Format collateral ID as "{MarketId}.{policyId}" @@ -404,7 +447,7 @@ export namespace StateMachine { * Step 2 (LONG_WITHDRAW_FRACTION) reduces collateral proportionally in a separate tx. */ export const handleLongRepayFraction = async (options: HandleBuildTxOptions): Promise => { - const { order, marketConfig, userAddress, networkEnv, utxos } = options; + const { order, marketConfig, userAddress, networkEnv, utxos, kupoService } = options; invariant(order.orderType === LongOrderType.LONG_REPAY_FRACTION, "Invalid order type for handleLongRepayFraction"); invariant(order.assetIn, "assetIn is required for LONG_REPAY_FRACTION order"); invariant(order.amountIn, "amountIn (ADA available to repay) is required for LONG_REPAY_FRACTION order"); @@ -438,6 +481,35 @@ export namespace StateMachine { // loan.amount is in ADA (float); convert to Lovelace to match order.amountIn and API expectations. const currentDebtLovelace = Math.round(loan.amount * 1_000_000); const availableLovelace = Number(order.amountIn); // already in Lovelace + + // Query wallet balance via Kupo — if wallet has enough ADA, build full repay tx instead + const walletBalance = await kupoService.getBalanceOfPubKeyAddress(userAddress); + const walletAda = walletBalance.get(marketConfig.assetA); + if (walletAda >= BigInt(currentDebtLovelace)) { + logger.info("handleLongRepayFraction: wallet has enough for full repay, redirecting", { + walletAda: walletAda.toString(), + currentDebtLovelace, + }); + const fullRepayResult = await handleLongRepay({ + ...options, + order: { ...order, orderType: LongOrderType.LONG_REPAY, amountIn: walletAda.toString() }, + }); + return { + ...fullRepayResult, + redirectToFullRepay: { + targetOrderType: LongOrderType.LONG_REPAY, + amountIn: walletAda.toString(), + assetIn: marketConfig.assetA.toString(), + assetOut: marketConfig.assetBQTokenRaw, + deleteOrderTypes: [ + LongOrderType.LONG_REPAY_FRACTION, + LongOrderType.LONG_WITHDRAW_FRACTION, + LongOrderType.LONG_SELL_FREED, + ], + }, + }; + } + const qTokenAmountFloat = loan.collaterals[0]?.qTokenAmount; invariant(qTokenAmountFloat !== undefined, "Loan has no collateral — cannot compute partial repay"); // qTokenAmount from API is human-readable (divided by 10^6), convert to raw on-chain amount @@ -446,6 +518,12 @@ export namespace StateMachine { // Remaining debt must stay >= minValue so the position stays protocol-legal. const newDebt = Math.max(currentDebtLovelace - availableLovelace, minValueLovelace); + // Check: both the repay amount AND remaining debt must be >= minValue. + const repayAmount = currentDebtLovelace - newDebt; + if (repayAmount < minValueLovelace || (availableLovelace < currentDebtLovelace && newDebt < minValueLovelace)) { + throw new Error(ERROR_BUILD_TX_CODE.ERROR_CANNOT_REPAY); + } + logger.info("handleLongRepayFraction", { currentDebtLovelace, availableLovelace, @@ -680,19 +758,24 @@ export namespace StateMachine { const amountOut = BigInt(output.value); // Check if we now have enough ADA to fully repay the remaining loan. - const { canFullRepay, loanAmount } = await checkLongRepayFunds( + const { canFullRepay, canRepay, loanAmount } = await checkLongRepayFunds( networkEnv, userAddress.bech32, marketConfig, Number(amountOut), ); - logger.info("waitingLongSellFreed: canFullRepay check", { + logger.info("waitingLongSellFreed: repay check", { available: amountOut.toString(), loanAmount: loanAmount.toString(), canFullRepay, + canRepay, }); + if (!canRepay) { + throw new Error(ERROR_BUILD_TX_CODE.ERROR_CANNOT_REPAY); + } + if (canFullRepay) { // Enough ADA → transition to existing LONG_REPAY (from closePosition) return { @@ -991,28 +1074,98 @@ export namespace StateMachine { }; }; + const checkShortRepayFunds = async ( + networkEnv: NetworkEnvironment, + userAddress: string, + marketConfig: MarketConfig, + availableAssetB: number, + ): Promise<{ + canFullRepay: boolean; + canRepay: boolean; + loan: LiqwidProviderV2.Loan; + loanAmountRaw: bigint; + }> => { + const apiConfig = LiqwidProviderV2.createConfig(networkEnv); + const userAddr = Address.fromBech32(userAddress); + const pkh = userAddr.toPubKeyHash()?.keyHash.hex; + invariant(pkh, "Failed to extract public key hash from user address"); + const loansResult = await LiqwidProviderV2.Data.loansForUser(apiConfig, [pkh]); + if (loansResult.type === "err") { + throw new Error(`Failed to fetch loans before short repay: ${loansResult.error.message}`); + } + const loan = loansResult.value.find((l) => l.marketId === marketConfig.borrowMarketIdShort); + invariant(loan, `No active loan found for market ${marketConfig.borrowMarketIdShort}`); + const loanAmountRaw = BigInt(Math.round(loan.amount * 1_000_000)); + const canFullRepay = BigInt(availableAssetB) >= loanAmountRaw; + + // Fetch Liqwid market minValue to check if repay is possible + // Liqwid requires: repay >= minValue AND remaining debt >= minValue (or full repay) + // If debt <= minValue * REPAY_MIN_VALUE_THRESHOLD_NUM / DEFAULT_DENOMINATOR, neither full nor fractional repay is possible without more funds + const marketsResult = await LiqwidProviderV2.Data.markets(apiConfig, { + ids: [marketConfig.borrowMarketIdShort], + }); + let canRepay = true; + if (marketsResult.type === "ok" && marketsResult.value.results.length > 0) { + const liqwidMarket = marketsResult.value.results[0]; + const minValueRaw = BigInt(Math.round(liqwidMarket.parameters.minValue * 1_000_000)); + // Threshold: debt must be > minValue * multiplier for fractional repay to work + // (repay portion >= minValue AND leftover >= minValue) + const minThreshold = (minValueRaw * REPAY_MIN_VALUE_THRESHOLD_NUM) / DEFAULT_DENOMINATOR; + + if (!canFullRepay && loanAmountRaw <= minThreshold) { + canRepay = false; + } + } + + return { canFullRepay, canRepay, loan, loanAmountRaw }; + }; + /** - * Build SHORT_REPAY transaction: Repay asset B loan to Liqwid and redeem qADA collateral + * Build SHORT_REPAY transaction: Full repay — pay off entire loan and redeem all collateral. + * Fetches loan from Liqwid API to get current UTXO and collateral info. */ export const handleShortRepay = async (options: HandleBuildTxOptions): Promise => { - const { order, marketConfig, userAddress, networkEnv, utxos, loanTxId, loanOutputIndex, collateralAmount } = - options; + const { order, marketConfig, userAddress, networkEnv, utxos, kupoService } = options; invariant(order.orderType === ShortOrderType.SHORT_REPAY, "Invalid order type for handleShortRepay"); invariant(order.assetIn, "assetIn is required for SHORT_REPAY order"); invariant(order.amountIn, "amountIn is required for SHORT_REPAY order"); - invariant(loanTxId, "loanTxId is required for SHORT_REPAY order"); - invariant(loanOutputIndex !== undefined, "loanOutputIndex is required for SHORT_REPAY order"); - invariant(collateralAmount, "collateralAmount is required for SHORT_REPAY order"); const apiConfig = LiqwidProviderV2.createConfig(networkEnv); - // Format loanUtxoId as "{txHash}-{outputIndex}" - const loanUtxoId = `${loanTxId}-${loanOutputIndex}`; + // Fetch current loan from API (always up-to-date, even after modifyBorrow) + const userAddr = Address.fromBech32(userAddress); + const pkh = userAddr.toPubKeyHash()?.keyHash.hex; + invariant(pkh, "Failed to extract public key hash from user address"); + const loansResult = await LiqwidProviderV2.Data.loansForUser(apiConfig, [pkh]); + if (loansResult.type === "err") { + throw new Error(`Failed to fetch loans for full repay: ${loansResult.error.message}`); + } + const loan = loansResult.value.find((l) => l.marketId === marketConfig.borrowMarketIdShort); + invariant(loan, `No active loan found for market ${marketConfig.borrowMarketIdShort}`); + + // Check if the user has enough asset B in wallet to cover the full debt + const loanAmountRaw = BigInt(Math.round(loan.amount * 1_000_000)); + const walletBalance = await kupoService.getBalanceOfPubKeyAddress(userAddress); + const availableRaw = walletBalance.get(marketConfig.assetB); + if (availableRaw < loanAmountRaw) { + throw new Error(ERROR_BUILD_TX_CODE.ERROR_CANNOT_REPAY); + } + + const loanUtxoId = `${loan.transactionId}-${loan.transactionIndex}`; - // Format collateral ID: use assetAQTokenRaw (qADA) for SHORT - const qTokenParts = marketConfig.assetAQTokenRaw.split("."); - const qTokenPolicyId = qTokenParts[0]; - const collateralId = `${marketConfig.borrowMarketIdShort}.${qTokenPolicyId}`; + const collateral = loan.collaterals[0]; + invariant(collateral, "Loan has no collateral"); + invariant(collateral.market, "Loan collateral has no market info"); + const qTokenAmountRaw = Math.round(collateral.qTokenAmount * 1_000_000); + const collateralId = `${collateral.market.id}.${collateral.id}`; + + logger.info("handleShortRepay: full repay", { + loanId: loan.id, + loanAmount: loan.amount, + qTokenAmountRaw, + loanUtxoId, + collateralId, + }); const buildTxResult = await LiqwidProviderV2.Transactions.repayLoan(apiConfig, { address: userAddress, @@ -1021,7 +1174,7 @@ export namespace StateMachine { collaterals: [ { id: collateralId, - amount: Number(collateralAmount), + amount: qTokenAmountRaw, }, ], }); @@ -1048,6 +1201,406 @@ export namespace StateMachine { }; }; + // ============================================================================ + // FRACTIONAL SHORT REPAY FLOW + // ============================================================================ + // + // Triggered when SHORT_BUY output (asset B received) < current loan amount. + // + // Full cycle until position is fully closed: + // + // SHORT_BUY + // │ (asset B received < loan) + // ▼ + // SHORT_REPAY_FRACTION ──── modifyBorrow(newDebt, keepCollateral) + // │ + // ▼ + // SHORT_WITHDRAW_FRACTION ── modifyBorrow(sameDebt, reducedCollateral, redeemCollateral=true) → ADA + // │ + // ▼ + // SHORT_BUY_FREED ────────── buy asset B with freed ADA (A_TO_B swap) + // │ + // ├── asset B received < remaining loan? ──► loop back to SHORT_REPAY_FRACTION + // │ + // └── asset B received >= remaining loan? ──► SHORT_REPAY (full repay) + // │ + // SHORT_WITHDRAW + // ============================================================================ + + /** + * Build SHORT_REPAY_FRACTION: Partial debt repay via modifyBorrow. + * Self-contained — fetches current loan from Liqwid API. + * Reduces debt by available asset B while keeping full collateral (qADA) unchanged. + * Step 2 (SHORT_WITHDRAW_FRACTION) reduces collateral proportionally in a separate tx. + */ + export const handleShortRepayFraction = async (options: HandleBuildTxOptions): Promise => { + const { order, marketConfig, userAddress, networkEnv, utxos, kupoService } = options; + invariant( + order.orderType === ShortOrderType.SHORT_REPAY_FRACTION, + "Invalid order type for handleShortRepayFraction", + ); + invariant(order.assetIn, "assetIn is required for SHORT_REPAY_FRACTION order"); + invariant(order.amountIn, "amountIn (asset B available to repay) is required for SHORT_REPAY_FRACTION order"); + + const apiConfig = LiqwidProviderV2.createConfig(networkEnv); + + // Fetch current loan from API (always up-to-date, even after prior modifyBorrow calls) + const userAddr = Address.fromBech32(userAddress); + const pkh = userAddr.toPubKeyHash()?.keyHash.hex; + invariant(pkh, "Failed to extract public key hash from user address"); + const loansResult = await LiqwidProviderV2.Data.loansForUser(apiConfig, [pkh]); + if (loansResult.type === "err") { + throw new Error(`Failed to fetch loans for short partial repay: ${loansResult.error.message}`); + } + const loan = loansResult.value.find((l) => l.marketId === marketConfig.borrowMarketIdShort); + invariant(loan, `No active loan found for market ${marketConfig.borrowMarketIdShort}`); + + const loanUtxoId = `${loan.transactionId}-${loan.transactionIndex}`; + + // Fetch market to get minimum borrow amount constraint. + const marketResult = await LiqwidProviderV2.Data.market( + apiConfig, + marketConfig.borrowMarketIdShort as LiqwidProviderV2.MarketId, + ); + if (marketResult.type === "err") { + throw new Error(`Failed to fetch market for short partial repay: ${marketResult.error.message}`); + } + invariant(marketResult.value, `Market ${marketConfig.borrowMarketIdShort} not found`); + const minValueRaw = Math.round(marketResult.value.parameters.minValue * 1_000_000); + + // loan.amount is human-readable; convert to raw units + const currentDebtRaw = Math.round(loan.amount * 1_000_000); + const availableRaw = Number(order.amountIn); // raw units of asset B + + // Query wallet balance via Kupo — if wallet has enough asset B, build full repay tx instead + const walletBalance = await kupoService.getBalanceOfPubKeyAddress(userAddress); + const walletAssetB = walletBalance.get(marketConfig.assetB); + if (walletAssetB >= BigInt(currentDebtRaw)) { + logger.info("handleShortRepayFraction: wallet has enough for full repay, redirecting", { + walletAssetB: walletAssetB.toString(), + currentDebtRaw, + }); + const fullRepayResult = await handleShortRepay({ + ...options, + order: { ...order, orderType: ShortOrderType.SHORT_REPAY, amountIn: walletAssetB.toString() }, + }); + return { + ...fullRepayResult, + redirectToFullRepay: { + targetOrderType: ShortOrderType.SHORT_REPAY, + amountIn: walletAssetB.toString(), + assetIn: marketConfig.assetB.toString(), + assetOut: marketConfig.assetAQTokenRaw, + deleteOrderTypes: [ + ShortOrderType.SHORT_REPAY_FRACTION, + ShortOrderType.SHORT_WITHDRAW_FRACTION, + ShortOrderType.SHORT_BUY_FREED, + ], + }, + }; + } + + const collateral = loan.collaterals[0]; + invariant(collateral, "Loan has no collateral — cannot compute partial repay"); + const qTokenAmountRaw = Math.round(collateral.qTokenAmount * 1_000_000); + + // Remaining debt must stay >= minValue so the position stays protocol-legal. + const newDebt = Math.max(currentDebtRaw - availableRaw, minValueRaw); + + // Check: both the repay amount AND remaining debt must be >= minValue. + // If debt <= minValue * REPAY_MIN_VALUE_THRESHOLD_NUM / DEFAULT_DENOMINATOR, neither full nor fractional repay is possible. + const repayAmount = currentDebtRaw - newDebt; + if (repayAmount < minValueRaw || (availableRaw < currentDebtRaw && newDebt < minValueRaw)) { + throw new Error(ERROR_BUILD_TX_CODE.ERROR_CANNOT_REPAY); + } + + invariant(collateral.market, "Loan collateral has no market info"); + const collateralId = `${collateral.market.id}.${collateral.id}`; + + logger.info("handleShortRepayFraction", { + currentDebtRaw, + availableRaw, + minValueRaw, + qTokenAmountRaw, + newDebt, + loanId: loan.id, + collateralId, + }); + + // Step 1 of fractional close: reduce debt only, keep FULL collateral unchanged. + const buildTxResult = await LiqwidProviderV2.Transactions.repayLoanFraction(apiConfig, { + address: userAddress, + utxos, + loanUtxoId, + amount: newDebt, + collaterals: [{ id: collateralId, amount: qTokenAmountRaw }], + }); + + if (buildTxResult.type === "err") { + throw new Error(`Failed to build short repay-fraction transaction: ${buildTxResult.error.message}`); + } + + const txRaw = buildTxResult.value; + const ECSL = RustModule.getE; + const eTx = ECSL.Transaction.from_hex(txRaw); + const txBody = eTx.body(); + const ttl = txBody.ttl(); + invariant(Maybe.isJust(ttl), "TTL must be set in the transaction body"); + safeFreeRustObjects(eTx, txBody); + + const validTo = getTimeFromSlotMagic(networkEnv, ttl); + const txId = LiqwidProviderV2.getTxHash(txRaw); + + return { txRaw, txId, validTo: validTo.getTime() }; + }; + + /** + * Wait for SHORT_REPAY_FRACTION tx confirmation. + * + * SHORT_REPAY_FRACTION is a Liqwid modifyBorrow tx that reduces debt while keeping + * full collateral. Asset B is consumed as repayment — no tokens returned to user. + * + * On confirmation → transition to SHORT_WITHDRAW_FRACTION: + * amountIn = originalDebtRaw (for proportional collateral calc in handleShortWithdrawFraction) + */ + export const waitingShortRepayFraction = async (options: WaitingOptions): Promise => { + const { marketConfig, txHash, userAddress, cardanoscanProvider, originalDebtLovelace } = options; + invariant(originalDebtLovelace, "originalDebtLovelace is required for waitingShortRepayFraction"); + + const txFoundOnChain = await cardanoscanProvider.findTransactionByHash( + userAddress, + txHash, + CardanoscanProvider.PAGE_SIZE, + CardanoscanProvider.MAX_PAGE, + ); + + if (txFoundOnChain) { + return { + isConfirmed: true, + nextOrderType: ShortOrderType.SHORT_WITHDRAW_FRACTION, + assetIn: marketConfig.assetA.toString(), // placeholder (handler fetches loan from API) + amountIn: originalDebtLovelace, // original debt for proportional collateral calc + assetOut: marketConfig.assetA.toString(), // ADA will be received after withdraw + }; + } + + return { isConfirmed: false }; + }; + + /** + * Build SHORT_WITHDRAW_FRACTION: Reduce collateral via modifyBorrow after a partial repay. + * Keeps the same debt level, reduces qADA collateral proportionally, and redeems freed qADA + * to ADA (sent to wallet for buying more asset B in SHORT_BUY_FREED). + */ + export const handleShortWithdrawFraction = async (options: HandleBuildTxOptions): Promise => { + const { order, marketConfig, userAddress, networkEnv, utxos } = options; + invariant( + order.orderType === ShortOrderType.SHORT_WITHDRAW_FRACTION, + "Invalid order type for handleShortWithdrawFraction", + ); + + const apiConfig = LiqwidProviderV2.createConfig(networkEnv); + + // Fetch current loan state (after SHORT_REPAY_FRACTION: debt reduced, collateral unchanged) + const userAddr = Address.fromBech32(userAddress); + const pkh = userAddr.toPubKeyHash()?.keyHash.hex; + invariant(pkh, "Failed to extract public key hash from user address"); + const loansResult = await LiqwidProviderV2.Data.loansForUser(apiConfig, [pkh]); + if (loansResult.type === "err") { + throw new Error(`Failed to fetch loans for short withdraw fraction: ${loansResult.error.message}`); + } + const loan = loansResult.value.find((l) => l.marketId === marketConfig.borrowMarketIdShort); + invariant(loan, `No active loan found for market ${marketConfig.borrowMarketIdShort}`); + + // Use loan UTXO info from the API (always up-to-date after modifyBorrow calls) + const loanUtxoId = `${loan.transactionId}-${loan.transactionIndex}`; + + const currentDebtRaw = Math.round(loan.amount * 1_000_000); + const collateral = loan.collaterals[0]; + invariant(collateral, "Loan has no collateral"); + const qTokenAmountRaw = Math.round(collateral.qTokenAmount * 1_000_000); + + // order.amountIn stores the original debt (before SHORT_REPAY_FRACTION) for proportional calc. + const originalDebtRaw = order.amountIn ? Number(order.amountIn) : currentDebtRaw; + const proportionalCollateral = Math.floor(qTokenAmountRaw * (currentDebtRaw / originalDebtRaw)); + + invariant(collateral.market, "Loan collateral has no market info"); + const collateralId = `${collateral.market.id}.${collateral.id}`; + + logger.info("handleShortWithdrawFraction", { + currentDebtRaw, + originalDebtRaw, + qTokenAmountRaw, + proportionalCollateral, + freedCollateral: qTokenAmountRaw - proportionalCollateral, + loanId: loan.id, + collateralId, + }); + + // Step 2: keep same debt, reduce collateral proportionally, redeem freed qADA to ADA. + const buildTxResult = await LiqwidProviderV2.Transactions.repayLoanFraction(apiConfig, { + address: userAddress, + utxos, + loanUtxoId, + amount: currentDebtRaw, + collaterals: [{ id: collateralId, amount: proportionalCollateral }], + redeemCollateral: true, + }); + + if (buildTxResult.type === "err") { + throw new Error(`Failed to build short withdraw-fraction transaction: ${buildTxResult.error.message}`); + } + + const txRaw = buildTxResult.value; + const ECSL = RustModule.getE; + const eTx = ECSL.Transaction.from_hex(txRaw); + const txBody = eTx.body(); + const ttl = txBody.ttl(); + invariant(Maybe.isJust(ttl), "TTL must be set in the transaction body"); + safeFreeRustObjects(eTx, txBody); + + const validTo = getTimeFromSlotMagic(networkEnv, ttl); + const txId = LiqwidProviderV2.getTxHash(txRaw); + + return { txRaw, txId, validTo: validTo.getTime() }; + }; + + /** + * Wait for SHORT_WITHDRAW_FRACTION tx confirmation. + * Finds ADA received (freed qADA redeemed to underlying) and transitions to SHORT_BUY_FREED. + */ + export const waitingShortWithdrawFraction = async (options: WaitingOptions): Promise => { + const { marketConfig, txHash, userAddress, cardanoscanProvider } = options; + + const txFoundOnChain = await cardanoscanProvider.findTransactionByHash( + userAddress, + txHash, + CardanoscanProvider.PAGE_SIZE, + CardanoscanProvider.MAX_PAGE, + ); + + if (txFoundOnChain) { + const userAddressHex = userAddress.toHex(); + + for (const output of txFoundOnChain.outputs) { + if (output.address === userAddressHex) { + // For SHORT, freed collateral is qADA → redeemed to ADA (native lovelace in output.value) + const amountOut = BigInt(output.value); + return { + isConfirmed: true, + nextOrderType: ShortOrderType.SHORT_BUY_FREED, + assetIn: marketConfig.assetA.toString(), // ADA + amountIn: amountOut.toString(), + assetOut: marketConfig.assetB.toString(), // asset B to buy + amountOut: amountOut.toString(), + }; + } + } + + throw new Error(`SHORT_WITHDRAW_FRACTION tx confirmed (${txHash}) but could not find ADA output for user`); + } + + return { isConfirmed: false }; + }; + + /** + * Build SHORT_BUY_FREED: Buy asset B with freed ADA. Same DEX swap as handleShortBuy. + */ + export const handleShortBuyFreed = async (options: HandleBuildTxOptions): Promise => { + invariant(options.order.orderType === ShortOrderType.SHORT_BUY_FREED, "Invalid order type for handleShortBuyFreed"); + return handleShortBuy({ ...options, order: { ...options.order, orderType: ShortOrderType.SHORT_BUY } }); + }; + + /** + * Wait for SHORT_BUY_FREED order output to be spent (DEX consumed). + * + * On confirmation, checks if enough asset B to fully repay the remaining loan. + * If yes → SHORT_REPAY (full repay). If no → loop back to SHORT_REPAY_FRACTION. + */ + export const waitingShortBuyFreed = async (options: WaitingOptions): Promise => { + const { marketConfig, txHash, orderOutputIndex, userAddress, cardanoscanProvider, assetOut, networkEnv } = options; + invariant(orderOutputIndex !== undefined, "orderOutputIndex is required for waitingShortBuyFreed"); + invariant(assetOut, "assetOut is required for waitingShortBuyFreed"); + + const userAddressHex = userAddress.toHex(); + + const spendingTx = await cardanoscanProvider.findTransactionHasSpent( + userAddress, + txHash, + orderOutputIndex, + CardanoscanProvider.PAGE_SIZE, + CardanoscanProvider.MAX_PAGE, + ); + + if (spendingTx) { + const assetOutUnit = assetOut.toBlockFrostString(); + + for (const output of spendingTx.outputs) { + if (output.address === userAddressHex) { + if (output.tokens && output.tokens.length > 0) { + const matchingToken = output.tokens.find((token) => token.assetId === assetOutUnit); + if (matchingToken) { + const amountOut = BigInt(matchingToken.value); + + // Check if we now have enough asset B to fully repay the remaining loan. + const { canFullRepay, canRepay, loanAmountRaw } = await checkShortRepayFunds( + networkEnv, + userAddress.bech32, + marketConfig, + Number(amountOut), + ); + + logger.info("waitingShortBuyFreed: repay check", { + available: amountOut.toString(), + loanAmountRaw: loanAmountRaw.toString(), + canFullRepay, + canRepay, + }); + + if (!canRepay) { + throw new Error(ERROR_BUILD_TX_CODE.ERROR_CANNOT_REPAY); + } + + if (canFullRepay) { + // Enough asset B → transition to SHORT_REPAY (full repay) + return { + isConfirmed: true, + nextOrderType: ShortOrderType.SHORT_REPAY, + assetIn: marketConfig.assetB.toString(), + amountIn: amountOut.toString(), + assetOut: marketConfig.assetAQTokenRaw, + amountOut: amountOut.toString(), + }; + } + + // Still not enough → loop: create another fractional cycle + return { + isConfirmed: true, + nextOrderType: ShortOrderType.SHORT_REPAY_FRACTION, + assetIn: marketConfig.assetB.toString(), + amountIn: amountOut.toString(), + assetOut: marketConfig.assetB.toString(), + amountOut: amountOut.toString(), + additionalOrders: [ + { orderType: ShortOrderType.SHORT_REPAY_FRACTION }, + { orderType: ShortOrderType.SHORT_WITHDRAW_FRACTION }, + { orderType: ShortOrderType.SHORT_BUY_FREED }, + ], + originalDebtLovelace: loanAmountRaw.toString(), + }; + } + } + } + } + + throw new Error( + `SHORT_BUY_FREED output spent (tx: ${spendingTx.hash}) but could not find matching output with asset ${assetOut.toString()}`, + ); + } + + return { isConfirmed: false }; + }; + /** * Build SHORT_WITHDRAW transaction: Withdraw asset A (ADA) from Liqwid */ @@ -1351,19 +1904,24 @@ export namespace StateMachine { } // For LONG_SELL, check if we have enough ADA to fully repay the loan. - const { canFullRepay, loanAmount } = await checkLongRepayFunds( + const { canFullRepay, canRepay, loanAmount } = await checkLongRepayFunds( networkEnv, userAddress.bech32, marketConfig, Number(amountOut), ); - logger.info("waitingLongSell: canFullRepay check", { + logger.info("waitingLongSell: repay check", { available: amountOut.toString(), loanAmount: loanAmount.toString(), canFullRepay, + canRepay, }); + if (!canRepay) { + throw new Error(ERROR_BUILD_TX_CODE.ERROR_CANNOT_REPAY); + } + if (canFullRepay) { // Happy path: enough ADA → full repay return { @@ -1630,10 +2188,10 @@ export namespace StateMachine { /** * Wait for SHORT_BUY order output to be spent (consumed by DEX) - * Extract asset B received and transition to SHORT_REPAY + * Extract asset B received and check if enough for full repay or fractional flow */ export const waitingShortBuy = async (options: WaitingOptions): Promise => { - const { marketConfig, txHash, orderOutputIndex, userAddress, cardanoscanProvider, assetOut } = options; + const { marketConfig, txHash, orderOutputIndex, userAddress, cardanoscanProvider, assetOut, networkEnv } = options; invariant(orderOutputIndex !== undefined, "orderOutputIndex is required for waitingShortBuy"); invariant(assetOut, "assetOut is required for waitingShortBuy"); @@ -1656,13 +2214,52 @@ export namespace StateMachine { const matchingToken = output.tokens.find((token) => token.assetId === assetOutUnit); if (matchingToken) { const amountOut = BigInt(matchingToken.value); + + // Check if we have enough asset B to fully repay the loan + const { canFullRepay, canRepay, loanAmountRaw } = await checkShortRepayFunds( + networkEnv, + userAddress.bech32, + marketConfig, + Number(amountOut), + ); + + logger.info("waitingShortBuy: repay check", { + available: amountOut.toString(), + loanAmountRaw: loanAmountRaw.toString(), + canFullRepay, + canRepay, + }); + + if (!canRepay) { + throw new Error(ERROR_BUILD_TX_CODE.ERROR_CANNOT_REPAY); + } + + if (canFullRepay) { + // Happy path: enough asset B → full repay + return { + isConfirmed: true, + nextOrderType: ShortOrderType.SHORT_REPAY, + assetIn: assetOut.toString(), + amountIn: amountOut.toString(), + assetOut: marketConfig.assetAQTokenRaw, // qADA to be redeemed + amountOut: amountOut.toString(), + }; + } + + // Insufficient asset B → start fractional repay cycle return { isConfirmed: true, - nextOrderType: ShortOrderType.SHORT_REPAY, + nextOrderType: ShortOrderType.SHORT_REPAY_FRACTION, assetIn: assetOut.toString(), amountIn: amountOut.toString(), - assetOut: marketConfig.assetAQTokenRaw, // qADA to be redeemed + assetOut: marketConfig.assetB.toString(), amountOut: amountOut.toString(), + additionalOrders: [ + { orderType: ShortOrderType.SHORT_REPAY_FRACTION }, + { orderType: ShortOrderType.SHORT_WITHDRAW_FRACTION }, + { orderType: ShortOrderType.SHORT_BUY_FREED }, + ], + originalDebtLovelace: loanAmountRaw.toString(), }; } } @@ -1777,6 +2374,9 @@ export namespace StateMachine { [ShortOrderType.SHORT_SELL]: handleShortSell, [ShortOrderType.SHORT_BUY]: handleShortBuy, [ShortOrderType.SHORT_REPAY]: handleShortRepay, + [ShortOrderType.SHORT_REPAY_FRACTION]: handleShortRepayFraction, + [ShortOrderType.SHORT_WITHDRAW_FRACTION]: handleShortWithdrawFraction, + [ShortOrderType.SHORT_BUY_FREED]: handleShortBuyFreed, [ShortOrderType.SHORT_WITHDRAW]: handleShortWithdraw, }; @@ -1798,6 +2398,9 @@ export namespace StateMachine { [ShortOrderType.SHORT_SELL]: waitingShortSell, [ShortOrderType.SHORT_BUY]: waitingShortBuy, [ShortOrderType.SHORT_REPAY]: waitingShortRepay, + [ShortOrderType.SHORT_REPAY_FRACTION]: waitingShortRepayFraction, + [ShortOrderType.SHORT_WITHDRAW_FRACTION]: waitingShortWithdrawFraction, + [ShortOrderType.SHORT_BUY_FREED]: waitingShortBuyFreed, [ShortOrderType.SHORT_WITHDRAW]: waitingShortWithdraw, }; } diff --git a/apps/long-short-backend/src/cmd/run-api.ts b/apps/long-short-backend/src/cmd/run-api.ts index 6d290cb..b3d276f 100644 --- a/apps/long-short-backend/src/cmd/run-api.ts +++ b/apps/long-short-backend/src/cmd/run-api.ts @@ -4,7 +4,7 @@ import { createApiServer } from "../api/server"; import { loadMarketConfigs } from "../config/market"; import type { DB } from "../database"; import { newKyselyClient } from "../database/postgres"; -import { CardanoscanProvider } from "../provider"; +import { CardanoscanProvider, KupoService } from "../provider"; import { logger } from "../utils"; const API_PORT = Number(process.env.API_PORT) || 9999; @@ -12,6 +12,7 @@ const API_HOST = process.env.API_HOST || "0.0.0.0"; const DATABASE_URL = process.env.DATABASE_URL; const NETWORK = process.env.NETWORK || "mainnet"; const CARDANOSCAN_API_KEY = process.env.CARDANOSCAN_API_KEY; +const KUPO_HOST = process.env.KUPO_HOST; async function main() { // Validate environment @@ -21,6 +22,9 @@ async function main() { if (!CARDANOSCAN_API_KEY) { throw new Error("CARDANOSCAN_API_KEY environment variable is required"); } + if (!KUPO_HOST) { + throw new Error("KUPO_HOST environment variable is required"); + } // Parse network environment const networkEnv = NETWORK === "mainnet" ? NetworkEnvironment.MAINNET : NetworkEnvironment.TESTNET_PREVIEW; @@ -35,6 +39,10 @@ async function main() { const db = await newKyselyClient(DATABASE_URL, { logSQL: false }); logger.info("Database connected"); + logger.info("Connecting to Kupo service..."); + const kupoService = await KupoService.new(KUPO_HOST, true); + logger.info("Kupo service connected"); + // Load market configs from database logger.info("Loading market configs..."); const marketConfigs = await loadMarketConfigs(db); @@ -53,6 +61,7 @@ async function main() { db, networkEnv, cardanoscanProvider, + kupoService, }); logger.info("Long-Short Backend started successfully", { diff --git a/apps/long-short-backend/src/constants.ts b/apps/long-short-backend/src/constants.ts index 242c6a3..514aa43 100644 --- a/apps/long-short-backend/src/constants.ts +++ b/apps/long-short-backend/src/constants.ts @@ -6,5 +6,16 @@ export const API_ENDPOINTS = { POSITION_BUILD_TX: "/position/build-tx", POSITION_CLOSE: "/position/close", POSITION_CREATE: "/position/create", + POSITION_DEBT: "/position/debt", POSITION_GET: "/position/get", }; + +export const ERROR_BUILD_TX_CODE = { + ERROR_CANNOT_REPAY: "ERROR_CANNOT_REPAY", +}; + +export const DEFAULT_DENOMINATOR = 10000n; + +/** Numerator for Liqwid minValue threshold (over DEFAULT_DENOMINATOR). + * Debt must be > minValue * REPAY_MIN_VALUE_THRESHOLD_NUM / DEFAULT_DENOMINATOR for fractional repay to work. */ +export const REPAY_MIN_VALUE_THRESHOLD_NUM = 21000n; diff --git a/apps/long-short-backend/src/provider/cardanoscan.ts b/apps/long-short-backend/src/provider/cardanoscan.ts index 20cb535..95330be 100644 --- a/apps/long-short-backend/src/provider/cardanoscan.ts +++ b/apps/long-short-backend/src/provider/cardanoscan.ts @@ -90,8 +90,8 @@ export type GetTransactionListOptions = { export class CardanoscanProvider { public static readonly MAINNET_URL = "https://api.cardanoscan.io/api/v1"; public static readonly PREVIEW_URL = "https://api-preview.cardanoscan.io/api/v1"; - public static readonly PAGE_SIZE = 1; - public static readonly MAX_PAGE = 2; + public static readonly PAGE_SIZE = 3; + public static readonly MAX_PAGE = 3; private readonly baseUrl: string; private readonly apiKey: string; diff --git a/apps/long-short-backend/src/provider/minswap-aggregator.ts b/apps/long-short-backend/src/provider/minswap-aggregator.ts index ce8190e..300f703 100644 --- a/apps/long-short-backend/src/provider/minswap-aggregator.ts +++ b/apps/long-short-backend/src/provider/minswap-aggregator.ts @@ -2,7 +2,7 @@ import { NetworkEnvironment } from "@minswap/felis-ledger-core"; import { logger } from "../utils"; const BASE_URLS: Record = { - [NetworkEnvironment.MAINNET]: "https://monorepo-mainnet-prod.minswap.org", + [NetworkEnvironment.MAINNET]: "https://aggr-monorepo-mainnet-prod.minswap.org", [NetworkEnvironment.TESTNET_PREVIEW]: "https://aggr.dev-3.minswap.org", [NetworkEnvironment.TESTNET_PREPROD]: "https://aggr.dev-3.minswap.org", }; @@ -45,8 +45,9 @@ export class MinswapAggregatorProvider { token_in: tokenIn, token_out: tokenOut, slippage, - exclude_protocols: ["MuesliSwap"], - allow_multi_hops: true, + include: ["MinswapV2"], + allow_multi_hops: false, + allowNonAtomicMultiHops: false, }); const response = await fetch(url, { diff --git a/apps/long-short-backend/src/repository/order-repository.ts b/apps/long-short-backend/src/repository/order-repository.ts index 3e9545d..ff00372 100644 --- a/apps/long-short-backend/src/repository/order-repository.ts +++ b/apps/long-short-backend/src/repository/order-repository.ts @@ -292,6 +292,37 @@ export namespace OrderRepository { }; } + export async function updateOrderForRedirect( + db: Kysely | Transaction, + orderId: bigint, + params: { assetIn: string; amountIn: string; assetOut: string; builtTxId: string; builtValidTo: Date }, + ): Promise { + await db + .updateTable("order") + .set({ + asset_in: params.assetIn, + amount_in: params.amountIn, + asset_out: params.assetOut, + built_tx_id: params.builtTxId, + built_valid_to: params.builtValidTo, + }) + .where("id", "=", orderId.toString()) + .execute(); + } + + export async function deleteOrdersByTypes( + db: Kysely | Transaction, + positionId: bigint, + orderTypes: string[], + ): Promise { + if (orderTypes.length === 0) return; + await db + .deleteFrom("order") + .where("position_id", "=", positionId.toString()) + .where("order_type", "in", orderTypes) + .execute(); + } + // biome-ignore lint/suspicious/noExplicitAny: DB row type function mapOrderRow(row: any): Order { return { diff --git a/apps/long-short-backend/src/services/position-service.ts b/apps/long-short-backend/src/services/position-service.ts index 6c2a914..3e2fd64 100644 --- a/apps/long-short-backend/src/services/position-service.ts +++ b/apps/long-short-backend/src/services/position-service.ts @@ -5,7 +5,7 @@ import type { Kysely } from "kysely"; import { StateMachine } from "../api/state-machine"; import { getMarketConfig, isSupportedMarket, type MarketConfig } from "../config/market"; import type { DB } from "../database"; -import { CardanoscanProvider, type MinswapAggregatorProvider } from "../provider"; +import { CardanoscanProvider, type KupoService, type MinswapAggregatorProvider } from "../provider"; import { OrderRepository } from "../repository/order-repository"; import { type Position, PositionRepository } from "../repository/position-repository"; import { logger } from "../utils"; @@ -51,6 +51,7 @@ export class PositionService { private readonly networkEnv: NetworkEnvironment, private readonly cardanoscanProvider: CardanoscanProvider, private readonly aggregatorProvider: MinswapAggregatorProvider, + private readonly kupoService: KupoService, ) {} async createPosition(input: CreatePositionInput): Promise { @@ -219,8 +220,11 @@ export class PositionService { positionAmountIn: position.amountIn, }; - // For LONG_REPAY_FRACTION, pass the original debt (stored in amountOut during creation) - if (waitingOrder.orderType === StateMachine.LongOrderType.LONG_REPAY_FRACTION) { + // For fractional repay flows, pass the original debt (stored in amountOut during creation) + if ( + waitingOrder.orderType === StateMachine.LongOrderType.LONG_REPAY_FRACTION || + waitingOrder.orderType === StateMachine.ShortOrderType.SHORT_REPAY_FRACTION + ) { waitingOptions.originalDebtLovelace = waitingOrder.amountOut ?? undefined; } @@ -451,34 +455,43 @@ export class PositionService { networkEnv: this.networkEnv, utxos, amountBorrow: position.amountBorrow, + kupoService: this.kupoService, }; - // LONG_REPAY and LONG_REPAY_FRACTION: no extra options needed — handlers fetch - // loan data directly from the Liqwid API (always up-to-date, even after modifyBorrow). + // LONG_REPAY, LONG_REPAY_FRACTION, SHORT_REPAY, SHORT_REPAY_FRACTION: no extra options needed — + // handlers fetch loan data directly from the Liqwid API (always up-to-date, even after modifyBorrow). // LONG_WITHDRAW and SHORT_WITHDRAW: handlers compute withdraw amount dynamically // from UTxO qToken balance and market exchange rate (no DB lookup needed). - // For SHORT_REPAY, we need the loan transaction ID, output index, and collateral amount from SHORT_BORROW - if (order.orderType === StateMachine.ShortOrderType.SHORT_REPAY) { - const borrowOrder = await OrderRepository.getOrderByPositionAndType( - this.db, - position.id, - StateMachine.ShortOrderType.SHORT_BORROW, - ); - if (!borrowOrder?.createdTxId) { - return { success: false, error: "SHORT_BORROW order not found or not confirmed yet" }; - } - if (!borrowOrder.amountIn) { - return { success: false, error: "SHORT_BORROW order amountIn (collateral amount) not set" }; - } - buildOptions.loanTxId = borrowOrder.createdTxId; - buildOptions.loanOutputIndex = borrowOrder.createdTxIndex ?? 0; - buildOptions.collateralAmount = borrowOrder.amountIn; // qADA amount used as collateral - } - const txResult = await buildFn(buildOptions); + // Handle redirect from fractional to full repay + if (txResult.redirectToFullRepay) { + const { targetOrderType, amountIn, assetIn, assetOut, deleteOrderTypes } = txResult.redirectToFullRepay; + await this.db.transaction().execute(async (trx) => { + await OrderRepository.deleteOrdersByTypes(trx, position.id, deleteOrderTypes); + const targetOrder = await OrderRepository.getOrderByPositionAndType(trx, position.id, targetOrderType); + invariant(targetOrder, "Target order for redirect not found"); + await OrderRepository.updateOrderForRedirect(trx, targetOrder.id, { + assetIn, + amountIn, + assetOut, + builtTxId: txResult.txId, + builtValidTo: new Date(txResult.validTo), + }); + logger.info("Redirected fractional to full repay", { + targetOrderType, + deletedTypes: deleteOrderTypes, + targetOrderId: targetOrder.id, + txId: txResult.txId, + validTo: new Date(txResult.validTo).toISOString(), + }); + }); + + return { success: true, txRaw: txResult.txRaw, txId: txResult.txId, orderType: targetOrderType }; + } + // Update order built_tx fields await OrderRepository.updateOrderBuiltTx(this.db, order.id, txResult.txId, new Date(txResult.validTo)); @@ -502,6 +515,38 @@ export class PositionService { return PositionRepository.getOpenPositionByUser(this.db, userAddress); } + async getDebt(userAddress: string, marketId: string): Promise<{ amount: string; asset: string } | null> { + const position = await PositionRepository.getOpenPositionByUserAndMarket(this.db, userAddress, marketId); + if (!position) return null; + + const marketConfig = getMarketConfig(marketId); + if (!marketConfig) return null; + + const borrowMarketId = + position.side === StateMachine.PositionSide.LONG + ? marketConfig.borrowMarketIdLong + : marketConfig.borrowMarketIdShort; + + const debtAsset = + position.side === StateMachine.PositionSide.LONG + ? marketConfig.assetA.toString() + : marketConfig.assetB.toString(); + + const apiConfig = LiqwidProviderV2.createConfig(this.networkEnv); + const userAddr = Address.fromBech32(userAddress); + const pkh = userAddr.toPubKeyHash()?.keyHash.hex; + if (!pkh) return null; + + const loansResult = await LiqwidProviderV2.Data.loansForUser(apiConfig, [pkh]); + if (loansResult.type === "err") return null; + + const loan = loansResult.value.find((l) => l.marketId === borrowMarketId); + if (!loan) return null; + + const amountRaw = BigInt(Math.round(loan.amount * 1_000_000)); + return { amount: amountRaw.toString(), asset: debtAsset }; + } + /** * Compute trading metrics for an OPEN position: * entry_price, liq_price, interest, unrealized_pnl, health diff --git a/apps/web/.gitignore b/apps/web/.gitignore deleted file mode 100644 index f886745..0000000 --- a/apps/web/.gitignore +++ /dev/null @@ -1,36 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js -.yarn/install-state.gz - -# testing -/coverage - -# next.js -/.next/ -/out/ - -# production -/build - -# misc -.DS_Store -*.pem - -# debug -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# env files (can opt-in for commiting if needed) -.env* - -# vercel -.vercel - -# typescript -*.tsbuildinfo -next-env.d.ts diff --git a/apps/web/app/api/liqwid/graphql/route.ts b/apps/web/app/api/liqwid/graphql/route.ts deleted file mode 100644 index 624ebae..0000000 --- a/apps/web/app/api/liqwid/graphql/route.ts +++ /dev/null @@ -1,33 +0,0 @@ -import type { NextRequest } from "next/server"; -import { NextResponse } from "next/server"; - -export async function POST(request: NextRequest) { - try { - const body = await request.json(); - - const response = await fetch("https://v2.api.preview.liqwid.dev/graphql", { - method: "POST", - headers: { - Accept: "*/*", - "Accept-Language": "en-US,en;q=0.9", - "Content-Type": "application/json", - "X-App-Source": "liqwid-app", - "X-Request-Id": `req_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, - }, - body: JSON.stringify(body), - }); - - if (!response.ok) { - return NextResponse.json( - { error: `Liqwid API error: ${response.status} ${response.statusText}` }, - { status: response.status }, - ); - } - - const data = await response.json(); - return NextResponse.json(data); - } catch (error) { - console.error("Liqwid GraphQL proxy error:", error); - return NextResponse.json({ error: "Failed to proxy request to Liqwid API" }, { status: 500 }); - } -} diff --git a/apps/web/app/api/liqwid/supply/route.ts b/apps/web/app/api/liqwid/supply/route.ts deleted file mode 100644 index cb881c5..0000000 --- a/apps/web/app/api/liqwid/supply/route.ts +++ /dev/null @@ -1,29 +0,0 @@ -import type { NextRequest } from "next/server"; -import { NextResponse } from "next/server"; - -export async function POST(request: NextRequest) { - try { - const body = await request.json(); - - const response = await fetch("https://v2.api.preview.liqwid.dev/graphql", { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify(body), - }); - - if (!response.ok) { - return NextResponse.json( - { error: `Liqwid API error: ${response.status} ${response.statusText}` }, - { status: response.status }, - ); - } - - const data = await response.json(); - return NextResponse.json(data); - } catch (error) { - console.error("Liqwid API proxy error:", error); - return NextResponse.json({ error: "Failed to proxy request to Liqwid API" }, { status: 500 }); - } -} diff --git a/apps/web/app/atoms/utils.ts b/apps/web/app/atoms/utils.ts deleted file mode 100644 index f2c5e91..0000000 --- a/apps/web/app/atoms/utils.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { atomWithStorage } from "jotai/utils"; - -// Utility function to create atoms with localStorage handling -export function createAtomWithStorage( - key: string, - initialValue: T, - parse: (value: string) => T | null, - serialize: (value: T | null) => string, -) { - return atomWithStorage(key, initialValue, { - getItem(key, initialValue) { - if (typeof localStorage === "undefined") { - return initialValue; - } - const storedValue = localStorage.getItem(key); - if (!storedValue) { - return initialValue; - } - try { - return parse(storedValue); - } catch { - return initialValue; - } - }, - setItem(key, newValue) { - if (typeof localStorage === "undefined") { - return; - } - if (newValue === null) { - localStorage.removeItem(key); - } else { - localStorage.setItem(key, serialize(newValue)); - } - }, - removeItem(key) { - if (typeof localStorage !== "undefined") { - localStorage.removeItem(key); - } - }, - }); -} diff --git a/apps/web/app/atoms/walletAtom.ts b/apps/web/app/atoms/walletAtom.ts deleted file mode 100644 index 28169d4..0000000 --- a/apps/web/app/atoms/walletAtom.ts +++ /dev/null @@ -1,231 +0,0 @@ -import { XJSON } from "@minswap/felis-ledger-core"; -import type { LendingMarket } from "@minswap/felis-lending-market"; -import { atom } from "jotai"; -import type { Asset } from "../../../../packages/ledger-core/dist/asset"; -import { LocalStorageKey } from "../constants/storage"; -import type { Cip30Api, WalletInfo } from "../lib/wallet-utils"; -import { createAtomWithStorage } from "./utils"; - -export type WalletData = { - walletInfo: WalletInfo; - api: Cip30Api; -}; -export const walletAtom = atom(null); -export const setWalletAtom = atom(null, (_get, set, update: WalletData | null) => { - set(walletAtom, update); -}); -export const connectedWalletAtom = createAtomWithStorage( - LocalStorageKey.CONNECTED_WALLET, - false, - (value) => value === "true", - (value) => String(value), -); -export const setConnectedWalletAtom = atom(null, (_get, set, update: boolean) => { - set(connectedWalletAtom, update); -}); -export type NitroWalletData = { - walletInfo: WalletInfo & { rootAddress: string }; - privateKey: string; -}; -export const nitroWalletAtom = atom(null); -export const setNitroWalletAtom = atom(null, (_get, set, update: NitroWalletData | null) => { - set(nitroWalletAtom, update); -}); - -export enum LongPositionStatus { - STEP_1_BUY_LONG_ASSET = "buy_long_asset", - STEP_2_SUPPLY_TOKEN = "supply_token", - STEP_3_BORROW_TOKEN = "borrow_token", - STEP_BUY_MORE_LONG_ASSET = "buy_more_long_asset", - OPENING_POSITION = "opening_position", - STEP_4_SELL_LONG_ASSET = "sell_long_asset", - STEP_5_REPAY_ASSET = "repay_asset", - STEP_6_WITHDRAW_COLLATERAL = "withdraw_collateral", - STEP_SELL_ALL_LONG_ASSET = "sell_all_long_asset", - CLOSED_POSITION = "closed_position", -} -export type LongPositionState = { - positionId: string; - status: LongPositionStatus; - nitroWalletAddress: string; - leverage: number; - longAsset: Asset; - borrowAsset: Asset; - createdAt: number; - updatedAt: number; - amount: { - iTotalBorrow: bigint; // ada - iTotalBuy: bigint; // ada - iTotalOperationFee: bigint; // ada - mTotalPaidFee: bigint; // ada - mBought: bigint; // ada - mTotalLong: bigint; // MIN - mLongBalance: bigint; // MIN - mBorrowed: bigint; // ada - mSupplied: bigint; // qMIN - mRepaid: bigint; // ada - mWithdrawn: bigint; // MIN - }; - transactions: { - step: LongPositionStatus; - txHash: string; - }[]; - hasCallback?: number; - callbackExtra?: string; -}; - -export enum ShortPositionStatus { - STEP_1_SUPPLY_TOKEN = "step_1_supply_token", - STEP_2_BORROW_TOKEN = "step_2_borrow_token", - STEP_3_SHORT_TOKEN = "step_3_short_token", - OPENING_POSITION = "opening_position", - STEP_4_BUY_BACK_TOKEN = "step_4_buy_back_token", - STEP_5_REPAY_ASSET = "step_5_repay_asset", - STEP_6_WITHDRAW_COLLATERAL = "step_6_withdraw_collateral", - CLOSED_POSITION = "closed_position", -} - -export type ShortPositionState = { - positionId: string; - status: ShortPositionStatus; - nitroWalletAddress: string; - shortAsset: Asset; - createdAt: number; - updatedAt: number; - amount: { - iTotalSupplyL: bigint; - iBorrowAmountL: bigint; - iLiquidationPrice: number; - mSuppliedL: bigint; - mShortedL: bigint; - mShortedEstimateAda: bigint; - mBorrowedL: bigint; - mTradingPrice: number; - mClosedPrice: number; - mClosedAda: bigint; // ada required to buy back Short Token - mRepaidL: bigint; // same with borrow token - mWithdrawnL: bigint; // same with supply token - }; - transactions: { - step: ShortPositionStatus; - txHash: string; - }[]; - hasCallback?: number; - callbackExtra?: string; - liquidationCall?: boolean; -}; - -// Base atom that stores all positions from all wallets -const allLongPositionsAtom = createAtomWithStorage( - LocalStorageKey.LONG_POSITIONS, - [], - (value) => XJSON.parse(value) as LongPositionState[], - (value) => XJSON.stringify(value), -); - -// Derived atom that filters positions for the current nitro wallet -export const longPositionAtom = atom((get) => { - const nitroWallet = get(nitroWalletAtom); - const allPositions = get(allLongPositionsAtom) || []; - - // If no nitro wallet connected, return empty array - if (!nitroWallet?.walletInfo?.address?.bech32) { - return []; - } - - // Filter positions for current nitro wallet address - return allPositions.filter((position) => position.nitroWalletAddress === nitroWallet.walletInfo.address.bech32); -}); // Write atom to add/update positions - -export const setLongPositionAtom = atom( - null, - (get, set, update: LongPositionState[] | ((prev: LongPositionState[]) => LongPositionState[])) => { - const nitroWallet = get(nitroWalletAtom); - - // If no nitro wallet connected, don't update anything - if (!nitroWallet?.walletInfo?.address?.bech32) { - return; - } - - const allPositions = get(allLongPositionsAtom) || []; - const currentWalletAddress = nitroWallet.walletInfo.address.bech32; - - // Get new positions (either array or function result) - const newPositions = - typeof update === "function" - ? update(allPositions.filter((p) => p.nitroWalletAddress === currentWalletAddress)) - : update; - - // Remove old positions for current wallet and add new ones - const otherWalletsPositions = allPositions.filter((p) => p.nitroWalletAddress !== currentWalletAddress); - const updatedAllPositions = [...otherWalletsPositions, ...newPositions]; - - set(allLongPositionsAtom, updatedAllPositions); - }, -); - -// Base atom that stores all short positions from all wallets -const allShortPositionsAtom = createAtomWithStorage( - LocalStorageKey.SHORT_POSITIONS, - [], - (value) => XJSON.parse(value) as ShortPositionState[], - (value) => XJSON.stringify(value), -); - -// Derived atom that filters short positions for the current nitro wallet -export const shortPositionAtom = atom((get) => { - const nitroWallet = get(nitroWalletAtom); - const allPositions = get(allShortPositionsAtom) || []; - - // If no nitro wallet connected, return empty array - if (!nitroWallet?.walletInfo?.address?.bech32) { - return []; - } - - // Filter positions for current nitro wallet address - return allPositions.filter((position) => position.nitroWalletAddress === nitroWallet.walletInfo.address.bech32); -}); - -// Write atom to add/update short positions -export const setShortPositionAtom = atom( - null, - (get, set, update: ShortPositionState[] | ((prev: ShortPositionState[]) => ShortPositionState[])) => { - const nitroWallet = get(nitroWalletAtom); - - // If no nitro wallet connected, don't update anything - if (!nitroWallet?.walletInfo?.address?.bech32) { - return; - } - - const allPositions = get(allShortPositionsAtom) || []; - const currentWalletAddress = nitroWallet.walletInfo.address.bech32; - - // Get new positions (either array or function result) - const newPositions = - typeof update === "function" - ? update(allPositions.filter((p) => p.nitroWalletAddress === currentWalletAddress)) - : update; - - // Remove old positions for current wallet and add new ones - const otherWalletsPositions = allPositions.filter((p) => p.nitroWalletAddress !== currentWalletAddress); - const updatedAllPositions = [...otherWalletsPositions, ...newPositions]; - - set(allShortPositionsAtom, updatedAllPositions); - }, -); - -// Balance atoms -export const rootBalanceAtom = atom(0n); -export const setRootBalanceAtom = atom(null, (_get, set, update: bigint) => { - set(rootBalanceAtom, update); -}); - -export const nitroBalanceAtom = atom(0n); -export const setNitroBalanceAtom = atom(null, (_get, set, update: bigint) => { - set(nitroBalanceAtom, update); -}); - -export const minAdaPriceAtom = atom(null); -export const setMinAdaPriceAtom = atom(null, (_get, set, update: LendingMarket.PriceInAdaResponse | null) => { - set(minAdaPriceAtom, update); -}); diff --git a/apps/web/app/components/deposit-withdraw.tsx b/apps/web/app/components/deposit-withdraw.tsx deleted file mode 100644 index 0a306a6..0000000 --- a/apps/web/app/components/deposit-withdraw.tsx +++ /dev/null @@ -1,314 +0,0 @@ -"use client"; - -import { ArrowDownOutlined, ArrowUpOutlined } from "@ant-design/icons"; -import { RustModule } from "@minswap/felis-ledger-utils"; -import { NitroWallet } from "@minswap/felis-lending-market"; -import { TxComplete } from "@minswap/felis-tx-builder"; -import { Alert, App, Button, Card, Col, Form, Input, Modal, Row, Space, Statistic } from "antd"; -import { useAtomValue, useSetAtom } from "jotai"; -import { useEffect, useState } from "react"; -import { - nitroBalanceAtom, - nitroWalletAtom, - rootBalanceAtom, - setNitroBalanceAtom, - setRootBalanceAtom, - walletAtom, -} from "../atoms/walletAtom"; -import { CONFIG } from "../config"; -import { Helpers } from "../lib/helpers"; -import { Utils } from "../lib/utils"; - -export const DepositWithdraw = () => { - const { message } = App.useApp(); - const nitroWallet = useAtomValue(nitroWalletAtom); - const rootWallet = useAtomValue(walletAtom); - const rootBalance = useAtomValue(rootBalanceAtom); - const nitroBalance = useAtomValue(nitroBalanceAtom); - const setRootBalance = useSetAtom(setRootBalanceAtom); - const setNitroBalance = useSetAtom(setNitroBalanceAtom); - const [depositModal, setDepositModal] = useState(false); - const [withdrawModal, setWithdrawModal] = useState(false); - const [depositLoading, setDepositLoading] = useState(false); - const [withdrawLoading, setWithdrawLoading] = useState(false); - const [depositForm] = Form.useForm(); - const [withdrawForm] = Form.useForm(); - - // Initialize balances from wallet info - useEffect(() => { - if (rootWallet?.walletInfo?.balance) { - setRootBalance(rootWallet.walletInfo.balance); - } - if (nitroWallet?.walletInfo?.balance) { - setNitroBalance(nitroWallet.walletInfo.balance); - } - }, [rootWallet?.walletInfo?.balance, nitroWallet?.walletInfo?.balance, setRootBalance, setNitroBalance]); - - // Poll balances every 10 seconds - useEffect(() => { - if (!rootWallet?.walletInfo || !nitroWallet?.walletInfo) return; - - const pollBalances = async () => { - try { - const [rootBal, nitroBal] = await Promise.all([ - Helpers.fetchBalance(rootWallet.walletInfo.address.bech32), - Helpers.fetchBalance(nitroWallet.walletInfo.address.bech32), - ]); - setRootBalance(rootBal); - setNitroBalance(nitroBal); - } catch (err) { - console.error("Failed to poll balances:", err); - } - }; - - const interval = setInterval(pollBalances, 10000); // 10 seconds - return () => clearInterval(interval); - }, [rootWallet?.walletInfo, nitroWallet?.walletInfo, setRootBalance, setNitroBalance]); - - const handleDeposit = async (values: { amount: string }) => { - if (!rootWallet?.api || !rootWallet?.walletInfo || !nitroWallet?.walletInfo) { - message.error("Missing wallet information"); - return; - } - - setDepositLoading(true); - try { - const amountInLovelace = BigInt(Math.floor(Number(values.amount) * 1_000_000)); - // Get UTXOs from root wallet - const utxosRaw = await rootWallet.api.getUtxos(); - if (!utxosRaw || utxosRaw.length === 0) { - message.error("No UTXOs available in root wallet"); - return; - } - - // Build deposit transaction using NitroWallet.depositNitroFunds - const txHex = await NitroWallet.depositNitroFunds({ - nitroAddress: nitroWallet.walletInfo.address, - rootAddress: rootWallet.walletInfo.address, - amount: amountInLovelace, - networkEnv: CONFIG.networkEnv, - rootAddressUtxos: utxosRaw, - }); - - // Sign and submit transaction - const witnessSet = await rootWallet.api.signTx(txHex, true); - // Using TxComplete to assemble (aka: finalize Tx) - const tx = RustModule.getE.Transaction.from_hex(txHex); - const txComplete = new TxComplete(tx); - txComplete.assemble(witnessSet); - - // Complete Tx - const signedTx = txComplete.complete(); - const txHash = await rootWallet.api.submitTx(signedTx); - message.success(`Deposit successful! Tx: ${txHash}`); - - depositForm.resetFields(); - setDepositModal(false); - } catch (err) { - const errorMsg = err instanceof Error ? err.message : String(err); - message.error(`Deposit failed: ${errorMsg}`); - console.error("Deposit error:", err); - } finally { - setDepositLoading(false); - } - }; - - const handleWithdraw = async (values: { amount: string }) => { - if (!rootWallet?.api || !rootWallet?.walletInfo || !nitroWallet?.walletInfo || !nitroWallet?.privateKey) { - message.error("Missing wallet information"); - return; - } - - setWithdrawLoading(true); - try { - const amountInLovelace = BigInt(Math.floor(Number(values.amount) * 1_000_000)); - - // Get UTXOs from nitro wallet - const utxosRaw = await NitroWallet.fetchRawUtxos(nitroWallet.walletInfo.address.bech32, CONFIG.networkEnv); - if (!utxosRaw || utxosRaw.length === 0) { - message.error("No UTXOs available in nitro wallet"); - return; - } - - // Build withdraw transaction using NitroWallet.withdrawNitroFunds - const signedTx = await NitroWallet.withdrawNitroFunds({ - nitroAddress: nitroWallet.walletInfo.address, - rootAddress: rootWallet.walletInfo.address, - amount: amountInLovelace, - networkEnv: CONFIG.networkEnv, - nitroAddressUtxos: utxosRaw, - nitroPrivateKey: nitroWallet.privateKey, - }); - const txHash = await NitroWallet.submitTx(signedTx, CONFIG.networkEnv); - message.success(`Withdraw successful! Tx: ${txHash}`); - - withdrawForm.resetFields(); - setWithdrawModal(false); - } catch (err) { - const errorMsg = err instanceof Error ? err.message : String(err); - message.error(`Withdraw failed: ${errorMsg}`); - console.error("Withdraw error:", err); - } finally { - setWithdrawLoading(false); - } - }; - - const isReadyForDeposit = rootWallet?.walletInfo && nitroWallet?.walletInfo && rootBalance > 0n; - - const isReadyForWithdraw = rootWallet?.walletInfo && nitroWallet?.walletInfo && nitroBalance > 0n; - - return ( - - - - - - - - - - - - - - - {!rootWallet?.walletInfo || !nitroWallet?.walletInfo ? ( - - ) : null} - - - - - - - {/* Deposit Modal */} - { - setDepositModal(false); - depositForm.resetFields(); - }} - onOk={() => depositForm.submit()} - open={depositModal} - title="Deposit ADA to Nitro Wallet" - > - - -
- { - const amount = parseFloat(value); - const availableAda = Number(rootBalance) / 1_000_000; - if (amount > availableAda) { - return Promise.reject(new Error(`Insufficient balance. Available: ${availableAda.toFixed(2)} ADA`)); - } - return Promise.resolve(); - }, - }, - ]} - > - - - - - -
-
- - {/* Withdraw Modal */} - { - setWithdrawModal(false); - withdrawForm.resetFields(); - }} - onOk={() => withdrawForm.submit()} - open={withdrawModal} - title="Withdraw ADA from Nitro Wallet" - > - - -
- { - const amount = parseFloat(value); - const availableAda = Number(nitroBalance) / 1_000_000; - if (amount > availableAda) { - return Promise.reject(new Error(`Insufficient balance. Available: ${availableAda.toFixed(2)} ADA`)); - } - return Promise.resolve(); - }, - }, - ]} - > - - - - - -
-
-
- ); -}; diff --git a/apps/web/app/components/eternl-connector.tsx b/apps/web/app/components/eternl-connector.tsx deleted file mode 100644 index a82147c..0000000 --- a/apps/web/app/components/eternl-connector.tsx +++ /dev/null @@ -1,96 +0,0 @@ -"use client"; - -import { CopyOutlined, LogoutOutlined } from "@ant-design/icons"; -import { App, Button, Layout, Space, Tooltip } from "antd"; -import { useAtomValue } from "jotai"; -import { useEffect } from "react"; -import { rootBalanceAtom, walletAtom } from "../atoms/walletAtom"; -import { useNitroWallet } from "../lib/use-nitro-wallet"; -import { useWallet } from "../lib/use-wallet"; -import { Utils } from "../lib/utils"; - -export const EternlConnector = () => { - const { message } = App.useApp(); - const wallet = useWallet(); - const nitroWallet = useNitroWallet(); - const globalWallet = useAtomValue(walletAtom); - const rootBalance = useAtomValue(rootBalanceAtom); - - const handleCopyAddress = async (address: string) => { - try { - await navigator.clipboard.writeText(address); - message.success("Address copied!"); - } catch (_err) { - message.error("Failed to copy address"); - } - }; - - // Show error notification only once when error occurs - useEffect(() => { - if (wallet.error) { - message.error(wallet.error); - } - }, [wallet.error, message]); - - // Use global wallet atom for display, but still show if walletInfo exists - const displayWallet = globalWallet?.walletInfo || wallet.walletInfo; - - if (displayWallet) { - return ( - - - {rootBalance !== undefined && ( - - {rootBalance > 0 ? Utils.formatBalance(rootBalance) : displayWallet.balance} ADA - - )} - - - - - - - ); - } - - return ( - - - - ); -}; diff --git a/apps/web/app/components/margin-trading-position-tab.tsx b/apps/web/app/components/margin-trading-position-tab.tsx deleted file mode 100644 index 00f1ef5..0000000 --- a/apps/web/app/components/margin-trading-position-tab.tsx +++ /dev/null @@ -1,926 +0,0 @@ -"use client"; - -import { CloseOutlined, DollarOutlined, SwapOutlined, TrophyOutlined } from "@ant-design/icons"; -import { ADA, Asset, Utxo, XJSON } from "@minswap/felis-ledger-core"; -import { LendingMarket, type LiqwidProvider, NitroWallet } from "@minswap/felis-lending-market"; -import invariant from "@minswap/tiny-invariant"; -import { Alert, App, Button, Card, Col, Divider, Progress, Row, Space, Statistic, Tag } from "antd"; -import { useAtomValue, useSetAtom } from "jotai"; -import { useCallback, useEffect, useRef } from "react"; -import { - type LongPositionState, - LongPositionStatus, - longPositionAtom, - type NitroWalletData, - nitroWalletAtom, - setLongPositionAtom, - type WalletData, - walletAtom, -} from "../atoms/walletAtom"; -import { CONFIG } from "../config"; -import { Helpers } from "../lib/helpers"; -import { Utils } from "../lib/utils"; - -const getStatusColor = (status: LongPositionStatus) => { - switch (status) { - case LongPositionStatus.STEP_1_BUY_LONG_ASSET: - return "orange"; - case LongPositionStatus.STEP_2_SUPPLY_TOKEN: - return "processing"; - case LongPositionStatus.OPENING_POSITION: - return "success"; - case LongPositionStatus.STEP_3_BORROW_TOKEN: - return "purple"; - case LongPositionStatus.STEP_BUY_MORE_LONG_ASSET: - return "orange"; - case LongPositionStatus.STEP_4_SELL_LONG_ASSET: - return "magenta"; - case LongPositionStatus.STEP_5_REPAY_ASSET: - return "geekblue"; - case LongPositionStatus.STEP_6_WITHDRAW_COLLATERAL: - return "cyan"; - case LongPositionStatus.STEP_SELL_ALL_LONG_ASSET: - return "magenta"; - case LongPositionStatus.CLOSED_POSITION: - return "red"; - default: - return "default"; - } -}; - -const getStatusText = (status: LongPositionStatus) => { - switch (status) { - case LongPositionStatus.STEP_1_BUY_LONG_ASSET: - return "Buying Asset"; - case LongPositionStatus.STEP_2_SUPPLY_TOKEN: - return "Supplying Token"; - case LongPositionStatus.OPENING_POSITION: - return "Opening..."; - case LongPositionStatus.STEP_4_SELL_LONG_ASSET: - case LongPositionStatus.STEP_5_REPAY_ASSET: - case LongPositionStatus.STEP_6_WITHDRAW_COLLATERAL: - case LongPositionStatus.STEP_SELL_ALL_LONG_ASSET: - return `Closing Position... ${status.replace(/_/g, " ")}`; - case LongPositionStatus.CLOSED_POSITION: - return "Position Closed"; - default: - return status.replace(/_/g, " "); - } -}; - -const getProgressPercent = (position: LongPositionState) => { - const { - status, - amount: { iTotalBuy, mBought }, - } = position; - if (status === LongPositionStatus.OPENING_POSITION) { - // Show 100% when position is fully opened - return 100; - } - const progressPercent = (Number(Utils.formatAmount(mBought)) * 100) / Number(Utils.formatAmount(iTotalBuy)); - return Math.min(Math.max(progressPercent, 0), 100); -}; - -const calculatePnL = (position: LongPositionState): { pnl: number; pnlPercent: number } => { - // Simplified PnL calculation - in real implementation, you'd fetch current prices - const totalInvested = Number(position.amount.iTotalBuy) / 1_000_000; - const currentValue = (Number(position.amount.mBought) / 1_000_000) * 1.05; // Mock 5% gain - const pnl = currentValue - totalInvested; - const pnlPercent = (pnl / totalInvested) * 100; - return { pnl, pnlPercent }; -}; - -enum ExtraStatus { - EXTRA_STEP_BUY_MORE = "extra_step_buy_more", - EXTRA_STEP_SELL_ALL = "extra_step_sell_all", -} - -type StepBuyMoreExtra = { - extraStatus: ExtraStatus.EXTRA_STEP_BUY_MORE; - buyMoreAmount: bigint; - nextStatus: LongPositionStatus.OPENING_POSITION; - logStatus: LongPositionStatus.STEP_BUY_MORE_LONG_ASSET; -}; -type StepSellAllExtra = { - extraStatus: ExtraStatus.EXTRA_STEP_SELL_ALL; - nextStatus: LongPositionStatus.CLOSED_POSITION; - logStatus: LongPositionStatus.STEP_SELL_ALL_LONG_ASSET; -}; - -type InnerHandleFn = (input: { - position: LongPositionState; - wallet: WalletData; - nitroWallet: NitroWalletData; - extra?: StepBuyMoreExtra | StepSellAllExtra; -}) => Promise; -type HandlePositionInput = { - position: LongPositionState; - errorMessage: string; - successMessage: string; - innerFn: InnerHandleFn; -}; - -const handleStep1: InnerHandleFn = async ({ position, wallet, nitroWallet, extra }) => { - if (position.hasCallback) { - await Helpers.sleep(10000); - const balance = await NitroWallet.fetchBalance(nitroWallet.walletInfo.address.bech32, CONFIG.networkEnv); - console.log("step 1 callback", XJSON.stringify(balance, 2)); - const minToken = Asset.fromString(LendingMarket.mapMINToken[CONFIG.networkEnv]); - let ok = balance.has(minToken); - const txHash = position.transactions[position.transactions.length - 1]?.txHash; - if (txHash) { - const txConfirmed = await Helpers.checkTxConfirmed(txHash); - console.log({ txConfirmed, txHash }); - ok = ok && txConfirmed; - } - if (ok) { - return { - ...position, - amount: { - ...position.amount, - mLongBalance: balance.get(minToken), - mTotalLong: position.amount.mTotalLong + balance.get(minToken), - }, - // priority extra - status: - extra && extra.extraStatus === ExtraStatus.EXTRA_STEP_BUY_MORE - ? extra.nextStatus - : LongPositionStatus.STEP_2_SUPPLY_TOKEN, - hasCallback: undefined, - callbackExtra: undefined, - }; - } else { - // continue callback - return { ...position, hasCallback: position.hasCallback + 1 }; - } - } - const [utxos, priceData] = await Promise.all([ - NitroWallet.fetchRawUtxos(nitroWallet.walletInfo.address.bech32, CONFIG.networkEnv), - LendingMarket.fetchAdaMinPrice(CONFIG.networkEnv), - ]); - invariant(nitroWallet.walletInfo.balance, "Nitro wallet balance is undefined"); - let mBought: bigint; - if (extra && extra.extraStatus === ExtraStatus.EXTRA_STEP_BUY_MORE) { - mBought = extra.buyMoreAmount; - } else { - mBought = 300_000_000n; - // mBought = nitroWallet.walletInfo.balance - LendingMarket.OpeningLongPosition.OPERATION_FEE_ADA; - } - if (mBought <= 0n) { - return { - ...position, - status: - extra && extra.extraStatus === ExtraStatus.EXTRA_STEP_BUY_MORE - ? extra.nextStatus - : LongPositionStatus.STEP_2_SUPPLY_TOKEN, - }; - } - const txHash = await LendingMarket.OpeningLongPosition.step1CreateOrder({ - nitroWallet: { - address: nitroWallet.walletInfo.address, - privateKey: nitroWallet.privateKey, - utxos, - submitTx: wallet.api.submitTx.bind(wallet.api), - }, - priceInAdaResponse: priceData, - networkEnv: CONFIG.networkEnv, - amountIn: mBought, - }); - console.log("Step 1 tx hash:", txHash); - const logStep = - extra && extra.extraStatus === ExtraStatus.EXTRA_STEP_BUY_MORE - ? extra.logStatus - : LongPositionStatus.STEP_1_BUY_LONG_ASSET; - return { - ...position, - amount: { - ...position.amount, - mBought: position.amount.mBought + mBought, - }, - updatedAt: Date.now(), - transactions: [...position.transactions, { txHash, step: logStep }], - hasCallback: 1, - }; -}; - -const handleStep2: InnerHandleFn = async ({ position, nitroWallet }) => { - if (position.hasCallback) { - await Helpers.sleep(10000); - const balance = await NitroWallet.fetchBalance(nitroWallet.walletInfo.address.bech32, CONFIG.networkEnv); - console.log("step 2 callback", XJSON.stringify(balance, 2)); - const qMinToken = Asset.fromString("186cd98a29585651c89f05807a876cf26cdf47a7f86f70be3b9e4cc0"); - let ok = balance.has(qMinToken); - const txHash = position.transactions[position.transactions.length - 1]?.txHash; - if (txHash) { - const txConfirmed = await Helpers.checkTxConfirmed(txHash); - console.log({ txConfirmed, txHash }); - ok = ok && txConfirmed; - } - if (ok) { - return { - ...position, - status: LongPositionStatus.STEP_3_BORROW_TOKEN, - amount: { - ...position.amount, - mSupplied: position.amount.mSupplied + balance.get(qMinToken), - }, - hasCallback: undefined, - callbackExtra: undefined, - }; - } else { - // continue callback - return { ...position, hasCallback: position.hasCallback + 1 }; - } - } - const utxos = await Helpers.fetchRawUtxos(nitroWallet.walletInfo.address); - const txHash = await LendingMarket.OpeningLongPosition.step2SupplyMIN({ - nitroWallet: { - address: nitroWallet.walletInfo.address, - privateKey: nitroWallet.privateKey, - utxos, - }, - minAmount: position.amount.mLongBalance, - networkEnv: CONFIG.networkEnv, - }); - console.log("Step 2 tx hash:", txHash); - return { - ...position, - updatedAt: Date.now(), - amount: { - ...position.amount, - mLongBalance: 0n, - }, - transactions: [...position.transactions, { txHash, step: LongPositionStatus.STEP_2_SUPPLY_TOKEN }], - hasCallback: 1, - }; -}; - -const handleStep3: InnerHandleFn = async ({ position, nitroWallet }) => { - if (position.hasCallback) { - await Helpers.sleep(10000); - const balance = await NitroWallet.fetchBalance(nitroWallet.walletInfo.address.bech32, CONFIG.networkEnv); - console.log("step 3 callback", XJSON.stringify(balance, 2)); - const qMinToken = Asset.fromString("186cd98a29585651c89f05807a876cf26cdf47a7f86f70be3b9e4cc0"); - let ok = !balance.has(qMinToken); - const txHash = position.transactions[position.transactions.length - 1]?.txHash; - if (txHash) { - const txConfirmed = await Helpers.checkTxConfirmed(txHash); - console.log({ txConfirmed, txHash }); - ok = ok && txConfirmed; - } - if (ok) { - return { - ...position, - status: LongPositionStatus.STEP_BUY_MORE_LONG_ASSET, - hasCallback: undefined, - callbackExtra: undefined, - }; - } else { - // continue callback - return { ...position, hasCallback: position.hasCallback + 1 }; - } - } - const utxos = await Helpers.fetchRawUtxos(nitroWallet.walletInfo.address); - const balance = Utxo.sumValue(utxos.map(Utxo.fromHex)); - const qMinToken = Asset.fromString("186cd98a29585651c89f05807a876cf26cdf47a7f86f70be3b9e4cc0"); - const qMinAmount = balance.get(qMinToken); - const collateralAmount = await LendingMarket.OpeningLongPosition.calculateWithdrawAllAmount({ - networkEnv: CONFIG.networkEnv, - address: nitroWallet.walletInfo.address, - marketId: "MIN", - qTokenAmount: Number(qMinAmount), - }); - const collaterals: LiqwidProvider.LoanCalculationInput["collaterals"] = [ - { - id: "Ada.186cd98a29585651c89f05807a876cf26cdf47a7f86f70be3b9e4cc0", - amount: Number(collateralAmount / 1e6), - }, - ]; - const buildTxCollaterals: LiqwidProvider.BorrowCollateral[] = [ - { - id: "qMIN", - amount: Number(qMinAmount), - }, - ]; - const { txHash, borrowAmount } = await LendingMarket.OpeningLongPosition.borrowAda({ - nitroWallet: { - address: nitroWallet.walletInfo.address, - privateKey: nitroWallet.privateKey, - utxos, - }, - borrowMarketId: "Ada", - currentDebt: 0, - collaterals, - buildTxCollaterals, - networkEnv: CONFIG.networkEnv, - forceBorrowAmount: Number(position.amount.iTotalBorrow), - }); - console.log("Step 3 tx hash:", txHash, borrowAmount); - return { - ...position, - updatedAt: Date.now(), - amount: { - ...position.amount, - mSupplied: 0n, - mBorrowed: position.amount.mBorrowed + borrowAmount, - }, - transactions: [...position.transactions, { txHash, step: LongPositionStatus.STEP_3_BORROW_TOKEN }], - hasCallback: 1, - }; -}; - -const handleStep4: InnerHandleFn = async ({ position, nitroWallet, wallet, extra }) => { - if (position.hasCallback) { - await Helpers.sleep(10000); - const balance = await NitroWallet.fetchBalance(nitroWallet.walletInfo.address.bech32, CONFIG.networkEnv); - console.log("step 4 callback", XJSON.stringify(balance, 2)); - const minToken = Asset.fromString(LendingMarket.mapMINToken[CONFIG.networkEnv]); - if (!balance.has(minToken)) { - return { - ...position, - status: - extra && extra.extraStatus === ExtraStatus.EXTRA_STEP_SELL_ALL - ? extra.nextStatus - : LongPositionStatus.STEP_5_REPAY_ASSET, - hasCallback: undefined, - callbackExtra: undefined, - }; - } else { - // continue callback - return { ...position, hasCallback: position.hasCallback + 1 }; - } - } - const [utxos, priceData] = await Promise.all([ - NitroWallet.fetchRawUtxos(nitroWallet.walletInfo.address.bech32, CONFIG.networkEnv), - LendingMarket.fetchAdaMinPrice(CONFIG.networkEnv), - ]); - const balance = Utxo.sumValue(utxos.map(Utxo.fromHex)); - console.log("step 4 balance", XJSON.stringify(balance, 2)); - const minToken = Asset.fromString(LendingMarket.mapMINToken[CONFIG.networkEnv]); - console.log("sell", balance.get(minToken)); - if (balance.get(minToken) <= 0n) { - return { - ...position, - status: - extra && extra.extraStatus === ExtraStatus.EXTRA_STEP_SELL_ALL - ? extra.nextStatus - : LongPositionStatus.STEP_5_REPAY_ASSET, - }; - } - const txHash = await LendingMarket.OpeningLongPosition.sellLongAsset({ - nitroWallet: { - address: nitroWallet.walletInfo.address, - privateKey: nitroWallet.privateKey, - utxos, - submitTx: wallet.api.submitTx.bind(wallet.api), - }, - priceInAdaResponse: priceData, - networkEnv: CONFIG.networkEnv, - amountIn: balance.get(minToken), - }); - console.log("selling tx hash:", txHash); - const logStatus = - extra && extra.extraStatus === ExtraStatus.EXTRA_STEP_SELL_ALL - ? extra.logStatus - : LongPositionStatus.STEP_4_SELL_LONG_ASSET; - return { - ...position, - updatedAt: Date.now(), - transactions: [...position.transactions, { txHash, step: logStatus }], - hasCallback: 1, - }; -}; - -// repay, close loan, receive qToken -const handleStep5: InnerHandleFn = async ({ position, nitroWallet }) => { - if (position.hasCallback) { - await Helpers.sleep(10000); - const balance = await NitroWallet.fetchBalance(nitroWallet.walletInfo.address.bech32, CONFIG.networkEnv); - console.log("step 5 callback", XJSON.stringify(balance, 2)); - const qMinToken = Asset.fromString("186cd98a29585651c89f05807a876cf26cdf47a7f86f70be3b9e4cc0"); - let ok = balance.has(qMinToken); - const txHash = position.transactions[position.transactions.length - 1]?.txHash; - if (txHash) { - const txConfirmed = await Helpers.checkTxConfirmed(txHash); - console.log({ txConfirmed, txHash }); - ok = ok && txConfirmed; - } - if (ok) { - return { - ...position, - status: LongPositionStatus.STEP_6_WITHDRAW_COLLATERAL, - hasCallback: undefined, - callbackExtra: undefined, - }; - } - } - const utxos = await Helpers.fetchRawUtxos(nitroWallet.walletInfo.address); - const txHash = await LendingMarket.OpeningLongPosition.repayAllDebt({ - nitroWallet: { - address: nitroWallet.walletInfo.address, - privateKey: nitroWallet.privateKey, - utxos, - }, - networkEnv: CONFIG.networkEnv, - }); - return { - ...position, - updatedAt: Date.now(), - transactions: [...position.transactions, { txHash, step: LongPositionStatus.STEP_5_REPAY_ASSET }], - hasCallback: 1, - }; -}; - -// withdraw collateral, pay qMIN, receive MIN -const handleStep6: InnerHandleFn = async ({ position, nitroWallet }) => { - if (position.hasCallback) { - await Helpers.sleep(10000); - const balance = await NitroWallet.fetchBalance(nitroWallet.walletInfo.address.bech32, CONFIG.networkEnv); - console.log("step 6 callback", XJSON.stringify(balance, 2)); - const minToken = Asset.fromString(LendingMarket.mapMINToken[CONFIG.networkEnv]); - let ok = balance.has(minToken); - const txHash = position.transactions[position.transactions.length - 1]?.txHash; - if (txHash) { - const txConfirmed = await Helpers.checkTxConfirmed(txHash); - console.log({ txConfirmed, txHash }); - ok = ok && txConfirmed; - } - if (ok) { - return { - ...position, - status: LongPositionStatus.STEP_SELL_ALL_LONG_ASSET, - hasCallback: undefined, - callbackExtra: undefined, - }; - } else { - // continue callback - return { ...position, hasCallback: position.hasCallback + 1 }; - } - } - const utxos = await Helpers.fetchRawUtxos(nitroWallet.walletInfo.address); - const balance = Utxo.sumValue(utxos.map(Utxo.fromHex)); - const qMinToken = Asset.fromString("186cd98a29585651c89f05807a876cf26cdf47a7f86f70be3b9e4cc0"); - const supplyAmount = balance.get(qMinToken); - const txHash = await LendingMarket.OpeningLongPosition.withdrawAllSupply({ - nitroWallet: { - address: nitroWallet.walletInfo.address, - privateKey: nitroWallet.privateKey, - utxos, - }, - networkEnv: CONFIG.networkEnv, - marketId: "MIN", - supplyQTokenAmount: Number(supplyAmount), - }); - console.log("Step 6: Withdrawing collateral from Liqwid", txHash); - return { - ...position, - updatedAt: Date.now(), - amount: { - ...position.amount, - mSupplied: 0n, - }, - transactions: [...position.transactions, { txHash, step: LongPositionStatus.STEP_6_WITHDRAW_COLLATERAL }], - hasCallback: 1, - }; -}; - -// MARK: Position Tab -export const PositionTab = () => { - const { message } = App.useApp(); - const wallet = useAtomValue(walletAtom); - const nitroWallet = useAtomValue(nitroWalletAtom); - const positions = useAtomValue(longPositionAtom); - const setPositions = useSetAtom(setLongPositionAtom); - - // Track positions that are currently being processed to prevent duplicate calls - const processingPositions = useRef>(new Set()); - - const handlePosition = useCallback( - async (input: HandlePositionInput) => { - const { position, errorMessage, successMessage, innerFn } = input; - if (!nitroWallet || !wallet) return; - // Check if this position is already being processed - if (processingPositions.current.has(position.positionId)) { - return; - } - // Mark position as being processed - processingPositions.current.add(position.positionId); - try { - let retries = 0; - const maxRetries = 3; - let lastError: Error | null = null; - - while (retries <= maxRetries) { - try { - const newPosition = await innerFn({ position, wallet, nitroWallet }); - setPositions((prev) => prev.map((p) => (p.positionId === position.positionId ? newPosition : p))); - if (!newPosition.hasCallback) { - message.success(`${successMessage} ${position.positionId.slice(0, 8)}`); - } - break; // Exit loop on success - } catch (error) { - lastError = error instanceof Error ? error : new Error(String(error)); - if (retries < maxRetries) { - retries++; - console.error("backoff error", error); - console.log( - `Retry ${retries}/${maxRetries} for position ${position.positionId.slice(0, 8)} after 30s...`, - ); - await Helpers.sleep(30000); // Sleep 30 seconds before retry - } else { - const txHash = position.transactions[position.transactions.length - 1]?.txHash; - if (txHash) { - const txConfirmed = await Helpers.checkTxConfirmed(txHash); - if (!txConfirmed) { - const prevStep = position.transactions[position.transactions.length - 2]?.step; - const lastStep = position.transactions[position.transactions.length - 1]?.step; - if (prevStep && lastStep && prevStep === lastStep) { - const transactions = [...position.transactions]; - transactions.pop(); // remove last failed tx - const newPosition = { ...position, hasCallback: 1, transactions }; - setPositions((prev) => prev.map((p) => (p.positionId === position.positionId ? newPosition : p))); - } - } - } - console.error("max retries reached for position:", position.positionId, lastError); - setTimeout(() => { - window.location.reload(); - }, 5000); - // throw lastError; - } - } - } - } catch (error) { - const errorMsg = error instanceof Error ? error.message : String(error); - message.error(`${errorMessage}: ${errorMsg}`); - console.error("handle position error: ", error); - } finally { - // Remove from processing set when done (success or error) - processingPositions.current.delete(position.positionId); - } - }, - [nitroWallet, wallet, setPositions, message], - ); - - useEffect(() => { - console.log("go here", { - date: new Date().toString(), - status: positions[0]?.status, - hasCallback: positions[0]?.hasCallback, - }); - for (const position of positions) { - if (position.status === LongPositionStatus.STEP_1_BUY_LONG_ASSET) { - handlePosition({ - position, - errorMessage: "Failed to buy long asset", - successMessage: "Successfully bought long asset for position", - innerFn: handleStep1, - }); - continue; - } - if (position.status === LongPositionStatus.STEP_2_SUPPLY_TOKEN) { - handlePosition({ - position, - errorMessage: "Failed to supply MIN tokens", - successMessage: "Successfully supplied MIN tokens for position", - innerFn: handleStep2, - }); - continue; - } - if (position.status === LongPositionStatus.STEP_3_BORROW_TOKEN) { - handlePosition({ - position, - errorMessage: "Failed to borrow tokens", - successMessage: "Successfully borrowed tokens for position", - innerFn: handleStep3, - }); - continue; - } - if (position.status === LongPositionStatus.STEP_BUY_MORE_LONG_ASSET) { - const buyMoreAmount = position.amount.iTotalBuy - position.amount.mBought; - handlePosition({ - position, - errorMessage: "Failed to buy more long asset", - successMessage: "Successfully bought more long asset for position", - innerFn: async (input) => { - return handleStep1({ - ...input, - extra: { - extraStatus: ExtraStatus.EXTRA_STEP_BUY_MORE, - buyMoreAmount, - nextStatus: LongPositionStatus.OPENING_POSITION, - logStatus: LongPositionStatus.STEP_BUY_MORE_LONG_ASSET, - }, - }); - }, - }); - continue; - } - if (position.status === LongPositionStatus.STEP_4_SELL_LONG_ASSET) { - handlePosition({ - position, - errorMessage: "Failed to sell long asset", - successMessage: "Successfully sold long asset for position", - innerFn: handleStep4, - }); - continue; - } - if (position.status === LongPositionStatus.STEP_5_REPAY_ASSET) { - handlePosition({ - position, - errorMessage: "Failed to close loan", - successMessage: "Successfully closed loan and repaid debt", - innerFn: handleStep5, - }); - continue; - } - if (position.status === LongPositionStatus.STEP_6_WITHDRAW_COLLATERAL) { - handlePosition({ - position, - errorMessage: "Failed to withdraw collateral", - successMessage: "Successfully withdrew collateral for position", - innerFn: handleStep6, - }); - continue; - } - if (position.status === LongPositionStatus.STEP_SELL_ALL_LONG_ASSET) { - handlePosition({ - position, - errorMessage: "Failed to sell all long asset", - successMessage: "Successfully sold all long asset for position", - innerFn: async (input) => { - return handleStep4({ - ...input, - extra: { - extraStatus: ExtraStatus.EXTRA_STEP_SELL_ALL, - nextStatus: LongPositionStatus.CLOSED_POSITION, - logStatus: LongPositionStatus.STEP_SELL_ALL_LONG_ASSET, - }, - }); - }, - }); - } - } - }, [positions, handlePosition]); - - const handleClosePosition = async (positionId: string) => { - try { - setPositions((prev) => - prev.map((p) => - p.positionId === positionId - ? { - ...p, - status: LongPositionStatus.STEP_4_SELL_LONG_ASSET, - updatedAt: Date.now(), - } - : p, - ), - ); - message.success("Position closing initiated"); - } catch (err) { - const errorMsg = err instanceof Error ? err.message : String(err); - message.error(`Failed to close position: ${errorMsg}`); - } - }; - - if (positions.length === 0) { - return ( - - ); - } - - const isPositionInProgress = ![LongPositionStatus.OPENING_POSITION, LongPositionStatus.CLOSED_POSITION].includes( - positions[0]?.status ?? LongPositionStatus.STEP_1_BUY_LONG_ASSET, - ); - - return ( -
- - {isPositionInProgress && ( - - )} - - - - - {positions.map((position) => { - const { pnl, pnlPercent } = calculatePnL(position); - const isPositionComplete = position.status === LongPositionStatus.OPENING_POSITION; - - return ( - } - onClick={() => handleClosePosition(position.positionId)} - type="text" - > - Close Position - - ) - } - key={position.positionId} - style={{ - border: isPositionComplete ? "2px solid #52c41a" : "1px solid #d9d9d9", - boxShadow: isPositionComplete ? "0 4px 12px rgba(82, 196, 26, 0.15)" : undefined, - }} - title={ - - - Position #{position.positionId.slice(0, 8)} - {getStatusText(position.status)} - - } - > - {/* Progress Bar */} - - {/* Basic Position Info */} - - - } - title="Leverage" - value={`${position.leverage}x`} - valueStyle={{ color: "#1890ff", fontWeight: "bold" }} - /> - - - } - title="Long Asset" - value={position.longAsset.tokenName.toString()} - /> - - - - - - = 0 ? "+" : ""} - suffix="ADA" - title="P&L" - value={pnl} - valueStyle={{ - color: pnl >= 0 ? "#3f8600" : "#cf1322", - fontWeight: "bold", - }} - /> - - - - {/* Financial Details */} - - - - - - - - - - - - - - - {/* Fees */} - - - - - - - - - = 0 ? "+" : ""} - suffix="%" - title="P&L %" - value={pnlPercent} - valueStyle={{ - fontSize: "12px", - color: pnlPercent >= 0 ? "#3f8600" : "#cf1322", - fontWeight: "bold", - }} - /> - - {" "} - {/* Transaction History */} - {position.transactions.length > 0 && ( - <> - -
-

Transaction History:

- - {position.transactions.map((tx) => ( -
-
- {getStatusText(tx.step)} -
-
- Tx: {tx.txHash} -
-
- ))} -
-
- - )} - {/* Timestamps */} -
- Created: {new Date(position.createdAt).toLocaleString()} - {position.updatedAt !== position.createdAt && ( - Updated: {new Date(position.updatedAt).toLocaleString()} - )} -
-
- ); - })} -
-
- ); -}; diff --git a/apps/web/app/components/margin-trading-trade-tab.tsx b/apps/web/app/components/margin-trading-trade-tab.tsx deleted file mode 100644 index dcce637..0000000 --- a/apps/web/app/components/margin-trading-trade-tab.tsx +++ /dev/null @@ -1,440 +0,0 @@ -"use client"; - -import { ArrowRightOutlined, InfoCircleOutlined } from "@ant-design/icons"; -import { DexV2Calculation, OrderV2Direction } from "@minswap/felis-dex-v2"; -import { ADA, Asset, Bytes } from "@minswap/felis-ledger-core"; -import { sha3 } from "@minswap/felis-ledger-utils"; -import { LendingMarket } from "@minswap/felis-lending-market"; -import invariant from "@minswap/tiny-invariant"; -import { - Alert, - App, - Button, - Card, - Col, - Divider, - Form, - InputNumber, - Radio, - Row, - Slider, - Space, - Statistic, - Tooltip, -} from "antd"; -import { useAtomValue, useSetAtom } from "jotai"; -import { useCallback, useEffect, useState } from "react"; -import { - type LongPositionState, - LongPositionStatus, - longPositionAtom, - minAdaPriceAtom, - nitroBalanceAtom, - nitroWalletAtom, - setLongPositionAtom, - walletAtom, -} from "../atoms/walletAtom"; -import { CONFIG } from "../config"; - -// POC Configuration -const MIN_REQUIRED_ADA = 312_000_000n; -const HARDCODED_TOTAL_ADA = 450; -const HARDCODED_LEVERAGE = 1.5; - -// MARK: Trade Tab -export const TradeTab = () => { - const { message } = App.useApp(); - const nitroWallet = useAtomValue(nitroWalletAtom); - const wallet = useAtomValue(walletAtom); - const positions = useAtomValue(longPositionAtom); - const setPositions = useSetAtom(setLongPositionAtom); - const nitroBalance = useAtomValue(nitroBalanceAtom); - - // Trading parameters - const [leverage, setLeverage] = useState<1 | 1.5>(HARDCODED_LEVERAGE as 1.5); - const [marginMode, _setMarginMode] = useState<"isolated">("isolated"); - const [autoBorrowRepay, setAutoBorrowRepay] = useState(true); - - // Input values - const [adaAmount, setAdaAmount] = useState(HARDCODED_TOTAL_ADA); - const [minAmount, setMinAmount] = useState(0); - const [sliderValue, setSliderValue] = useState(100); - const minAdaPrice = useAtomValue(minAdaPriceAtom); - - // Loading states - const [loading, setLoading] = useState(false); - // const _hasEnoughBalance = nitroBalance >= MIN_REQUIRED_ADA; - - const handleAmountChange = (value: number | null) => { - if (value === null) return; - setMinAmount(value); - }; - - const handleAdaAmountChange = useCallback( - (value: number | null) => { - if (value === null) return; - // const percentage = (value / Number(MIN_REQUIRED_ADA)) * 100; - setSliderValue(100); - - if (minAdaPrice) { - try { - const amountInLovelace = BigInt(Math.floor(value * 1_000_000)); - const result = DexV2Calculation.calculateSwapExactIn({ - datumReserves: [BigInt(minAdaPrice.datumReserves[0]), BigInt(minAdaPrice.datumReserves[1])], - valueReserves: [BigInt(minAdaPrice.valueReserves[0]), BigInt(minAdaPrice.valueReserves[1])], - tradingFee: { - feeANumerator: BigInt(minAdaPrice.tradingFee.feeANumerator), - feeBNumerator: BigInt(minAdaPrice.tradingFee.feeBNumerator), - }, - amountIn: amountInLovelace, - direction: OrderV2Direction.A_TO_B, - feeSharingNumerator: minAdaPrice.feeSharingNumerator ? BigInt(minAdaPrice.feeSharingNumerator) : null, - }); - - const minAmountReceived = Number(result.amountOut) / 1_000_000; - setMinAmount(minAmountReceived); - } catch (err) { - console.error("Failed to calculate MIN amount:", err); - } - } - }, - [minAdaPrice], - ); - - useEffect(() => { - if (nitroBalance && nitroBalance >= MIN_REQUIRED_ADA) { - handleAdaAmountChange(300); - } - }, [nitroBalance, handleAdaAmountChange]); - - // const handleSliderChange = (value: number) => { - // setSliderValue(value); - // if (minAdaPrice) { - // try { - // const amountInLovelace = BigInt(Math.floor(totalAda * 1_000_000)); - - // const result = DexV2Calculation.calculateSwapExactIn({ - // datumReserves: [BigInt(minAdaPrice.datumReserves[0]), BigInt(minAdaPrice.datumReserves[1])], - // valueReserves: [BigInt(minAdaPrice.valueReserves[0]), BigInt(minAdaPrice.valueReserves[1])], - // tradingFee: { - // feeANumerator: BigInt(minAdaPrice.tradingFee.feeANumerator), - // feeBNumerator: BigInt(minAdaPrice.tradingFee.feeBNumerator), - // }, - // amountIn: amountInLovelace, - // direction: OrderV2Direction.A_TO_B, - // feeSharingNumerator: minAdaPrice.feeSharingNumerator ? BigInt(minAdaPrice.feeSharingNumerator) : null, - // }); - - // const minAmountReceived = Number(result.amountOut) / 1_000_000; - // setMinAmount(minAmountReceived); - // } catch (err) { - // console.error("Failed to calculate MIN amount:", err); - // } - // } - // }; - - const borrowAmount = 150; - const shouldBorrow = borrowAmount > 0; - const adaDebt = shouldBorrow ? borrowAmount : 0; - - const calculateLiquidationPrice = (): number => { - if (adaDebt <= 0) return 0; - return adaDebt / minAmount; - }; - - const _liquidationPrice = calculateLiquidationPrice(); - - const handleBuy = async () => { - invariant(wallet && nitroWallet); - if (adaAmount <= 0) { - message.error("Please enter ADA amount"); - return; - } - - if (!minAdaPrice) { - message.error("Price data not available"); - return; - } - - setLoading(true); - try { - const now = Date.now(); - const newLongPositionState: LongPositionState = { - positionId: sha3(Bytes.fromString(`${nitroWallet.walletInfo.address.bech32}.${now}`).hex), - status: LongPositionStatus.STEP_1_BUY_LONG_ASSET, - nitroWalletAddress: nitroWallet.walletInfo.address.bech32, - leverage, - longAsset: Asset.fromString(LendingMarket.mapMINToken[CONFIG.networkEnv]), // MIN - borrowAsset: ADA, - createdAt: Date.now(), - updatedAt: Date.now(), - amount: { - iTotalBuy: BigInt(Math.floor(adaAmount * 1e6)), - iTotalBorrow: 150_000_000n, - iTotalOperationFee: LendingMarket.OpeningLongPosition.OPERATION_FEE_ADA, - mTotalPaidFee: 0n, - mBought: 0n, - mTotalLong: 0n, - mLongBalance: 0n, - mBorrowed: 0n, - mSupplied: 0n, - mRepaid: 0n, - mWithdrawn: 0n, - }, - transactions: [], - }; - setPositions([newLongPositionState]); - message.success("Position opened successfully!"); - setAdaAmount(0); - setMinAmount(0); - setSliderValue(0); - } catch (err) { - const errorMsg = err instanceof Error ? err.message : String(err); - message.error(`Failed to open position: ${errorMsg}`); - console.error("Buy error:", err); - } finally { - setLoading(false); - } - }; - - return ( - - {/* POC Version Warning */} - {nitroWallet?.walletInfo && nitroBalance >= MIN_REQUIRED_ADA ? ( - - ) : null} - - {nitroWallet?.walletInfo && nitroBalance < MIN_REQUIRED_ADA ? ( - - ) : null} - - {/* Mode Selection */} - - -
Margin Mode
- - - -
Leverage
- setLeverage(e.target.value)} style={{ width: "100%" }} value={leverage}> - - 1.00x - - 1.50x - - - -
Borrow/Repay
- setAutoBorrowRepay(e.target.value === "auto")} - style={{ width: "100%" }} - value={autoBorrowRepay ? "auto" : "manual"} - > - Auto - - Manual - - - - -
Order Type
- - -
- - - - {/* Market Price Info */} - - - - - - - - - - - - - - {/* Amount Inputs */} -
- - - - - - - - - - - - - - - -
- - {/* Slider */} -
-
- Margin Slider - {sliderValue.toFixed(0)}% -
- {}} - value={sliderValue} - /> -
- - - - {/* Trading Info */} - - - - - Avbl - - } - value={((Number(nitroBalance) ?? 0) / 1_000_000).toFixed(2)} - valueStyle={{ fontSize: 14 }} - /> - - - - - - Max - - } - value={(((Number(nitroBalance) ?? 0) / 1_000_000) * leverage).toFixed(2)} - valueStyle={{ fontSize: 14 }} - /> - - - {/* - - - Liq.Price - - } - value={liquidationPrice.toFixed(4)} - valueStyle={{ fontSize: 14 }} - /> - - */} - - - {/* Borrow/Repay Info */} - {shouldBorrow && ( - <> - - - - - - Borrow - - } - value={borrowAmount.toFixed(2)} - valueStyle={{ fontSize: 14 }} - /> - - - - - - Repay - - } - value={borrowAmount.toFixed(2)} - valueStyle={{ fontSize: 14 }} - /> - - - - - )} - - {/* Buy Button */} - -
- ); -}; diff --git a/apps/web/app/components/margin-trading.tsx b/apps/web/app/components/margin-trading.tsx deleted file mode 100644 index fdf493f..0000000 --- a/apps/web/app/components/margin-trading.tsx +++ /dev/null @@ -1,43 +0,0 @@ -"use client"; - -import { Alert, Badge, Card, Tabs } from "antd"; -import { useAtomValue } from "jotai"; -import { longPositionAtom, nitroWalletAtom } from "../atoms/walletAtom"; -import { PositionTab } from "./margin-trading-position-tab"; -import { TradeTab } from "./margin-trading-trade-tab"; - -export const MarginTrading = () => { - const nitroWallet = useAtomValue(nitroWalletAtom); - const positions = useAtomValue(longPositionAtom); - const hasActivePositions = (positions ?? []).length > 0; - - return ( - } - style={{ marginTop: 16 }} - title="Isolated Margin Long $MIN" - > - {!nitroWallet && ( - - )} - , - }, - ]), - { - key: "position", - label: `Position${hasActivePositions ? ` (${(positions ?? []).length})` : ""}`, - children: , - }, - ]} - /> - - ); -}; diff --git a/apps/web/app/components/nitro-wallet-connector.tsx b/apps/web/app/components/nitro-wallet-connector.tsx deleted file mode 100644 index a52a730..0000000 --- a/apps/web/app/components/nitro-wallet-connector.tsx +++ /dev/null @@ -1,252 +0,0 @@ -"use client"; - -import { CopyOutlined, LogoutOutlined } from "@ant-design/icons"; -import { Address } from "@minswap/felis-ledger-core"; -import { NitroWallet } from "@minswap/felis-lending-market"; -import invariant from "@minswap/tiny-invariant"; -import { Alert, App, Button, Card, Col, Row, Space, Statistic, Tooltip } from "antd"; -import { useAtom, useAtomValue, useSetAtom } from "jotai"; -import { useCallback, useEffect, useState } from "react"; -import { - type NitroWalletData, - nitroBalanceAtom, - nitroWalletAtom, - setNitroBalanceAtom, - setNitroWalletAtom, - walletAtom, -} from "../atoms/walletAtom"; -import { CONFIG } from "../config"; -import { LocalStorageKey } from "../constants/storage"; -import { Utils } from "../lib/utils"; - -export const NitroWalletConnector = () => { - const { message } = App.useApp(); - const nitroWallet = useAtomValue(nitroWalletAtom); - const wallet = useAtomValue(walletAtom); - const [_, setNitroWallet] = useAtom(setNitroWalletAtom); - const [loading, setLoading] = useState(false); - const nitroBalance = useAtomValue(nitroBalanceAtom); - const setNitroBalance = useSetAtom(setNitroBalanceAtom); - - /** - * Fetch balance from the blockchain for a given address - */ - const fetchBalance = useCallback( - async (address: Address): Promise => { - try { - const value = await NitroWallet.fetchBalance(address.bech32, CONFIG.networkEnv); - setNitroBalance(value.coin()); - return value.coin(); - } catch (err) { - const errorMsg = err instanceof Error ? err.message : String(err); - message.error(`Failed to fetch balance: ${errorMsg}`); - return 0n; - } - }, - [message.error, setNitroBalance], - ); - - const loadFromStorage = useCallback(async () => { - const rootAddress = wallet?.walletInfo?.address.bech32; - if (!rootAddress) { - return false; - } - try { - const stored = localStorage.getItem(LocalStorageKey.NITRO_WALLET); - if (stored) { - const parsedData = JSON.parse(stored); - const nitroWallet = { - ...parsedData, - walletInfo: { - ...parsedData.walletInfo, - address: Address.fromBech32(parsedData.walletInfo.address), - }, - }; - if (nitroWallet.walletInfo.rootAddress !== rootAddress) { - return false; - } - - // Fetch real-time balance from blockchain - const balance = await fetchBalance(nitroWallet.walletInfo.address); - // Create updated wallet with fresh balance - const updatedNitroWallet = { - ...nitroWallet, - walletInfo: { - ...nitroWallet.walletInfo, - balance: balance, - }, - }; - - setNitroWallet(updatedNitroWallet); - return true; - } - return false; - } catch (err) { - const errorMsg = err instanceof Error ? err.message : String(err); - message.error(`Failed to load Nitro wallet from storage: ${errorMsg}`); - return false; - } - }, [wallet?.walletInfo, fetchBalance, setNitroWallet, message.error]); - - useEffect(() => { - if (wallet?.walletInfo) { - loadFromStorage(); - } - }, [wallet?.walletInfo, loadFromStorage]); - - const handleCopyAddress = async (address: string) => { - try { - await navigator.clipboard.writeText(address); - message.success("Address copied!"); - } catch (_err) { - message.error("Failed to copy address"); - } - }; - - /** - * Save Nitro wallet to localStorage - */ - const saveToStorage = useCallback( - (data: NitroWalletData) => { - try { - localStorage.setItem(LocalStorageKey.NITRO_WALLET, JSON.stringify(data)); - } catch (err) { - const errorMsg = err instanceof Error ? err.message : String(err); - message.error(`Failed to save Nitro wallet: ${errorMsg}`); - } - }, - [message.error], - ); - - /** - * Create new Nitro wallet using wallet.api.signData() - * Requires connected wallet (wallet.api must exist) - */ - const createNewWallet = useCallback(async () => { - invariant(wallet?.api && wallet.walletInfo); - try { - const nitroWalletData = await NitroWallet.createNitroWallet({ - rootAddress: wallet.walletInfo.address.bech32, - networkId: wallet.walletInfo.networkId, - signData: wallet.api.signData.bind(wallet.api), - }); - const balance = await fetchBalance(nitroWalletData.walletInfo.address); - setNitroWallet({ ...nitroWalletData, walletInfo: { ...nitroWalletData.walletInfo, balance } }); - return nitroWalletData; - } catch (err) { - const errorMsg = err instanceof Error ? err.message : String(err); - throw new Error(`Failed to create new Nitro wallet: ${errorMsg}`); - } - }, [wallet?.walletInfo, setNitroWallet, wallet?.api, fetchBalance]); - - const connect = useCallback(async () => { - setLoading(true); - try { - // Try to load from localStorage first - const loaded = await loadFromStorage(); - if (loaded) { - return; - } - - // If not in storage, create new wallet - const nitroWallet = await createNewWallet(); - saveToStorage(nitroWallet); - } catch (err) { - const errorMsg = err instanceof Error ? err.message : String(err); - message.error(`Failed to connect Nitro wallet: ${errorMsg}`); - } finally { - setLoading(false); - } - }, [createNewWallet, loadFromStorage, message.error, saveToStorage]); - - /** - * Disconnect and remove from localStorage - */ - const disconnect = useCallback(() => { - try { - localStorage.removeItem(LocalStorageKey.NITRO_WALLET); - setNitroWallet(null); - } catch (err) { - const errorMsg = err instanceof Error ? err.message : String(err); - message.error(`Failed to disconnect Nitro wallet: ${errorMsg}`); - } - }, [message.error, setNitroWallet]); - - if (nitroWallet) { - const { walletInfo } = nitroWallet; - return ( - } onClick={disconnect} type="text"> - Disconnect - - } - headStyle={{ color: "white", borderColor: "#764ba2" }} - style={{ - marginTop: 16, - background: "linear-gradient(135deg, #764ba2 0%, #667eea 100%)", - borderColor: "#764ba2", - }} - title="Nitro Wallet Connected" - > - - - - - -
-
Nitro Address
- - - -
- -
-
- ); - } - - return ( - - - {!wallet?.walletInfo && ( - - )} - {wallet?.walletInfo && !nitroWallet && ( - - - - - )} - {nitroWallet && ( - - )} - - - ); -}; diff --git a/apps/web/app/components/short-trading-position-tab.tsx b/apps/web/app/components/short-trading-position-tab.tsx deleted file mode 100644 index d3f8793..0000000 --- a/apps/web/app/components/short-trading-position-tab.tsx +++ /dev/null @@ -1,731 +0,0 @@ -"use client"; - -import { CloseOutlined, DollarOutlined, SwapOutlined, TrophyOutlined } from "@ant-design/icons"; -import { DexV2Calculation, OrderV2Direction } from "@minswap/felis-dex-v2"; -import { Address, Asset } from "@minswap/felis-ledger-core"; -import { LendingMarket, LiqwidProvider } from "@minswap/felis-lending-market"; -import invariant from "@minswap/tiny-invariant"; -import { Alert, App, Button, Card, Col, Divider, Progress, Row, Space, Statistic, Tag } from "antd"; -import { useAtomValue, useSetAtom } from "jotai"; -import { useCallback, useEffect, useState } from "react"; -import { - minAdaPriceAtom, - nitroWalletAtom, - type ShortPositionState, - ShortPositionStatus, - ShortPositionStatus as ShortPositionStatusEnum, - setShortPositionAtom, - shortPositionAtom, -} from "../atoms/walletAtom"; -import { CONFIG } from "../config"; -import { - ExtraStatus, - shortHandleStep1, - shortHandleStep2, - shortHandleStep3, - shortHandleStep4, - shortHandleStep5, - shortHandleStep6, - usePosition, -} from "../lib/use-position"; -import { Utils } from "../lib/utils"; - -const getStatusColor = (status: ShortPositionStatus) => { - switch (status) { - case ShortPositionStatusEnum.STEP_1_SUPPLY_TOKEN: - return "processing"; - case ShortPositionStatus.STEP_2_BORROW_TOKEN: - return "purple"; - case ShortPositionStatus.STEP_3_SHORT_TOKEN: - return "magenta"; - case ShortPositionStatusEnum.OPENING_POSITION: - return "success"; - case ShortPositionStatusEnum.STEP_4_BUY_BACK_TOKEN: - return "orange"; - case ShortPositionStatusEnum.STEP_5_REPAY_ASSET: - return "geekblue"; - case ShortPositionStatusEnum.STEP_6_WITHDRAW_COLLATERAL: - return "cyan"; - case ShortPositionStatusEnum.CLOSED_POSITION: - return "red"; - default: - return "default"; - } -}; - -const getStatusText = (status: ShortPositionStatus) => { - switch (status) { - case ShortPositionStatusEnum.STEP_1_SUPPLY_TOKEN: - return "Supplying Token"; - case ShortPositionStatusEnum.STEP_2_BORROW_TOKEN: - return "Borrowing Token"; - case ShortPositionStatusEnum.STEP_3_SHORT_TOKEN: - return "Short Token"; - case ShortPositionStatusEnum.STEP_4_BUY_BACK_TOKEN: - return "Buying Back Token"; - case ShortPositionStatusEnum.STEP_5_REPAY_ASSET: - return "Repaying Asset"; - case ShortPositionStatusEnum.STEP_6_WITHDRAW_COLLATERAL: - return "Withdrawing Collateral"; - default: - return status.replace(/_/g, " "); - } -}; - -const getProgressPercent = (_position: ShortPositionState) => { - if (_position.amount.mShortedL < 0n) { - return 50; - } - return 100; -}; - -const calculatePnlA = (options: { - mClosedAda: bigint; - minAdaPrice: LendingMarket.PriceInAdaResponse | null; - shortReceivedL: bigint; - totalRepay: bigint; - supplyEarned: number; -}): number => { - const { mClosedAda, minAdaPrice, shortReceivedL, totalRepay, supplyEarned } = options; - if (mClosedAda > 0n) { - const pnlA = (Number(shortReceivedL) - Number(mClosedAda)) / 1e6 + supplyEarned; - return pnlA; - } - if (!minAdaPrice) { - return 0; - } - const result = DexV2Calculation.calculateSwapExactOut({ - datumReserves: [BigInt(minAdaPrice.datumReserves[0]), BigInt(minAdaPrice.datumReserves[1])], - valueReserves: [BigInt(minAdaPrice.valueReserves[0]), BigInt(minAdaPrice.valueReserves[1])], - tradingFee: { - feeANumerator: BigInt(minAdaPrice.tradingFee.feeANumerator), - feeBNumerator: BigInt(minAdaPrice.tradingFee.feeBNumerator), - }, - expectedReceive: totalRepay, - direction: OrderV2Direction.A_TO_B, - feeSharingNumerator: minAdaPrice.feeSharingNumerator ? BigInt(minAdaPrice.feeSharingNumerator) : null, - }); - if (result.type === "err") { - return 0; - } - const buyBackL = result.value.necessaryAmountIn; - const pnlL = Number(shortReceivedL) - Number(buyBackL); - const pnlA = pnlL / 1e6 + supplyEarned; - return pnlA; -}; - -// MARK: Short Position Tab -export const ShortPositionTab = () => { - const { message } = App.useApp(); - const nitroWallet = useAtomValue(nitroWalletAtom); - const positions = useAtomValue(shortPositionAtom); - const setShortPositions = useSetAtom(setShortPositionAtom); - const positionHandler = usePosition(); - const [supplyApy, setSupplyApy] = useState(0); - const [borrowApy, setBorrowApy] = useState(0); - const [borrowInterest, setBorrowInterest] = useState(0); - const [supplyInterest, setSupplyInterest] = useState(0); - // const [liquidationCall, setLiquidationCall] = useState(false); - - const minAdaPrice = useAtomValue(minAdaPriceAtom); - - useEffect(() => { - const getSupplyApy = async (paymentKey: string) => { - const result = await LiqwidProvider.getNetApy({ - input: { - paymentKeys: [paymentKey], - supplies: [ - { - marketId: "Ada", - amount: 1000, - }, - ], - currency: "USD", - }, - networkEnv: CONFIG.networkEnv, - }); - if (result.type === "err") { - return 0; - } else { - return Math.floor(result.value.supplyApy * 100 * 100) / 100; - } - }; - if (nitroWallet) { - const pkh = nitroWallet.walletInfo.address.toPubKeyHash()?.keyHash.hex; - if (pkh) { - getSupplyApy(pkh).then((apy) => setSupplyApy(Number(apy))); - } - } - }, [nitroWallet]); - - // polling data - useEffect(() => { - if (!nitroWallet) { - return; - } - const paymentKey = nitroWallet?.walletInfo.address.toPubKeyHash()?.keyHash.hex; - if (!paymentKey) { - return; - } - const fetchData = async () => { - const loansData = await LiqwidProvider.getLoansBorrow({ - input: { - paymentKeys: [paymentKey], - }, - networkEnv: CONFIG.networkEnv, - }); - if (loansData.type === "ok") { - const loan = loansData.value[loansData.value.length - 1]; - if (loan) { - setBorrowApy(loan.APY * 100); - setBorrowInterest(loan.interest); - } - } - - const supplyEarned = await LiqwidProvider.getYieldEarned({ - input: { addresses: [nitroWallet.walletInfo.address.bech32] }, - networkEnv: CONFIG.networkEnv, - }); - if (supplyEarned.type === "ok") { - for (const market of supplyEarned.value.markets) { - if (market.id === "Ada") { - setSupplyInterest(market.amount); - } - } - } - }; - - fetchData(); - const interval = setInterval(fetchData, 10000); // 10 seconds - return () => clearInterval(interval); - }, [nitroWallet]); - - useEffect(() => { - console.log("go here", { - date: new Date().toString(), - status: positions[0]?.status, - hasCallback: positions[0]?.hasCallback, - }); - for (const position of positions) { - if (position.status === ShortPositionStatusEnum.STEP_1_SUPPLY_TOKEN) { - positionHandler.handlePosition({ - position, - errorMessage: "Failed to supply asset", - successMessage: "Successfully Supplied asset for position", - positionType: "short", - innerFn: async (input) => { - if (input.position.hasCallback && input.position.hasCallback >= 16) { - const transactions = [...input.position.transactions]; - transactions.pop(); - return { - ...input.position, - amount: { - ...position.amount, - mSuppliedL: 0n, - }, - transactions, - status: ShortPositionStatusEnum.STEP_1_SUPPLY_TOKEN, - hasCallback: undefined, - callbackExtra: undefined, - } as ShortPositionState; - } - return shortHandleStep1({ - ...input, - extra: { - extraStatus: ExtraStatus.EXTRA_SHORT_STEP_1, - marketId: "Ada", - amount: position.amount.iTotalSupplyL, - }, - }); - }, - }); - } else if (position.status === ShortPositionStatusEnum.STEP_2_BORROW_TOKEN) { - positionHandler.handlePosition({ - position, - errorMessage: "Failed to borrow asset", - successMessage: "Successfully borrowed asset for position", - positionType: "short", - innerFn: async (input) => { - if (input.position.hasCallback && input.position.hasCallback >= 16) { - const transactions = [...input.position.transactions]; - transactions.pop(); - return { - ...input.position, - amount: { - ...position.amount, - mBorrowedL: 0n, - }, - transactions, - status: ShortPositionStatusEnum.STEP_2_BORROW_TOKEN, - hasCallback: undefined, - callbackExtra: undefined, - } as ShortPositionState; - } - return shortHandleStep2({ - ...input, - extra: { - extraStatus: ExtraStatus.EXTRA_SHORT_STEP_2, - borrowAmountL: Number(position.amount.iBorrowAmountL), - collateralMode: { - mode: LendingMarket.CollateralMode.ISOLATED_MARGIN, - borrowMarketId: "MIN", - supplyMarketId: "Ada", - }, - borrowMarketId: "MIN", - }, - }); - }, - }); - } else if (position.status === ShortPositionStatusEnum.STEP_3_SHORT_TOKEN) { - positionHandler.handlePosition({ - position, - errorMessage: "Failed to short asset", - successMessage: "Successfully shorted asset for position", - positionType: "short", - innerFn: async (input) => { - const priceData = await LendingMarket.fetchAdaMinPrice(CONFIG.networkEnv); - return shortHandleStep3({ - ...input, - extra: { - extraStatus: ExtraStatus.EXTRA_SHORT_STEP_3, - priceInAdaResponse: priceData, - amountIn: position.amount.mBorrowedL, - }, - }); - }, - }); - } else if (position.status === ShortPositionStatusEnum.STEP_4_BUY_BACK_TOKEN) { - positionHandler.handlePosition({ - position, - errorMessage: "Failed to buy back asset", - successMessage: "Successfully bought back asset for position", - positionType: "short", - innerFn: async (input) => { - const priceData = await LendingMarket.fetchAdaMinPrice(CONFIG.networkEnv); - let loanTxHash: string | null = null; - for (const { txHash, step } of position.transactions) { - if (step === ShortPositionStatusEnum.STEP_2_BORROW_TOKEN) { - loanTxHash = txHash; - } - } - invariant(loanTxHash, "Loan transaction hash not found"); - const totalRepay = await LendingMarket.calculateRepayAllAmountL({ - networkEnv: CONFIG.networkEnv, - address: Address.fromBech32(position.nitroWalletAddress), - loanTxHash, - }); - return shortHandleStep4({ - ...input, - extra: { - extraStatus: ExtraStatus.EXTRA_SHORT_STEP_4, - priceInAdaResponse: priceData, - expectedReceive: totalRepay + totalRepay / 1000n, - }, - }); - }, - }); - } else if (position.status === ShortPositionStatusEnum.STEP_5_REPAY_ASSET) { - positionHandler.handlePosition({ - position, - errorMessage: "Failed to repay asset", - successMessage: "Successfully repaid asset for position", - positionType: "short", - innerFn: shortHandleStep5, - }); - } else if (position.status === ShortPositionStatusEnum.STEP_6_WITHDRAW_COLLATERAL) { - positionHandler.handlePosition({ - position, - errorMessage: "Failed to withdraw collateral", - successMessage: "Successfully withdrew collateral for position", - positionType: "short", - innerFn: async (input) => { - return shortHandleStep6({ - ...input, - extra: { - extraStatus: ExtraStatus.EXTRA_SHORT_STEP_6, - supplyMarketId: "Ada", - qToken: Asset.fromString(LiqwidProvider.mapQAdaToken[CONFIG.networkEnv]), - }, - }); - }, - }); - } - } - }, [positions, positionHandler]); // IMPORTANT: Don't add more - - const handleClosePosition = useCallback( - (positionId: string, liquidationCall?: boolean) => { - try { - setShortPositions((prev) => - prev.map((p) => - p.positionId === positionId - ? { - ...p, - status: ShortPositionStatusEnum.STEP_4_BUY_BACK_TOKEN, - updatedAt: Date.now(), - liquidationCall: liquidationCall, - } - : p, - ), - ); - message.success("Position closing initiated"); - } catch (err) { - const errorMsg = err instanceof Error ? err.message : String(err); - message.error(`Failed to close position: ${errorMsg}`); - } - }, - [setShortPositions, message], - ); - - // liquidation notice and POC notice - useEffect(() => { - const lastPrice = minAdaPrice?.price; - if (!lastPrice) { - return; - } - for (const position of positions) { - const liqPrice = position.amount.iLiquidationPrice; - if (Number(lastPrice) >= liqPrice && position.liquidationCall !== true) { - handleClosePosition(position.positionId, true); - message.warning( - `Position #${position.positionId.slice( - 0, - 8, - )} has been liquidated as the market price reached the liquidation price of ${liqPrice} ADA/MIN.`, - ); - } - } - }, [minAdaPrice, positions, handleClosePosition, message]); - - if (positions.length === 0) { - return ( - - ); - } - - const isPositionInProgress = positions.some( - (p) => - [ShortPositionStatusEnum.OPENING_POSITION, ShortPositionStatusEnum.CLOSED_POSITION].includes(p.status) === false, - ); - - // const adhoc = (positionId: string) => { - // setShortPositions((prev) => - // prev.map((p) => - // p.positionId === positionId - // ? { - // ...p, - // status: ShortPositionStatusEnum.STEP_6_WITHDRAW_COLLATERAL, - // hasCallback: 0, - // callbackExtra: undefined, - // } - // : p, - // ), - // ); - // }; - - return ( -
- - {isPositionInProgress && ( - - )} - - - - - - {positions.map((position) => { - let pnlA = 0; - if ( - [ - ShortPositionStatusEnum.STEP_1_SUPPLY_TOKEN, - ShortPositionStatus.STEP_2_BORROW_TOKEN, - ShortPositionStatusEnum.STEP_3_SHORT_TOKEN, - ].includes(position.status) - ) { - pnlA = 0; - } else { - pnlA = calculatePnlA({ - minAdaPrice: minAdaPrice, - shortReceivedL: position.amount.mShortedEstimateAda, - totalRepay: position.amount.mBorrowedL + BigInt(Math.floor(borrowInterest * 1e6)), - supplyEarned: supplyInterest, - mClosedAda: position.amount.mClosedAda ?? 0n, - }); - } - const isPositionComplete = position.status === ShortPositionStatusEnum.OPENING_POSITION; - - return ( - } - onClick={() => handleClosePosition(position.positionId)} - type="text" - > - Close Position - - ) - } - key={position.positionId} - style={{ - border: isPositionComplete ? "2px solid #52c41a" : "1px solid #d9d9d9", - boxShadow: isPositionComplete ? "0 4px 12px rgba(82, 196, 26, 0.15)" : undefined, - }} - title={ - - - Position #{position.positionId.slice(0, 8)} - {getStatusText(position.status)} - - } - > - {/*
- ); -}; diff --git a/apps/web/app/components/short-trading-trade-tab.tsx b/apps/web/app/components/short-trading-trade-tab.tsx deleted file mode 100644 index 8e9b428..0000000 --- a/apps/web/app/components/short-trading-trade-tab.tsx +++ /dev/null @@ -1,280 +0,0 @@ -"use client"; - -import { ArrowRightOutlined, InfoCircleOutlined } from "@ant-design/icons"; -import { DexV2Calculation, OrderV2Direction } from "@minswap/felis-dex-v2"; -import { Asset, Bytes } from "@minswap/felis-ledger-core"; -import { sha3 } from "@minswap/felis-ledger-utils"; -import { LendingMarket } from "@minswap/felis-lending-market"; -import invariant from "@minswap/tiny-invariant"; -import { Alert, App, Button, Card, Col, Divider, Form, InputNumber, Radio, Row, Space, Statistic, Tooltip } from "antd"; -import { useAtomValue, useSetAtom } from "jotai"; -import { useEffect, useState } from "react"; -import { - minAdaPriceAtom, - nitroBalanceAtom, - nitroWalletAtom, - type ShortPositionState, - ShortPositionStatus, - setShortPositionAtom, - shortPositionAtom, -} from "../atoms/walletAtom"; -import { CONFIG } from "../config"; -import { Utils } from "../lib/utils"; - -const MIN_REQUIRED_ADA = 1_200_000_000n; // 1200 ada -const AMOUNT_IN_L = 500_000_000n; // 500 ada -const SUPPLY_AMOUNT_L = 1_000_000_000n; // 1000 ada - -// MARK: Trade Tab -export const ShortTradeTab = () => { - const { message } = App.useApp(); - const nitroWallet = useAtomValue(nitroWalletAtom); - const positions = useAtomValue(shortPositionAtom); - const setPositions = useSetAtom(setShortPositionAtom); - const nitroBalance = useAtomValue(nitroBalanceAtom); - const minAdaPrice = useAtomValue(minAdaPriceAtom); - const [minAmountL, setMinAmountL] = useState(0n); - const [supplyAdaAmountL, _setSupplyAdaAmountL] = useState(SUPPLY_AMOUNT_L); - const [liquidationPrice, setLiquidationPrice] = useState(0); - - useEffect(() => { - if (minAdaPrice) { - try { - const result = DexV2Calculation.calculateSwapExactIn({ - datumReserves: [BigInt(minAdaPrice.datumReserves[0]), BigInt(minAdaPrice.datumReserves[1])], - valueReserves: [BigInt(minAdaPrice.valueReserves[0]), BigInt(minAdaPrice.valueReserves[1])], - tradingFee: { - feeANumerator: BigInt(minAdaPrice.tradingFee.feeANumerator), - feeBNumerator: BigInt(minAdaPrice.tradingFee.feeBNumerator), - }, - amountIn: AMOUNT_IN_L, - direction: OrderV2Direction.A_TO_B, - feeSharingNumerator: minAdaPrice.feeSharingNumerator ? BigInt(minAdaPrice.feeSharingNumerator) : null, - }); - setMinAmountL(result.amountOut); - setLiquidationPrice(Number(minAdaPrice.price) * 1.1); // Liquidation at 10% price increase - } catch (err) { - console.error("Failed to calculate MIN amount:", err); - } - } - }, [minAdaPrice]); - - const handleShort = async () => { - invariant(nitroWallet, "Nitro wallet is not connected"); - const now = Date.now(); - const newShortPositionState: ShortPositionState = { - positionId: sha3(Bytes.fromString(`${nitroWallet.walletInfo.address.bech32}.${now}`).hex), - status: ShortPositionStatus.STEP_1_SUPPLY_TOKEN, - nitroWalletAddress: nitroWallet.walletInfo.address.bech32, - shortAsset: Asset.fromString(LendingMarket.mapMINToken[CONFIG.networkEnv]), // MIN - createdAt: Date.now(), - updatedAt: Date.now(), - amount: { - iTotalSupplyL: supplyAdaAmountL, - iBorrowAmountL: minAmountL, - iLiquidationPrice: liquidationPrice, - mSuppliedL: 0n, - mShortedL: 0n, - mShortedEstimateAda: 0n, - mBorrowedL: 0n, - mTradingPrice: 0, - mClosedPrice: 0, - mClosedAda: 0n, - mRepaidL: 0n, - mWithdrawnL: 0n, - }, - transactions: [], - }; - setPositions([newShortPositionState]); - message.success("Short Position opened successfully!"); - }; - - return ( - - {/* POC Version Warning */} - {nitroWallet?.walletInfo && nitroBalance >= MIN_REQUIRED_ADA ? ( - - ) : null} - - {nitroWallet?.walletInfo && nitroBalance < MIN_REQUIRED_ADA ? ( - - ) : null} - - - - {/* Mode Selection */} - - -
Margin Mode
- - - -
Leverage
- {}} style={{ width: "100%" }} value={0.5}> - - 1.00x - - 0.50x - - - -
Borrow/Repay
- {}} style={{ width: "100%" }} value={"auto"}> - Auto - - Manual - - - - -
Order Type
- - -
- - - - {/* Market Price Info */} - - - - - - - - - - - - - - {/* Amount Inputs */} -
- - - - {}} - placeholder="0.00" - step={0.01} - style={{ width: "100%" }} - value={Number(Number(AMOUNT_IN_L) / 1e6)} - /> - - - - - - - - {}} - placeholder="0.00" - step={0.01} - style={{ width: "100%" }} - value={Number(Utils.formatAmount(minAmountL))} - /> - - - -
- - - - {/* Trading Info */} - - - - - Total Supply Ada - - } - value={Number(Utils.formatAmount(supplyAdaAmountL))} - valueStyle={{ fontSize: 14 }} - /> - - - - - - Total Borrow - - } - value={Number(Utils.formatAmount(minAmountL))} - valueStyle={{ fontSize: 14 }} - /> - - - - - - Liq.Price - - } - value={liquidationPrice} - valueStyle={{ fontSize: 14 }} - /> - - - - - -
- ); -}; diff --git a/apps/web/app/components/short-trading.tsx b/apps/web/app/components/short-trading.tsx deleted file mode 100644 index 22666c7..0000000 --- a/apps/web/app/components/short-trading.tsx +++ /dev/null @@ -1,43 +0,0 @@ -"use client"; - -import { Alert, Badge, Card, Tabs } from "antd"; -import { useAtomValue } from "jotai"; -import { nitroWalletAtom, shortPositionAtom } from "../atoms/walletAtom"; -import { ShortPositionTab } from "./short-trading-position-tab"; -import { ShortTradeTab } from "./short-trading-trade-tab"; - -export const ShortMarginTrading = () => { - const nitroWallet = useAtomValue(nitroWalletAtom); - const positions = useAtomValue(shortPositionAtom); - const hasActivePositions = (positions ?? []).length > 0; - - return ( - } - style={{ marginTop: 16 }} - title="Isolated Margin Short $MIN" - > - {!nitroWallet && ( - - )} - , - }, - ]), - { - key: "position", - label: `Position${hasActivePositions ? ` (${(positions ?? []).length})` : ""}`, - children: , - }, - ]} - /> - - ); -}; diff --git a/apps/web/app/config/index.ts b/apps/web/app/config/index.ts deleted file mode 100644 index e57ce77..0000000 --- a/apps/web/app/config/index.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { NetworkEnvironment } from "@minswap/felis-ledger-core"; - -type Config = { - networkEnv: NetworkEnvironment; -}; - -const networkEnv = - process.env["NETWORK_ENV"] === "mainnet" ? NetworkEnvironment.MAINNET : NetworkEnvironment.TESTNET_PREVIEW; -export const CONFIG: Config = { - networkEnv, -}; diff --git a/apps/web/app/constants/storage.ts b/apps/web/app/constants/storage.ts deleted file mode 100644 index 2702bab..0000000 --- a/apps/web/app/constants/storage.ts +++ /dev/null @@ -1,6 +0,0 @@ -export enum LocalStorageKey { - NITRO_WALLET = "minswap_nitro_wallet", - LONG_POSITIONS = "minswap_long_positions_state", - SHORT_POSITIONS = "minswap_short_positions_state", - CONNECTED_WALLET = "minswap_connected_wallet", -} diff --git a/apps/web/app/favicon.ico b/apps/web/app/favicon.ico deleted file mode 100644 index 718d6fe..0000000 Binary files a/apps/web/app/favicon.ico and /dev/null differ diff --git a/apps/web/app/fonts/GeistMonoVF.woff b/apps/web/app/fonts/GeistMonoVF.woff deleted file mode 100644 index f2ae185..0000000 Binary files a/apps/web/app/fonts/GeistMonoVF.woff and /dev/null differ diff --git a/apps/web/app/fonts/GeistVF.woff b/apps/web/app/fonts/GeistVF.woff deleted file mode 100644 index 1b62daa..0000000 Binary files a/apps/web/app/fonts/GeistVF.woff and /dev/null differ diff --git a/apps/web/app/globals.css b/apps/web/app/globals.css deleted file mode 100644 index 6af7ecb..0000000 --- a/apps/web/app/globals.css +++ /dev/null @@ -1,50 +0,0 @@ -:root { - --background: #ffffff; - --foreground: #171717; -} - -@media (prefers-color-scheme: dark) { - :root { - --background: #0a0a0a; - --foreground: #ededed; - } -} - -html, -body { - max-width: 100vw; - overflow-x: hidden; -} - -body { - color: var(--foreground); - background: var(--background); -} - -* { - box-sizing: border-box; - padding: 0; - margin: 0; -} - -a { - color: inherit; - text-decoration: none; -} - -.imgDark { - display: none; -} - -@media (prefers-color-scheme: dark) { - html { - color-scheme: dark; - } - - .imgLight { - display: none; - } - .imgDark { - display: unset; - } -} diff --git a/apps/web/app/layout.tsx b/apps/web/app/layout.tsx deleted file mode 100644 index 28be03e..0000000 --- a/apps/web/app/layout.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import type { Metadata } from "next"; -import localFont from "next/font/local"; -import "./globals.css"; -import { AntdRegistry } from "@ant-design/nextjs-registry"; -import { App as AntApp, ConfigProvider } from "antd"; - -const geistSans = localFont({ - src: "./fonts/GeistVF.woff", - variable: "--font-geist-sans", -}); -const geistMono = localFont({ - src: "./fonts/GeistMonoVF.woff", - variable: "--font-geist-mono", -}); - -export const metadata: Metadata = { - title: "Create Next App", - description: "Generated by create next app", -}; - -export default function RootLayout({ - children, -}: Readonly<{ - children: React.ReactNode; -}>) { - return ( - - - - - {children} - - - - - ); -} diff --git a/apps/web/app/lib/helpers.ts b/apps/web/app/lib/helpers.ts deleted file mode 100644 index 052066c..0000000 --- a/apps/web/app/lib/helpers.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { type Address, NetworkEnvironment, Utxo } from "@minswap/felis-ledger-core"; -import { NitroWallet } from "@minswap/felis-lending-market"; -import { CONFIG } from "../config"; - -export namespace Helpers { - export const fetchBalance = async (address: string): Promise => { - try { - const value = await NitroWallet.fetchBalance(address, CONFIG.networkEnv); - return value.coin(); - } catch { - return 0n; - } - }; - - export const fetchRawUtxos = async (address: Address): Promise => { - try { - const utxos = await NitroWallet.fetchUtxos(address.bech32, CONFIG.networkEnv); - return utxos.map(Utxo.toHex); - } catch { - return []; - } - }; - export const sleep = (ms: number): Promise => { - return new Promise((resolve) => setTimeout(resolve, ms)); - }; - - export const checkTxConfirmed = async (txHash: string): Promise => { - try { - const network = CONFIG.networkEnv === NetworkEnvironment.MAINNET ? "mainnet" : "preview"; - const blockfrostApiKey = process.env.NEXT_PUBLIC_BLOCKFROST_API_KEY || "previewb6Lj4mtJ7suOIgYjOAVzweDaKONGNSUJ"; - const url = `https://cardano-${network}.blockfrost.io/api/v0/txs/${txHash}`; - const response = await fetch(url, { - method: "GET", - headers: { - project_id: blockfrostApiKey, - }, - }); - // Status code 200 = transaction confirmed - // Status code 404 = transaction not found (not confirmed yet) - if (response.status === 200) { - return true; - } - - if (response.status === 404) { - return false; - } - // Handle other status codes - console.warn(`Unexpected response status ${response.status} when checking tx confirmation`); - return false; - } catch (error) { - console.error("Error checking transaction confirmation:", error); - return false; - } - }; -} diff --git a/apps/web/app/lib/use-nitro-wallet.ts b/apps/web/app/lib/use-nitro-wallet.ts deleted file mode 100644 index 96f51b8..0000000 --- a/apps/web/app/lib/use-nitro-wallet.ts +++ /dev/null @@ -1,252 +0,0 @@ -import { baseWalletFromEntropy } from "@minswap/felis-cip"; -import { Address } from "@minswap/felis-ledger-core"; -import { sha3 } from "@minswap/felis-ledger-utils"; -import { NitroWallet } from "@minswap/felis-lending-market"; -import { useAtom, useSetAtom } from "jotai"; -import { useCallback, useEffect, useState } from "react"; -import { setNitroBalanceAtom, setNitroWalletAtom } from "../atoms/walletAtom"; -import { CONFIG } from "../config"; -import { useWallet } from "./use-wallet"; -import type { WalletInfo } from "./wallet-utils"; - -export interface NitroWalletData { - walletInfo: WalletInfo & { rootAddress: string }; - privateKey: string; -} - -const NITRO_WALLET_STORAGE_KEY = "minswap_nitro_wallet"; - -export const useNitroWallet = () => { - const wallet = useWallet(); - const [walletData, setWalletData] = useState(null); - const [loading, setLoading] = useState(false); - const [error, setError] = useState(null); - const setNitroBalance = useSetAtom(setNitroBalanceAtom); - const [_, setNitroWallet] = useAtom(setNitroWalletAtom); - - /** - * Fetch balance from the blockchain for a given address - */ - const fetchBalance = useCallback(async (address: Address): Promise => { - try { - const value = await NitroWallet.fetchBalance(address.bech32, CONFIG.networkEnv); - return value.coin(); - } catch (err) { - const errorMsg = err instanceof Error ? err.message : String(err); - console.error("Failed to fetch balance:", errorMsg); - return 0n; - } - }, []); - - /** - * Fetch UTXOs from the blockchain for a given address - */ - const fetchUtxos = useCallback(async (address: Address) => { - try { - const utxos = await NitroWallet.fetchUtxos(address.bech32, CONFIG.networkEnv); - return utxos; - } catch (err) { - const errorMsg = err instanceof Error ? err.message : String(err); - console.error("Failed to fetch UTXOs:", errorMsg); - return []; - } - }, []); - - /** - * Load Nitro wallet from localStorage - */ - const loadFromStorage = useCallback(async () => { - console.log("nitro loadFromStorage called", wallet.isConnected, wallet?.walletInfo?.address.bech32); - const rootAddress = wallet?.walletInfo?.address.bech32; - if (!rootAddress) { - return false; - } - try { - const stored = localStorage.getItem(NITRO_WALLET_STORAGE_KEY); - if (stored) { - const parsedData = JSON.parse(stored); - const nitroWallet = { - ...parsedData, - walletInfo: { - ...parsedData.walletInfo, - address: Address.fromBech32(parsedData.walletInfo.address), - }, - }; - if (nitroWallet.walletInfo.rootAddress !== rootAddress) { - return false; - } - - // Fetch real-time balance from blockchain - const balance = await fetchBalance(nitroWallet.walletInfo.address); - nitroWallet.walletInfo.balance = balance; - - setWalletData(nitroWallet); - setError(null); - return true; - } - return false; - } catch (err) { - const errorMsg = err instanceof Error ? err.message : String(err); - setError(`Failed to load Nitro wallet from storage: ${errorMsg}`); - console.error("Storage load error:", err); - return false; - } - }, [wallet?.walletInfo?.address.bech32, fetchBalance, wallet.isConnected]); - - /** - * Create new Nitro wallet using wallet.api.signData() - * Requires connected wallet (wallet.api must exist) - */ - const createNewWallet = useCallback(async () => { - if (!wallet) { - throw new Error("Wallet instance not provided"); - } - - if (!wallet.api) { - throw new Error("Eternl wallet not connected. Please connect your wallet first."); - } - - if (!wallet.walletInfo) { - throw new Error("Wallet info not available"); - } - - try { - // Placeholder signature for testing - const message = `Create Nitro Wallet with address ${wallet.walletInfo.address.bech32}`; - const signedData = await wallet.api.signData( - wallet.walletInfo.address.bech32, - Buffer.from(message).toString("hex"), - ); - const entropy = sha3(signedData.signature); - const nitroWallet = baseWalletFromEntropy(entropy, wallet.walletInfo.networkId); - const nitroWalletData = { - walletInfo: { - address: nitroWallet.address, - rootAddress: wallet.walletInfo.address.bech32, - networkId: wallet.walletInfo.networkId, - }, - privateKey: nitroWallet.paymentKey.toHex(), - }; - setWalletData(nitroWalletData); - return nitroWalletData; - } catch (err) { - const errorMsg = err instanceof Error ? err.message : String(err); - throw new Error(`Failed to create new Nitro wallet: ${errorMsg}`); - } - }, [wallet]); - - /** - * Save Nitro wallet to localStorage - */ - const saveToStorage = useCallback((data: NitroWalletData) => { - try { - localStorage.setItem(NITRO_WALLET_STORAGE_KEY, JSON.stringify(data)); - setWalletData(data); - setError(null); - } catch (err) { - const errorMsg = err instanceof Error ? err.message : String(err); - setError(`Failed to save Nitro wallet: ${errorMsg}`); - console.error("Storage save error:", err); - } - }, []); - - const connect = useCallback(async () => { - setLoading(true); - setError(null); - try { - // Try to load from localStorage first - const loaded = await loadFromStorage(); - if (loaded) { - return; - } - - // If not in storage, create new wallet - const nitroWallet = await createNewWallet(); - saveToStorage(nitroWallet); - } catch (err) { - const errorMsg = err instanceof Error ? err.message : String(err); - setError(errorMsg); - console.error("Wallet connection error:", err); - } finally { - setLoading(false); - } - }, [loadFromStorage, createNewWallet, saveToStorage]); - - /** - * Disconnect and remove from localStorage - */ - const disconnect = useCallback(() => { - try { - localStorage.removeItem(NITRO_WALLET_STORAGE_KEY); - setWalletData(null); - setError(null); - setNitroBalance(0n); - setNitroWallet(null); - } catch (err) { - const errorMsg = err instanceof Error ? err.message : String(err); - setError(`Failed to disconnect: ${errorMsg}`); - console.error("Disconnect error:", err); - } - }, [setNitroBalance, setNitroWallet]); - - const clearError = useCallback(() => { - setError(null); - }, []); - - /** - * Auto-load Nitro wallet from storage when Eternl wallet connects - */ - useEffect(() => { - const autoLoad = async () => { - const rootAddress = wallet?.walletInfo?.address.bech32; - if (!rootAddress) { - return; - } - try { - const stored = localStorage.getItem(NITRO_WALLET_STORAGE_KEY); - if (stored) { - const parsedData = JSON.parse(stored); - const nitroWallet = { - ...parsedData, - walletInfo: { - ...parsedData.walletInfo, - address: Address.fromBech32(parsedData.walletInfo.address), - }, - }; - if (nitroWallet.walletInfo.rootAddress !== rootAddress) { - return; - } - - // Fetch real-time balance from blockchain - const balance = await fetchBalance(nitroWallet.walletInfo.address); - nitroWallet.walletInfo.balance = balance; - - setWalletData(nitroWallet); - setError(null); - } - } catch (err) { - const _errorMsg = err instanceof Error ? err.message : String(err); - console.error("Storage load error:", err); - } - }; - - if (wallet.walletInfo) { - autoLoad(); - } - }, [wallet.walletInfo?.address.bech32, fetchBalance, wallet.walletInfo]); - - return { - walletData, - loading, - error, - connect, - disconnect, - clearError, - saveToStorage, - loadFromStorage, - createNewWallet, - fetchBalance, - fetchUtxos, - isConnected: walletData !== null, - }; -}; diff --git a/apps/web/app/lib/use-position.ts b/apps/web/app/lib/use-position.ts deleted file mode 100644 index 8a31d29..0000000 --- a/apps/web/app/lib/use-position.ts +++ /dev/null @@ -1,576 +0,0 @@ -import { DEXOrderTransaction } from "@minswap/felis-build-tx"; -import { DexV2Calculation, DexVersion, OrderV2Direction, OrderV2StepType } from "@minswap/felis-dex-v2"; -import { PrivateKey, Utxo, Value } from "@minswap/felis-ledger-core"; -import { Result } from "@minswap/felis-ledger-utils"; -import { type LiqwidProvider, NitroWallet } from "@minswap/felis-lending-market"; -import { CoinSelectionAlgorithm, EmulatorProvider } from "@minswap/felis-tx-builder"; -import invariant from "@minswap/tiny-invariant"; -import { App } from "antd"; -import { useAtomValue, useSetAtom } from "jotai"; -import { useCallback, useRef } from "react"; -import { ADA, Asset } from "../../../../packages/ledger-core/dist/asset"; -import { LendingMarket } from "../../../../packages/minswap-lending-market/dist/lending-market"; -import { - type LongPositionState, - type LongPositionStatus, - type NitroWalletData, - nitroWalletAtom, - type ShortPositionState, - ShortPositionStatus, - setLongPositionAtom, - setShortPositionAtom, - type WalletData, - walletAtom, -} from "../atoms/walletAtom"; -import { CONFIG } from "../config"; -import { Helpers } from "./helpers"; - -const CALLBACK_SLEEP_DURATION_MS = 10000; // 10 seconds - -export enum ExtraStatus { - EXTRA_STEP_BUY_MORE = "extra_step_buy_more", - EXTRA_STEP_SELL_ALL = "extra_step_sell_all", - EXTRA_SHORT_STEP_1 = "extra_short_step_1", - EXTRA_SHORT_STEP_2 = "extra_short_step_2", - EXTRA_SHORT_STEP_3 = "extra_short_step_3", - EXTRA_SHORT_STEP_4 = "extra_short_step_4", - EXTRA_SHORT_STEP_5 = "extra_short_step_5", - EXTRA_SHORT_STEP_6 = "extra_short_step_6", -} - -type StepBuyMoreExtra = { - extraStatus: ExtraStatus.EXTRA_STEP_BUY_MORE; - buyMoreAmount: bigint; - nextStatus: LongPositionStatus.OPENING_POSITION; - logStatus: LongPositionStatus.STEP_BUY_MORE_LONG_ASSET; -}; -type StepSellAllExtra = { - extraStatus: ExtraStatus.EXTRA_STEP_SELL_ALL; - nextStatus: LongPositionStatus.CLOSED_POSITION; - logStatus: LongPositionStatus.STEP_SELL_ALL_LONG_ASSET; -}; -type ShortStep1Extra = { - extraStatus: ExtraStatus.EXTRA_SHORT_STEP_1; - marketId: LendingMarket.MarketId; - amount: bigint; -}; -type ShortStep2Extra = { - extraStatus: ExtraStatus.EXTRA_SHORT_STEP_2; - borrowAmountL: number; - collateralMode: LendingMarket.CollateralMarginType; - borrowMarketId: LiqwidProvider.BorrowMarket; -}; -type ShortStep3Extra = { - extraStatus: ExtraStatus.EXTRA_SHORT_STEP_3; - priceInAdaResponse: LendingMarket.PriceInAdaResponse; - amountIn: bigint; -}; -type ShortStep4Extra = { - extraStatus: ExtraStatus.EXTRA_SHORT_STEP_4; - priceInAdaResponse: LendingMarket.PriceInAdaResponse; - expectedReceive: bigint; -}; -type ShortStep5Extra = { - extraStatus: ExtraStatus.EXTRA_SHORT_STEP_5; -}; -type ShortStep6Extra = { - extraStatus: ExtraStatus.EXTRA_SHORT_STEP_6; - supplyMarketId: LendingMarket.MarketId; - qToken: Asset; -}; -type InnerHandleFn = (input: { - position: LongPositionState | ShortPositionState; - wallet: WalletData; - nitroWallet: NitroWalletData; - extra?: - | StepBuyMoreExtra - | StepSellAllExtra - | ShortStep1Extra - | ShortStep2Extra - | ShortStep3Extra - | ShortStep4Extra - | ShortStep5Extra - | ShortStep6Extra; -}) => Promise; - -type HandlePositionInput = { - position: LongPositionState | ShortPositionState; - positionType: "long" | "short"; - errorMessage: string; - successMessage: string; - innerFn: InnerHandleFn; -}; - -export const innerHandleCallback = async ({ - position, - nextStatus, - extraBalance, -}: { - position: LongPositionState | ShortPositionState; - nextStatus: string; - extraBalance?: { address: string; requiredValue: Value }; -}): Promise => { - invariant(position.hasCallback, "type-safe"); - await Helpers.sleep(CALLBACK_SLEEP_DURATION_MS); - const txHash = position.transactions[position.transactions.length - 1]?.txHash; - invariant(txHash, "type-safe"); - let ok = await Helpers.checkTxConfirmed(txHash); - if (extraBalance && ok) { - const balance = await NitroWallet.fetchBalance(extraBalance.address, CONFIG.networkEnv); - for (const [asset, amount] of extraBalance.requiredValue.flatten()) { - const assetAmount = balance.get(asset); - ok = ok && assetAmount >= amount; - } - } - console.log({ txConfirmed: ok, txHash }); - if (ok) { - return { - ...position, - // biome-ignore lint/suspicious/noExplicitAny: lazy - status: nextStatus as any, - hasCallback: undefined, - callbackExtra: undefined, - }; - } else { - // continue callback - return { ...position, hasCallback: position.hasCallback + 1 }; - } -}; - -// supply ada, receive qAda -export const shortHandleStep1: InnerHandleFn = async (options) => { - const position = options.position as ShortPositionState; - const { nitroWallet, extra } = options; - invariant(extra && extra.extraStatus === ExtraStatus.EXTRA_SHORT_STEP_1, "Invalid extra data for short step 1"); - if (position.hasCallback) { - return innerHandleCallback({ - position, - nextStatus: ShortPositionStatus.STEP_2_BORROW_TOKEN, - }); - } else { - const utxos = await Helpers.fetchRawUtxos(nitroWallet.walletInfo.address); - const txHash = await LendingMarket.supplyTokens({ - nitroWallet: { - address: nitroWallet.walletInfo.address, - privateKey: nitroWallet.privateKey, - utxos, - }, - networkEnv: CONFIG.networkEnv, - amount: extra.amount, - marketId: extra.marketId, - }); - console.log("shortHandleStep1 tx hash:", txHash); - const newPosition: ShortPositionState = { - ...position, - updatedAt: Date.now(), - amount: { - ...position.amount, - mSuppliedL: extra.amount, - }, - transactions: [...position.transactions, { txHash, step: ShortPositionStatus.STEP_1_SUPPLY_TOKEN }], - hasCallback: 1, - }; - return newPosition; - } -}; - -// borrow MIN, supply qADA -export const shortHandleStep2: InnerHandleFn = async (options) => { - const position = options.position as ShortPositionState; - const { nitroWallet, extra } = options; - invariant(extra && extra.extraStatus === ExtraStatus.EXTRA_SHORT_STEP_2, "Invalid extra data for short step 2"); - if (position.hasCallback) { - return innerHandleCallback({ - position, - nextStatus: ShortPositionStatus.STEP_3_SHORT_TOKEN, - }); - } else { - const utxos = await NitroWallet.fetchUtxos(nitroWallet.walletInfo.address.bech32, CONFIG.networkEnv); - const balance = Utxo.sumValue(utxos); - const { collaterals, buildTxCollaterals } = await LendingMarket.getCollaterals({ - networkEnv: CONFIG.networkEnv, - address: nitroWallet.walletInfo.address, - balance, - collateralMode: extra.collateralMode, - }); - const { txHash } = await LendingMarket.borrowTokens({ - nitroWallet: { - address: nitroWallet.walletInfo.address, - privateKey: nitroWallet.privateKey, - utxos: utxos.map(Utxo.toHex), - }, - networkEnv: CONFIG.networkEnv, - borrowAmountL: extra.borrowAmountL, - borrowMarketId: extra.borrowMarketId, - currentDebt: 0, - collaterals, - buildTxCollaterals, - }); - console.log("shortHandleStep2 tx hash:", txHash); - const newPosition: ShortPositionState = { - ...position, - updatedAt: Date.now(), - amount: { - ...position.amount, - mBorrowedL: BigInt(extra.borrowAmountL), - }, - transactions: [...position.transactions, { txHash, step: ShortPositionStatus.STEP_2_BORROW_TOKEN }], - hasCallback: 1, - }; - return newPosition; - } -}; - -// short $MIN, receive Ada -export const shortHandleStep3: InnerHandleFn = async (options) => { - const position = options.position as ShortPositionState; - const { nitroWallet, extra } = options; - invariant(extra && extra.extraStatus === ExtraStatus.EXTRA_SHORT_STEP_3, "Invalid extra data for short step 3"); - if (position.hasCallback) { - invariant(position.callbackExtra, "type-safe"); - const callbackData = JSON.parse(position.callbackExtra) as { - address: string; - asset: string; - requiredAmount: string; - }; - const extraBalance: { address: string; requiredValue: Value } = { - address: callbackData.address, - requiredValue: new Value().add(Asset.fromString(callbackData.asset), BigInt(callbackData.requiredAmount)), - }; - return innerHandleCallback({ - position, - nextStatus: ShortPositionStatus.OPENING_POSITION, - extraBalance, - }); - } else { - const utxos = await NitroWallet.fetchUtxos(nitroWallet.walletInfo.address.bech32, CONFIG.networkEnv); - const { priceInAdaResponse, amountIn } = extra; - const result = DexV2Calculation.calculateSwapExactIn({ - datumReserves: [BigInt(priceInAdaResponse.datumReserves[0]), BigInt(priceInAdaResponse.datumReserves[1])], - valueReserves: [BigInt(priceInAdaResponse.valueReserves[0]), BigInt(priceInAdaResponse.valueReserves[1])], - tradingFee: { - feeANumerator: BigInt(priceInAdaResponse.tradingFee.feeANumerator), - feeBNumerator: BigInt(priceInAdaResponse.tradingFee.feeBNumerator), - }, - amountIn, - direction: OrderV2Direction.B_TO_A, - feeSharingNumerator: priceInAdaResponse.feeSharingNumerator - ? BigInt(priceInAdaResponse.feeSharingNumerator) - : null, - }); - const minReceive = (result.amountOut * 99n) / 100n; // slippage 1% - const txb = DEXOrderTransaction.createBulkOrdersTx({ - networkEnv: CONFIG.networkEnv, - sender: nitroWallet.walletInfo.address, - orderOptions: [ - { - lpAsset: Asset.fromString(priceInAdaResponse.lpAsset), - version: DexVersion.DEX_V2, - type: OrderV2StepType.SWAP_EXACT_IN, - assetIn: Asset.fromString(priceInAdaResponse.assetB), - amountIn: amountIn, - minimumAmountOut: 1n, - direction: OrderV2Direction.B_TO_A, - killOnFailed: false, - isLimitOrder: false, - }, - ], - }); - const txComplete = await txb.completeUnsafe({ - changeAddress: nitroWallet.walletInfo.address, - walletUtxos: utxos, - coinSelectionAlgorithm: CoinSelectionAlgorithm.MINSWAP, - provider: new EmulatorProvider(CONFIG.networkEnv), - }); - const signedTx = txComplete.signWithPrivateKey(PrivateKey.fromHex(nitroWallet.privateKey)).complete(); - NitroWallet.quickBatching(signedTx, CONFIG.networkEnv); - const txHash = await NitroWallet.submitTx(signedTx, CONFIG.networkEnv); - console.log("shortHandleStep3 tx hash:", txHash); - const newPosition: ShortPositionState = { - ...position, - updatedAt: Date.now(), - amount: { - ...position.amount, - mShortedL: amountIn, - mShortedEstimateAda: result.amountOut, - mTradingPrice: Number(priceInAdaResponse.price), - }, - transactions: [...position.transactions, { txHash, step: ShortPositionStatus.STEP_3_SHORT_TOKEN }], - hasCallback: 1, - callbackExtra: JSON.stringify({ - address: nitroWallet.walletInfo.address.bech32, - asset: ADA.toString(), - requiredAmount: minReceive.toString(), - }), - }; - return newPosition; - } -}; - -// buy back $MIN, used Ada -export const shortHandleStep4: InnerHandleFn = async (options) => { - const position = options.position as ShortPositionState; - const { nitroWallet, extra } = options; - invariant(extra && extra.extraStatus === ExtraStatus.EXTRA_SHORT_STEP_4, "Invalid extra data for short step 4"); - if (position.hasCallback) { - invariant(position.callbackExtra, "type-safe"); - const callbackData = JSON.parse(position.callbackExtra) as { - address: string; - asset: string; - requiredAmount: string; - }; - const extraBalance: { address: string; requiredValue: Value } = { - address: callbackData.address, - requiredValue: new Value().add(Asset.fromString(callbackData.asset), BigInt(callbackData.requiredAmount)), - }; - return innerHandleCallback({ - position, - nextStatus: ShortPositionStatus.STEP_5_REPAY_ASSET, - extraBalance, - }); - } else { - const utxos = await NitroWallet.fetchUtxos(nitroWallet.walletInfo.address.bech32, CONFIG.networkEnv); - const { priceInAdaResponse, expectedReceive } = extra; - const result = DexV2Calculation.calculateSwapExactOut({ - datumReserves: [BigInt(priceInAdaResponse.datumReserves[0]), BigInt(priceInAdaResponse.datumReserves[1])], - valueReserves: [BigInt(priceInAdaResponse.valueReserves[0]), BigInt(priceInAdaResponse.valueReserves[1])], - tradingFee: { - feeANumerator: BigInt(priceInAdaResponse.tradingFee.feeANumerator), - feeBNumerator: BigInt(priceInAdaResponse.tradingFee.feeBNumerator), - }, - expectedReceive, - direction: OrderV2Direction.A_TO_B, - feeSharingNumerator: priceInAdaResponse.feeSharingNumerator - ? BigInt(priceInAdaResponse.feeSharingNumerator) - : null, - }); - const necessaryAmountIn = Result.unwrap(result).necessaryAmountIn; - const txb = DEXOrderTransaction.createBulkOrdersTx({ - networkEnv: CONFIG.networkEnv, - sender: nitroWallet.walletInfo.address, - orderOptions: [ - { - lpAsset: Asset.fromString(priceInAdaResponse.lpAsset), - version: DexVersion.DEX_V2, - type: OrderV2StepType.SWAP_EXACT_OUT, - assetIn: Asset.fromString(priceInAdaResponse.assetA), - maximumAmountIn: necessaryAmountIn, - expectedReceived: expectedReceive, - direction: OrderV2Direction.A_TO_B, - killOnFailed: false, - }, - ], - }); - const txComplete = await txb.completeUnsafe({ - changeAddress: nitroWallet.walletInfo.address, - walletUtxos: utxos, - coinSelectionAlgorithm: CoinSelectionAlgorithm.MINSWAP, - provider: new EmulatorProvider(CONFIG.networkEnv), - }); - const signedTx = txComplete.signWithPrivateKey(PrivateKey.fromHex(nitroWallet.privateKey)).complete(); - NitroWallet.quickBatching(signedTx, CONFIG.networkEnv); - const txHash = await NitroWallet.submitTx(signedTx, CONFIG.networkEnv); - console.log("shortHandleStep4 tx hash:", txHash); - const newPosition: ShortPositionState = { - ...position, - updatedAt: Date.now(), - amount: { - ...position.amount, - mClosedAda: necessaryAmountIn, - mClosedPrice: Number(priceInAdaResponse.price), - }, - transactions: [...position.transactions, { txHash, step: ShortPositionStatus.STEP_4_BUY_BACK_TOKEN }], - hasCallback: 1, - callbackExtra: JSON.stringify({ - address: nitroWallet.walletInfo.address.bech32, - asset: priceInAdaResponse.assetB, - requiredAmount: expectedReceive.toString(), - }), - }; - return newPosition; - } -}; - -// repay MIN, receive qAda back -export const shortHandleStep5: InnerHandleFn = async (options) => { - const position = options.position as ShortPositionState; - const { nitroWallet } = options; - if (position.hasCallback) { - return innerHandleCallback({ - position, - nextStatus: ShortPositionStatus.STEP_6_WITHDRAW_COLLATERAL, - }); - } else { - const utxos = await NitroWallet.fetchRawUtxos(nitroWallet.walletInfo.address.bech32, CONFIG.networkEnv); - let loanTxHash = ""; - for (const { txHash, step } of position.transactions) { - if (step === ShortPositionStatus.STEP_2_BORROW_TOKEN) { - loanTxHash = txHash; - } - } - console.warn("loanTxHash", loanTxHash); - const { repayAmountL, txHash } = await LendingMarket.repayAllDebt({ - nitroWallet: { - address: nitroWallet.walletInfo.address, - privateKey: nitroWallet.privateKey, - utxos, - }, - networkEnv: CONFIG.networkEnv, - loanTxHash, - }); - console.log("shortHandleStep5 tx hash:", txHash); - const newPosition: ShortPositionState = { - ...position, - updatedAt: Date.now(), - amount: { - ...position.amount, - mRepaidL: repayAmountL, - }, - transactions: [...position.transactions, { txHash, step: ShortPositionStatus.STEP_5_REPAY_ASSET }], - hasCallback: 1, - }; - return newPosition; - } -}; - -// withdraw qADA collateral, receive Ada back -export const shortHandleStep6: InnerHandleFn = async (options) => { - const position = options.position as ShortPositionState; - const { nitroWallet, extra } = options; - invariant(extra && extra.extraStatus === ExtraStatus.EXTRA_SHORT_STEP_6, "Invalid extra data for short step 6"); - if (position.hasCallback) { - return innerHandleCallback({ - position, - nextStatus: ShortPositionStatus.CLOSED_POSITION, - }); - } else { - const utxos = await NitroWallet.fetchUtxos(nitroWallet.walletInfo.address.bech32, CONFIG.networkEnv); - const balance = Utxo.sumValue(utxos); - const { supplyMarketId, qToken } = extra; - const qTokenAmountA = Number(balance.get(qToken)) / 1e6; - const { txHash, withdrawAllAmountL } = await LendingMarket.withdrawAllSupply({ - nitroWallet: { - address: nitroWallet.walletInfo.address, - privateKey: nitroWallet.privateKey, - utxos: utxos.map(Utxo.toHex), - }, - networkEnv: CONFIG.networkEnv, - marketId: supplyMarketId, - supplyQTokenAmountA: qTokenAmountA, - }); - console.log("shortHandleStep6 tx hash:", txHash); - const newPosition: ShortPositionState = { - ...position, - updatedAt: Date.now(), - amount: { - ...position.amount, - mWithdrawnL: withdrawAllAmountL, - }, - transactions: [...position.transactions, { txHash, step: ShortPositionStatus.STEP_6_WITHDRAW_COLLATERAL }], - hasCallback: 1, - }; - return newPosition; - } -}; - -export const usePosition = () => { - const { message } = App.useApp(); - const wallet = useAtomValue(walletAtom); - const nitroWallet = useAtomValue(nitroWalletAtom); - const setLongPositions = useSetAtom(setLongPositionAtom); - const setShortPositions = useSetAtom(setShortPositionAtom); - - // Track positions that are currently being processed to prevent duplicate calls - const processingPositions = useRef>(new Set()); - - const handlePosition = useCallback( - async (input: HandlePositionInput) => { - const { positionType, position, errorMessage, successMessage, innerFn } = input; - if (!nitroWallet || !wallet) return; - // Check if this position is already being processed - if (processingPositions.current.has(position.positionId)) { - return; - } - // Mark position as being processed - processingPositions.current.add(position.positionId); - try { - let retries = 0; - const maxRetries = 3; - let lastError: Error | null = null; - - while (retries <= maxRetries) { - try { - let hasCallback: number | undefined; - if (positionType === "long") { - const newPosition = (await innerFn({ position, wallet, nitroWallet })) as LongPositionState; - hasCallback = newPosition.hasCallback; - setLongPositions((prev) => prev.map((p) => (p.positionId === position.positionId ? newPosition : p))); - } else { - const newPosition = (await innerFn({ position, wallet, nitroWallet })) as ShortPositionState; - hasCallback = newPosition.hasCallback; - setShortPositions((prev) => prev.map((p) => (p.positionId === position.positionId ? newPosition : p))); - } - if (!hasCallback) { - message.success(`${successMessage} ${position.positionId.slice(0, 8)}`); - } - break; // Exit loop on success - } catch (error) { - lastError = error instanceof Error ? error : new Error(String(error)); - if (retries < maxRetries) { - retries++; - console.error("backoff error", error); - console.log( - `Retry ${retries}/${maxRetries} for position ${position.positionId.slice(0, 8)} after 30s...`, - ); - await Helpers.sleep(30000); // Sleep 30 seconds before retry - } else { - const txHash = position.transactions[position.transactions.length - 1]?.txHash; - if (txHash) { - const txConfirmed = await Helpers.checkTxConfirmed(txHash); - if (!txConfirmed) { - const prevStep = position.transactions[position.transactions.length - 2]?.step; - const lastStep = position.transactions[position.transactions.length - 1]?.step; - if (prevStep && lastStep && prevStep === lastStep) { - const transactions = [...position.transactions]; - transactions.pop(); // remove last failed tx - const newPosition = { ...position, hasCallback: 1, transactions }; - if (positionType === "long") { - setLongPositions((prev) => - prev.map((p) => - p.positionId === position.positionId ? (newPosition as LongPositionState) : p, - ), - ); - } else { - setShortPositions((prev) => - prev.map((p) => - p.positionId === position.positionId ? (newPosition as ShortPositionState) : p, - ), - ); - } - } - } - } - console.error("max retries reached for position:", position.positionId, lastError); - setTimeout(() => { - window.location.reload(); - }, 5000); - // throw lastError; - } - } - } - } catch (error) { - const errorMsg = error instanceof Error ? error.message : String(error); - message.error(`${errorMessage}: ${errorMsg}`); - console.error("handle position error: ", error); - } finally { - // Remove from processing set when done (success or error) - processingPositions.current.delete(position.positionId); - } - }, - [nitroWallet, wallet, setLongPositions, setShortPositions, message], - ); - - return { - handlePosition, - }; -}; diff --git a/apps/web/app/lib/use-wallet.ts b/apps/web/app/lib/use-wallet.ts deleted file mode 100644 index a74c4ab..0000000 --- a/apps/web/app/lib/use-wallet.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { useAtom, useSetAtom } from "jotai"; -import { useCallback, useState } from "react"; -import { setConnectedWalletAtom, setRootBalanceAtom, setWalletAtom } from "../atoms/walletAtom"; -import { type Cip30Api, getAddressInfo, getWalletApi, type WalletInfo } from "./wallet-utils"; - -export const useWallet = () => { - const [_, setWallet] = useAtom(setWalletAtom); - const [__, setConnectedWallet] = useAtom(setConnectedWalletAtom); - const [walletInfo, setWalletInfo] = useState(null); - const [api, setApi] = useState(null); - const [loading, setLoading] = useState(false); - const [error, setError] = useState(null); - const setRootBalance = useSetAtom(setRootBalanceAtom); - - const connect = useCallback(async () => { - setLoading(true); - setError(null); - try { - const eternlApi = await getWalletApi("eternl"); - if (!eternlApi) { - setError("Eternl wallet not found or not enabled."); - return; - } - - const info = await getAddressInfo(eternlApi); - if (info) { - setWalletInfo(info); - setApi(eternlApi); - setWallet({ walletInfo: info, api: eternlApi }); - setConnectedWallet(true); - } else { - setError("Failed to get wallet information."); - } - } catch (err) { - const errorMsg = err instanceof Error ? err.message : String(err); - setError(`Error connecting wallet: ${errorMsg}`); - console.error("Wallet connection error:", err); - } finally { - setLoading(false); - } - }, [setWallet, setConnectedWallet]); - - const disconnect = useCallback(() => { - setWalletInfo(null); - setApi(null); - setError(null); - setWallet(null); - setConnectedWallet(false); - setRootBalance(0n); - }, [setConnectedWallet, setWallet, setRootBalance]); - - const clearError = useCallback(() => { - setError(null); - }, []); - - return { - walletInfo, - api, - setWalletInfo, - loading, - setLoading, - error, - connect, - disconnect, - clearError, - isConnected: walletInfo !== null && api !== null, - }; -}; diff --git a/apps/web/app/lib/utils.ts b/apps/web/app/lib/utils.ts deleted file mode 100644 index 43afff1..0000000 --- a/apps/web/app/lib/utils.ts +++ /dev/null @@ -1,13 +0,0 @@ -export namespace Utils { - export const shortenAddress = (address: string): string => { - return `${address.slice(0, 8)}...${address.slice(-8)}`; - }; - export const formatAmount = (amount: bigint, decimals?: number): string => { - const _decimals = decimals ?? 6; - return (Number(amount) / 10 ** _decimals).toFixed(2); - }; - export const formatBalance = (balance: bigint | undefined): string => { - if (!balance) return "0.00"; - return (Number(balance) / 1_000_000).toFixed(2); - }; -} diff --git a/apps/web/app/lib/wallet-utils.ts b/apps/web/app/lib/wallet-utils.ts deleted file mode 100644 index 507b990..0000000 --- a/apps/web/app/lib/wallet-utils.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { Address, Value } from "@minswap/felis-ledger-core"; -import { RustModule } from "@minswap/felis-ledger-utils"; - -/** - * CIP-30 Wallet utilities for Cardano - * These utilities handle wallet connection and data retrieval - * Address parsing is delegated to the backend/wallet - */ - -export interface WalletInfo { - address: Address; - balance?: bigint; - networkId: number; -} - -export interface Cip30Window extends Window { - cardano?: { - [walletName: string]: { - enable(): Promise; - isEnabled(): Promise; - apiVersion: string; - name: string; - icon: string; - }; - }; -} - -export interface Cip30Api { - getNetworkId(): Promise; - getUtxos(): Promise; - getBalance(): Promise; - getUsedAddresses(): Promise; - getUnusedAddresses(): Promise; - getChangeAddress(): Promise; - getRewardAddresses(): Promise; - signTx(tx: string, partialSign: boolean): Promise; - signData(addr: string, payload: string): Promise<{ signature: string; key: string }>; - submitTx(tx: string): Promise; - getCollaterals?(params: { amount: string }): Promise; - onAccountChange?(callback: () => void): void; - onNetworkChange?(callback: (networkId: number) => void): void; -} - -export const getWalletApi = async (walletName: string): Promise => { - const window_ = window as Cip30Window; - if (!window_.cardano?.[walletName]) { - return null; - } - try { - const walletExtension = window_.cardano[walletName]; - const api = await walletExtension.enable(); - return api; - } catch (error) { - const errorMsg = error instanceof Error ? error.message : String(error); - console.error(`Failed to enable ${walletName}: ${errorMsg}`, error); - return null; - } -}; - -export const getAddressInfo = async (api: Cip30Api): Promise => { - try { - await RustModule.load(); - const addressRaw = await api.getChangeAddress(); - const balanceRaw = await api.getBalance(); - const networkId = await api.getNetworkId(); - const balanceValue = Value.fromHex(balanceRaw); - return { - address: Address.fromHex(addressRaw), - balance: balanceValue.coin(), - networkId, - }; - } catch (error) { - const errorMsg = error instanceof Error ? error.message : String(error); - console.error("Failed to get address info:", errorMsg, error); - return null; - } -}; - -export const connectToEternlWallet = async (): Promise => { - const eternlApi = await getWalletApi("eternl"); - if (!eternlApi) { - console.log("Eternl wallet not found or not enabled."); - return null; - } - return getAddressInfo(eternlApi); -}; diff --git a/apps/web/app/page.tsx b/apps/web/app/page.tsx deleted file mode 100644 index eaa7463..0000000 --- a/apps/web/app/page.tsx +++ /dev/null @@ -1,92 +0,0 @@ -"use client"; - -import { LendingMarket } from "@minswap/felis-lending-market"; -import { App, Button, Layout, Space } from "antd"; -import { useAtomValue, useSetAtom } from "jotai"; -import { useEffect, useState } from "react"; -import { connectedWalletAtom, setMinAdaPriceAtom, walletAtom } from "./atoms/walletAtom"; -import { DepositWithdraw } from "./components/deposit-withdraw"; -import { EternlConnector } from "./components/eternl-connector"; -import { MarginTrading } from "./components/margin-trading"; -import { NitroWalletConnector } from "./components/nitro-wallet-connector"; -import { ShortMarginTrading } from "./components/short-trading"; -import { CONFIG } from "./config"; -import { useWallet } from "./lib/use-wallet"; - -export default function Home() { - const { message } = App.useApp(); - const walletConnected = useAtomValue(connectedWalletAtom); - const wallet = useAtomValue(walletAtom); - const walletHook = useWallet(); - const setMinAdaPrice = useSetAtom(setMinAdaPriceAtom); - const [isClearingHistory, setIsClearingHistory] = useState(false); - const [positionType, setPositionType] = useState<"short" | "long">("short"); - - const clearHistory = async () => { - setIsClearingHistory(true); - try { - // Clear all localStorage values - localStorage.clear(); - message.success("Local storage cleared successfully"); - // Force page reload after a short delay - setTimeout(() => { - window.location.reload(); - }, 500); - } catch (_err) { - message.error("Failed to clear local storage"); - setIsClearingHistory(false); - } - }; - - useEffect(() => { - // Auto-connect if wallet was previously connected and we don't have wallet data yet - if (walletConnected && !wallet) { - walletHook.connect(); - } - }, [walletConnected, wallet, walletHook]); - - // polling fetch $MIN price 10 seconds - useEffect(() => { - const fetchMinPrice = async () => { - try { - const priceData = await LendingMarket.fetchAdaMinPrice(CONFIG.networkEnv); - setMinAdaPrice(priceData); - // message.info(`MIN price fetched: ${priceData.price} ADA per MIN`); - } catch (_err) { - message.error("Failed to fetch MIN price"); - } finally { - } - }; - fetchMinPrice(); - const interval = setInterval(fetchMinPrice, 10000); // 10 seconds - return () => clearInterval(interval); - }, [setMinAdaPrice, message]); - - return ( - - - -
- -
-
- - - - -
-
- - - {positionType === "long" ? : } -
-
-
- ); -} diff --git a/apps/web/eslint.config.js b/apps/web/eslint.config.js deleted file mode 100644 index e8759ff..0000000 --- a/apps/web/eslint.config.js +++ /dev/null @@ -1,4 +0,0 @@ -import { nextJsConfig } from "@repo/eslint-config/next-js"; - -/** @type {import("eslint").Linter.Config} */ -export default nextJsConfig; diff --git a/apps/web/next.config.js b/apps/web/next.config.js deleted file mode 100644 index 5d7066d..0000000 --- a/apps/web/next.config.js +++ /dev/null @@ -1,37 +0,0 @@ -/** @type {import('next').NextConfig} */ -const nextConfig = { - async rewrites() { - return [ - { - source: "/api/liqwid/:path*", - destination: "https://v2.api.preview.liqwid.dev/:path*", - }, - ]; - }, - turbopack: { - resolveAlias: { - // Alias node WASM modules to web versions for browser compatibility - "@minswap/cardano-serialization-lib-nodejs": "@minswap/cardano-serialization-lib-browser", - "@emurgo/cardano-serialization-lib-nodejs": "@emurgo/cardano-serialization-lib-browser", - "@repo/uplc-node": "@repo/uplc-web", - }, - }, - webpack(config) { - // Alias node WASM modules to web versions for browser compatibility - config.resolve.alias["@minswap/cardano-serialization-lib-nodejs"] = "@minswap/cardano-serialization-lib-browser"; - config.resolve.alias["@emurgo/cardano-serialization-lib-nodejs"] = "@emurgo/cardano-serialization-lib-browser"; - config.resolve.alias["@repo/uplc-node"] = "@repo/uplc-web"; - - // Enable WebAssembly support - config.experiments = { - ...(config.experiments ?? {}), - asyncWebAssembly: true, - layers: true, - syncWebAssembly: true, - }; - - return config; - }, -}; - -export default nextConfig; diff --git a/apps/web/package.json b/apps/web/package.json deleted file mode 100644 index 4043ced..0000000 --- a/apps/web/package.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "name": "web", - "version": "0.1.0", - "type": "module", - "private": true, - "scripts": { - "dev": "next dev --turbopack --port 3002", - "build": "next build", - "start": "next start", - "lint": "next lint --max-warnings 0", - "check-types": "tsc --noEmit" - }, - "dependencies": { - "@ant-design/icons": "5.x", - "@ant-design/nextjs-registry": "^1.1.0", - "@minswap/tiny-invariant": "^1.2.0", - "@minswap/felis-ledger-core": "workspace:*", - "@minswap/felis-ledger-utils": "workspace:*", - "@minswap/felis-tx-builder": "workspace:*", - "@minswap/felis-cip": "workspace:*", - "@repo/ui": "workspace:*", - "@minswap/felis-lending-market": "workspace:*", - "@minswap/felis-dex-v2": "workspace:*", - "@minswap/felis-build-tx": "workspace:*", - "antd": "^5.27.6", - "next": "^16.0.10", - "react": "^19.2.3", - "react-dom": "^19.2.3", - "jotai": "^2.10.2" - }, - "devDependencies": { - "@repo/eslint-config": "workspace:*", - "@repo/typescript-config": "workspace:*", - "@types/node": "^22.15.3", - "@types/react": "^19.2.7", - "@types/react-dom": "^19.2.3", - "eslint": "^9.31.0", - "typescript": "5.8.2" - } -} diff --git a/apps/web/public/file-text.svg b/apps/web/public/file-text.svg deleted file mode 100644 index 9cfb3c9..0000000 --- a/apps/web/public/file-text.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/apps/web/public/globe.svg b/apps/web/public/globe.svg deleted file mode 100644 index 4230a3d..0000000 --- a/apps/web/public/globe.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/apps/web/public/next.svg b/apps/web/public/next.svg deleted file mode 100644 index 5174b28..0000000 --- a/apps/web/public/next.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/apps/web/public/turborepo-dark.svg b/apps/web/public/turborepo-dark.svg deleted file mode 100644 index dae38fe..0000000 --- a/apps/web/public/turborepo-dark.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/apps/web/public/turborepo-light.svg b/apps/web/public/turborepo-light.svg deleted file mode 100644 index ddea915..0000000 --- a/apps/web/public/turborepo-light.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/apps/web/public/vercel.svg b/apps/web/public/vercel.svg deleted file mode 100644 index 0164ddc..0000000 --- a/apps/web/public/vercel.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/apps/web/public/window.svg b/apps/web/public/window.svg deleted file mode 100644 index bbc7800..0000000 --- a/apps/web/public/window.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/apps/web/tsconfig.json b/apps/web/tsconfig.json deleted file mode 100644 index c2fa4ee..0000000 --- a/apps/web/tsconfig.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "@repo/typescript-config/nextjs.json", - "compilerOptions": { - "plugins": [ - { - "name": "next" - } - ] - }, - "include": ["**/*.ts", "**/*.tsx", "next-env.d.ts", "next.config.js", ".next/types/**/*.ts"], - "exclude": ["node_modules"] -} diff --git a/docker-compose.yml b/docker-compose.yml index c609bc9..4c9bbc1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,15 +8,13 @@ x-base-backend: &base-backend depends_on: postgres: condition: service_healthy - redis: - condition: service_healthy environment: DATABASE_URL: postgres://postgres:JBNGlQ9wNFLlYWc2mG@postgres:5432/margin - REDIS_URL: redis://default:7obaQyYSDDLDk3ECYA@redis:6379 API_PORT: 9999 API_HOST: 0.0.0.0 NETWORK: testnet-preview CARDANOSCAN_API_KEY: ${CARDANOSCAN_API_KEY} + KUPO_HOST: http://dev-3.tail2feb3.ts.net:1442 healthcheck: test: ["CMD-SHELL", "curl -f http://localhost:9999/health || exit 1"] interval: 10s @@ -32,34 +30,6 @@ services: - "9999:9999" command: ["pnpm", "--filter=long-short-backend", "start"] - # web: - # build: - # context: . - # dockerfile: Dockerfile - # network_mode: host - # environment: - # NODE_ENV: production - # NEXT_PUBLIC_NETWORK_ENV: TESTNET_PREVIEW - # PORT: 3002 - # expose: - # - "3002" - # restart: unless-stopped - - redis: - image: redis:8 - container_name: margin-redis - restart: always - command: --requirepass 7obaQyYSDDLDk3ECYA - ports: - - "6380:6379" - volumes: - - redis-data:/data - healthcheck: - test: ["CMD", "redis-cli", "-a", "7obaQyYSDDLDk3ECYA", "--raw", "incr", "ping"] - interval: 5s - timeout: 3s - retries: 5 - postgres: image: postgres:18 container_name: margin-postgres @@ -80,4 +50,3 @@ services: volumes: postgres-data: {} - redis-data: {} diff --git a/package.json b/package.json index 601e344..2222367 100644 --- a/package.json +++ b/package.json @@ -8,8 +8,6 @@ "scripts": { "build": "turbo run build", "dev": "turbo run dev", - "lint": "turbo run lint", - "format": "prettier --write \"**/*.{ts,tsx,md}\"", "check-types": "turbo run check-types", "format-and-lint": "biome check .", "format-and-lint:fix": "biome check . --write --unsafe", @@ -26,5 +24,16 @@ "packageManager": "pnpm@9.0.0", "engines": { "node": ">=22" + }, + "pnpm": { + "overrides": { + "flatted@<=3.4.1": "3.4.2", + "glob@>=10.2.0 <10.5.0": "10.5.0", + "minimatch@<3.1.4": "3.1.5", + "minimatch@>=9.0.0 <9.0.7": "9.0.9", + "rollup@>=4.0.0 <4.59.0": "4.60.0", + "socket.io-parser@>=4.0.0 <4.2.6": "4.2.6", + "lodash@<4.17.23": "4.17.23" + } } } diff --git a/packages/cip/package.json b/packages/cip/package.json index f7c16ef..d44ad3c 100644 --- a/packages/cip/package.json +++ b/packages/cip/package.json @@ -27,13 +27,11 @@ "check-circular-imports": "dpdm --no-warning --no-tree src" }, "devDependencies": { - "@repo/eslint-config": "workspace:*", "@repo/typescript-config": "workspace:*", + "@types/json-bigint": "^1.0.4", "@types/node": "^22.15.3", - "eslint": "^9.31.0", + "dpdm": "^3.15.1", "typescript": "5.8.2", - "@types/json-bigint": "^1.0.4", - "dpdm": "^3.14.0", "vitest": "^3.2.4" }, "dependencies": { diff --git a/packages/eslint-config/README.md b/packages/eslint-config/README.md deleted file mode 100644 index 8b42d90..0000000 --- a/packages/eslint-config/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# `@turbo/eslint-config` - -Collection of internal eslint configurations. diff --git a/packages/eslint-config/base.js b/packages/eslint-config/base.js deleted file mode 100644 index f9aea48..0000000 --- a/packages/eslint-config/base.js +++ /dev/null @@ -1,32 +0,0 @@ -import js from "@eslint/js"; -import eslintConfigPrettier from "eslint-config-prettier"; -import turboPlugin from "eslint-plugin-turbo"; -import tseslint from "typescript-eslint"; -import onlyWarn from "eslint-plugin-only-warn"; - -/** - * A shared ESLint configuration for the repository. - * - * @type {import("eslint").Linter.Config[]} - * */ -export default [ - js.configs.recommended, - eslintConfigPrettier, - ...tseslint.configs.recommended, - { - plugins: { - turbo: turboPlugin, - }, - rules: { - "turbo/no-undeclared-env-vars": "warn", - }, - }, - { - plugins: { - onlyWarn, - }, - }, - { - ignores: ["dist/**"], - }, -]; diff --git a/packages/eslint-config/next.js b/packages/eslint-config/next.js deleted file mode 100644 index 6bf01a7..0000000 --- a/packages/eslint-config/next.js +++ /dev/null @@ -1,49 +0,0 @@ -import js from "@eslint/js"; -import eslintConfigPrettier from "eslint-config-prettier"; -import tseslint from "typescript-eslint"; -import pluginReactHooks from "eslint-plugin-react-hooks"; -import pluginReact from "eslint-plugin-react"; -import globals from "globals"; -import pluginNext from "@next/eslint-plugin-next"; -import { config as baseConfig } from "./base.js"; - -/** - * A custom ESLint configuration for libraries that use Next.js. - * - * @type {import("eslint").Linter.Config[]} - * */ -export const nextJsConfig = [ - ...baseConfig, - js.configs.recommended, - eslintConfigPrettier, - ...tseslint.configs.recommended, - { - ...pluginReact.configs.flat.recommended, - languageOptions: { - ...pluginReact.configs.flat.recommended.languageOptions, - globals: { - ...globals.serviceworker, - }, - }, - }, - { - plugins: { - "@next/next": pluginNext, - }, - rules: { - ...pluginNext.configs.recommended.rules, - ...pluginNext.configs["core-web-vitals"].rules, - }, - }, - { - plugins: { - "react-hooks": pluginReactHooks, - }, - settings: { react: { version: "detect" } }, - rules: { - ...pluginReactHooks.configs.recommended.rules, - // React scope no longer necessary with new JSX transform. - "react/react-in-jsx-scope": "off", - }, - }, -]; diff --git a/packages/eslint-config/package.json b/packages/eslint-config/package.json deleted file mode 100644 index e64f5cb..0000000 --- a/packages/eslint-config/package.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "@repo/eslint-config", - "version": "0.0.0", - "type": "module", - "private": true, - "exports": { - "./base": "./base.js", - "./next-js": "./next.js", - "./react-internal": "./react-internal.js" - }, - "devDependencies": { - "@eslint/js": "^9.31.0", - "@next/eslint-plugin-next": "^15.4.2", - "eslint": "^9.31.0", - "eslint-config-prettier": "^10.1.1", - "eslint-plugin-only-warn": "^1.1.0", - "eslint-plugin-react": "^7.37.5", - "eslint-plugin-react-hooks": "^5.2.0", - "eslint-plugin-turbo": "^2.5.0", - "globals": "^16.3.0", - "typescript": "^5.8.2", - "typescript-eslint": "^8.37.0" - } -} diff --git a/packages/eslint-config/react-internal.js b/packages/eslint-config/react-internal.js deleted file mode 100644 index daeccba..0000000 --- a/packages/eslint-config/react-internal.js +++ /dev/null @@ -1,39 +0,0 @@ -import js from "@eslint/js"; -import eslintConfigPrettier from "eslint-config-prettier"; -import tseslint from "typescript-eslint"; -import pluginReactHooks from "eslint-plugin-react-hooks"; -import pluginReact from "eslint-plugin-react"; -import globals from "globals"; -import { config as baseConfig } from "./base.js"; - -/** - * A custom ESLint configuration for libraries that use React. - * - * @type {import("eslint").Linter.Config[]} */ -export const config = [ - ...baseConfig, - js.configs.recommended, - eslintConfigPrettier, - ...tseslint.configs.recommended, - pluginReact.configs.flat.recommended, - { - languageOptions: { - ...pluginReact.configs.flat.recommended.languageOptions, - globals: { - ...globals.serviceworker, - ...globals.browser, - }, - }, - }, - { - plugins: { - "react-hooks": pluginReactHooks, - }, - settings: { react: { version: "detect" } }, - rules: { - ...pluginReactHooks.configs.recommended.rules, - // React scope no longer necessary with new JSX transform. - "react/react-in-jsx-scope": "off", - }, - }, -]; diff --git a/packages/felis/package.json b/packages/felis/package.json index 532149f..2baacbf 100644 --- a/packages/felis/package.json +++ b/packages/felis/package.json @@ -11,7 +11,9 @@ "bugs": { "url": "https://github.com/minswap/felis/issues" }, - "files": ["dist"], + "files": [ + "dist" + ], "exports": { ".": "./dist/index.js" }, @@ -24,29 +26,27 @@ "check-circular-imports": "dpdm --no-warning --no-tree src" }, "devDependencies": { - "@repo/eslint-config": "workspace:*", "@repo/typescript-config": "workspace:*", "@types/node": "^22.15.3", - "eslint": "^9.31.0", - "typescript": "5.8.2", - "dpdm": "^3.14.0" + "dpdm": "^3.15.1", + "typescript": "5.8.2" }, "dependencies": { - "@minswap/felis-ledger-utils": "workspace:*", - "@minswap/felis-ledger-core": "workspace:*", + "@minswap/felis-build-tx": "workspace:*", "@minswap/felis-cip": "workspace:*", - "@minswap/felis-tx-builder": "workspace:*", - "@minswap/felis-provider": "workspace:*", "@minswap/felis-dex-v1": "workspace:*", "@minswap/felis-dex-v2": "workspace:*", - "@minswap/felis-build-tx": "workspace:*", - "@minswap/felis-stableswap": "workspace:*", + "@minswap/felis-ledger-core": "workspace:*", + "@minswap/felis-ledger-utils": "workspace:*", "@minswap/felis-lending-market": "workspace:*", + "@minswap/felis-provider": "workspace:*", "@minswap/felis-splash": "workspace:*", + "@minswap/felis-stableswap": "workspace:*", "@minswap/felis-sundaeswap-v1": "workspace:*", "@minswap/felis-sundaeswap-v3": "workspace:*", + "@minswap/felis-syncer": "workspace:*", + "@minswap/felis-tx-builder": "workspace:*", "@minswap/felis-wingriders-v1": "workspace:*", - "@minswap/felis-wingriders-v2": "workspace:*", - "@minswap/felis-syncer": "workspace:*" + "@minswap/felis-wingriders-v2": "workspace:*" } } diff --git a/packages/ledger-core/package.json b/packages/ledger-core/package.json index bfec973..2f524a1 100644 --- a/packages/ledger-core/package.json +++ b/packages/ledger-core/package.json @@ -28,22 +28,22 @@ }, "devDependencies": { "@repo/typescript-config": "workspace:*", + "@types/json-bigint": "^1.0.4", "@types/node": "^22.15.3", + "dpdm": "^3.15.1", + "fast-check": "^3.23.2", "typescript": "5.8.2", - "@types/json-bigint": "^1.0.4", - "dpdm": "^3.14.0", - "vitest": "^3.2.4", - "fast-check": "^3.23.2" + "vitest": "^3.2.4" }, "dependencies": { + "@cardano-ogmios/schema": "^6.11.0", "@minswap/felis-ledger-utils": "workspace:*", - "bignumber.js": "^9.1.2", - "@stricahq/cbors": "^1.0.3", "@minswap/tiny-invariant": "^1.2.0", - "remeda": "^2.19.2", - "json-bigint": "^1.0.0", - "@cardano-ogmios/schema": "^6.11.0", + "@stricahq/cbors": "^1.0.3", + "@stricahq/typhonjs": "2.0.0", + "bignumber.js": "^9.1.2", "cbor": "^10.0.3", - "@stricahq/typhonjs": "2.0.0" + "json-bigint": "^1.0.0", + "remeda": "^2.19.2" } } diff --git a/packages/ledger-utils/package.json b/packages/ledger-utils/package.json index c06da3a..9740ff9 100644 --- a/packages/ledger-utils/package.json +++ b/packages/ledger-utils/package.json @@ -27,25 +27,24 @@ "check-circular-imports": "dpdm --no-warning --no-tree src" }, "devDependencies": { - "@repo/eslint-config": "workspace:*", "@repo/typescript-config": "workspace:*", "@types/json-bigint": "^1.0.4", "@types/node": "^22.15.3", + "dpdm": "^3.15.1", + "fast-check": "^3.23.2", "typescript": "5.8.2", - "dpdm": "^3.14.0", - "vitest": "^3.2.4", - "fast-check": "^3.23.2" + "vitest": "^3.2.4" }, "dependencies": { "@emurgo/cardano-serialization-lib-browser": "13.2.1", "@emurgo/cardano-serialization-lib-nodejs": "13.2.1", "@minswap/cardano-serialization-lib-browser": "11.1.0-minswap.33", "@minswap/cardano-serialization-lib-nodejs": "11.1.0-minswap.33", - "@minswap/tiny-invariant": "^1.2.0", "@minswap/felis-uplc-node": "workspace:*", "@minswap/felis-uplc-web": "workspace:*", + "@minswap/tiny-invariant": "^1.2.0", "blakejs": "^1.2.1", - "sha3": "^2.1.4", - "json-bigint": "^1.0.0" + "json-bigint": "^1.0.0", + "sha3": "^2.1.4" } } diff --git a/packages/minswap-build-tx/package.json b/packages/minswap-build-tx/package.json index 80e28c7..e50e2b5 100644 --- a/packages/minswap-build-tx/package.json +++ b/packages/minswap-build-tx/package.json @@ -27,20 +27,18 @@ "check-circular-imports": "dpdm --no-warning --no-tree src" }, "devDependencies": { - "@repo/eslint-config": "workspace:*", "@repo/typescript-config": "workspace:*", + "@types/json-bigint": "^1.0.4", "@types/node": "^22.15.3", - "eslint": "^9.31.0", + "dpdm": "^3.15.1", "typescript": "5.8.2", - "@types/json-bigint": "^1.0.4", - "dpdm": "^3.14.0", "vitest": "^3.2.4" }, "dependencies": { + "@minswap/felis-dex-v2": "workspace:*", "@minswap/felis-ledger-core": "workspace:*", "@minswap/felis-ledger-utils": "workspace:*", "@minswap/felis-tx-builder": "workspace:*", - "@minswap/felis-dex-v2": "workspace:*", "@minswap/tiny-invariant": "^1.2.0", "bignumber.js": "^9.1.2" } diff --git a/packages/minswap-dex-v1/package.json b/packages/minswap-dex-v1/package.json index 5ac1d50..ba06505 100644 --- a/packages/minswap-dex-v1/package.json +++ b/packages/minswap-dex-v1/package.json @@ -10,7 +10,9 @@ "bugs": { "url": "https://github.com/minswap/felis/issues" }, - "files": ["dist"], + "files": [ + "dist" + ], "exports": { ".": "./dist/index.js" }, @@ -23,13 +25,11 @@ "check-circular-imports": "dpdm --no-warning --no-tree src" }, "devDependencies": { - "@repo/eslint-config": "workspace:*", "@repo/typescript-config": "workspace:*", - "@types/node": "^22.15.3", - "eslint": "^9.31.0", - "typescript": "5.8.2", "@types/json-bigint": "^1.0.4", - "dpdm": "^3.14.0" + "@types/node": "^22.15.3", + "dpdm": "^3.15.1", + "typescript": "5.8.2" }, "dependencies": { "@minswap/felis-ledger-core": "workspace:*", diff --git a/packages/minswap-dex-v2/package.json b/packages/minswap-dex-v2/package.json index 2ddd22f..0aeff2c 100644 --- a/packages/minswap-dex-v2/package.json +++ b/packages/minswap-dex-v2/package.json @@ -27,13 +27,11 @@ "check-circular-imports": "dpdm --no-warning --no-tree src" }, "devDependencies": { - "@repo/eslint-config": "workspace:*", "@repo/typescript-config": "workspace:*", + "@types/json-bigint": "^1.0.4", "@types/node": "^22.15.3", - "eslint": "^9.31.0", + "dpdm": "^3.15.1", "typescript": "5.8.2", - "@types/json-bigint": "^1.0.4", - "dpdm": "^3.14.0", "vitest": "^3.2.4" }, "dependencies": { diff --git a/packages/minswap-lending-market/package.json b/packages/minswap-lending-market/package.json index 89fb814..4463a50 100644 --- a/packages/minswap-lending-market/package.json +++ b/packages/minswap-lending-market/package.json @@ -25,25 +25,23 @@ "check-circular-imports": "dpdm --no-warning --no-tree src" }, "devDependencies": { - "@repo/eslint-config": "workspace:*", "@repo/typescript-config": "workspace:*", - "@types/node": "^22.15.3", - "eslint": "^9.31.0", - "typescript": "5.8.2", "@types/json-bigint": "^1.0.4", - "dpdm": "^3.14.0" + "@types/node": "^22.15.3", + "dpdm": "^3.15.1", + "typescript": "5.8.2" }, "dependencies": { + "@minswap/felis-build-tx": "workspace:*", + "@minswap/felis-cip": "workspace:*", + "@minswap/felis-dex-v2": "workspace:*", "@minswap/felis-ledger-core": "workspace:*", "@minswap/felis-ledger-utils": "workspace:*", "@minswap/felis-tx-builder": "workspace:*", - "@minswap/felis-build-tx": "workspace:*", - "@minswap/felis-dex-v2": "workspace:*", - "@minswap/felis-cip": "workspace:*", - "remeda": "^2.19.2", "@minswap/tiny-invariant": "^1.2.0", "bignumber.js": "^9.1.2", + "cbor": "^10.0.3", "json-bigint": "^1.0.0", - "cbor": "^10.0.3" + "remeda": "^2.19.2" } } diff --git a/packages/minswap-stableswap/package.json b/packages/minswap-stableswap/package.json index 6cf4306..f9e6d01 100644 --- a/packages/minswap-stableswap/package.json +++ b/packages/minswap-stableswap/package.json @@ -10,7 +10,9 @@ "bugs": { "url": "https://github.com/minswap/felis/issues" }, - "files": ["dist"], + "files": [ + "dist" + ], "exports": { ".": "./dist/index.js" }, @@ -25,23 +27,21 @@ "check-circular-imports": "dpdm --no-warning --no-tree src" }, "devDependencies": { - "@repo/eslint-config": "workspace:*", "@repo/typescript-config": "workspace:*", "@types/json-bigint": "^1.0.4", "@types/node": "^22.15.3", - "dpdm": "^3.14.0", - "eslint": "^9.31.0", + "dpdm": "^3.15.1", "fast-check": "^3.23.2", "typescript": "5.8.2", "vitest": "^3.2.4" }, "dependencies": { - "@minswap/tiny-invariant": "^1.2.0", - "@minswap/felis-ledger-core": "workspace:*", - "@minswap/felis-ledger-utils": "workspace:*", "@minswap/felis-build-tx": "workspace:*", "@minswap/felis-dex-v2": "workspace:*", + "@minswap/felis-ledger-core": "workspace:*", + "@minswap/felis-ledger-utils": "workspace:*", "@minswap/felis-tx-builder": "workspace:*", + "@minswap/tiny-invariant": "^1.2.0", "bignumber.js": "^9.1.2", "json-bigint": "^1.0.0", "remeda": "^2.19.2" diff --git a/packages/provider/package.json b/packages/provider/package.json index 9db2571..a5c990e 100644 --- a/packages/provider/package.json +++ b/packages/provider/package.json @@ -10,7 +10,9 @@ "bugs": { "url": "https://github.com/minswap/felis/issues" }, - "files": ["dist"], + "files": [ + "dist" + ], "exports": { ".": "./dist/index.js" }, @@ -23,19 +25,17 @@ "check-circular-imports": "dpdm --no-warning --no-tree src" }, "devDependencies": { - "@repo/eslint-config": "workspace:*", + "@minswap/felis-dex-v2": "workspace:*", "@repo/typescript-config": "workspace:*", "@types/json-bigint": "^1.0.4", "@types/node": "^22.15.3", - "dpdm": "^3.14.0", - "eslint": "^9.31.0", - "typescript": "5.8.2", - "@minswap/felis-dex-v2": "workspace:*" + "dpdm": "^3.15.1", + "typescript": "5.8.2" }, "dependencies": { - "@minswap/tiny-invariant": "^1.2.0", "@minswap/felis-ledger-core": "workspace:*", "@minswap/felis-ledger-utils": "workspace:*", + "@minswap/tiny-invariant": "^1.2.0", "remeda": "^2.19.2" } } diff --git a/packages/splash/package.json b/packages/splash/package.json index 7827981..9a550fb 100644 --- a/packages/splash/package.json +++ b/packages/splash/package.json @@ -10,7 +10,9 @@ "bugs": { "url": "https://github.com/minswap/felis/issues" }, - "files": ["dist"], + "files": [ + "dist" + ], "exports": { ".": "./dist/index.js" }, @@ -23,13 +25,11 @@ "check-circular-imports": "dpdm --no-warning --no-tree src" }, "devDependencies": { - "@repo/eslint-config": "workspace:*", "@repo/typescript-config": "workspace:*", - "@types/node": "^22.15.3", - "eslint": "^9.31.0", - "typescript": "5.8.2", "@types/json-bigint": "^1.0.4", - "dpdm": "^3.14.0" + "@types/node": "^22.15.3", + "dpdm": "^3.15.1", + "typescript": "5.8.2" }, "dependencies": { "@minswap/felis-ledger-core": "workspace:*", diff --git a/packages/sundaeswap-v1/package.json b/packages/sundaeswap-v1/package.json index 06565f5..477b486 100644 --- a/packages/sundaeswap-v1/package.json +++ b/packages/sundaeswap-v1/package.json @@ -10,7 +10,9 @@ "bugs": { "url": "https://github.com/minswap/felis/issues" }, - "files": ["dist"], + "files": [ + "dist" + ], "exports": { ".": "./dist/index.js" }, @@ -25,13 +27,11 @@ "check-circular-imports": "dpdm --no-warning --no-tree src" }, "devDependencies": { - "@repo/eslint-config": "workspace:*", "@repo/typescript-config": "workspace:*", + "@types/json-bigint": "^1.0.4", "@types/node": "^22.15.3", - "eslint": "^9.31.0", + "dpdm": "^3.15.1", "typescript": "5.8.2", - "@types/json-bigint": "^1.0.4", - "dpdm": "^3.14.0", "vitest": "^3.2.4" }, "dependencies": { diff --git a/packages/sundaeswap-v3/package.json b/packages/sundaeswap-v3/package.json index 2668b43..ab07408 100644 --- a/packages/sundaeswap-v3/package.json +++ b/packages/sundaeswap-v3/package.json @@ -10,7 +10,9 @@ "bugs": { "url": "https://github.com/minswap/felis/issues" }, - "files": ["dist"], + "files": [ + "dist" + ], "exports": { ".": "./dist/index.js" }, @@ -23,13 +25,11 @@ "check-circular-imports": "dpdm --no-warning --no-tree src" }, "devDependencies": { - "@repo/eslint-config": "workspace:*", "@repo/typescript-config": "workspace:*", - "@types/node": "^22.15.3", - "eslint": "^9.31.0", - "typescript": "5.8.2", "@types/json-bigint": "^1.0.4", - "dpdm": "^3.14.0" + "@types/node": "^22.15.3", + "dpdm": "^3.15.1", + "typescript": "5.8.2" }, "dependencies": { "@minswap/felis-ledger-core": "workspace:*", diff --git a/packages/syncer/package.json b/packages/syncer/package.json index 2be198d..a8a23df 100644 --- a/packages/syncer/package.json +++ b/packages/syncer/package.json @@ -10,7 +10,9 @@ "bugs": { "url": "https://github.com/minswap/felis/issues" }, - "files": ["dist"], + "files": [ + "dist" + ], "exports": { ".": "./dist/index.js" }, @@ -25,27 +27,25 @@ "check-circular-imports": "dpdm --no-warning --no-tree src" }, "devDependencies": { - "@repo/eslint-config": "workspace:*", "@repo/typescript-config": "workspace:*", + "@types/json-bigint": "^1.0.4", "@types/node": "^22.15.3", - "eslint": "^9.31.0", + "dpdm": "^3.15.1", "typescript": "5.8.2", - "@types/json-bigint": "^1.0.4", - "dpdm": "^3.14.0", "vitest": "^3.2.4" }, "dependencies": { - "@minswap/tiny-invariant": "^1.2.0", - "@minswap/felis-ledger-core": "workspace:*", - "@minswap/felis-ledger-utils": "workspace:*", "@minswap/felis-dex-v1": "workspace:*", "@minswap/felis-dex-v2": "workspace:*", + "@minswap/felis-ledger-core": "workspace:*", + "@minswap/felis-ledger-utils": "workspace:*", + "@minswap/felis-splash": "workspace:*", "@minswap/felis-stableswap": "workspace:*", "@minswap/felis-sundaeswap-v1": "workspace:*", "@minswap/felis-sundaeswap-v3": "workspace:*", + "@minswap/felis-tx-builder": "workspace:*", "@minswap/felis-wingriders-v1": "workspace:*", "@minswap/felis-wingriders-v2": "workspace:*", - "@minswap/felis-splash": "workspace:*", - "@minswap/felis-tx-builder": "workspace:*" + "@minswap/tiny-invariant": "^1.2.0" } } diff --git a/packages/tx-builder/package.json b/packages/tx-builder/package.json index 77391f4..497c0f3 100644 --- a/packages/tx-builder/package.json +++ b/packages/tx-builder/package.json @@ -25,21 +25,19 @@ "check-circular-imports": "dpdm --no-warning --no-tree src" }, "devDependencies": { - "@repo/eslint-config": "workspace:*", "@repo/typescript-config": "workspace:*", - "@types/node": "^22.15.3", - "eslint": "^9.31.0", - "typescript": "5.8.2", "@types/json-bigint": "^1.0.4", - "dpdm": "^3.14.0" + "@types/node": "^22.15.3", + "dpdm": "^3.15.1", + "typescript": "5.8.2" }, "dependencies": { + "@minswap/felis-cip": "workspace:*", "@minswap/felis-ledger-core": "workspace:*", "@minswap/felis-ledger-utils": "workspace:*", - "@minswap/felis-cip": "workspace:*", - "remeda": "^2.19.2", "@minswap/tiny-invariant": "^1.2.0", "bignumber.js": "^9.1.2", - "json-bigint": "^1.0.0" + "json-bigint": "^1.0.0", + "remeda": "^2.19.2" } } diff --git a/packages/ui/eslint.config.mjs b/packages/ui/eslint.config.mjs deleted file mode 100644 index 19170f8..0000000 --- a/packages/ui/eslint.config.mjs +++ /dev/null @@ -1,4 +0,0 @@ -import { config } from "@repo/eslint-config/react-internal"; - -/** @type {import("eslint").Linter.Config} */ -export default config; diff --git a/packages/ui/package.json b/packages/ui/package.json deleted file mode 100644 index 3bb9d11..0000000 --- a/packages/ui/package.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "@repo/ui", - "version": "0.0.0", - "private": true, - "exports": { - "./*": "./src/*.tsx" - }, - "scripts": { - "lint": "eslint . --max-warnings 0", - "generate:component": "turbo gen react-component", - "check-types": "tsc --noEmit" - }, - "devDependencies": { - "@repo/eslint-config": "workspace:*", - "@repo/typescript-config": "workspace:*", - "@types/node": "^22.15.3", - "@types/react": "19.2.7", - "@types/react-dom": "19.2.3", - "eslint": "^9.31.0", - "typescript": "5.8.3" - }, - "dependencies": { - "react": "^19.2.3", - "react-dom": "^19.2.3" - } -} \ No newline at end of file diff --git a/packages/ui/src/button.tsx b/packages/ui/src/button.tsx deleted file mode 100644 index 78e5420..0000000 --- a/packages/ui/src/button.tsx +++ /dev/null @@ -1,20 +0,0 @@ -"use client"; - -import { ReactNode } from "react"; - -interface ButtonProps { - children: ReactNode; - className?: string; - appName: string; -} - -export const Button = ({ children, className, appName }: ButtonProps) => { - return ( - - ); -}; diff --git a/packages/ui/src/card.tsx b/packages/ui/src/card.tsx deleted file mode 100644 index 7b98893..0000000 --- a/packages/ui/src/card.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { type JSX } from "react"; - -export function Card({ - className, - title, - children, - href, -}: { - className?: string; - title: string; - children: React.ReactNode; - href: string; -}): JSX.Element { - return ( - -

- {title} -> -

-

{children}

-
- ); -} diff --git a/packages/ui/src/code.tsx b/packages/ui/src/code.tsx deleted file mode 100644 index f7cbd22..0000000 --- a/packages/ui/src/code.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { type JSX } from "react"; - -export function Code({ - children, - className, -}: { - children: React.ReactNode; - className?: string; -}): JSX.Element { - return {children}; -} diff --git a/packages/ui/tsconfig.json b/packages/ui/tsconfig.json deleted file mode 100644 index ca86687..0000000 --- a/packages/ui/tsconfig.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "@repo/typescript-config/react-library.json", - "compilerOptions": { - "outDir": "dist" - }, - "include": ["src"], - "exclude": ["node_modules", "dist"] -} diff --git a/packages/wingriders-v1/package.json b/packages/wingriders-v1/package.json index 7937ece..a524256 100644 --- a/packages/wingriders-v1/package.json +++ b/packages/wingriders-v1/package.json @@ -10,7 +10,9 @@ "bugs": { "url": "https://github.com/minswap/felis/issues" }, - "files": ["dist"], + "files": [ + "dist" + ], "exports": { ".": "./dist/index.js" }, @@ -23,13 +25,11 @@ "check-circular-imports": "dpdm --no-warning --no-tree src" }, "devDependencies": { - "@repo/eslint-config": "workspace:*", "@repo/typescript-config": "workspace:*", - "@types/node": "^22.15.3", - "eslint": "^9.31.0", - "typescript": "5.8.2", "@types/json-bigint": "^1.0.4", - "dpdm": "^3.14.0" + "@types/node": "^22.15.3", + "dpdm": "^3.15.1", + "typescript": "5.8.2" }, "dependencies": { "@minswap/felis-ledger-core": "workspace:*", diff --git a/packages/wingriders-v2/package.json b/packages/wingriders-v2/package.json index d8176ef..408966c 100644 --- a/packages/wingriders-v2/package.json +++ b/packages/wingriders-v2/package.json @@ -10,7 +10,9 @@ "bugs": { "url": "https://github.com/minswap/felis/issues" }, - "files": ["dist"], + "files": [ + "dist" + ], "exports": { ".": "./dist/index.js" }, @@ -23,13 +25,11 @@ "check-circular-imports": "dpdm --no-warning --no-tree src" }, "devDependencies": { - "@repo/eslint-config": "workspace:*", "@repo/typescript-config": "workspace:*", - "@types/node": "^22.15.3", - "eslint": "^9.31.0", - "typescript": "5.8.2", "@types/json-bigint": "^1.0.4", - "dpdm": "^3.14.0" + "@types/node": "^22.15.3", + "dpdm": "^3.15.1", + "typescript": "5.8.2" }, "dependencies": { "@minswap/felis-ledger-core": "workspace:*", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ffdf90c..eeb63c1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,6 +4,15 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +overrides: + flatted@<=3.4.1: 3.4.2 + glob@>=10.2.0 <10.5.0: 10.5.0 + minimatch@<3.1.4: 3.1.5 + minimatch@>=9.0.0 <9.0.7: 9.0.9 + rollup@>=4.0.0 <4.59.0: 4.60.0 + socket.io-parser@>=4.0.0 <4.2.6: 4.2.6 + lodash@<4.17.23: 4.17.23 + importers: .: @@ -54,9 +63,6 @@ importers: specifier: ^4.8.3 version: 4.8.3 devDependencies: - '@repo/eslint-config': - specifier: workspace:* - version: link:../../packages/eslint-config '@repo/typescript-config': specifier: workspace:* version: link:../../packages/typescript-config @@ -67,11 +73,8 @@ importers: specifier: ^22.15.3 version: 22.15.3 dpdm: - specifier: ^3.14.0 - version: 3.14.0 - eslint: - specifier: ^9.31.0 - version: 9.31.0(jiti@2.6.1) + specifier: ^3.15.1 + version: 3.15.1 typescript: specifier: 5.8.2 version: 5.8.2 @@ -87,6 +90,12 @@ importers: '@fastify/cors': specifier: ^10.0.2 version: 10.1.0 + '@fastify/helmet': + specifier: ^13.0.2 + version: 13.0.2 + '@fastify/rate-limit': + specifier: ^10.3.0 + version: 10.3.0 '@minswap/felis-build-tx': specifier: workspace:* version: link:../../packages/minswap-build-tx @@ -142,8 +151,8 @@ importers: specifier: ^1.0.0 version: 1.0.0 kysely: - specifier: ^0.28.11 - version: 0.28.11 + specifier: ^0.28.14 + version: 0.28.14 p-timeout: specifier: ^7.0.1 version: 7.0.1 @@ -160,9 +169,6 @@ importers: '@cardano-ogmios/schema': specifier: ^6.11.0 version: 6.14.0 - '@repo/eslint-config': - specifier: workspace:* - version: link:../../packages/eslint-config '@repo/typescript-config': specifier: workspace:* version: link:../../packages/typescript-config @@ -179,17 +185,14 @@ importers: specifier: ^8.16.0 version: 8.16.0 dpdm: - specifier: ^3.14.0 - version: 3.14.0 - eslint: - specifier: ^9.31.0 - version: 9.31.0(jiti@2.6.1) + specifier: ^3.15.1 + version: 3.15.1 kysely-codegen: specifier: ^0.19.0 - version: 0.19.0(kysely@0.28.11)(pg@8.18.0)(typescript@5.8.2) + version: 0.19.0(kysely@0.28.14)(pg@8.18.0)(typescript@5.8.2) kysely-ctl: specifier: ^0.19.0 - version: 0.19.0(kysely@0.28.11)(typescript@5.8.2) + version: 0.19.0(kysely@0.28.14)(typescript@5.8.2) tsx: specifier: ^4.19.4 version: 4.20.3 @@ -200,79 +203,6 @@ importers: specifier: ^3.2.4 version: 3.2.4(@types/node@22.15.3)(jiti@2.6.1)(tsx@4.20.3) - apps/web: - dependencies: - '@ant-design/icons': - specifier: 5.x - version: 5.6.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@ant-design/nextjs-registry': - specifier: ^1.1.0 - version: 1.1.0(@ant-design/cssinjs@1.24.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(antd@5.27.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(next@16.0.10(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@minswap/felis-build-tx': - specifier: workspace:* - version: link:../../packages/minswap-build-tx - '@minswap/felis-cip': - specifier: workspace:* - version: link:../../packages/cip - '@minswap/felis-dex-v2': - specifier: workspace:* - version: link:../../packages/minswap-dex-v2 - '@minswap/felis-ledger-core': - specifier: workspace:* - version: link:../../packages/ledger-core - '@minswap/felis-ledger-utils': - specifier: workspace:* - version: link:../../packages/ledger-utils - '@minswap/felis-lending-market': - specifier: workspace:* - version: link:../../packages/minswap-lending-market - '@minswap/felis-tx-builder': - specifier: workspace:* - version: link:../../packages/tx-builder - '@minswap/tiny-invariant': - specifier: ^1.2.0 - version: 1.2.0 - '@repo/ui': - specifier: workspace:* - version: link:../../packages/ui - antd: - specifier: ^5.27.6 - version: 5.27.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - jotai: - specifier: ^2.10.2 - version: 2.15.1(@types/react@19.2.7)(react@19.2.3) - next: - specifier: ^16.0.10 - version: 16.0.10(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: - specifier: ^19.2.3 - version: 19.2.3 - react-dom: - specifier: ^19.2.3 - version: 19.2.3(react@19.2.3) - devDependencies: - '@repo/eslint-config': - specifier: workspace:* - version: link:../../packages/eslint-config - '@repo/typescript-config': - specifier: workspace:* - version: link:../../packages/typescript-config - '@types/node': - specifier: ^22.15.3 - version: 22.15.3 - '@types/react': - specifier: ^19.2.7 - version: 19.2.7 - '@types/react-dom': - specifier: ^19.2.3 - version: 19.2.3(@types/react@19.2.7) - eslint: - specifier: ^9.31.0 - version: 9.31.0(jiti@2.6.1) - typescript: - specifier: 5.8.2 - version: 5.8.2 - packages/cip: dependencies: '@minswap/felis-ledger-core': @@ -288,9 +218,6 @@ importers: specifier: ^3.1.0 version: 3.1.0 devDependencies: - '@repo/eslint-config': - specifier: workspace:* - version: link:../eslint-config '@repo/typescript-config': specifier: workspace:* version: link:../typescript-config @@ -301,11 +228,8 @@ importers: specifier: ^22.15.3 version: 22.15.3 dpdm: - specifier: ^3.14.0 - version: 3.14.0 - eslint: - specifier: ^9.31.0 - version: 9.31.0(jiti@2.6.1) + specifier: ^3.15.1 + version: 3.15.1 typescript: specifier: 5.8.2 version: 5.8.2 @@ -313,42 +237,6 @@ importers: specifier: ^3.2.4 version: 3.2.4(@types/node@22.15.3)(jiti@2.6.1)(tsx@4.20.3) - packages/eslint-config: - devDependencies: - '@eslint/js': - specifier: ^9.31.0 - version: 9.31.0 - '@next/eslint-plugin-next': - specifier: ^15.4.2 - version: 15.4.2 - eslint: - specifier: ^9.31.0 - version: 9.31.0(jiti@2.6.1) - eslint-config-prettier: - specifier: ^10.1.1 - version: 10.1.1(eslint@9.31.0(jiti@2.6.1)) - eslint-plugin-only-warn: - specifier: ^1.1.0 - version: 1.1.0 - eslint-plugin-react: - specifier: ^7.37.5 - version: 7.37.5(eslint@9.31.0(jiti@2.6.1)) - eslint-plugin-react-hooks: - specifier: ^5.2.0 - version: 5.2.0(eslint@9.31.0(jiti@2.6.1)) - eslint-plugin-turbo: - specifier: ^2.5.0 - version: 2.5.0(eslint@9.31.0(jiti@2.6.1))(turbo@2.5.5) - globals: - specifier: ^16.3.0 - version: 16.3.0 - typescript: - specifier: ^5.8.2 - version: 5.8.2 - typescript-eslint: - specifier: ^8.37.0 - version: 8.37.0(eslint@9.31.0(jiti@2.6.1))(typescript@5.8.2) - packages/felis: dependencies: '@minswap/felis-build-tx': @@ -400,9 +288,6 @@ importers: specifier: workspace:* version: link:../wingriders-v2 devDependencies: - '@repo/eslint-config': - specifier: workspace:* - version: link:../eslint-config '@repo/typescript-config': specifier: workspace:* version: link:../typescript-config @@ -410,11 +295,8 @@ importers: specifier: ^22.15.3 version: 22.15.3 dpdm: - specifier: ^3.14.0 - version: 3.14.0 - eslint: - specifier: ^9.31.0 - version: 9.31.0(jiti@2.6.1) + specifier: ^3.15.1 + version: 3.15.1 typescript: specifier: 5.8.2 version: 5.8.2 @@ -459,8 +341,8 @@ importers: specifier: ^22.15.3 version: 22.15.3 dpdm: - specifier: ^3.14.0 - version: 3.14.0 + specifier: ^3.15.1 + version: 3.15.1 fast-check: specifier: ^3.23.2 version: 3.23.2 @@ -504,9 +386,6 @@ importers: specifier: ^2.1.4 version: 2.1.4 devDependencies: - '@repo/eslint-config': - specifier: workspace:* - version: link:../eslint-config '@repo/typescript-config': specifier: workspace:* version: link:../typescript-config @@ -517,8 +396,8 @@ importers: specifier: ^22.15.3 version: 22.15.3 dpdm: - specifier: ^3.14.0 - version: 3.14.0 + specifier: ^3.15.1 + version: 3.15.1 fast-check: specifier: ^3.23.2 version: 3.23.2 @@ -550,9 +429,6 @@ importers: specifier: ^9.1.2 version: 9.3.1 devDependencies: - '@repo/eslint-config': - specifier: workspace:* - version: link:../eslint-config '@repo/typescript-config': specifier: workspace:* version: link:../typescript-config @@ -563,11 +439,8 @@ importers: specifier: ^22.15.3 version: 22.15.3 dpdm: - specifier: ^3.14.0 - version: 3.14.0 - eslint: - specifier: ^9.31.0 - version: 9.31.0(jiti@2.6.1) + specifier: ^3.15.1 + version: 3.15.1 typescript: specifier: 5.8.2 version: 5.8.2 @@ -587,9 +460,6 @@ importers: specifier: ^1.2.0 version: 1.2.0 devDependencies: - '@repo/eslint-config': - specifier: workspace:* - version: link:../eslint-config '@repo/typescript-config': specifier: workspace:* version: link:../typescript-config @@ -600,11 +470,8 @@ importers: specifier: ^22.15.3 version: 22.15.3 dpdm: - specifier: ^3.14.0 - version: 3.14.0 - eslint: - specifier: ^9.31.0 - version: 9.31.0(jiti@2.6.1) + specifier: ^3.15.1 + version: 3.15.1 typescript: specifier: 5.8.2 version: 5.8.2 @@ -621,9 +488,6 @@ importers: specifier: ^1.2.0 version: 1.2.0 devDependencies: - '@repo/eslint-config': - specifier: workspace:* - version: link:../eslint-config '@repo/typescript-config': specifier: workspace:* version: link:../typescript-config @@ -634,11 +498,8 @@ importers: specifier: ^22.15.3 version: 22.15.3 dpdm: - specifier: ^3.14.0 - version: 3.14.0 - eslint: - specifier: ^9.31.0 - version: 9.31.0(jiti@2.6.1) + specifier: ^3.15.1 + version: 3.15.1 typescript: specifier: 5.8.2 version: 5.8.2 @@ -682,9 +543,6 @@ importers: specifier: ^2.19.2 version: 2.28.0 devDependencies: - '@repo/eslint-config': - specifier: workspace:* - version: link:../eslint-config '@repo/typescript-config': specifier: workspace:* version: link:../typescript-config @@ -695,11 +553,8 @@ importers: specifier: ^22.15.3 version: 22.15.3 dpdm: - specifier: ^3.14.0 - version: 3.14.0 - eslint: - specifier: ^9.31.0 - version: 9.31.0(jiti@2.6.1) + specifier: ^3.15.1 + version: 3.15.1 typescript: specifier: 5.8.2 version: 5.8.2 @@ -734,9 +589,6 @@ importers: specifier: ^2.19.2 version: 2.28.0 devDependencies: - '@repo/eslint-config': - specifier: workspace:* - version: link:../eslint-config '@repo/typescript-config': specifier: workspace:* version: link:../typescript-config @@ -747,11 +599,8 @@ importers: specifier: ^22.15.3 version: 22.15.3 dpdm: - specifier: ^3.14.0 - version: 3.14.0 - eslint: - specifier: ^9.31.0 - version: 9.31.0(jiti@2.6.1) + specifier: ^3.15.1 + version: 3.15.1 fast-check: specifier: ^3.23.2 version: 3.23.2 @@ -780,9 +629,6 @@ importers: '@minswap/felis-dex-v2': specifier: workspace:* version: link:../minswap-dex-v2 - '@repo/eslint-config': - specifier: workspace:* - version: link:../eslint-config '@repo/typescript-config': specifier: workspace:* version: link:../typescript-config @@ -793,11 +639,8 @@ importers: specifier: ^22.15.3 version: 22.15.3 dpdm: - specifier: ^3.14.0 - version: 3.14.0 - eslint: - specifier: ^9.31.0 - version: 9.31.0(jiti@2.6.1) + specifier: ^3.15.1 + version: 3.15.1 typescript: specifier: 5.8.2 version: 5.8.2 @@ -817,9 +660,6 @@ importers: specifier: ^1.2.1 version: 1.2.1 devDependencies: - '@repo/eslint-config': - specifier: workspace:* - version: link:../eslint-config '@repo/typescript-config': specifier: workspace:* version: link:../typescript-config @@ -830,11 +670,8 @@ importers: specifier: ^22.15.3 version: 22.15.3 dpdm: - specifier: ^3.14.0 - version: 3.14.0 - eslint: - specifier: ^9.31.0 - version: 9.31.0(jiti@2.6.1) + specifier: ^3.15.1 + version: 3.15.1 typescript: specifier: 5.8.2 version: 5.8.2 @@ -851,9 +688,6 @@ importers: specifier: ^1.2.0 version: 1.2.0 devDependencies: - '@repo/eslint-config': - specifier: workspace:* - version: link:../eslint-config '@repo/typescript-config': specifier: workspace:* version: link:../typescript-config @@ -864,11 +698,8 @@ importers: specifier: ^22.15.3 version: 22.15.3 dpdm: - specifier: ^3.14.0 - version: 3.14.0 - eslint: - specifier: ^9.31.0 - version: 9.31.0(jiti@2.6.1) + specifier: ^3.15.1 + version: 3.15.1 typescript: specifier: 5.8.2 version: 5.8.2 @@ -888,9 +719,6 @@ importers: specifier: ^1.2.0 version: 1.2.0 devDependencies: - '@repo/eslint-config': - specifier: workspace:* - version: link:../eslint-config '@repo/typescript-config': specifier: workspace:* version: link:../typescript-config @@ -901,11 +729,8 @@ importers: specifier: ^22.15.3 version: 22.15.3 dpdm: - specifier: ^3.14.0 - version: 3.14.0 - eslint: - specifier: ^9.31.0 - version: 9.31.0(jiti@2.6.1) + specifier: ^3.15.1 + version: 3.15.1 typescript: specifier: 5.8.2 version: 5.8.2 @@ -949,9 +774,6 @@ importers: specifier: ^1.2.0 version: 1.2.0 devDependencies: - '@repo/eslint-config': - specifier: workspace:* - version: link:../eslint-config '@repo/typescript-config': specifier: workspace:* version: link:../typescript-config @@ -962,11 +784,8 @@ importers: specifier: ^22.15.3 version: 22.15.3 dpdm: - specifier: ^3.14.0 - version: 3.14.0 - eslint: - specifier: ^9.31.0 - version: 9.31.0(jiti@2.6.1) + specifier: ^3.15.1 + version: 3.15.1 typescript: specifier: 5.8.2 version: 5.8.2 @@ -998,9 +817,6 @@ importers: specifier: ^2.19.2 version: 2.28.0 devDependencies: - '@repo/eslint-config': - specifier: workspace:* - version: link:../eslint-config '@repo/typescript-config': specifier: workspace:* version: link:../typescript-config @@ -1011,48 +827,14 @@ importers: specifier: ^22.15.3 version: 22.15.3 dpdm: - specifier: ^3.14.0 - version: 3.14.0 - eslint: - specifier: ^9.31.0 - version: 9.31.0(jiti@2.6.1) + specifier: ^3.15.1 + version: 3.15.1 typescript: specifier: 5.8.2 version: 5.8.2 packages/typescript-config: {} - packages/ui: - dependencies: - react: - specifier: ^19.2.3 - version: 19.2.3 - react-dom: - specifier: ^19.2.3 - version: 19.2.3(react@19.2.3) - devDependencies: - '@repo/eslint-config': - specifier: workspace:* - version: link:../eslint-config - '@repo/typescript-config': - specifier: workspace:* - version: link:../typescript-config - '@types/node': - specifier: ^22.15.3 - version: 22.15.3 - '@types/react': - specifier: 19.2.7 - version: 19.2.7 - '@types/react-dom': - specifier: 19.2.3 - version: 19.2.3(@types/react@19.2.7) - eslint: - specifier: ^9.31.0 - version: 9.31.0(jiti@2.6.1) - typescript: - specifier: 5.8.3 - version: 5.8.3 - packages/uplc-node: {} packages/uplc-web: {} @@ -1069,9 +851,6 @@ importers: specifier: ^1.2.0 version: 1.2.0 devDependencies: - '@repo/eslint-config': - specifier: workspace:* - version: link:../eslint-config '@repo/typescript-config': specifier: workspace:* version: link:../typescript-config @@ -1082,11 +861,8 @@ importers: specifier: ^22.15.3 version: 22.15.3 dpdm: - specifier: ^3.14.0 - version: 3.14.0 - eslint: - specifier: ^9.31.0 - version: 9.31.0(jiti@2.6.1) + specifier: ^3.15.1 + version: 3.15.1 typescript: specifier: 5.8.2 version: 5.8.2 @@ -1106,9 +882,6 @@ importers: specifier: ^1.2.1 version: 1.2.1 devDependencies: - '@repo/eslint-config': - specifier: workspace:* - version: link:../eslint-config '@repo/typescript-config': specifier: workspace:* version: link:../typescript-config @@ -1119,60 +892,14 @@ importers: specifier: ^22.15.3 version: 22.15.3 dpdm: - specifier: ^3.14.0 - version: 3.14.0 - eslint: - specifier: ^9.31.0 - version: 9.31.0(jiti@2.6.1) + specifier: ^3.15.1 + version: 3.15.1 typescript: specifier: 5.8.2 version: 5.8.2 packages: - '@ant-design/colors@7.2.1': - resolution: {integrity: sha512-lCHDcEzieu4GA3n8ELeZ5VQ8pKQAWcGGLRTQ50aQM2iqPpq2evTxER84jfdPvsPAtEcZ7m44NI45edFMo8oOYQ==} - - '@ant-design/cssinjs-utils@1.1.3': - resolution: {integrity: sha512-nOoQMLW1l+xR1Co8NFVYiP8pZp3VjIIzqV6D6ShYF2ljtdwWJn5WSsH+7kvCktXL/yhEtWURKOfH5Xz/gzlwsg==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@ant-design/cssinjs@1.24.0': - resolution: {integrity: sha512-K4cYrJBsgvL+IoozUXYjbT6LHHNt+19a9zkvpBPxLjFHas1UpPM2A5MlhROb0BT8N8WoavM5VsP9MeSeNK/3mg==} - peerDependencies: - react: '>=16.0.0' - react-dom: '>=16.0.0' - - '@ant-design/fast-color@2.0.6': - resolution: {integrity: sha512-y2217gk4NqL35giHl72o6Zzqji9O7vHh9YmhUVkPtAOpoTCH4uWxo/pr4VE8t0+ChEPs0qo4eJRC5Q1eXWo3vA==} - engines: {node: '>=8.x'} - - '@ant-design/icons-svg@4.4.2': - resolution: {integrity: sha512-vHbT+zJEVzllwP+CM+ul7reTEfBR0vgxFe7+lREAsAA7YGsYpboiq2sQNeQeRvh09GfQgs/GyFEvZpJ9cLXpXA==} - - '@ant-design/icons@5.6.1': - resolution: {integrity: sha512-0/xS39c91WjPAZOWsvi1//zjx6kAp4kxWwctR6kuU6p133w8RU0D2dSCvZC19uQyharg/sAvYxGYWl01BbZZfg==} - engines: {node: '>=8'} - peerDependencies: - react: '>=16.0.0' - react-dom: '>=16.0.0' - - '@ant-design/nextjs-registry@1.1.0': - resolution: {integrity: sha512-zZ9SKyqTHonUK7l/z/ixpVx0LSnZTlIqYFOccSDI7jx7ojCMTGxzkl3ugGWPPh8xPYDsVxqzwJZBic84H7LgLw==} - peerDependencies: - '@ant-design/cssinjs': ^1.24.0 - antd: ^5.0.0 - next: ^14.0.0 || ^15.0.0 - react: '>=16.0.0' - react-dom: '>=16.0.0' - - '@ant-design/react-slick@1.1.2': - resolution: {integrity: sha512-EzlvzE6xQUBrZuuhSAFTdsr4P2bBBHGZwKFemEfq8gIGyIQCxalYfZW/T2ORbtQx5rU69o+WycP3exY/7T1hGA==} - peerDependencies: - react: '>=16.9.0' - '@babel/code-frame@7.29.0': resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} engines: {node: '>=6.9.0'} @@ -1181,10 +908,6 @@ packages: resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} engines: {node: '>=6.9.0'} - '@babel/runtime@7.28.4': - resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} - engines: {node: '>=6.9.0'} - '@biomejs/biome@2.1.4': resolution: {integrity: sha512-QWlrqyxsU0FCebuMnkvBIkxvPqH89afiJzjMl+z67ybutse590jgeaFdDurE9XYtzpjRGTI1tlUZPGWmbKsElA==} engines: {node: '>=14.21.3'} @@ -1253,15 +976,6 @@ packages: '@cardanosolutions/json-bigint@1.1.0': resolution: {integrity: sha512-Pdgz18cSwLKKgheOqW/dqbzNI+CliNT4AdaKaKY/P++J9qLxIB8MITCurlzbaFWV3W4nmK0CRQwI1yvuArmjFg==} - '@emnapi/runtime@1.7.1': - resolution: {integrity: sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==} - - '@emotion/hash@0.8.0': - resolution: {integrity: sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==} - - '@emotion/unitless@0.7.5': - resolution: {integrity: sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==} - '@emurgo/cardano-message-signing-nodejs@1.1.0': resolution: {integrity: sha512-PQRc8K8wZshEdmQenNUzVtiI8oJNF/1uAnBhidee5C4o1l2mDLOW+ur46HWHIFKQ6x8mSJTllcjMscHgzju0gQ==} @@ -1427,44 +1141,6 @@ packages: cpu: [x64] os: [win32] - '@eslint-community/eslint-utils@4.7.0': - resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - - '@eslint-community/regexpp@4.12.1': - resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - - '@eslint/config-array@0.21.0': - resolution: {integrity: sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/config-helpers@0.3.0': - resolution: {integrity: sha512-ViuymvFmcJi04qdZeDc2whTHryouGcDlaxPqarTD0ZE10ISpxGUVZGZDx4w01upyIynL3iu6IXH2bS1NhclQMw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/core@0.15.1': - resolution: {integrity: sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/eslintrc@3.3.1': - resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/js@9.31.0': - resolution: {integrity: sha512-LOm5OVt7D4qiKCqoiPbA7LWmI+tbw1VbTUowBcUMgQSuM6poJufkFkYDcQpo5KfgD39TnNySV26QjOh7VFpSyw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/object-schema@2.1.6': - resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/plugin-kit@0.3.3': - resolution: {integrity: sha512-1+WqvgNMhmlAambTvT3KPtCl/Ibr68VldY2XY40SL1CE0ZXiakFR/cbTspaF5HsnpDMvcYYoJHfl4980NBjGag==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@fastify/ajv-compiler@4.0.5': resolution: {integrity: sha512-KoWKW+MhvfTRWL4qrhUwAAZoaChluo0m0vbiJlGMt2GXvL4LVPQEjt8kSpHI3IBq5Rez8fg+XeH3cneztq+C7A==} @@ -1480,168 +1156,17 @@ packages: '@fastify/forwarded@3.0.1': resolution: {integrity: sha512-JqDochHFqXs3C3Ml3gOY58zM7OqO9ENqPo0UqAjAjH8L01fRZqwX9iLeX34//kiJubF7r2ZQHtBRU36vONbLlw==} + '@fastify/helmet@13.0.2': + resolution: {integrity: sha512-tO1QMkOfNeCt9l4sG/FiWErH4QMm+RjHzbMTrgew1DYOQ2vb/6M1G2iNABBrD7Xq6dUk+HLzWW8u+rmmhQHifA==} + '@fastify/merge-json-schemas@0.2.1': resolution: {integrity: sha512-OA3KGBCy6KtIvLf8DINC5880o5iBlDX4SxzLQS8HorJAbqluzLRn80UXU0bxZn7UOFhFgpRJDasfwn9nG4FG4A==} '@fastify/proxy-addr@5.1.0': resolution: {integrity: sha512-INS+6gh91cLUjB+PVHfu1UqcB76Sqtpyp7bnL+FYojhjygvOPA9ctiD/JDKsyD9Xgu4hUhCSJBPig/w7duNajw==} - '@humanfs/core@0.19.1': - resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} - engines: {node: '>=18.18.0'} - - '@humanfs/node@0.16.6': - resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} - engines: {node: '>=18.18.0'} - - '@humanwhocodes/module-importer@1.0.1': - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} - - '@humanwhocodes/retry@0.3.1': - resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} - engines: {node: '>=18.18'} - - '@humanwhocodes/retry@0.4.3': - resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} - engines: {node: '>=18.18'} - - '@img/colour@1.0.0': - resolution: {integrity: sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==} - engines: {node: '>=18'} - - '@img/sharp-darwin-arm64@0.34.5': - resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [darwin] - - '@img/sharp-darwin-x64@0.34.5': - resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [darwin] - - '@img/sharp-libvips-darwin-arm64@1.2.4': - resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==} - cpu: [arm64] - os: [darwin] - - '@img/sharp-libvips-darwin-x64@1.2.4': - resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==} - cpu: [x64] - os: [darwin] - - '@img/sharp-libvips-linux-arm64@1.2.4': - resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} - cpu: [arm64] - os: [linux] - - '@img/sharp-libvips-linux-arm@1.2.4': - resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} - cpu: [arm] - os: [linux] - - '@img/sharp-libvips-linux-ppc64@1.2.4': - resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} - cpu: [ppc64] - os: [linux] - - '@img/sharp-libvips-linux-riscv64@1.2.4': - resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} - cpu: [riscv64] - os: [linux] - - '@img/sharp-libvips-linux-s390x@1.2.4': - resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} - cpu: [s390x] - os: [linux] - - '@img/sharp-libvips-linux-x64@1.2.4': - resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} - cpu: [x64] - os: [linux] - - '@img/sharp-libvips-linuxmusl-arm64@1.2.4': - resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} - cpu: [arm64] - os: [linux] - - '@img/sharp-libvips-linuxmusl-x64@1.2.4': - resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} - cpu: [x64] - os: [linux] - - '@img/sharp-linux-arm64@0.34.5': - resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [linux] - - '@img/sharp-linux-arm@0.34.5': - resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm] - os: [linux] - - '@img/sharp-linux-ppc64@0.34.5': - resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [ppc64] - os: [linux] - - '@img/sharp-linux-riscv64@0.34.5': - resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [riscv64] - os: [linux] - - '@img/sharp-linux-s390x@0.34.5': - resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [s390x] - os: [linux] - - '@img/sharp-linux-x64@0.34.5': - resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [linux] - - '@img/sharp-linuxmusl-arm64@0.34.5': - resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [linux] - - '@img/sharp-linuxmusl-x64@0.34.5': - resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [linux] - - '@img/sharp-wasm32@0.34.5': - resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [wasm32] - - '@img/sharp-win32-arm64@0.34.5': - resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [win32] - - '@img/sharp-win32-ia32@0.34.5': - resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [ia32] - os: [win32] - - '@img/sharp-win32-x64@0.34.5': - resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [win32] + '@fastify/rate-limit@10.3.0': + resolution: {integrity: sha512-eIGkG9XKQs0nyynatApA3EVrojHOuq4l6fhB4eeCk4PIOeadvOJz9/4w3vGI44Go17uaXOWEcPkaD8kuKm7g6Q==} '@ioredis/commands@1.5.0': resolution: {integrity: sha512-eUgLqrMf8nJkZxT24JvVRrQya1vZkQh8BBeYNwGDqa5I0VUi8ACx7uFvAaLxintokpTenkK6DASvo/bvNbBGow==} @@ -1653,6 +1178,10 @@ packages: '@jridgewell/sourcemap-codec@1.5.5': resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + '@lukeed/ms@2.0.2': + resolution: {integrity: sha512-9I2Zn6+NJLfaGoz9jN3lpwDgAYvfGeNYdbAIjJOqzs4Tpc+VU3Jqq4IofSUBKajiDS8k9fZIg18/z13mpk1bsA==} + engines: {node: '>=8'} + '@minswap/cardano-serialization-lib-browser@11.1.0-minswap.33': resolution: {integrity: sha512-onMYkYLn1oC/GA0Qd1iLEeF5ipiPFYOTS7RXsViLptIzcNzEEVFcb4amNL5HwrF+XnlbzR3ZyUvfYBsnQUnK6g==} @@ -1662,76 +1191,10 @@ packages: '@minswap/tiny-invariant@1.2.0': resolution: {integrity: sha512-m4CMTsZ4MDB2WLND6rV0eti+f2WcMPhKvXf9ZHXlQMqvNmgoX1z//84FpEX0D1vVTPfJtNS8XIoIQ9pm6X590A==} - '@next/env@16.0.10': - resolution: {integrity: sha512-8tuaQkyDVgeONQ1MeT9Mkk8pQmZapMKFh5B+OrFUlG3rVmYTXcXlBetBgTurKXGaIZvkoqRT9JL5K3phXcgang==} - - '@next/eslint-plugin-next@15.4.2': - resolution: {integrity: sha512-k0rjdWjXBY6tAOty1ckrMETE6Mx66d85NsgcAIdDp7/cXOsTJ93ywmbg3uUcpxX5TUHFEcCWI5mb8nPhwCe9jg==} - - '@next/swc-darwin-arm64@16.0.10': - resolution: {integrity: sha512-4XgdKtdVsaflErz+B5XeG0T5PeXKDdruDf3CRpnhN+8UebNa5N2H58+3GDgpn/9GBurrQ1uWW768FfscwYkJRg==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [darwin] - - '@next/swc-darwin-x64@16.0.10': - resolution: {integrity: sha512-spbEObMvRKkQ3CkYVOME+ocPDFo5UqHb8EMTS78/0mQ+O1nqE8toHJVioZo4TvebATxgA8XMTHHrScPrn68OGw==} - engines: {node: '>= 10'} - cpu: [x64] - os: [darwin] - - '@next/swc-linux-arm64-gnu@16.0.10': - resolution: {integrity: sha512-uQtWE3X0iGB8apTIskOMi2w/MKONrPOUCi5yLO+v3O8Mb5c7K4Q5KD1jvTpTF5gJKa3VH/ijKjKUq9O9UhwOYw==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@next/swc-linux-arm64-musl@16.0.10': - resolution: {integrity: sha512-llA+hiDTrYvyWI21Z0L1GiXwjQaanPVQQwru5peOgtooeJ8qx3tlqRV2P7uH2pKQaUfHxI/WVarvI5oYgGxaTw==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@next/swc-linux-x64-gnu@16.0.10': - resolution: {integrity: sha512-AK2q5H0+a9nsXbeZ3FZdMtbtu9jxW4R/NgzZ6+lrTm3d6Zb7jYrWcgjcpM1k8uuqlSy4xIyPR2YiuUr+wXsavA==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@next/swc-linux-x64-musl@16.0.10': - resolution: {integrity: sha512-1TDG9PDKivNw5550S111gsO4RGennLVl9cipPhtkXIFVwo31YZ73nEbLjNC8qG3SgTz/QZyYyaFYMeY4BKZR/g==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@next/swc-win32-arm64-msvc@16.0.10': - resolution: {integrity: sha512-aEZIS4Hh32xdJQbHz121pyuVZniSNoqDVx1yIr2hy+ZwJGipeqnMZBJHyMxv2tiuAXGx6/xpTcQJ6btIiBjgmg==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [win32] - - '@next/swc-win32-x64-msvc@16.0.10': - resolution: {integrity: sha512-E+njfCoFLb01RAFEnGZn6ERoOqhK1Gl3Lfz1Kjnj0Ulfu7oJbuMyvBKNj/bw8XZnenHDASlygTjZICQW+rYW1Q==} - engines: {node: '>= 10'} - cpu: [x64] - os: [win32] - '@noble/hashes@1.8.0': resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} engines: {node: ^14.21.3 || >=16} - '@nodelib/fs.scandir@2.1.5': - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} - - '@nodelib/fs.stat@2.0.5': - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} - - '@nodelib/fs.walk@1.2.8': - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} - '@pinojs/redact@0.4.0': resolution: {integrity: sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==} @@ -1739,158 +1202,128 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} - '@rc-component/async-validator@5.0.4': - resolution: {integrity: sha512-qgGdcVIF604M9EqjNF0hbUTz42bz/RDtxWdWuU5EQe3hi7M8ob54B6B35rOsvX5eSvIHIzT9iH1R3n+hk3CGfg==} - engines: {node: '>=14.x'} - - '@rc-component/color-picker@2.0.1': - resolution: {integrity: sha512-WcZYwAThV/b2GISQ8F+7650r5ZZJ043E57aVBFkQ+kSY4C6wdofXgB0hBx+GPGpIU0Z81eETNoDUJMr7oy/P8Q==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rc-component/context@1.4.0': - resolution: {integrity: sha512-kFcNxg9oLRMoL3qki0OMxK+7g5mypjgaaJp/pkOis/6rVxma9nJBF/8kCIuTYHUQNr0ii7MxqE33wirPZLJQ2w==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rc-component/mini-decimal@1.1.0': - resolution: {integrity: sha512-jS4E7T9Li2GuYwI6PyiVXmxTiM6b07rlD9Ge8uGZSCz3WlzcG5ZK7g5bbuKNeZ9pgUuPK/5guV781ujdVpm4HQ==} - engines: {node: '>=8.x'} - - '@rc-component/mutate-observer@1.1.0': - resolution: {integrity: sha512-QjrOsDXQusNwGZPf4/qRQasg7UFEj06XiCJ8iuiq/Io7CrHrgVi6Uuetw60WAMG1799v+aM8kyc+1L/GBbHSlw==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rc-component/portal@1.1.2': - resolution: {integrity: sha512-6f813C0IsasTZms08kfA8kPAGxbbkYToa8ALaiDIGGECU4i9hj8Plgbx0sNJDrey3EtHO30hmdaxtT0138xZcg==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rc-component/qrcode@1.0.1': - resolution: {integrity: sha512-g8eeeaMyFXVlq8cZUeaxCDhfIYjpao0l9cvm5gFwKXy/Vm1yDWV7h2sjH5jHYzdFedlVKBpATFB1VKMrHzwaWQ==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rc-component/tour@1.15.1': - resolution: {integrity: sha512-Tr2t7J1DKZUpfJuDZWHxyxWpfmj8EZrqSgyMZ+BCdvKZ6r1UDsfU46M/iWAAFBy961Ssfom2kv5f3UcjIL2CmQ==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rc-component/trigger@2.3.0': - resolution: {integrity: sha512-iwaxZyzOuK0D7lS+0AQEtW52zUWxoGqTGkke3dRyb8pYiShmRpCjB/8TzPI4R6YySCH7Vm9BZj/31VPiiQTLBg==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rollup/rollup-android-arm-eabi@4.46.3': - resolution: {integrity: sha512-UmTdvXnLlqQNOCJnyksjPs1G4GqXNGW1LrzCe8+8QoaLhhDeTXYBgJ3k6x61WIhlHX2U+VzEJ55TtIjR/HTySA==} + '@rollup/rollup-android-arm-eabi@4.60.0': + resolution: {integrity: sha512-WOhNW9K8bR3kf4zLxbfg6Pxu2ybOUbB2AjMDHSQx86LIF4rH4Ft7vmMwNt0loO0eonglSNy4cpD3MKXXKQu0/A==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.46.3': - resolution: {integrity: sha512-8NoxqLpXm7VyeI0ocidh335D6OKT0UJ6fHdnIxf3+6oOerZZc+O7r+UhvROji6OspyPm+rrIdb1gTXtVIqn+Sg==} + '@rollup/rollup-android-arm64@4.60.0': + resolution: {integrity: sha512-u6JHLll5QKRvjciE78bQXDmqRqNs5M/3GVqZeMwvmjaNODJih/WIrJlFVEihvV0MiYFmd+ZyPr9wxOVbPAG2Iw==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.46.3': - resolution: {integrity: sha512-csnNavqZVs1+7/hUKtgjMECsNG2cdB8F7XBHP6FfQjqhjF8rzMzb3SLyy/1BG7YSfQ+bG75Ph7DyedbUqwq1rA==} + '@rollup/rollup-darwin-arm64@4.60.0': + resolution: {integrity: sha512-qEF7CsKKzSRc20Ciu2Zw1wRrBz4g56F7r/vRwY430UPp/nt1x21Q/fpJ9N5l47WWvJlkNCPJz3QRVw008fi7yA==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.46.3': - resolution: {integrity: sha512-r2MXNjbuYabSIX5yQqnT8SGSQ26XQc8fmp6UhlYJd95PZJkQD1u82fWP7HqvGUf33IsOC6qsiV+vcuD4SDP6iw==} + '@rollup/rollup-darwin-x64@4.60.0': + resolution: {integrity: sha512-WADYozJ4QCnXCH4wPB+3FuGmDPoFseVCUrANmA5LWwGmC6FL14BWC7pcq+FstOZv3baGX65tZ378uT6WG8ynTw==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.46.3': - resolution: {integrity: sha512-uluObTmgPJDuJh9xqxyr7MV61Imq+0IvVsAlWyvxAaBSNzCcmZlhfYcRhCdMaCsy46ccZa7vtDDripgs9Jkqsw==} + '@rollup/rollup-freebsd-arm64@4.60.0': + resolution: {integrity: sha512-6b8wGHJlDrGeSE3aH5mGNHBjA0TTkxdoNHik5EkvPHCt351XnigA4pS7Wsj/Eo9Y8RBU6f35cjN9SYmCFBtzxw==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.46.3': - resolution: {integrity: sha512-AVJXEq9RVHQnejdbFvh1eWEoobohUYN3nqJIPI4mNTMpsyYN01VvcAClxflyk2HIxvLpRcRggpX1m9hkXkpC/A==} + '@rollup/rollup-freebsd-x64@4.60.0': + resolution: {integrity: sha512-h25Ga0t4jaylMB8M/JKAyrvvfxGRjnPQIR8lnCayyzEjEOx2EJIlIiMbhpWxDRKGKF8jbNH01NnN663dH638mA==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.46.3': - resolution: {integrity: sha512-byyflM+huiwHlKi7VHLAYTKr67X199+V+mt1iRgJenAI594vcmGGddWlu6eHujmcdl6TqSNnvqaXJqZdnEWRGA==} + '@rollup/rollup-linux-arm-gnueabihf@4.60.0': + resolution: {integrity: sha512-RzeBwv0B3qtVBWtcuABtSuCzToo2IEAIQrcyB/b2zMvBWVbjo8bZDjACUpnaafaxhTw2W+imQbP2BD1usasK4g==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.46.3': - resolution: {integrity: sha512-aLm3NMIjr4Y9LklrH5cu7yybBqoVCdr4Nvnm8WB7PKCn34fMCGypVNpGK0JQWdPAzR/FnoEoFtlRqZbBBLhVoQ==} + '@rollup/rollup-linux-arm-musleabihf@4.60.0': + resolution: {integrity: sha512-Sf7zusNI2CIU1HLzuu9Tc5YGAHEZs5Lu7N1ssJG4Tkw6e0MEsN7NdjUDDfGNHy2IU+ENyWT+L2obgWiguWibWQ==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.46.3': - resolution: {integrity: sha512-VtilE6eznJRDIoFOzaagQodUksTEfLIsvXymS+UdJiSXrPW7Ai+WG4uapAc3F7Hgs791TwdGh4xyOzbuzIZrnw==} + '@rollup/rollup-linux-arm64-gnu@4.60.0': + resolution: {integrity: sha512-DX2x7CMcrJzsE91q7/O02IJQ5/aLkVtYFryqCjduJhUfGKG6yJV8hxaw8pZa93lLEpPTP/ohdN4wFz7yp/ry9A==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.46.3': - resolution: {integrity: sha512-dG3JuS6+cRAL0GQ925Vppafi0qwZnkHdPeuZIxIPXqkCLP02l7ka+OCyBoDEv8S+nKHxfjvjW4OZ7hTdHkx8/w==} + '@rollup/rollup-linux-arm64-musl@4.60.0': + resolution: {integrity: sha512-09EL+yFVbJZlhcQfShpswwRZ0Rg+z/CsSELFCnPt3iK+iqwGsI4zht3secj5vLEs957QvFFXnzAT0FFPIxSrkQ==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loongarch64-gnu@4.46.3': - resolution: {integrity: sha512-iU8DxnxEKJptf8Vcx4XvAUdpkZfaz0KWfRrnIRrOndL0SvzEte+MTM7nDH4A2Now4FvTZ01yFAgj6TX/mZl8hQ==} + '@rollup/rollup-linux-loong64-gnu@4.60.0': + resolution: {integrity: sha512-i9IcCMPr3EXm8EQg5jnja0Zyc1iFxJjZWlb4wr7U2Wx/GrddOuEafxRdMPRYVaXjgbhvqalp6np07hN1w9kAKw==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-loong64-musl@4.60.0': + resolution: {integrity: sha512-DGzdJK9kyJ+B78MCkWeGnpXJ91tK/iKA6HwHxF4TAlPIY7GXEvMe8hBFRgdrR9Ly4qebR/7gfUs9y2IoaVEyog==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-ppc64-gnu@4.46.3': - resolution: {integrity: sha512-VrQZp9tkk0yozJoQvQcqlWiqaPnLM6uY1qPYXvukKePb0fqaiQtOdMJSxNFUZFsGw5oA5vvVokjHrx8a9Qsz2A==} + '@rollup/rollup-linux-ppc64-gnu@4.60.0': + resolution: {integrity: sha512-RwpnLsqC8qbS8z1H1AxBA1H6qknR4YpPR9w2XX0vo2Sz10miu57PkNcnHVaZkbqyw/kUWfKMI73jhmfi9BRMUQ==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-ppc64-musl@4.60.0': + resolution: {integrity: sha512-Z8pPf54Ly3aqtdWC3G4rFigZgNvd+qJlOE52fmko3KST9SoGfAdSRCwyoyG05q1HrrAblLbk1/PSIV+80/pxLg==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.46.3': - resolution: {integrity: sha512-uf2eucWSUb+M7b0poZ/08LsbcRgaDYL8NCGjUeFMwCWFwOuFcZ8D9ayPl25P3pl+D2FH45EbHdfyUesQ2Lt9wA==} + '@rollup/rollup-linux-riscv64-gnu@4.60.0': + resolution: {integrity: sha512-3a3qQustp3COCGvnP4SvrMHnPQ9d1vzCakQVRTliaz8cIp/wULGjiGpbcqrkv0WrHTEp8bQD/B3HBjzujVWLOA==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.46.3': - resolution: {integrity: sha512-7tnUcDvN8DHm/9ra+/nF7lLzYHDeODKKKrh6JmZejbh1FnCNZS8zMkZY5J4sEipy2OW1d1Ncc4gNHUd0DLqkSg==} + '@rollup/rollup-linux-riscv64-musl@4.60.0': + resolution: {integrity: sha512-pjZDsVH/1VsghMJ2/kAaxt6dL0psT6ZexQVrijczOf+PeP2BUqTHYejk3l6TlPRydggINOeNRhvpLa0AYpCWSQ==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.46.3': - resolution: {integrity: sha512-MUpAOallJim8CsJK+4Lc9tQzlfPbHxWDrGXZm2z6biaadNpvh3a5ewcdat478W+tXDoUiHwErX/dOql7ETcLqg==} + '@rollup/rollup-linux-s390x-gnu@4.60.0': + resolution: {integrity: sha512-3ObQs0BhvPgiUVZrN7gqCSvmFuMWvWvsjG5ayJ3Lraqv+2KhOsp+pUbigqbeWqueGIsnn+09HBw27rJ+gYK4VQ==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.46.3': - resolution: {integrity: sha512-F42IgZI4JicE2vM2PWCe0N5mR5vR0gIdORPqhGQ32/u1S1v3kLtbZ0C/mi9FFk7C5T0PgdeyWEPajPjaUpyoKg==} + '@rollup/rollup-linux-x64-gnu@4.60.0': + resolution: {integrity: sha512-EtylprDtQPdS5rXvAayrNDYoJhIz1/vzN2fEubo3yLE7tfAw+948dO0g4M0vkTVFhKojnF+n6C8bDNe+gDRdTg==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.46.3': - resolution: {integrity: sha512-oLc+JrwwvbimJUInzx56Q3ujL3Kkhxehg7O1gWAYzm8hImCd5ld1F2Gry5YDjR21MNb5WCKhC9hXgU7rRlyegQ==} + '@rollup/rollup-linux-x64-musl@4.60.0': + resolution: {integrity: sha512-k09oiRCi/bHU9UVFqD17r3eJR9bn03TyKraCrlz5ULFJGdJGi7VOmm9jl44vOJvRJ6P7WuBi/s2A97LxxHGIdw==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.46.3': - resolution: {integrity: sha512-lOrQ+BVRstruD1fkWg9yjmumhowR0oLAAzavB7yFSaGltY8klttmZtCLvOXCmGE9mLIn8IBV/IFrQOWz5xbFPg==} + '@rollup/rollup-openbsd-x64@4.60.0': + resolution: {integrity: sha512-1o/0/pIhozoSaDJoDcec+IVLbnRtQmHwPV730+AOD29lHEEo4F5BEUB24H0OBdhbBBDwIOSuf7vgg0Ywxdfiiw==} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.60.0': + resolution: {integrity: sha512-pESDkos/PDzYwtyzB5p/UoNU/8fJo68vcXM9ZW2V0kjYayj1KaaUfi1NmTUTUpMn4UhU4gTuK8gIaFO4UGuMbA==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.60.0': + resolution: {integrity: sha512-hj1wFStD7B1YBeYmvY+lWXZ7ey73YGPcViMShYikqKT1GtstIKQAtfUI6yrzPjAy/O7pO0VLXGmUVWXQMaYgTQ==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.46.3': - resolution: {integrity: sha512-vvrVKPRS4GduGR7VMH8EylCBqsDcw6U+/0nPDuIjXQRbHJc6xOBj+frx8ksfZAh6+Fptw5wHrN7etlMmQnPQVg==} + '@rollup/rollup-win32-ia32-msvc@4.60.0': + resolution: {integrity: sha512-SyaIPFoxmUPlNDq5EHkTbiKzmSEmq/gOYFI/3HHJ8iS/v1mbugVa7dXUzcJGQfoytp9DJFLhHH4U3/eTy2Bq4w==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.46.3': - resolution: {integrity: sha512-fi3cPxCnu3ZeM3EwKZPgXbWoGzm2XHgB/WShKI81uj8wG0+laobmqy5wbgEwzstlbLu4MyO8C19FyhhWseYKNQ==} + '@rollup/rollup-win32-x64-gnu@4.60.0': + resolution: {integrity: sha512-RdcryEfzZr+lAr5kRm2ucN9aVlCCa2QNq4hXelZxb8GG0NJSazq44Z3PCCc8wISRuCVnGs0lQJVX5Vp6fKA+IA==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.60.0': + resolution: {integrity: sha512-PrsWNQ8BuE00O3Xsx3ALh2Df8fAj9+cvvX9AIA6o4KpATR98c9mud4XtDWVvsEuyia5U4tVSTKygawyJkjm60w==} cpu: [x64] os: [win32] @@ -1909,9 +1342,6 @@ packages: '@stricahq/typhonjs@2.0.0': resolution: {integrity: sha512-4EdoVAht+hKDaBT1m0qCBQsi5unP9ghM4eUUKGcQcQQiEUZGsP8CgxcGuQbsXL1/LU5wNKoBnxWXUiylZD9uRQ==} - '@swc/helpers@0.5.15': - resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} - '@types/bun@1.3.8': resolution: {integrity: sha512-3LvWJ2q5GerAXYxO2mffLTqOzEu5qnhEAlh48Vnu8WQfnmSwbgagjGZV6BoHKJztENYEDn6QmVd949W4uESRJA==} @@ -1930,82 +1360,12 @@ packages: '@types/json-bigint@1.0.4': resolution: {integrity: sha512-ydHooXLbOmxBbubnA7Eh+RpBzuaIiQjh8WGJYQB50JFGFrdxW7JzVlyEV7fAXw0T2sqJ1ysTneJbiyNLqZRAag==} - '@types/json-schema@7.0.15': - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - '@types/node@22.15.3': resolution: {integrity: sha512-lX7HFZeHf4QG/J7tBZqrCAXwz9J5RD56Y6MpP0eJkka8p+K0RY/yBTW7CYFJ4VGCclxqOLKmiGP5juQc6MKgcw==} '@types/pg@8.16.0': resolution: {integrity: sha512-RmhMd/wD+CF8Dfo+cVIy3RR5cl8CyfXQ0tGgW6XBL8L4LM/UTEbNXYRbLwU6w+CgrKBNbrQWt4FUtTfaU5jSYQ==} - '@types/react-dom@19.2.3': - resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} - peerDependencies: - '@types/react': ^19.2.0 - - '@types/react@19.2.7': - resolution: {integrity: sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==} - - '@typescript-eslint/eslint-plugin@8.37.0': - resolution: {integrity: sha512-jsuVWeIkb6ggzB+wPCsR4e6loj+rM72ohW6IBn2C+5NCvfUVY8s33iFPySSVXqtm5Hu29Ne/9bnA0JmyLmgenA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - '@typescript-eslint/parser': ^8.37.0 - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' - - '@typescript-eslint/parser@8.37.0': - resolution: {integrity: sha512-kVIaQE9vrN9RLCQMQ3iyRlVJpTiDUY6woHGb30JDkfJErqrQEmtdWH3gV0PBAfGZgQXoqzXOO0T3K6ioApbbAA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' - - '@typescript-eslint/project-service@8.37.0': - resolution: {integrity: sha512-BIUXYsbkl5A1aJDdYJCBAo8rCEbAvdquQ8AnLb6z5Lp1u3x5PNgSSx9A/zqYc++Xnr/0DVpls8iQ2cJs/izTXA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <5.9.0' - - '@typescript-eslint/scope-manager@8.37.0': - resolution: {integrity: sha512-0vGq0yiU1gbjKob2q691ybTg9JX6ShiVXAAfm2jGf3q0hdP6/BruaFjL/ManAR/lj05AvYCH+5bbVo0VtzmjOA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/tsconfig-utils@8.37.0': - resolution: {integrity: sha512-1/YHvAVTimMM9mmlPvTec9NP4bobA1RkDbMydxG8omqwJJLEW/Iy2C4adsAESIXU3WGLXFHSZUU+C9EoFWl4Zg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <5.9.0' - - '@typescript-eslint/type-utils@8.37.0': - resolution: {integrity: sha512-SPkXWIkVZxhgwSwVq9rqj/4VFo7MnWwVaRNznfQDc/xPYHjXnPfLWn+4L6FF1cAz6e7dsqBeMawgl7QjUMj4Ow==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' - - '@typescript-eslint/types@8.37.0': - resolution: {integrity: sha512-ax0nv7PUF9NOVPs+lmQ7yIE7IQmAf8LGcXbMvHX5Gm+YJUYNAl340XkGnrimxZ0elXyoQJuN5sbg6C4evKA4SQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/typescript-estree@8.37.0': - resolution: {integrity: sha512-zuWDMDuzMRbQOM+bHyU4/slw27bAUEcKSKKs3hcv2aNnc/tvE/h7w60dwVw8vnal2Pub6RT1T7BI8tFZ1fE+yg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <5.9.0' - - '@typescript-eslint/utils@8.37.0': - resolution: {integrity: sha512-TSFvkIW6gGjN2p6zbXo20FzCABbyUAuq6tBvNRGsKdsSQ6a7rnV6ADfZ7f4iI3lIiXc4F4WWvtUfDw9CJ9pO5A==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' - - '@typescript-eslint/visitor-keys@8.37.0': - resolution: {integrity: sha512-YzfhzcTnZVPiLfP/oeKtDp2evwvHLMe0LOy7oe+hb9KKIumLNohYS9Hgp1ifwpu42YWxhZE8yieggz6JpqO/1w==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@vitest/expect@3.2.4': resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==} @@ -2038,16 +1398,6 @@ packages: abstract-logging@2.0.1: resolution: {integrity: sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==} - acorn-jsx@5.3.2: - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - - acorn@8.15.0: - resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} - engines: {node: '>=0.4.0'} - hasBin: true - ajv-formats@3.0.1: resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} peerDependencies: @@ -2056,9 +1406,6 @@ packages: ajv: optional: true - ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - ajv@8.17.1: resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} @@ -2066,8 +1413,8 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-regex@6.1.0: - resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} engines: {node: '>=12'} ansi-styles@3.2.1: @@ -2078,63 +1425,21 @@ packages: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} - ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} engines: {node: '>=12'} - antd@5.27.6: - resolution: {integrity: sha512-70HrjVbzDXvtiUQ5MP1XdNudr/wGAk9Ivaemk6f36yrAeJurJSmZ8KngOIilolLRHdGuNc6/Vk+4T1OZpSjpag==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - array-buffer-byte-length@1.0.2: - resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} - engines: {node: '>= 0.4'} - - array-includes@3.1.9: - resolution: {integrity: sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==} - engines: {node: '>= 0.4'} - - array.prototype.findlast@1.2.5: - resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} - engines: {node: '>= 0.4'} - - array.prototype.flat@1.3.3: - resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} - engines: {node: '>= 0.4'} - - array.prototype.flatmap@1.3.3: - resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} - engines: {node: '>= 0.4'} - - array.prototype.tosorted@1.1.4: - resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} - engines: {node: '>= 0.4'} - - arraybuffer.prototype.slice@1.0.4: - resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} - engines: {node: '>= 0.4'} - assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} - async-function@1.0.0: - resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} - engines: {node: '>= 0.4'} - atomic-sleep@1.0.0: resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} engines: {node: '>=8.0.0'} - available-typed-arrays@1.0.7: - resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} - engines: {node: '>= 0.4'} - avvio@9.1.0: resolution: {integrity: sha512-fYASnYi600CsH/j9EQov7lECAniYiBFiiAtBNuZYLA2leLe9qOvZzqYHFjtIj6gD2VMoMLP14834LFWvr4IfDw==} @@ -2196,25 +1501,10 @@ packages: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} - call-bind-apply-helpers@1.0.2: - resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} - engines: {node: '>= 0.4'} - - call-bind@1.0.8: - resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} - engines: {node: '>= 0.4'} - - call-bound@1.0.4: - resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} - engines: {node: '>= 0.4'} - callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - caniuse-lite@1.0.30001727: - resolution: {integrity: sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==} - cbor@10.0.10: resolution: {integrity: sha512-EirvzAg0G4okCsdTfTjLWHU+tToQ2V2ptO3577Vyy2GOTeVJad99uCIuDqdK7ppFRRcEuigyJY6TJ59wv5JpSg==} engines: {node: '>=20'} @@ -2245,9 +1535,6 @@ packages: citty@0.2.0: resolution: {integrity: sha512-8csy5IBFI2ex2hTVpaHN2j+LNE199AgiI7y4dMintrr8i0lQiFn+0AWMZrWdHKIgMOer65f8IThysYhoReqjWA==} - classnames@2.5.1: - resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==} - cli-cursor@3.1.0: resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} engines: {node: '>=8'} @@ -2256,9 +1543,6 @@ packages: resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} engines: {node: '>=6'} - client-only@0.0.1: - resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} - cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} @@ -2284,9 +1568,6 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - compute-scroll-into-view@3.1.1: - resolution: {integrity: sha512-VRhuHOLoKYOy4UbilLbUzbYg93XLjv2PncJC50EuTWPA3gaja1UjBsUP/D/9/juV3vQFr6XBEzn9KCAHdUvOHw==} - concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} @@ -2301,9 +1582,6 @@ packages: resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} engines: {node: '>=18'} - copy-to-clipboard@3.3.3: - resolution: {integrity: sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==} - cosmiconfig@9.0.0: resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} engines: {node: '>=14'} @@ -2323,27 +1601,6 @@ packages: crypto-js@4.2.0: resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} - csstype@3.1.3: - resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} - - csstype@3.2.3: - resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} - - data-view-buffer@1.0.2: - resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} - engines: {node: '>= 0.4'} - - data-view-byte-length@1.0.2: - resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} - engines: {node: '>= 0.4'} - - data-view-byte-offset@1.0.1: - resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} - engines: {node: '>= 0.4'} - - dayjs@1.11.18: - resolution: {integrity: sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA==} - debug@4.4.1: resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} engines: {node: '>=6.0'} @@ -2357,20 +1614,9 @@ packages: resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} engines: {node: '>=6'} - deep-is@0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - defaults@1.0.4: resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} - define-data-property@1.1.4: - resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} - engines: {node: '>= 0.4'} - - define-properties@1.2.1: - resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} - engines: {node: '>= 0.4'} - defu@6.1.4: resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} @@ -2385,26 +1631,14 @@ packages: destr@2.0.5: resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} - detect-libc@2.1.2: - resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} - engines: {node: '>=8'} - diff@3.5.1: resolution: {integrity: sha512-Z3u54A8qGyqFOSr2pk0ijYs8mOE9Qz8kTvtKeBI+upoG9j04Sq+oI7W8zAJiQybDcESET8/uIdHzs0p3k4fZlw==} engines: {node: '>=0.3.1'} - doctrine@2.1.0: - resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} - engines: {node: '>=0.10.0'} - dotenv-expand@12.0.3: resolution: {integrity: sha512-uc47g4b+4k/M/SeaW1y4OApx+mtLWl92l5LMPP0GNXctZqELk+YGgOPIIC5elYmUH4OuoK3JLhuRUYegeySiFA==} engines: {node: '>=12'} - dotenv@16.0.3: - resolution: {integrity: sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==} - engines: {node: '>=12'} - dotenv@16.6.1: resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} engines: {node: '>=12'} @@ -2413,14 +1647,10 @@ packages: resolution: {integrity: sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==} engines: {node: '>=12'} - dpdm@3.14.0: - resolution: {integrity: sha512-YJzsFSyEtj88q5eTELg3UWU7TVZkG1dpbF4JDQ3t1b07xuzXmdoGeSz9TKOke1mUuOpWlk4q+pBh+aHzD6GBTg==} + dpdm@3.15.1: + resolution: {integrity: sha512-qa+BsZAGU3BhhQ6/Fdpd9YYYa3gdF0zMY/vW5rAj/QLJQgPbTX25h7cOe12dfRZvU0/JJP/g5LRgB6lTaVwILw==} hasBin: true - dunder-proto@1.0.1: - resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} - engines: {node: '>= 0.4'} - eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} @@ -2444,41 +1674,9 @@ packages: error-ex@1.3.4: resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} - es-abstract@1.24.0: - resolution: {integrity: sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==} - engines: {node: '>= 0.4'} - - es-define-property@1.0.1: - resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} - engines: {node: '>= 0.4'} - - es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} - - es-iterator-helpers@1.2.1: - resolution: {integrity: sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==} - engines: {node: '>= 0.4'} - es-module-lexer@1.7.0: resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} - es-object-atoms@1.1.1: - resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} - engines: {node: '>= 0.4'} - - es-set-tostringtag@2.1.0: - resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} - engines: {node: '>= 0.4'} - - es-shim-unscopables@1.1.0: - resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} - engines: {node: '>= 0.4'} - - es-to-primitive@1.3.0: - resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} - engines: {node: '>= 0.4'} - esbuild@0.25.8: resolution: {integrity: sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q==} engines: {node: '>=18'} @@ -2492,83 +1690,9 @@ packages: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} - escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - - eslint-config-prettier@10.1.1: - resolution: {integrity: sha512-4EQQr6wXwS+ZJSzaR5ZCrYgLxqvUjdXctaEtBqHcbkW944B1NQyO4qpdHQbXBONfwxXdkAY81HH4+LUfrg+zPw==} - hasBin: true - peerDependencies: - eslint: '>=7.0.0' - - eslint-plugin-only-warn@1.1.0: - resolution: {integrity: sha512-2tktqUAT+Q3hCAU0iSf4xAN1k9zOpjK5WO8104mB0rT/dGhOa09582HN5HlbxNbPRZ0THV7nLGvzugcNOSjzfA==} - engines: {node: '>=6'} - - eslint-plugin-react-hooks@5.2.0: - resolution: {integrity: sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==} - engines: {node: '>=10'} - peerDependencies: - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 - - eslint-plugin-react@7.37.5: - resolution: {integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==} - engines: {node: '>=4'} - peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 - - eslint-plugin-turbo@2.5.0: - resolution: {integrity: sha512-qQk54MrUZv0gnpxV23sccTc+FL3UJ8q7vG7HmXuS2RP8gdjWDwI1CCJTJD8EdRIDjsMxF0xi0AKcMY0CwIlXVg==} - peerDependencies: - eslint: '>6.6.0' - turbo: '>2.0.0' - - eslint-scope@8.4.0: - resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - eslint-visitor-keys@3.4.3: - resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - eslint-visitor-keys@4.2.1: - resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - eslint@9.31.0: - resolution: {integrity: sha512-QldCVh/ztyKJJZLr4jXNUByx3gR+TDYZCRXEktiZoUR3PGy4qCmSbkxcIle8GEwGpb5JBZazlaJ/CxLidXdEbQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - hasBin: true - peerDependencies: - jiti: '*' - peerDependenciesMeta: - jiti: - optional: true - - espree@10.4.0: - resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - esquery@1.6.0: - resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} - engines: {node: '>=0.10'} - - esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} - - estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} - estree-walker@3.0.3: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} - esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} - expect-type@1.2.2: resolution: {integrity: sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==} engines: {node: '>=12.0.0'} @@ -2589,23 +1713,9 @@ packages: fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - fast-glob@3.3.1: - resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} - engines: {node: '>=8.6.0'} - - fast-glob@3.3.3: - resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} - engines: {node: '>=8.6.0'} - - fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - fast-json-stringify@6.2.0: resolution: {integrity: sha512-Eaf/KNIDwHkzfyeQFNfLXJnQ7cl1XQI3+zRqmPlvtkMigbXnAcasTrvJQmquBSxKfFGeRA6PFog8t+hFmpDoWw==} - fast-levenshtein@2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - fast-querystring@1.1.2: resolution: {integrity: sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==} @@ -2630,10 +1740,6 @@ packages: picomatch: optional: true - file-entry-cache@8.0.0: - resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} - engines: {node: '>=16.0.0'} - fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -2642,21 +1748,6 @@ packages: resolution: {integrity: sha512-5Ye4vHsypZRYtS01ob/iwHzGRUDELlsoCftI/OZFhcLs1M0tkGPcXldE80TAZC5yYuJMBPJQQ43UHlqbJWiX2w==} engines: {node: '>=20'} - find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} - - flat-cache@4.0.1: - resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} - engines: {node: '>=16'} - - flatted@3.3.3: - resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} - - for-each@0.3.5: - resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} - engines: {node: '>= 0.4'} - foreground-child@3.3.1: resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} engines: {node: '>=14'} @@ -2676,29 +1767,10 @@ packages: function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - function.prototype.name@1.1.8: - resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} - engines: {node: '>= 0.4'} - - functions-have-names@1.2.3: - resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} - get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} - get-intrinsic@1.3.0: - resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} - engines: {node: '>= 0.4'} - - get-proto@1.0.1: - resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} - engines: {node: '>= 0.4'} - - get-symbol-description@1.1.0: - resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} - engines: {node: '>= 0.4'} - get-tsconfig@4.10.1: resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==} @@ -2710,16 +1782,8 @@ packages: resolution: {integrity: sha512-/Iu4prUrydE3Pb3lCBMbcSNIf81tgGt0W1ZwknnyF62t3tHmtiJTRj0f+1ZIhp3+Rh0ktz1pJVoa7ZXUCskivA==} engines: {node: '>= 4.8.0'} - glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} - - glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} - - glob@10.4.5: - resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + glob@10.5.0: + resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me hasBin: true @@ -2727,32 +1791,9 @@ packages: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me - globals@14.0.0: - resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} - engines: {node: '>=18'} - - globals@16.3.0: - resolution: {integrity: sha512-bqWEnJ1Nt3neqx2q5SFfGS8r/ahumIakg3HcwtNlrVlwXIeNumWn/c7Pn/wKzGhf6SaW6H6uWXLqC30STCMchQ==} - engines: {node: '>=18'} - - globalthis@1.0.4: - resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} - engines: {node: '>= 0.4'} - - gopd@1.2.0: - resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} - engines: {node: '>= 0.4'} - graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - graphemer@1.4.0: - resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - - has-bigints@1.1.0: - resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} - engines: {node: '>= 0.4'} - has-flag@3.0.0: resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} engines: {node: '>=4'} @@ -2761,44 +1802,21 @@ packages: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} - has-property-descriptors@1.0.2: - resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} - - has-proto@1.2.0: - resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} - engines: {node: '>= 0.4'} - - has-symbols@1.1.0: - resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} - engines: {node: '>= 0.4'} - - has-tostringtag@1.0.2: - resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} - engines: {node: '>= 0.4'} - hasown@2.0.2: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} + helmet@8.1.0: + resolution: {integrity: sha512-jOiHyAZsmnr8LqoPGmCjYAaiuWwjAPLgY8ZX2XrmHawt99/u1y6RgrZMTeoPfpUbV96HOalYgz1qzkRbw54Pmg==} + engines: {node: '>=18.0.0'} + ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - ignore@5.3.2: - resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} - engines: {node: '>= 4'} - - ignore@7.0.5: - resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} - engines: {node: '>= 4'} - import-fresh@3.3.1: resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} engines: {node: '>=6'} - imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - inflight@1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. @@ -2806,10 +1824,6 @@ packages: inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - internal-slot@1.1.0: - resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} - engines: {node: '>= 0.4'} - interpret@1.4.0: resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==} engines: {node: '>= 0.10'} @@ -2822,124 +1836,29 @@ packages: resolution: {integrity: sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==} engines: {node: '>= 10'} - is-array-buffer@3.0.5: - resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} - engines: {node: '>= 0.4'} - is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - is-async-function@2.1.1: - resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} - engines: {node: '>= 0.4'} - - is-bigint@1.1.0: - resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} - engines: {node: '>= 0.4'} - - is-boolean-object@1.2.2: - resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} - engines: {node: '>= 0.4'} - - is-callable@1.2.7: - resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} - engines: {node: '>= 0.4'} - is-core-module@2.16.1: resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} engines: {node: '>= 0.4'} - is-data-view@1.0.2: - resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} - engines: {node: '>= 0.4'} - - is-date-object@1.1.0: - resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} - engines: {node: '>= 0.4'} - - is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - - is-finalizationregistry@1.1.1: - resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} - engines: {node: '>= 0.4'} - is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} - is-generator-function@1.1.0: - resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} - engines: {node: '>= 0.4'} - - is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - is-interactive@1.0.0: resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} engines: {node: '>=8'} - is-map@2.0.3: - resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} - engines: {node: '>= 0.4'} - - is-negative-zero@2.0.3: - resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} - engines: {node: '>= 0.4'} - - is-number-object@1.1.1: - resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} - engines: {node: '>= 0.4'} - is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} - is-regex@1.2.1: - resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} - engines: {node: '>= 0.4'} - - is-set@2.0.3: - resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} - engines: {node: '>= 0.4'} - - is-shared-array-buffer@1.0.4: - resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} - engines: {node: '>= 0.4'} - - is-string@1.1.1: - resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} - engines: {node: '>= 0.4'} - - is-symbol@1.1.1: - resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} - engines: {node: '>= 0.4'} - - is-typed-array@1.1.15: - resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} - engines: {node: '>= 0.4'} - is-unicode-supported@0.1.0: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} - is-weakmap@2.0.2: - resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} - engines: {node: '>= 0.4'} - - is-weakref@1.1.1: - resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} - engines: {node: '>= 0.4'} - - is-weakset@2.0.4: - resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} - engines: {node: '>= 0.4'} - - isarray@2.0.5: - resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} - isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} @@ -2948,10 +1867,6 @@ packages: peerDependencies: ws: '*' - iterator.prototype@1.1.5: - resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} - engines: {node: '>= 0.4'} - jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} @@ -2959,24 +1874,6 @@ packages: resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true - jotai@2.15.1: - resolution: {integrity: sha512-yHT1HAZ3ba2Q8wgaUQ+xfBzEtcS8ie687I8XVCBinfg4bNniyqLIN+utPXWKQE93LMF5fPbQSVRZqgpcN5yd6Q==} - engines: {node: '>=12.20.0'} - peerDependencies: - '@babel/core': '>=7.0.0' - '@babel/template': '>=7.0.0' - '@types/react': '>=17.0.0' - react: '>=17.0.0' - peerDependenciesMeta: - '@babel/core': - optional: true - '@babel/template': - optional: true - '@types/react': - optional: true - react: - optional: true - js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -2990,37 +1887,18 @@ packages: json-bigint@1.0.0: resolution: {integrity: sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==} - json-buffer@3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} json-schema-ref-resolver@3.0.0: resolution: {integrity: sha512-hOrZIVL5jyYFjzk7+y7n5JDzGlU8rfWDuYyHwGa2WA8/pcmMHezp2xsVwxrebD/Q9t8Nc5DboieySDpCp4WG4A==} - json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - json-schema-traverse@1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} - json-stable-stringify-without-jsonify@1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - - json2mq@0.2.0: - resolution: {integrity: sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA==} - jsonfile@6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} - jsx-ast-utils@3.3.5: - resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} - engines: {node: '>=4.0'} - - keyv@4.5.4: - resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} - kysely-codegen@0.19.0: resolution: {integrity: sha512-ZpdQQnpfY0kh45CA6yPA9vdFsBE+b06Fx7QVcbL5rX//yjbA0yYGZGhnH7GTd4P4BY/HIv5uAfuOD83JVZf95w==} engines: {node: '>=20.0.0'} @@ -3073,35 +1951,24 @@ packages: kysely-prisma-postgres: optional: true - kysely@0.28.11: - resolution: {integrity: sha512-zpGIFg0HuoC893rIjYX1BETkVWdDnzTzF5e0kWXJFg5lE0k1/LfNWBejrcnOFu8Q2Rfq/hTDTU7XLUM8QOrpzg==} + kysely@0.28.14: + resolution: {integrity: sha512-SU3lgh0rPvq7upc6vvdVrCsSMUG1h3ChvHVOY7wJ2fw4C9QEB7X3d5eyYEyULUX7UQtxZJtZXGuT6U2US72UYA==} engines: {node: '>=20.0.0'} - levn@0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} - light-my-request@6.6.0: resolution: {integrity: sha512-CHYbu8RtboSIoVsHZ6Ye4cj4Aw/yg2oAFimlF7mNvfDV192LR7nDiKtSIfCuLT7KokPSTn/9kfVLm5OGN0A28A==} lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} - lodash.defaults@4.2.0: resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==} lodash.isarguments@3.1.0: resolution: {integrity: sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==} - lodash.merge@4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - - lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + lodash@4.17.23: + resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==} log-symbols@4.1.0: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} @@ -3111,10 +1978,6 @@ packages: resolution: {integrity: sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==} engines: {node: '>= 0.6.0'} - loose-envify@1.4.0: - resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} - hasBin: true - loupe@3.2.0: resolution: {integrity: sha512-2NCfZcT5VGVNX9mSZIxLRkEAegDGBpuQZBy13desuHeVORmBDyAET4TkJr4SjqQy3A8JDofMN6LpkK8Xcm/dlw==} @@ -3124,14 +1987,6 @@ packages: magic-string@0.30.17: resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} - math-intrinsics@1.1.0: - resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} - engines: {node: '>= 0.4'} - - merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - micromatch@4.0.8: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} @@ -3140,18 +1995,18 @@ packages: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} - minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} - minimatch@9.0.5: - resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + minimatch@9.0.9: + resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==} engines: {node: '>=16 || 14 >=14.17'} minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - minipass@7.1.2: - resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + minipass@7.1.3: + resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} engines: {node: '>=16 || 14 >=14.17'} mnemonist@0.40.0: @@ -3165,30 +2020,6 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - - next@16.0.10: - resolution: {integrity: sha512-RtWh5PUgI+vxlV3HdR+IfWA1UUHu0+Ram/JBO4vWB54cVPentCD0e+lxyAYEsDTqGGMg7qpjhKh6dc6aW7W/sA==} - engines: {node: '>=20.9.0'} - hasBin: true - peerDependencies: - '@opentelemetry/api': ^1.1.0 - '@playwright/test': ^1.51.1 - babel-plugin-react-compiler: '*' - react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 - react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 - sass: ^1.3.0 - peerDependenciesMeta: - '@opentelemetry/api': - optional: true - '@playwright/test': - optional: true - babel-plugin-react-compiler: - optional: true - sass: - optional: true - node-fetch-native@1.6.7: resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} @@ -3210,34 +2041,6 @@ packages: engines: {node: '>=18'} hasBin: true - object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} - - object-inspect@1.13.4: - resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} - engines: {node: '>= 0.4'} - - object-keys@1.1.1: - resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} - engines: {node: '>= 0.4'} - - object.assign@4.1.7: - resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} - engines: {node: '>= 0.4'} - - object.entries@1.1.9: - resolution: {integrity: sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==} - engines: {node: '>= 0.4'} - - object.fromentries@2.0.8: - resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} - engines: {node: '>= 0.4'} - - object.values@1.2.1: - resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} - engines: {node: '>= 0.4'} - obliterator@2.0.5: resolution: {integrity: sha512-42CPE9AhahZRsMNslczq0ctAEtqk8Eka26QofnqC346BZdHDySk3LWka23LI7ULIw11NmltpiLagIq8gBozxTw==} @@ -3258,26 +2061,10 @@ packages: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} - optionator@0.9.4: - resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} - engines: {node: '>= 0.8.0'} - ora@5.4.1: resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} engines: {node: '>=10'} - own-keys@1.0.1: - resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} - engines: {node: '>= 0.4'} - - p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} - - p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} - p-timeout@7.0.1: resolution: {integrity: sha512-AxTM2wDGORHGEkPCt8yqxOTMgpfbEHqF51f/5fJCmwFC3C/zNcGT63SymH2ttOAaiIws2zVg4+izQCjrakcwHg==} engines: {node: '>=20'} @@ -3293,10 +2080,6 @@ packages: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} - path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - path-is-absolute@1.0.1: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} engines: {node: '>=0.10.0'} @@ -3384,14 +2167,6 @@ packages: resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} engines: {node: '>=4'} - possible-typed-array-names@1.1.0: - resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} - engines: {node: '>= 0.4'} - - postcss@8.4.31: - resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} - engines: {node: ^10 || ^12 || >=14} - postcss@8.5.6: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} @@ -3412,278 +2187,21 @@ packages: resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} engines: {node: '>=0.10.0'} - prelude-ls@1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} - process-warning@4.0.1: resolution: {integrity: sha512-3c2LzQ3rY9d0hc1emcsHhfT9Jwz0cChib/QN89oME2R451w5fy3f0afAhERFZAwrbDU43wk12d0ORBpDVME50Q==} process-warning@5.0.0: resolution: {integrity: sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==} - prop-types@15.8.1: - resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} - - punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} - pure-rand@6.1.0: resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} - queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - quick-format-unescaped@4.0.4: resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} - rc-cascader@3.34.0: - resolution: {integrity: sha512-KpXypcvju9ptjW9FaN2NFcA2QH9E9LHKq169Y0eWtH4e/wHQ5Wh5qZakAgvb8EKZ736WZ3B0zLLOBsrsja5Dag==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-checkbox@3.5.0: - resolution: {integrity: sha512-aOAQc3E98HteIIsSqm6Xk2FPKIER6+5vyEFMZfo73TqM+VVAIqOkHoPjgKLqSNtVLWScoaM7vY2ZrGEheI79yg==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-collapse@3.9.0: - resolution: {integrity: sha512-swDdz4QZ4dFTo4RAUMLL50qP0EY62N2kvmk2We5xYdRwcRn8WcYtuetCJpwpaCbUfUt5+huLpVxhvmnK+PHrkA==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-dialog@9.6.0: - resolution: {integrity: sha512-ApoVi9Z8PaCQg6FsUzS8yvBEQy0ZL2PkuvAgrmohPkN3okps5WZ5WQWPc1RNuiOKaAYv8B97ACdsFU5LizzCqg==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-drawer@7.3.0: - resolution: {integrity: sha512-DX6CIgiBWNpJIMGFO8BAISFkxiuKitoizooj4BDyee8/SnBn0zwO2FHrNDpqqepj0E/TFTDpmEBCyFuTgC7MOg==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-dropdown@4.2.1: - resolution: {integrity: sha512-YDAlXsPv3I1n42dv1JpdM7wJ+gSUBfeyPK59ZpBD9jQhK9jVuxpjj3NmWQHOBceA1zEPVX84T2wbdb2SD0UjmA==} - peerDependencies: - react: '>=16.11.0' - react-dom: '>=16.11.0' - - rc-field-form@2.7.0: - resolution: {integrity: sha512-hgKsCay2taxzVnBPZl+1n4ZondsV78G++XVsMIJCAoioMjlMQR9YwAp7JZDIECzIu2Z66R+f4SFIRrO2DjDNAA==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-image@7.12.0: - resolution: {integrity: sha512-cZ3HTyyckPnNnUb9/DRqduqzLfrQRyi+CdHjdqgsyDpI3Ln5UX1kXnAhPBSJj9pVRzwRFgqkN7p9b6HBDjmu/Q==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-input-number@9.5.0: - resolution: {integrity: sha512-bKaEvB5tHebUURAEXw35LDcnRZLq3x1k7GxfAqBMzmpHkDGzjAtnUL8y4y5N15rIFIg5IJgwr211jInl3cipag==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-input@1.8.0: - resolution: {integrity: sha512-KXvaTbX+7ha8a/k+eg6SYRVERK0NddX8QX7a7AnRvUa/rEH0CNMlpcBzBkhI0wp2C8C4HlMoYl8TImSN+fuHKA==} - peerDependencies: - react: '>=16.0.0' - react-dom: '>=16.0.0' - - rc-mentions@2.20.0: - resolution: {integrity: sha512-w8HCMZEh3f0nR8ZEd466ATqmXFCMGMN5UFCzEUL0bM/nGw/wOS2GgRzKBcm19K++jDyuWCOJOdgcKGXU3fXfbQ==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-menu@9.16.1: - resolution: {integrity: sha512-ghHx6/6Dvp+fw8CJhDUHFHDJ84hJE3BXNCzSgLdmNiFErWSOaZNsihDAsKq9ByTALo/xkNIwtDFGIl6r+RPXBg==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-motion@2.9.5: - resolution: {integrity: sha512-w+XTUrfh7ArbYEd2582uDrEhmBHwK1ZENJiSJVb7uRxdE7qJSYjbO2eksRXmndqyKqKoYPc9ClpPh5242mV1vA==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-notification@5.6.4: - resolution: {integrity: sha512-KcS4O6B4qzM3KH7lkwOB7ooLPZ4b6J+VMmQgT51VZCeEcmghdeR4IrMcFq0LG+RPdnbe/ArT086tGM8Snimgiw==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-overflow@1.5.0: - resolution: {integrity: sha512-Lm/v9h0LymeUYJf0x39OveU52InkdRXqnn2aYXfWmo8WdOonIKB2kfau+GF0fWq6jPgtdO9yMqveGcK6aIhJmg==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-pagination@5.1.0: - resolution: {integrity: sha512-8416Yip/+eclTFdHXLKTxZvn70duYVGTvUUWbckCCZoIl3jagqke3GLsFrMs0bsQBikiYpZLD9206Ej4SOdOXQ==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-picker@4.11.3: - resolution: {integrity: sha512-MJ5teb7FlNE0NFHTncxXQ62Y5lytq6sh5nUw0iH8OkHL/TjARSEvSHpr940pWgjGANpjCwyMdvsEV55l5tYNSg==} - engines: {node: '>=8.x'} - peerDependencies: - date-fns: '>= 2.x' - dayjs: '>= 1.x' - luxon: '>= 3.x' - moment: '>= 2.x' - react: '>=16.9.0' - react-dom: '>=16.9.0' - peerDependenciesMeta: - date-fns: - optional: true - dayjs: - optional: true - luxon: - optional: true - moment: - optional: true - - rc-progress@4.0.0: - resolution: {integrity: sha512-oofVMMafOCokIUIBnZLNcOZFsABaUw8PPrf1/y0ZBvKZNpOiu5h4AO9vv11Sw0p4Hb3D0yGWuEattcQGtNJ/aw==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-rate@2.13.1: - resolution: {integrity: sha512-QUhQ9ivQ8Gy7mtMZPAjLbxBt5y9GRp65VcUyGUMF3N3fhiftivPHdpuDIaWIMOTEprAjZPC08bls1dQB+I1F2Q==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-resize-observer@1.4.3: - resolution: {integrity: sha512-YZLjUbyIWox8E9i9C3Tm7ia+W7euPItNWSPX5sCcQTYbnwDb5uNpnLHQCG1f22oZWUhLw4Mv2tFmeWe68CDQRQ==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-segmented@2.7.0: - resolution: {integrity: sha512-liijAjXz+KnTRVnxxXG2sYDGd6iLL7VpGGdR8gwoxAXy2KglviKCxLWZdjKYJzYzGSUwKDSTdYk8brj54Bn5BA==} - peerDependencies: - react: '>=16.0.0' - react-dom: '>=16.0.0' - - rc-select@14.16.8: - resolution: {integrity: sha512-NOV5BZa1wZrsdkKaiK7LHRuo5ZjZYMDxPP6/1+09+FB4KoNi8jcG1ZqLE3AVCxEsYMBe65OBx71wFoHRTP3LRg==} - engines: {node: '>=8.x'} - peerDependencies: - react: '*' - react-dom: '*' - - rc-slider@11.1.9: - resolution: {integrity: sha512-h8IknhzSh3FEM9u8ivkskh+Ef4Yo4JRIY2nj7MrH6GQmrwV6mcpJf5/4KgH5JaVI1H3E52yCdpOlVyGZIeph5A==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-steps@6.0.1: - resolution: {integrity: sha512-lKHL+Sny0SeHkQKKDJlAjV5oZ8DwCdS2hFhAkIjuQt1/pB81M0cA0ErVFdHq9+jmPmFw1vJB2F5NBzFXLJxV+g==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-switch@4.1.0: - resolution: {integrity: sha512-TI8ufP2Az9oEbvyCeVE4+90PDSljGyuwix3fV58p7HV2o4wBnVToEyomJRVyTaZeqNPAp+vqeo4Wnj5u0ZZQBg==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-table@7.54.0: - resolution: {integrity: sha512-/wDTkki6wBTjwylwAGjpLKYklKo9YgjZwAU77+7ME5mBoS32Q4nAwoqhA2lSge6fobLW3Tap6uc5xfwaL2p0Sw==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-tabs@15.7.0: - resolution: {integrity: sha512-ZepiE+6fmozYdWf/9gVp7k56PKHB1YYoDsKeQA1CBlJ/POIhjkcYiv0AGP0w2Jhzftd3AVvZP/K+V+Lpi2ankA==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-textarea@1.10.2: - resolution: {integrity: sha512-HfaeXiaSlpiSp0I/pvWpecFEHpVysZ9tpDLNkxQbMvMz6gsr7aVZ7FpWP9kt4t7DB+jJXesYS0us1uPZnlRnwQ==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-tooltip@6.4.0: - resolution: {integrity: sha512-kqyivim5cp8I5RkHmpsp1Nn/Wk+1oeloMv9c7LXNgDxUpGm+RbXJGL+OPvDlcRnx9DBeOe4wyOIl4OKUERyH1g==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-tree-select@5.27.0: - resolution: {integrity: sha512-2qTBTzwIT7LRI1o7zLyrCzmo5tQanmyGbSaGTIf7sYimCklAToVVfpMC6OAldSKolcnjorBYPNSKQqJmN3TCww==} - peerDependencies: - react: '*' - react-dom: '*' - - rc-tree@5.13.1: - resolution: {integrity: sha512-FNhIefhftobCdUJshO7M8uZTA9F4OPGVXqGfZkkD/5soDeOhwO06T/aKTrg0WD8gRg/pyfq+ql3aMymLHCTC4A==} - engines: {node: '>=10.x'} - peerDependencies: - react: '*' - react-dom: '*' - - rc-upload@4.9.2: - resolution: {integrity: sha512-nHx+9rbd1FKMiMRYsqQ3NkXUv7COHPBo3X1Obwq9SWS6/diF/A0aJ5OHubvwUAIDs+4RMleljV0pcrNUc823GQ==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-util@5.44.4: - resolution: {integrity: sha512-resueRJzmHG9Q6rI/DfK6Kdv9/Lfls05vzMs1Sk3M2P+3cJa+MakaZyWY8IPfehVuhPJFKrIY1IK4GqbiaiY5w==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-virtual-list@3.19.2: - resolution: {integrity: sha512-Ys6NcjwGkuwkeaWBDqfI3xWuZ7rDiQXlH1o2zLfFzATfEgXcqpk8CkgMfbJD81McqjcJVez25a3kPxCR807evA==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - rc9@2.1.2: resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==} - react-dom@19.2.3: - resolution: {integrity: sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==} - peerDependencies: - react: ^19.2.3 - - react-is@16.13.1: - resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} - - react-is@18.3.1: - resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} - - react@19.2.3: - resolution: {integrity: sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==} - engines: {node: '>=0.10.0'} - readable-stream@3.6.2: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} @@ -3708,14 +2226,6 @@ packages: resolution: {integrity: sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==} engines: {node: '>=4'} - reflect.getprototypeof@1.0.10: - resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} - engines: {node: '>= 0.4'} - - regexp.prototype.flags@1.5.4: - resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} - engines: {node: '>= 0.4'} - remeda@2.28.0: resolution: {integrity: sha512-943nIauNk4xBh/2DNcsZCc3DRpKncNXnNjtWlqfhM72FvD4bKuOXWSfuY0+k7yf8/Ob3+QzXtxLeobLoMn/INA==} @@ -3730,9 +2240,6 @@ packages: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} - resize-observer-polyfill@1.5.1: - resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==} - resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -3745,10 +2252,6 @@ packages: engines: {node: '>= 0.4'} hasBin: true - resolve@2.0.0-next.5: - resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} - hasBin: true - restore-cursor@3.1.0: resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} engines: {node: '>=8'} @@ -3764,29 +2267,14 @@ packages: rfdc@1.4.1: resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} - rollup@4.46.3: - resolution: {integrity: sha512-RZn2XTjXb8t5g13f5YclGoilU/kwT696DIkY3sywjdZidNSi3+vseaQov7D7BZXVJCPv3pDWUN69C78GGbXsKw==} + rollup@4.60.0: + resolution: {integrity: sha512-yqjxruMGBQJ2gG4HtjZtAfXArHomazDHoFwFFmZZl0r7Pdo7qCIXKqKHZc8yeoMgzJJ+pO6pEEHa+V7uzWlrAQ==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true - run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - - safe-array-concat@1.1.3: - resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} - engines: {node: '>=0.4'} - safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - safe-push-apply@1.0.0: - resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} - engines: {node: '>= 0.4'} - - safe-regex-test@1.1.0: - resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} - engines: {node: '>= 0.4'} - safe-regex2@5.0.0: resolution: {integrity: sha512-YwJwe5a51WlK7KbOJREPdjNrpViQBI3p4T50lfwPuDhZnE3XGVTlGvi+aolc5+RvxDD6bnUmjVsU9n1eboLUYw==} @@ -3794,24 +2282,9 @@ packages: resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} engines: {node: '>=10'} - scheduler@0.27.0: - resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} - - scroll-into-view-if-needed@3.1.0: - resolution: {integrity: sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==} - secure-json-parse@4.1.0: resolution: {integrity: sha512-l4KnYfEyqYJxDwlNVyRfO2E4NTHfMKAWdUuA8J0yve2Dz/E/PdBepY03RvyJpssIpRFwJoCD55wA+mEDs6ByWA==} - semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} - hasBin: true - - semver@7.7.2: - resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} - engines: {node: '>=10'} - hasBin: true - semver@7.7.3: resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} engines: {node: '>=10'} @@ -3820,25 +2293,9 @@ packages: set-cookie-parser@2.7.2: resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==} - set-function-length@1.2.2: - resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} - engines: {node: '>= 0.4'} - - set-function-name@2.0.2: - resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} - engines: {node: '>= 0.4'} - - set-proto@1.0.0: - resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} - engines: {node: '>= 0.4'} - sha3@2.1.4: resolution: {integrity: sha512-S8cNxbyb0UGUM2VhRD4Poe5N58gJnJsLJ5vC7FYWGUmGhcsj4++WaIOBFVDxlG0W3To6xBuiRh+i0Qp2oNCOtg==} - sharp@0.34.5: - resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -3856,22 +2313,6 @@ packages: engines: {node: '>=4'} hasBin: true - side-channel-list@1.0.0: - resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} - engines: {node: '>= 0.4'} - - side-channel-map@1.0.1: - resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} - engines: {node: '>= 0.4'} - - side-channel-weakmap@1.0.2: - resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} - engines: {node: '>= 0.4'} - - side-channel@1.1.0: - resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} - engines: {node: '>= 0.4'} - siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} @@ -3886,8 +2327,8 @@ packages: resolution: {integrity: sha512-uP0bpjWrjQmUt5DTHq9RuoCBdFJF10cdX9X+a368j/Ft0wmaVgxlrjvK3kjvgCODOMMOz9lcaRzxmso0bTWZ/g==} engines: {node: '>=10.0.0'} - socket.io-parser@4.2.5: - resolution: {integrity: sha512-bPMmpy/5WWKHea5Y/jYAP6k74A+hvmRCQaJuJB6I/ML5JZq/KfNieUVo/3Mh7SAqn7TyFdIo6wqYHInG1MU1bQ==} + socket.io-parser@4.2.6: + resolution: {integrity: sha512-asJqbVBDsBCJx0pTqw3WfesSY0iRX+2xzWEWzrpcH7L6fLzrhyF8WPI8UaeM4YCuDfpwA/cgsdugMsmtz8EJeg==} engines: {node: '>=10.0.0'} sonic-boom@4.2.0: @@ -3910,13 +2351,6 @@ packages: std-env@3.9.0: resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} - stop-iteration-iterator@1.1.0: - resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} - engines: {node: '>= 0.4'} - - string-convert@0.2.1: - resolution: {integrity: sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==} - string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -3925,25 +2359,6 @@ packages: resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} engines: {node: '>=12'} - string.prototype.matchall@4.0.12: - resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==} - engines: {node: '>= 0.4'} - - string.prototype.repeat@1.0.0: - resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==} - - string.prototype.trim@1.2.10: - resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} - engines: {node: '>= 0.4'} - - string.prototype.trimend@1.0.9: - resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} - engines: {node: '>= 0.4'} - - string.prototype.trimstart@1.0.8: - resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} - engines: {node: '>= 0.4'} - string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} @@ -3951,33 +2366,13 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} - strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} engines: {node: '>=12'} - strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - strip-literal@3.0.0: resolution: {integrity: sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==} - styled-jsx@5.1.6: - resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} - engines: {node: '>= 12.0.0'} - peerDependencies: - '@babel/core': '*' - babel-plugin-macros: '*' - react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0' - peerDependenciesMeta: - '@babel/core': - optional: true - babel-plugin-macros: - optional: true - - stylis@4.3.6: - resolution: {integrity: sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==} - supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} @@ -3994,10 +2389,6 @@ packages: resolution: {integrity: sha512-4iMVL6HAINXWf1ZKZjIPcz5wYaOdPhtO8ATvZ+Xqp3BTdaqtAwQkNmKORqcIo5YkQqGXq5cwfswDwMqqQNrpJA==} engines: {node: '>=20'} - throttle-debounce@5.0.2: - resolution: {integrity: sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==} - engines: {node: '>=12.22'} - tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} @@ -4032,18 +2423,9 @@ packages: resolution: {integrity: sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw==} engines: {node: '>=12'} - toggle-selection@1.0.6: - resolution: {integrity: sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==} - tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - ts-api-utils@2.1.0: - resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} - engines: {node: '>=18.12'} - peerDependencies: - typescript: '>=4.8.4' - ts-custom-error@3.3.1: resolution: {integrity: sha512-5OX1tzOjxWEgsr/YEUWSuPrQ00deKLh6D7OTWcvNHm12/7QPyRh8SYpyWvA4IZv8H/+GQWQEh/kwo95Q9OVW1A==} engines: {node: '>=14.0.0'} @@ -4100,37 +2482,10 @@ packages: resolution: {integrity: sha512-eZ7wI6KjtT1eBqCnh2JPXWNUAxtoxxfi6VdBdZFvil0ychCOTxbm7YLRBi1JSt7U3c+u3CLxpoPxLdvr/Npr3A==} hasBin: true - type-check@0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} - type-fest@4.41.0: resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} engines: {node: '>=16'} - typed-array-buffer@1.0.3: - resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} - engines: {node: '>= 0.4'} - - typed-array-byte-length@1.0.3: - resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} - engines: {node: '>= 0.4'} - - typed-array-byte-offset@1.0.4: - resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} - engines: {node: '>= 0.4'} - - typed-array-length@1.0.7: - resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} - engines: {node: '>= 0.4'} - - typescript-eslint@8.37.0: - resolution: {integrity: sha512-TnbEjzkE9EmcO0Q2zM+GE8NQLItNAJpMmED1BdgoBMYNdqMhzlbqfdSwiRlAzEK2pA9UzVW0gzaaIzXWg2BjfA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' - typescript@5.8.2: resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==} engines: {node: '>=14.17'} @@ -4144,10 +2499,6 @@ packages: ufo@1.6.3: resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} - unbox-primitive@1.1.0: - resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} - engines: {node: '>= 0.4'} - undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} @@ -4155,9 +2506,6 @@ packages: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} - uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} @@ -4243,22 +2591,6 @@ packages: whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} - which-boxed-primitive@1.1.1: - resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} - engines: {node: '>= 0.4'} - - which-builtin-type@1.2.1: - resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} - engines: {node: '>= 0.4'} - - which-collection@1.0.2: - resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} - engines: {node: '>= 0.4'} - - which-typed-array@1.1.19: - resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} - engines: {node: '>= 0.4'} - which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} @@ -4269,10 +2601,6 @@ packages: engines: {node: '>=8'} hasBin: true - word-wrap@1.2.5: - resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} - engines: {node: '>=0.10.0'} - wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} @@ -4328,72 +2656,11 @@ packages: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} - yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} - zod@4.3.6: resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} snapshots: - '@ant-design/colors@7.2.1': - dependencies: - '@ant-design/fast-color': 2.0.6 - - '@ant-design/cssinjs-utils@1.1.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@ant-design/cssinjs': 1.24.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@babel/runtime': 7.28.4 - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@ant-design/cssinjs@1.24.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@babel/runtime': 7.28.4 - '@emotion/hash': 0.8.0 - '@emotion/unitless': 0.7.5 - classnames: 2.5.1 - csstype: 3.1.3 - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - stylis: 4.3.6 - - '@ant-design/fast-color@2.0.6': - dependencies: - '@babel/runtime': 7.28.4 - - '@ant-design/icons-svg@4.4.2': {} - - '@ant-design/icons@5.6.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@ant-design/colors': 7.2.1 - '@ant-design/icons-svg': 4.4.2 - '@babel/runtime': 7.28.4 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@ant-design/nextjs-registry@1.1.0(@ant-design/cssinjs@1.24.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(antd@5.27.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(next@16.0.10(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@ant-design/cssinjs': 1.24.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - antd: 5.27.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - next: 16.0.10(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@ant-design/react-slick@1.1.2(react@19.2.3)': - dependencies: - '@babel/runtime': 7.28.4 - classnames: 2.5.1 - json2mq: 0.2.0 - react: 19.2.3 - resize-observer-polyfill: 1.5.1 - throttle-debounce: 5.0.2 - '@babel/code-frame@7.29.0': dependencies: '@babel/helper-validator-identifier': 7.28.5 @@ -4402,8 +2669,6 @@ snapshots: '@babel/helper-validator-identifier@7.28.5': {} - '@babel/runtime@7.28.4': {} - '@biomejs/biome@2.1.4': optionalDependencies: '@biomejs/cli-darwin-arm64': 2.1.4 @@ -4462,15 +2727,6 @@ snapshots: '@cardanosolutions/json-bigint@1.1.0': {} - '@emnapi/runtime@1.7.1': - dependencies: - tslib: 2.8.1 - optional: true - - '@emotion/hash@0.8.0': {} - - '@emotion/unitless@0.7.5': {} - '@emurgo/cardano-message-signing-nodejs@1.1.0': {} '@emurgo/cardano-serialization-lib-browser@13.2.1': {} @@ -4555,50 +2811,6 @@ snapshots: '@esbuild/win32-x64@0.25.8': optional: true - '@eslint-community/eslint-utils@4.7.0(eslint@9.31.0(jiti@2.6.1))': - dependencies: - eslint: 9.31.0(jiti@2.6.1) - eslint-visitor-keys: 3.4.3 - - '@eslint-community/regexpp@4.12.1': {} - - '@eslint/config-array@0.21.0': - dependencies: - '@eslint/object-schema': 2.1.6 - debug: 4.4.1 - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color - - '@eslint/config-helpers@0.3.0': {} - - '@eslint/core@0.15.1': - dependencies: - '@types/json-schema': 7.0.15 - - '@eslint/eslintrc@3.3.1': - dependencies: - ajv: 6.12.6 - debug: 4.4.1 - espree: 10.4.0 - globals: 14.0.0 - ignore: 5.3.2 - import-fresh: 3.3.1 - js-yaml: 4.1.0 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - - '@eslint/js@9.31.0': {} - - '@eslint/object-schema@2.1.6': {} - - '@eslint/plugin-kit@0.3.3': - dependencies: - '@eslint/core': 0.15.1 - levn: 0.4.1 - '@fastify/ajv-compiler@4.0.5': dependencies: ajv: 8.17.1 @@ -4618,6 +2830,11 @@ snapshots: '@fastify/forwarded@3.0.1': {} + '@fastify/helmet@13.0.2': + dependencies: + fastify-plugin: 5.1.0 + helmet: 8.1.0 + '@fastify/merge-json-schemas@0.2.1': dependencies: dequal: 2.0.3 @@ -4627,115 +2844,11 @@ snapshots: '@fastify/forwarded': 3.0.1 ipaddr.js: 2.3.0 - '@humanfs/core@0.19.1': {} - - '@humanfs/node@0.16.6': + '@fastify/rate-limit@10.3.0': dependencies: - '@humanfs/core': 0.19.1 - '@humanwhocodes/retry': 0.3.1 - - '@humanwhocodes/module-importer@1.0.1': {} - - '@humanwhocodes/retry@0.3.1': {} - - '@humanwhocodes/retry@0.4.3': {} - - '@img/colour@1.0.0': - optional: true - - '@img/sharp-darwin-arm64@0.34.5': - optionalDependencies: - '@img/sharp-libvips-darwin-arm64': 1.2.4 - optional: true - - '@img/sharp-darwin-x64@0.34.5': - optionalDependencies: - '@img/sharp-libvips-darwin-x64': 1.2.4 - optional: true - - '@img/sharp-libvips-darwin-arm64@1.2.4': - optional: true - - '@img/sharp-libvips-darwin-x64@1.2.4': - optional: true - - '@img/sharp-libvips-linux-arm64@1.2.4': - optional: true - - '@img/sharp-libvips-linux-arm@1.2.4': - optional: true - - '@img/sharp-libvips-linux-ppc64@1.2.4': - optional: true - - '@img/sharp-libvips-linux-riscv64@1.2.4': - optional: true - - '@img/sharp-libvips-linux-s390x@1.2.4': - optional: true - - '@img/sharp-libvips-linux-x64@1.2.4': - optional: true - - '@img/sharp-libvips-linuxmusl-arm64@1.2.4': - optional: true - - '@img/sharp-libvips-linuxmusl-x64@1.2.4': - optional: true - - '@img/sharp-linux-arm64@0.34.5': - optionalDependencies: - '@img/sharp-libvips-linux-arm64': 1.2.4 - optional: true - - '@img/sharp-linux-arm@0.34.5': - optionalDependencies: - '@img/sharp-libvips-linux-arm': 1.2.4 - optional: true - - '@img/sharp-linux-ppc64@0.34.5': - optionalDependencies: - '@img/sharp-libvips-linux-ppc64': 1.2.4 - optional: true - - '@img/sharp-linux-riscv64@0.34.5': - optionalDependencies: - '@img/sharp-libvips-linux-riscv64': 1.2.4 - optional: true - - '@img/sharp-linux-s390x@0.34.5': - optionalDependencies: - '@img/sharp-libvips-linux-s390x': 1.2.4 - optional: true - - '@img/sharp-linux-x64@0.34.5': - optionalDependencies: - '@img/sharp-libvips-linux-x64': 1.2.4 - optional: true - - '@img/sharp-linuxmusl-arm64@0.34.5': - optionalDependencies: - '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 - optional: true - - '@img/sharp-linuxmusl-x64@0.34.5': - optionalDependencies: - '@img/sharp-libvips-linuxmusl-x64': 1.2.4 - optional: true - - '@img/sharp-wasm32@0.34.5': - dependencies: - '@emnapi/runtime': 1.7.1 - optional: true - - '@img/sharp-win32-arm64@0.34.5': - optional: true - - '@img/sharp-win32-ia32@0.34.5': - optional: true - - '@img/sharp-win32-x64@0.34.5': - optional: true + '@lukeed/ms': 2.0.2 + fastify-plugin: 5.1.0 + toad-cache: 3.7.0 '@ioredis/commands@1.5.0': {} @@ -4743,194 +2856,101 @@ snapshots: dependencies: string-width: 5.1.2 string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.0 + strip-ansi: 7.2.0 strip-ansi-cjs: strip-ansi@6.0.1 wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 '@jridgewell/sourcemap-codec@1.5.5': {} + '@lukeed/ms@2.0.2': {} + '@minswap/cardano-serialization-lib-browser@11.1.0-minswap.33': {} '@minswap/cardano-serialization-lib-nodejs@11.1.0-minswap.33': {} '@minswap/tiny-invariant@1.2.0': {} - '@next/env@16.0.10': {} - - '@next/eslint-plugin-next@15.4.2': - dependencies: - fast-glob: 3.3.1 - - '@next/swc-darwin-arm64@16.0.10': - optional: true + '@noble/hashes@1.8.0': {} - '@next/swc-darwin-x64@16.0.10': - optional: true + '@pinojs/redact@0.4.0': {} - '@next/swc-linux-arm64-gnu@16.0.10': + '@pkgjs/parseargs@0.11.0': optional: true - '@next/swc-linux-arm64-musl@16.0.10': + '@rollup/rollup-android-arm-eabi@4.60.0': optional: true - '@next/swc-linux-x64-gnu@16.0.10': + '@rollup/rollup-android-arm64@4.60.0': optional: true - '@next/swc-linux-x64-musl@16.0.10': + '@rollup/rollup-darwin-arm64@4.60.0': optional: true - '@next/swc-win32-arm64-msvc@16.0.10': + '@rollup/rollup-darwin-x64@4.60.0': optional: true - '@next/swc-win32-x64-msvc@16.0.10': + '@rollup/rollup-freebsd-arm64@4.60.0': optional: true - '@noble/hashes@1.8.0': {} - - '@nodelib/fs.scandir@2.1.5': - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - - '@nodelib/fs.stat@2.0.5': {} - - '@nodelib/fs.walk@1.2.8': - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.19.1 - - '@pinojs/redact@0.4.0': {} - - '@pkgjs/parseargs@0.11.0': - optional: true - - '@rc-component/async-validator@5.0.4': - dependencies: - '@babel/runtime': 7.28.4 - - '@rc-component/color-picker@2.0.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@ant-design/fast-color': 2.0.6 - '@babel/runtime': 7.28.4 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@rc-component/context@1.4.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@babel/runtime': 7.28.4 - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@rc-component/mini-decimal@1.1.0': - dependencies: - '@babel/runtime': 7.28.4 - - '@rc-component/mutate-observer@1.1.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@babel/runtime': 7.28.4 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@rc-component/portal@1.1.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@babel/runtime': 7.28.4 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@rc-component/qrcode@1.0.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@babel/runtime': 7.28.4 - classnames: 2.5.1 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@rc-component/tour@1.15.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@babel/runtime': 7.28.4 - '@rc-component/portal': 1.1.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@rc-component/trigger': 2.3.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@rc-component/trigger@2.3.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@babel/runtime': 7.28.4 - '@rc-component/portal': 1.1.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - classnames: 2.5.1 - rc-motion: 2.9.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-resize-observer: 1.4.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - '@rollup/rollup-android-arm-eabi@4.46.3': + '@rollup/rollup-freebsd-x64@4.60.0': optional: true - '@rollup/rollup-android-arm64@4.46.3': + '@rollup/rollup-linux-arm-gnueabihf@4.60.0': optional: true - '@rollup/rollup-darwin-arm64@4.46.3': + '@rollup/rollup-linux-arm-musleabihf@4.60.0': optional: true - '@rollup/rollup-darwin-x64@4.46.3': + '@rollup/rollup-linux-arm64-gnu@4.60.0': optional: true - '@rollup/rollup-freebsd-arm64@4.46.3': + '@rollup/rollup-linux-arm64-musl@4.60.0': optional: true - '@rollup/rollup-freebsd-x64@4.46.3': + '@rollup/rollup-linux-loong64-gnu@4.60.0': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.46.3': + '@rollup/rollup-linux-loong64-musl@4.60.0': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.46.3': + '@rollup/rollup-linux-ppc64-gnu@4.60.0': optional: true - '@rollup/rollup-linux-arm64-gnu@4.46.3': + '@rollup/rollup-linux-ppc64-musl@4.60.0': optional: true - '@rollup/rollup-linux-arm64-musl@4.46.3': + '@rollup/rollup-linux-riscv64-gnu@4.60.0': optional: true - '@rollup/rollup-linux-loongarch64-gnu@4.46.3': + '@rollup/rollup-linux-riscv64-musl@4.60.0': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.46.3': + '@rollup/rollup-linux-s390x-gnu@4.60.0': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.46.3': + '@rollup/rollup-linux-x64-gnu@4.60.0': optional: true - '@rollup/rollup-linux-riscv64-musl@4.46.3': + '@rollup/rollup-linux-x64-musl@4.60.0': optional: true - '@rollup/rollup-linux-s390x-gnu@4.46.3': + '@rollup/rollup-openbsd-x64@4.60.0': optional: true - '@rollup/rollup-linux-x64-gnu@4.46.3': + '@rollup/rollup-openharmony-arm64@4.60.0': optional: true - '@rollup/rollup-linux-x64-musl@4.46.3': + '@rollup/rollup-win32-arm64-msvc@4.60.0': optional: true - '@rollup/rollup-win32-arm64-msvc@4.46.3': + '@rollup/rollup-win32-ia32-msvc@4.60.0': optional: true - '@rollup/rollup-win32-ia32-msvc@4.46.3': + '@rollup/rollup-win32-x64-gnu@4.60.0': optional: true - '@rollup/rollup-win32-x64-msvc@4.46.3': + '@rollup/rollup-win32-x64-msvc@4.60.0': optional: true '@sinclair/typebox@0.34.48': {} @@ -4955,11 +2975,7 @@ snapshots: blakejs: 1.2.1 bs58: 5.0.0 buffer: 6.0.3 - lodash: 4.17.21 - - '@swc/helpers@0.5.15': - dependencies: - tslib: 2.8.1 + lodash: 4.17.23 '@types/bun@1.3.8': dependencies: @@ -4977,8 +2993,6 @@ snapshots: '@types/json-bigint@1.0.4': {} - '@types/json-schema@7.0.15': {} - '@types/node@22.15.3': dependencies: undici-types: 6.21.0 @@ -4989,107 +3003,6 @@ snapshots: pg-protocol: 1.11.0 pg-types: 2.2.0 - '@types/react-dom@19.2.3(@types/react@19.2.7)': - dependencies: - '@types/react': 19.2.7 - - '@types/react@19.2.7': - dependencies: - csstype: 3.2.3 - - '@typescript-eslint/eslint-plugin@8.37.0(@typescript-eslint/parser@8.37.0(eslint@9.31.0(jiti@2.6.1))(typescript@5.8.2))(eslint@9.31.0(jiti@2.6.1))(typescript@5.8.2)': - dependencies: - '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.37.0(eslint@9.31.0(jiti@2.6.1))(typescript@5.8.2) - '@typescript-eslint/scope-manager': 8.37.0 - '@typescript-eslint/type-utils': 8.37.0(eslint@9.31.0(jiti@2.6.1))(typescript@5.8.2) - '@typescript-eslint/utils': 8.37.0(eslint@9.31.0(jiti@2.6.1))(typescript@5.8.2) - '@typescript-eslint/visitor-keys': 8.37.0 - eslint: 9.31.0(jiti@2.6.1) - graphemer: 1.4.0 - ignore: 7.0.5 - natural-compare: 1.4.0 - ts-api-utils: 2.1.0(typescript@5.8.2) - typescript: 5.8.2 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/parser@8.37.0(eslint@9.31.0(jiti@2.6.1))(typescript@5.8.2)': - dependencies: - '@typescript-eslint/scope-manager': 8.37.0 - '@typescript-eslint/types': 8.37.0 - '@typescript-eslint/typescript-estree': 8.37.0(typescript@5.8.2) - '@typescript-eslint/visitor-keys': 8.37.0 - debug: 4.4.1 - eslint: 9.31.0(jiti@2.6.1) - typescript: 5.8.2 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/project-service@8.37.0(typescript@5.8.2)': - dependencies: - '@typescript-eslint/tsconfig-utils': 8.37.0(typescript@5.8.2) - '@typescript-eslint/types': 8.37.0 - debug: 4.4.1 - typescript: 5.8.2 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/scope-manager@8.37.0': - dependencies: - '@typescript-eslint/types': 8.37.0 - '@typescript-eslint/visitor-keys': 8.37.0 - - '@typescript-eslint/tsconfig-utils@8.37.0(typescript@5.8.2)': - dependencies: - typescript: 5.8.2 - - '@typescript-eslint/type-utils@8.37.0(eslint@9.31.0(jiti@2.6.1))(typescript@5.8.2)': - dependencies: - '@typescript-eslint/types': 8.37.0 - '@typescript-eslint/typescript-estree': 8.37.0(typescript@5.8.2) - '@typescript-eslint/utils': 8.37.0(eslint@9.31.0(jiti@2.6.1))(typescript@5.8.2) - debug: 4.4.1 - eslint: 9.31.0(jiti@2.6.1) - ts-api-utils: 2.1.0(typescript@5.8.2) - typescript: 5.8.2 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/types@8.37.0': {} - - '@typescript-eslint/typescript-estree@8.37.0(typescript@5.8.2)': - dependencies: - '@typescript-eslint/project-service': 8.37.0(typescript@5.8.2) - '@typescript-eslint/tsconfig-utils': 8.37.0(typescript@5.8.2) - '@typescript-eslint/types': 8.37.0 - '@typescript-eslint/visitor-keys': 8.37.0 - debug: 4.4.1 - fast-glob: 3.3.3 - is-glob: 4.0.3 - minimatch: 9.0.5 - semver: 7.7.2 - ts-api-utils: 2.1.0(typescript@5.8.2) - typescript: 5.8.2 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/utils@8.37.0(eslint@9.31.0(jiti@2.6.1))(typescript@5.8.2)': - dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.31.0(jiti@2.6.1)) - '@typescript-eslint/scope-manager': 8.37.0 - '@typescript-eslint/types': 8.37.0 - '@typescript-eslint/typescript-estree': 8.37.0(typescript@5.8.2) - eslint: 9.31.0(jiti@2.6.1) - typescript: 5.8.2 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/visitor-keys@8.37.0': - dependencies: - '@typescript-eslint/types': 8.37.0 - eslint-visitor-keys: 4.2.1 - '@vitest/expect@3.2.4': dependencies: '@types/chai': 5.2.2 @@ -5134,23 +3047,10 @@ snapshots: abstract-logging@2.0.1: {} - acorn-jsx@5.3.2(acorn@8.15.0): - dependencies: - acorn: 8.15.0 - - acorn@8.15.0: {} - ajv-formats@3.0.1(ajv@8.17.1): optionalDependencies: ajv: 8.17.1 - ajv@6.12.6: - dependencies: - fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 - ajv@8.17.1: dependencies: fast-deep-equal: 3.1.3 @@ -5160,7 +3060,7 @@ snapshots: ansi-regex@5.0.1: {} - ansi-regex@6.1.0: {} + ansi-regex@6.2.2: {} ansi-styles@3.2.1: dependencies: @@ -5170,135 +3070,14 @@ snapshots: dependencies: color-convert: 2.0.1 - ansi-styles@6.2.1: {} - - antd@5.27.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@ant-design/colors': 7.2.1 - '@ant-design/cssinjs': 1.24.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@ant-design/cssinjs-utils': 1.1.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@ant-design/fast-color': 2.0.6 - '@ant-design/icons': 5.6.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@ant-design/react-slick': 1.1.2(react@19.2.3) - '@babel/runtime': 7.28.4 - '@rc-component/color-picker': 2.0.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@rc-component/mutate-observer': 1.1.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@rc-component/qrcode': 1.0.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@rc-component/tour': 1.15.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@rc-component/trigger': 2.3.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - classnames: 2.5.1 - copy-to-clipboard: 3.3.3 - dayjs: 1.11.18 - rc-cascader: 3.34.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-checkbox: 3.5.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-collapse: 3.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-dialog: 9.6.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-drawer: 7.3.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-dropdown: 4.2.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-field-form: 2.7.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-image: 7.12.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-input: 1.8.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-input-number: 9.5.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-mentions: 2.20.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-menu: 9.16.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-motion: 2.9.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-notification: 5.6.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-pagination: 5.1.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-picker: 4.11.3(dayjs@1.11.18)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-progress: 4.0.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-rate: 2.13.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-resize-observer: 1.4.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-segmented: 2.7.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-select: 14.16.8(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-slider: 11.1.9(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-steps: 6.0.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-switch: 4.1.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-table: 7.54.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-tabs: 15.7.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-textarea: 1.10.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-tooltip: 6.4.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-tree: 5.13.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-tree-select: 5.27.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-upload: 4.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - scroll-into-view-if-needed: 3.1.0 - throttle-debounce: 5.0.2 - transitivePeerDependencies: - - date-fns - - luxon - - moment + ansi-styles@6.2.3: {} argparse@2.0.1: {} - array-buffer-byte-length@1.0.2: - dependencies: - call-bound: 1.0.4 - is-array-buffer: 3.0.5 - - array-includes@3.1.9: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-object-atoms: 1.1.1 - get-intrinsic: 1.3.0 - is-string: 1.1.1 - math-intrinsics: 1.1.0 - - array.prototype.findlast@1.2.5: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - es-shim-unscopables: 1.1.0 - - array.prototype.flat@1.3.3: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-shim-unscopables: 1.1.0 - - array.prototype.flatmap@1.3.3: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-shim-unscopables: 1.1.0 - - array.prototype.tosorted@1.1.4: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-shim-unscopables: 1.1.0 - - arraybuffer.prototype.slice@1.0.4: - dependencies: - array-buffer-byte-length: 1.0.2 - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - is-array-buffer: 3.0.5 - assertion-error@2.0.1: {} - async-function@1.0.0: {} - atomic-sleep@1.0.0: {} - available-typed-arrays@1.0.7: - dependencies: - possible-typed-array-names: 1.1.0 - avvio@9.1.0: dependencies: '@fastify/error': 4.2.0 @@ -5374,27 +3153,8 @@ snapshots: cac@6.7.14: {} - call-bind-apply-helpers@1.0.2: - dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 - - call-bind@1.0.8: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-define-property: 1.0.1 - get-intrinsic: 1.3.0 - set-function-length: 1.2.2 - - call-bound@1.0.4: - dependencies: - call-bind-apply-helpers: 1.0.2 - get-intrinsic: 1.3.0 - callsites@3.1.0: {} - caniuse-lite@1.0.30001727: {} - cbor@10.0.10: dependencies: nofilter: 3.1.0 @@ -5430,16 +3190,12 @@ snapshots: citty@0.2.0: {} - classnames@2.5.1: {} - cli-cursor@3.1.0: dependencies: restore-cursor: 3.1.0 cli-spinners@2.9.2: {} - client-only@0.0.1: {} - cliui@8.0.1: dependencies: string-width: 4.2.3 @@ -5462,8 +3218,6 @@ snapshots: color-name@1.1.4: {} - compute-scroll-into-view@3.1.1: {} - concat-map@0.0.1: {} confbox@0.2.2: {} @@ -5472,10 +3226,6 @@ snapshots: cookie@1.1.1: {} - copy-to-clipboard@3.3.3: - dependencies: - toggle-selection: 1.0.6 - cosmiconfig@9.0.0(typescript@5.8.2): dependencies: env-paths: 2.2.1 @@ -5499,54 +3249,16 @@ snapshots: crypto-js@4.2.0: {} - csstype@3.1.3: {} - - csstype@3.2.3: {} - - data-view-buffer@1.0.2: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-data-view: 1.0.2 - - data-view-byte-length@1.0.2: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-data-view: 1.0.2 - - data-view-byte-offset@1.0.1: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-data-view: 1.0.2 - - dayjs@1.11.18: {} - debug@4.4.1: dependencies: ms: 2.1.3 deep-eql@5.0.2: {} - deep-is@0.1.4: {} - defaults@1.0.4: dependencies: clone: 1.0.4 - define-data-property@1.1.4: - dependencies: - es-define-property: 1.0.1 - es-errors: 1.3.0 - gopd: 1.2.0 - - define-properties@1.2.1: - dependencies: - define-data-property: 1.1.4 - has-property-descriptors: 1.0.2 - object-keys: 1.1.1 - defu@6.1.4: {} denque@2.1.0: {} @@ -5555,41 +3267,26 @@ snapshots: destr@2.0.5: {} - detect-libc@2.1.2: - optional: true - diff@3.5.1: {} - doctrine@2.1.0: - dependencies: - esutils: 2.0.3 - dotenv-expand@12.0.3: dependencies: dotenv: 16.6.1 - dotenv@16.0.3: {} - dotenv@16.6.1: {} dotenv@17.2.3: {} - dpdm@3.14.0: + dpdm@3.15.1: dependencies: chalk: 4.1.2 fs-extra: 11.3.1 - glob: 10.4.5 + glob: 10.5.0 ora: 5.4.1 tslib: 2.8.1 typescript: 5.8.3 yargs: 17.7.2 - dunder-proto@1.0.1: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-errors: 1.3.0 - gopd: 1.2.0 - eastasianwidth@0.2.0: {} emoji-regex@8.0.0: {} @@ -5616,109 +3313,8 @@ snapshots: dependencies: is-arrayish: 0.2.1 - es-abstract@1.24.0: - dependencies: - array-buffer-byte-length: 1.0.2 - arraybuffer.prototype.slice: 1.0.4 - available-typed-arrays: 1.0.7 - call-bind: 1.0.8 - call-bound: 1.0.4 - data-view-buffer: 1.0.2 - data-view-byte-length: 1.0.2 - data-view-byte-offset: 1.0.1 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - es-set-tostringtag: 2.1.0 - es-to-primitive: 1.3.0 - function.prototype.name: 1.1.8 - get-intrinsic: 1.3.0 - get-proto: 1.0.1 - get-symbol-description: 1.1.0 - globalthis: 1.0.4 - gopd: 1.2.0 - has-property-descriptors: 1.0.2 - has-proto: 1.2.0 - has-symbols: 1.1.0 - hasown: 2.0.2 - internal-slot: 1.1.0 - is-array-buffer: 3.0.5 - is-callable: 1.2.7 - is-data-view: 1.0.2 - is-negative-zero: 2.0.3 - is-regex: 1.2.1 - is-set: 2.0.3 - is-shared-array-buffer: 1.0.4 - is-string: 1.1.1 - is-typed-array: 1.1.15 - is-weakref: 1.1.1 - math-intrinsics: 1.1.0 - object-inspect: 1.13.4 - object-keys: 1.1.1 - object.assign: 4.1.7 - own-keys: 1.0.1 - regexp.prototype.flags: 1.5.4 - safe-array-concat: 1.1.3 - safe-push-apply: 1.0.0 - safe-regex-test: 1.1.0 - set-proto: 1.0.0 - stop-iteration-iterator: 1.1.0 - string.prototype.trim: 1.2.10 - string.prototype.trimend: 1.0.9 - string.prototype.trimstart: 1.0.8 - typed-array-buffer: 1.0.3 - typed-array-byte-length: 1.0.3 - typed-array-byte-offset: 1.0.4 - typed-array-length: 1.0.7 - unbox-primitive: 1.1.0 - which-typed-array: 1.1.19 - - es-define-property@1.0.1: {} - - es-errors@1.3.0: {} - - es-iterator-helpers@1.2.1: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-set-tostringtag: 2.1.0 - function-bind: 1.1.2 - get-intrinsic: 1.3.0 - globalthis: 1.0.4 - gopd: 1.2.0 - has-property-descriptors: 1.0.2 - has-proto: 1.2.0 - has-symbols: 1.1.0 - internal-slot: 1.1.0 - iterator.prototype: 1.1.5 - safe-array-concat: 1.1.3 - es-module-lexer@1.7.0: {} - es-object-atoms@1.1.1: - dependencies: - es-errors: 1.3.0 - - es-set-tostringtag@2.1.0: - dependencies: - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - has-tostringtag: 1.0.2 - hasown: 2.0.2 - - es-shim-unscopables@1.1.0: - dependencies: - hasown: 2.0.2 - - es-to-primitive@1.3.0: - dependencies: - is-callable: 1.2.7 - is-date-object: 1.1.0 - is-symbol: 1.1.1 - esbuild@0.25.8: optionalDependencies: '@esbuild/aix-ppc64': 0.25.8 @@ -5744,127 +3340,18 @@ snapshots: '@esbuild/openbsd-x64': 0.25.8 '@esbuild/openharmony-arm64': 0.25.8 '@esbuild/sunos-x64': 0.25.8 - '@esbuild/win32-arm64': 0.25.8 - '@esbuild/win32-ia32': 0.25.8 - '@esbuild/win32-x64': 0.25.8 - - escalade@3.2.0: {} - - escape-string-regexp@1.0.5: {} - - escape-string-regexp@4.0.0: {} - - eslint-config-prettier@10.1.1(eslint@9.31.0(jiti@2.6.1)): - dependencies: - eslint: 9.31.0(jiti@2.6.1) - - eslint-plugin-only-warn@1.1.0: {} - - eslint-plugin-react-hooks@5.2.0(eslint@9.31.0(jiti@2.6.1)): - dependencies: - eslint: 9.31.0(jiti@2.6.1) - - eslint-plugin-react@7.37.5(eslint@9.31.0(jiti@2.6.1)): - dependencies: - array-includes: 3.1.9 - array.prototype.findlast: 1.2.5 - array.prototype.flatmap: 1.3.3 - array.prototype.tosorted: 1.1.4 - doctrine: 2.1.0 - es-iterator-helpers: 1.2.1 - eslint: 9.31.0(jiti@2.6.1) - estraverse: 5.3.0 - hasown: 2.0.2 - jsx-ast-utils: 3.3.5 - minimatch: 3.1.2 - object.entries: 1.1.9 - object.fromentries: 2.0.8 - object.values: 1.2.1 - prop-types: 15.8.1 - resolve: 2.0.0-next.5 - semver: 6.3.1 - string.prototype.matchall: 4.0.12 - string.prototype.repeat: 1.0.0 - - eslint-plugin-turbo@2.5.0(eslint@9.31.0(jiti@2.6.1))(turbo@2.5.5): - dependencies: - dotenv: 16.0.3 - eslint: 9.31.0(jiti@2.6.1) - turbo: 2.5.5 - - eslint-scope@8.4.0: - dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 - - eslint-visitor-keys@3.4.3: {} - - eslint-visitor-keys@4.2.1: {} - - eslint@9.31.0(jiti@2.6.1): - dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.31.0(jiti@2.6.1)) - '@eslint-community/regexpp': 4.12.1 - '@eslint/config-array': 0.21.0 - '@eslint/config-helpers': 0.3.0 - '@eslint/core': 0.15.1 - '@eslint/eslintrc': 3.3.1 - '@eslint/js': 9.31.0 - '@eslint/plugin-kit': 0.3.3 - '@humanfs/node': 0.16.6 - '@humanwhocodes/module-importer': 1.0.1 - '@humanwhocodes/retry': 0.4.3 - '@types/estree': 1.0.8 - '@types/json-schema': 7.0.15 - ajv: 6.12.6 - chalk: 4.1.2 - cross-spawn: 7.0.6 - debug: 4.4.1 - escape-string-regexp: 4.0.0 - eslint-scope: 8.4.0 - eslint-visitor-keys: 4.2.1 - espree: 10.4.0 - esquery: 1.6.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 8.0.0 - find-up: 5.0.0 - glob-parent: 6.0.2 - ignore: 5.3.2 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - json-stable-stringify-without-jsonify: 1.0.1 - lodash.merge: 4.6.2 - minimatch: 3.1.2 - natural-compare: 1.4.0 - optionator: 0.9.4 - optionalDependencies: - jiti: 2.6.1 - transitivePeerDependencies: - - supports-color - - espree@10.4.0: - dependencies: - acorn: 8.15.0 - acorn-jsx: 5.3.2(acorn@8.15.0) - eslint-visitor-keys: 4.2.1 - - esquery@1.6.0: - dependencies: - estraverse: 5.3.0 + '@esbuild/win32-arm64': 0.25.8 + '@esbuild/win32-ia32': 0.25.8 + '@esbuild/win32-x64': 0.25.8 - esrecurse@4.3.0: - dependencies: - estraverse: 5.3.0 + escalade@3.2.0: {} - estraverse@5.3.0: {} + escape-string-regexp@1.0.5: {} estree-walker@3.0.3: dependencies: '@types/estree': 1.0.8 - esutils@2.0.3: {} - expect-type@1.2.2: {} exponential-backoff@3.1.3: {} @@ -5879,24 +3366,6 @@ snapshots: fast-deep-equal@3.1.3: {} - fast-glob@3.3.1: - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.8 - - fast-glob@3.3.3: - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.8 - - fast-json-stable-stringify@2.1.0: {} - fast-json-stringify@6.2.0: dependencies: '@fastify/merge-json-schemas': 0.2.1 @@ -5906,8 +3375,6 @@ snapshots: json-schema-ref-resolver: 3.0.0 rfdc: 1.4.1 - fast-levenshtein@2.0.6: {} - fast-querystring@1.1.2: dependencies: fast-decode-uri-component: 1.0.1 @@ -5942,10 +3409,6 @@ snapshots: optionalDependencies: picomatch: 4.0.3 - file-entry-cache@8.0.0: - dependencies: - flat-cache: 4.0.1 - fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -5956,22 +3419,6 @@ snapshots: fast-querystring: 1.1.2 safe-regex2: 5.0.0 - find-up@5.0.0: - dependencies: - locate-path: 6.0.0 - path-exists: 4.0.0 - - flat-cache@4.0.1: - dependencies: - flatted: 3.3.3 - keyv: 4.5.4 - - flatted@3.3.3: {} - - for-each@0.3.5: - dependencies: - is-callable: 1.2.7 - foreground-child@3.3.1: dependencies: cross-spawn: 7.0.6 @@ -5990,43 +3437,8 @@ snapshots: function-bind@1.1.2: {} - function.prototype.name@1.1.8: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - functions-have-names: 1.2.3 - hasown: 2.0.2 - is-callable: 1.2.7 - - functions-have-names@1.2.3: {} - get-caller-file@2.0.5: {} - get-intrinsic@1.3.0: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - function-bind: 1.1.2 - get-proto: 1.0.1 - gopd: 1.2.0 - has-symbols: 1.1.0 - hasown: 2.0.2 - math-intrinsics: 1.1.0 - - get-proto@1.0.1: - dependencies: - dunder-proto: 1.0.1 - es-object-atoms: 1.1.1 - - get-symbol-description@1.1.0: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - get-tsconfig@4.10.1: dependencies: resolve-pkg-maps: 1.0.0 @@ -6048,20 +3460,12 @@ snapshots: shelljs: 0.8.5 shelljs.exec: 1.1.8 - glob-parent@5.1.2: - dependencies: - is-glob: 4.0.3 - - glob-parent@6.0.2: - dependencies: - is-glob: 4.0.3 - - glob@10.4.5: + glob@10.5.0: dependencies: foreground-child: 3.3.1 jackspeak: 3.4.3 - minimatch: 9.0.5 - minipass: 7.1.2 + minimatch: 9.0.9 + minipass: 7.1.3 package-json-from-dist: 1.0.1 path-scurry: 1.11.1 @@ -6070,62 +3474,29 @@ snapshots: fs.realpath: 1.0.0 inflight: 1.0.6 inherits: 2.0.4 - minimatch: 3.1.2 + minimatch: 3.1.5 once: 1.4.0 path-is-absolute: 1.0.1 - globals@14.0.0: {} - - globals@16.3.0: {} - - globalthis@1.0.4: - dependencies: - define-properties: 1.2.1 - gopd: 1.2.0 - - gopd@1.2.0: {} - graceful-fs@4.2.11: {} - graphemer@1.4.0: {} - - has-bigints@1.1.0: {} - has-flag@3.0.0: {} has-flag@4.0.0: {} - has-property-descriptors@1.0.2: - dependencies: - es-define-property: 1.0.1 - - has-proto@1.2.0: - dependencies: - dunder-proto: 1.0.1 - - has-symbols@1.1.0: {} - - has-tostringtag@1.0.2: - dependencies: - has-symbols: 1.1.0 - hasown@2.0.2: dependencies: function-bind: 1.1.2 - ieee754@1.2.1: {} - - ignore@5.3.2: {} + helmet@8.1.0: {} - ignore@7.0.5: {} + ieee754@1.2.1: {} import-fresh@3.3.1: dependencies: parent-module: 1.0.1 resolve-from: 4.0.0 - imurmurhash@0.1.4: {} - inflight@1.0.6: dependencies: once: 1.4.0 @@ -6133,12 +3504,6 @@ snapshots: inherits@2.0.4: {} - internal-slot@1.1.0: - dependencies: - es-errors: 1.3.0 - hasown: 2.0.2 - side-channel: 1.1.0 - interpret@1.4.0: {} ioredis@5.9.2: @@ -6157,138 +3522,26 @@ snapshots: ipaddr.js@2.3.0: {} - is-array-buffer@3.0.5: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - get-intrinsic: 1.3.0 - is-arrayish@0.2.1: {} - is-async-function@2.1.1: - dependencies: - async-function: 1.0.0 - call-bound: 1.0.4 - get-proto: 1.0.1 - has-tostringtag: 1.0.2 - safe-regex-test: 1.1.0 - - is-bigint@1.1.0: - dependencies: - has-bigints: 1.1.0 - - is-boolean-object@1.2.2: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 - - is-callable@1.2.7: {} - is-core-module@2.16.1: dependencies: hasown: 2.0.2 - is-data-view@1.0.2: - dependencies: - call-bound: 1.0.4 - get-intrinsic: 1.3.0 - is-typed-array: 1.1.15 - - is-date-object@1.1.0: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 - - is-extglob@2.1.1: {} - - is-finalizationregistry@1.1.1: - dependencies: - call-bound: 1.0.4 - is-fullwidth-code-point@3.0.0: {} - is-generator-function@1.1.0: - dependencies: - call-bound: 1.0.4 - get-proto: 1.0.1 - has-tostringtag: 1.0.2 - safe-regex-test: 1.1.0 - - is-glob@4.0.3: - dependencies: - is-extglob: 2.1.1 - is-interactive@1.0.0: {} - is-map@2.0.3: {} - - is-negative-zero@2.0.3: {} - - is-number-object@1.1.1: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 - is-number@7.0.0: {} - is-regex@1.2.1: - dependencies: - call-bound: 1.0.4 - gopd: 1.2.0 - has-tostringtag: 1.0.2 - hasown: 2.0.2 - - is-set@2.0.3: {} - - is-shared-array-buffer@1.0.4: - dependencies: - call-bound: 1.0.4 - - is-string@1.1.1: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 - - is-symbol@1.1.1: - dependencies: - call-bound: 1.0.4 - has-symbols: 1.1.0 - safe-regex-test: 1.1.0 - - is-typed-array@1.1.15: - dependencies: - which-typed-array: 1.1.19 - is-unicode-supported@0.1.0: {} - is-weakmap@2.0.2: {} - - is-weakref@1.1.1: - dependencies: - call-bound: 1.0.4 - - is-weakset@2.0.4: - dependencies: - call-bound: 1.0.4 - get-intrinsic: 1.3.0 - - isarray@2.0.5: {} - isexe@2.0.0: {} isomorphic-ws@4.0.1(ws@7.5.10): dependencies: ws: 7.5.10 - iterator.prototype@1.1.5: - dependencies: - define-data-property: 1.1.4 - es-object-atoms: 1.1.1 - get-intrinsic: 1.3.0 - get-proto: 1.0.1 - has-symbols: 1.1.0 - set-function-name: 2.0.2 - jackspeak@3.4.3: dependencies: '@isaacs/cliui': 8.0.2 @@ -6297,11 +3550,6 @@ snapshots: jiti@2.6.1: {} - jotai@2.15.1(@types/react@19.2.7)(react@19.2.3): - optionalDependencies: - '@types/react': 19.2.7 - react: 19.2.3 - js-tokens@4.0.0: {} js-tokens@9.0.1: {} @@ -6314,49 +3562,28 @@ snapshots: dependencies: bignumber.js: 9.3.1 - json-buffer@3.0.1: {} - json-parse-even-better-errors@2.3.1: {} json-schema-ref-resolver@3.0.0: dependencies: dequal: 2.0.3 - json-schema-traverse@0.4.1: {} - json-schema-traverse@1.0.0: {} - json-stable-stringify-without-jsonify@1.0.1: {} - - json2mq@0.2.0: - dependencies: - string-convert: 0.2.1 - jsonfile@6.1.0: dependencies: universalify: 2.0.1 optionalDependencies: graceful-fs: 4.2.11 - jsx-ast-utils@3.3.5: - dependencies: - array-includes: 3.1.9 - array.prototype.flat: 1.3.3 - object.assign: 4.1.7 - object.values: 1.2.1 - - keyv@4.5.4: - dependencies: - json-buffer: 3.0.1 - - kysely-codegen@0.19.0(kysely@0.28.11)(pg@8.18.0)(typescript@5.8.2): + kysely-codegen@0.19.0(kysely@0.28.14)(pg@8.18.0)(typescript@5.8.2): dependencies: chalk: 4.1.2 cosmiconfig: 9.0.0(typescript@5.8.2) dotenv: 17.2.3 dotenv-expand: 12.0.3 git-diff: 2.0.6 - kysely: 0.28.11 + kysely: 0.28.14 micromatch: 4.0.8 minimist: 1.2.8 pluralize: 8.0.0 @@ -6366,14 +3593,14 @@ snapshots: transitivePeerDependencies: - typescript - kysely-ctl@0.19.0(kysely@0.28.11)(typescript@5.8.2): + kysely-ctl@0.19.0(kysely@0.28.14)(typescript@5.8.2): dependencies: c12: 3.3.3 citty: 0.1.6 confbox: 0.2.2 consola: 3.4.2 jiti: 2.6.1 - kysely: 0.28.11 + kysely: 0.28.14 nypm: 0.6.4 ofetch: 1.5.1 pathe: 2.0.3 @@ -6384,12 +3611,7 @@ snapshots: - magicast - typescript - kysely@0.28.11: {} - - levn@0.4.1: - dependencies: - prelude-ls: 1.2.1 - type-check: 0.4.0 + kysely@0.28.14: {} light-my-request@6.6.0: dependencies: @@ -6399,17 +3621,11 @@ snapshots: lines-and-columns@1.2.4: {} - locate-path@6.0.0: - dependencies: - p-locate: 5.0.0 - lodash.defaults@4.2.0: {} lodash.isarguments@3.1.0: {} - lodash.merge@4.6.2: {} - - lodash@4.17.21: {} + lodash@4.17.23: {} log-symbols@4.1.0: dependencies: @@ -6418,10 +3634,6 @@ snapshots: loglevel@1.9.2: {} - loose-envify@1.4.0: - dependencies: - js-tokens: 4.0.0 - loupe@3.2.0: {} lru-cache@10.4.3: {} @@ -6430,10 +3642,6 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 - math-intrinsics@1.1.0: {} - - merge2@1.4.1: {} - micromatch@4.0.8: dependencies: braces: 3.0.3 @@ -6441,17 +3649,17 @@ snapshots: mimic-fn@2.1.0: {} - minimatch@3.1.2: + minimatch@3.1.5: dependencies: brace-expansion: 1.1.12 - minimatch@9.0.5: + minimatch@9.0.9: dependencies: brace-expansion: 2.0.2 minimist@1.2.8: {} - minipass@7.1.2: {} + minipass@7.1.3: {} mnemonist@0.40.0: dependencies: @@ -6461,31 +3669,6 @@ snapshots: nanoid@3.3.11: {} - natural-compare@1.4.0: {} - - next@16.0.10(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@next/env': 16.0.10 - '@swc/helpers': 0.5.15 - caniuse-lite: 1.0.30001727 - postcss: 8.4.31 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - styled-jsx: 5.1.6(react@19.2.3) - optionalDependencies: - '@next/swc-darwin-arm64': 16.0.10 - '@next/swc-darwin-x64': 16.0.10 - '@next/swc-linux-arm64-gnu': 16.0.10 - '@next/swc-linux-arm64-musl': 16.0.10 - '@next/swc-linux-x64-gnu': 16.0.10 - '@next/swc-linux-x64-musl': 16.0.10 - '@next/swc-win32-arm64-msvc': 16.0.10 - '@next/swc-win32-x64-msvc': 16.0.10 - sharp: 0.34.5 - transitivePeerDependencies: - - '@babel/core' - - babel-plugin-macros - node-fetch-native@1.6.7: {} node-fetch@2.7.0: @@ -6500,42 +3683,6 @@ snapshots: pathe: 2.0.3 tinyexec: 1.0.2 - object-assign@4.1.1: {} - - object-inspect@1.13.4: {} - - object-keys@1.1.1: {} - - object.assign@4.1.7: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - has-symbols: 1.1.0 - object-keys: 1.1.1 - - object.entries@1.1.9: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - - object.fromentries@2.0.8: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-object-atoms: 1.1.1 - - object.values@1.2.1: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - obliterator@2.0.5: {} ofetch@1.5.1: @@ -6556,15 +3703,6 @@ snapshots: dependencies: mimic-fn: 2.1.0 - optionator@0.9.4: - dependencies: - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.4.1 - prelude-ls: 1.2.1 - type-check: 0.4.0 - word-wrap: 1.2.5 - ora@5.4.1: dependencies: bl: 4.1.0 @@ -6577,20 +3715,6 @@ snapshots: strip-ansi: 6.0.1 wcwidth: 1.0.1 - own-keys@1.0.1: - dependencies: - get-intrinsic: 1.3.0 - object-keys: 1.1.1 - safe-push-apply: 1.0.0 - - p-limit@3.1.0: - dependencies: - yocto-queue: 0.1.0 - - p-locate@5.0.0: - dependencies: - p-limit: 3.1.0 - p-timeout@7.0.1: {} package-json-from-dist@1.0.1: {} @@ -6606,8 +3730,6 @@ snapshots: json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 - path-exists@4.0.0: {} - path-is-absolute@1.0.1: {} path-key@3.1.1: {} @@ -6617,7 +3739,7 @@ snapshots: path-scurry@1.11.1: dependencies: lru-cache: 10.4.3 - minipass: 7.1.2 + minipass: 7.1.3 pathe@2.0.3: {} @@ -6694,14 +3816,6 @@ snapshots: pluralize@8.0.0: {} - possible-typed-array-names@1.1.0: {} - - postcss@8.4.31: - dependencies: - nanoid: 3.3.11 - picocolors: 1.1.1 - source-map-js: 1.2.1 - postcss@8.5.6: dependencies: nanoid: 3.3.11 @@ -6718,361 +3832,19 @@ snapshots: dependencies: xtend: 4.0.2 - prelude-ls@1.2.1: {} - process-warning@4.0.1: {} process-warning@5.0.0: {} - prop-types@15.8.1: - dependencies: - loose-envify: 1.4.0 - object-assign: 4.1.1 - react-is: 16.13.1 - - punycode@2.3.1: {} - pure-rand@6.1.0: {} - queue-microtask@1.2.3: {} - quick-format-unescaped@4.0.4: {} - rc-cascader@3.34.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@babel/runtime': 7.28.4 - classnames: 2.5.1 - rc-select: 14.16.8(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-tree: 5.13.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - rc-checkbox@3.5.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@babel/runtime': 7.28.4 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - rc-collapse@3.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@babel/runtime': 7.28.4 - classnames: 2.5.1 - rc-motion: 2.9.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - rc-dialog@9.6.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@babel/runtime': 7.28.4 - '@rc-component/portal': 1.1.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - classnames: 2.5.1 - rc-motion: 2.9.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - rc-drawer@7.3.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@babel/runtime': 7.28.4 - '@rc-component/portal': 1.1.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - classnames: 2.5.1 - rc-motion: 2.9.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - rc-dropdown@4.2.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@babel/runtime': 7.28.4 - '@rc-component/trigger': 2.3.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - rc-field-form@2.7.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@babel/runtime': 7.28.4 - '@rc-component/async-validator': 5.0.4 - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - rc-image@7.12.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@babel/runtime': 7.28.4 - '@rc-component/portal': 1.1.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - classnames: 2.5.1 - rc-dialog: 9.6.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-motion: 2.9.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - rc-input-number@9.5.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@babel/runtime': 7.28.4 - '@rc-component/mini-decimal': 1.1.0 - classnames: 2.5.1 - rc-input: 1.8.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - rc-input@1.8.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@babel/runtime': 7.28.4 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - rc-mentions@2.20.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@babel/runtime': 7.28.4 - '@rc-component/trigger': 2.3.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - classnames: 2.5.1 - rc-input: 1.8.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-menu: 9.16.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-textarea: 1.10.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - rc-menu@9.16.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@babel/runtime': 7.28.4 - '@rc-component/trigger': 2.3.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - classnames: 2.5.1 - rc-motion: 2.9.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-overflow: 1.5.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - rc-motion@2.9.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@babel/runtime': 7.28.4 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - rc-notification@5.6.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@babel/runtime': 7.28.4 - classnames: 2.5.1 - rc-motion: 2.9.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - rc-overflow@1.5.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@babel/runtime': 7.28.4 - classnames: 2.5.1 - rc-resize-observer: 1.4.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - rc-pagination@5.1.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@babel/runtime': 7.28.4 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - rc-picker@4.11.3(dayjs@1.11.18)(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@babel/runtime': 7.28.4 - '@rc-component/trigger': 2.3.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - classnames: 2.5.1 - rc-overflow: 1.5.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-resize-observer: 1.4.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - optionalDependencies: - dayjs: 1.11.18 - - rc-progress@4.0.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@babel/runtime': 7.28.4 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - rc-rate@2.13.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@babel/runtime': 7.28.4 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - rc-resize-observer@1.4.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@babel/runtime': 7.28.4 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - resize-observer-polyfill: 1.5.1 - - rc-segmented@2.7.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@babel/runtime': 7.28.4 - classnames: 2.5.1 - rc-motion: 2.9.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - rc-select@14.16.8(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@babel/runtime': 7.28.4 - '@rc-component/trigger': 2.3.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - classnames: 2.5.1 - rc-motion: 2.9.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-overflow: 1.5.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-virtual-list: 3.19.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - rc-slider@11.1.9(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@babel/runtime': 7.28.4 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - rc-steps@6.0.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@babel/runtime': 7.28.4 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - rc-switch@4.1.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@babel/runtime': 7.28.4 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - rc-table@7.54.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@babel/runtime': 7.28.4 - '@rc-component/context': 1.4.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - classnames: 2.5.1 - rc-resize-observer: 1.4.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-virtual-list: 3.19.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - rc-tabs@15.7.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@babel/runtime': 7.28.4 - classnames: 2.5.1 - rc-dropdown: 4.2.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-menu: 9.16.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-motion: 2.9.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-resize-observer: 1.4.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - rc-textarea@1.10.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@babel/runtime': 7.28.4 - classnames: 2.5.1 - rc-input: 1.8.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-resize-observer: 1.4.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - rc-tooltip@6.4.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@babel/runtime': 7.28.4 - '@rc-component/trigger': 2.3.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - rc-tree-select@5.27.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@babel/runtime': 7.28.4 - classnames: 2.5.1 - rc-select: 14.16.8(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-tree: 5.13.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - rc-tree@5.13.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@babel/runtime': 7.28.4 - classnames: 2.5.1 - rc-motion: 2.9.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-virtual-list: 3.19.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - rc-upload@4.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@babel/runtime': 7.28.4 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - rc-util@5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@babel/runtime': 7.28.4 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - react-is: 18.3.1 - - rc-virtual-list@3.19.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@babel/runtime': 7.28.4 - classnames: 2.5.1 - rc-resize-observer: 1.4.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - rc9@2.1.2: dependencies: defu: 6.1.4 destr: 2.0.5 - react-dom@19.2.3(react@19.2.3): - dependencies: - react: 19.2.3 - scheduler: 0.27.0 - - react-is@16.13.1: {} - - react-is@18.3.1: {} - - react@19.2.3: {} - readable-stream@3.6.2: dependencies: inherits: 2.0.4 @@ -7093,26 +3865,6 @@ snapshots: dependencies: redis-errors: 1.2.0 - reflect.getprototypeof@1.0.10: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - get-intrinsic: 1.3.0 - get-proto: 1.0.1 - which-builtin-type: 1.2.1 - - regexp.prototype.flags@1.5.4: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-errors: 1.3.0 - get-proto: 1.0.1 - gopd: 1.2.0 - set-function-name: 2.0.2 - remeda@2.28.0: dependencies: type-fest: 4.41.0 @@ -7123,8 +3875,6 @@ snapshots: require-from-string@2.0.2: {} - resize-observer-polyfill@1.5.1: {} - resolve-from@4.0.0: {} resolve-pkg-maps@1.0.0: {} @@ -7135,12 +3885,6 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - resolve@2.0.0-next.5: - dependencies: - is-core-module: 2.16.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - restore-cursor@3.1.0: dependencies: onetime: 5.1.2 @@ -7152,137 +3896,55 @@ snapshots: rfdc@1.4.1: {} - rollup@4.46.3: + rollup@4.60.0: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.46.3 - '@rollup/rollup-android-arm64': 4.46.3 - '@rollup/rollup-darwin-arm64': 4.46.3 - '@rollup/rollup-darwin-x64': 4.46.3 - '@rollup/rollup-freebsd-arm64': 4.46.3 - '@rollup/rollup-freebsd-x64': 4.46.3 - '@rollup/rollup-linux-arm-gnueabihf': 4.46.3 - '@rollup/rollup-linux-arm-musleabihf': 4.46.3 - '@rollup/rollup-linux-arm64-gnu': 4.46.3 - '@rollup/rollup-linux-arm64-musl': 4.46.3 - '@rollup/rollup-linux-loongarch64-gnu': 4.46.3 - '@rollup/rollup-linux-ppc64-gnu': 4.46.3 - '@rollup/rollup-linux-riscv64-gnu': 4.46.3 - '@rollup/rollup-linux-riscv64-musl': 4.46.3 - '@rollup/rollup-linux-s390x-gnu': 4.46.3 - '@rollup/rollup-linux-x64-gnu': 4.46.3 - '@rollup/rollup-linux-x64-musl': 4.46.3 - '@rollup/rollup-win32-arm64-msvc': 4.46.3 - '@rollup/rollup-win32-ia32-msvc': 4.46.3 - '@rollup/rollup-win32-x64-msvc': 4.46.3 + '@rollup/rollup-android-arm-eabi': 4.60.0 + '@rollup/rollup-android-arm64': 4.60.0 + '@rollup/rollup-darwin-arm64': 4.60.0 + '@rollup/rollup-darwin-x64': 4.60.0 + '@rollup/rollup-freebsd-arm64': 4.60.0 + '@rollup/rollup-freebsd-x64': 4.60.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.60.0 + '@rollup/rollup-linux-arm-musleabihf': 4.60.0 + '@rollup/rollup-linux-arm64-gnu': 4.60.0 + '@rollup/rollup-linux-arm64-musl': 4.60.0 + '@rollup/rollup-linux-loong64-gnu': 4.60.0 + '@rollup/rollup-linux-loong64-musl': 4.60.0 + '@rollup/rollup-linux-ppc64-gnu': 4.60.0 + '@rollup/rollup-linux-ppc64-musl': 4.60.0 + '@rollup/rollup-linux-riscv64-gnu': 4.60.0 + '@rollup/rollup-linux-riscv64-musl': 4.60.0 + '@rollup/rollup-linux-s390x-gnu': 4.60.0 + '@rollup/rollup-linux-x64-gnu': 4.60.0 + '@rollup/rollup-linux-x64-musl': 4.60.0 + '@rollup/rollup-openbsd-x64': 4.60.0 + '@rollup/rollup-openharmony-arm64': 4.60.0 + '@rollup/rollup-win32-arm64-msvc': 4.60.0 + '@rollup/rollup-win32-ia32-msvc': 4.60.0 + '@rollup/rollup-win32-x64-gnu': 4.60.0 + '@rollup/rollup-win32-x64-msvc': 4.60.0 fsevents: 2.3.3 - run-parallel@1.2.0: - dependencies: - queue-microtask: 1.2.3 - - safe-array-concat@1.1.3: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - get-intrinsic: 1.3.0 - has-symbols: 1.1.0 - isarray: 2.0.5 - safe-buffer@5.2.1: {} - safe-push-apply@1.0.0: - dependencies: - es-errors: 1.3.0 - isarray: 2.0.5 - - safe-regex-test@1.1.0: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-regex: 1.2.1 - safe-regex2@5.0.0: dependencies: ret: 0.5.0 safe-stable-stringify@2.5.0: {} - scheduler@0.27.0: {} - - scroll-into-view-if-needed@3.1.0: - dependencies: - compute-scroll-into-view: 3.1.1 - secure-json-parse@4.1.0: {} - semver@6.3.1: {} - - semver@7.7.2: {} - semver@7.7.3: {} set-cookie-parser@2.7.2: {} - set-function-length@1.2.2: - dependencies: - define-data-property: 1.1.4 - es-errors: 1.3.0 - function-bind: 1.1.2 - get-intrinsic: 1.3.0 - gopd: 1.2.0 - has-property-descriptors: 1.0.2 - - set-function-name@2.0.2: - dependencies: - define-data-property: 1.1.4 - es-errors: 1.3.0 - functions-have-names: 1.2.3 - has-property-descriptors: 1.0.2 - - set-proto@1.0.0: - dependencies: - dunder-proto: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - sha3@2.1.4: dependencies: buffer: 6.0.3 - sharp@0.34.5: - dependencies: - '@img/colour': 1.0.0 - detect-libc: 2.1.2 - semver: 7.7.3 - optionalDependencies: - '@img/sharp-darwin-arm64': 0.34.5 - '@img/sharp-darwin-x64': 0.34.5 - '@img/sharp-libvips-darwin-arm64': 1.2.4 - '@img/sharp-libvips-darwin-x64': 1.2.4 - '@img/sharp-libvips-linux-arm': 1.2.4 - '@img/sharp-libvips-linux-arm64': 1.2.4 - '@img/sharp-libvips-linux-ppc64': 1.2.4 - '@img/sharp-libvips-linux-riscv64': 1.2.4 - '@img/sharp-libvips-linux-s390x': 1.2.4 - '@img/sharp-libvips-linux-x64': 1.2.4 - '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 - '@img/sharp-libvips-linuxmusl-x64': 1.2.4 - '@img/sharp-linux-arm': 0.34.5 - '@img/sharp-linux-arm64': 0.34.5 - '@img/sharp-linux-ppc64': 0.34.5 - '@img/sharp-linux-riscv64': 0.34.5 - '@img/sharp-linux-s390x': 0.34.5 - '@img/sharp-linux-x64': 0.34.5 - '@img/sharp-linuxmusl-arm64': 0.34.5 - '@img/sharp-linuxmusl-x64': 0.34.5 - '@img/sharp-wasm32': 0.34.5 - '@img/sharp-win32-arm64': 0.34.5 - '@img/sharp-win32-ia32': 0.34.5 - '@img/sharp-win32-x64': 0.34.5 - optional: true - shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 @@ -7297,34 +3959,6 @@ snapshots: interpret: 1.4.0 rechoir: 0.6.2 - side-channel-list@1.0.0: - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.4 - - side-channel-map@1.0.1: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - object-inspect: 1.13.4 - - side-channel-weakmap@1.0.2: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - object-inspect: 1.13.4 - side-channel-map: 1.0.1 - - side-channel@1.1.0: - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.4 - side-channel-list: 1.0.0 - side-channel-map: 1.0.1 - side-channel-weakmap: 1.0.2 - siginfo@2.0.0: {} signal-exit@3.0.7: {} @@ -7336,13 +3970,13 @@ snapshots: '@socket.io/component-emitter': 3.1.2 debug: 4.4.1 engine.io-client: 6.6.4 - socket.io-parser: 4.2.5 + socket.io-parser: 4.2.6 transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - socket.io-parser@4.2.5: + socket.io-parser@4.2.6: dependencies: '@socket.io/component-emitter': 3.1.2 debug: 4.4.1 @@ -7363,13 +3997,6 @@ snapshots: std-env@3.9.0: {} - stop-iteration-iterator@1.1.0: - dependencies: - es-errors: 1.3.0 - internal-slot: 1.1.0 - - string-convert@0.2.1: {} - string-width@4.2.3: dependencies: emoji-regex: 8.0.0 @@ -7380,51 +4007,7 @@ snapshots: dependencies: eastasianwidth: 0.2.0 emoji-regex: 9.2.2 - strip-ansi: 7.1.0 - - string.prototype.matchall@4.0.12: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - get-intrinsic: 1.3.0 - gopd: 1.2.0 - has-symbols: 1.1.0 - internal-slot: 1.1.0 - regexp.prototype.flags: 1.5.4 - set-function-name: 2.0.2 - side-channel: 1.1.0 - - string.prototype.repeat@1.0.0: - dependencies: - define-properties: 1.2.1 - es-abstract: 1.24.0 - - string.prototype.trim@1.2.10: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-data-property: 1.1.4 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-object-atoms: 1.1.1 - has-property-descriptors: 1.0.2 - - string.prototype.trimend@1.0.9: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - - string.prototype.trimstart@1.0.8: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 + strip-ansi: 7.2.0 string_decoder@1.3.0: dependencies: @@ -7434,23 +4017,14 @@ snapshots: dependencies: ansi-regex: 5.0.1 - strip-ansi@7.1.0: + strip-ansi@7.2.0: dependencies: - ansi-regex: 6.1.0 - - strip-json-comments@3.1.1: {} + ansi-regex: 6.2.2 strip-literal@3.0.0: dependencies: js-tokens: 9.0.1 - styled-jsx@5.1.6(react@19.2.3): - dependencies: - client-only: 0.0.1 - react: 19.2.3 - - stylis@4.3.6: {} - supports-color@5.5.0: dependencies: has-flag: 3.0.0 @@ -7465,8 +4039,6 @@ snapshots: dependencies: real-require: 0.2.0 - throttle-debounce@5.0.2: {} - tinybench@2.9.0: {} tinyexec@0.3.2: {} @@ -7490,14 +4062,8 @@ snapshots: toad-cache@3.7.0: {} - toggle-selection@1.0.6: {} - tr46@0.0.3: {} - ts-api-utils@2.1.0(typescript@5.8.2): - dependencies: - typescript: 5.8.2 - ts-custom-error@3.3.1: {} tsconfck@3.1.6(typescript@5.8.2): @@ -7540,77 +4106,18 @@ snapshots: turbo-windows-64: 2.5.5 turbo-windows-arm64: 2.5.5 - type-check@0.4.0: - dependencies: - prelude-ls: 1.2.1 - type-fest@4.41.0: {} - typed-array-buffer@1.0.3: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-typed-array: 1.1.15 - - typed-array-byte-length@1.0.3: - dependencies: - call-bind: 1.0.8 - for-each: 0.3.5 - gopd: 1.2.0 - has-proto: 1.2.0 - is-typed-array: 1.1.15 - - typed-array-byte-offset@1.0.4: - dependencies: - available-typed-arrays: 1.0.7 - call-bind: 1.0.8 - for-each: 0.3.5 - gopd: 1.2.0 - has-proto: 1.2.0 - is-typed-array: 1.1.15 - reflect.getprototypeof: 1.0.10 - - typed-array-length@1.0.7: - dependencies: - call-bind: 1.0.8 - for-each: 0.3.5 - gopd: 1.2.0 - is-typed-array: 1.1.15 - possible-typed-array-names: 1.1.0 - reflect.getprototypeof: 1.0.10 - - typescript-eslint@8.37.0(eslint@9.31.0(jiti@2.6.1))(typescript@5.8.2): - dependencies: - '@typescript-eslint/eslint-plugin': 8.37.0(@typescript-eslint/parser@8.37.0(eslint@9.31.0(jiti@2.6.1))(typescript@5.8.2))(eslint@9.31.0(jiti@2.6.1))(typescript@5.8.2) - '@typescript-eslint/parser': 8.37.0(eslint@9.31.0(jiti@2.6.1))(typescript@5.8.2) - '@typescript-eslint/typescript-estree': 8.37.0(typescript@5.8.2) - '@typescript-eslint/utils': 8.37.0(eslint@9.31.0(jiti@2.6.1))(typescript@5.8.2) - eslint: 9.31.0(jiti@2.6.1) - typescript: 5.8.2 - transitivePeerDependencies: - - supports-color - typescript@5.8.2: {} typescript@5.8.3: {} ufo@1.6.3: {} - unbox-primitive@1.1.0: - dependencies: - call-bound: 1.0.4 - has-bigints: 1.1.0 - has-symbols: 1.1.0 - which-boxed-primitive: 1.1.1 - undici-types@6.21.0: {} universalify@2.0.1: {} - uri-js@4.4.1: - dependencies: - punycode: 2.3.1 - util-deprecate@1.0.2: {} vite-node@3.2.4(@types/node@22.15.3)(jiti@2.6.1)(tsx@4.20.3): @@ -7640,7 +4147,7 @@ snapshots: fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6 - rollup: 4.46.3 + rollup: 4.60.0 tinyglobby: 0.2.14 optionalDependencies: '@types/node': 22.15.3 @@ -7700,47 +4207,6 @@ snapshots: tr46: 0.0.3 webidl-conversions: 3.0.1 - which-boxed-primitive@1.1.1: - dependencies: - is-bigint: 1.1.0 - is-boolean-object: 1.2.2 - is-number-object: 1.1.1 - is-string: 1.1.1 - is-symbol: 1.1.1 - - which-builtin-type@1.2.1: - dependencies: - call-bound: 1.0.4 - function.prototype.name: 1.1.8 - has-tostringtag: 1.0.2 - is-async-function: 2.1.1 - is-date-object: 1.1.0 - is-finalizationregistry: 1.1.1 - is-generator-function: 1.1.0 - is-regex: 1.2.1 - is-weakref: 1.1.1 - isarray: 2.0.5 - which-boxed-primitive: 1.1.1 - which-collection: 1.0.2 - which-typed-array: 1.1.19 - - which-collection@1.0.2: - dependencies: - is-map: 2.0.3 - is-set: 2.0.3 - is-weakmap: 2.0.2 - is-weakset: 2.0.4 - - which-typed-array@1.1.19: - dependencies: - available-typed-arrays: 1.0.7 - call-bind: 1.0.8 - call-bound: 1.0.4 - for-each: 0.3.5 - get-proto: 1.0.1 - gopd: 1.2.0 - has-tostringtag: 1.0.2 - which@2.0.2: dependencies: isexe: 2.0.0 @@ -7750,8 +4216,6 @@ snapshots: siginfo: 2.0.0 stackback: 0.0.2 - word-wrap@1.2.5: {} - wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 @@ -7760,9 +4224,9 @@ snapshots: wrap-ansi@8.1.0: dependencies: - ansi-styles: 6.2.1 + ansi-styles: 6.2.3 string-width: 5.1.2 - strip-ansi: 7.1.0 + strip-ansi: 7.2.0 wrappy@1.0.2: {} @@ -7788,6 +4252,4 @@ snapshots: y18n: 5.0.8 yargs-parser: 21.1.1 - yocto-queue@0.1.0: {} - zod@4.3.6: {} diff --git a/turbo.json b/turbo.json index 70801e2..8e3d7ee 100644 --- a/turbo.json +++ b/turbo.json @@ -5,7 +5,7 @@ "build": { "dependsOn": ["^build"], "inputs": ["$TURBO_DEFAULT$", ".env*"], - "outputs": [".next/**", "!.next/cache/**", "dist/**"] + "outputs": ["dist/**"] }, "@minswap/felis-ledger-utils#build": { "dependsOn": ["@minswap/felis-uplc-node#build", "@minswap/felis-uplc-web#build"], @@ -137,22 +137,6 @@ "inputs": ["$TURBO_DEFAULT$", ".env*"], "outputs": ["dist/**"] }, - "web#build": { - "dependsOn": [ - "@minswap/felis-ledger-core#build", - "@minswap/felis-ledger-utils#build", - "@minswap/felis-tx-builder#build", - "@minswap/felis-cip#build", - "@minswap/felis-lending-market#build", - "@minswap/felis-dex-v2#build", - "@minswap/felis-build-tx#build" - ], - "inputs": ["$TURBO_DEFAULT$", ".env*"], - "outputs": [".next/**", "!.next/cache/**"] - }, - "lint": { - "dependsOn": ["^lint"] - }, "check-types": { "dependsOn": ["^check-types"] },