diff --git a/.changeset/blue-aliens-ring.md b/.changeset/blue-aliens-ring.md new file mode 100644 index 000000000..2e0459e68 --- /dev/null +++ b/.changeset/blue-aliens-ring.md @@ -0,0 +1,6 @@ +--- +"@ckb-ccc/fiber": patch +--- + +Abstract channel, invoice and payment methods of Fiber + \ No newline at end of file diff --git a/.changeset/polite-pianos-attend.md b/.changeset/polite-pianos-attend.md new file mode 100644 index 000000000..b014c2ab8 --- /dev/null +++ b/.changeset/polite-pianos-attend.md @@ -0,0 +1,6 @@ +--- +"@ckb-ccc/fiber": major +--- + +Initial fiber-sdk module + \ No newline at end of file diff --git a/.changeset/unlucky-tools-deliver.md b/.changeset/unlucky-tools-deliver.md new file mode 100644 index 000000000..b8639f29d --- /dev/null +++ b/.changeset/unlucky-tools-deliver.md @@ -0,0 +1,5 @@ +--- +"@ckb-ccc/fiber": patch +--- + +Wrap fiber RPCs as fiber-sdk into CCC, with playable presentation diff --git a/.gitignore b/.gitignore index 2ae4b0725..910f38b18 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,6 @@ packages/*/dist* .env* *.DS_Store + +.tmp-fiber-js +.pnpm-store diff --git a/packages/fiber/.npmignore b/packages/fiber/.npmignore new file mode 100644 index 000000000..7a88408aa --- /dev/null +++ b/packages/fiber/.npmignore @@ -0,0 +1,21 @@ +node_modules/ +misc/ + +*test.js +*test.ts +*test.d.ts +*test.d.ts.map +*spec.js +*spec.ts +*spec.d.ts +*spec.d.ts.map + +tsconfig.json +tsconfig.*.json +eslint.config.mjs +.prettierrc +.prettierignore + +tsconfig.tsbuildinfo +tsconfig.*.tsbuildinfo +.github/ diff --git a/packages/fiber/.prettierignore b/packages/fiber/.prettierignore new file mode 100644 index 000000000..9c99c800b --- /dev/null +++ b/packages/fiber/.prettierignore @@ -0,0 +1,12 @@ +node_modules/ + +dist/ +dist.commonjs/ + +.npmignore +.prettierrc +tsconfig.json +eslint.config.mjs + +tsconfig.tsbuildinfo +.github/ diff --git a/packages/fiber/.prettierrc b/packages/fiber/.prettierrc new file mode 100644 index 000000000..6390af088 --- /dev/null +++ b/packages/fiber/.prettierrc @@ -0,0 +1,5 @@ +{ + "singleQuote": false, + "trailingComma": "all", + "plugins": ["prettier-plugin-organize-imports"] +} diff --git a/packages/fiber/CHANGELOG.md b/packages/fiber/CHANGELOG.md new file mode 100644 index 000000000..e69de29bb diff --git a/packages/fiber/README.md b/packages/fiber/README.md new file mode 100644 index 000000000..c7ca85232 --- /dev/null +++ b/packages/fiber/README.md @@ -0,0 +1,209 @@ +# Fiber SDK + +A TypeScript/JavaScript SDK for building on [Fiber](https://github.com/nervosnetwork/fiber)—the Nervos payment channel network. One client, one config, and typed methods for channels, invoices, payments, node info, and peers. Built for the [CCC](https://github.com/ckb-devrel/ccc) stack with camelCase APIs and full type exports. + +--- + +## Why use it + +- **Single entry point** — `FiberSDK` wraps Fiber JSON-RPC so you don’t deal with raw RPC or snake_case. +- **TypeScript-first** — Params and results are typed; import `Channel`, `PaymentResult`, `NewInvoiceParamsLike`, etc. from the package. +- **Minimal surface** — Channels, invoices, payments, plus node info and peer management. +- **Fiber-native** — Talks to a running Fiber node over HTTP; no extra runtimes. Use it in Node or the browser. + +--- + +## Install + +```bash +npm install @ckb-ccc/fiber +``` + +--- + +## Quick start + +Create a client and point it at your Fiber node: + +```ts +import { FiberSDK } from "@ckb-ccc/fiber"; + +const sdk = new FiberSDK({ + endpoint: "http://127.0.0.1:8227", + timeout: 5000, // optional, milliseconds +}); +``` + +Then use the same `sdk` for channels, invoices, and payments: + +```ts +const channels = await sdk.listChannels(); +const { invoiceAddress, invoice } = await sdk.newInvoice({ + amount: "0x5f5e100", // 100000000 decimal + currency: "Fibt", + paymentPreimage: "0x" + "01".repeat(32), // 32 bytes; each byte is 0x01 = 1 decimal (example preimage) + description: "Coffee", + expiry: "0xe10", // 3600 decimal + finalExpiryDelta: "0x9283C0", // 9601984 decimal +}); +const payment = await sdk.sendPayment({ invoice: invoiceAddress }); +``` + +That’s the core loop: create an invoice (always pass `paymentPreimage`; optional `paymentHash` is available on `NewInvoiceParamsLike` for hold-style setups), share `invoiceAddress`, and the payer calls `sendPayment` with it. + +--- + +## SDK at a glance + +| Domain | What it does | +| ----------- | -------------------------------------------------------------------------------------------------------------------------------------------- | +| **Channel** | List channels, open and accept, shut down or abandon, update channel options (`sdk.channel.updateChannel`). | +| **Invoice** | Create, parse, get or cancel by payment hash, settle with preimage (`sdk.invoice.settleInvoice`). | +| **Payment** | Send a payment, get status by hash, build a router, send with a pre-built router. | +| **Info** | Node metadata via `getNodeInfo()` (`node_info` RPC). | +| **Peer** | `connectPeer`, `disconnectPeer`, `listPeers`. | + +Most calls exist both as **top-level methods** on `FiberSDK` and on **domain objects** `sdk.channel`, `sdk.invoice`, `sdk.payment`, `sdk.info`, and `sdk.peer`. Use the domain objects when a method is only there (e.g. `acceptChannel`, `buildRouter`, `settleInvoice`, `updateChannel`). Types are exported so you can annotate your code with `Channel`, `PaymentResult`, `NewInvoiceParamsLike`, `SettleInvoiceParamsLike`, and so on. + +--- + +## Node info and peers + +**Node** + +```ts +const info = await sdk.getNodeInfo(); +// info.version, info.nodeId, info.addresses, ... +``` + +**Peers** + +```ts +await sdk.connectPeer({ address: "/ip4/127.0.0.1/tcp/8228", save: true }); +const peers = await sdk.listPeers(); +await sdk.disconnectPeer({ peerId: "" }); +``` + +--- + +## Channels + +Channels are the links between your node and others. You list them, open new ones toward a peer, and either shut them down cleanly (when they’re open) or abandon them (e.g. when an open never completed). + +**List and open** + +```ts +const channels = await sdk.listChannels(); +// Optional filter: sdk.listChannels({ includeClosed: false }) + +const temporaryChannelId = await sdk.openChannel({ + peerId: "", + fundingAmount: "0xba43b7400", // 50000000000 decimal + public: true, +}); +``` + +The counterparty accepts with `sdk.channel.acceptChannel({ temporaryChannelId, fundingAmount, ... })` and gets back the final `channelId`. You use that `channelId` later to shut down or update the channel. + +**Shut down, abandon, or update** + +```ts +await sdk.shutdownChannel({ + channelId: readyChannelId, + feeRate: "0x3FC", // 1020 decimal + force: false, +}); + +await sdk.abandonChannel({ channelId: temporaryChannelId }); + +await sdk.channel.updateChannel({ + channelId: readyChannelId, + enabled: true, +}); +``` + +Use `shutdownChannel` for an established channel you want to close; use `abandonChannel` for a channel that never reached “ready” (e.g. a stuck open). `updateChannel` is only on `sdk.channel` (not duplicated as a top-level `FiberSDK` method). + +--- + +## Invoices + +Invoices represent a request to be paid: amount, currency, **payment preimage** (or optional `paymentHash` for hold invoices), optional description and expiry. You create one, share the **invoice address**, and the payer pays to that address. + +**Create and share** + +```ts +const { invoiceAddress, invoice } = await sdk.newInvoice({ + amount: "0x5f5e100", // 100000000 decimal + currency: "Fibt", + paymentPreimage: "0x" + "01".repeat(32), // 32 bytes; each byte is 0x01 = 1 decimal (example preimage) + description: "Order #42", + expiry: "0xe10", // 3600 decimal + finalExpiryDelta: "0x9283C0", // 9601984 decimal +}); +// Send invoiceAddress to the payer (e.g. QR or link). +// Keep invoice.data.paymentHash to look up or cancel later. +``` + +See `NewInvoiceParamsLike` in `src/types/invoice.ts` for optional `paymentHash`, `allowMpp`, UDT script, and other fields. + +**Parse, get, cancel** + +```ts +const parsed = await sdk.parseInvoice({ invoice: invoiceAddress }); +const info = await sdk.getInvoice(invoice.data.paymentHash); +await sdk.cancelInvoice(invoice.data.paymentHash); +``` + +`parseInvoice` on `FiberSDK` takes `{ invoice: string }` and returns a `CkbInvoice` (the API layer returns `{ invoice }` as `ParseInvoiceResult`). + +Settling an invoice with a preimage is done via `sdk.invoice.settleInvoice({ paymentHash, paymentPreimage })` (typed as `SettleInvoiceParamsLike`). + +--- + +## Payments + +Payments are “send money to this invoice.” You pass the invoice address (or a pre-built router via `sdk.payment`), and the node figures out routing and state updates. + +**Send and track** + +```ts +const result = await sdk.sendPayment({ + invoice: invoiceAddress, +}); +// result.paymentHash, result.status, result.fee, ... + +const status = await sdk.getPayment(result.paymentHash); +``` + +If you prefer to build the route yourself, use `sdk.payment.buildRouter(...)` and `sdk.payment.sendPaymentWithRouter(...)`. Params and results are typed (`SendPaymentCommandParamsLike`, `PaymentResult`, etc.). + +--- + +## Basic usage flows + +**Flow 1: Receive payment** +Create an invoice with `newInvoice` (include `paymentPreimage` or `paymentHash` per your flow), expose `invoiceAddress` to the payer. They call `sendPayment({ invoice: invoiceAddress })`. You can poll or use `getInvoice(paymentHash)` / `getPayment(paymentHash)` as needed. + +**Flow 2: Send payment** +Obtain an invoice string (e.g. from the receiver). Optionally `parseInvoice({ invoice })` to inspect it. Call `sendPayment({ invoice })`. Use `getPayment(paymentHash)` to check status and fee. + +**Flow 3: Channel lifecycle** +Open with `openChannel`; the other side calls `acceptChannel`. Once ready, use `listChannels` to see state and balances. To close, use `shutdownChannel`; if the channel never became ready, use `abandonChannel`. Adjust live settings with `sdk.channel.updateChannel` when supported. + +--- + +## TypeScript and exports + +- All APIs use **camelCase** (e.g. `paymentHash`, `invoiceAddress`). `FiberClient` converts params with `camelToSnake` and responses with `snakeToCamel` (see `utils.ts`). Bigint and number values in RPC params are serialized to hex strings. +- Import **types** from the package: `Channel`, `PaymentResult`, `NewInvoiceParamsLike`, `FiberClient`, etc. +- Besides `FiberSDK`, the package exports `ChannelApi`, `InvoiceApi`, `PaymentApi`, `InfoApi`, `PeerApi`, and `FiberClient` for custom wiring, plus helpers from `utils.ts` (`camelToSnake`, `snakeToCamel`, `toHex`). + +For full type definitions and optional parameters, use your editor’s IntelliSense or browse `packages/fiber/src/types/`. + +--- + +## Learn more + +- [Fiber](https://github.com/nervosnetwork/fiber) — Node implementation and RPC. +- [CCC](https://github.com/ckb-devrel/ccc) — CKBer’s Codebase / Common Chains Connector. diff --git a/packages/fiber/eslint.config.mjs b/packages/fiber/eslint.config.mjs new file mode 100644 index 000000000..8dae5ed1b --- /dev/null +++ b/packages/fiber/eslint.config.mjs @@ -0,0 +1,47 @@ +// @ts-check + +import eslint from "@eslint/js"; +import eslintPluginPrettierRecommended from "eslint-plugin-prettier/recommended"; +import tseslint from "typescript-eslint"; + +import { dirname } from "path"; +import { fileURLToPath } from "url"; + +export default [ + ...tseslint.config({ + files: ["**/*.ts"], + extends: [ + eslint.configs.recommended, + ...tseslint.configs.recommendedTypeChecked, + ], + rules: { + "@typescript-eslint/no-unused-vars": [ + "error", + { + args: "all", + argsIgnorePattern: "^_", + caughtErrors: "all", + caughtErrorsIgnorePattern: "^_", + destructuredArrayIgnorePattern: "^_", + varsIgnorePattern: "^_", + ignoreRestSiblings: true, + }, + ], + "@typescript-eslint/unbound-method": ["error", { ignoreStatic: true }], + "@typescript-eslint/no-unsafe-member-access": "off", + "@typescript-eslint/require-await": "off", + "no-empty": "off", + "prefer-const": [ + "error", + { ignoreReadBeforeAssign: true, destructuring: "all" }, + ], + }, + languageOptions: { + parserOptions: { + project: true, + tsconfigRootDir: dirname(fileURLToPath(import.meta.url)), + }, + }, + }), + eslintPluginPrettierRecommended, +]; diff --git a/packages/fiber/misc/basedirs/dist.commonjs/package.json b/packages/fiber/misc/basedirs/dist.commonjs/package.json new file mode 100644 index 000000000..5bbefffba --- /dev/null +++ b/packages/fiber/misc/basedirs/dist.commonjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/packages/fiber/misc/basedirs/dist/package.json b/packages/fiber/misc/basedirs/dist/package.json new file mode 100644 index 000000000..aead43de3 --- /dev/null +++ b/packages/fiber/misc/basedirs/dist/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} \ No newline at end of file diff --git a/packages/fiber/package.json b/packages/fiber/package.json new file mode 100644 index 000000000..14daab897 --- /dev/null +++ b/packages/fiber/package.json @@ -0,0 +1,62 @@ +{ + "name": "@ckb-ccc/fiber", + "version": "0.1.0", + "type": "module", + "description": "CCC - CKBer's Codebase. Common Chains Connector's support for Fiber SDK", + "author": "ashuralyk ", + "license": "MIT", + "private": false, + "homepage": "https://github.com/ckb-devrel/ccc", + "repository": { + "type": "git", + "url": "git://github.com/ckb-devrel/ccc.git" + }, + "sideEffects": false, + "main": "dist.commonjs/index.js", + "module": "dist/index.js", + "browser": "dist/index.js", + "types": "dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js", + "require": "./dist.commonjs/index.js", + "default": "./dist.commonjs/index.js" + } + }, + "scripts": { + "build": "rimraf ./dist && rimraf ./dist.commonjs && tsc && tsc --project tsconfig.commonjs.json && copyfiles -u 2 misc/basedirs/**/* .", + "lint": "eslint ./src", + "format": "prettier --write . && eslint --fix ./src", + "test": "vitest", + "test:ci": "vitest run" + }, + "devDependencies": { + "@eslint/js": "^9.34.0", + "@nervosnetwork/fiber-js": "^0.7.0", + "@noble/curves": "^1.7.0", + "@types/node": "^24.3.0", + "bs58": "^6.0.0", + "copyfiles": "^2.4.1", + "dotenv": "^17.2.1", + "eslint": "^9.34.0", + "eslint-config-prettier": "^10.1.8", + "eslint-plugin-prettier": "^5.5.4", + "fake-indexeddb": "^6.2.5", + "prettier": "^3.6.2", + "prettier-linter-helpers": "^1.0.1", + "prettier-plugin-organize-imports": "^4.2.0", + "rimraf": "^6.0.1", + "tsx": "^4.20.5", + "typescript": "^5.9.2", + "typescript-eslint": "^8.41.0", + "vitest": "^3.2.4", + "web-worker": "^1.5.0" + }, + "publishConfig": { + "access": "public" + }, + "dependencies": { + "@ckb-ccc/core": "workspace:*" + } +} diff --git a/packages/fiber/scripts/worker-idb-wrapper.mjs b/packages/fiber/scripts/worker-idb-wrapper.mjs new file mode 100644 index 000000000..a48914276 --- /dev/null +++ b/packages/fiber/scripts/worker-idb-wrapper.mjs @@ -0,0 +1,84 @@ +/** + * Runs inside each Node.js worker thread spawned by the FiberRuntime polyfill. + * Sets up IndexedDB (memory or persistent) and exposes WorkerGlobalScope-like + * globals, then loads the fiber-js inline worker IIFE via a temp file + import() + * (fiber-js only ships this code as a string; Node has no blob: Worker without + * executing that string somehow — this avoids eval() while keeping the same runtime). + * + * workerData shape: + * script: string — the fiber-js IIFE source to write and import + * storageType: "memory" | "persistent" (default: "memory") + * storageDir?: string — required when storageType === "persistent" + */ +import { randomUUID } from "node:crypto"; +import { unlinkSync, writeFileSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import { pathToFileURL } from "node:url"; +import { parentPort, workerData } from "worker_threads"; + +// ── WorkerGlobalScope compatibility ────────────────────────────────────────── +globalThis.self = globalThis; + +// In browser workers, postMessage() sends to the parent; +// in Node worker_threads we use parentPort. +globalThis.postMessage = function postMessage(data) { + parentPort?.postMessage(data); +}; + +if (typeof globalThis.onerror === "undefined") globalThis.onerror = null; +if (typeof globalThis.onmessage === "undefined") globalThis.onmessage = null; + +// Forward messages from the main thread to the script's onmessage handler +parentPort?.on("message", (value) => { + if (typeof globalThis.onmessage === "function") { + globalThis.onmessage({ data: value }); + } +}); + +// ── IndexedDB backend ───────────────────────────────────────────────────────── +const storageType = workerData?.storageType ?? "memory"; + +if (storageType === "persistent") { + const storageDir = workerData?.storageDir; + if (!storageDir) { + throw new Error( + "worker-idb-wrapper: storageDir is required for persistent storage mode", + ); + } + // indexeddbshim provides a spec-compliant IndexedDB backed by SQLite. + // Install it: pnpm add indexeddbshim (or npm install indexeddbshim) + let setGlobalVars; + try { + ({ default: setGlobalVars } = await import("indexeddbshim")); + } catch { + throw new Error( + "worker-idb-wrapper: persistent storage requires the 'indexeddbshim' package.\n" + + "Install it with: pnpm add indexeddbshim", + ); + } + setGlobalVars(globalThis, { + checkOrigin: false, + databaseBasePath: storageDir, + }); +} else { + // Default: in-memory IndexedDB (fake-indexeddb) + await import("fake-indexeddb/auto"); +} + +// ── Run the fiber-js worker IIFE (string → temp .mjs → dynamic import) ─────── +const script = workerData?.script; +if (typeof script !== "string") { + throw new Error("worker-idb-wrapper: workerData.script must be a string"); +} +const tmpPath = join(tmpdir(), `ccc-fiber-inline-worker-${randomUUID()}.mjs`); +writeFileSync(tmpPath, script, "utf8"); +try { + await import(pathToFileURL(tmpPath).href); +} finally { + try { + unlinkSync(tmpPath); + } catch { + // ignore (e.g. concurrent unlink or platform quirks) + } +} diff --git a/packages/fiber/src/api/channel.ts b/packages/fiber/src/api/channel.ts new file mode 100644 index 000000000..832b72e94 --- /dev/null +++ b/packages/fiber/src/api/channel.ts @@ -0,0 +1,51 @@ +import { ccc } from "@ckb-ccc/core"; +import { FiberClient } from "../rpc.js"; +import * as fiber from "../types/index.js"; + +export class ChannelApi { + constructor(private readonly rpc: FiberClient) {} + + async openChannel(params: fiber.OpenChannelParamsLike): Promise { + const normalized = fiber.OpenChannelParams.from(params); + const res = await this.rpc.call("open_channel", [ + { ...normalized }, + ]); + return res.temporaryChannelId; + } + + async acceptChannel(params: fiber.AcceptChannelParamsLike): Promise { + const normalized = fiber.AcceptChannelParams.from(params); + const res = await this.rpc.call( + "accept_channel", + [{ ...normalized }], + ); + return res.channelId; + } + + async abandonChannel(params: fiber.AbandonChannelParamsLike): Promise { + const normalized = fiber.AbandonChannelParams.from(params); + await this.rpc.call("abandon_channel", [{ ...normalized }]); + } + + async listChannels( + params?: fiber.ListChannelsParamsLike, + ): Promise { + const normalized = fiber.ListChannelsParams.from(params ?? {}); + const res = await this.rpc.call("list_channels", [ + { ...normalized }, + ]); + return res.channels; + } + + async shutdownChannel( + params: fiber.ShutdownChannelParamsLike, + ): Promise { + const normalized = fiber.ShutdownChannelParams.from(params); + await this.rpc.call("shutdown_channel", [{ ...normalized }]); + } + + async updateChannel(params: fiber.UpdateChannelParamsLike): Promise { + const normalized = fiber.UpdateChannelParams.from(params); + await this.rpc.call("update_channel", [{ ...normalized }]); + } +} diff --git a/packages/fiber/src/api/index.ts b/packages/fiber/src/api/index.ts new file mode 100644 index 000000000..8ae36f337 --- /dev/null +++ b/packages/fiber/src/api/index.ts @@ -0,0 +1,5 @@ +export * from "./channel.js"; +export * from "./info.js"; +export * from "./invoice.js"; +export * from "./payment.js"; +export * from "./peer.js"; diff --git a/packages/fiber/src/api/info.ts b/packages/fiber/src/api/info.ts new file mode 100644 index 000000000..69e616d27 --- /dev/null +++ b/packages/fiber/src/api/info.ts @@ -0,0 +1,10 @@ +import { FiberClient } from "../rpc.js"; +import type * as fiber from "../types/index.js"; + +export class InfoApi { + constructor(private readonly rpc: FiberClient) {} + + async getNodeInfo(): Promise { + return this.rpc.call("node_info", []); + } +} diff --git a/packages/fiber/src/api/invoice.ts b/packages/fiber/src/api/invoice.ts new file mode 100644 index 000000000..8488b006b --- /dev/null +++ b/packages/fiber/src/api/invoice.ts @@ -0,0 +1,48 @@ +import { FiberClient } from "../rpc.js"; +import * as fiber from "../types/index.js"; + +export class InvoiceApi { + constructor(private readonly rpc: FiberClient) {} + + async newInvoice( + params: fiber.NewInvoiceParamsLike, + ): Promise { + const normalized = fiber.NewInvoiceParams.from(params); + return this.rpc.call("new_invoice", [ + { ...normalized }, + ]); + } + + async parseInvoice( + params: fiber.ParseInvoiceParamsLike, + ): Promise { + const normalized = fiber.ParseInvoiceParams.from(params); + return this.rpc.call("parse_invoice", [ + { ...normalized }, + ]); + } + + async getInvoice( + params: fiber.InvoiceParamsLike, + ): Promise { + const normalized = fiber.InvoiceParams.from(params); + return this.rpc.call("get_invoice", [ + { ...normalized }, + ]); + } + + async cancelInvoice( + params: fiber.InvoiceParamsLike, + ): Promise { + const normalized = fiber.InvoiceParams.from(params); + return this.rpc.call("cancel_invoice", [ + { ...normalized }, + ]); + } + + /** Settle an invoice by providing the preimage. */ + async settleInvoice(params: fiber.SettleInvoiceParamsLike): Promise { + const normalized = fiber.SettleInvoiceParams.from(params); + await this.rpc.call("settle_invoice", [{ ...normalized }]); + } +} diff --git a/packages/fiber/src/api/payment.ts b/packages/fiber/src/api/payment.ts new file mode 100644 index 000000000..ac1162b56 --- /dev/null +++ b/packages/fiber/src/api/payment.ts @@ -0,0 +1,42 @@ +import { FiberClient } from "../rpc.js"; +import * as fiber from "../types/index.js"; + +export class PaymentApi { + constructor(private readonly rpc: FiberClient) {} + + async sendPayment( + params: fiber.SendPaymentCommandParamsLike, + ): Promise { + const normalized = fiber.SendPaymentCommandParams.from(params); + return this.rpc.call("send_payment", [ + { ...normalized }, + ]); + } + + async getPayment( + params: fiber.GetPaymentCommandParamsLike, + ): Promise { + const normalized = fiber.GetPaymentCommandParams.from(params); + return this.rpc.call("get_payment", [ + { ...normalized }, + ]); + } + + async buildRouter( + params: fiber.BuildRouterParamsLike, + ): Promise { + const normalized = fiber.BuildRouterParams.from(params); + return this.rpc.call("build_router", [ + { ...normalized }, + ]); + } + + async sendPaymentWithRouter( + params: fiber.SendPaymentWithRouterParamsLike, + ): Promise { + const normalized = fiber.SendPaymentWithRouterParams.from(params); + return this.rpc.call("send_payment_with_router", [ + { ...normalized }, + ]); + } +} diff --git a/packages/fiber/src/api/peer.ts b/packages/fiber/src/api/peer.ts new file mode 100644 index 000000000..bba9882f8 --- /dev/null +++ b/packages/fiber/src/api/peer.ts @@ -0,0 +1,21 @@ +import { FiberClient } from "../rpc.js"; +import * as fiber from "../types/index.js"; + +export class PeerApi { + constructor(private readonly rpc: FiberClient) {} + + async connectPeer(params: fiber.ConnectPeerParamsLike): Promise { + const normalized = fiber.ConnectPeerParams.from(params); + await this.rpc.call("connect_peer", [{ ...normalized }]); + } + + async disconnectPeer(params: fiber.DisconnectPeerParamsLike): Promise { + const normalized = fiber.DisconnectPeerParams.from(params); + await this.rpc.call("disconnect_peer", [{ ...normalized }]); + } + + async listPeers(): Promise { + const res = await this.rpc.call("list_peers", []); + return res.peers; + } +} diff --git a/packages/fiber/src/barrel.ts b/packages/fiber/src/barrel.ts new file mode 100644 index 000000000..c2fbf527f --- /dev/null +++ b/packages/fiber/src/barrel.ts @@ -0,0 +1,5 @@ +export * from "./api/index.js"; +export * from "./rpc.js"; +export * from "./sdk.js"; +export * from "./types/index.js"; +export * from "./utils.js"; diff --git a/packages/fiber/src/index.ts b/packages/fiber/src/index.ts new file mode 100644 index 000000000..3a2530a7b --- /dev/null +++ b/packages/fiber/src/index.ts @@ -0,0 +1,2 @@ +export * from "./barrel.js"; +export * as fiber from "./barrel.js"; diff --git a/packages/fiber/src/rpc.ts b/packages/fiber/src/rpc.ts new file mode 100644 index 000000000..12df4c6b3 --- /dev/null +++ b/packages/fiber/src/rpc.ts @@ -0,0 +1,65 @@ +import { ccc } from "@ckb-ccc/core"; +import { camelToSnake, snakeToCamel } from "./utils.js"; + +/** + * Serializes JavaScript values for Fiber JSON-RPC: bigint and number become hex strings. + * Other values are passed through; objects and arrays are traversed recursively. + */ +export function serializeRpcParams(value: unknown): unknown { + if (typeof value === "bigint" || typeof value === "number") { + return "0x" + value.toString(16); + } + if (Array.isArray(value)) { + return value.map(serializeRpcParams); + } + if (value !== null && typeof value === "object") { + const obj = value as Record; + if (Object.keys(obj).length === 0) return obj; + const out: Record = {}; + for (const key of Object.keys(obj)) { + out[key] = serializeRpcParams(obj[key]); + } + return out; + } + return value; +} + +export interface FiberClientConfig extends ccc.RequestorJsonRpcConfig { + endpoint: string; +} + +/** + * Low-level JSON-RPC client for the Fiber node API. + * Serializes params (bigint/number → hex) and forwards requests. + */ +export class FiberClient { + private readonly requestor: ccc.RequestorJsonRpc; + + constructor(config: FiberClientConfig) { + this.requestor = new ccc.RequestorJsonRpc(config.endpoint, { + timeout: config.timeout, + maxConcurrent: config.maxConcurrent, + fallbacks: config.fallbacks, + transport: config.transport, + }); + } + + async call(method: string, params: unknown[]): Promise { + const serialized = (params ?? []).map((p) => + serializeRpcParams(camelToSnake(p)), + ); + const result = await this.request(method, serialized); + return snakeToCamel(result) as T; + } + + private async request( + method: string, + serialized: unknown[], + ): Promise { + const result = await this.requestor.request(method, serialized); + if (result === undefined) { + throw new Error(`RPC method "${method}" failed`); + } + return result; + } +} diff --git a/packages/fiber/src/sdk.ts b/packages/fiber/src/sdk.ts new file mode 100644 index 000000000..2f209e767 --- /dev/null +++ b/packages/fiber/src/sdk.ts @@ -0,0 +1,119 @@ +import { ccc } from "@ckb-ccc/core"; +import { + ChannelApi, + InfoApi, + InvoiceApi, + PaymentApi, + PeerApi, +} from "./api/index.js"; +import { FiberClient } from "./rpc.js"; +import type * as fiber from "./types/index.js"; + +export interface FiberSDKConfig { + endpoint: string; + timeout?: number; +} + +/** + * High-level SDK for the Fiber node RPC. All params and return types use camelCase (CCC convention). + */ +export class FiberSDK { + readonly channel: ChannelApi; + readonly payment: PaymentApi; + readonly invoice: InvoiceApi; + readonly info: InfoApi; + readonly peer: PeerApi; + + constructor(config: FiberSDKConfig) { + const rpc = new FiberClient({ + endpoint: config.endpoint, + timeout: config.timeout, + }); + this.channel = new ChannelApi(rpc); + this.payment = new PaymentApi(rpc); + this.invoice = new InvoiceApi(rpc); + this.info = new InfoApi(rpc); + this.peer = new PeerApi(rpc); + } + + async getNodeInfo(): Promise { + return this.info.getNodeInfo(); + } + + async listChannels( + params?: fiber.ListChannelsParamsLike, + ): Promise { + return this.channel.listChannels(params); + } + + async openChannel(params: fiber.OpenChannelParamsLike): Promise { + return this.channel.openChannel(params); + } + + async acceptChannel(params: fiber.AcceptChannelParamsLike): Promise { + return this.channel.acceptChannel(params); + } + + async shutdownChannel( + params: fiber.ShutdownChannelParamsLike, + ): Promise { + return this.channel.shutdownChannel(params); + } + + async abandonChannel(params: fiber.AbandonChannelParamsLike): Promise { + return this.channel.abandonChannel(params); + } + + async sendPayment( + params: fiber.SendPaymentCommandParamsLike, + ): Promise { + return this.payment.sendPayment(params); + } + + async parseInvoice( + params: fiber.ParseInvoiceParamsLike, + ): Promise { + const result = await this.invoice.parseInvoice(params); + return result.invoice; + } + + async newInvoice( + params: fiber.NewInvoiceParamsLike, + ): Promise { + return this.invoice.newInvoice(params); + } + + async getInvoice(paymentHash: ccc.HexLike): Promise { + return this.invoice.getInvoice({ + paymentHash, + }); + } + + async cancelInvoice( + paymentHash: ccc.HexLike, + ): Promise { + return this.invoice.cancelInvoice({ + paymentHash, + }); + } + + async getPayment(paymentHash: ccc.HexLike): Promise { + return this.payment.getPayment({ + paymentHash, + }); + } + + async connectPeer(params: fiber.ConnectPeerParamsLike): Promise { + return this.peer.connectPeer(params); + } + + async disconnectPeer(params: fiber.DisconnectPeerParamsLike): Promise { + return this.peer.disconnectPeer(params); + } + + async listPeers(): Promise { + return this.peer.listPeers(); + } +} + +export default FiberSDK; diff --git a/packages/fiber/src/types/channel.ts b/packages/fiber/src/types/channel.ts new file mode 100644 index 000000000..8ffc2fb3f --- /dev/null +++ b/packages/fiber/src/types/channel.ts @@ -0,0 +1,228 @@ +import { ccc } from "@ckb-ccc/core"; +import { toHex } from "../utils"; + +// ─── OpenChannel ─────────────────────────────────────────────────────────── + +export type OpenChannelParamsLike = { + peerId: string; + fundingAmount: ccc.NumLike; + public?: boolean; + fundingUdtTypeScript?: ccc.ScriptLike; + shutdownScript?: ccc.ScriptLike; + commitmentDelayEpoch?: ccc.NumLike; + commitmentFeeRate?: ccc.NumLike; + fundingFeeRate?: ccc.NumLike; + tlcExpiryDelta?: ccc.NumLike; + tlcMinValue?: ccc.NumLike; + tlcFeeProportionalMillionths?: ccc.NumLike; + maxTlcValueInFlight?: ccc.NumLike; + maxTlcNumberInFlight?: ccc.NumLike; +}; + +export class OpenChannelParams { + constructor( + public readonly peerId: string, + public readonly fundingAmount: ccc.Hex, + private readonly _public?: boolean, + public readonly fundingUdtTypeScript?: ccc.Script, + public readonly shutdownScript?: ccc.Script, + public readonly commitmentDelayEpoch?: ccc.Hex, + public readonly commitmentFeeRate?: ccc.Hex, + public readonly fundingFeeRate?: ccc.Hex, + public readonly tlcExpiryDelta?: ccc.Hex, + public readonly tlcMinValue?: ccc.Hex, + public readonly tlcFeeProportionalMillionths?: ccc.Hex, + public readonly maxTlcValueInFlight?: ccc.Hex, + public readonly maxTlcNumberInFlight?: ccc.Hex, + ) {} + + get public(): boolean | undefined { + return this._public; + } + + static from(like: OpenChannelParamsLike): OpenChannelParams { + return new OpenChannelParams( + like.peerId, + ccc.numToHex(like.fundingAmount), + like.public, + like.fundingUdtTypeScript + ? ccc.Script.from(like.fundingUdtTypeScript) + : undefined, + like.shutdownScript ? ccc.Script.from(like.shutdownScript) : undefined, + toHex(like.commitmentDelayEpoch), + toHex(like.commitmentFeeRate), + toHex(like.fundingFeeRate), + toHex(like.tlcExpiryDelta), + toHex(like.tlcMinValue), + toHex(like.tlcFeeProportionalMillionths), + toHex(like.maxTlcValueInFlight), + toHex(like.maxTlcNumberInFlight), + ); + } +} + +export type OpenChannelResult = { + temporaryChannelId: ccc.Hex; +}; + +// ─── AbandonChannel ─────────────────────────────────────────────────────── + +export type AbandonChannelParamsLike = { + channelId: ccc.HexLike; +}; + +export class AbandonChannelParams { + constructor(public readonly channelId: ccc.Hex) {} + + static from(like: AbandonChannelParamsLike): AbandonChannelParams { + return new AbandonChannelParams(ccc.hexFrom(like.channelId)); + } +} + +// ─── AcceptChannel ────────────────────────────────────────────────────────── + +export type AcceptChannelParamsLike = { + temporaryChannelId: ccc.HexLike; + fundingAmount: ccc.NumLike; + shutdownScript?: ccc.ScriptLike; + maxTlcValueInFlight?: ccc.NumLike; + maxTlcNumberInFlight?: ccc.NumLike; + tlcMinValue?: ccc.NumLike; + tlcFeeProportionalMillionths?: ccc.NumLike; + tlcExpiryDelta?: ccc.NumLike; +}; + +export class AcceptChannelParams { + constructor( + public readonly temporaryChannelId: ccc.Hex, + public readonly fundingAmount: ccc.Hex, + public readonly shutdownScript?: ccc.Script, + public readonly maxTlcValueInFlight?: ccc.Hex, + public readonly maxTlcNumberInFlight?: ccc.Hex, + public readonly tlcMinValue?: ccc.Hex, + public readonly tlcFeeProportionalMillionths?: ccc.Hex, + public readonly tlcExpiryDelta?: ccc.Hex, + ) {} + + static from(like: AcceptChannelParamsLike): AcceptChannelParams { + return new AcceptChannelParams( + ccc.hexFrom(like.temporaryChannelId), + ccc.numToHex(like.fundingAmount), + like.shutdownScript ? ccc.Script.from(like.shutdownScript) : undefined, + toHex(like.maxTlcValueInFlight), + toHex(like.maxTlcNumberInFlight), + toHex(like.tlcMinValue), + toHex(like.tlcFeeProportionalMillionths), + toHex(like.tlcExpiryDelta), + ); + } +} + +export type AcceptChannelResult = { + channelId: ccc.Hex; +}; + +// ─── ListChannels ────────────────────────────────────────────────────────── + +export type ListChannelsParamsLike = { + peerId?: string; + includeClosed?: boolean; +}; + +export class ListChannelsParams { + constructor( + public readonly peerId?: string, + public readonly includeClosed?: boolean, + ) {} + + static from(like: ListChannelsParamsLike): ListChannelsParams { + return new ListChannelsParams(like.peerId, like.includeClosed); + } +} + +// ─── Channel (result type) ────────────────────────────────────────────────── + +export type ChannelState = { + stateName: string; + stateFlags: string; +}; + +export type Channel = { + channelId: ccc.Hex; + isPublic: boolean; + channelOutpoint: ccc.Hex; + peerId: ccc.Hex; + fundingUdtTypeScript?: ccc.Script; + state: ChannelState; + localBalance: ccc.Hex; + offeredTlcBalance: ccc.Hex; + remoteBalance: ccc.Hex; + receivedTlcBalance: ccc.Hex; + latestCommitmentTransactionHash?: ccc.Hex; + createdAt: ccc.Hex; + enabled: boolean; + tlcExpiryDelta: ccc.Hex; + tlcFeeProportionalMillionths: ccc.Hex; + shutdownTransactionHash?: ccc.Hex; +}; + +export type ListChannelsResult = { + channels: Channel[]; +}; + +// ─── ShutdownChannel ────────────────────────────────────────────────────── + +export type ShutdownChannelParamsLike = { + channelId: ccc.HexLike; + closeScript?: ccc.ScriptLike; + feeRate?: ccc.NumLike; + force?: boolean; +}; + +export class ShutdownChannelParams { + constructor( + public readonly channelId: ccc.Hex, + public readonly closeScript?: ccc.Script, + public readonly feeRate?: ccc.Hex, + public readonly force?: boolean, + ) {} + + static from(like: ShutdownChannelParamsLike): ShutdownChannelParams { + return new ShutdownChannelParams( + ccc.hexFrom(like.channelId), + like.closeScript ? ccc.Script.from(like.closeScript) : undefined, + toHex(like.feeRate), + like.force, + ); + } +} + +// ─── UpdateChannel ───────────────────────────────────────────────────────── + +export type UpdateChannelParamsLike = { + channelId: ccc.HexLike; + enabled?: boolean; + tlcExpiryDelta?: ccc.NumLike; + tlcMinimumValue?: ccc.NumLike; + tlcFeeProportionalMillionths?: ccc.NumLike; +}; + +export class UpdateChannelParams { + constructor( + public readonly channelId: ccc.Hex, + public readonly enabled?: boolean, + public readonly tlcExpiryDelta?: ccc.Hex, + public readonly tlcMinimumValue?: ccc.Hex, + public readonly tlcFeeProportionalMillionths?: ccc.Hex, + ) {} + + static from(like: UpdateChannelParamsLike): UpdateChannelParams { + return new UpdateChannelParams( + ccc.hexFrom(like.channelId), + like.enabled, + toHex(like.tlcExpiryDelta), + toHex(like.tlcMinimumValue), + toHex(like.tlcFeeProportionalMillionths), + ); + } +} diff --git a/packages/fiber/src/types/index.ts b/packages/fiber/src/types/index.ts new file mode 100644 index 000000000..8ae36f337 --- /dev/null +++ b/packages/fiber/src/types/index.ts @@ -0,0 +1,5 @@ +export * from "./channel.js"; +export * from "./info.js"; +export * from "./invoice.js"; +export * from "./payment.js"; +export * from "./peer.js"; diff --git a/packages/fiber/src/types/info.ts b/packages/fiber/src/types/info.ts new file mode 100644 index 000000000..b98f3990d --- /dev/null +++ b/packages/fiber/src/types/info.ts @@ -0,0 +1,34 @@ +import { ccc } from "@ckb-ccc/core"; + +export type UdtDep = { + cellDep?: ccc.CellDep; + typeId?: ccc.Script; +}; + +export type UdtArgInfo = { + name: string; + script: ccc.Script; + autoAcceptAmount?: ccc.Hex; + cellDeps: UdtDep[]; +}; + +export type UdtCfgInfos = UdtArgInfo[]; + +export type NodeInfo = { + version: string; + commitHash: string; + nodeId: string; + nodeName?: string; + addresses: string[]; + chainHash: ccc.Hex; + openChannelAutoAcceptMinCkbFundingAmount: ccc.Hex; + autoAcceptChannelCkbFundingAmount: ccc.Hex; + defaultFundingLockScript: ccc.Script; + tlcExpiryDelta: ccc.Hex; + tlcMinValue: ccc.Hex; + tlcFeeProportionalMillionths: ccc.Hex; + channelCount: ccc.Hex; + pendingChannelCount: ccc.Hex; + peersCount: ccc.Hex; + udtCfgInfos: UdtCfgInfos; +}; diff --git a/packages/fiber/src/types/invoice.ts b/packages/fiber/src/types/invoice.ts new file mode 100644 index 000000000..7925e5b8a --- /dev/null +++ b/packages/fiber/src/types/invoice.ts @@ -0,0 +1,150 @@ +import { ccc } from "@ckb-ccc/core"; +import { toHex } from "../utils"; + +export type Currency = "Fibb" | "Fibt" | "Fibd"; + +export type CkbInvoiceStatus = + | "Open" + | "Cancelled" + | "Expired" + | "Received" + | "Paid"; + +export type HashAlgorithm = "ckb_hash" | "sha256"; + +export type Attribute = + | { FinalHtlcMinimumExpiryDelta: ccc.Hex } + | { ExpiryTime: ccc.Hex } + | { Description: string } + | { FallbackAddr: string } + | { UdtScript: ccc.Hex } + | { PayeePublicKey: string } + | { HashAlgorithm: number } + | { Feature: ccc.Hex }; + +export type InvoiceData = { + timestamp: ccc.Hex; + paymentHash: ccc.Hex; + attrs: Attribute[]; +}; + +export type CkbInvoice = { + currency: Currency; + amount?: ccc.Hex; + signature?: string; + data: InvoiceData; +}; + +// ─── NewInvoice ─────────────────────────────────────────────────────────── + +export type NewInvoiceParamsLike = { + amount: ccc.NumLike; + description?: string; + currency: Currency; + paymentPreimage: ccc.HexLike; + expiry?: ccc.NumLike; + fallbackAddress?: string; + finalExpiryDelta?: ccc.NumLike; + udtTypeScript?: ccc.ScriptLike; + hashAlgorithm?: HashAlgorithm; + paymentHash?: ccc.HexLike; + allowMpp?: boolean; +}; + +export class NewInvoiceParams { + constructor( + public readonly amount: ccc.Hex, + public readonly currency: Currency, + public readonly paymentPreimage: ccc.Hex, + public readonly description?: string, + public readonly expiry?: ccc.Hex, + public readonly fallbackAddress?: string, + public readonly finalExpiryDelta?: ccc.Hex, + public readonly udtTypeScript?: ccc.Script, + public readonly hashAlgorithm?: HashAlgorithm, + public readonly paymentHash?: ccc.HexLike, + public readonly allowMpp?: boolean, + ) {} + + static from(like: NewInvoiceParamsLike): NewInvoiceParams { + return new NewInvoiceParams( + ccc.numToHex(like.amount), + like.currency, + ccc.hexFrom(like.paymentPreimage), + like.description, + toHex(like.expiry), + like.fallbackAddress, + toHex(like.finalExpiryDelta), + like.udtTypeScript ? ccc.Script.from(like.udtTypeScript) : undefined, + like.hashAlgorithm, + like.paymentHash, + like.allowMpp, + ); + } +} + +export type InvoiceResult = { + invoiceAddress: string; + invoice: CkbInvoice; +}; + +export type NewInvoiceResult = InvoiceResult; + +// ─── ParseInvoice ────────────────────────────────────────────────────────── + +export type ParseInvoiceParamsLike = { + invoice: string; +}; + +export class ParseInvoiceParams { + constructor(public readonly invoice: string) {} + + static from(like: ParseInvoiceParamsLike): ParseInvoiceParams { + return new ParseInvoiceParams(like.invoice); + } +} + +export type ParseInvoiceResult = { + invoice: CkbInvoice; +}; + +// ─── InvoiceParams (get_invoice / cancel_invoice) ─────────────────────────── + +export type InvoiceParamsLike = { + paymentHash: ccc.HexLike; +}; + +export class InvoiceParams { + constructor(public readonly paymentHash: ccc.Hex) {} + + static from(like: InvoiceParamsLike): InvoiceParams { + return new InvoiceParams(ccc.hexFrom(like.paymentHash)); + } +} + +// ─── SettleInvoice ───────────────────────────────────────────────────────── + +export type SettleInvoiceParamsLike = { + paymentHash: ccc.HexLike; + paymentPreimage: ccc.HexLike; +}; + +export class SettleInvoiceParams { + constructor( + public readonly paymentHash: ccc.Hex, + public readonly paymentPreimage: ccc.Hex, + ) {} + + static from(like: SettleInvoiceParamsLike): SettleInvoiceParams { + return new SettleInvoiceParams( + ccc.hexFrom(like.paymentHash), + ccc.hexFrom(like.paymentPreimage), + ); + } +} + +export type GetInvoiceResult = { + invoiceAddress: string; + invoice: CkbInvoice; + status: CkbInvoiceStatus; +}; diff --git a/packages/fiber/src/types/payment.ts b/packages/fiber/src/types/payment.ts new file mode 100644 index 000000000..149062bff --- /dev/null +++ b/packages/fiber/src/types/payment.ts @@ -0,0 +1,278 @@ +import { ccc } from "@ckb-ccc/core"; +import { toHex } from "../utils"; + +export type PaymentSessionStatus = + | "Created" + | "Inflight" + | "Success" + | "Failed"; + +export type PaymentCustomRecordsLike = { + [key: string]: ccc.HexLike; +}; + +export class PaymentCustomRecords { + constructor(public readonly record: Record) {} + + static from(like: PaymentCustomRecordsLike): PaymentCustomRecords { + const out: Record = {}; + for (const key of Object.keys(like)) { + out[key] = ccc.hexFrom(like[key]); + } + return new PaymentCustomRecords(out); + } +} + +export type SessionRouteNodeLike = { + pubkey: string; + amount: ccc.NumLike; + channelOutpoint: ccc.HexLike; +}; + +export type SessionRouteNode = { + pubkey: string; + amount: ccc.Hex; + channelOutpoint: ccc.Hex; +}; + +export type PaymentCustomRecordsPlain = Record; + +export type GetPaymentCommandResult = { + paymentHash: ccc.Hex; + status: PaymentSessionStatus; + createdAt: ccc.Hex; + lastUpdatedAt: ccc.Hex; + failedError?: string; + fee: ccc.Hex; + customRecords?: PaymentCustomRecordsPlain; + router?: SessionRouteNode[]; +}; + +// ─── HopRequire ───────────────────────────────────────────────────────────── + +export type HopRequireLike = { + pubkey: string; + channelOutpoint: ccc.HexLike; +}; + +export class HopRequire { + constructor( + public readonly pubkey: string, + public readonly channelOutpoint: ccc.Hex, + ) {} + + static from(like: HopRequireLike): HopRequire { + return new HopRequire(like.pubkey, ccc.hexFrom(like.channelOutpoint)); + } +} + +// ─── HopHint ─────────────────────────────────────────────────────────────── + +export type HopHintLike = { + pubkey: string; + channelOutpoint: ccc.HexLike; + feeRate: ccc.NumLike; + tlcExpiryDelta: ccc.NumLike; +}; + +export class HopHint { + constructor( + public readonly pubkey: string, + public readonly channelOutpoint: ccc.Hex, + public readonly feeRate: ccc.Hex, + public readonly tlcExpiryDelta: ccc.Hex, + ) {} + + static from(like: HopHintLike): HopHint { + return new HopHint( + like.pubkey, + ccc.hexFrom(like.channelOutpoint), + ccc.numToHex(like.feeRate), + ccc.numToHex(like.tlcExpiryDelta), + ); + } +} + +// ─── RouterHop ────────────────────────────────────────────────────────────── + +export type RouterHopLike = { + target: ccc.HexLike; + channelOutpoint: ccc.HexLike; + amountReceived: ccc.NumLike; + incomingTlcExpiry: ccc.NumLike; +}; + +export class RouterHop { + constructor( + public readonly target: ccc.Hex, + public readonly channelOutpoint: ccc.Hex, + public readonly amountReceived: ccc.Hex, + public readonly incomingTlcExpiry: ccc.Hex, + ) {} + + static from(like: RouterHopLike): RouterHop { + return new RouterHop( + ccc.hexFrom(like.target), + ccc.hexFrom(like.channelOutpoint), + ccc.numToHex(like.amountReceived), + ccc.numToHex(like.incomingTlcExpiry), + ); + } +} + +// ─── GetPayment ──────────────────────────────────────────────────────────── + +export type GetPaymentCommandParamsLike = { + paymentHash: ccc.HexLike; +}; + +export class GetPaymentCommandParams { + constructor(public readonly paymentHash: ccc.Hex) {} + + static from(like: GetPaymentCommandParamsLike): GetPaymentCommandParams { + return new GetPaymentCommandParams(ccc.hexFrom(like.paymentHash)); + } +} + +// ─── SendPayment ─────────────────────────────────────────────────────────── + +export type SendPaymentCommandParamsLike = { + targetPubkey?: string; + amount?: ccc.NumLike; + paymentHash?: ccc.HexLike; + finalTlcExpiryDelta?: ccc.NumLike; + tlcExpiryLimit?: ccc.NumLike; + invoice?: string; + timeout?: ccc.NumLike; + maxFeeAmount?: ccc.NumLike; + maxFeeRate?: ccc.NumLike; + maxParts?: ccc.NumLike; + trampolineHops?: string[]; + keysend?: boolean; + udtTypeScript?: ccc.ScriptLike; + allowSelfPayment?: boolean; + customRecords?: PaymentCustomRecordsLike; + hopHints?: HopHintLike[]; + dryRun?: boolean; +}; + +export class SendPaymentCommandParams { + constructor( + public readonly targetPubkey?: string, + public readonly amount?: ccc.Hex, + public readonly paymentHash?: ccc.Hex, + public readonly finalTlcExpiryDelta?: ccc.Hex, + public readonly tlcExpiryLimit?: ccc.Hex, + public readonly invoice?: string, + public readonly timeout?: ccc.Hex, + public readonly maxFeeAmount?: ccc.Hex, + public readonly maxFeeRate?: ccc.Hex, + public readonly maxParts?: ccc.Hex, + public readonly trampolineHops?: string[], + public readonly keysend?: boolean, + public readonly udtTypeScript?: ccc.Script, + public readonly allowSelfPayment?: boolean, + public readonly customRecords?: PaymentCustomRecords, + public readonly hopHints?: HopHint[], + public readonly dryRun?: boolean, + ) {} + + static from(like: SendPaymentCommandParamsLike): SendPaymentCommandParams { + return new SendPaymentCommandParams( + like.targetPubkey, + toHex(like.amount), + like.paymentHash ? ccc.hexFrom(like.paymentHash) : undefined, + toHex(like.finalTlcExpiryDelta), + toHex(like.tlcExpiryLimit), + like.invoice, + toHex(like.timeout), + toHex(like.maxFeeAmount), + toHex(like.maxFeeRate), + toHex(like.maxParts), + like.trampolineHops, + like.keysend, + like.udtTypeScript ? ccc.Script.from(like.udtTypeScript) : undefined, + like.allowSelfPayment, + like.customRecords + ? PaymentCustomRecords.from(like.customRecords) + : undefined, + like.hopHints?.map((h) => HopHint.from(h)), + like.dryRun, + ); + } +} + +// ─── BuildRouter ─────────────────────────────────────────────────────────── + +export type BuildRouterParamsLike = { + amount?: ccc.NumLike; + udtTypeScript?: ccc.ScriptLike; + hopsInfo: HopRequireLike[]; + finalTlcExpiryDelta?: ccc.NumLike; +}; + +export class BuildRouterParams { + constructor( + public readonly hopsInfo: HopRequire[], + public readonly amount?: ccc.Hex, + public readonly udtTypeScript?: ccc.Script, + public readonly finalTlcExpiryDelta?: ccc.Hex, + ) {} + + static from(like: BuildRouterParamsLike): BuildRouterParams { + return new BuildRouterParams( + like.hopsInfo.map((h) => HopRequire.from(h)), + toHex(like.amount), + like.udtTypeScript ? ccc.Script.from(like.udtTypeScript) : undefined, + toHex(like.finalTlcExpiryDelta), + ); + } +} + +export type BuildPaymentRouterResult = { + routerHops: RouterHop[]; +}; + +// ─── SendPaymentWithRouter ──────────────────────────────────────────────── + +export type SendPaymentWithRouterParamsLike = { + paymentHash?: ccc.HexLike; + router: RouterHopLike[]; + invoice?: string; + customRecords?: PaymentCustomRecordsLike; + keysend?: boolean; + udtTypeScript?: ccc.ScriptLike; + dryRun?: boolean; +}; + +export class SendPaymentWithRouterParams { + constructor( + public readonly router: RouterHop[], + public readonly paymentHash?: ccc.Hex, + public readonly invoice?: string, + public readonly customRecords?: PaymentCustomRecords, + public readonly keysend?: boolean, + public readonly udtTypeScript?: ccc.Script, + public readonly dryRun?: boolean, + ) {} + + static from( + like: SendPaymentWithRouterParamsLike, + ): SendPaymentWithRouterParams { + return new SendPaymentWithRouterParams( + like.router.map((r) => RouterHop.from(r)), + like.paymentHash ? ccc.hexFrom(like.paymentHash) : undefined, + like.invoice, + like.customRecords + ? PaymentCustomRecords.from(like.customRecords) + : undefined, + like.keysend, + like.udtTypeScript ? ccc.Script.from(like.udtTypeScript) : undefined, + like.dryRun, + ); + } +} + +// ─── Aliases ─────────────────────────────────────────────────────────────── + +export type PaymentResult = GetPaymentCommandResult; diff --git a/packages/fiber/src/types/peer.ts b/packages/fiber/src/types/peer.ts new file mode 100644 index 000000000..f972da02d --- /dev/null +++ b/packages/fiber/src/types/peer.ts @@ -0,0 +1,43 @@ +// ─── ConnectPeer ─────────────────────────────────────────────────────────── + +export type ConnectPeerParamsLike = { + address: string; + save?: boolean; +}; + +export class ConnectPeerParams { + constructor( + public readonly address: string, + public readonly save?: boolean, + ) {} + + static from(like: ConnectPeerParamsLike): ConnectPeerParams { + return new ConnectPeerParams(like.address, like.save); + } +} + +// ─── DisconnectPeer ──────────────────────────────────────────────────────── + +export type DisconnectPeerParamsLike = { + peerId: string; +}; + +export class DisconnectPeerParams { + constructor(public readonly peerId: string) {} + + static from(like: DisconnectPeerParamsLike): DisconnectPeerParams { + return new DisconnectPeerParams(like.peerId); + } +} + +// ─── ListPeers (result types) ─────────────────────────────────────────────── + +export type PeerInfo = { + pubkey: string; + peerId: string; + address: string; +}; + +export type ListPeerResult = { + peers: PeerInfo[]; +}; diff --git a/packages/fiber/src/utils.ts b/packages/fiber/src/utils.ts new file mode 100644 index 000000000..36801ce77 --- /dev/null +++ b/packages/fiber/src/utils.ts @@ -0,0 +1,42 @@ +import { ccc } from "@ckb-ccc/core"; + +function camelToSnakeKey(s: string): string { + return s.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`); +} + +function snakeToCamelKey(s: string): string { + return s.replace(/_([a-z])/g, (_: string, c: string) => c.toUpperCase()); +} + +function convertKeys(value: unknown, keyFn: (key: string) => string): unknown { + if (value === null || value === undefined) { + return value; + } + if (Array.isArray(value)) { + return value.map((item) => convertKeys(item, keyFn)); + } + if (typeof value === "object" && value.constructor === Object) { + const obj = value as Record; + const out: Record = {}; + for (const key of Object.keys(obj)) { + const newKey = keyFn(key); + out[newKey] = convertKeys(obj[key], keyFn); + } + return out; + } + return value; +} + +// Convert object keys from camelCase to snake_case (recursive). Used when sending params to Fiber RPC. +export function camelToSnake(value: T): unknown { + return convertKeys(value, camelToSnakeKey); +} + +// Convert object keys from snake_case to camelCase (recursive). Used when receiving results from Fiber RPC. +export function snakeToCamel(value: T): unknown { + return convertKeys(value, snakeToCamelKey); +} + +export function toHex(value?: ccc.NumLike): ccc.Hex | undefined { + return value ? ccc.numToHex(value) : undefined; +} diff --git a/packages/fiber/tests/fiber.test.ts b/packages/fiber/tests/fiber.test.ts new file mode 100644 index 000000000..c7679bbf4 --- /dev/null +++ b/packages/fiber/tests/fiber.test.ts @@ -0,0 +1,209 @@ +/** + * Integration tests for Fiber SDK (channel, invoice, payment). + * Starts an in-process Fiber node via FiberRuntime and exercises the SDK + * against the HTTP JSON-RPC bridge it provides. + * + * Failure-scenario tests call the real node with invalid data (e.g. zero + * channel_id, invalid invoice string). Error messages from the fiber WASM + * worker in the console are expected — the node rejects the request and the + * SDK correctly surfaces the error. They are not SDK bugs. + */ +import { ccc } from "@ckb-ccc/core"; +import crypto from "node:crypto"; +import { afterAll, beforeAll, describe, expect, it, vi } from "vitest"; +import { FiberSDK } from "../src/sdk.js"; +import { FiberRuntime } from "./runtime/index.js"; + +vi.mock("@joyid/ckb", () => ({ + verifySignature: async () => true, + verifyCredential: async () => true, +})); + +const RPC_PORT = 18227; +const FIXED8_SCALE = 10n ** 8n; +const CHANNEL_TEST_FUNDING_AMOUNT_FIXED8 = ccc.numToHex(500n * FIXED8_SCALE); +const CHANNEL_TEST_FEE_RATE = 1020; +const INVOICE_TEST_AMOUNT = 100_000_000; +const INVOICE_TEST_EXPIRY_SEC = 3600; +const INVOICE_TEST_FINAL_EXPIRY_DELTA = 9_600_000; + +function hex(bytes: number): ccc.Hex { + return ("0x" + "00".repeat(bytes)) as ccc.Hex; +} + +let runtime: FiberRuntime; + +function createSdk(): FiberSDK { + return new FiberSDK({ endpoint: runtime.info.rpcUrl, timeout: 10000 }); +} + +beforeAll(async () => { + runtime = new FiberRuntime(); + await runtime.start({ + config: { fiberPort: 8228, databasePrefix: "/wasm-fiber" }, + storage: { type: "memory" }, + rpcPort: RPC_PORT, + }); +}, 60000); + +afterAll(async () => { + await runtime?.stop(); +}, 5000); + +describe("Fiber SDK", () => { + describe("info", () => { + it("getNodeInfo returns nodeId and addresses", async () => { + const sdk = createSdk(); + const info = await sdk.getNodeInfo(); + expect(info).toHaveProperty("nodeId"); + expect(typeof info.nodeId).toBe("string"); + expect(info).toHaveProperty("addresses"); + }); + }); + + describe("peer", () => { + it("listPeers", async () => { + const sdk = createSdk(); + await sdk.listPeers(); + }); + + it("connectPeer", async () => { + const sdk = createSdk(); + await sdk + .connectPeer({ + address: + "/ip4/127.0.0.1/tcp/8228/p2p/QmZicX1EZumP6wkB9DpmV2xBQDm3pexRvqoYdhKotNjDFa", + }) + .catch((err) => { + expect(err.message).toContain('RPC method "connect_peer" failed'); + }); + }); + }); + + describe("channel", () => { + it("openChannel", async () => { + const sdk = createSdk(); + await sdk + .openChannel({ + peerId: "QmZicX1EZumP6wkB9DpmV2xBQDm3pexRvqoYdhKotNjDFa", + fundingAmount: CHANNEL_TEST_FUNDING_AMOUNT_FIXED8, + public: true, + }) + .catch((err) => { + expect(err.message).toContain("Invalid parameter"); + }); + }); + + it("listChannels", async () => { + const sdk = createSdk(); + const result = await sdk.listChannels(); + expect(Array.isArray(result)).toBe(true); + }); + + it("shutdownChannel", async () => { + const sdk = createSdk(); + await sdk + .shutdownChannel({ + channelId: hex(32), + feeRate: CHANNEL_TEST_FEE_RATE, + force: false, + }) + .catch((err) => { + expect(err.message).toContain("Channel not found error"); + }); + }); + + it("abandonChannel", async () => { + const sdk = createSdk(); + await sdk.abandonChannel({ channelId: hex(32) }).catch((err) => { + expect(err.message).toContain("Invalid parameter"); + }); + }); + }); + + describe("invoice", () => { + it("newInvoice returns invoice address and invoice", async () => { + const sdk = createSdk(); + const preimage = ccc.hexFrom(crypto.randomBytes(32)); + const result = await sdk.newInvoice({ + amount: INVOICE_TEST_AMOUNT, + currency: "Fibt", + paymentPreimage: preimage, + description: "test invoice", + expiry: INVOICE_TEST_EXPIRY_SEC, + finalExpiryDelta: INVOICE_TEST_FINAL_EXPIRY_DELTA, + }); + expect(result).toHaveProperty("invoiceAddress"); + expect(result).toHaveProperty("invoice"); + expect(result.invoice).toHaveProperty("data"); + expect(result.invoice.data).toHaveProperty("paymentHash"); + }); + + it("parseInvoice returns invoice object", async () => { + const sdk = createSdk(); + const result = await sdk.parseInvoice({ + invoice: + "fibt1000000001pcsaug0p0exgfw0pnm6vk0rnt4xefskmrz0k2vqxr4lnrms60qasvc54jagg2hk8v40k88exmp04pn5cpcnrcsw5lk9w0w6l0m3k84e2ax4v6gq9ne2n77u4p8h3npx6tuufqftq8eyqxw9t4upaw4f89xukcee79rm0p0jv92d5ckq7pmvm09ma3psheu3rfyy9atlrdr4el6ys8yqurl2m74msuykljp35j0s47vpw8h3crfp5ldp8kp4xlusqk6rad3ssgwn2a429qlpgfgjrtj3gzy26w50cy7gypgjm6mjgaz2ff5q4am0avf6paxja2gh2wppjagqlg466yzty0r0pfz8qpuzqgq43mkgx", + }); + expect(result).toHaveProperty("currency"); + expect(result).toHaveProperty("data"); + expect(result.data).toHaveProperty("paymentHash"); + }); + + it("getInvoice returns invoice when it exists", async () => { + const sdk = createSdk(); + const preimage = ccc.hexFrom(crypto.randomBytes(32)); + const created = await sdk.newInvoice({ + amount: INVOICE_TEST_AMOUNT, + currency: "Fibt", + paymentPreimage: preimage, + description: "getInvoice test", + expiry: INVOICE_TEST_EXPIRY_SEC, + finalExpiryDelta: INVOICE_TEST_FINAL_EXPIRY_DELTA, + }); + const paymentHash = created.invoice.data.paymentHash; + const got = await sdk.getInvoice(paymentHash); + expect(got).toHaveProperty("status"); + expect(got).toHaveProperty("invoice"); + expect(got.invoice.data.paymentHash).toBe(paymentHash); + }); + + it("cancelInvoice succeeds when invoice exists", async () => { + const sdk = createSdk(); + const preimage = ccc.hexFrom(crypto.randomBytes(32)); + const created = await sdk.newInvoice({ + amount: INVOICE_TEST_AMOUNT, + currency: "Fibt", + paymentPreimage: preimage, + description: "cancelInvoice test", + expiry: INVOICE_TEST_EXPIRY_SEC, + finalExpiryDelta: INVOICE_TEST_FINAL_EXPIRY_DELTA, + }); + const paymentHash = created.invoice.data.paymentHash; + const result = await sdk.cancelInvoice(paymentHash); + expect(result).toHaveProperty("status"); + }); + }); + + describe("payment", () => { + it("sendPayment", async () => { + const sdk = createSdk(); + const preimage = ccc.hexFrom(crypto.randomBytes(32)); + const created = await sdk.newInvoice({ + amount: INVOICE_TEST_AMOUNT, + currency: "Fibt", + paymentPreimage: preimage, + description: "sendPayment test", + expiry: INVOICE_TEST_EXPIRY_SEC, + finalExpiryDelta: INVOICE_TEST_FINAL_EXPIRY_DELTA, + }); + await sdk + .sendPayment({ invoice: created.invoiceAddress }) + .catch((err) => { + expect(err.message).toContain( + "Send payment error: Failed to build route, Feature not enabled: allow_self_payment is not enabled, can not pay to self", + ); + }); + }); + }); +}); diff --git a/packages/fiber/tests/runtime/config.ts b/packages/fiber/tests/runtime/config.ts new file mode 100644 index 000000000..751ee862f --- /dev/null +++ b/packages/fiber/tests/runtime/config.ts @@ -0,0 +1,78 @@ +import { readFileSync } from "node:fs"; +import { resolve } from "node:path"; + +export type StorageMode = + | { type: "memory" } + | { type: "persistent"; dir: string }; + +/** + * Inline options for generating a fiber node YAML config. + * All fields are optional — reasonable defaults are applied. + */ +export interface FiberNodeOptions { + /** libp2p P2P listening port. Default: 8228 */ + fiberPort?: number; + /** fiber-wasm internal RPC port (written into the YAML; separate from the HTTP bridge). Default: 8227 */ + internalRpcPort?: number; + /** IndexedDB database name prefix — used by the storage backend. Default: "/wasm-fiber" */ + databasePrefix?: string; + /** Bootnode multiaddrs to connect at startup. Default: [] */ + bootnodeAddrs?: string[]; + /** CKB RPC endpoint. Default: "https://testnet.ckbapp.dev/" */ + ckbRpcUrl?: string; + /** Fiber chain. Default: "testnet" */ + chain?: string; +} + +/** Build the YAML string expected by fiber.start(). */ +export function buildFiberConfigYaml(opts: FiberNodeOptions): string { + const fiberPort = opts.fiberPort ?? 8228; + const internalRpcPort = opts.internalRpcPort ?? 8227; + const ckbRpcUrl = opts.ckbRpcUrl ?? "https://testnet.ckbapp.dev/"; + const chain = opts.chain ?? "testnet"; + const bootnodeAddrs = opts.bootnodeAddrs ?? []; + + const bootnodeYaml = + bootnodeAddrs.length === 0 + ? " bootnode_addrs: []" + : ` bootnode_addrs:\n${bootnodeAddrs.map((a) => ` - "${a}"`).join("\n")}`; + + return `fiber: + listening_addr: "/ip4/127.0.0.1/tcp/${fiberPort}" +${bootnodeYaml} + announce_listening_addr: false + announced_addrs: [] + chain: ${chain} + scripts: [] +rpc: + listening_addr: "127.0.0.1:${internalRpcPort}" +ckb: + rpc_url: "${ckbRpcUrl}" + udt_whitelist: [] +services: + - fiber + - rpc + - ckb`; +} + +/** + * Load a raw YAML config string from a file path. + * The string is passed verbatim to fiber.start(); no parsing is done. + */ +export function loadFiberConfigFile(yamlPath: string): string { + return readFileSync(resolve(yamlPath), "utf8"); +} + +/** Resolve a FiberNodeOptions or file path to a YAML string for fiber.start(). */ +export function resolveFiberConfig(config: FiberNodeOptions | string): { + yaml: string; + databasePrefix: string; +} { + if (typeof config === "string") { + return { yaml: loadFiberConfigFile(config), databasePrefix: "/wasm-fiber" }; + } + return { + yaml: buildFiberConfigYaml(config), + databasePrefix: config.databasePrefix ?? "/wasm-fiber", + }; +} diff --git a/packages/fiber/tests/runtime/fiberRuntime.ts b/packages/fiber/tests/runtime/fiberRuntime.ts new file mode 100644 index 000000000..6a7d48059 --- /dev/null +++ b/packages/fiber/tests/runtime/fiberRuntime.ts @@ -0,0 +1,205 @@ +import type { Server } from "node:http"; +import { + type FiberNodeOptions, + type StorageMode, + resolveFiberConfig, +} from "./config.js"; +import { fiberKeyPairToBase58PeerId, hexPeerIdToBase58 } from "./peerId.js"; +import { installNodePolyfills } from "./polyfill.js"; +import { + type FiberLike, + closeRpcServer, + createRpcServer, + listenRpcServer, +} from "./rpcBridge.js"; + +export type { FiberNodeOptions, StorageMode } from "./config.js"; + +export interface FiberRuntimeOptions { + /** + * Fiber node configuration: + * - Pass a FiberNodeOptions object to generate config inline. + * - Pass a file path string to load a YAML config from disk. + */ + config: FiberNodeOptions | string; + + /** Storage backend for fiber-wasm IndexedDB. Default: { type: "memory" }. */ + storage?: StorageMode; + + /** + * 32-byte secp256k1 private key for the fiber P2P identity. + * Generated randomly if omitted (ephemeral — use for tests). + */ + fiberKeyPair?: Uint8Array; + + /** + * 32-byte secp256k1 private key for CKB transaction signing. + * Generated randomly if omitted. + */ + ckbSecretKey?: Uint8Array; + + /** Custom chain spec string (for chains other than testnet/mainnet). */ + chainSpec?: string; + + /** fiber-wasm log level. Default: "info". */ + logLevel?: "trace" | "debug" | "info" | "error"; + + /** HTTP JSON-RPC server host. Default: "127.0.0.1". */ + rpcHost?: string; + + /** + * HTTP JSON-RPC server preferred port. Retries up to 10 ports on EADDRINUSE. + * Default: 18227. + */ + rpcPort?: number; + + /** Add CORS headers to RPC responses. Default: false. */ + cors?: boolean; + + /** Log RPC requests/responses to stdout. Default: false. */ + verbose?: boolean; +} + +/** Information about a running fiber node. */ +export interface FiberRuntimeInfo { + /** Full HTTP JSON-RPC endpoint URL, e.g. "http://127.0.0.1:18227". */ + rpcUrl: string; + /** Actual port the RPC server bound to (may differ from rpcPort on retry). */ + rpcPort: number; + /** Raw node_id hex from node_info (may be the CKB key, not the P2P key). */ + nodeId: string; + /** + * Base58 PeerId derived from fiberKeyPair using the tentacle/secio scheme. + * This is the identity used for P2P connections — use it in multiaddrs: + * /ip4/127.0.0.1/tcp//p2p/ + */ + p2pPeerId: string; + /** Multiaddrs returned by node_info, or a constructed fallback. */ + addresses: string[]; +} + +/** + * Manages the lifecycle of a single in-process fiber node (fiber-js WASM) + * and its HTTP JSON-RPC bridge. + * + * Usage: + * const runtime = new FiberRuntime(); + * const info = await runtime.start({ config: { fiberPort: 8228 } }); + * // ... run tests or serve traffic ... + * await runtime.stop(); + */ +export class FiberRuntime { + private fiber: FiberLike | null = null; + private server: Server | null = null; + private _info: FiberRuntimeInfo | null = null; + + /** Start the fiber node and HTTP RPC bridge. Throws if already started. */ + async start(options: FiberRuntimeOptions): Promise { + if (this.fiber) throw new Error("FiberRuntime is already running"); + + const { + config, + storage = { type: "memory" }, + chainSpec, + logLevel = "info", + rpcHost = "127.0.0.1", + rpcPort: preferredRpcPort = 18227, + cors = false, + verbose = false, + } = options; + + // 1. Install Node.js polyfills (idempotent — first call wins for storage mode) + installNodePolyfills(storage); + + // 2. Resolve config → YAML string + databasePrefix + const { yaml, databasePrefix } = resolveFiberConfig(config); + + // 3. Resolve key pairs + const { Fiber, randomSecretKey } = await import("@nervosnetwork/fiber-js"); + const fiberKeyPair = options.fiberKeyPair ?? randomSecretKey(); + const ckbSecretKey = options.ckbSecretKey ?? randomSecretKey(); + + // 4. Start the fiber WASM node + const fiber = new Fiber(); + await fiber + .start( + yaml, + fiberKeyPair, + ckbSecretKey, + chainSpec, + logLevel, + databasePrefix, + ) + .catch((err: unknown) => { + throw new Error( + `FiberRuntime: fiber node failed to start — ${String(err)}`, + ); + }); + + // 5. Warm up: wait for the fiber state machine to be ready + await fiber.invokeCommand("list_channels", [{}]); + + // 6. Start HTTP JSON-RPC bridge + const server = createRpcServer(fiber as FiberLike, { cors, verbose }); + const actualPort = await listenRpcServer(server, preferredRpcPort, rpcHost); + if (actualPort !== preferredRpcPort) { + console.warn( + `[FiberRuntime] Port ${preferredRpcPort} in use; RPC bound to ${actualPort}`, + ); + } + + // 7. Query node info and build runtime info + const rpcUrl = `http://${rpcHost}:${actualPort}`; + const rawInfo = (await fiber.nodeInfo()) as { + node_id?: string; + addresses?: string[]; + }; + const nodeId = rawInfo.node_id ?? ""; + const p2pPeerId = + fiberKeyPair.length === 32 + ? fiberKeyPairToBase58PeerId(fiberKeyPair) + : hexPeerIdToBase58(nodeId); + + let addresses: string[] = Array.isArray(rawInfo.addresses) + ? rawInfo.addresses + : []; + // Build fallback multiaddr when node_info returns no addresses + if (addresses.length === 0 && p2pPeerId) { + const fiberPort = + typeof config === "object" ? (config.fiberPort ?? 8228) : 8228; + addresses = [`/ip4/127.0.0.1/tcp/${fiberPort}/p2p/${p2pPeerId}`]; + } + + this.fiber = fiber as FiberLike; + this.server = server; + this._info = { rpcUrl, rpcPort: actualPort, nodeId, p2pPeerId, addresses }; + return this._info; + } + + /** Stop the RPC bridge and fiber node. Safe to call multiple times. */ + async stop(): Promise { + await closeRpcServer(this.server); + this.server = null; + if (this.fiber) { + try { + await this.fiber.stop(); + } catch { + // ignore stop errors — node may already be shutting down + } + this.fiber = null; + } + this._info = null; + } + + /** Runtime info. Throws if the node has not been started. */ + get info(): FiberRuntimeInfo { + if (!this._info) throw new Error("FiberRuntime has not been started"); + return this._info; + } + + /** Direct proxy to fiber.invokeCommand() for raw RPC access. */ + async invokeCommand(method: string, params?: unknown[]): Promise { + if (!this.fiber) throw new Error("FiberRuntime has not been started"); + return this.fiber.invokeCommand(method, params); + } +} diff --git a/packages/fiber/tests/runtime/index.ts b/packages/fiber/tests/runtime/index.ts new file mode 100644 index 000000000..c0c611db6 --- /dev/null +++ b/packages/fiber/tests/runtime/index.ts @@ -0,0 +1,5 @@ +export * from "./config.js"; +export * from "./fiberRuntime.js"; +export * from "./peerId.js"; +export * from "./polyfill.js"; +export * from "./rpcBridge.js"; diff --git a/packages/fiber/tests/runtime/peerId.ts b/packages/fiber/tests/runtime/peerId.ts new file mode 100644 index 000000000..73d3f187e --- /dev/null +++ b/packages/fiber/tests/runtime/peerId.ts @@ -0,0 +1,81 @@ +/** + * Peer ID utilities for Fiber / libp2p nodes. + * + * The fiber-wasm uses the tentacle/secio peer-identity scheme: + * PeerId = base58(multihash(SHA256, SHA256(pubkeyBytes))) + * + * node_info.node_id returns a hex-encoded secp256k1 public key (possibly the + * CKB key, not the fiber P2P key). To build a valid /p2p/ multiaddr + * for connecting peers, derive the PeerId from the fiber key pair directly + * via fiberKeyPairToBase58PeerId(). + * + * @see https://github.com/driftluo/tentacle/blob/87ef6d9bd659012bb1394f5f3e8ccd4f8e615197/secio/src/peer_id.rs#L59-L73 + */ +import { secp256k1 } from "@noble/curves/secp256k1"; +import bs58 from "bs58"; +import { createHash } from "node:crypto"; + +/** + * Derive the libp2p base58 PeerId (Qm...) from a 33-byte compressed + * secp256k1 public key using the tentacle/secio SHA256 multihash scheme. + */ +export function pubkeyBytesToBase58PeerId(pubkey: Uint8Array): string { + if (pubkey.length !== 33) return ""; + const digest = createHash("sha256").update(pubkey).digest(); + const multihash = new Uint8Array(2 + 32); + multihash[0] = 0x12; // SHA2-256 code + multihash[1] = 0x20; // 32-byte length + multihash.set(digest, 2); + return bs58.encode(multihash); +} + +/** + * Derive the libp2p base58 PeerId from a 32-byte fiber private key. + * This is the identity that fiber-wasm uses for libp2p P2P connections. + */ +export function fiberKeyPairToBase58PeerId(fiberKeyPair: Uint8Array): string { + if (fiberKeyPair.length !== 32) return ""; + const pubkey = secp256k1.getPublicKey(fiberKeyPair, true); + return pubkeyBytesToBase58PeerId(pubkey); +} + +/** + * Convert a hex-encoded node_id (from node_info RPC) to a base58 PeerId. + * node_info may return the CKB key (32 or 33 bytes hex) rather than the fiber + * P2P key. Prefer fiberKeyPairToBase58PeerId() for building valid multiaddrs. + * + * Uses the libp2p PublicKey protobuf encoding (KeyType=Secp256k1) before + * hashing — which is the format used by node_info's identity key. + */ +export function hexPeerIdToBase58(hex: string): string { + const raw = hex.replace(/^0x/i, "").trim(); + if (!/^[0-9a-fA-F]+$/.test(raw)) return hex; + const len = raw.length; + if (len !== 64 && len !== 66) return hex; + + let pubkeyBytes = Buffer.from(raw, "hex"); + // If 32-byte raw key, prepend compression prefix + if (pubkeyBytes.length === 32) { + const compressed = Buffer.alloc(33); + compressed[0] = 0x02; + pubkeyBytes.copy(compressed, 1); + pubkeyBytes = compressed; + } + if (pubkeyBytes.length !== 33) return hex; + + // Libp2p PublicKey protobuf: field 1 = KeyType (Secp256k1=2), field 2 = Data + const protobuf = Buffer.alloc(2 + 2 + 33); + let off = 0; + protobuf[off++] = 0x08; // field 1, varint + protobuf[off++] = 0x02; // Secp256k1 + protobuf[off++] = 0x12; // field 2, bytes + protobuf[off++] = 0x21; // 33 bytes + pubkeyBytes.copy(protobuf, off); + + const digest = createHash("sha256").update(protobuf).digest(); + const multihash = new Uint8Array(2 + 32); + multihash[0] = 0x12; + multihash[1] = 0x20; + multihash.set(digest, 2); + return bs58.encode(multihash); +} diff --git a/packages/fiber/tests/runtime/polyfill.ts b/packages/fiber/tests/runtime/polyfill.ts new file mode 100644 index 000000000..f0894da13 --- /dev/null +++ b/packages/fiber/tests/runtime/polyfill.ts @@ -0,0 +1,191 @@ +/** + * Node.js polyfills for @nervosnetwork/fiber-js. + * + * fiber-js is browser-only: it uses Blob, URL.createObjectURL, and Worker to + * spin up inline Web Workers (the fiber WASM and its DB worker are bundled as + * IIFE strings). This module patches those three globals on globalThis so that + * fiber-js can start inside a Node.js process. + * + * Call installNodePolyfills() BEFORE constructing a Fiber instance. + * Safe to call multiple times — installs only on the first call. + */ +import { existsSync } from "node:fs"; +import { dirname, join } from "node:path"; +import { fileURLToPath } from "node:url"; +import { Worker as NodeWorker } from "node:worker_threads"; +import type { StorageMode } from "./config.js"; + +const __dirname = dirname(fileURLToPath(import.meta.url)); + +// Works from both tests/runtime/ (vitest) and any compiled path: +// join(__dirname, "..", "..", "scripts") → packages/fiber/scripts/ +const SCRIPTS_DIR = join(__dirname, "..", "..", "scripts"); +const WORKER_IDB_WRAPPER_PATH = join(SCRIPTS_DIR, "worker-idb-wrapper.mjs"); + +function checkWrapperExists(): void { + if (!existsSync(WORKER_IDB_WRAPPER_PATH)) { + throw new Error( + `FiberRuntime: worker wrapper not found at ${WORKER_IDB_WRAPPER_PATH}.\n` + + `Ensure packages/fiber/scripts/worker-idb-wrapper.mjs exists.`, + ); + } +} + +/** Adapt a Node.js worker_threads.Worker to the browser Worker interface. */ +function adaptNodeWorker(nodeWorker: NodeWorker): Worker { + type MsgListener = (ev: MessageEvent) => void; + type ErrListener = (ev: ErrorEvent) => void; + + const listeners: { message: MsgListener[]; error: ErrListener[] } = { + message: [], + error: [], + }; + let onmessageFn: MsgListener | null = null; + let onerrorFn: ErrListener | null = null; + + nodeWorker.on("message", (data: unknown) => { + const ev = { data, type: "message" } as MessageEvent; + onmessageFn?.(ev); + listeners.message.forEach((fn) => fn(ev)); + }); + nodeWorker.on("error", (err: Error) => { + const ev = { + message: err.message, + filename: err.stack, + type: "error", + } as ErrorEvent; + onerrorFn?.(ev); + listeners.error.forEach((fn) => fn(ev)); + }); + + return { + postMessage: (data: unknown) => nodeWorker.postMessage(data), + terminate: () => void nodeWorker.terminate(), + get onmessage() { + return onmessageFn; + }, + set onmessage(fn: MsgListener | null) { + onmessageFn = fn; + }, + get onerror() { + return onerrorFn; + }, + set onerror(fn: ErrListener | null) { + onerrorFn = fn; + }, + addEventListener( + type: "message" | "error", + listener: MsgListener | ErrListener, + ) { + (listeners[type] as (MsgListener | ErrListener)[]).push(listener); + }, + removeEventListener( + type: "message" | "error", + listener: MsgListener | ErrListener, + ) { + const list = listeners[type] as (MsgListener | ErrListener)[]; + const i = list.indexOf(listener); + if (i !== -1) list.splice(i, 1); + }, + dispatchEvent: () => true, + } as unknown as Worker; +} + +let installed = false; + +/** + * Install Node.js polyfills for Blob, URL.createObjectURL/revokeObjectURL, + * and Worker so that @nervosnetwork/fiber-js can run in Node.js. + * + * The storage mode is captured at install time and passed to every Worker + * spawned by fiber-js via workerData. Calling this function a second time + * is a no-op — the first call's storage mode wins for the lifetime of the + * process. + */ +export function installNodePolyfills( + storage: StorageMode = { type: "memory" }, +): void { + if (installed) return; + installed = true; + + checkWrapperExists(); + + const OriginalBlob = globalThis.Blob; + const OriginalCreateObjectURL = URL.createObjectURL.bind(URL); + const OriginalRevokeObjectURL = URL.revokeObjectURL?.bind(URL); + + // Map blob objects → their inline JS script text (set during createObjectURL intercept) + const blobToScript = new WeakMap(); + // Map fake blob: URL ids → their script text (looked up when Worker is constructed) + const scriptStore = new Map(); + let blobIdCounter = 0; + + // Intercept Blob construction: capture the inline IIFE script text + function PatchedBlob( + this: Blob, + parts?: BlobPart[], + options?: BlobPropertyBag, + ): Blob { + const blob = new OriginalBlob(parts, options); + if ( + parts?.length === 1 && + typeof parts[0] === "string" && + options?.type === "text/javascript" + ) { + blobToScript.set(blob, parts[0]); + } + return blob; + } + (globalThis as unknown as { Blob: typeof Blob }).Blob = + PatchedBlob as unknown as typeof Blob; + + // Intercept createObjectURL: return a fake blob: id instead of a real URL + URL.createObjectURL = (obj: Blob | MediaSource): string => { + const script = blobToScript.get(obj as Blob); + if (script !== undefined) { + const id = `nodejs-inline-${++blobIdCounter}`; + scriptStore.set(id, script); + return `blob:${id}`; + } + return OriginalCreateObjectURL(obj); + }; + + if (OriginalRevokeObjectURL) { + URL.revokeObjectURL = (url: string): void => { + if (url.startsWith("blob:nodejs-inline-")) { + scriptStore.delete(url.replace("blob:", "")); + return; + } + OriginalRevokeObjectURL(url); + }; + } + + // Worker extra data to pass to the wrapper (storage config) + const workerExtraData: Record = + storage.type === "persistent" + ? { storageType: "persistent", storageDir: storage.dir } + : { storageType: "memory" }; + + // Replace globalThis.Worker: intercept blob: URLs created above and spawn + // real Node.js worker threads running the IDB wrapper + the fiber IIFE + (globalThis as unknown as { Worker: typeof Worker }).Worker = function ( + url: string | URL, + ): Worker { + const urlStr = typeof url === "string" ? url : url.toString(); + if (urlStr.startsWith("blob:nodejs-inline-")) { + const id = urlStr.replace("blob:", ""); + const script = scriptStore.get(id); + scriptStore.delete(id); + if (script) { + const nodeWorker = new NodeWorker(WORKER_IDB_WRAPPER_PATH, { + workerData: { script, ...workerExtraData }, + eval: false, + }); + return adaptNodeWorker(nodeWorker); + } + } + throw new Error( + `FiberRuntime polyfill: only blob:nodejs-inline-* Workers are supported. Got: ${urlStr}`, + ); + } as unknown as typeof Worker; +} diff --git a/packages/fiber/tests/runtime/rpcBridge.ts b/packages/fiber/tests/runtime/rpcBridge.ts new file mode 100644 index 000000000..5b88e742e --- /dev/null +++ b/packages/fiber/tests/runtime/rpcBridge.ts @@ -0,0 +1,125 @@ +import { createServer, type Server } from "node:http"; + +/** Minimal interface required by the RPC bridge (satisfied by fiber-js Fiber). */ +export interface FiberLike { + invokeCommand(name: string, args?: unknown[]): Promise; + stop(): Promise; +} + +export interface RpcBridgeOptions { + /** Add CORS headers (Access-Control-Allow-Origin: *). Default: false. */ + cors?: boolean; + /** Log every RPC request and response to stdout. Default: false. */ + verbose?: boolean; +} + +const CORS_HEADERS = { + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Methods": "POST, OPTIONS", + "Access-Control-Allow-Headers": "Content-Type", +}; + +/** + * Create an HTTP server that exposes a JSON-RPC 2.0 interface over + * fiber.invokeCommand(). POST / is the only accepted endpoint. + */ +export function createRpcServer( + fiber: FiberLike, + options: RpcBridgeOptions = {}, +): Server { + const { cors = false, verbose = false } = options; + + return createServer((req, res) => { + if (cors && req.method === "OPTIONS") { + res.writeHead(204, CORS_HEADERS); + res.end(); + return; + } + if (req.method !== "POST" || req.url !== "/") { + res.writeHead(404, cors ? CORS_HEADERS : {}); + res.end(); + return; + } + + let body = ""; + req.setEncoding("utf8"); + req.on("data", (chunk: string) => { + body += chunk; + }); + req.on("end", () => { + void (async () => { + let id: number | undefined; + const headers: Record = { + "Content-Type": "application/json", + ...(cors ? CORS_HEADERS : {}), + }; + try { + const payload = JSON.parse(body) as { + method: string; + params?: unknown[]; + id: number; + }; + const { method, params = [], id: payloadId } = payload; + id = payloadId; + if (verbose) console.log("[fiber-rpc] →", method, params); + const result = await fiber.invokeCommand(method, params); + if (verbose) console.log("[fiber-rpc] ←", JSON.stringify(result)); + res.writeHead(200, headers); + res.end(JSON.stringify({ jsonrpc: "2.0", result, id })); + } catch (err) { + const message = err instanceof Error ? err.message : String(err); + res.writeHead(200, headers); + res.end( + JSON.stringify({ + jsonrpc: "2.0", + error: { code: -32603, message }, + id: id ?? 0, + }), + ); + } + })(); + }); + }); +} + +/** + * Start the server on preferredPort, retrying up to maxRetries times on + * EADDRINUSE. Resolves to the actual port that was bound. + */ +export function listenRpcServer( + server: Server, + preferredPort: number, + host = "127.0.0.1", + maxRetries = 10, +): Promise { + return new Promise((resolve, reject) => { + const tryPort = (port: number) => { + server.removeAllListeners("error"); + server.removeAllListeners("listening"); + server.once("error", (err: NodeJS.ErrnoException) => { + if (err.code === "EADDRINUSE" && port < preferredPort + maxRetries) { + tryPort(port + 1); + } else { + reject( + err.code === "EADDRINUSE" + ? new Error( + `FiberRuntime: could not bind RPC server to any port in ` + + `[${preferredPort}..${preferredPort + maxRetries - 1}]. ` + + `Stop other fiber-node processes or choose a different port.`, + ) + : err, + ); + } + }); + server.once("listening", () => resolve(port)); + server.listen(port, host); + }; + tryPort(preferredPort); + }); +} + +/** Gracefully close a server (resolves immediately if null). */ +export function closeRpcServer(server: Server | null): Promise { + if (!server) return Promise.resolve(); + return new Promise((resolve) => server.close(() => resolve())); +} diff --git a/packages/fiber/tsconfig.base.json b/packages/fiber/tsconfig.base.json new file mode 100644 index 000000000..7e5ac952b --- /dev/null +++ b/packages/fiber/tsconfig.base.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "target": "es2020", + "incremental": true, + "allowJs": true, + "importHelpers": false, + "declaration": true, + "declarationMap": true, + "experimentalDecorators": true, + "useDefineForClassFields": false, + "esModuleInterop": true, + "strict": true, + "noImplicitAny": true, + "strictBindCallApply": true, + "strictNullChecks": true, + "alwaysStrict": true, + "noFallthroughCasesInSwitch": true, + "forceConsistentCasingInFileNames": true, + "skipLibCheck": true + }, + "include": ["src/**/*"] +} diff --git a/packages/fiber/tsconfig.commonjs.json b/packages/fiber/tsconfig.commonjs.json new file mode 100644 index 000000000..e914ddad0 --- /dev/null +++ b/packages/fiber/tsconfig.commonjs.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.base.json", + "compilerOptions": { + "module": "CommonJS", + "moduleResolution": "node", + "outDir": "./dist.commonjs" + }, + "include": ["src/**/*"] +} diff --git a/packages/fiber/tsconfig.json b/packages/fiber/tsconfig.json new file mode 100644 index 000000000..df22faeca --- /dev/null +++ b/packages/fiber/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.base.json", + "compilerOptions": { + "module": "ESNext", + "moduleResolution": "Bundler", + "outDir": "./dist", + } +} diff --git a/packages/fiber/typedoc.json b/packages/fiber/typedoc.json new file mode 100644 index 000000000..7cb18013c --- /dev/null +++ b/packages/fiber/typedoc.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://typedoc.org/schema.json", + "entryPoints": ["./src/index.ts"], + "extends": ["../../typedoc.base.json"], + "name": "@ckb-ccc fiber" +} diff --git a/packages/fiber/vitest.config.mts b/packages/fiber/vitest.config.mts new file mode 100644 index 000000000..99992c94f --- /dev/null +++ b/packages/fiber/vitest.config.mts @@ -0,0 +1,13 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + include: ["tests/**/*.test.ts"], + sequence: { + shuffle: false, + }, + coverage: { + include: ["src/**/*.ts"], + }, + }, +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d52d483a7..8c7c2dea3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -24,7 +24,7 @@ importers: version: 30.0.0 '@vitest/coverage-v8': specifier: 3.2.4 - version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.5)(yaml@2.8.1)) + version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.43.1)(tsx@4.20.5)(yaml@2.8.1)) jest: specifier: 30.1.1 version: 30.1.1(@types/node@24.3.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.2)) @@ -48,7 +48,7 @@ importers: version: 5.9.2 vitest: specifier: ^3.2.4 - version: 3.2.4(@types/debug@4.1.12)(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.5)(yaml@2.8.1) + version: 3.2.4(@types/debug@4.1.12)(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.43.1)(tsx@4.20.5)(yaml@2.8.1) packages/ccc: dependencies: @@ -88,13 +88,13 @@ importers: version: 2.4.1 eslint: specifier: ^9.34.0 - version: 9.34.0(jiti@2.5.1) + version: 9.34.0(jiti@2.6.1) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.34.0(jiti@2.5.1)) + version: 10.1.8(eslint@9.34.0(jiti@2.6.1)) eslint-plugin-prettier: specifier: ^5.5.4 - version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1))(prettier@3.6.2) + version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.6.1)))(eslint@9.34.0(jiti@2.6.1))(prettier@3.6.2) prettier: specifier: ^3.6.2 version: 3.6.2 @@ -109,7 +109,7 @@ importers: version: 5.9.2 typescript-eslint: specifier: ^8.41.0 - version: 8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + version: 8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) packages/ckb-ccc: dependencies: @@ -125,13 +125,13 @@ importers: version: 2.4.1 eslint: specifier: ^9.34.0 - version: 9.34.0(jiti@2.5.1) + version: 9.34.0(jiti@2.6.1) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.34.0(jiti@2.5.1)) + version: 10.1.8(eslint@9.34.0(jiti@2.6.1)) eslint-plugin-prettier: specifier: ^5.5.4 - version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1))(prettier@3.6.2) + version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.6.1)))(eslint@9.34.0(jiti@2.6.1))(prettier@3.6.2) prettier: specifier: ^3.6.2 version: 3.6.2 @@ -146,7 +146,7 @@ importers: version: 5.9.2 typescript-eslint: specifier: ^8.41.0 - version: 8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + version: 8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) packages/connector: dependencies: @@ -162,13 +162,13 @@ importers: version: 9.34.0 eslint: specifier: ^9.34.0 - version: 9.34.0(jiti@2.5.1) + version: 9.34.0(jiti@2.6.1) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.34.0(jiti@2.5.1)) + version: 10.1.8(eslint@9.34.0(jiti@2.6.1)) eslint-plugin-prettier: specifier: ^5.5.4 - version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1))(prettier@3.6.2) + version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.6.1)))(eslint@9.34.0(jiti@2.6.1))(prettier@3.6.2) prettier: specifier: ^3.6.2 version: 3.6.2 @@ -183,7 +183,7 @@ importers: version: 5.9.2 typescript-eslint: specifier: ^8.41.0 - version: 8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + version: 8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) packages/connector-react: dependencies: @@ -205,13 +205,13 @@ importers: version: 19.2.7 eslint: specifier: ^9.34.0 - version: 9.34.0(jiti@2.5.1) + version: 9.34.0(jiti@2.6.1) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.34.0(jiti@2.5.1)) + version: 10.1.8(eslint@9.34.0(jiti@2.6.1)) eslint-plugin-prettier: specifier: ^5.5.4 - version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1))(prettier@3.6.2) + version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.6.1)))(eslint@9.34.0(jiti@2.6.1))(prettier@3.6.2) prettier: specifier: ^3.6.2 version: 3.6.2 @@ -226,13 +226,13 @@ importers: version: 5.9.2 typescript-eslint: specifier: ^8.41.0 - version: 8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + version: 8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) packages/core: dependencies: '@joyid/ckb': specifier: ^1.1.2 - version: 1.1.2(typescript@5.9.2) + version: 1.1.2(typescript@5.9.2)(zod@3.25.76) '@noble/ciphers': specifier: ^0.5.3 version: 0.5.3 @@ -272,13 +272,13 @@ importers: version: 2.4.1 eslint: specifier: ^9.34.0 - version: 9.34.0(jiti@2.5.1) + version: 9.34.0(jiti@2.6.1) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.34.0(jiti@2.5.1)) + version: 10.1.8(eslint@9.34.0(jiti@2.6.1)) eslint-plugin-prettier: specifier: ^5.5.4 - version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1))(prettier@3.6.2) + version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.6.1)))(eslint@9.34.0(jiti@2.6.1))(prettier@3.6.2) prettier: specifier: ^3.6.2 version: 3.6.2 @@ -293,10 +293,10 @@ importers: version: 5.9.2 typescript-eslint: specifier: ^8.41.0 - version: 8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + version: 8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) vitest: specifier: ^3.2.4 - version: 3.2.4(@types/debug@4.1.12)(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.5)(yaml@2.8.1) + version: 3.2.4(@types/debug@4.1.12)(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.43.1)(tsx@4.20.5)(yaml@2.8.1) packages/demo: dependencies: @@ -375,16 +375,16 @@ importers: version: 19.2.3(@types/react@19.2.7) eslint: specifier: ^9.34.0 - version: 9.34.0(jiti@2.5.1) + version: 9.34.0(jiti@2.6.1) eslint-config-next: specifier: 16.0.10 - version: 16.0.10(@typescript-eslint/parser@8.49.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + version: 16.0.10(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.2))(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.34.0(jiti@2.5.1)) + version: 10.1.8(eslint@9.34.0(jiti@2.6.1)) eslint-plugin-prettier: specifier: ^5.5.4 - version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1))(prettier@3.6.2) + version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.6.1)))(eslint@9.34.0(jiti@2.6.1))(prettier@3.6.2) postcss: specifier: ^8.5.6 version: 8.5.6 @@ -408,10 +408,10 @@ importers: dependencies: '@docusaurus/core': specifier: 3.9.2 - version: 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) + version: 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) '@docusaurus/preset-classic': specifier: 3.9.2 - version: 3.9.2(@algolia/client-search@5.46.0)(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(@types/react@19.2.7)(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(search-insights@2.17.3)(typescript@5.9.2) + version: 3.9.2(@algolia/client-search@5.46.0)(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(@types/react@19.2.7)(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(search-insights@2.17.3)(typescript@5.9.2) '@mdx-js/react': specifier: ^3.1.1 version: 3.1.1(@types/react@19.2.7)(react@19.2.3) @@ -455,13 +455,13 @@ importers: version: 2.4.1 eslint: specifier: ^9.34.0 - version: 9.34.0(jiti@2.5.1) + version: 9.34.0(jiti@2.6.1) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.34.0(jiti@2.5.1)) + version: 10.1.8(eslint@9.34.0(jiti@2.6.1)) eslint-plugin-prettier: specifier: ^5.5.4 - version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1))(prettier@3.6.2) + version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.6.1)))(eslint@9.34.0(jiti@2.6.1))(prettier@3.6.2) prettier: specifier: ^3.6.2 version: 3.6.2 @@ -476,7 +476,7 @@ importers: version: 5.9.2 typescript-eslint: specifier: ^8.41.0 - version: 8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + version: 8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) packages/examples: dependencies: @@ -492,13 +492,13 @@ importers: version: 9.34.0 eslint: specifier: ^9.34.0 - version: 9.34.0(jiti@2.5.1) + version: 9.34.0(jiti@2.6.1) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.34.0(jiti@2.5.1)) + version: 10.1.8(eslint@9.34.0(jiti@2.6.1)) eslint-plugin-prettier: specifier: ^5.5.4 - version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1))(prettier@3.6.2) + version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.6.1)))(eslint@9.34.0(jiti@2.6.1))(prettier@3.6.2) prettier: specifier: ^3.6.2 version: 3.6.2 @@ -513,7 +513,7 @@ importers: version: 5.9.2 typescript-eslint: specifier: ^8.41.0 - version: 8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + version: 8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) packages/faucet: dependencies: @@ -583,19 +583,19 @@ importers: version: 6.0.3 '@typescript-eslint/eslint-plugin': specifier: ^8.41.0 - version: 8.41.0(@typescript-eslint/parser@8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + version: 8.41.0(@typescript-eslint/parser@8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.41.0 - version: 8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + version: 8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) eslint: specifier: ^9.34.0 - version: 9.34.0(jiti@2.5.1) + version: 9.34.0(jiti@2.6.1) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.34.0(jiti@2.5.1)) + version: 10.1.8(eslint@9.34.0(jiti@2.6.1)) eslint-plugin-prettier: specifier: ^5.5.4 - version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1))(prettier@3.6.2) + version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.6.1)))(eslint@9.34.0(jiti@2.6.1))(prettier@3.6.2) globals: specifier: ^16.3.0 version: 16.3.0 @@ -631,7 +631,74 @@ importers: version: 5.9.2 typescript-eslint: specifier: ^8.41.0 - version: 8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + version: 8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) + + packages/fiber: + dependencies: + '@ckb-ccc/core': + specifier: workspace:* + version: link:../core + devDependencies: + '@eslint/js': + specifier: ^9.34.0 + version: 9.34.0 + '@nervosnetwork/fiber-js': + specifier: ^0.7.0 + version: 0.7.0 + '@noble/curves': + specifier: ^1.7.0 + version: 1.9.7 + '@types/node': + specifier: ^24.3.0 + version: 24.3.0 + bs58: + specifier: ^6.0.0 + version: 6.0.0 + copyfiles: + specifier: ^2.4.1 + version: 2.4.1 + dotenv: + specifier: ^17.2.1 + version: 17.2.1 + eslint: + specifier: ^9.34.0 + version: 9.34.0(jiti@2.6.1) + eslint-config-prettier: + specifier: ^10.1.8 + version: 10.1.8(eslint@9.34.0(jiti@2.6.1)) + eslint-plugin-prettier: + specifier: ^5.5.4 + version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.6.1)))(eslint@9.34.0(jiti@2.6.1))(prettier@3.6.2) + fake-indexeddb: + specifier: ^6.2.5 + version: 6.2.5 + prettier: + specifier: ^3.6.2 + version: 3.6.2 + prettier-linter-helpers: + specifier: ^1.0.1 + version: 1.0.1 + prettier-plugin-organize-imports: + specifier: ^4.2.0 + version: 4.2.0(prettier@3.6.2)(typescript@5.9.2) + rimraf: + specifier: ^6.0.1 + version: 6.0.1 + tsx: + specifier: ^4.20.5 + version: 4.20.5 + typescript: + specifier: ^5.9.2 + version: 5.9.2 + typescript-eslint: + specifier: ^8.41.0 + version: 8.49.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) + vitest: + specifier: ^3.2.4 + version: 3.2.4(@types/debug@4.1.12)(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.43.1)(tsx@4.20.5)(yaml@2.8.1) + web-worker: + specifier: ^1.5.0 + version: 1.5.0 packages/joy-id: dependencies: @@ -640,10 +707,10 @@ importers: version: link:../core '@joyid/ckb': specifier: ^1.1.2 - version: 1.1.2(typescript@5.9.2) + version: 1.1.2(typescript@5.9.2)(zod@3.25.76) '@joyid/common': specifier: ^0.2.1 - version: 0.2.1(typescript@5.9.2) + version: 0.2.1(typescript@5.9.2)(zod@3.25.76) devDependencies: '@eslint/js': specifier: ^9.34.0 @@ -653,13 +720,13 @@ importers: version: 2.4.1 eslint: specifier: ^9.34.0 - version: 9.34.0(jiti@2.5.1) + version: 9.34.0(jiti@2.6.1) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.34.0(jiti@2.5.1)) + version: 10.1.8(eslint@9.34.0(jiti@2.6.1)) eslint-plugin-prettier: specifier: ^5.5.4 - version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1))(prettier@3.6.2) + version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.6.1)))(eslint@9.34.0(jiti@2.6.1))(prettier@3.6.2) prettier: specifier: ^3.6.2 version: 3.6.2 @@ -674,7 +741,7 @@ importers: version: 5.9.2 typescript-eslint: specifier: ^8.41.0 - version: 8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + version: 8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) packages/lumos-patches: dependencies: @@ -698,7 +765,7 @@ importers: version: 0.24.0-next.2 '@joyid/ckb': specifier: ^1.1.2 - version: 1.1.2(typescript@5.9.2) + version: 1.1.2(typescript@5.9.2)(zod@3.25.76) devDependencies: '@eslint/js': specifier: ^9.34.0 @@ -708,13 +775,13 @@ importers: version: 2.4.1 eslint: specifier: ^9.34.0 - version: 9.34.0(jiti@2.5.1) + version: 9.34.0(jiti@2.6.1) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.34.0(jiti@2.5.1)) + version: 10.1.8(eslint@9.34.0(jiti@2.6.1)) eslint-plugin-prettier: specifier: ^5.5.4 - version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1))(prettier@3.6.2) + version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.6.1)))(eslint@9.34.0(jiti@2.6.1))(prettier@3.6.2) prettier: specifier: ^3.6.2 version: 3.6.2 @@ -729,7 +796,7 @@ importers: version: 5.9.2 typescript-eslint: specifier: ^8.41.0 - version: 8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + version: 8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) packages/nip07: dependencies: @@ -745,13 +812,13 @@ importers: version: 2.4.1 eslint: specifier: ^9.34.0 - version: 9.34.0(jiti@2.5.1) + version: 9.34.0(jiti@2.6.1) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.34.0(jiti@2.5.1)) + version: 10.1.8(eslint@9.34.0(jiti@2.6.1)) eslint-plugin-prettier: specifier: ^5.5.4 - version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1))(prettier@3.6.2) + version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.6.1)))(eslint@9.34.0(jiti@2.6.1))(prettier@3.6.2) prettier: specifier: ^3.6.2 version: 3.6.2 @@ -766,7 +833,7 @@ importers: version: 5.9.2 typescript-eslint: specifier: ^8.41.0 - version: 8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + version: 8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) packages/okx: dependencies: @@ -788,13 +855,13 @@ importers: version: 2.4.1 eslint: specifier: ^9.34.0 - version: 9.34.0(jiti@2.5.1) + version: 9.34.0(jiti@2.6.1) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.34.0(jiti@2.5.1)) + version: 10.1.8(eslint@9.34.0(jiti@2.6.1)) eslint-plugin-prettier: specifier: ^5.5.4 - version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1))(prettier@3.6.2) + version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.6.1)))(eslint@9.34.0(jiti@2.6.1))(prettier@3.6.2) prettier: specifier: ^3.6.2 version: 3.6.2 @@ -809,7 +876,7 @@ importers: version: 5.9.2 typescript-eslint: specifier: ^8.41.0 - version: 8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + version: 8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) packages/playground: dependencies: @@ -891,16 +958,16 @@ importers: version: 1.18.8 eslint: specifier: ^9.34.0 - version: 9.34.0(jiti@2.5.1) + version: 9.34.0(jiti@2.6.1) eslint-config-next: specifier: 16.0.10 - version: 16.0.10(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + version: 16.0.10(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.2))(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.34.0(jiti@2.5.1)) + version: 10.1.8(eslint@9.34.0(jiti@2.6.1)) eslint-plugin-prettier: specifier: ^5.5.4 - version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1))(prettier@3.6.2) + version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.6.1)))(eslint@9.34.0(jiti@2.6.1))(prettier@3.6.2) postcss: specifier: ^8.5.6 version: 8.5.6 @@ -931,13 +998,13 @@ importers: version: 2.4.1 eslint: specifier: ^9.34.0 - version: 9.34.0(jiti@2.5.1) + version: 9.34.0(jiti@2.6.1) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.34.0(jiti@2.5.1)) + version: 10.1.8(eslint@9.34.0(jiti@2.6.1)) eslint-plugin-prettier: specifier: ^5.5.4 - version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1))(prettier@3.6.2) + version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.6.1)))(eslint@9.34.0(jiti@2.6.1))(prettier@3.6.2) prettier: specifier: ^3.6.2 version: 3.6.2 @@ -952,7 +1019,7 @@ importers: version: 5.9.2 typescript-eslint: specifier: ^8.41.0 - version: 8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + version: 8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) packages/shell: dependencies: @@ -977,13 +1044,13 @@ importers: version: 2.4.1 eslint: specifier: ^9.34.0 - version: 9.34.0(jiti@2.5.1) + version: 9.34.0(jiti@2.6.1) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.34.0(jiti@2.5.1)) + version: 10.1.8(eslint@9.34.0(jiti@2.6.1)) eslint-plugin-prettier: specifier: ^5.5.4 - version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1))(prettier@3.6.2) + version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.6.1)))(eslint@9.34.0(jiti@2.6.1))(prettier@3.6.2) prettier: specifier: ^3.6.2 version: 3.6.2 @@ -998,7 +1065,7 @@ importers: version: 5.9.2 typescript-eslint: specifier: ^8.41.0 - version: 8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + version: 8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) packages/spore: dependencies: @@ -1023,13 +1090,13 @@ importers: version: 17.2.1 eslint: specifier: ^9.34.0 - version: 9.34.0(jiti@2.5.1) + version: 9.34.0(jiti@2.6.1) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.34.0(jiti@2.5.1)) + version: 10.1.8(eslint@9.34.0(jiti@2.6.1)) eslint-plugin-prettier: specifier: ^5.5.4 - version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1))(prettier@3.6.2) + version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.6.1)))(eslint@9.34.0(jiti@2.6.1))(prettier@3.6.2) prettier: specifier: ^3.6.2 version: 3.6.2 @@ -1044,10 +1111,10 @@ importers: version: 5.9.2 typescript-eslint: specifier: ^8.41.0 - version: 8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + version: 8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) vitest: specifier: ^3.2.4 - version: 3.2.4(@types/debug@4.1.12)(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.5)(yaml@2.8.1) + version: 3.2.4(@types/debug@4.1.12)(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.43.1)(tsx@4.20.5)(yaml@2.8.1) packages/ssri: dependencies: @@ -1066,13 +1133,13 @@ importers: version: 2.4.1 eslint: specifier: ^9.34.0 - version: 9.34.0(jiti@2.5.1) + version: 9.34.0(jiti@2.6.1) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.34.0(jiti@2.5.1)) + version: 10.1.8(eslint@9.34.0(jiti@2.6.1)) eslint-plugin-prettier: specifier: ^5.5.4 - version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1))(prettier@3.6.2) + version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.6.1)))(eslint@9.34.0(jiti@2.6.1))(prettier@3.6.2) prettier: specifier: ^3.6.2 version: 3.6.2 @@ -1087,7 +1154,7 @@ importers: version: 5.9.2 typescript-eslint: specifier: ^8.41.0 - version: 8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + version: 8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) packages/tests: devDependencies: @@ -1099,13 +1166,13 @@ importers: version: 9.34.0 eslint: specifier: ^9.34.0 - version: 9.34.0(jiti@2.5.1) + version: 9.34.0(jiti@2.6.1) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.34.0(jiti@2.5.1)) + version: 10.1.8(eslint@9.34.0(jiti@2.6.1)) eslint-plugin-prettier: specifier: ^5.5.4 - version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1))(prettier@3.6.2) + version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.6.1)))(eslint@9.34.0(jiti@2.6.1))(prettier@3.6.2) prettier: specifier: ^3.6.2 version: 3.6.2 @@ -1120,7 +1187,7 @@ importers: version: 5.9.2 typescript-eslint: specifier: ^8.41.0 - version: 8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + version: 8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) packages/udt: dependencies: @@ -1142,13 +1209,13 @@ importers: version: 2.4.1 eslint: specifier: ^9.34.0 - version: 9.34.0(jiti@2.5.1) + version: 9.34.0(jiti@2.6.1) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.34.0(jiti@2.5.1)) + version: 10.1.8(eslint@9.34.0(jiti@2.6.1)) eslint-plugin-prettier: specifier: ^5.5.4 - version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1))(prettier@3.6.2) + version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.6.1)))(eslint@9.34.0(jiti@2.6.1))(prettier@3.6.2) prettier: specifier: ^3.6.2 version: 3.6.2 @@ -1163,7 +1230,7 @@ importers: version: 5.9.2 typescript-eslint: specifier: ^8.41.0 - version: 8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + version: 8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) packages/uni-sat: dependencies: @@ -1179,13 +1246,13 @@ importers: version: 2.4.1 eslint: specifier: ^9.34.0 - version: 9.34.0(jiti@2.5.1) + version: 9.34.0(jiti@2.6.1) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.34.0(jiti@2.5.1)) + version: 10.1.8(eslint@9.34.0(jiti@2.6.1)) eslint-plugin-prettier: specifier: ^5.5.4 - version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1))(prettier@3.6.2) + version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.6.1)))(eslint@9.34.0(jiti@2.6.1))(prettier@3.6.2) prettier: specifier: ^3.6.2 version: 3.6.2 @@ -1200,7 +1267,7 @@ importers: version: 5.9.2 typescript-eslint: specifier: ^8.41.0 - version: 8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + version: 8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) packages/utxo-global: dependencies: @@ -1216,13 +1283,13 @@ importers: version: 2.4.1 eslint: specifier: ^9.34.0 - version: 9.34.0(jiti@2.5.1) + version: 9.34.0(jiti@2.6.1) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.34.0(jiti@2.5.1)) + version: 10.1.8(eslint@9.34.0(jiti@2.6.1)) eslint-plugin-prettier: specifier: ^5.5.4 - version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1))(prettier@3.6.2) + version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.6.1)))(eslint@9.34.0(jiti@2.6.1))(prettier@3.6.2) prettier: specifier: ^3.6.2 version: 3.6.2 @@ -1237,7 +1304,7 @@ importers: version: 5.9.2 typescript-eslint: specifier: ^8.41.0 - version: 8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + version: 8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) packages/xverse: dependencies: @@ -1256,13 +1323,13 @@ importers: version: 2.4.1 eslint: specifier: ^9.34.0 - version: 9.34.0(jiti@2.5.1) + version: 9.34.0(jiti@2.6.1) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.34.0(jiti@2.5.1)) + version: 10.1.8(eslint@9.34.0(jiti@2.6.1)) eslint-plugin-prettier: specifier: ^5.5.4 - version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1))(prettier@3.6.2) + version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.6.1)))(eslint@9.34.0(jiti@2.6.1))(prettier@3.6.2) prettier: specifier: ^3.6.2 version: 3.6.2 @@ -1277,7 +1344,7 @@ importers: version: 5.9.2 typescript-eslint: specifier: ^8.41.0 - version: 8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + version: 8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) packages: @@ -2635,102 +2702,204 @@ packages: '@emnapi/wasi-threads@1.0.4': resolution: {integrity: sha512-PJR+bOmMOPH8AtcTGAyYNiuJ3/Fcoj2XN/gBEWzDIKh254XO+mM9XoXHk5GNEhodxeMznbg7BlRojVbKN+gC6g==} + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + '@esbuild/aix-ppc64@0.25.9': resolution: {integrity: sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm64@0.25.9': resolution: {integrity: sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==} engines: {node: '>=18'} cpu: [arm64] os: [android] + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + '@esbuild/android-arm@0.25.9': resolution: {integrity: sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==} engines: {node: '>=18'} cpu: [arm] os: [android] + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + '@esbuild/android-x64@0.25.9': resolution: {integrity: sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==} engines: {node: '>=18'} cpu: [x64] os: [android] + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-arm64@0.25.9': resolution: {integrity: sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + '@esbuild/darwin-x64@0.25.9': resolution: {integrity: sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==} engines: {node: '>=18'} cpu: [x64] os: [darwin] + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-arm64@0.25.9': resolution: {integrity: sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + '@esbuild/freebsd-x64@0.25.9': resolution: {integrity: sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm64@0.25.9': resolution: {integrity: sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==} engines: {node: '>=18'} cpu: [arm64] os: [linux] + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + '@esbuild/linux-arm@0.25.9': resolution: {integrity: sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==} engines: {node: '>=18'} cpu: [arm] os: [linux] + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-ia32@0.25.9': resolution: {integrity: sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==} engines: {node: '>=18'} cpu: [ia32] os: [linux] + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-loong64@0.25.9': resolution: {integrity: sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==} engines: {node: '>=18'} cpu: [loong64] os: [linux] + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-mips64el@0.25.9': resolution: {integrity: sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-ppc64@0.25.9': resolution: {integrity: sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-riscv64@0.25.9': resolution: {integrity: sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-s390x@0.25.9': resolution: {integrity: sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==} engines: {node: '>=18'} cpu: [s390x] os: [linux] + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + '@esbuild/linux-x64@0.25.9': resolution: {integrity: sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==} engines: {node: '>=18'} @@ -2743,6 +2912,12 @@ packages: cpu: [arm64] os: [netbsd] + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + '@esbuild/netbsd-x64@0.25.9': resolution: {integrity: sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==} engines: {node: '>=18'} @@ -2755,6 +2930,12 @@ packages: cpu: [arm64] os: [openbsd] + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + '@esbuild/openbsd-x64@0.25.9': resolution: {integrity: sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==} engines: {node: '>=18'} @@ -2767,24 +2948,48 @@ packages: cpu: [arm64] os: [openharmony] + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + '@esbuild/sunos-x64@0.25.9': resolution: {integrity: sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==} engines: {node: '>=18'} cpu: [x64] os: [sunos] + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-arm64@0.25.9': resolution: {integrity: sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==} engines: {node: '>=18'} cpu: [arm64] os: [win32] + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-ia32@0.25.9': resolution: {integrity: sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==} engines: {node: '>=18'} cpu: [ia32] os: [win32] + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + '@esbuild/win32-x64@0.25.9': resolution: {integrity: sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==} engines: {node: '>=18'} @@ -3425,6 +3630,9 @@ packages: '@nervosnetwork/ckb-types@0.109.5': resolution: {integrity: sha512-5jQNjFw76YCd+Ppl+0RvBWzxwvWaKfWC5wjVFFdNAieX7xksCHfZFIeow8je7AF8uVypwe56WlLBlblxw9NBBQ==} + '@nervosnetwork/fiber-js@0.7.0': + resolution: {integrity: sha512-CUAPJI8DfqIqSoKMxHvWGYXDX/tPE7F7isygTKzwVKEEuhGb5xWwdlVLK3r6/Uwgi0WAq9lPFobS8rUNgVQkqQ==} + '@nestjs/cli@11.0.10': resolution: {integrity: sha512-4waDT0yGWANg0pKz4E47+nUrqIJv/UqrZ5wLPkCqc7oMGRMWKAaw1NDZ9rKsaqhqvxb2LfI5+uXOWr4yi94DOQ==} engines: {node: '>= 20.11'} @@ -4885,6 +5093,9 @@ packages: resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} engines: {node: '>= 0.4'} + async-mutex@0.5.0: + resolution: {integrity: sha512-1A94B18jkJ3DYq284ohPxoXbfTA5HsQ7/Mf4DEhcyLx3Bz27Rh59iScbB6EPiP+B+joue6YCxcMXSbFC1tZKwA==} + asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} @@ -5953,6 +6164,11 @@ packages: esast-util-from-js@2.0.1: resolution: {integrity: sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==} + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + esbuild@0.25.9: resolution: {integrity: sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==} engines: {node: '>=18'} @@ -6268,6 +6484,10 @@ packages: extendable-error@0.1.7: resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} + fake-indexeddb@6.2.5: + resolution: {integrity: sha512-CGnyrvbhPlWYMngksqrSSUT1BAVP49dZocrHuK0SvtR0D5TMs5wP0o3j7jexDJW01KSadjBp1M/71o/KR3nD1w==} + engines: {node: '>=18'} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -6539,16 +6759,18 @@ packages: glob@10.4.5: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + 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 glob@11.0.3: resolution: {integrity: sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==} engines: {node: 20 || >=22} + 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 glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Glob versions prior to v9 are no longer supported + 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 global-dirs@3.0.1: resolution: {integrity: sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==} @@ -7332,6 +7554,10 @@ packages: resolution: {integrity: sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==} hasBin: true + jiti@2.6.1: + resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} + hasBin: true + joi@17.13.3: resolution: {integrity: sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==} @@ -7450,70 +7676,140 @@ packages: libphonenumber-js@1.12.14: resolution: {integrity: sha512-HBAMAV7f3yGYy7ZZN5FxQ1tXJTwC77G5/96Yn/SH/HPyKX2EMLGFuCIYUmdLU7CxxJlQcvJymP/PGLzyapurhQ==} + lightningcss-android-arm64@1.31.1: + resolution: {integrity: sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + lightningcss-darwin-arm64@1.30.1: resolution: {integrity: sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [darwin] + lightningcss-darwin-arm64@1.31.1: + resolution: {integrity: sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + lightningcss-darwin-x64@1.30.1: resolution: {integrity: sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [darwin] + lightningcss-darwin-x64@1.31.1: + resolution: {integrity: sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + lightningcss-freebsd-x64@1.30.1: resolution: {integrity: sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [freebsd] + lightningcss-freebsd-x64@1.31.1: + resolution: {integrity: sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + lightningcss-linux-arm-gnueabihf@1.30.1: resolution: {integrity: sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==} engines: {node: '>= 12.0.0'} cpu: [arm] os: [linux] + lightningcss-linux-arm-gnueabihf@1.31.1: + resolution: {integrity: sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + lightningcss-linux-arm64-gnu@1.30.1: resolution: {integrity: sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + lightningcss-linux-arm64-gnu@1.31.1: + resolution: {integrity: sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + lightningcss-linux-arm64-musl@1.30.1: resolution: {integrity: sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + lightningcss-linux-arm64-musl@1.31.1: + resolution: {integrity: sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + lightningcss-linux-x64-gnu@1.30.1: resolution: {integrity: sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + lightningcss-linux-x64-gnu@1.31.1: + resolution: {integrity: sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + lightningcss-linux-x64-musl@1.30.1: resolution: {integrity: sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + lightningcss-linux-x64-musl@1.31.1: + resolution: {integrity: sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + lightningcss-win32-arm64-msvc@1.30.1: resolution: {integrity: sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [win32] + lightningcss-win32-arm64-msvc@1.31.1: + resolution: {integrity: sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + lightningcss-win32-x64-msvc@1.30.1: resolution: {integrity: sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [win32] + lightningcss-win32-x64-msvc@1.31.1: + resolution: {integrity: sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + lightningcss@1.30.1: resolution: {integrity: sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==} engines: {node: '>= 12.0.0'} + lightningcss@1.31.1: + resolution: {integrity: sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ==} + engines: {node: '>= 12.0.0'} + lilconfig@3.1.3: resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} engines: {node: '>=14'} @@ -8810,8 +9106,8 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} - prettier-linter-helpers@1.0.0: - resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} + prettier-linter-helpers@1.0.1: + resolution: {integrity: sha512-SxToR7P8Y2lWmv/kTzVLC1t/GDI2WGjMwNhLLE9qtH8Q13C+aEmuRlzDst4Up4s0Wc8sF2M+J57iB3cMLqftfg==} engines: {node: '>=6.0.0'} prettier-plugin-organize-imports@4.2.0: @@ -9588,6 +9884,9 @@ packages: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} engines: {node: '>= 0.4'} + stream-browserify@3.0.0: + resolution: {integrity: sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==} + streamsearch@1.1.0: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} @@ -9770,6 +10069,7 @@ packages: tar@7.4.3: resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} engines: {node: '>=18'} + deprecated: Old versions of tar 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 term-size@2.2.1: resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} @@ -10282,6 +10582,37 @@ packages: engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true + vite@5.4.21: + resolution: {integrity: sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + vite@7.1.3: resolution: {integrity: sha512-OOUi5zjkDxYrKhTV3V7iKsoS37VUM7v40+HuwEmcrsf11Cdx9y3DIr2Px6liIcZFwt3XSRpQvFpL3WVy7ApkGw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -10366,6 +10697,9 @@ packages: web-namespaces@2.0.1: resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} + web-worker@1.5.0: + resolution: {integrity: sha512-RiMReJrTAiA+mBjGONMnjVDP2u3p9R1vkcGz6gDIrOMT3oGuYwX2WRMYI9ipkphSuE5XKEhydbhNEJh4NY9mlw==} + webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} @@ -10626,8 +10960,8 @@ packages: peerDependencies: zod: ^3.25.0 || ^4.0.0 - zod@4.1.13: - resolution: {integrity: sha512-AvvthqfqrAhNH9dnfmrfKzX5upOdjUVJYFqNSlkmGf64gRaTzlPwz99IHYnVs28qYAybvAlBV+H7pn0saFY4Ig==} + zod@3.25.76: + resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} @@ -12209,7 +12543,7 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/bundler@3.9.2(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2)': + '@docusaurus/bundler@3.9.2(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2)': dependencies: '@babel/core': 7.28.3 '@docusaurus/babel': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) @@ -12221,7 +12555,7 @@ snapshots: clean-css: 5.3.3 copy-webpack-plugin: 11.0.0(webpack@5.101.3) css-loader: 6.11.0(webpack@5.101.3) - css-minimizer-webpack-plugin: 5.0.1(clean-css@5.3.3)(lightningcss@1.30.1)(webpack@5.101.3) + css-minimizer-webpack-plugin: 5.0.1(clean-css@5.3.3)(lightningcss@1.31.1)(webpack@5.101.3) cssnano: 6.1.2(postcss@8.5.6) file-loader: 6.2.0(webpack@5.101.3) html-minifier-terser: 7.2.0 @@ -12251,10 +12585,10 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/core@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2)': + '@docusaurus/core@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2)': dependencies: '@docusaurus/babel': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@docusaurus/bundler': 3.9.2(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) + '@docusaurus/bundler': 3.9.2(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) '@docusaurus/logger': 3.9.2 '@docusaurus/mdx-loader': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@docusaurus/utils': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) @@ -12383,13 +12717,13 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/plugin-content-blog@3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2))(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2)': + '@docusaurus/plugin-content-blog@3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2))(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) '@docusaurus/logger': 3.9.2 '@docusaurus/mdx-loader': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) - '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2))(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2))(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@docusaurus/types': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@docusaurus/utils': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@docusaurus/utils-common': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) @@ -12425,13 +12759,13 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2)': + '@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) '@docusaurus/logger': 3.9.2 '@docusaurus/mdx-loader': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@docusaurus/module-type-aliases': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2))(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2))(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@docusaurus/types': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@docusaurus/utils': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@docusaurus/utils-common': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) @@ -12466,9 +12800,9 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-content-pages@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2)': + '@docusaurus/plugin-content-pages@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) '@docusaurus/mdx-loader': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@docusaurus/types': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@docusaurus/utils': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) @@ -12497,9 +12831,9 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-css-cascade-layers@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2)': + '@docusaurus/plugin-css-cascade-layers@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) '@docusaurus/types': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@docusaurus/utils': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@docusaurus/utils-validation': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) @@ -12525,9 +12859,9 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-debug@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2)': + '@docusaurus/plugin-debug@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) '@docusaurus/types': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@docusaurus/utils': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) fs-extra: 11.3.1 @@ -12554,9 +12888,9 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-google-analytics@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2)': + '@docusaurus/plugin-google-analytics@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) '@docusaurus/types': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@docusaurus/utils-validation': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) react: 19.2.3 @@ -12581,9 +12915,9 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-google-gtag@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2)': + '@docusaurus/plugin-google-gtag@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) '@docusaurus/types': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@docusaurus/utils-validation': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@types/gtag.js': 0.0.12 @@ -12609,9 +12943,9 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-google-tag-manager@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2)': + '@docusaurus/plugin-google-tag-manager@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) '@docusaurus/types': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@docusaurus/utils-validation': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) react: 19.2.3 @@ -12636,9 +12970,9 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-sitemap@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2)': + '@docusaurus/plugin-sitemap@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) '@docusaurus/logger': 3.9.2 '@docusaurus/types': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@docusaurus/utils': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) @@ -12668,9 +13002,9 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-svgr@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2)': + '@docusaurus/plugin-svgr@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) '@docusaurus/types': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@docusaurus/utils': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@docusaurus/utils-validation': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) @@ -12699,22 +13033,22 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/preset-classic@3.9.2(@algolia/client-search@5.46.0)(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(@types/react@19.2.7)(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(search-insights@2.17.3)(typescript@5.9.2)': - dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) - '@docusaurus/plugin-content-blog': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2))(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) - '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) - '@docusaurus/plugin-content-pages': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) - '@docusaurus/plugin-css-cascade-layers': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) - '@docusaurus/plugin-debug': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) - '@docusaurus/plugin-google-analytics': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) - '@docusaurus/plugin-google-gtag': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) - '@docusaurus/plugin-google-tag-manager': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) - '@docusaurus/plugin-sitemap': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) - '@docusaurus/plugin-svgr': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) - '@docusaurus/theme-classic': 3.9.2(@types/react@19.2.7)(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) - '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2))(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@docusaurus/theme-search-algolia': 3.9.2(@algolia/client-search@5.46.0)(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(@types/react@19.2.7)(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(search-insights@2.17.3)(typescript@5.9.2) + '@docusaurus/preset-classic@3.9.2(@algolia/client-search@5.46.0)(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(@types/react@19.2.7)(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(search-insights@2.17.3)(typescript@5.9.2)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) + '@docusaurus/plugin-content-blog': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2))(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) + '@docusaurus/plugin-content-pages': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) + '@docusaurus/plugin-css-cascade-layers': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) + '@docusaurus/plugin-debug': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) + '@docusaurus/plugin-google-analytics': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) + '@docusaurus/plugin-google-gtag': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) + '@docusaurus/plugin-google-tag-manager': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) + '@docusaurus/plugin-sitemap': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) + '@docusaurus/plugin-svgr': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) + '@docusaurus/theme-classic': 3.9.2(@types/react@19.2.7)(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2))(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/theme-search-algolia': 3.9.2(@algolia/client-search@5.46.0)(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(@types/react@19.2.7)(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(search-insights@2.17.3)(typescript@5.9.2) '@docusaurus/types': 3.9.2(acorn@8.15.0)(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) @@ -12745,16 +13079,16 @@ snapshots: '@types/react': 19.2.7 react: 19.2.3 - '@docusaurus/theme-classic@3.9.2(@types/react@19.2.7)(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2)': + '@docusaurus/theme-classic@3.9.2(@types/react@19.2.7)(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) '@docusaurus/logger': 3.9.2 '@docusaurus/mdx-loader': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@docusaurus/module-type-aliases': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@docusaurus/plugin-content-blog': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2))(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) - '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) - '@docusaurus/plugin-content-pages': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) - '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2))(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/plugin-content-blog': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2))(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) + '@docusaurus/plugin-content-pages': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2))(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@docusaurus/theme-translations': 3.9.2 '@docusaurus/types': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@docusaurus/utils': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) @@ -12793,11 +13127,11 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/theme-common@3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2))(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@docusaurus/theme-common@3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2))(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': dependencies: '@docusaurus/mdx-loader': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@docusaurus/module-type-aliases': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) '@docusaurus/utils': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@docusaurus/utils-common': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@types/history': 4.7.11 @@ -12818,13 +13152,13 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/theme-search-algolia@3.9.2(@algolia/client-search@5.46.0)(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(@types/react@19.2.7)(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(search-insights@2.17.3)(typescript@5.9.2)': + '@docusaurus/theme-search-algolia@3.9.2(@algolia/client-search@5.46.0)(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(@types/react@19.2.7)(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(search-insights@2.17.3)(typescript@5.9.2)': dependencies: '@docsearch/react': 3.9.0(@algolia/client-search@5.46.0)(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(search-insights@2.17.3) - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) '@docusaurus/logger': 3.9.2 - '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) - '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2))(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3))(acorn@8.15.0)(lightningcss@1.31.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2))(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@docusaurus/theme-translations': 3.9.2 '@docusaurus/utils': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@docusaurus/utils-validation': 3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) @@ -12972,81 +13306,150 @@ snapshots: tslib: 2.8.1 optional: true + '@esbuild/aix-ppc64@0.21.5': + optional: true + '@esbuild/aix-ppc64@0.25.9': optional: true + '@esbuild/android-arm64@0.21.5': + optional: true + '@esbuild/android-arm64@0.25.9': optional: true + '@esbuild/android-arm@0.21.5': + optional: true + '@esbuild/android-arm@0.25.9': optional: true + '@esbuild/android-x64@0.21.5': + optional: true + '@esbuild/android-x64@0.25.9': optional: true + '@esbuild/darwin-arm64@0.21.5': + optional: true + '@esbuild/darwin-arm64@0.25.9': optional: true + '@esbuild/darwin-x64@0.21.5': + optional: true + '@esbuild/darwin-x64@0.25.9': optional: true + '@esbuild/freebsd-arm64@0.21.5': + optional: true + '@esbuild/freebsd-arm64@0.25.9': optional: true + '@esbuild/freebsd-x64@0.21.5': + optional: true + '@esbuild/freebsd-x64@0.25.9': optional: true + '@esbuild/linux-arm64@0.21.5': + optional: true + '@esbuild/linux-arm64@0.25.9': optional: true + '@esbuild/linux-arm@0.21.5': + optional: true + '@esbuild/linux-arm@0.25.9': optional: true + '@esbuild/linux-ia32@0.21.5': + optional: true + '@esbuild/linux-ia32@0.25.9': optional: true + '@esbuild/linux-loong64@0.21.5': + optional: true + '@esbuild/linux-loong64@0.25.9': optional: true + '@esbuild/linux-mips64el@0.21.5': + optional: true + '@esbuild/linux-mips64el@0.25.9': optional: true + '@esbuild/linux-ppc64@0.21.5': + optional: true + '@esbuild/linux-ppc64@0.25.9': optional: true + '@esbuild/linux-riscv64@0.21.5': + optional: true + '@esbuild/linux-riscv64@0.25.9': optional: true + '@esbuild/linux-s390x@0.21.5': + optional: true + '@esbuild/linux-s390x@0.25.9': optional: true + '@esbuild/linux-x64@0.21.5': + optional: true + '@esbuild/linux-x64@0.25.9': optional: true '@esbuild/netbsd-arm64@0.25.9': optional: true + '@esbuild/netbsd-x64@0.21.5': + optional: true + '@esbuild/netbsd-x64@0.25.9': optional: true '@esbuild/openbsd-arm64@0.25.9': optional: true + '@esbuild/openbsd-x64@0.21.5': + optional: true + '@esbuild/openbsd-x64@0.25.9': optional: true '@esbuild/openharmony-arm64@0.25.9': optional: true + '@esbuild/sunos-x64@0.21.5': + optional: true + '@esbuild/sunos-x64@0.25.9': optional: true + '@esbuild/win32-arm64@0.21.5': + optional: true + '@esbuild/win32-arm64@0.25.9': optional: true + '@esbuild/win32-ia32@0.21.5': + optional: true + '@esbuild/win32-ia32@0.25.9': optional: true + '@esbuild/win32-x64@0.21.5': + optional: true + '@esbuild/win32-x64@0.25.9': optional: true @@ -13055,9 +13458,9 @@ snapshots: eslint: 8.57.1 eslint-visitor-keys: 3.4.3 - '@eslint-community/eslint-utils@4.7.0(eslint@9.34.0(jiti@2.5.1))': + '@eslint-community/eslint-utils@4.7.0(eslint@9.34.0(jiti@2.6.1))': dependencies: - eslint: 9.34.0(jiti@2.5.1) + eslint: 9.34.0(jiti@2.6.1) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.1': {} @@ -13663,9 +14066,9 @@ snapshots: '@types/yargs': 17.0.33 chalk: 4.1.2 - '@joyid/ckb@1.1.2(typescript@5.9.2)': + '@joyid/ckb@1.1.2(typescript@5.9.2)(zod@3.25.76)': dependencies: - '@joyid/common': 0.2.1(typescript@5.9.2) + '@joyid/common': 0.2.1(typescript@5.9.2)(zod@3.25.76) '@nervosnetwork/ckb-sdk-utils': 0.109.5 cross-fetch: 4.0.0 uncrypto: 0.1.3 @@ -13674,9 +14077,9 @@ snapshots: - typescript - zod - '@joyid/common@0.2.1(typescript@5.9.2)': + '@joyid/common@0.2.1(typescript@5.9.2)(zod@3.25.76)': dependencies: - abitype: 0.8.7(typescript@5.9.2) + abitype: 0.8.7(typescript@5.9.2)(zod@3.25.76) type-fest: 4.6.0 transitivePeerDependencies: - typescript @@ -13849,6 +14252,11 @@ snapshots: '@nervosnetwork/ckb-types@0.109.5': {} + '@nervosnetwork/fiber-js@0.7.0': + dependencies: + async-mutex: 0.5.0 + stream-browserify: 3.0.0 + '@nestjs/cli@11.0.10(@types/node@24.3.0)': dependencies: '@angular-devkit/core': 19.2.15(chokidar@4.0.3) @@ -14761,15 +15169,15 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@8.41.0(@typescript-eslint/parser@8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2)': + '@typescript-eslint/eslint-plugin@8.41.0(@typescript-eslint/parser@8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + '@typescript-eslint/parser': 8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) '@typescript-eslint/scope-manager': 8.41.0 - '@typescript-eslint/type-utils': 8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) - '@typescript-eslint/utils': 8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + '@typescript-eslint/type-utils': 8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) + '@typescript-eslint/utils': 8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) '@typescript-eslint/visitor-keys': 8.41.0 - eslint: 9.34.0(jiti@2.5.1) + eslint: 9.34.0(jiti@2.6.1) graphemer: 1.4.0 ignore: 7.0.5 natural-compare: 1.4.0 @@ -14778,15 +15186,15 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@8.49.0(@typescript-eslint/parser@8.49.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2)': + '@typescript-eslint/eslint-plugin@8.49.0(@typescript-eslint/parser@8.49.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.49.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + '@typescript-eslint/parser': 8.49.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) '@typescript-eslint/scope-manager': 8.49.0 - '@typescript-eslint/type-utils': 8.49.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) - '@typescript-eslint/utils': 8.49.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + '@typescript-eslint/type-utils': 8.49.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) + '@typescript-eslint/utils': 8.49.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) '@typescript-eslint/visitor-keys': 8.49.0 - eslint: 9.34.0(jiti@2.5.1) + eslint: 9.34.0(jiti@2.6.1) ignore: 7.0.5 natural-compare: 1.4.0 ts-api-utils: 2.1.0(typescript@5.9.2) @@ -14807,26 +15215,26 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2)': + '@typescript-eslint/parser@8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2)': dependencies: '@typescript-eslint/scope-manager': 8.41.0 '@typescript-eslint/types': 8.41.0 '@typescript-eslint/typescript-estree': 8.41.0(typescript@5.9.2) '@typescript-eslint/visitor-keys': 8.41.0 debug: 4.4.1 - eslint: 9.34.0(jiti@2.5.1) + eslint: 9.34.0(jiti@2.6.1) typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.49.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2)': + '@typescript-eslint/parser@8.49.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2)': dependencies: '@typescript-eslint/scope-manager': 8.49.0 '@typescript-eslint/types': 8.49.0 '@typescript-eslint/typescript-estree': 8.49.0(typescript@5.9.2) '@typescript-eslint/visitor-keys': 8.49.0 debug: 4.4.1 - eslint: 9.34.0(jiti@2.5.1) + eslint: 9.34.0(jiti@2.6.1) typescript: 5.9.2 transitivePeerDependencies: - supports-color @@ -14884,25 +15292,25 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2)': + '@typescript-eslint/type-utils@8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2)': dependencies: '@typescript-eslint/types': 8.41.0 '@typescript-eslint/typescript-estree': 8.41.0(typescript@5.9.2) - '@typescript-eslint/utils': 8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + '@typescript-eslint/utils': 8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) debug: 4.4.1 - eslint: 9.34.0(jiti@2.5.1) + eslint: 9.34.0(jiti@2.6.1) ts-api-utils: 2.1.0(typescript@5.9.2) typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@8.49.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2)': + '@typescript-eslint/type-utils@8.49.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2)': dependencies: '@typescript-eslint/types': 8.49.0 '@typescript-eslint/typescript-estree': 8.49.0(typescript@5.9.2) - '@typescript-eslint/utils': 8.49.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + '@typescript-eslint/utils': 8.49.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) debug: 4.4.1 - eslint: 9.34.0(jiti@2.5.1) + eslint: 9.34.0(jiti@2.6.1) ts-api-utils: 2.1.0(typescript@5.9.2) typescript: 5.9.2 transitivePeerDependencies: @@ -14974,24 +15382,24 @@ snapshots: - supports-color - typescript - '@typescript-eslint/utils@8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2)': + '@typescript-eslint/utils@8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2)': dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.34.0(jiti@2.5.1)) + '@eslint-community/eslint-utils': 4.7.0(eslint@9.34.0(jiti@2.6.1)) '@typescript-eslint/scope-manager': 8.41.0 '@typescript-eslint/types': 8.41.0 '@typescript-eslint/typescript-estree': 8.41.0(typescript@5.9.2) - eslint: 9.34.0(jiti@2.5.1) + eslint: 9.34.0(jiti@2.6.1) typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.49.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2)': + '@typescript-eslint/utils@8.49.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2)': dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.34.0(jiti@2.5.1)) + '@eslint-community/eslint-utils': 4.7.0(eslint@9.34.0(jiti@2.6.1)) '@typescript-eslint/scope-manager': 8.49.0 '@typescript-eslint/types': 8.49.0 '@typescript-eslint/typescript-estree': 8.49.0(typescript@5.9.2) - eslint: 9.34.0(jiti@2.5.1) + eslint: 9.34.0(jiti@2.6.1) typescript: 5.9.2 transitivePeerDependencies: - supports-color @@ -15078,7 +15486,7 @@ snapshots: '@unrs/resolver-binding-win32-x64-msvc@1.11.1': optional: true - '@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.5)(yaml@2.8.1))': + '@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.43.1)(tsx@4.20.5)(yaml@2.8.1))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 1.0.2 @@ -15093,7 +15501,7 @@ snapshots: std-env: 3.9.0 test-exclude: 7.0.1 tinyrainbow: 2.0.0 - vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.5)(yaml@2.8.1) + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.43.1)(tsx@4.20.5)(yaml@2.8.1) transitivePeerDependencies: - supports-color @@ -15105,13 +15513,13 @@ snapshots: chai: 5.3.3 tinyrainbow: 2.0.0 - '@vitest/mocker@3.2.4(vite@7.1.3(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.5)(yaml@2.8.1))': + '@vitest/mocker@3.2.4(vite@7.1.3(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.43.1)(tsx@4.20.5)(yaml@2.8.1))': dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 magic-string: 0.30.18 optionalDependencies: - vite: 7.1.3(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.5)(yaml@2.8.1) + vite: 7.1.3(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.43.1)(tsx@4.20.5)(yaml@2.8.1) '@vitest/pretty-format@3.2.4': dependencies: @@ -15219,9 +15627,11 @@ snapshots: '@xtuc/long@4.2.2': {} - abitype@0.8.7(typescript@5.9.2): + abitype@0.8.7(typescript@5.9.2)(zod@3.25.76): dependencies: typescript: 5.9.2 + optionalDependencies: + zod: 3.25.76 abort-controller@3.0.0: dependencies: @@ -15451,6 +15861,10 @@ snapshots: async-function@1.0.0: {} + async-mutex@0.5.0: + dependencies: + tslib: 2.8.1 + asynckit@0.4.0: {} autoprefixer@10.4.21(postcss@8.5.6): @@ -16168,7 +16582,7 @@ snapshots: optionalDependencies: webpack: 5.101.3 - css-minimizer-webpack-plugin@5.0.1(clean-css@5.3.3)(lightningcss@1.30.1)(webpack@5.101.3): + css-minimizer-webpack-plugin@5.0.1(clean-css@5.3.3)(lightningcss@1.31.1)(webpack@5.101.3): dependencies: '@jridgewell/trace-mapping': 0.3.30 cssnano: 6.1.2(postcss@8.5.6) @@ -16179,7 +16593,7 @@ snapshots: webpack: 5.101.3 optionalDependencies: clean-css: 5.3.3 - lightningcss: 1.30.1 + lightningcss: 1.31.1 css-prefers-color-scheme@10.0.0(postcss@8.5.6): dependencies: @@ -16665,6 +17079,32 @@ snapshots: esast-util-from-estree: 2.0.0 vfile-message: 4.0.3 + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + esbuild@0.25.9: optionalDependencies: '@esbuild/aix-ppc64': 0.25.9 @@ -16708,18 +17148,18 @@ snapshots: escape-string-regexp@5.0.0: {} - eslint-config-next@16.0.10(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2): + eslint-config-next@16.0.10(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.2))(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2): dependencies: '@next/eslint-plugin-next': 16.0.10 - eslint: 9.34.0(jiti@2.5.1) + eslint: 9.34.0(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.34.0(jiti@2.5.1)) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.34.0(jiti@2.5.1)) - eslint-plugin-jsx-a11y: 6.10.2(eslint@9.34.0(jiti@2.5.1)) - eslint-plugin-react: 7.37.5(eslint@9.34.0(jiti@2.5.1)) - eslint-plugin-react-hooks: 7.0.1(eslint@9.34.0(jiti@2.5.1)) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.2))(eslint@9.34.0(jiti@2.6.1)))(eslint@9.34.0(jiti@2.6.1)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.2))(eslint@9.34.0(jiti@2.6.1)))(eslint@9.34.0(jiti@2.6.1)))(eslint@9.34.0(jiti@2.6.1)) + eslint-plugin-jsx-a11y: 6.10.2(eslint@9.34.0(jiti@2.6.1)) + eslint-plugin-react: 7.37.5(eslint@9.34.0(jiti@2.6.1)) + eslint-plugin-react-hooks: 7.0.1(eslint@9.34.0(jiti@2.6.1)) globals: 16.4.0 - typescript-eslint: 8.49.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + typescript-eslint: 8.49.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) optionalDependencies: typescript: 5.9.2 transitivePeerDependencies: @@ -16728,29 +17168,9 @@ snapshots: - eslint-plugin-import-x - supports-color - eslint-config-next@16.0.10(@typescript-eslint/parser@8.49.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2): + eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.6.1)): dependencies: - '@next/eslint-plugin-next': 16.0.10 - eslint: 9.34.0(jiti@2.5.1) - eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.49.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1)) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.49.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.49.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1)) - eslint-plugin-jsx-a11y: 6.10.2(eslint@9.34.0(jiti@2.5.1)) - eslint-plugin-react: 7.37.5(eslint@9.34.0(jiti@2.5.1)) - eslint-plugin-react-hooks: 7.0.1(eslint@9.34.0(jiti@2.5.1)) - globals: 16.4.0 - typescript-eslint: 8.49.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) - optionalDependencies: - typescript: 5.9.2 - transitivePeerDependencies: - - '@typescript-eslint/parser' - - eslint-import-resolver-webpack - - eslint-plugin-import-x - - supports-color - - eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.5.1)): - dependencies: - eslint: 9.34.0(jiti@2.5.1) + eslint: 9.34.0(jiti@2.6.1) eslint-config-prettier@9.1.2(eslint@8.57.1): dependencies: @@ -16769,59 +17189,33 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.49.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1)): + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.2))(eslint@9.34.0(jiti@2.6.1)))(eslint@9.34.0(jiti@2.6.1)): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.1 - eslint: 9.34.0(jiti@2.5.1) + eslint: 9.34.0(jiti@2.6.1) get-tsconfig: 4.10.1 is-bun-module: 2.0.0 stable-hash: 0.0.5 tinyglobby: 0.2.14 unrs-resolver: 1.11.1 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.49.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.49.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.2))(eslint@9.34.0(jiti@2.6.1)))(eslint@9.34.0(jiti@2.6.1)))(eslint@9.34.0(jiti@2.6.1)) transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.34.0(jiti@2.5.1)): - dependencies: - '@nolyfill/is-core-module': 1.0.39 - debug: 4.4.1 - eslint: 9.34.0(jiti@2.5.1) - get-tsconfig: 4.10.1 - is-bun-module: 2.0.0 - stable-hash: 0.0.5 - tinyglobby: 0.2.14 - unrs-resolver: 1.11.1 - optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.34.0(jiti@2.5.1)) - transitivePeerDependencies: - - supports-color - - eslint-module-utils@2.12.1(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.34.0(jiti@2.5.1)): + eslint-module-utils@2.12.1(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.2))(eslint@9.34.0(jiti@2.6.1)))(eslint@9.34.0(jiti@2.6.1)))(eslint@9.34.0(jiti@2.6.1)): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.9.2) - eslint: 9.34.0(jiti@2.5.1) - eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.34.0(jiti@2.5.1)) - transitivePeerDependencies: - - supports-color - - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.49.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.49.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1)): - dependencies: - debug: 3.2.7 - optionalDependencies: - '@typescript-eslint/parser': 8.49.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) - eslint: 9.34.0(jiti@2.5.1) + eslint: 9.34.0(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.49.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1)) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.2))(eslint@9.34.0(jiti@2.6.1)))(eslint@9.34.0(jiti@2.6.1)) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.34.0(jiti@2.5.1)): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.2))(eslint@9.34.0(jiti@2.6.1)))(eslint@9.34.0(jiti@2.6.1)))(eslint@9.34.0(jiti@2.6.1)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -16830,9 +17224,9 @@ snapshots: array.prototype.flatmap: 1.3.3 debug: 3.2.7 doctrine: 2.1.0 - eslint: 9.34.0(jiti@2.5.1) + eslint: 9.34.0(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.34.0(jiti@2.5.1)) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.2))(eslint@9.34.0(jiti@2.6.1)))(eslint@9.34.0(jiti@2.6.1)))(eslint@9.34.0(jiti@2.6.1)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -16850,36 +17244,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.49.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.49.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1)): - dependencies: - '@rtsao/scc': 1.1.0 - array-includes: 3.1.9 - array.prototype.findlastindex: 1.2.6 - array.prototype.flat: 1.3.3 - array.prototype.flatmap: 1.3.3 - debug: 3.2.7 - doctrine: 2.1.0 - eslint: 9.34.0(jiti@2.5.1) - eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.49.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.49.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1)) - hasown: 2.0.2 - is-core-module: 2.16.1 - is-glob: 4.0.3 - minimatch: 3.1.2 - object.fromentries: 2.0.8 - object.groupby: 1.0.3 - object.values: 1.2.1 - semver: 6.3.1 - string.prototype.trimend: 1.0.9 - tsconfig-paths: 3.15.0 - optionalDependencies: - '@typescript-eslint/parser': 8.49.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - supports-color - - eslint-plugin-jsx-a11y@6.10.2(eslint@9.34.0(jiti@2.5.1)): + eslint-plugin-jsx-a11y@6.10.2(eslint@9.34.0(jiti@2.6.1)): dependencies: aria-query: 5.3.2 array-includes: 3.1.9 @@ -16889,7 +17254,7 @@ snapshots: axobject-query: 4.1.0 damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 - eslint: 9.34.0(jiti@2.5.1) + eslint: 9.34.0(jiti@2.6.1) hasown: 2.0.2 jsx-ast-utils: 3.3.5 language-tags: 1.0.9 @@ -16905,38 +17270,38 @@ snapshots: globals: 13.24.0 rambda: 7.5.0 - eslint-plugin-prettier@5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1))(prettier@3.6.2): + eslint-plugin-prettier@5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.34.0(jiti@2.6.1)))(eslint@9.34.0(jiti@2.6.1))(prettier@3.6.2): dependencies: - eslint: 9.34.0(jiti@2.5.1) + eslint: 9.34.0(jiti@2.6.1) prettier: 3.6.2 - prettier-linter-helpers: 1.0.0 + prettier-linter-helpers: 1.0.1 synckit: 0.11.11 optionalDependencies: '@types/eslint': 9.6.1 - eslint-config-prettier: 10.1.8(eslint@9.34.0(jiti@2.5.1)) + eslint-config-prettier: 10.1.8(eslint@9.34.0(jiti@2.6.1)) eslint-plugin-prettier@5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@9.1.2(eslint@8.57.1))(eslint@8.57.1)(prettier@3.6.2): dependencies: eslint: 8.57.1 prettier: 3.6.2 - prettier-linter-helpers: 1.0.0 + prettier-linter-helpers: 1.0.1 synckit: 0.11.11 optionalDependencies: '@types/eslint': 9.6.1 eslint-config-prettier: 9.1.2(eslint@8.57.1) - eslint-plugin-react-hooks@7.0.1(eslint@9.34.0(jiti@2.5.1)): + eslint-plugin-react-hooks@7.0.1(eslint@9.34.0(jiti@2.6.1)): dependencies: '@babel/core': 7.28.3 '@babel/parser': 7.28.3 - eslint: 9.34.0(jiti@2.5.1) + eslint: 9.34.0(jiti@2.6.1) hermes-parser: 0.25.1 - zod: 4.1.13 - zod-validation-error: 4.0.2(zod@4.1.13) + zod: 3.25.76 + zod-validation-error: 4.0.2(zod@3.25.76) transitivePeerDependencies: - supports-color - eslint-plugin-react@7.37.5(eslint@9.34.0(jiti@2.5.1)): + eslint-plugin-react@7.37.5(eslint@9.34.0(jiti@2.6.1)): dependencies: array-includes: 3.1.9 array.prototype.findlast: 1.2.5 @@ -16944,7 +17309,7 @@ snapshots: array.prototype.tosorted: 1.1.4 doctrine: 2.1.0 es-iterator-helpers: 1.2.1 - eslint: 9.34.0(jiti@2.5.1) + eslint: 9.34.0(jiti@2.6.1) estraverse: 5.3.0 hasown: 2.0.2 jsx-ast-utils: 3.3.5 @@ -17045,9 +17410,9 @@ snapshots: transitivePeerDependencies: - supports-color - eslint@9.34.0(jiti@2.5.1): + eslint@9.34.0(jiti@2.6.1): dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.34.0(jiti@2.5.1)) + '@eslint-community/eslint-utils': 4.7.0(eslint@9.34.0(jiti@2.6.1)) '@eslint-community/regexpp': 4.12.1 '@eslint/config-array': 0.21.0 '@eslint/config-helpers': 0.3.1 @@ -17083,7 +17448,7 @@ snapshots: natural-compare: 1.4.0 optionator: 0.9.4 optionalDependencies: - jiti: 2.5.1 + jiti: 2.6.1 transitivePeerDependencies: - supports-color @@ -17283,6 +17648,8 @@ snapshots: extendable-error@0.1.7: {} + fake-indexeddb@6.2.5: {} + fast-deep-equal@3.1.3: {} fast-diff@1.3.0: {} @@ -17840,7 +18207,7 @@ snapshots: history@4.10.1: dependencies: - '@babel/runtime': 7.28.3 + '@babel/runtime': 7.28.4 loose-envify: 1.4.0 resolve-pathname: 3.0.0 tiny-invariant: 1.3.3 @@ -18644,6 +19011,9 @@ snapshots: jiti@2.5.1: {} + jiti@2.6.1: + optional: true + joi@17.13.3: dependencies: '@hapi/hoek': 9.3.0 @@ -18748,36 +19118,69 @@ snapshots: libphonenumber-js@1.12.14: {} + lightningcss-android-arm64@1.31.1: + optional: true + lightningcss-darwin-arm64@1.30.1: optional: true + lightningcss-darwin-arm64@1.31.1: + optional: true + lightningcss-darwin-x64@1.30.1: optional: true + lightningcss-darwin-x64@1.31.1: + optional: true + lightningcss-freebsd-x64@1.30.1: optional: true + lightningcss-freebsd-x64@1.31.1: + optional: true + lightningcss-linux-arm-gnueabihf@1.30.1: optional: true + lightningcss-linux-arm-gnueabihf@1.31.1: + optional: true + lightningcss-linux-arm64-gnu@1.30.1: optional: true + lightningcss-linux-arm64-gnu@1.31.1: + optional: true + lightningcss-linux-arm64-musl@1.30.1: optional: true + lightningcss-linux-arm64-musl@1.31.1: + optional: true + lightningcss-linux-x64-gnu@1.30.1: optional: true + lightningcss-linux-x64-gnu@1.31.1: + optional: true + lightningcss-linux-x64-musl@1.30.1: optional: true + lightningcss-linux-x64-musl@1.31.1: + optional: true + lightningcss-win32-arm64-msvc@1.30.1: optional: true + lightningcss-win32-arm64-msvc@1.31.1: + optional: true + lightningcss-win32-x64-msvc@1.30.1: optional: true + lightningcss-win32-x64-msvc@1.31.1: + optional: true + lightningcss@1.30.1: dependencies: detect-libc: 2.0.4 @@ -18793,6 +19196,23 @@ snapshots: lightningcss-win32-arm64-msvc: 1.30.1 lightningcss-win32-x64-msvc: 1.30.1 + lightningcss@1.31.1: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.31.1 + lightningcss-darwin-arm64: 1.31.1 + lightningcss-darwin-x64: 1.31.1 + lightningcss-freebsd-x64: 1.31.1 + lightningcss-linux-arm-gnueabihf: 1.31.1 + lightningcss-linux-arm64-gnu: 1.31.1 + lightningcss-linux-arm64-musl: 1.31.1 + lightningcss-linux-x64-gnu: 1.31.1 + lightningcss-linux-x64-musl: 1.31.1 + lightningcss-win32-arm64-msvc: 1.31.1 + lightningcss-win32-x64-msvc: 1.31.1 + optional: true + lilconfig@3.1.3: {} linebreak@1.1.0: @@ -20390,7 +20810,7 @@ snapshots: prelude-ls@1.2.1: {} - prettier-linter-helpers@1.0.0: + prettier-linter-helpers@1.0.1: dependencies: fast-diff: 1.3.0 @@ -21324,6 +21744,11 @@ snapshots: es-errors: 1.3.0 internal-slot: 1.1.0 + stream-browserify@3.0.0: + dependencies: + inherits: 2.0.4 + readable-stream: 3.6.2 + streamsearch@1.1.0: {} string-length@4.0.2: @@ -21838,24 +22263,24 @@ snapshots: typescript: 5.9.2 yaml: 2.8.1 - typescript-eslint@8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2): + typescript-eslint@8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2): dependencies: - '@typescript-eslint/eslint-plugin': 8.41.0(@typescript-eslint/parser@8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) - '@typescript-eslint/parser': 8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + '@typescript-eslint/eslint-plugin': 8.41.0(@typescript-eslint/parser@8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) + '@typescript-eslint/parser': 8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) '@typescript-eslint/typescript-estree': 8.41.0(typescript@5.9.2) - '@typescript-eslint/utils': 8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) - eslint: 9.34.0(jiti@2.5.1) + '@typescript-eslint/utils': 8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) + eslint: 9.34.0(jiti@2.6.1) typescript: 5.9.2 transitivePeerDependencies: - supports-color - typescript-eslint@8.49.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2): + typescript-eslint@8.49.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2): dependencies: - '@typescript-eslint/eslint-plugin': 8.49.0(@typescript-eslint/parser@8.49.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) - '@typescript-eslint/parser': 8.49.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + '@typescript-eslint/eslint-plugin': 8.49.0(@typescript-eslint/parser@8.49.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) + '@typescript-eslint/parser': 8.49.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) '@typescript-eslint/typescript-estree': 8.49.0(typescript@5.9.2) - '@typescript-eslint/utils': 8.49.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) - eslint: 9.34.0(jiti@2.5.1) + '@typescript-eslint/utils': 8.49.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2) + eslint: 9.34.0(jiti@2.6.1) typescript: 5.9.2 transitivePeerDependencies: - supports-color @@ -22067,16 +22492,15 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 - vite-node@3.2.4(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.5)(yaml@2.8.1): + vite-node@3.2.4(@types/node@24.3.0)(lightningcss@1.31.1)(terser@5.43.1): dependencies: cac: 6.7.14 debug: 4.4.1 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 7.1.3(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.5)(yaml@2.8.1) + vite: 5.4.21(@types/node@24.3.0)(lightningcss@1.31.1)(terser@5.43.1) transitivePeerDependencies: - '@types/node' - - jiti - less - lightningcss - sass @@ -22085,10 +22509,19 @@ snapshots: - sugarss - supports-color - terser - - tsx - - yaml - vite@7.1.3(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.5)(yaml@2.8.1): + vite@5.4.21(@types/node@24.3.0)(lightningcss@1.31.1)(terser@5.43.1): + dependencies: + esbuild: 0.21.5 + postcss: 8.5.6 + rollup: 4.49.0 + optionalDependencies: + '@types/node': 24.3.0 + fsevents: 2.3.3 + lightningcss: 1.31.1 + terser: 5.43.1 + + vite@7.1.3(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.43.1)(tsx@4.20.5)(yaml@2.8.1): dependencies: esbuild: 0.25.9 fdir: 6.5.0(picomatch@4.0.3) @@ -22099,17 +22532,17 @@ snapshots: optionalDependencies: '@types/node': 24.3.0 fsevents: 2.3.3 - jiti: 2.5.1 - lightningcss: 1.30.1 + jiti: 2.6.1 + lightningcss: 1.31.1 terser: 5.43.1 tsx: 4.20.5 yaml: 2.8.1 - vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.5)(yaml@2.8.1): + vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.43.1)(tsx@4.20.5)(yaml@2.8.1): dependencies: '@types/chai': 5.2.2 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@7.1.3(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.5)(yaml@2.8.1)) + '@vitest/mocker': 3.2.4(vite@7.1.3(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.43.1)(tsx@4.20.5)(yaml@2.8.1)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 @@ -22127,8 +22560,8 @@ snapshots: tinyglobby: 0.2.14 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 7.1.3(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.5)(yaml@2.8.1) - vite-node: 3.2.4(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.5)(yaml@2.8.1) + vite: 7.1.3(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.43.1)(tsx@4.20.5)(yaml@2.8.1) + vite-node: 3.2.4(@types/node@24.3.0)(lightningcss@1.31.1)(terser@5.43.1) why-is-node-running: 2.3.0 optionalDependencies: '@types/debug': 4.1.12 @@ -22166,6 +22599,8 @@ snapshots: web-namespaces@2.0.1: {} + web-worker@1.5.0: {} + webidl-conversions@3.0.1: {} webpack-bundle-analyzer@4.10.2: @@ -22501,10 +22936,10 @@ snapshots: yoga-wasm-web@0.3.3: {} - zod-validation-error@4.0.2(zod@4.1.13): + zod-validation-error@4.0.2(zod@3.25.76): dependencies: - zod: 4.1.13 + zod: 3.25.76 - zod@4.1.13: {} + zod@3.25.76: {} zwitch@2.0.4: {}