diff --git a/.cursor/worktrees.json b/.cursor/worktrees.json deleted file mode 100644 index bf9e730..0000000 --- a/.cursor/worktrees.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "setup-worktree": ["pnpm install"] -} diff --git a/.gitignore b/.gitignore index feb03c5..c2283c8 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,6 @@ dist-ssr # opensrc - source code for packages opensrc/ + +.turbo +*.tsbuildinfo \ No newline at end of file diff --git a/.husky/commit-msg b/.husky/commit-msg new file mode 100755 index 0000000..38bf73a --- /dev/null +++ b/.husky/commit-msg @@ -0,0 +1 @@ +pnpm commitlint --edit ${1} diff --git a/biome.json b/biome.json index 6b38be3..ee7c6a1 100644 --- a/biome.json +++ b/biome.json @@ -14,7 +14,8 @@ "!**/.vscode", "!**/routeTree.gen.ts", "!**/client-factory.ts", - "!**/api-schemas.ts" + "!**/api-schemas.ts", + "!**/opensrc" ] }, "formatter": { diff --git a/commitlint.config.cjs b/commitlint.config.cjs new file mode 100644 index 0000000..69b4242 --- /dev/null +++ b/commitlint.config.cjs @@ -0,0 +1,3 @@ +module.exports = { + extends: ["@commitlint/config-conventional"], +}; diff --git a/components.json b/components.json deleted file mode 100644 index 7934967..0000000 --- a/components.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "$schema": "https://ui.shadcn.com/schema.json", - "style": "base-vega", - "rsc": false, - "tsx": true, - "tailwind": { - "config": "", - "css": "src/styles.css", - "baseColor": "zinc", - "cssVariables": true, - "prefix": "" - }, - "aliases": { - "components": "@/components", - "utils": "@/lib/utils", - "ui": "@/components/ui", - "lib": "@/lib", - "hooks": "@/hooks" - }, - "iconLibrary": "lucide" -} diff --git a/index.html b/index.html index b92d082..0e4aacb 100644 --- a/index.html +++ b/index.html @@ -14,6 +14,6 @@
- + diff --git a/package.json b/package.json index 5fdc9be..01ec7e0 100644 --- a/package.json +++ b/package.json @@ -1,71 +1,29 @@ { - "name": "perps", - "private": true, - "type": "module", + "name": "@yieldxyz/perps", + "keywords": [ + "perps", + "yieldxyz" + ], "scripts": { - "dev": "vite --port 3000", - "build": "vite build && tsc", - "preview": "vite preview", - "test": "vitest run", - "lint": "biome check . && tsc", - "format": "biome format --write .", - "generate-client-factory": "tsx --env-file .env scripts/generate-client-factory.ts", - "generate-routes": "tsr generate", - "generate-tradingview-symbols": "tsx --env-file .env scripts/generate-tradingview-symbols/index.ts" - }, - "dependencies": { - "@base-ui/react": "^1.1.0", - "@effect-atom/atom-react": "^0.4.6", - "@effect/experimental": "^0.58.0", - "@effect/platform": "^0.94.2", - "@effect/platform-node": "^0.104.1", - "@ledgerhq/wallet-api-client": "^1.12.6", - "@lucas-barake/effect-form-react": "^0.14.0", - "@reown/appkit": "^1.8.17", - "@reown/appkit-adapter-wagmi": "^1.8.17", - "@stakekit/common": "^0.0.61", - "@tailwindcss/vite": "^4.0.6", - "@tanstack/react-devtools": "^0.9.2", - "@tanstack/react-query": "^5.90.20", - "@tanstack/react-router": "^1.157.8", - "@tanstack/react-router-devtools": "^1.157.8", - "@tanstack/react-virtual": "^3.13.18", - "@tanstack/router-plugin": "^1.157.8", - "class-variance-authority": "^0.7.1", - "clsx": "^2.1.1", - "effect": "^3.19.15", - "lucide-react": "^0.563.0", - "react": "^19.2.0", - "react-dom": "^19.2.0", - "sonner": "^2.0.7", - "tailwind-merge": "^3.0.2", - "tailwindcss": "^4.0.6", - "tw-animate-css": "^1.3.6", - "viem": "^2.45.0", - "wagmi": "^3.4.1" + "dev": "turbo dev --filter=@yieldxyz/perps-common --filter=@yieldxyz/perps-widget --filter=@yieldxyz/perps-dashboard", + "dev:widget": "turbo dev --filter=@yieldxyz/perps-common --filter=@yieldxyz/perps-widget", + "dev:dashboard": "turbo dev --filter=@yieldxyz/perps-common --filter=@yieldxyz/perps-dashboard", + + "build:widget": "turbo build --filter=@yieldxyz/perps-widget", + "build:dashboard": "turbo build --filter=@yieldxyz/perps-dashboard", + + "build": "turbo build", + "test": "turbo test", + "lint": "turbo lint", + "format": "turbo format", + "prepare": "husky" }, "devDependencies": { - "@biomejs/biome": "2.3.12", - "@effect/language-service": "^0.72.0", - "@tanstack/devtools-vite": "^0.4.1", - "@tanstack/router-cli": "^1.157.15", - "@testing-library/dom": "^10.4.0", - "@testing-library/react": "^16.3.2", - "@tim-smart/openapi-gen": "^0.4.13", - "@types/node": "^25.0.10", - "@types/react": "^19.2.9", - "@types/react-dom": "^19.2.0", - "@vite-pwa/assets-generator": "^1.0.2", - "@vitejs/plugin-react": "^5.0.4", - "@vitest/browser-playwright": "^4.0.18", - "babel-plugin-react-compiler": "^1.0.0", - "jsdom": "^27.0.0", - "openapi-filter": "^3.2.3", - "tsx": "^4.21.0", - "typescript": "^5.7.2", - "vite": "^7.3.1", - "vite-plugin-node-polyfills": "^0.25.0", - "vitest": "^4.0.18", - "vitest-browser-react": "^2.0.4" + "turbo": "catalog:", + "@biomejs/biome": "catalog:", + "@effect/language-service": "catalog:", + "@commitlint/cli": "catalog:", + "@commitlint/config-conventional": "catalog:", + "husky": "catalog:" } } diff --git a/packages/common/package.json b/packages/common/package.json new file mode 100644 index 0000000..7933729 --- /dev/null +++ b/packages/common/package.json @@ -0,0 +1,108 @@ +{ + "name": "@yieldxyz/perps-common", + "version": "0.0.1", + "private": true, + "type": "module", + "scripts": { + "dev": "pnpm run watch", + "watch": "tsc -b --watch", + "build": "rm -rf dist && tsc -b && pnpm run copy-assets", + "test": "vitest run", + "copy-assets": "cp -r src/assets dist/src && cp -r src/styles dist/src/styles", + "lint": "biome check . && tsc -b", + "format": "biome format --write .", + "generate-client-factory": "tsx --env-file .env scripts/generate-client-factory.ts", + "generate-tradingview-symbols": "tsx --env-file .env scripts/generate-tradingview-symbols/index.ts" + }, + "exports": { + "./vite.config": { + "default": "./dist/src/vite.config.js" + }, + "./styles": { + "default": "./dist/src/styles/index.css" + }, + "./assets/*": { + "default": "./dist/src/assets/*" + }, + "./services": { + "types": "./dist/src/services/index.d.ts", + "default": "./dist/src/services/index.js" + }, + "./domain": { + "types": "./dist/src/domain/index.d.ts", + "default": "./dist/src/domain/index.js" + }, + "./components": { + "types": "./dist/src/components/index.d.ts", + "default": "./dist/src/components/index.js" + }, + "./context": { + "types": "./dist/src/context/index.d.ts", + "default": "./dist/src/context/index.js" + }, + "./atoms": { + "types": "./dist/src/atoms/index.d.ts", + "default": "./dist/src/atoms/index.js" + }, + "./hooks": { + "types": "./dist/src/hooks/index.d.ts", + "default": "./dist/src/hooks/index.js" + }, + "./lib": { + "types": "./dist/src/lib/index.d.ts", + "default": "./dist/src/lib/index.js" + } + }, + "dependencies": { + "@base-ui/react": "catalog:", + "@effect-atom/atom-react": "catalog:", + "@effect/experimental": "^0.58.0", + "@effect/platform": "catalog:", + "@effect/platform-node": "catalog:", + "@ledgerhq/wallet-api-client": "catalog:", + "@lucas-barake/effect-form-react": "catalog:", + "@reown/appkit": "catalog:", + "@reown/appkit-adapter-wagmi": "catalog:", + "@stakekit/common": "catalog:", + "@tailwindcss/vite": "catalog:", + "@tanstack/react-devtools": "catalog:", + "@tanstack/react-query": "catalog:", + "@tanstack/react-router": "catalog:", + "@tanstack/react-router-devtools": "catalog:", + "@tanstack/react-virtual": "catalog:", + "class-variance-authority": "catalog:", + "clsx": "catalog:", + "effect": "catalog:", + "lucide-react": "catalog:", + "react": "catalog:", + "react-dom": "catalog:", + "sonner": "catalog:", + "tailwind-merge": "catalog:", + "tailwindcss": "catalog:", + "tw-animate-css": "catalog:", + "viem": "catalog:", + "wagmi": "catalog:" + }, + "devDependencies": { + "@tanstack/devtools-vite": "catalog:", + "@tanstack/router-cli": "catalog:", + "@testing-library/dom": "catalog:", + "@testing-library/react": "catalog:", + "@tim-smart/openapi-gen": "catalog:", + "@types/node": "catalog:", + "@types/react": "catalog:", + "@types/react-dom": "catalog:", + "@vite-pwa/assets-generator": "catalog:", + "@vitejs/plugin-react": "catalog:", + "@vitest/browser-playwright": "catalog:", + "babel-plugin-react-compiler": "catalog:", + "jsdom": "catalog:", + "openapi-filter": "catalog:", + "tsx": "catalog:", + "typescript": "catalog:", + "vite": "catalog:", + "vite-plugin-node-polyfills": "catalog:", + "vitest": "catalog:", + "vitest-browser-react": "catalog:" + } +} diff --git a/scripts/generate-client-factory.ts b/packages/common/scripts/generate-client-factory.ts similarity index 97% rename from scripts/generate-client-factory.ts rename to packages/common/scripts/generate-client-factory.ts index 33eab10..0b8351e 100644 --- a/scripts/generate-client-factory.ts +++ b/packages/common/scripts/generate-client-factory.ts @@ -14,7 +14,7 @@ const fetchOpenApiSpecs = Effect.gen(function* () { const client = yield* HttpClient.HttpClient; const fs = yield* FileSystem.FileSystem; - const perpsDocsUrl = yield* Config.string("VITE_PERPS_DOCS_URL"); + const perpsDocsUrl = yield* Config.string("PERPS_DOCS_URL"); const perpsJsonPath = yield* perpsOpenApiJsonPath; yield* client.get(perpsDocsUrl).pipe( diff --git a/scripts/generate-tradingview-symbols/index.ts b/packages/common/scripts/generate-tradingview-symbols/index.ts similarity index 97% rename from scripts/generate-tradingview-symbols/index.ts rename to packages/common/scripts/generate-tradingview-symbols/index.ts index 3e09b62..12abbcd 100644 --- a/scripts/generate-tradingview-symbols/index.ts +++ b/packages/common/scripts/generate-tradingview-symbols/index.ts @@ -19,7 +19,7 @@ import { normalizeSymbol, ProvidersResponse, TradingViewSearchResponse, -} from "scripts/generate-tradingview-symbols/utils"; +} from "./utils"; // ----------------------------------------------------------------------------- // HttpClient Services @@ -29,8 +29,8 @@ class PerpsClient extends Effect.Service()( { dependencies: [FetchHttpClient.layer], effect: Effect.gen(function* () { - const baseUrl = yield* Config.string("VITE_PERPS_BASE_URL"); - const apiKey = yield* Config.string("VITE_PERPS_API_KEY"); + const baseUrl = yield* Config.string("PERPS_BASE_URL"); + const apiKey = yield* Config.string("PERPS_API_KEY"); const client = yield* HttpClient.HttpClient; return client.pipe( @@ -247,7 +247,6 @@ const program = Effect.gen(function* () { const path = join( dirname(fileURLToPath(import.meta.url)), "..", - "..", "src", "assets", "tradingview-symbols.json", diff --git a/scripts/generate-tradingview-symbols/utils.ts b/packages/common/scripts/generate-tradingview-symbols/utils.ts similarity index 100% rename from scripts/generate-tradingview-symbols/utils.ts rename to packages/common/scripts/generate-tradingview-symbols/utils.ts diff --git a/src/assets/hyperliquid.png b/packages/common/src/assets/hyperliquid.png similarity index 100% rename from src/assets/hyperliquid.png rename to packages/common/src/assets/hyperliquid.png diff --git a/src/assets/tradingview-symbols.json b/packages/common/src/assets/tradingview-symbols.json similarity index 99% rename from src/assets/tradingview-symbols.json rename to packages/common/src/assets/tradingview-symbols.json index 1098d8d..d9cb0c4 100644 --- a/src/assets/tradingview-symbols.json +++ b/packages/common/src/assets/tradingview-symbols.json @@ -128,7 +128,7 @@ { "status": "match", "perpsSymbol": "SNX", - "tradingViewSymbol": "SNXUSDC", + "tradingViewSymbol": "SNXUSD", "providerId": "BINANCE" }, { @@ -417,7 +417,7 @@ "status": "match", "perpsSymbol": "MAV", "tradingViewSymbol": "MAVUSD", - "providerId": "BINANCE" + "providerId": "TVC" }, { "status": "match", @@ -825,7 +825,7 @@ "status": "match", "perpsSymbol": "VINE", "tradingViewSymbol": "VINEUSD", - "providerId": "KRAKEN" + "providerId": "CRYPTOCOM" }, { "status": "match", diff --git a/src/atoms/actions-atoms.ts b/packages/common/src/atoms/actions-atoms.ts similarity index 62% rename from src/atoms/actions-atoms.ts rename to packages/common/src/atoms/actions-atoms.ts index e0dc0a5..ed2cbf5 100644 --- a/src/atoms/actions-atoms.ts +++ b/packages/common/src/atoms/actions-atoms.ts @@ -1,12 +1,12 @@ import { Reactivity } from "@effect/experimental/Reactivity"; -import { Atom } from "@effect-atom/atom-react"; +import { Atom, type Result } from "@effect-atom/atom-react"; import { Effect, Stream } from "effect"; -import { portfolioReactivityKeysArray } from "@/atoms/portfolio-atoms"; -import type { WalletConnected } from "@/domain/wallet"; -import type { ActionDto } from "@/services/api-client/api-schemas"; -import { runtimeAtom } from "@/services/runtime"; +import type { SignTransactionsState, WalletConnected } from "../domain/wallet"; +import type { ActionDto } from "../services/api-client/api-schemas"; +import { runtimeAtom } from "../services/runtime"; +import { portfolioReactivityKeysArray } from "./portfolio-atoms"; -export const actionAtom = Atom.writable( +export const actionAtom = Atom.writable( () => null, (ctx, value) => ctx.setSelf(value), ); @@ -21,7 +21,21 @@ const getActionAtom = Atom.make( }), ); -export const signActionAtoms = Atom.family( +type SignActionAtoms = ( + arg: (action: ActionDto) => Effect.Effect< + { + stream: Stream.Stream; + retry: Effect.Effect; + }, + never, + never + >, +) => { + machineStreamAtom: Atom.Atom>; + retryMachineAtom: Atom.AtomResultFn; +}; + +export const signActionAtoms: SignActionAtoms = Atom.family( (signTransactions: WalletConnected["signTransactions"]) => { const machineAtom = runtimeAtom.atom((ctx) => ctx diff --git a/packages/common/src/atoms/close-position-atoms.ts b/packages/common/src/atoms/close-position-atoms.ts new file mode 100644 index 0000000..e72d916 --- /dev/null +++ b/packages/common/src/atoms/close-position-atoms.ts @@ -0,0 +1,56 @@ +import { Atom, Registry, Result } from "@effect-atom/atom-react"; +import { Number as _Number, Effect } from "effect"; +import type { WalletConnected } from "../domain/wallet"; +import { getCloseCalculations } from "../lib/math"; +import { ApiClientService } from "../services/api-client"; +import type { PositionDto } from "../services/api-client/api-schemas"; +import { runtimeAtom } from "../services/runtime"; +import { actionAtom } from "./actions-atoms"; +import { selectedProviderAtom } from "./providers-atoms"; + +export const SLIDER_STOPS = [0, 25, 50, 75, 100]; + +export const closePercentageAtom = Atom.writable( + () => 25, + (ctx, value) => + ctx.setSelf(_Number.clamp({ minimum: 0, maximum: 100 })(value)), +); + +export const submitCloseAtom = runtimeAtom.fn( + Effect.fn(function* (args: { + position: PositionDto; + wallet: WalletConnected; + }) { + const client = yield* ApiClientService; + const registry = yield* Registry.AtomRegistry; + + const selectedProvider = registry + .get(selectedProviderAtom) + .pipe(Result.getOrElse(() => null)); + + if (!selectedProvider) { + return yield* Effect.dieMessage("No selected provider"); + } + + const closePercentage = registry.get(closePercentageAtom); + const closeCalculations = + closePercentage === 100 + ? null + : getCloseCalculations(args.position, closePercentage); + + const action = yield* client.ActionsControllerExecuteAction({ + providerId: selectedProvider.id, + address: args.wallet.currentAccount.address, + action: "close", + args: { + marketId: args.position.marketId, + side: args.position.side, + ...(closeCalculations && { + size: closeCalculations.closeSizeInMarketPrice, + }), + }, + }); + + registry.set(actionAtom, action); + }), +); diff --git a/packages/common/src/atoms/config-atom.ts b/packages/common/src/atoms/config-atom.ts new file mode 100644 index 0000000..86681ed --- /dev/null +++ b/packages/common/src/atoms/config-atom.ts @@ -0,0 +1,4 @@ +import { ConfigService } from "../services/config"; +import { runtimeAtom } from "../services/runtime"; + +export const configAtom = runtimeAtom.atom(ConfigService); diff --git a/packages/common/src/atoms/edit-position-atoms.ts b/packages/common/src/atoms/edit-position-atoms.ts new file mode 100644 index 0000000..9171492 --- /dev/null +++ b/packages/common/src/atoms/edit-position-atoms.ts @@ -0,0 +1,73 @@ +import { Atom, Registry, Result } from "@effect-atom/atom-react"; +import { Effect, Option } from "effect"; +import type { + TPOrSLConfiguration, + TPOrSLOption, + TPOrSLSettings, +} from "../components/molecules/tp-sl-dialog"; +import type { WalletConnected } from "../domain/wallet"; +import { ApiClientService } from "../services/api-client"; +import type { + ArgumentsDto, + PositionDto, +} from "../services/api-client/api-schemas"; +import { runtimeAtom } from "../services/runtime"; +import { actionAtom } from "./actions-atoms"; +import { selectedProviderAtom } from "./providers-atoms"; + +export const tpSlArgument = (tpOrSL: TPOrSLConfiguration) => + Option.some(tpOrSL).pipe( + Option.filterMap((v) => + v.triggerPrice !== null && v.option !== null + ? Option.some(v.triggerPrice) + : Option.none(), + ), + Option.getOrUndefined, + ); + +export const editSLTPAtom = Atom.family((actionType: TPOrSLOption) => + runtimeAtom.fn( + Effect.fn(function* ({ + position, + wallet, + tpOrSLSettings, + }: { + position: PositionDto; + wallet: WalletConnected; + tpOrSLSettings: TPOrSLSettings; + }) { + const client = yield* ApiClientService; + const registry = yield* Registry.AtomRegistry; + + const selectedProvider = registry + .get(selectedProviderAtom) + .pipe(Result.getOrElse(() => null)); + + if (!selectedProvider) { + return yield* Effect.dieMessage("No selected provider"); + } + + const newStopLossPrice: ArgumentsDto["stopLossPrice"] = tpSlArgument( + tpOrSLSettings.stopLoss, + ); + + const newTakeProfitPrice: ArgumentsDto["takeProfitPrice"] = tpSlArgument( + tpOrSLSettings.takeProfit, + ); + + const action = yield* client.ActionsControllerExecuteAction({ + providerId: selectedProvider.id, + address: wallet.currentAccount.address, + action: actionType, + args: { + marketId: position.marketId, + ...(actionType === "stopLoss" + ? { stopLossPrice: newStopLossPrice } + : { takeProfitPrice: newTakeProfitPrice }), + }, + }); + + registry.set(actionAtom, action); + }), + ), +); diff --git a/packages/common/src/atoms/index.ts b/packages/common/src/atoms/index.ts new file mode 100644 index 0000000..568b037 --- /dev/null +++ b/packages/common/src/atoms/index.ts @@ -0,0 +1,13 @@ +export * from "./actions-atoms"; +export * from "./close-position-atoms"; +export * from "./config-atom"; +export * from "./edit-position-atoms"; +export * from "./markets-atoms"; +export * from "./order-form-atoms"; +export * from "./orders-pending-actions-atom"; +export * from "./portfolio-atoms"; +export * from "./position-pending-actions-atom"; +export * from "./providers-atoms"; +export * from "./tokens-atoms"; +export * from "./utils"; +export * from "./wallet-atom"; diff --git a/src/atoms/markets-atoms.ts b/packages/common/src/atoms/markets-atoms.ts similarity index 77% rename from src/atoms/markets-atoms.ts rename to packages/common/src/atoms/markets-atoms.ts index a018e89..7b115e0 100644 --- a/src/atoms/markets-atoms.ts +++ b/packages/common/src/atoms/markets-atoms.ts @@ -1,9 +1,9 @@ import { Atom, AtomRef } from "@effect-atom/atom-react"; import { Data, Duration, Effect, Record, Schedule, Stream } from "effect"; -import { selectedProviderAtom } from "@/atoms/providers-atoms"; -import { ApiClientService } from "@/services/api-client"; -import type { ProviderDto } from "@/services/api-client/api-schemas"; -import { runtimeAtom } from "@/services/runtime"; +import { ApiClientService } from "../services/api-client"; +import type { ProviderDto } from "../services/api-client/api-schemas"; +import { runtimeAtom } from "../services/runtime"; +import { selectedProviderAtom } from "./providers-atoms"; const DEFAULT_LIMIT = 50; @@ -37,20 +37,18 @@ const getAllMarkets = Effect.fn(function* (selectedProvider: ProviderDto) { ]; }); -export const marketsAtom = runtimeAtom - .atom( - Effect.fn(function* (ctx) { - const selectedProvider = yield* ctx.result(selectedProviderAtom); +export const marketsAtom = runtimeAtom.atom( + Effect.fn(function* (ctx) { + const selectedProvider = yield* ctx.result(selectedProviderAtom); - const markets = yield* getAllMarkets(selectedProvider); + const markets = yield* getAllMarkets(selectedProvider); - return Record.fromIterableBy( - markets.map((market) => AtomRef.make(market)), - (m) => m.value.id, - ); - }), - ) - .pipe(Atom.keepAlive); + return Record.fromIterableBy( + markets.map((market) => AtomRef.make(market)), + (m) => m.value.id, + ); + }), +); export class MarketNotFoundError extends Data.TaggedError( "MarketNotFoundError", diff --git a/packages/common/src/atoms/order-form-atoms.ts b/packages/common/src/atoms/order-form-atoms.ts new file mode 100644 index 0000000..31c842e --- /dev/null +++ b/packages/common/src/atoms/order-form-atoms.ts @@ -0,0 +1,269 @@ +import { Atom, Registry, Result } from "@effect-atom/atom-react"; +import { FormBuilder, FormReact } from "@lucas-barake/effect-form-react"; +import { Number as _Number, Effect, Schema } from "effect"; +import { AmountField, type TPOrSLSettings } from "../components"; +import { isWalletConnected, type WalletConnected } from "../domain"; +import { + calcBaseAmountFromUsd, + calculateMargin, + calculatePositionSize, + clampPercent, + getLiquidationPrice, + getMaxLeverage, + MIN_LEVERAGE, + percentOf, + round, + valueFromPercent, +} from "../lib"; +import { + ApiClientService, + ApiSchemas, + type ApiTypes, + runtimeAtom, +} from "../services"; +import { actionAtom } from "./actions-atoms"; +import { tpSlArgument } from "./edit-position-atoms"; +import { selectedProviderBalancesAtom } from "./portfolio-atoms"; +import { selectedProviderAtom } from "./providers-atoms"; +import { walletAtom } from "./wallet-atom"; + +// Constants +export const ORDER_SLIDER_STOPS = [0, 25, 50, 75, 100]; + +// Types +export type OrderType = "market" | "limit"; +export type OrderSide = ApiTypes.PositionDtoSide; + +// Schemas +export const LeverageRangesSchema = Schema.Data( + ApiSchemas.MarketDto.fields.leverageRange, +).pipe(Schema.brand("LeverageRange")); + +// Order Type Atom +export const orderTypeAtom = Atom.writable( + () => "market", + (ctx, value) => ctx.setSelf(value), +); + +// Order Side Atom +export const orderSideAtom = Atom.writable( + () => "long", + (ctx, value) => ctx.setSelf(value), +); + +// Leverage Atom (family keyed by leverage ranges) +export const leverageAtom = Atom.family( + (leverageRanges: typeof LeverageRangesSchema.Type) => + Atom.writable( + () => getMaxLeverage(leverageRanges), + (ctx, value: number) => + ctx.setSelf( + _Number.clamp({ + minimum: MIN_LEVERAGE, + maximum: getMaxLeverage(leverageRanges), + })(value), + ), + ), +); + +// TP/SL Settings Atom +export const tpOrSLSettingsAtom = Atom.writable( + () => ({ + takeProfit: { + option: null, + triggerPrice: null, + percentage: null, + }, + stopLoss: { + option: null, + triggerPrice: null, + percentage: null, + }, + }), + (ctx, value) => ctx.setSelf(value), +); + +// Limit Price Atom +export const limitPriceAtom = Atom.writable( + () => null, + (ctx, value) => ctx.setSelf(value), +); + +// Order Form Atom (family keyed by leverage ranges) +export const orderFormAtom = Atom.family( + (leverageRanges: typeof LeverageRangesSchema.Type) => { + const orderFormBuilder = FormBuilder.empty + .addField( + "Amount", + Schema.NumberFromString.pipe( + Schema.annotations({ message: () => "Invalid amount" }), + Schema.greaterThan(0, { message: () => "Must be greater than 0" }), + ), + ) + .refineEffect((values) => + Effect.gen(function* () { + const registry = yield* Registry.AtomRegistry; + const wallet = registry + .get(walletAtom) + .pipe(Result.getOrElse(() => null)); + + if (!isWalletConnected(wallet)) { + return yield* Effect.dieMessage("No wallet"); + } + + const providerBalance = registry + .get(selectedProviderBalancesAtom(wallet.currentAccount.address)) + .pipe(Result.getOrElse(() => null)); + + if (!providerBalance) { + return { path: ["Amount"], message: "Missing provider balance" }; + } + + const leverage = registry.get(leverageAtom(leverageRanges)); + const requiredMargin = calculateMargin({ + positionSize: values.Amount, + leverage, + }); + + if (requiredMargin > providerBalance.availableBalance) { + return { + path: ["Amount"], + message: "Insufficient balance", + }; + } + }), + ); + + const OrderForm = FormReact.make(orderFormBuilder, { + runtime: runtimeAtom, + fields: { Amount: AmountField }, + onSubmit: ( + { + wallet, + market, + side, + }: { + wallet: WalletConnected; + market: ApiSchemas.MarketDto; + side: ApiTypes.PositionDtoSide; + }, + { decoded }, + ) => + Effect.gen(function* () { + const client = yield* ApiClientService; + const registry = yield* Registry.AtomRegistry; + + const selectedProvider = registry + .get(selectedProviderAtom) + .pipe(Result.getOrElse(() => null)); + + if (!selectedProvider) { + return yield* Effect.dieMessage("No selected provider"); + } + + const leverage = registry.get(leverageAtom(leverageRanges)); + const orderType = registry.get(orderTypeAtom); + const tpOrSLSettings = registry.get(tpOrSLSettingsAtom); + + const stopLossPrice = tpSlArgument(tpOrSLSettings.stopLoss); + const takeProfitPrice = tpSlArgument(tpOrSLSettings.takeProfit); + + const limitPrice = + orderType === "limit" ? registry.get(limitPriceAtom) : undefined; + + const action = yield* client.ActionsControllerExecuteAction({ + providerId: selectedProvider.id, + address: wallet.currentAccount.address, + action: "open", + args: { + marketId: market.id, + side, + size: decoded.Amount.toString(), + marginMode: "isolated", + ...(stopLossPrice && { stopLossPrice }), + ...(takeProfitPrice && { takeProfitPrice }), + ...(leverage && { leverage }), + ...(limitPrice && { limitPrice: limitPrice }), + }, + }); + + registry.set(actionAtom, action); + }), + }); + + const setAmountFieldAtom = OrderForm.setValue(OrderForm.fields.Amount); + const amountFieldAtom = OrderForm.getFieldValue(OrderForm.fields.Amount); + + return Atom.readable(() => ({ + form: OrderForm, + setAmountFieldAtom, + amountFieldAtom, + })); + }, +); + +// Helper functions for order calculations +export const getOrderCalculations = ( + amount: number, + leverage: number, + market: ApiSchemas.MarketDto, + side: ApiTypes.PositionDtoSide, +) => { + const cryptoAmount = calcBaseAmountFromUsd({ + usdAmount: amount, + priceUsd: market.markPrice, + }); + + const liquidationPrice = getLiquidationPrice({ + currentPrice: market.markPrice, + leverage, + side, + }); + + const margin = calculateMargin({ positionSize: amount, leverage }); + + const feeRate = market.takerFee ? Number.parseFloat(market.takerFee) : 0; + const fees = amount * feeRate; + + return { + margin, + amount, + cryptoAmount, + liquidationPrice, + fees, + leverage, + }; +}; + +// Helper function for percentage change +export const calculateOrderPositionSize = ( + providerBalance: { availableBalance: number }, + leverage: number, + percentage: number, +) => { + const clampedValue = clampPercent(percentage); + const marginToUse = valueFromPercent({ + total: providerBalance.availableBalance, + percent: clampedValue, + }); + const positionSize = calculatePositionSize({ + margin: marginToUse, + leverage, + }); + + return round(positionSize); +}; + +// Helper function for calculating percentage from amount +export const calculateOrderPercentage = ( + amount: number, + leverage: number, + availableBalance: number, +) => { + const margin = calculateMargin({ positionSize: amount, leverage }); + const percentage = clampPercent( + percentOf({ part: margin, whole: availableBalance }), + ); + + return Math.round(percentage); +}; diff --git a/src/atoms/orders-pending-actions-atom.ts b/packages/common/src/atoms/orders-pending-actions-atom.ts similarity index 77% rename from src/atoms/orders-pending-actions-atom.ts rename to packages/common/src/atoms/orders-pending-actions-atom.ts index 9976f69..ebda7bc 100644 --- a/src/atoms/orders-pending-actions-atom.ts +++ b/packages/common/src/atoms/orders-pending-actions-atom.ts @@ -1,10 +1,10 @@ import { Atom, Registry, Result } from "@effect-atom/atom-react"; import { Effect } from "effect"; -import { actionAtom } from "@/atoms/actions-atoms"; -import { selectedProviderAtom } from "@/atoms/providers-atoms"; -import type { WalletAccount } from "@/domain/wallet"; -import { ApiClientService } from "@/services/api-client"; -import { runtimeAtom } from "@/services/runtime"; +import type { WalletAccount } from "../domain/wallet"; +import { ApiClientService } from "../services/api-client"; +import { runtimeAtom } from "../services/runtime"; +import { actionAtom } from "./actions-atoms"; +import { selectedProviderAtom } from "./providers-atoms"; export const cancelOrderAtom = Atom.family((orderId: string) => runtimeAtom.fn( diff --git a/src/atoms/portfolio-atoms.ts b/packages/common/src/atoms/portfolio-atoms.ts similarity index 90% rename from src/atoms/portfolio-atoms.ts rename to packages/common/src/atoms/portfolio-atoms.ts index 4e8b6fb..ce4cb84 100644 --- a/src/atoms/portfolio-atoms.ts +++ b/packages/common/src/atoms/portfolio-atoms.ts @@ -1,10 +1,10 @@ import { Atom } from "@effect-atom/atom-react"; import { Duration, Effect } from "effect"; -import { providersAtom, selectedProviderAtom } from "@/atoms/providers-atoms"; -import { withRefreshAfter } from "@/atoms/utils"; -import type { WalletAccount } from "@/domain/wallet"; -import { ApiClientService } from "@/services/api-client"; -import { runtimeAtom, withReactivity } from "@/services/runtime"; +import type { WalletAccount } from "../domain/wallet"; +import { ApiClientService } from "../services/api-client"; +import { runtimeAtom, withReactivity } from "../services/runtime"; +import { providersAtom, selectedProviderAtom } from "./providers-atoms"; +import { withRefreshAfter } from "./utils"; export const portfolioReactivityKeys = { positions: "positions", diff --git a/src/atoms/position-pending-actions-atom.ts b/packages/common/src/atoms/position-pending-actions-atom.ts similarity index 69% rename from src/atoms/position-pending-actions-atom.ts rename to packages/common/src/atoms/position-pending-actions-atom.ts index 58fdf59..786bbe8 100644 --- a/src/atoms/position-pending-actions-atom.ts +++ b/packages/common/src/atoms/position-pending-actions-atom.ts @@ -1,18 +1,16 @@ import { Registry, Result } from "@effect-atom/atom-react"; import { Effect } from "effect"; -import { actionAtom } from "@/atoms/actions-atoms"; -import { selectedProviderAtom } from "@/atoms/providers-atoms"; import type { TPOrSLOption, TPOrSLSettings, -} from "@/components/molecules/tp-sl-dialog"; -import type { WalletAccount, WalletConnected } from "@/domain/wallet"; -import { ApiClientService } from "@/services/api-client"; -import type { - ArgumentsDto, - PositionDto, -} from "@/services/api-client/api-schemas"; -import { runtimeAtom } from "@/services/runtime"; +} from "../components/molecules/tp-sl-dialog"; +import type { WalletAccount, WalletConnected } from "../domain/wallet"; +import { ApiClientService } from "../services/api-client"; +import type { PositionDto } from "../services/api-client/api-schemas"; +import { runtimeAtom } from "../services/runtime"; +import { actionAtom } from "./actions-atoms"; +import { tpSlArgument } from "./edit-position-atoms"; +import { selectedProviderAtom } from "./providers-atoms"; export const editSLOrTPAtom = runtimeAtom.fn( Effect.fn(function* ({ @@ -37,17 +35,9 @@ export const editSLOrTPAtom = runtimeAtom.fn( return yield* Effect.dieMessage("No selected provider"); } - const newStopLossPrice: ArgumentsDto["stopLossPrice"] = - tpOrSLSettings.stopLoss.triggerPrice && - tpOrSLSettings.stopLoss.option !== null - ? tpOrSLSettings.stopLoss.triggerPrice - : undefined; + const newStopLossPrice = tpSlArgument(tpOrSLSettings.stopLoss); - const newTakeProfitPrice: ArgumentsDto["takeProfitPrice"] = - tpOrSLSettings.takeProfit.triggerPrice && - tpOrSLSettings.takeProfit.option !== null - ? tpOrSLSettings.takeProfit.triggerPrice - : undefined; + const newTakeProfitPrice = tpSlArgument(tpOrSLSettings.takeProfit); const action = yield* client.ActionsControllerExecuteAction({ providerId: selectedProvider.id, diff --git a/src/atoms/providers-atoms.ts b/packages/common/src/atoms/providers-atoms.ts similarity index 50% rename from src/atoms/providers-atoms.ts rename to packages/common/src/atoms/providers-atoms.ts index 008bf72..0765114 100644 --- a/src/atoms/providers-atoms.ts +++ b/packages/common/src/atoms/providers-atoms.ts @@ -1,8 +1,8 @@ import { Atom, Result } from "@effect-atom/atom-react"; -import { Array as _Array, Effect } from "effect"; -import { ApiClientService } from "@/services/api-client"; -import type { ProviderDto } from "@/services/api-client/api-schemas"; -import { runtimeAtom, withReactivity } from "@/services/runtime"; +import { Array as _Array, Data, Effect } from "effect"; +import { ApiClientService } from "../services/api-client"; +import type { ProviderDto } from "../services/api-client/api-schemas"; +import { runtimeAtom, withReactivity } from "../services/runtime"; export const providersReactivityKeys = { providers: "providers", @@ -14,23 +14,31 @@ export const providersReactivityKeysArray = Object.values( export const providersAtom = runtimeAtom .atom( - Effect.gen(function* () { - const client = yield* ApiClientService; - - return yield* client.ProvidersControllerGetProviders(); - }), + ApiClientService.pipe( + Effect.andThen((client) => client.ProvidersControllerGetProviders()), + ), ) .pipe(withReactivity([providersReactivityKeys.providers]), Atom.keepAlive); +export class ProviderNotFoundError extends Data.TaggedError( + "ProviderNotFoundError", +) {} + const initialProviderAtom = runtimeAtom.atom( Effect.fn(function* (ctx) { const providers = yield* ctx.resultOnce(providersAtom); - return yield* _Array.head(providers); + const initialProvider = _Array.head(providers); + + if (initialProvider._tag === "None") { + return yield* new ProviderNotFoundError(); + } + + return initialProvider.value; }), ); export const selectedProviderAtom = Atom.writable( (ctx) => ctx.get(initialProviderAtom), (ctx, value: ProviderDto) => ctx.setSelf(Result.success(value)), -); +).pipe(Atom.keepAlive); diff --git a/src/atoms/tokens-atoms.ts b/packages/common/src/atoms/tokens-atoms.ts similarity index 94% rename from src/atoms/tokens-atoms.ts rename to packages/common/src/atoms/tokens-atoms.ts index e24bd52..0b96e8c 100644 --- a/src/atoms/tokens-atoms.ts +++ b/packages/common/src/atoms/tokens-atoms.ts @@ -2,11 +2,11 @@ import { HttpClientRequest, HttpClientResponse } from "@effect/platform"; import { Atom } from "@effect-atom/atom-react"; import { EvmNetworks } from "@stakekit/common"; import { Array as _Array, Effect, Option, pipe, Record, Schema } from "effect"; -import type { TokenBalance } from "@/domain/types"; -import type { WalletAccount } from "@/domain/wallet"; -import { ConfigService } from "@/services/config"; -import { HttpClientService } from "@/services/http-client"; -import { runtimeAtom, withReactivity } from "@/services/runtime"; +import type { TokenBalance } from "../domain/types"; +import type { WalletAccount } from "../domain/wallet"; +import { ConfigService } from "../services/config"; +import { HttpClientService } from "../services/http-client"; +import { runtimeAtom, withReactivity } from "../services/runtime"; export const tokensReactivityKeys = { tokenBalances: "tokenBalances", diff --git a/src/atoms/utils.ts b/packages/common/src/atoms/utils.ts similarity index 100% rename from src/atoms/utils.ts rename to packages/common/src/atoms/utils.ts diff --git a/src/atoms/wallet-atom.ts b/packages/common/src/atoms/wallet-atom.ts similarity index 88% rename from src/atoms/wallet-atom.ts rename to packages/common/src/atoms/wallet-atom.ts index 02ce412..86fa6f7 100644 --- a/src/atoms/wallet-atom.ts +++ b/packages/common/src/atoms/wallet-atom.ts @@ -3,9 +3,9 @@ import { Effect, Stream } from "effect"; import type { BrowserWalletConnected, LedgerWalletConnected, -} from "@/domain/wallet"; -import { runtimeAtom } from "@/services/runtime"; -import { WalletService } from "@/services/wallet/wallet-service"; +} from "../domain/wallet"; +import { runtimeAtom } from "../services/runtime"; +import { WalletService } from "../services/wallet/wallet-service"; export const walletAtom = runtimeAtom.atom( WalletService.pipe( diff --git a/packages/common/src/components/index.ts b/packages/common/src/components/index.ts new file mode 100644 index 0000000..0b4b88a --- /dev/null +++ b/packages/common/src/components/index.ts @@ -0,0 +1,24 @@ +export * from "./molecules/address-switcher"; +export * from "./molecules/Chart/index"; +export * from "./molecules/forms"; +export * from "./molecules/leverage-dialog"; +export * from "./molecules/limit-price-dialog"; +export * from "./molecules/order-type-dialog"; +export * from "./molecules/percentage-slider"; +export * from "./molecules/sign-transactions"; +export * from "./molecules/toggle-group"; +export * from "./molecules/token-icon"; +export * from "./molecules/tp-sl-dialog"; + +export * from "./ui/button"; +export * from "./ui/card"; +export * from "./ui/dialog"; +export * from "./ui/divider"; +export * from "./ui/popover"; +export * from "./ui/select"; +export * from "./ui/skeleton"; +export * from "./ui/slider"; +export * from "./ui/spinner"; +export * from "./ui/tabs"; +export * from "./ui/text"; +export * from "./ui/toaster"; diff --git a/src/components/modules/PositionDetails/Overview/Chart/index.tsx b/packages/common/src/components/molecules/Chart/index.tsx similarity index 51% rename from src/components/modules/PositionDetails/Overview/Chart/index.tsx rename to packages/common/src/components/molecules/Chart/index.tsx index 4a98ca2..a6b06be 100644 --- a/src/components/modules/PositionDetails/Overview/Chart/index.tsx +++ b/packages/common/src/components/molecules/Chart/index.tsx @@ -2,20 +2,26 @@ import { useAtomValue } from "@effect-atom/atom-react"; import { Option } from "effect"; import { TriangleAlertIcon } from "lucide-react"; import { useLayoutEffect, useRef, useState } from "react"; +import { cn } from "../../../lib"; +import { TRADING_VIEW_WIDGET_SCRIPT_URL } from "../../../services"; +import { Text } from "../../ui/text"; +import { ToggleGroup } from "../toggle-group"; import { CHART_INTERVALS, INITIAL_INTERVAL, tradingViewSymbolAtom, -} from "@/components/modules/PositionDetails/Overview/Chart/state"; -import { ToggleGroup } from "@/components/molecules/toggle-group"; -import { TRADING_VIEW_WIDGET_SCRIPT_URL } from "@/services/constants"; +} from "./state"; -function createTradingViewWidget({ +export type ChartVariant = "widget" | "dashboard"; + +export function createTradingViewWidget({ container, onIframeReady, providerId, tradingViewSymbol, + variant, }: { + variant: ChartVariant; container: HTMLDivElement; providerId: string; tradingViewSymbol: string; @@ -23,6 +29,53 @@ function createTradingViewWidget({ }) { container.innerHTML = ""; + const widgetConfig = { + allow_symbol_change: false, + calendar: false, + details: false, + hide_side_toolbar: true, + hide_top_toolbar: true, + hide_legend: true, + hide_volume: true, + hotlist: false, + interval: INITIAL_INTERVAL, + locale: "en", + save_image: false, + style: "1", + symbol: `${providerId}:${tradingViewSymbol}`, + theme: "dark", + timezone: "exchange", + backgroundColor: "rgba(0, 0, 0, 1)", + gridColor: "rgba(74, 74, 74, 0.51)", + watchlist: [], + withdateranges: false, + compareSymbols: [], + studies: [], + autosize: true, + overrides: { + "paneProperties.vertGridProperties.color": "#363c4e", + "mainSeriesProperties.candleStyle.upColor": "#26a69a", + "mainSeriesProperties.candleStyle.downColor": "#ef5350", + // Add these to hide/change border colors: + "paneProperties.separatorColor": "#000000", // transparent (for volume pane separator), + "scalesProperties.lineColor": "transparent", + "scalesProperties.textColor": "#9598a1", // axis text color + "paneProperties.backgroundType": "solid", + "paneProperties.background": "#000000", + }, + }; + + const config = + variant === "widget" + ? JSON.stringify(widgetConfig) + : JSON.stringify({ + ...widgetConfig, + hide_side_toolbar: false, + hide_top_toolbar: false, + hide_legend: false, + hide_volume: false, + }); + const widgetDiv = document.createElement("div"); widgetDiv.className = "tradingview-widget-container__widget"; widgetDiv.style.height = "100%"; @@ -33,31 +86,7 @@ function createTradingViewWidget({ script.src = TRADING_VIEW_WIDGET_SCRIPT_URL; script.type = "text/javascript"; script.async = true; - script.innerHTML = ` - { - "allow_symbol_change": false, - "calendar": false, - "details": false, - "hide_side_toolbar": true, - "hide_top_toolbar": true, - "hide_legend": true, - "hide_volume": true, - "hotlist": true, - "interval": "${INITIAL_INTERVAL}", - "locale": "en", - "save_image": false, - "style": "1", - "symbol": "${providerId}:${tradingViewSymbol}", - "theme": "dark", - "timezone": "exchange", - "backgroundColor": "rgba(0, 0, 0, 1)", - "gridColor": "rgba(74, 74, 74, 0.51)", - "watchlist": [], - "withdateranges": false, - "compareSymbols": [], - "studies": [], - "autosize": true - }`; + script.innerHTML = config; container.appendChild(script); let charLoadTimeout: NodeJS.Timeout | null = null; @@ -94,7 +123,9 @@ function createTradingViewWidget({ function ChartAvailable({ providerId, tradingViewSymbol, + variant, }: { + variant: ChartVariant; providerId: string; tradingViewSymbol: string; }) { @@ -105,11 +136,13 @@ function ChartAvailable({ const [isLoading, setIsLoading] = useState(true); useLayoutEffect(() => { + setIsLoading(true); const container = containerRef.current; if (!container) return; return createTradingViewWidget({ container, + variant, providerId, tradingViewSymbol, onIframeReady: (iframe) => { @@ -117,7 +150,7 @@ function ChartAvailable({ iframeRef.current = iframe; }, }); - }, [providerId, tradingViewSymbol]); + }, [providerId, tradingViewSymbol, variant]); const handleIntervalChange = (newInterval: string) => { if (newInterval === chartInterval || !iframeRef.current?.contentWindow) { @@ -133,11 +166,21 @@ function ChartAvailable({ return ( <> -
+
{/* Loading overlay */} @@ -145,37 +188,58 @@ function ChartAvailable({
- Loading chart... + + Loading chart... +
)}
-
- -
+ {variant === "widget" && ( +
+ +
+ )} ); } -const ChartNotAvailable = () => { +const ChartNotAvailable = ({ variant }: { variant: ChartVariant }) => { return ( -
+
- Chart not available + + Chart not available +
); }; -export const Chart = ({ symbol }: { symbol: string }) => { +export const Chart = ({ + symbol, + variant, +}: { + symbol: string; + variant: "widget" | "dashboard"; +}) => { const chartMeta = useAtomValue(tradingViewSymbolAtom(symbol)).pipe( Option.map((v) => ({ providerId: v.providerId, @@ -184,5 +248,9 @@ export const Chart = ({ symbol }: { symbol: string }) => { Option.getOrNull, ); - return chartMeta ? : ; + return chartMeta ? ( + + ) : ( + + ); }; diff --git a/src/components/modules/PositionDetails/Overview/Chart/state.ts b/packages/common/src/components/molecules/Chart/state.ts similarity index 77% rename from src/components/modules/PositionDetails/Overview/Chart/state.ts rename to packages/common/src/components/molecules/Chart/state.ts index 9c3ec72..66bfd7c 100644 --- a/src/components/modules/PositionDetails/Overview/Chart/state.ts +++ b/packages/common/src/components/molecules/Chart/state.ts @@ -1,6 +1,6 @@ import { Atom } from "@effect-atom/atom-react"; -import { Record, Schema } from "effect"; -import tradingViewSymbols from "@/assets/tradingview-symbols.json" with { +import { Array as _Array, Option, Record, Schema } from "effect"; +import tradingViewSymbols from "../../../assets/tradingview-symbols.json" with { type: "json", }; @@ -34,4 +34,6 @@ export const CHART_INTERVALS = [ { value: "W", label: "1w" }, ]; -export const INITIAL_INTERVAL = CHART_INTERVALS[0].value; +export const INITIAL_INTERVAL = _Array + .head(CHART_INTERVALS) + .pipe(Option.getOrThrow).value; diff --git a/src/components/molecules/address-switcher.tsx b/packages/common/src/components/molecules/address-switcher.tsx similarity index 85% rename from src/components/molecules/address-switcher.tsx rename to packages/common/src/components/molecules/address-switcher.tsx index 73518a2..10b02a4 100644 --- a/src/components/molecules/address-switcher.tsx +++ b/packages/common/src/components/molecules/address-switcher.tsx @@ -2,21 +2,25 @@ import { useAtomSet } from "@effect-atom/atom-react"; import { useDisconnect } from "@reown/appkit/react"; import { Match } from "effect"; import { Check, ChevronDown, Copy, LogOut, Wallet } from "lucide-react"; +import type React from "react"; import { useEffect, useRef, useState } from "react"; import { switchBrowserAccountAtom, switchLedgerAccountAtom, -} from "@/atoms/wallet-atom"; -import { Button } from "@/components/ui/button"; -import { Dialog } from "@/components/ui/dialog"; +} from "../../atoms/wallet-atom"; +import type { + BrowserWalletConnected, + LedgerWalletConnected, +} from "../../domain/wallet"; import { - type BrowserWalletConnected, isBrowserWalletConnected, isLedgerWalletConnected, - type LedgerWalletConnected, type WalletConnected, -} from "@/domain/wallet"; -import { cn, truncateAddress } from "@/lib/utils"; +} from "../../domain/wallet"; +import { cn, truncateAddress } from "../../lib/utils"; +import { Button } from "../ui/button"; +import { Dialog } from "../ui/dialog"; +import { Text } from "../ui/text"; const LedgerAccountList = ({ wallet, @@ -56,13 +60,13 @@ const LedgerAccountList = ({
- + Account ID: {truncateAddress(account.id)} - + - + Address: {truncateAddress(account.address)} - +
{isCurrentAccount && } @@ -105,9 +109,9 @@ const BrowserAccountList = ({
- + {truncateAddress(account.address)} - +
{isCurrentAccount && } @@ -226,26 +230,29 @@ const DisconnectButton = ({ onDisconnect }: { onDisconnect: () => void }) => { ); }; -export const AddressSwitcher = ({ wallet }: { wallet: WalletConnected }) => { +interface AddressSwitcherProps { + wallet: WalletConnected; + trigger?: React.ReactElement; +} + +export const AddressSwitcher = ({ wallet, trigger }: AddressSwitcherProps) => { const [open, setOpen] = useState(false); return ( ( - - )} + render={ + trigger ?? + ((props) => ( + + )) + } /> diff --git a/src/components/molecules/forms/index.tsx b/packages/common/src/components/molecules/forms/index.tsx similarity index 82% rename from src/components/molecules/forms/index.tsx rename to packages/common/src/components/molecules/forms/index.tsx index 0a746c9..102f2d9 100644 --- a/src/components/molecules/forms/index.tsx +++ b/packages/common/src/components/molecules/forms/index.tsx @@ -1,5 +1,6 @@ import type { FormReact } from "@lucas-barake/effect-form-react"; import { Option } from "effect"; +import { Text } from "../../ui/text"; export const AmountField: FormReact.FieldComponent = ({ field }) => { const onChange: (typeof field)["onChange"] = (newValue) => { @@ -41,11 +42,21 @@ export const AmountField: FormReact.FieldComponent = ({ field }) => { {Option.isSome(field.error) && (
- ! + + ! +
- + {field.error.value} - +
)}
diff --git a/packages/common/src/components/molecules/index.ts b/packages/common/src/components/molecules/index.ts new file mode 100644 index 0000000..67c5a39 --- /dev/null +++ b/packages/common/src/components/molecules/index.ts @@ -0,0 +1,7 @@ +export * from "./leverage-dialog"; +export * from "./limit-price-dialog"; +export * from "./order-type-dialog"; +export * from "./percentage-slider"; +export * from "./toggle-group"; +export * from "./token-icon"; +export * from "./tp-sl-dialog"; diff --git a/src/components/modules/Order/Overview/leverage-dialog.tsx b/packages/common/src/components/molecules/leverage-dialog.tsx similarity index 70% rename from src/components/modules/Order/Overview/leverage-dialog.tsx rename to packages/common/src/components/molecules/leverage-dialog.tsx index f304b19..7348e96 100644 --- a/src/components/modules/Order/Overview/leverage-dialog.tsx +++ b/packages/common/src/components/molecules/leverage-dialog.tsx @@ -1,18 +1,21 @@ import type { DialogRootActions } from "@base-ui/react/dialog"; import { X } from "lucide-react"; import { useRef, useState } from "react"; -import { ToggleGroup } from "@/components/molecules/toggle-group"; -import { Button } from "@/components/ui/button"; -import { Dialog } from "@/components/ui/dialog"; -import { Divider } from "@/components/ui/divider"; -import { Slider } from "@/components/ui/slider"; +import { formatAmount, formatPercentage } from "../../lib/formatting"; import { + generateLeverageButtons, + getLeverageFromPercent, getLeveragePercent, + getLeverageStops, getLiquidationPrice, getPriceChangePercentToLiquidation, - MIN_LEVERAGE, -} from "@/domain/position"; -import { formatAmount, formatPercentage } from "@/lib/utils"; +} from "../../lib/math"; +import { Button } from "../ui/button"; +import { Dialog } from "../ui/dialog"; +import { Divider } from "../ui/divider"; +import { Slider } from "../ui/slider"; +import { Text } from "../ui/text"; +import { ToggleGroup } from "./toggle-group"; type LeverageDialogProps = Pick< LeverageDialogContentProps, @@ -73,11 +76,7 @@ export function LeverageDialogContent({ }: LeverageDialogContentProps) { const [localLeverage, setLocalLeverage] = useState(leverage); - const leverageStops = [ - MIN_LEVERAGE, - Math.round(maxLeverage / 2), - maxLeverage, - ]; + const leverageStops = getLeverageStops(maxLeverage); const leveragePercent = getLeveragePercent({ leverage: localLeverage, @@ -105,12 +104,14 @@ export function LeverageDialogContent({
{/* Header */}
- Leverage - +
); } - -const generateLeverageButtons = (maxLeverage: number): number[] => { - const buttons: number[] = []; - - if (maxLeverage >= 2) { - buttons.push(2); - } - - if (maxLeverage >= 5) { - buttons.push(5); - } - - let value = 10; - while (value <= maxLeverage) { - buttons.push(value); - value *= 2; - } - - if (buttons[buttons.length - 1] !== maxLeverage && maxLeverage > 2) { - buttons.push(maxLeverage); - } - - return [...new Set(buttons)].sort((a, b) => a - b); -}; diff --git a/src/components/modules/Order/Overview/limit-price-dialog.tsx b/packages/common/src/components/molecules/limit-price-dialog.tsx similarity index 88% rename from src/components/modules/Order/Overview/limit-price-dialog.tsx rename to packages/common/src/components/molecules/limit-price-dialog.tsx index 8e87f25..f9578a3 100644 --- a/src/components/modules/Order/Overview/limit-price-dialog.tsx +++ b/packages/common/src/components/molecules/limit-price-dialog.tsx @@ -5,8 +5,10 @@ import clsx from "clsx"; import { Option, Schema } from "effect"; import { X } from "lucide-react"; import { useRef } from "react"; -import { Button } from "@/components/ui/button"; -import { Dialog } from "@/components/ui/dialog"; +import { applyPercentDelta, round } from "../../lib/math"; +import { Button } from "../ui/button"; +import { Dialog } from "../ui/dialog"; +import { Text } from "../ui/text"; const PRICE_QUICK_ADJUSTMENTS = [-1, -2, -5, -10]; @@ -67,9 +69,8 @@ function LimitPriceDialogContent({ const submit = useAtomSet(LimitPriceForm.submit); const handleQuickAdjust = (percent: number) => { - const adjustment = currentPrice * (percent / 100); - const newPrice = currentPrice + adjustment; - setAmount(newPrice.toString()); + const newPrice = applyPercentDelta({ value: currentPrice, percent }); + setAmount(round(newPrice, 2).toString()); }; const handleConfirm = () => @@ -82,9 +83,9 @@ function LimitPriceDialogContent({ {/* Header */}
- + Set limit price - + @@ -179,7 +181,9 @@ const LimitPriceForm = FormReact.make(limitPriceFormBuilder, { )} /> - USD + + USD +
), }, diff --git a/src/components/modules/Order/Overview/order-type-dialog.tsx b/packages/common/src/components/molecules/order-type-dialog.tsx similarity index 84% rename from src/components/modules/Order/Overview/order-type-dialog.tsx rename to packages/common/src/components/molecules/order-type-dialog.tsx index c0e3104..969d89d 100644 --- a/src/components/modules/Order/Overview/order-type-dialog.tsx +++ b/packages/common/src/components/molecules/order-type-dialog.tsx @@ -1,8 +1,10 @@ import type { DialogRootActions } from "@base-ui/react/dialog"; import { Check, ChevronDown } from "lucide-react"; import { useRef } from "react"; -import type { OrderType } from "@/components/modules/Order/Overview/state"; -import { Dialog } from "@/components/ui/dialog"; +import { Dialog } from "../ui/dialog"; +import { Text } from "../ui/text"; + +type OrderType = "market" | "limit"; interface OrderTypeDialogProps { selectedType: OrderType; @@ -49,10 +51,10 @@ export function OrderTypeDialog({ type="button" className="flex items-center gap-2 bg-[#161616] px-3.5 py-2.5 rounded-[11px] h-9" > - + {ORDER_TYPE_OPTIONS.find((opt) => opt.value === selectedType) ?.label ?? "Market"} - + )} @@ -77,12 +79,12 @@ export function OrderTypeDialog({ className="flex items-center gap-2 bg-white/5 px-4 py-4 rounded-[10px] w-full text-left transition-colors hover:bg-white/10 cursor-pointer" >
- + {option.label} - - + + {option.description} - +
{isSelected && ( diff --git a/src/components/molecules/percentage-slider.tsx b/packages/common/src/components/molecules/percentage-slider.tsx similarity index 88% rename from src/components/molecules/percentage-slider.tsx rename to packages/common/src/components/molecules/percentage-slider.tsx index 711ad24..c778881 100644 --- a/src/components/molecules/percentage-slider.tsx +++ b/packages/common/src/components/molecules/percentage-slider.tsx @@ -1,8 +1,5 @@ -import { - ToggleGroup, - type ToggleGroupProps, -} from "@/components/molecules/toggle-group"; -import { Slider } from "@/components/ui/slider"; +import { Slider } from "../ui/slider"; +import { ToggleGroup, type ToggleGroupProps } from "./toggle-group"; const percentageOptions = [ { value: "25", label: "25%" }, diff --git a/src/components/molecules/sign/sign-content.tsx b/packages/common/src/components/molecules/sign-transactions/index.tsx similarity index 74% rename from src/components/molecules/sign/sign-content.tsx rename to packages/common/src/components/molecules/sign-transactions/index.tsx index 63a9ba2..4e2f717 100644 --- a/src/components/molecules/sign/sign-content.tsx +++ b/packages/common/src/components/molecules/sign-transactions/index.tsx @@ -1,5 +1,5 @@ -import { Result, useAtomSet, useAtomValue } from "@effect-atom/atom-react"; -import { Navigate } from "@tanstack/react-router"; +import type { SignTransactionsState } from "@yieldxyz/perps-common/domain"; +import { cn, formatSnakeCase } from "@yieldxyz/perps-common/lib"; import { Cause } from "effect"; import { CheckCircle2, @@ -10,37 +10,21 @@ import { Send, XCircle, } from "lucide-react"; -import type { signActionAtoms } from "@/atoms/actions-atoms"; -import { Button } from "@/components/ui/button"; -import { Card, CardSection } from "@/components/ui/card"; -import { Skeleton } from "@/components/ui/skeleton"; -import type { SignTransactionsState } from "@/domain/wallet"; -import { cn, formatSnakeCase } from "@/lib/utils"; +import { Button } from "../../ui/button"; +import { Card, CardSection } from "../../ui/card"; +import { Text } from "../../ui/text"; -interface SignTransactionsProps { +export interface TransactionProgressProps { state: SignTransactionsState; - retry: () => void; -} - -function SignTransactionsWithState({ state, retry }: SignTransactionsProps) { - return ( -
-

- Progress -

- - retry()} /> -
- ); + onRetry?: () => void; + onClose?: () => void; } -function SignTransactionsContent({ +export function TransactionProgress({ state, onRetry, -}: { - state: SignTransactionsState; - onRetry?: () => void; -}) { + onClose, +}: TransactionProgressProps) { const { transactions, currentTxIndex, step, error, isDone } = state; const totalTransactions = transactions.length; @@ -52,11 +36,11 @@ function SignTransactionsContent({
{/* Progress indicator */}
-

+ {isDone ? "All transactions complete" : `Transaction ${currentTxIndex + 1} of ${totalTransactions}`} -

+ {totalTransactions > 1 && (
{transactions.map((tx, idx) => ( @@ -87,9 +71,13 @@ function SignTransactionsContent({
-

+ {getErrorDescription(error)} -

+
@@ -122,12 +110,16 @@ function SignTransactionsContent({ {/* Transaction header */}
-

+ {formatTransactionType(tx.type)} -

-

+ + {formatSnakeCase(tx.network)} -

+
- {/* Retry button when there's an error */} - {error !== null && onRetry && ( - - )} + {/* Action buttons */} +
+ {error !== null && onRetry && ( + + )} + {(isDone || error !== null) && onClose && ( + + )} +
); } @@ -190,25 +189,25 @@ function TransactionStatusBadge({ }) { if (status === "CONFIRMED") { return ( - + Confirmed - + ); } if (status === "FAILED" || status === "NOT_FOUND") { return ( - + Failed - + ); } if (isFuture) { return ( - + Pending - + ); } @@ -220,16 +219,16 @@ function TransactionStatusBadge({ }; return ( - + {stepLabels[step]} - + ); } return ( - + {status} - + ); } @@ -282,16 +281,18 @@ function VerticalProgressStep({ )}
{/* Label on the right */} - {label} - +
); } @@ -348,35 +349,3 @@ function getErrorDescription(error: SignTransactionsState["error"]): string { return "An error occurred"; } - -export function SignTransactions({ - machineAtoms, -}: { - machineAtoms: ReturnType; -}) { - const { machineStreamAtom, retryMachineAtom } = machineAtoms; - const state = useAtomValue(machineStreamAtom); - const retry = useAtomSet(retryMachineAtom); - - const result = Result.all({ state, retry }); - - if (Result.isFailure(result)) { - return ( - <> - - - - ); - } - - if (Result.isSuccess(result)) { - return ( - - ); - } - - return ; -} diff --git a/src/components/molecules/toggle-group.tsx b/packages/common/src/components/molecules/toggle-group.tsx similarity index 98% rename from src/components/molecules/toggle-group.tsx rename to packages/common/src/components/molecules/toggle-group.tsx index ca451c4..1de3e20 100644 --- a/src/components/molecules/toggle-group.tsx +++ b/packages/common/src/components/molecules/toggle-group.tsx @@ -1,7 +1,7 @@ import { Toggle } from "@base-ui/react/toggle"; import { ToggleGroup as BaseToggleGroup } from "@base-ui/react/toggle-group"; import type { ComponentProps } from "react"; -import { cn } from "@/lib/utils"; +import { cn } from "../../lib/utils"; export interface ToggleOption { value: string; diff --git a/src/components/molecules/token-icon.tsx b/packages/common/src/components/molecules/token-icon.tsx similarity index 90% rename from src/components/molecules/token-icon.tsx rename to packages/common/src/components/molecules/token-icon.tsx index 158feec..80d815d 100644 --- a/src/components/molecules/token-icon.tsx +++ b/packages/common/src/components/molecules/token-icon.tsx @@ -1,6 +1,5 @@ import { cva, type VariantProps } from "class-variance-authority"; -import { getNetworkLogo } from "@/lib/utils"; -import type { Networks } from "@/services/api-client/client-factory"; +import { getNetworkLogo } from "../../lib/utils"; const tokenIconVariants = cva("relative flex items-end", { variants: { @@ -38,7 +37,7 @@ const networkBadgeVariants = cva( export type TokenIconProps = { logoURI: string; name: string; - network?: Networks; + network?: string; } & VariantProps; export function TokenIcon({ logoURI, name, network, size }: TokenIconProps) { diff --git a/src/components/molecules/tp-sl-dialog.tsx b/packages/common/src/components/molecules/tp-sl-dialog.tsx similarity index 68% rename from src/components/molecules/tp-sl-dialog.tsx rename to packages/common/src/components/molecules/tp-sl-dialog.tsx index b3fda6a..4cb0045 100644 --- a/src/components/molecules/tp-sl-dialog.tsx +++ b/packages/common/src/components/molecules/tp-sl-dialog.tsx @@ -2,14 +2,23 @@ import type { DialogRootActions } from "@base-ui/react/dialog"; import { Match } from "effect"; import { X } from "lucide-react"; import { useRef, useState } from "react"; -import { Button } from "@/components/ui/button"; -import { Card, CardSection } from "@/components/ui/card"; -import { Dialog } from "@/components/ui/dialog"; -import { formatAmount } from "@/lib/utils"; - -const OPTIONS = [0, 10, 25, 50, 100] as const; - -type TPOrSLPercentageOption = (typeof OPTIONS)[number] | null; +import { formatAmount } from "../../lib/formatting"; +import { + calcTpSlPercentFromTriggerPrice, + calcTpSlTriggerPriceFromPercent, + DEFAULT_TP_SL_PERCENT_OPTIONS, + findMatchingPercentOption, + getTpSlPercentPrefix, + round, +} from "../../lib/math"; +import { Button } from "../ui/button"; +import { Card, CardSection } from "../ui/card"; +import { Dialog } from "../ui/dialog"; +import { Text } from "../ui/text"; + +type TPOrSLPercentageOption = + | (typeof DEFAULT_TP_SL_PERCENT_OPTIONS)[number] + | null; export type TPOrSLConfiguration = { option: TPOrSLPercentageOption; @@ -109,25 +118,12 @@ function TPOrSLDialogContent({ ): TPOrSLConfiguration["triggerPrice"] => { if (option === null || option === 0) return null; - return Match.value({ side, tpOrSl }).pipe( - Match.when( - { side: "short", tpOrSl: "takeProfit" }, - () => entryPrice * (1 - option / 100), - ), - Match.when( - { side: "short", tpOrSl: "stopLoss" }, - () => entryPrice * (1 + option / 100), - ), - Match.when( - { side: "long", tpOrSl: "takeProfit" }, - () => entryPrice * (1 + option / 100), - ), - Match.when( - { side: "long", tpOrSl: "stopLoss" }, - () => entryPrice * (1 - option / 100), - ), - Match.exhaustive, - ); + return calcTpSlTriggerPriceFromPercent({ + entryPrice, + percent: option, + side, + tpOrSl, + }); }; const handleTPOrSLOptionChange = ( @@ -157,27 +153,17 @@ function TPOrSLDialogContent({ })); } - const percentage = Match.value({ side, tpOrSl }).pipe( - Match.when( - { side: "short", tpOrSl: "takeProfit" }, - () => ((entryPrice - triggerPrice) / entryPrice) * 100, - ), - Match.when( - { side: "short", tpOrSl: "stopLoss" }, - () => ((triggerPrice - entryPrice) / entryPrice) * 100, - ), - Match.when( - { side: "long", tpOrSl: "takeProfit" }, - () => ((triggerPrice - entryPrice) / entryPrice) * 100, - ), - Match.when( - { side: "long", tpOrSl: "stopLoss" }, - () => ((entryPrice - triggerPrice) / entryPrice) * 100, - ), - Match.exhaustive, - ); - - const option = findMatchingOption(percentage); + const percentage = calcTpSlPercentFromTriggerPrice({ + entryPrice, + triggerPrice, + side, + tpOrSl, + }); + + const option = findMatchingPercentOption({ + percent: percentage, + options: DEFAULT_TP_SL_PERCENT_OPTIONS, + }); setLocalSettings((prev) => ({ ...prev, @@ -200,27 +186,17 @@ function TPOrSLDialogContent({ })); } - const triggerPrice = Match.value({ side, tpOrSl }).pipe( - Match.when( - { side: "short", tpOrSl: "takeProfit" }, - () => entryPrice * (1 - percentage / 100), - ), - Match.when( - { side: "short", tpOrSl: "stopLoss" }, - () => entryPrice * (1 + percentage / 100), - ), - Match.when( - { side: "long", tpOrSl: "takeProfit" }, - () => entryPrice * (1 + percentage / 100), - ), - Match.when( - { side: "long", tpOrSl: "stopLoss" }, - () => entryPrice * (1 - percentage / 100), - ), - Match.exhaustive, - ); - - const option = findMatchingOption(percentage); + const triggerPrice = calcTpSlTriggerPriceFromPercent({ + entryPrice, + percent: percentage, + side, + tpOrSl, + }); + + const option = findMatchingPercentOption({ + percent: percentage, + options: DEFAULT_TP_SL_PERCENT_OPTIONS, + }); setLocalSettings((prev) => ({ ...prev, @@ -244,9 +220,9 @@ function TPOrSLDialogContent({ {/* Header */}
- + {dialogTitle} - +
-

+ {Match.value(isSingleMode).pipe( Match.when( true, @@ -267,7 +243,7 @@ function TPOrSLDialogContent({ "Pick a percentage gain or loss, or enter a custom trigger price to automatically close your position.", ), )} -

+
{/* Info Card */} @@ -334,7 +310,8 @@ function TPOrSLDialogContent({ {/* Done Button */} @@ -352,13 +329,13 @@ interface InfoRowProps { function InfoRow({ label, value, position }: InfoRowProps) { return ( - + {label} - +
- + {formatAmount(value, { maximumFractionDigits: 0 })} - +
); @@ -386,9 +363,9 @@ function TPOrSLSection({ return (
- + {label} - +
- {OPTIONS.map((option) => ( + {DEFAULT_TP_SL_PERCENT_OPTIONS.map((option) => ( @@ -477,15 +444,19 @@ function TPOrSLInputFields({ inputMode="decimal" value={Match.value(triggerPrice).pipe( Match.when(null, () => ""), - Match.orElse((value) => value.toFixed(2)), + Match.orElse((value) => round(value, 2).toString()), )} onChange={(e) => onTriggerPriceChange(e.target.value)} placeholder="Trigger price" className="w-full h-full bg-transparent text-white text-sm font-normal tracking-[-0.42px] pl-4 pr-10 outline-none placeholder:text-gray-2" /> - + ($) - +
""), Match.when(0, () => ""), - Match.orElse((value) => value.toFixed(2)), + Match.orElse((value) => round(value, 2).toString()), )} onChange={(e) => onPercentChange(e.target.value)} placeholder={percentPlaceholder} className="w-full h-full bg-transparent text-white text-sm font-normal tracking-[-0.42px] pl-4 pr-8 outline-none placeholder:text-gray-2" /> - + % - +
); } - -const findMatchingOption = (percent: number): TPOrSLPercentageOption | null => - OPTIONS.find((opt) => opt !== null && Math.abs(percent - opt) < 0.5) || null; - -export const getTPOrSLConfigurationFromPosition = ({ - amount, - entryPrice, - tpOrSl, - side = "long", -}: { - entryPrice: number; - amount: number | undefined; - tpOrSl: TPOrSLOption; - side?: "long" | "short"; -}): TPOrSLConfiguration => { - const percentage = Match.value(amount).pipe( - Match.when(undefined, () => null), - Match.orElse((value) => - Match.value({ side, tpOrSl }).pipe( - Match.when( - { side: "short", tpOrSl: "takeProfit" }, - () => ((entryPrice - value) / entryPrice) * 100, - ), - Match.when( - { side: "short", tpOrSl: "stopLoss" }, - () => ((value - entryPrice) / entryPrice) * 100, - ), - Match.when( - { side: "long", tpOrSl: "takeProfit" }, - () => ((value - entryPrice) / entryPrice) * 100, - ), - Match.when( - { side: "long", tpOrSl: "stopLoss" }, - () => ((entryPrice - value) / entryPrice) * 100, - ), - Match.exhaustive, - ), - ), - ); - const option = Match.value(percentage).pipe( - Match.when(null, () => null), - Match.when(0, () => null), - Match.orElse((value) => findMatchingOption(value)), - ); - - return { - option, - triggerPrice: amount || null, - percentage, - }; -}; diff --git a/src/components/ui/button.tsx b/packages/common/src/components/ui/button.tsx similarity index 76% rename from src/components/ui/button.tsx rename to packages/common/src/components/ui/button.tsx index 5be28e0..c3909df 100644 --- a/src/components/ui/button.tsx +++ b/packages/common/src/components/ui/button.tsx @@ -1,11 +1,10 @@ import { Button as ButtonPrimitive } from "@base-ui/react/button"; import { cva, type VariantProps } from "class-variance-authority"; - -import { cn } from "@/lib/utils"; +import { cn } from "../../lib/utils"; import { Spinner } from "./spinner"; const buttonVariants = cva( - "cursor-pointer focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-2xl border border-transparent bg-clip-padding text-sm focus-visible:ring-[3px] aria-invalid:ring-[3px] [&_svg:not([class*='size-'])]:size-4 inline-flex items-center justify-center whitespace-nowrap transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none shrink-0 [&_svg]:shrink-0 outline-none group/button select-none font-semibold text-base", + "cursor-pointer focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-xl border border-transparent bg-clip-padding text-sm focus-visible:ring-[3px] aria-invalid:ring-[3px] [&_svg:not([class*='size-'])]:size-4 inline-flex items-center justify-center whitespace-nowrap transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none shrink-0 [&_svg]:shrink-0 outline-none group/button select-none font-semibold text-base", { variants: { variant: { @@ -23,11 +22,11 @@ const buttonVariants = cva( link: "text-primary underline-offset-4 hover:underline", }, size: { + lg: "h-14 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-3 has-data-[icon=inline-start]:pl-3", default: - "h-15 gap-1.5 px-2.5 in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2", - xs: "h-6 gap-1 rounded-[min(var(--radius-md),8px)] px-2 text-xs in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3", - sm: "h-8 gap-1 rounded-[min(var(--radius-md),10px)] px-2.5 in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5", - lg: "h-10 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-3 has-data-[icon=inline-start]:pl-3", + "h-12 gap-1.5 px-2.5 in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2", + sm: "h-10 gap-1 rounded-[min(var(--radius-md),10px)] px-2.5 in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5", + xs: "h-8 gap-1 rounded-[min(var(--radius-md),8px)] px-2 text-xs in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3", icon: "size-9", "icon-xs": "size-6 rounded-full in-data-[slot=button-group]:rounded-md [&_svg:not([class*='size-'])]:size-3", diff --git a/src/components/ui/card.tsx b/packages/common/src/components/ui/card.tsx similarity index 87% rename from src/components/ui/card.tsx rename to packages/common/src/components/ui/card.tsx index 1fc6d43..052a0b1 100644 --- a/src/components/ui/card.tsx +++ b/packages/common/src/components/ui/card.tsx @@ -1,6 +1,5 @@ import { cva, type VariantProps } from "class-variance-authority"; - -import { cn } from "@/lib/utils"; +import { cn } from "../../lib/utils"; const cardVariants = cva("flex flex-col w-full"); @@ -14,8 +13,8 @@ const cardSectionVariants = cva("bg-gray-3 px-4 py-[18px]", { variants: { position: { first: "rounded-t-2xl", - middle: "border-t border-[#090909]", - last: "rounded-b-2xl border-t border-[#090909]", + middle: "border-t border-surface-3", + last: "rounded-b-2xl border-t border-surface-3", only: "rounded-2xl", }, }, diff --git a/src/components/ui/dialog.tsx b/packages/common/src/components/ui/dialog.tsx similarity index 96% rename from src/components/ui/dialog.tsx rename to packages/common/src/components/ui/dialog.tsx index 38b1fed..5dca9cf 100644 --- a/src/components/ui/dialog.tsx +++ b/packages/common/src/components/ui/dialog.tsx @@ -2,8 +2,8 @@ import { Dialog as DialogPrimitive } from "@base-ui/react/dialog"; import { cva, type VariantProps } from "class-variance-authority"; import { X } from "lucide-react"; import type { ComponentProps } from "react"; -import { useRootContainer } from "@/context/root-container"; -import { cn } from "@/lib/utils"; +import { useRootContainer } from "../../context/root-container"; +import { cn } from "../../lib/utils"; // Re-export the Root component const Root = DialogPrimitive.Root; @@ -46,7 +46,7 @@ function Backdrop({ const dialogPopupVariants = cva( [ "fixed z-50", - "bg-[#222] rounded-2xl overflow-hidden", + "bg-[#151515] rounded-2xl overflow-hidden", "animate-in fade-in zoom-in-95 duration-200", "data-[ending-style]:opacity-0 data-[ending-style]:scale-95", "data-[starting-style]:opacity-0 data-[starting-style]:scale-95", diff --git a/packages/common/src/components/ui/divider.tsx b/packages/common/src/components/ui/divider.tsx new file mode 100644 index 0000000..ba86f00 --- /dev/null +++ b/packages/common/src/components/ui/divider.tsx @@ -0,0 +1,3 @@ +export const Divider = () => { + return
; +}; diff --git a/packages/common/src/components/ui/popover.tsx b/packages/common/src/components/ui/popover.tsx new file mode 100644 index 0000000..28a092f --- /dev/null +++ b/packages/common/src/components/ui/popover.tsx @@ -0,0 +1,128 @@ +import { Popover as PopoverPrimitive } from "@base-ui/react/popover"; +import type { ComponentProps } from "react"; +import { useRootContainer } from "../../context/root-container"; +import { cn } from "../../lib/utils"; + +// Re-export the Root component +const Root = PopoverPrimitive.Root; + +// Re-export the Trigger component +const Trigger = PopoverPrimitive.Trigger; + +// Portal with container support +const Portal = ({ + children, + ...props +}: ComponentProps) => { + const rootContainer = useRootContainer(); + + return ( + + {children} + + ); +}; + +// Positioner for positioning the popup +function Positioner({ + className, + sideOffset = 8, + ...props +}: ComponentProps) { + return ( + + ); +} + +// Popup with default styles +function Popup({ + className, + ...props +}: ComponentProps) { + return ( + + ); +} + +// Arrow component +function Arrow({ + className, + ...props +}: ComponentProps) { + return ( + + ); +} + +// Title with default styles +function Title({ + className, + ...props +}: ComponentProps) { + return ( + + ); +} + +// Description with default styles +function Description({ + className, + ...props +}: ComponentProps) { + return ( + + ); +} + +// Close button +function Close({ + className, + ...props +}: ComponentProps) { + return ; +} + +export const Popover = { + Root, + Trigger, + Portal, + Positioner, + Popup, + Arrow, + Title, + Description, + Close, +}; diff --git a/packages/common/src/components/ui/select.tsx b/packages/common/src/components/ui/select.tsx new file mode 100644 index 0000000..2bf40cf --- /dev/null +++ b/packages/common/src/components/ui/select.tsx @@ -0,0 +1,213 @@ +import { Select as SelectPrimitive } from "@base-ui/react/select"; +import { cva, type VariantProps } from "class-variance-authority"; +import { Check, ChevronDown } from "lucide-react"; +import type { ComponentProps, ReactNode } from "react"; +import { useRootContainer } from "../../context/root-container"; +import { cn } from "../../lib/utils"; + +// Re-export the Root component +const Root = SelectPrimitive.Root; + +// Re-export the Value component +const Value = SelectPrimitive.Value; + +// Re-export the Icon component +const Icon = SelectPrimitive.Icon; + +// Re-export the Group component +const Group = SelectPrimitive.Group; + +// Re-export the GroupLabel component +const GroupLabel = ({ + className, + ...props +}: ComponentProps) => ( + +); + +const selectTriggerVariants = cva( + [ + "flex items-center justify-between gap-2", + "bg-white/5 rounded-lg", + "text-white text-[13px]", + "transition-colors", + "hover:bg-white/10", + "focus:outline-none", + "disabled:opacity-50 disabled:cursor-not-allowed", + ], + { + variants: { + size: { + sm: "h-8 px-3", + default: "h-10 px-3.5", + lg: "h-12 px-4", + }, + }, + defaultVariants: { + size: "default", + }, + }, +); + +interface TriggerProps + extends ComponentProps, + VariantProps {} + +function Trigger({ className, size, children, ...props }: TriggerProps) { + return ( + + {children} + + + + + ); +} + +// Portal with container support +const Portal = ({ + children, + ...props +}: ComponentProps) => { + const rootContainer = useRootContainer(); + + return ( + + {children} + + ); +}; + +// Positioner for positioning the popup +function Positioner({ + className, + ...props +}: ComponentProps) { + return ( + + ); +} + +// Popup with default styles +function Popup({ + className, + ...props +}: ComponentProps) { + return ( + + ); +} + +// Item with default styles +interface ItemProps extends ComponentProps { + icon?: ReactNode; + showIndicator?: boolean; +} + +function Item({ + className, + icon, + children, + showIndicator = true, + ...props +}: ItemProps) { + return ( + + {icon && {icon}} + + {children} + + {showIndicator && ( + + + + )} + + ); +} + +// ItemText component +const ItemText = ({ + className, + ...props +}: ComponentProps) => ( + +); + +// ItemIndicator component +const ItemIndicator = ({ + className, + children, + ...props +}: ComponentProps) => ( + + {children ?? } + +); + +// Separator +function Separator({ + className, + ...props +}: ComponentProps) { + return ( + + ); +} + +export const Select = { + Root, + Trigger, + Value, + Icon, + Portal, + Positioner, + Popup, + Group, + GroupLabel, + Item, + ItemText, + ItemIndicator, + Separator, +}; diff --git a/src/components/ui/skeleton.tsx b/packages/common/src/components/ui/skeleton.tsx similarity index 96% rename from src/components/ui/skeleton.tsx rename to packages/common/src/components/ui/skeleton.tsx index 29becb8..96fd951 100644 --- a/src/components/ui/skeleton.tsx +++ b/packages/common/src/components/ui/skeleton.tsx @@ -1,4 +1,4 @@ -import { cn } from "@/lib/utils"; +import { cn } from "../../lib/utils"; interface SkeletonProps { className?: string; diff --git a/src/components/ui/slider.tsx b/packages/common/src/components/ui/slider.tsx similarity index 99% rename from src/components/ui/slider.tsx rename to packages/common/src/components/ui/slider.tsx index a3b1305..4a8a1f4 100644 --- a/src/components/ui/slider.tsx +++ b/packages/common/src/components/ui/slider.tsx @@ -2,7 +2,7 @@ import { Slider as SliderPrimitive } from "@base-ui/react/slider"; import { cva, type VariantProps } from "class-variance-authority"; import type { ReactNode } from "react"; import React from "react"; -import { cn } from "@/lib/utils"; +import { cn } from "../../lib/utils"; const sliderControlVariants = cva( "relative flex touch-none select-none items-center", diff --git a/src/components/ui/spinner.tsx b/packages/common/src/components/ui/spinner.tsx similarity index 94% rename from src/components/ui/spinner.tsx rename to packages/common/src/components/ui/spinner.tsx index 8149f6a..c4e04c4 100644 --- a/src/components/ui/spinner.tsx +++ b/packages/common/src/components/ui/spinner.tsx @@ -1,4 +1,4 @@ -import { cn } from "@/lib/utils"; +import { cn } from "../../lib/utils"; function Spinner({ className }: { className?: string }) { return ( diff --git a/src/components/ui/tabs.tsx b/packages/common/src/components/ui/tabs.tsx similarity index 95% rename from src/components/ui/tabs.tsx rename to packages/common/src/components/ui/tabs.tsx index 72f9209..86ef6f8 100644 --- a/src/components/ui/tabs.tsx +++ b/packages/common/src/components/ui/tabs.tsx @@ -1,7 +1,6 @@ import { Tabs as TabsPrimitive } from "@base-ui/react/tabs"; import { cva, type VariantProps } from "class-variance-authority"; - -import { cn } from "@/lib/utils"; +import { cn } from "../../lib/utils"; function Tabs({ className, @@ -30,7 +29,7 @@ const tabsListVariants = cva( line: "gap-2.5 bg-transparent", pill: "gap-1 bg-transparent p-0 h-auto", contained: - "bg-[#121314] h-12 p-[5px] rounded-[10px] gap-[5px] w-full overflow-hidden", + "bg-surface-2 h-12 p-[5px] rounded-[10px] gap-[5px] w-full overflow-hidden", }, }, defaultVariants: { @@ -62,7 +61,7 @@ function TabsTrigger({ className, ...props }: TabsPrimitive.Tab.Props) { // Base styles "relative inline-flex h-9 flex-1 items-center justify-center whitespace-nowrap rounded-xl px-4 py-2 text-sm font-semibold transition-all", // Default inactive state - dark background - "bg-[#121314] text-muted-foreground", + "bg-surface-2 text-muted-foreground", // Active state - white background, black text "data-active:bg-white data-active:text-black data-active:border data-active:border-white", // Pill variant styling via parent diff --git a/packages/common/src/components/ui/text.tsx b/packages/common/src/components/ui/text.tsx new file mode 100644 index 0000000..80ab79a --- /dev/null +++ b/packages/common/src/components/ui/text.tsx @@ -0,0 +1,100 @@ +import { cva, type VariantProps } from "class-variance-authority"; +import type { HTMLAttributes } from "react"; +import { cn } from "../../lib/utils"; + +export const textVariants = cva("", { + variants: { + variant: { + inherit: "", + titleXl: "font-semibold text-xl text-foreground", + titleXlTight: "font-semibold text-xl text-foreground tracking-[-0.6px]", + titleLg: + "text-foreground text-lg font-semibold leading-tight tracking-[-0.72px]", + titleMd: + "text-foreground text-md font-semibold leading-tight tracking-[-0.54px]", + bodyMd: "text-md", + headingBase: "text-foreground font-semibold text-base", + headingBaseTight: + "text-foreground font-semibold text-base tracking-tight", + labelBaseWhite: "text-white font-semibold text-base tracking-tight", + labelBase: "font-semibold text-base tracking-tight", + labelSm: "font-semibold text-sm tracking-tight", + labelSmSemibold: "text-sm font-semibold", + labelBaseSemibold: "text-base font-semibold", + labelXs: "font-semibold text-xs tracking-tight", + labelSmWhiteNeg: + "font-semibold text-sm text-white tracking-[-0.42px] leading-tight", + labelSmWhiteNegNoLeading: + "font-semibold text-sm text-white tracking-[-0.42px]", + labelSmForegroundNeg: + "font-semibold text-sm text-foreground tracking-[-0.42px] leading-tight", + bodySmWhiteNeg: + "text-sm text-white font-normal tracking-[-0.42px] leading-tight", + bodySmWhiteNegNoLeading: + "text-white text-sm font-normal tracking-[-0.42px]", + bodySmWhite: "text-white text-sm font-normal", + labelSmGray2Tight: "text-gray-2 font-semibold text-sm tracking-tight", + labelSmGray2Neg: "text-gray-2 text-sm font-semibold tracking-[-0.42px]", + labelSmGray2NegTight: + "text-gray-2 font-semibold text-sm leading-tight tracking-[-0.42px]", + bodySmGray2: "text-sm text-gray-2", + bodySmMedium: "text-sm font-medium", + bodySmGray2Tight: "text-gray-2 text-sm font-normal tracking-tight", + bodySmTight: "text-sm font-normal tracking-tight", + bodySmGray2Neg: "text-gray-2 text-sm font-normal tracking-[-0.42px]", + bodySmGray2NegTight: + "text-gray-2 font-normal text-sm tracking-[-0.42px] leading-tight", + bodySmNeg: "text-sm font-normal tracking-[-0.42px]", + bodyXsGray2: "text-xs text-gray-2", + labelXsGray2: "text-gray-2 font-semibold text-xs tracking-tight", + labelXsWhiteNeg: "text-white text-xs font-semibold tracking-[-0.24px]", + helperSmGray1: "text-gray-1 text-sm", + helperSmGray1Tight: "text-gray-1 text-sm tracking-tight", + bodyXsGray2Medium: "font-medium text-gray-2 text-xs", + bodySmForegroundMedium: "font-medium text-foreground text-sm", + bodyBaseForegroundMedium: "font-medium text-foreground", + bodyBaseForegroundMediumTight: + "font-medium text-foreground tracking-tight", + caption11Gray2Medium: "font-medium text-[11px] text-gray-2", + amountDisplay30: + "text-white font-semibold text-[30px] tracking-tight leading-tight", + amountDisplay44: + "text-white text-[44px] font-semibold tracking-[-1.76px] leading-none", + optionTitle: + "text-white font-bold text-base tracking-[-0.48px] leading-tight", + badgePrimary: + "px-2.5 py-1 text-xs font-semibold rounded-full bg-primary/10 text-primary", + badgeDestructive: + "px-2.5 py-1 text-xs font-semibold rounded-full bg-destructive/10 text-destructive", + badgeNeutral: + "px-2.5 py-1 text-xs font-semibold rounded-full bg-gray-3 text-gray-2", + badgeWhiteSmall: + "bg-white/25 px-1.5 py-1 rounded-[5px] text-[11px] text-white leading-none", + badgeWhiteTight: + "bg-white/25 px-1.5 py-1 rounded text-[11px] text-white text-center leading-tight", + badgeSideTight: + "px-1.5 py-1 rounded text-[11px] text-white text-center leading-tight", + }, + }, + defaultVariants: { + variant: "bodySmGray2", + }, +}); + +type TextAs = "span" | "p" | "div" | "label" | "h1" | "h2" | "h3"; + +export type TextProps = HTMLAttributes & + VariantProps & { + as?: TextAs; + }; + +export function Text({ as = "span", variant, className, ...props }: TextProps) { + const Comp = as; + return ( + + ); +} diff --git a/src/components/ui/toaster.tsx b/packages/common/src/components/ui/toaster.tsx similarity index 100% rename from src/components/ui/toaster.tsx rename to packages/common/src/components/ui/toaster.tsx diff --git a/src/context/appkit.tsx b/packages/common/src/context/appkit.tsx similarity index 87% rename from src/context/appkit.tsx rename to packages/common/src/context/appkit.tsx index 488247d..5dfd993 100644 --- a/src/context/appkit.tsx +++ b/packages/common/src/context/appkit.tsx @@ -1,8 +1,8 @@ import { Result, useAtomValue } from "@effect-atom/atom-react"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { WagmiProvider } from "wagmi"; -import { configAtom } from "@/atoms/config-atom"; -import { walletAtom } from "@/atoms/wallet-atom"; +import { configAtom } from "../atoms/config-atom"; +import { walletAtom } from "../atoms/wallet-atom"; const qc = new QueryClient(); diff --git a/src/context/index.tsx b/packages/common/src/context/index.tsx similarity index 62% rename from src/context/index.tsx rename to packages/common/src/context/index.tsx index b6ef508..8105a5f 100644 --- a/src/context/index.tsx +++ b/packages/common/src/context/index.tsx @@ -1,7 +1,7 @@ import { StrictMode } from "react"; -import { Toaster } from "@/components/ui/toaster"; -import { AppKit } from "@/context/appkit"; -import { RootContainerProvider } from "@/context/root-container"; +import { Toaster } from "../components/ui/toaster"; +import { AppKit } from "./appkit"; +import { RootContainerProvider } from "./root-container"; export const Providers = ({ children }: { children: React.ReactNode }) => { return ( @@ -15,3 +15,5 @@ export const Providers = ({ children }: { children: React.ReactNode }) => { ); }; + +export * from "./root-container"; diff --git a/src/context/root-container.tsx b/packages/common/src/context/root-container.tsx similarity index 100% rename from src/context/root-container.tsx rename to packages/common/src/context/root-container.tsx diff --git a/src/domain/chains/evm.ts b/packages/common/src/domain/chains/evm.ts similarity index 100% rename from src/domain/chains/evm.ts rename to packages/common/src/domain/chains/evm.ts diff --git a/packages/common/src/domain/chains/index.ts b/packages/common/src/domain/chains/index.ts new file mode 100644 index 0000000..22d91bc --- /dev/null +++ b/packages/common/src/domain/chains/index.ts @@ -0,0 +1,6 @@ +import type { SupportedEvmChain } from "./evm"; + +export type SupportedSKChains = SupportedEvmChain; + +export * from "./evm"; +export * from "./ledger"; diff --git a/src/domain/chains/ledger.ts b/packages/common/src/domain/chains/ledger.ts similarity index 95% rename from src/domain/chains/ledger.ts rename to packages/common/src/domain/chains/ledger.ts index cfb98e9..a2f53d6 100644 --- a/src/domain/chains/ledger.ts +++ b/packages/common/src/domain/chains/ledger.ts @@ -1,6 +1,6 @@ import type { Currency, Families } from "@ledgerhq/wallet-api-client"; import { EvmNetworks } from "@stakekit/common"; -import type { SupportedSKChains } from "@/domain/chains"; +import type { SupportedSKChains } from "./index"; export type SupportedLedgerLiveFamilies = Extract; diff --git a/packages/common/src/domain/index.ts b/packages/common/src/domain/index.ts new file mode 100644 index 0000000..a8bc10d --- /dev/null +++ b/packages/common/src/domain/index.ts @@ -0,0 +1,6 @@ +export * from "./chains"; +export * from "./signer"; +export * from "./tokens"; +export * from "./transactions"; +export * from "./types"; +export * from "./wallet"; diff --git a/src/domain/signer.ts b/packages/common/src/domain/signer.ts similarity index 96% rename from src/domain/signer.ts rename to packages/common/src/domain/signer.ts index 3a01379..8d204a7 100644 --- a/src/domain/signer.ts +++ b/packages/common/src/domain/signer.ts @@ -1,6 +1,6 @@ import type { WagmiAdapter } from "@reown/appkit-adapter-wagmi"; import { Data, type Effect, Schema, type Stream } from "effect"; -import type { Transaction, TransactionHash } from "@/domain/transactions"; +import type { Transaction, TransactionHash } from "./transactions"; const BrowserWalletAccount = Schema.Struct({ address: Schema.String.pipe(Schema.brand("WalletAccountAddress")), diff --git a/src/domain/tokens.ts b/packages/common/src/domain/tokens.ts similarity index 92% rename from src/domain/tokens.ts rename to packages/common/src/domain/tokens.ts index 0f75b60..a0a8b96 100644 --- a/src/domain/tokens.ts +++ b/packages/common/src/domain/tokens.ts @@ -1,5 +1,5 @@ import { Equal, Schema } from "effect"; -import { Networks } from "@/services/api-client/api-schemas"; +import { Networks } from "../services/api-client/api-schemas"; const Token = Schema.Struct({ network: Networks, diff --git a/src/domain/transactions.ts b/packages/common/src/domain/transactions.ts similarity index 95% rename from src/domain/transactions.ts rename to packages/common/src/domain/transactions.ts index b72475d..82dcd60 100644 --- a/src/domain/transactions.ts +++ b/packages/common/src/domain/transactions.ts @@ -9,6 +9,7 @@ export const EvmTx = Schema.Struct({ value: Schema.optional(Schema.BigInt), gasLimit: Schema.BigInt, chainId: Schema.Number, + nonce: Schema.optional(Schema.Number), }); export const EIP712Tx = Schema.Struct({ diff --git a/src/domain/types.ts b/packages/common/src/domain/types.ts similarity index 79% rename from src/domain/types.ts rename to packages/common/src/domain/types.ts index 8bc149d..226d817 100644 --- a/src/domain/types.ts +++ b/packages/common/src/domain/types.ts @@ -1,4 +1,4 @@ -import type { TokenDto } from "@/services/api-client/api-schemas"; +import type { TokenDto } from "../services/api-client/api-schemas"; export type TokenString = `${TokenDto["network"]}-${TokenDto["address"]}`; diff --git a/src/domain/wallet.ts b/packages/common/src/domain/wallet.ts similarity index 94% rename from src/domain/wallet.ts rename to packages/common/src/domain/wallet.ts index 0c2425b..5064c34 100644 --- a/src/domain/wallet.ts +++ b/packages/common/src/domain/wallet.ts @@ -2,6 +2,11 @@ import type { HttpClientError } from "@effect/platform"; import type { WagmiAdapter } from "@reown/appkit-adapter-wagmi"; import { Data, type Effect, type Stream } from "effect"; import type { ParseError } from "effect/ParseResult"; +import type { + ActionDto, + TransactionDto, +} from "../services/api-client/api-schemas"; +import type { SKClientError } from "../services/api-client/client-factory"; import type { BrowserSigner, BrowserWalletAccount, @@ -10,12 +15,7 @@ import type { SignTransactionError, SwitchAccountError, WalletAccount, -} from "@/domain/signer"; -import type { - ActionDto, - TransactionDto, -} from "@/services/api-client/api-schemas"; -import type { SKClientError } from "@/services/api-client/client-factory"; +} from "./signer"; export class TransactionNotConfirmedError extends Data.TaggedError( "TransactionNotConfirmedError", @@ -118,4 +118,4 @@ export const isLedgerWalletConnected = ( ): wallet is LedgerWalletConnected => isWalletConnected(wallet) && wallet.type === "ledger"; -export type { WalletAccount } from "@/domain/signer"; +export type { WalletAccount } from "./signer"; diff --git a/packages/common/src/hooks/index.ts b/packages/common/src/hooks/index.ts new file mode 100644 index 0000000..b6c08b6 --- /dev/null +++ b/packages/common/src/hooks/index.ts @@ -0,0 +1,8 @@ +export * from "./use-close-position"; +export * from "./use-deposit-form"; +export * from "./use-edit-position"; +export * from "./use-order-actions"; +export * from "./use-order-form"; +export * from "./use-position-actions"; +export * from "./use-tp-sl-orders"; +export * from "./use-withdraw-form"; diff --git a/packages/common/src/hooks/use-close-position.ts b/packages/common/src/hooks/use-close-position.ts new file mode 100644 index 0000000..d3c24ce --- /dev/null +++ b/packages/common/src/hooks/use-close-position.ts @@ -0,0 +1,33 @@ +import { useAtomSet, useAtomValue } from "@effect-atom/atom-react"; +import { + closePercentageAtom, + submitCloseAtom, +} from "../atoms/close-position-atoms"; +import { getCloseCalculations } from "../lib/math"; +import type { PositionDto } from "../services/api-client/api-schemas"; + +export const useClosePercentage = () => { + const closePercentage = useAtomValue(closePercentageAtom); + const setClosePercentage = useAtomSet(closePercentageAtom); + + return { + closePercentage, + setClosePercentage, + }; +}; + +export const useCloseCalculations = (position: PositionDto) => { + const { closePercentage } = useClosePercentage(); + + return getCloseCalculations(position, closePercentage); +}; + +export const useSubmitClose = () => { + const submitResult = useAtomValue(submitCloseAtom); + const submitClose = useAtomSet(submitCloseAtom); + + return { + submitResult, + submitClose, + }; +}; diff --git a/src/components/modules/Account/Deposit/state.tsx b/packages/common/src/hooks/use-deposit-form.ts similarity index 59% rename from src/components/modules/Account/Deposit/state.tsx rename to packages/common/src/hooks/use-deposit-form.ts index 35bc4c6..f225435 100644 --- a/src/components/modules/Account/Deposit/state.tsx +++ b/packages/common/src/hooks/use-deposit-form.ts @@ -8,34 +8,39 @@ import { import { FormBuilder, FormReact } from "@lucas-barake/effect-form-react"; import { Array as _Array, - Number as _Number, Effect, Option, Predicate, Record, Schema, } from "effect"; -import { actionAtom } from "@/atoms/actions-atoms"; -import { providersAtom } from "@/atoms/providers-atoms"; import { + actionAtom, moralisTokenBalancesAtom, + selectedProviderAtom, type TokenBalances, -} from "@/atoms/tokens-atoms"; -import { walletAtom } from "@/atoms/wallet-atom"; -import { AmountField } from "@/components/molecules/forms"; -import { isArbUsdcToken, isEthNativeToken, makeToken } from "@/domain/tokens"; -import type { TokenBalance } from "@/domain/types"; + walletAtom, +} from "../atoms"; +import { AmountField } from "../components"; import { + isArbUsdcToken, + isEthNativeToken, isWalletConnected, + makeToken, + type TokenBalance, type WalletAccount, - type WalletConnected, -} from "@/domain/wallet"; -import { formatTokenAmount, truncateNumber } from "@/lib/utils"; -import { ApiClientService } from "@/services/api-client"; -import type { ProviderDto } from "@/services/api-client/api-schemas"; -import { runtimeAtom } from "@/services/runtime"; - -const selectedTokenBalanceAtom = Atom.family( +} from "../domain"; +import { + calcBaseAmountFromUsd, + clampPercent, + formatTokenAmount, + percentOf, + round, + valueFromPercent, +} from "../lib"; +import { ApiClientService, runtimeAtom } from "../services"; + +export const selectedTokenBalanceAtom = Atom.family( (walletAddress: WalletAccount["address"]) => Atom.writable( (ctx) => @@ -47,78 +52,6 @@ const selectedTokenBalanceAtom = Atom.family( ), ); -const selectedProviderAtom = Atom.writable( - (ctx) => - ctx - .get(providersAtom) - .pipe(Result.map(_Array.head), Result.map(Option.getOrNull)), - (ctx, value: ProviderDto) => ctx.setSelf(Result.success(value)), -); - -export const useProviders = () => { - const providers = useAtomValue(providersAtom).pipe( - Result.getOrElse(() => null), - ); - - return { - providers, - }; -}; - -export const useTokenBalances = (walletAddress: WalletAccount["address"]) => { - const tokenBalances = useAtomValue( - moralisTokenBalancesAtom(walletAddress), - ).pipe(Result.getOrElse(() => Record.empty() as TokenBalances)); - - return { - tokenBalances, - }; -}; - -export const useDepositForm = () => { - const submit = useAtomSet(DepositForm.submit); - const submitResult = useAtomValue(DepositForm.submit); - - return { - submit, - submitResult, - }; -}; - -export const useSelectedTokenBalance = ( - walletAddress: WalletAccount["address"], -) => { - const selectedTokenBalance = useAtomValue( - selectedTokenBalanceAtom(walletAddress), - ).pipe(Result.getOrElse(() => null)); - const setSelectedTokenBalance = useAtomSet( - selectedTokenBalanceAtom(walletAddress), - ); - const setAmount = useAtomSet(setAmountFieldAtom); - - const handleSelectTokenBalance = (tokenBalance: TokenBalance) => { - setSelectedTokenBalance(tokenBalance); - setAmount("0"); - }; - - return { - selectedTokenBalance, - handleSelectTokenBalance, - }; -}; - -export const useSelectedProvider = () => { - const selectedProvider = useAtomValue(selectedProviderAtom).pipe( - Result.getOrElse(() => null), - ); - const setSelectedProvider = useAtomSet(selectedProviderAtom); - - return { - selectedProvider, - setSelectedProvider, - }; -}; - export const depositFormBuilder = FormBuilder.empty .addField( "Amount", @@ -147,7 +80,10 @@ export const depositFormBuilder = FormBuilder.empty return { path: ["Amount"], message: "Missing token balance" }; } - const cryptoAmount = values.Amount / tokenBalance.price; + const cryptoAmount = calcBaseAmountFromUsd({ + usdAmount: values.Amount, + priceUsd: tokenBalance.price, + }); const usdMin = isArbUsdcToken(makeToken(tokenBalance.token)) ? 5 : 10; @@ -161,54 +97,128 @@ export const depositFormBuilder = FormBuilder.empty }), ); -export const DepositForm = FormReact.make(depositFormBuilder, { - runtime: runtimeAtom, - fields: { Amount: AmountField }, - onSubmit: ({ wallet }: { wallet: WalletConnected }, { decoded }) => - Effect.gen(function* () { - const client = yield* ApiClientService; - const registry = yield* Registry.AtomRegistry; +export type DepositFormBuilder = typeof depositFormBuilder; - const selectedTokenBalance = registry - .get(selectedTokenBalanceAtom(wallet.currentAccount.address)) - .pipe(Result.getOrElse(() => null)); +const depositOnSubmit = Effect.gen(function* () { + const client = yield* ApiClientService; + const registry = yield* Registry.AtomRegistry; - if (!selectedTokenBalance) { - return yield* Effect.dieMessage("No selected token balance"); - } + const wallet = registry.get(walletAtom).pipe(Result.getOrElse(() => null)); - const selectedProvider = registry - .get(selectedProviderAtom) - .pipe(Result.getOrElse(() => null)); + if (!isWalletConnected(wallet)) { + return yield* Effect.dieMessage("No wallet"); + } - if (!selectedProvider) { - return yield* Effect.dieMessage("No selected provider"); - } + const selectedTokenBalance = registry + .get(selectedTokenBalanceAtom(wallet.currentAccount.address)) + .pipe(Result.getOrElse(() => null)); - const cryptoAmount = decoded.Amount / selectedTokenBalance.price; - - const action = yield* client.ActionsControllerExecuteAction({ - providerId: selectedProvider.id, - address: wallet.currentAccount.address, - action: "fund", - args: { - amount: cryptoAmount.toString(), - fromToken: { - network: selectedTokenBalance.token.network, - ...(!isEthNativeToken(makeToken(selectedTokenBalance.token)) && { - address: selectedTokenBalance.token.address, - }), - }, - }, - }); + if (!selectedTokenBalance) { + return yield* Effect.dieMessage("No selected token balance"); + } - registry.set(actionAtom, action); - }), + const selectedProvider = registry + .get(selectedProviderAtom) + .pipe(Result.getOrElse(() => null)); + + if (!selectedProvider) { + return yield* Effect.dieMessage("No selected provider"); + } + + return { client, wallet, selectedTokenBalance, selectedProvider }; }); -const amountAtom = DepositForm.getFieldAtom(DepositForm.fields.Amount); +export const createDepositForm = ( + amountFieldComponent: FormReact.FieldComponent, +) => + FormReact.make(depositFormBuilder, { + runtime: runtimeAtom, + fields: { Amount: amountFieldComponent }, + onSubmit: (_, { decoded }) => + Effect.gen(function* () { + const { client, wallet, selectedTokenBalance, selectedProvider } = + yield* depositOnSubmit; + + const cryptoAmount = calcBaseAmountFromUsd({ + usdAmount: decoded.Amount, + priceUsd: selectedTokenBalance.price, + }); + + const action = yield* client.ActionsControllerExecuteAction({ + providerId: selectedProvider.id, + address: wallet.currentAccount.address, + action: "fund", + args: { + amount: cryptoAmount.toString(), + fromToken: { + network: selectedTokenBalance.token.network, + ...(!isEthNativeToken(makeToken(selectedTokenBalance.token)) && { + address: selectedTokenBalance.token.address, + }), + }, + }, + }); + + const registry = yield* Registry.AtomRegistry; + registry.set(actionAtom, action); + }), + }); + +export const DepositForm = createDepositForm(AmountField); + +const amountAtom = DepositForm.getFieldValue(DepositForm.fields.Amount); const setAmountFieldAtom = DepositForm.setValue(DepositForm.fields.Amount); +export const useDepositForm = () => { + const submit = useAtomSet(DepositForm.submit); + const submitResult = useAtomValue(DepositForm.submit); + + return { + submit, + submitResult, + }; +}; + +export const useSetDepositAmount = () => { + const setAmount = useAtomSet(setAmountFieldAtom); + + return { + setAmount, + }; +}; + +export const useTokenBalances = (walletAddress: WalletAccount["address"]) => { + const tokenBalances = useAtomValue( + moralisTokenBalancesAtom(walletAddress), + ).pipe(Result.getOrElse(() => Record.empty() as TokenBalances)); + + return { + tokenBalances, + }; +}; + +export const useSelectedTokenBalance = ( + walletAddress: WalletAccount["address"], +) => { + const selectedTokenBalance = useAtomValue( + selectedTokenBalanceAtom(walletAddress), + ).pipe(Result.getOrElse(() => null)); + const setSelectedTokenBalance = useAtomSet( + selectedTokenBalanceAtom(walletAddress), + ); + const setAmount = useAtomSet(setAmountFieldAtom); + + const handleSelectTokenBalance = (tokenBalance: TokenBalance) => { + setSelectedTokenBalance(tokenBalance); + setAmount("0"); + }; + + return { + selectedTokenBalance, + handleSelectTokenBalance, + }; +}; + export const useDepositPercentage = ( walletAddress: WalletAccount["address"], ) => { @@ -229,8 +239,8 @@ export const useDepositPercentage = ( Option.getOrElse(() => 0), ); - const percentage = _Number.clamp({ minimum: 0, maximum: 100 })( - (amount / availableBalanceUsd) * 100, + const percentage = clampPercent( + percentOf({ part: amount, whole: availableBalanceUsd }), ); const handlePercentageChange = (newPercentage: number) => { @@ -238,8 +248,11 @@ export const useDepositPercentage = ( return setAmount(availableBalanceUsd.toString()); } - const amount = (availableBalanceUsd * newPercentage) / 100; - setAmount(truncateNumber(amount).toString()); + const newAmount = valueFromPercent({ + total: availableBalanceUsd, + percent: newPercentage, + }); + setAmount(round(newAmount).toString()); }; return { @@ -269,7 +282,10 @@ const tokenAmountValueAtom = Atom.family( } return formatTokenAmount({ - amount: amount / tokenBalance.price, + amount: calcBaseAmountFromUsd({ + usdAmount: amount, + priceUsd: tokenBalance.price, + }), symbol: tokenBalance.token.symbol, }); }), diff --git a/packages/common/src/hooks/use-edit-position.ts b/packages/common/src/hooks/use-edit-position.ts new file mode 100644 index 0000000..aefbd3b --- /dev/null +++ b/packages/common/src/hooks/use-edit-position.ts @@ -0,0 +1,28 @@ +import { useAtomSet, useAtomValue } from "@effect-atom/atom-react"; +import { editSLTPAtom } from "../atoms/edit-position-atoms"; +import { updateLeverageAtom } from "../atoms/position-pending-actions-atom"; + +export const useEditSLTP = () => { + const editTPResult = useAtomValue(editSLTPAtom("takeProfit")); + const editTP = useAtomSet(editSLTPAtom("takeProfit")); + + const editSLResult = useAtomValue(editSLTPAtom("stopLoss")); + const editSL = useAtomSet(editSLTPAtom("stopLoss")); + + return { + editTPResult, + editTP, + editSLResult, + editSL, + }; +}; + +export const useUpdateLeverage = () => { + const updateLeverageResult = useAtomValue(updateLeverageAtom); + const updateLeverage = useAtomSet(updateLeverageAtom); + + return { + updateLeverageResult, + updateLeverage, + }; +}; diff --git a/src/hooks/use-order-actions.ts b/packages/common/src/hooks/use-order-actions.ts similarity index 91% rename from src/hooks/use-order-actions.ts rename to packages/common/src/hooks/use-order-actions.ts index ebddc18..ce66819 100644 --- a/src/hooks/use-order-actions.ts +++ b/packages/common/src/hooks/use-order-actions.ts @@ -1,5 +1,5 @@ import { Option, Schema } from "effect"; -import type { OrderDto } from "@/services/api-client/api-schemas"; +import type { OrderDto } from "../services/api-client/api-schemas"; const CancelOrderPendingActionSchema = Schema.Struct({ type: Schema.Literal("cancelOrder"), diff --git a/packages/common/src/hooks/use-order-form.ts b/packages/common/src/hooks/use-order-form.ts new file mode 100644 index 0000000..85fedb4 --- /dev/null +++ b/packages/common/src/hooks/use-order-form.ts @@ -0,0 +1,213 @@ +import { Result, useAtomSet, useAtomValue } from "@effect-atom/atom-react"; +import { Option, Schema } from "effect"; +import { + calculateOrderPercentage, + calculateOrderPositionSize, + getOrderCalculations, + LeverageRangesSchema, + leverageAtom, + limitPriceAtom, + orderFormAtom, + orderSideAtom, + orderTypeAtom, + tpOrSLSettingsAtom, +} from "../atoms/order-form-atoms"; +import { + positionsAtom, + selectedProviderBalancesAtom, +} from "../atoms/portfolio-atoms"; +import type { WalletConnected } from "../domain"; +import type { ApiSchemas, ApiTypes } from "../services"; + +export const useOrderType = () => { + const orderType = useAtomValue(orderTypeAtom); + const setOrderType = useAtomSet(orderTypeAtom); + + return { + orderType, + setOrderType, + }; +}; + +export const useOrderSide = () => { + const orderSide = useAtomValue(orderSideAtom); + const setOrderSide = useAtomSet(orderSideAtom); + + return { + orderSide, + setOrderSide, + }; +}; + +export const useLeverage = ( + leverageRanges: typeof LeverageRangesSchema.Type, +) => { + const leverage = useAtomValue(leverageAtom(leverageRanges)); + const setLeverage = useAtomSet(leverageAtom(leverageRanges)); + + return { + leverage, + setLeverage, + }; +}; + +export const useTPOrSLSettings = () => { + const tpOrSLSettings = useAtomValue(tpOrSLSettingsAtom); + const setTPOrSLSettings = useAtomSet(tpOrSLSettingsAtom); + + return { + tpOrSLSettings, + setTPOrSLSettings, + }; +}; + +export const useLimitPrice = () => { + const limitPrice = useAtomValue(limitPriceAtom); + const setLimitPrice = useAtomSet(limitPriceAtom); + + return { + limitPrice, + setLimitPrice, + }; +}; + +export const useOrderProviderBalance = (wallet: WalletConnected) => { + const providerBalance = useAtomValue( + selectedProviderBalancesAtom(wallet.currentAccount.address), + ).pipe(Result.getOrElse(() => null)); + + return { + providerBalance, + }; +}; + +export const useCurrentPosition = ( + wallet: WalletConnected, + marketId: string, +) => { + const positions = useAtomValue( + positionsAtom(wallet.currentAccount.address), + ).pipe(Result.getOrElse(() => [])); + + const currentPosition = positions.find( + (position) => position.marketId === marketId, + ); + + return { + currentPosition: currentPosition ?? null, + }; +}; + +// Hooks that depend on orderFormAtom +export const useOrderFormSubmit = ( + leverageRanges: typeof LeverageRangesSchema.Type, +) => { + const { form } = useAtomValue(orderFormAtom(leverageRanges)); + const submit = useAtomSet(form.submit); + const submitResult = useAtomValue(form.submit); + + return { + submit, + submitResult, + }; +}; + +export const useOrderAmount = ( + leverageRanges: typeof LeverageRangesSchema.Type, +) => { + const { amountFieldAtom } = useAtomValue(orderFormAtom(leverageRanges)); + const amount = useAtomValue(amountFieldAtom).pipe( + Option.map(Number), + Option.filter((v) => !Number.isNaN(v)), + Option.getOrElse(() => 0), + ); + + return { amount }; +}; + +export const useHandlePercentageChange = ( + wallet: WalletConnected, + leverageRanges: typeof LeverageRangesSchema.Type, +) => { + const { setAmountFieldAtom } = useAtomValue(orderFormAtom(leverageRanges)); + const setAmount = useAtomSet(setAmountFieldAtom); + const { providerBalance } = useOrderProviderBalance(wallet); + const { leverage } = useLeverage(leverageRanges); + + return { + handlePercentageChange: (value: number) => { + if (!providerBalance) return; + + const positionSize = calculateOrderPositionSize( + providerBalance, + leverage, + value, + ); + + setAmount(positionSize.toString()); + }, + }; +}; + +export const useOrderPercentage = ( + wallet: WalletConnected, + leverageRanges: typeof LeverageRangesSchema.Type, +) => { + const { amount } = useOrderAmount(leverageRanges); + const { leverage } = useLeverage(leverageRanges); + + const providerBalance = useAtomValue( + selectedProviderBalancesAtom(wallet.currentAccount.address), + ).pipe(Result.getOrElse(() => null)); + + if (!providerBalance) { + return { + percentage: 0, + }; + } + + const percentage = calculateOrderPercentage( + amount, + leverage, + providerBalance.availableBalance, + ); + + return { + percentage, + }; +}; + +export const useOrderCalculations = ( + market: ApiSchemas.MarketDto, + side: ApiTypes.PositionDtoSide, + leverageRanges: typeof LeverageRangesSchema.Type, +) => { + const { amount } = useOrderAmount(leverageRanges); + const { leverage } = useLeverage(leverageRanges); + + return getOrderCalculations(amount, leverage, market, side); +}; + +// Re-export from order-form-atoms for convenience +export { + LeverageRangesSchema, + ORDER_SLIDER_STOPS, + type OrderSide, + type OrderType, + orderFormAtom, +} from "../atoms/order-form-atoms"; + +// Helper to decode leverage ranges from market +export const decodeLeverageRanges = ( + leverageRange: ApiSchemas.MarketDto["leverageRange"], +) => Schema.decodeSync(LeverageRangesSchema)(leverageRange); + +export const useProviderBalance = (wallet: WalletConnected) => { + const providerBalance = useAtomValue( + selectedProviderBalancesAtom(wallet.currentAccount.address), + ).pipe(Result.getOrElse(() => null)); + + return { + providerBalance, + }; +}; diff --git a/src/hooks/use-position-actions.ts b/packages/common/src/hooks/use-position-actions.ts similarity index 93% rename from src/hooks/use-position-actions.ts rename to packages/common/src/hooks/use-position-actions.ts index e84c9ed..7180101 100644 --- a/src/hooks/use-position-actions.ts +++ b/packages/common/src/hooks/use-position-actions.ts @@ -1,11 +1,10 @@ import { Match, Option, Schema } from "effect"; -import type { PositionDto } from "@/services/api-client/api-schemas"; +import type { PositionDto } from "../services/api-client/api-schemas"; const UpdateLeverageSchema = Schema.Struct({ type: Schema.Literal("updateLeverage"), args: Schema.Struct({ marketId: Schema.String, - leverage: Schema.Number, }), }); diff --git a/src/hooks/use-tp-sl-orders.ts b/packages/common/src/hooks/use-tp-sl-orders.ts similarity index 93% rename from src/hooks/use-tp-sl-orders.ts rename to packages/common/src/hooks/use-tp-sl-orders.ts index 158a4de..aabd670 100644 --- a/src/hooks/use-tp-sl-orders.ts +++ b/packages/common/src/hooks/use-tp-sl-orders.ts @@ -1,5 +1,5 @@ import { Match, Option, Schema } from "effect"; -import type { OrderDto } from "@/services/api-client/api-schemas"; +import type { OrderDto } from "../services/api-client/api-schemas"; const TpSlOrderSchema = Schema.Struct({ type: Schema.Literal("take_profit", "stop_loss"), diff --git a/packages/common/src/hooks/use-withdraw-form.ts b/packages/common/src/hooks/use-withdraw-form.ts new file mode 100644 index 0000000..522d9ea --- /dev/null +++ b/packages/common/src/hooks/use-withdraw-form.ts @@ -0,0 +1,180 @@ +import { + Registry, + Result, + useAtomSet, + useAtomValue, +} from "@effect-atom/atom-react"; +import { FormBuilder, FormReact } from "@lucas-barake/effect-form-react"; +import { Effect, Option, Schema } from "effect"; +import { + actionAtom, + selectedProviderAtom, + selectedProviderBalancesAtom, + walletAtom, +} from "../atoms"; +import { AmountField } from "../components"; +import { isWalletConnected, type WalletAccount } from "../domain"; +import { clampPercent, percentOf, round, valueFromPercent } from "../lib"; +import { ApiClientService, runtimeAtom } from "../services"; + +export const withdrawFormBuilder = FormBuilder.empty + .addField( + "Amount", + Schema.NumberFromString.pipe( + Schema.annotations({ message: () => "Invalid amount" }), + Schema.greaterThan(0, { message: () => "Must be greater than 0" }), + ), + ) + .refineEffect((values) => + Effect.gen(function* () { + const registry = yield* Registry.AtomRegistry; + const wallet = registry + .get(walletAtom) + .pipe(Result.getOrElse(() => null)); + + if (!isWalletConnected(wallet)) { + return yield* Effect.dieMessage("No wallet"); + } + + const providerBalance = registry + .get(selectedProviderBalancesAtom(wallet.currentAccount.address)) + .pipe(Result.getOrElse(() => null)); + + if (!providerBalance) { + return { path: ["Amount"], message: "Missing provider balance" }; + } + + if (providerBalance.availableBalance <= 0) { + return { + path: ["Amount"], + message: "No available balance to withdraw", + }; + } + + if (values.Amount > providerBalance.availableBalance) { + return { + path: ["Amount"], + message: "Insufficient balance", + }; + } + }), + ); + +export type WithdrawFormBuilder = typeof withdrawFormBuilder; + +const withdrawOnSubmit = Effect.gen(function* () { + const client = yield* ApiClientService; + const registry = yield* Registry.AtomRegistry; + + const wallet = registry.get(walletAtom).pipe(Result.getOrElse(() => null)); + + if (!isWalletConnected(wallet)) { + return yield* Effect.dieMessage("No wallet"); + } + + const selectedProvider = registry + .get(selectedProviderAtom) + .pipe(Result.getOrElse(() => null)); + + if (!selectedProvider) { + return yield* Effect.dieMessage("No selected provider"); + } + + const providerBalance = registry + .get(selectedProviderBalancesAtom(wallet.currentAccount.address)) + .pipe(Result.getOrElse(() => null)); + + if (!providerBalance) { + return yield* Effect.dieMessage("No provider balance"); + } + + return { client, wallet, selectedProvider, providerBalance }; +}); + +export const createWithdrawForm = ( + amountFieldComponent: FormReact.FieldComponent, +) => + FormReact.make(withdrawFormBuilder, { + runtime: runtimeAtom, + fields: { Amount: amountFieldComponent }, + onSubmit: (_, { decoded }) => + Effect.gen(function* () { + const { client, wallet, selectedProvider } = yield* withdrawOnSubmit; + + const action = yield* client.ActionsControllerExecuteAction({ + providerId: selectedProvider.id, + address: wallet.currentAccount.address, + action: "withdraw", + args: { + amount: decoded.Amount.toString(), + }, + }); + + const registry = yield* Registry.AtomRegistry; + registry.set(actionAtom, action); + }), + }); + +export const WithdrawForm = createWithdrawForm(AmountField); + +const setAmountFieldAtom = WithdrawForm.setValue(WithdrawForm.fields.Amount); +const amountFieldAtom = WithdrawForm.getFieldValue(WithdrawForm.fields.Amount); + +export const useWithdrawForm = () => { + const submit = useAtomSet(WithdrawForm.submit); + const submitResult = useAtomValue(WithdrawForm.submit); + + return { + submit, + submitResult, + }; +}; + +export const useSetWithdrawAmount = () => { + const setAmount = useAtomSet(setAmountFieldAtom); + + return { + setAmount, + }; +}; + +export const useWithdrawPercentage = ( + walletAddress: WalletAccount["address"], +) => { + const amount = useAtomValue(amountFieldAtom).pipe( + Option.map(Number), + Option.filter((v) => !Number.isNaN(v)), + Option.getOrElse(() => 0), + ); + + const setAmount = useAtomSet(setAmountFieldAtom); + + const availableBalance = useAtomValue( + selectedProviderBalancesAtom(walletAddress), + ).pipe( + Result.value, + Option.map((v) => v.availableBalance), + Option.getOrElse(() => 0), + ); + + const handlePercentageChange = (newPercentage: number) => { + if (newPercentage >= 100) { + return setAmount(availableBalance.toString()); + } + + const amount = valueFromPercent({ + total: availableBalance, + percent: newPercentage, + }); + setAmount(round(amount, 6).toString()); + }; + + const percentage = clampPercent( + percentOf({ part: amount, whole: availableBalance }), + ); + + return { + percentage: Math.round(percentage), + handlePercentageChange, + }; +}; diff --git a/packages/common/src/lib/formatting.ts b/packages/common/src/lib/formatting.ts new file mode 100644 index 0000000..eb1517d --- /dev/null +++ b/packages/common/src/lib/formatting.ts @@ -0,0 +1,163 @@ +/** + * Formatting helpers (display-only). + * + * Keep this module free of business logic / calculations; those live in `lib/math.ts`. + */ + +import { Option } from "effect"; +import type { TPOrSLSettings } from "../components/molecules/tp-sl-dialog"; + +const tokenAmountFormatter = new Intl.NumberFormat("en-US", { + minimumFractionDigits: 2, + maximumFractionDigits: 5, +}); + +/** + * Formats a token amount as `"SYMBOL 1.2345"`. + */ +export const formatTokenAmount = ({ + amount, + symbol, +}: { + amount: number | string; + symbol: string; +}) => { + const parsedAmount = typeof amount === "string" ? parseFloat(amount) : amount; + return `${symbol} ${tokenAmountFormatter.format(parsedAmount)}`; +}; + +/** + * Formats a USD-like amount with adaptive decimals and optional sign. + * + * This is used widely across the widget UI for prices, balances, margin, PnL, etc. + * + * Negative values are formatted as `-$37.1` (minus before symbol). + */ +export const formatAmount = ( + amount: number | string, + options = { symbol: "$" } as { + minimumFractionDigits?: number; + maximumFractionDigits?: number; + withSign?: boolean; + symbol?: string | null; + }, +): string => { + const amountNumber = typeof amount === "string" ? parseFloat(amount) : amount; + const symbol = options.symbol !== null ? (options.symbol ?? "$") : ""; + const isNegative = amountNumber < 0; + const absAmount = Math.abs(amountNumber); + + const hasCustomDigits = + options.minimumFractionDigits !== undefined || + options.maximumFractionDigits !== undefined; + + const { maxDigits, minDigits } = (() => { + if (hasCustomDigits) { + return { + minDigits: options.minimumFractionDigits, + maxDigits: options.maximumFractionDigits, + }; + } + + if (absAmount >= 1000) { + return { minDigits: undefined, maxDigits: 0 }; + } + if (absAmount >= 1) { + return { minDigits: 2, maxDigits: 4 }; + } + if (absAmount >= 0.01) { + return { minDigits: undefined, maxDigits: 4 }; + } + if (absAmount === 0) { + return { minDigits: 2, maxDigits: undefined }; + } + return { minDigits: 6, maxDigits: undefined }; + })(); + + const formattedNumber = absAmount.toLocaleString("en-US", { + minimumFractionDigits: minDigits, + maximumFractionDigits: maxDigits, + }); + + const sign = options?.withSign + ? isNegative + ? "-" + : "+" + : isNegative + ? "-" + : ""; + + return `${sign}${symbol}${formattedNumber}`; +}; + +/** + * Formats a percentage number: `12.345` -> `"12.35%"` + */ +export const formatPercentage = ( + percentage: number, + options?: { + maximumFractionDigits?: number; + }, +) => `${percentage.toFixed(options?.maximumFractionDigits ?? 2)}%`; + +/** + * Formats a rate string as a percentage. + * + * Example: `"0.0001"` -> `"0.01%"` + */ +export const formatRate = ( + rate: string, + options?: { + maximumFractionDigits?: number; + }, +) => formatPercentage(Number.parseFloat(rate) * 100, options); + +/** + * Returns a human-friendly USD amount using compact suffixes (K/M/B). + * + * - `1234` -> `$1.23K` + * - `2_500_000` -> `$2.50M` + * + * For smaller values it falls back to `formatAmount`. + */ +export function formatCompactUsdAmount(volume: number): string { + if (volume >= 1_000_000_000) { + return `$${(volume / 1_000_000_000).toFixed(2)}B`; + } + if (volume >= 1_000_000) { + return `$${(volume / 1_000_000).toFixed(2)}M`; + } + if (volume >= 1_000) { + return `$${(volume / 1_000).toFixed(2)}K`; + } + return formatAmount(volume); +} + +/** + * Formats TP/SL settings for display. + * + * - Long: "TP +10%, SL -5%" or "TP Off, SL Off" + * - Short: "TP -10%, SL +5%" or "TP Off, SL Off" + */ +export function formatTPOrSLSettings( + settings: TPOrSLSettings, + side: "long" | "short" = "long", +): string { + const tp = Option.fromNullable(settings.takeProfit.percentage).pipe( + Option.filter((percentage) => percentage !== 0), + Option.map((percentage) => + side === "short" ? `TP -${percentage}%` : `TP +${percentage}%`, + ), + Option.getOrElse(() => "TP Off"), + ); + + const sl = Option.fromNullable(settings.stopLoss.percentage).pipe( + Option.filter((percentage) => percentage !== 0), + Option.map((percentage) => + side === "short" ? `SL +${percentage}%` : `SL -${percentage}%`, + ), + Option.getOrElse(() => "SL Off"), + ); + + return `${tp}, ${sl}`; +} diff --git a/packages/common/src/lib/index.ts b/packages/common/src/lib/index.ts new file mode 100644 index 0000000..ade722f --- /dev/null +++ b/packages/common/src/lib/index.ts @@ -0,0 +1,3 @@ +export * from "./formatting"; +export * from "./math"; +export * from "./utils"; diff --git a/packages/common/src/lib/math.ts b/packages/common/src/lib/math.ts new file mode 100644 index 0000000..cda7017 --- /dev/null +++ b/packages/common/src/lib/math.ts @@ -0,0 +1,486 @@ +import { Number as _Number, Option } from "effect"; +import type { + MarketDto, + PositionDto, +} from "../services/api-client/api-schemas"; + +/** + * The minimum leverage supported by the UI/SDK. + * + * Note: this was previously defined in `domain/market.ts`, but lives here since + * it is tightly coupled to leverage-related math helpers. + */ +export const MIN_LEVERAGE = 1; + +/** + * A reasonable default max leverage fallback. + * + * Note: some markets provide their own leverage range; use `getMaxLeverage`. + */ +export const MAX_LEVERAGE = 40; + +/** + * Safely parses a decimal string to a number. + * + * Returns `fallback` when parsing fails. + */ +export const parseFloatOr = (value: string, fallback: number): number => { + return _Number.parse(value).pipe(Option.getOrElse(() => fallback)); +}; + +/** + * Safely parses a decimal string to a number. + * + * Returns `0` when parsing fails. + */ +export const parseFloatOrZero = (value: string): number => + parseFloatOr(value, 0); + +/** + * Clamps a percentage into the \([0, 100]\) interval. + */ +export const clampPercent = (percent: number): number => + _Number.clamp({ minimum: 0, maximum: 100 })(percent); + +/** + * Computes \( \frac{part}{whole} \cdot 100 \) with safe handling for `whole <= 0`. + */ +export const percentOf = ({ + part, + whole, +}: { + part: number; + whole: number; +}): number => { + if (whole <= 0) return 0; + return (part / whole) * 100; +}; + +/** + * Computes `total * percent/100`. + */ +export const valueFromPercent = ({ + total, + percent, +}: { + total: number; + percent: number; +}): number => total * (percent / 100); + +/** + * Applies a percentage delta to a value: `value * (1 + percent/100)`. + * + * This is commonly used for "quick adjust" UI controls (e.g. `-1%`, `-5%`). + */ +export const applyPercentDelta = ({ + value, + percent, +}: { + value: number; + percent: number; +}): number => value * (1 + percent / 100); + +/** + * Estimates the 24h low/high from a current price and an absolute change magnitude. + * + * This is useful when the backend provides `priceChange24h` but not the explicit low/high. + */ +export const estimateLowHighFromAbsoluteChange = ({ + currentPrice, + priceChange24h, +}: { + currentPrice: number; + priceChange24h: number; +}): { low: number; high: number } => { + const d = Math.abs(priceChange24h); + return { low: currentPrice - d, high: currentPrice + d }; +}; + +/** + * Computes the notional value (USD) given a price and size. + * + * `sizeBase` can be either a number or a decimal string coming from DTOs. + */ +export const calcNotionalUsd = ({ + priceUsd, + sizeBase, +}: { + priceUsd: number; + sizeBase: number | string; +}): number => { + const s = + typeof sizeBase === "string" ? parseFloatOrZero(sizeBase) : sizeBase; + return priceUsd * s; +}; + +/** + * Computes PnL% = (pnl / margin) * 100 with safe handling for `margin <= 0`. + */ +export const calcPnlPercent = ({ + pnlUsd, + marginUsd, +}: { + pnlUsd: number; + marginUsd: number; +}): number => (marginUsd > 0 ? (pnlUsd / marginUsd) * 100 : 0); + +/** + * Converts a USD amount into a crypto/base amount using a USD price. + */ +export const calcBaseAmountFromUsd = ({ + usdAmount, + priceUsd, +}: { + usdAmount: number; + priceUsd: number; +}): number => { + if (priceUsd <= 0) return 0; + return usdAmount / priceUsd; +}; + +/** + * Converts a crypto/base amount into USD using a USD price. + */ +export const calcUsdFromBaseAmount = ({ + baseAmount, + priceUsd, +}: { + baseAmount: number; + priceUsd: number; +}): number => baseAmount * priceUsd; + +/** + * Truncates a number down to the given decimal precision. + * + * Example: `round(1.239, 2) -> 1.23` + */ +export const round = (number: number, precision: number = 2) => + _Number.round(number, precision); + +/** + * Computes max leverage from the leverage range (falls back to `MAX_LEVERAGE`). + */ +export const getMaxLeverage = ( + leverages: MarketDto["leverageRange"], +): number => + leverages.length > 0 + ? (leverages[leverages.length - 1] ?? MAX_LEVERAGE) + : MAX_LEVERAGE; + +/** + * Generic percent change between two prices: \(\frac{current - reference}{reference} \cdot 100\). + */ +export const getPriceChangePercent = ({ + currentPrice, + pastOrFuturePrice, +}: { + currentPrice: number; + pastOrFuturePrice: number; +}) => { + if (pastOrFuturePrice === 0) return 100; + return ((currentPrice - pastOrFuturePrice) / pastOrFuturePrice) * 100; +}; + +/** + * Price change percent for a position relative to entry. + */ +export const getPositionChangePercent = (position: PositionDto) => + getPriceChangePercent({ + currentPrice: position.markPrice, + pastOrFuturePrice: position.entryPrice, + }); + +/** + * Calculates the liquidation price given a current price, leverage and side. + */ +export const getLiquidationPrice = ({ + currentPrice, + leverage, + side, +}: { + currentPrice: number; + leverage: number; + side: "long" | "short"; +}) => + side === "long" + ? currentPrice * (1 - 1 / leverage) + : currentPrice * (1 + 1 / leverage); + +/** + * Percent price change needed to reach liquidation. + */ +export const getPriceChangePercentToLiquidation = ({ + currentPrice, + liquidationPrice, +}: { + currentPrice: number; + liquidationPrice: number; +}) => + getPriceChangePercent({ + currentPrice, + pastOrFuturePrice: liquidationPrice, + }); + +/** + * Maps a leverage into slider percent space between `MIN_LEVERAGE` and `maxLeverage`. + */ +export const getLeveragePercent = ({ + leverage, + maxLeverage, +}: { + leverage: number; + maxLeverage: number; +}) => ((leverage - MIN_LEVERAGE) / (maxLeverage - MIN_LEVERAGE)) * 100; + +/** + * Converts a slider percent \([0..100]\) into a leverage value between + * `MIN_LEVERAGE` and `maxLeverage`. + */ +export const getLeverageFromPercent = ({ + percent, + maxLeverage, +}: { + percent: number; + maxLeverage: number; +}): number => { + const p = clampPercent(percent); + return Math.round(MIN_LEVERAGE + (p / 100) * (maxLeverage - MIN_LEVERAGE)); +}; + +/** + * Recommended leverage slider "stop" markers. + */ +export const getLeverageStops = (maxLeverage: number): number[] => [ + MIN_LEVERAGE, + Math.round(maxLeverage / 2), + maxLeverage, +]; + +/** + * Generates common leverage button presets (2x, 5x, 10x, 20x... up to max). + */ +export const generateLeverageButtons = (maxLeverage: number): number[] => { + const buttons: number[] = []; + + if (maxLeverage >= 2) { + buttons.push(2); + } + + if (maxLeverage >= 5) { + buttons.push(5); + } + + let value = 10; + while (value <= maxLeverage) { + buttons.push(value); + value *= 2; + } + + if (buttons[buttons.length - 1] !== maxLeverage && maxLeverage > 2) { + buttons.push(maxLeverage); + } + + return [...new Set(buttons)].sort((a, b) => a - b); +}; + +/** + * Calculates required margin for a notional position size and leverage. + */ +export const calculateMargin = ({ + positionSize, + leverage, +}: { + positionSize: number; + leverage: number; +}) => { + if (leverage <= 0) return positionSize; + return positionSize / leverage; +}; + +/** + * Calculates notional position size from margin and leverage. + */ +export const calculatePositionSize = ({ + margin, + leverage, +}: { + margin: number; + leverage: number; +}) => margin * leverage; + +/** + * Computes close-related UI calculations for a given close percentage. + */ +export const getCloseCalculations = ( + position: PositionDto, + closePercentage: number, +) => { + const ratio = closePercentage / 100; + const sizeNum = parseFloatOrZero(position.size); + const positionValue = position.markPrice * sizeNum; + const closeValue = positionValue * ratio; + const marginReturn = position.margin * ratio; + const pnlReturn = position.unrealizedPnl * ratio; + const youWillReceive = marginReturn + pnlReturn; + const closeSize = sizeNum * ratio; + const closeSizeInMarketPrice = round( + closeSize * position.markPrice, + 6, + ).toString(); + + return { + closeValue, + marginReturn, + pnlReturn, + youWillReceive, + closeSize, + closeSizeInMarketPrice, + }; +}; + +export type TpSlKind = "takeProfit" | "stopLoss"; + +/** + * Returns the "+" / "-" prefix used for TP/SL percent labels. + */ +export const getTpSlPercentPrefix = ({ + side, + tpOrSl, +}: { + side: "long" | "short"; + tpOrSl: TpSlKind; +}): "+" | "-" => { + if (side === "short") { + return tpOrSl === "takeProfit" ? "-" : "+"; + } + return tpOrSl === "takeProfit" ? "+" : "-"; +}; + +/** + * Calculates a TP/SL trigger price from entry and a (positive) percent move. + */ +export const calcTpSlTriggerPriceFromPercent = ({ + entryPrice, + percent, + side, + tpOrSl, +}: { + entryPrice: number; + percent: number; + side: "long" | "short"; + tpOrSl: TpSlKind; +}): number => { + const p = percent / 100; + const prefix = getTpSlPercentPrefix({ side, tpOrSl }); + return prefix === "+" ? entryPrice * (1 + p) : entryPrice * (1 - p); +}; + +/** + * Calculates the (positive) percent move between entry and trigger price for TP/SL. + */ +export const calcTpSlPercentFromTriggerPrice = ({ + entryPrice, + triggerPrice, + side, + tpOrSl, +}: { + entryPrice: number; + triggerPrice: number; + side: "long" | "short"; + tpOrSl: TpSlKind; +}): number => { + if (entryPrice <= 0) return 0; + const prefix = getTpSlPercentPrefix({ side, tpOrSl }); + const raw = + prefix === "+" + ? ((triggerPrice - entryPrice) / entryPrice) * 100 + : ((entryPrice - triggerPrice) / entryPrice) * 100; + return raw; +}; + +/** + * Default TP/SL percent presets used by the widget UI. + */ +export const DEFAULT_TP_SL_PERCENT_OPTIONS = [0, 10, 25, 50, 100] as const; +type DefaultTpSlPercentOption = (typeof DEFAULT_TP_SL_PERCENT_OPTIONS)[number]; + +/** + * Finds a matching percent option within a tolerance. + */ +export const findMatchingPercentOption = ({ + percent, + options, + tolerance = 0.5, +}: { + percent: number; + options: ReadonlyArray; + tolerance?: number; +}): T | null => + options.find((opt) => Math.abs(percent - opt) < tolerance) ?? null; + +/** + * Computes TP/SL configuration (percentage + option) from a trigger price. + * + * This is used to prefill UI when the backend provides an existing TP/SL order. + */ +export function getTPOrSLConfigurationFromPosition(args: { + entryPrice: number; + amount: number | undefined; + tpOrSl: TpSlKind; + side?: "long" | "short"; +}): { + option: DefaultTpSlPercentOption | null; + triggerPrice: number | null; + percentage: number | null; +}; +export function getTPOrSLConfigurationFromPosition(args: { + entryPrice: number; + amount: number | undefined; + tpOrSl: TpSlKind; + side?: "long" | "short"; + options: ReadonlyArray; +}): { + option: T | null; + triggerPrice: number | null; + percentage: number | null; +}; +export function getTPOrSLConfigurationFromPosition({ + amount, + entryPrice, + tpOrSl, + side = "long", + options, +}: { + entryPrice: number; + amount: number | undefined; + tpOrSl: TpSlKind; + side?: "long" | "short"; + options?: ReadonlyArray; +}): { + option: T | DefaultTpSlPercentOption | null; + triggerPrice: number | null; + percentage: number | null; +} { + const optList = + options ?? (DEFAULT_TP_SL_PERCENT_OPTIONS as unknown as ReadonlyArray); + const percentage = + amount === undefined + ? null + : calcTpSlPercentFromTriggerPrice({ + entryPrice, + triggerPrice: amount, + side, + tpOrSl, + }); + + const option = + percentage === null || percentage === 0 + ? null + : findMatchingPercentOption({ percent: percentage, options: optList }); + + return { + option, + triggerPrice: amount || null, + percentage, + }; +} diff --git a/packages/common/src/lib/utils.ts b/packages/common/src/lib/utils.ts new file mode 100644 index 0000000..5b71b14 --- /dev/null +++ b/packages/common/src/lib/utils.ts @@ -0,0 +1,40 @@ +import { type ClassValue, clsx } from "clsx"; +import { twMerge } from "tailwind-merge"; +import type { TokenString } from "../domain/types"; +import type { TokenDto } from "../services/api-client/api-schemas"; + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)); +} + +export const getNetworkLogo = (network: string) => + `https://assets.stakek.it/networks/${network}.svg`; + +export const getTokenLogo = (tokenSymbol: string) => + `https://assets.stakek.it/tokens/${tokenSymbol.toLowerCase()}.svg`; + +export const getTokenString = (token: TokenDto): TokenString => + `${token.network}-${token.address}`; + +export const truncateAddress = (address: string, length: number = 6) => + `${address.slice(0, length)}...${address.slice(-length)}`; + +export const formatSnakeCase = (network: string) => { + let str = network[0]?.toUpperCase() ?? ""; + for (let i = 1; i < network.length; i++) { + str += + network[i] === "_" ? ` ${network[++i]?.toUpperCase() ?? ""}` : network[i]; + } + return str; +}; + +export const formatDate = (timestamp: number): string => { + const date = new Date(timestamp); + return date.toLocaleDateString("en-US", { + day: "numeric", + month: "short", + hour: "numeric", + minute: "2-digit", + hour12: true, + }); +}; diff --git a/src/services/api-client/api-schemas.ts b/packages/common/src/services/api-client/api-schemas.ts similarity index 81% rename from src/services/api-client/api-schemas.ts rename to packages/common/src/services/api-client/api-schemas.ts index d87b22e..ae27cc2 100644 --- a/src/services/api-client/api-schemas.ts +++ b/packages/common/src/services/api-client/api-schemas.ts @@ -42,7 +42,7 @@ export class ProviderDto extends S.Class("ProviderDto")({ /** * Supported action types */ -"supportedActions": S.Array(S.Literal("open", "close", "updateLeverage", "stopLoss", "takeProfit", "cancelOrder", "fund", "withdraw")), +"supportedActions": S.Array(S.Literal("open", "close", "updateLeverage", "stopLoss", "takeProfit", "cancelOrder", "fund", "withdraw", "approveAgent")), /** * Argument schemas for each supported action (JSON Schema format) */ @@ -86,18 +86,30 @@ export class MarketsControllerGetMarketsParams extends S.Struct({ /** * Network identifier */ -export class Networks extends S.Literal("ethereum", "ethereum-goerli", "ethereum-holesky", "ethereum-sepolia", "ethereum-hoodi", "arbitrum", "base", "base-sepolia", "gnosis", "optimism", "polygon", "polygon-amoy", "starknet", "zksync", "linea", "unichain", "monad-testnet", "monad", "avalanche-c", "avalanche-c-atomic", "avalanche-p", "binance", "celo", "fantom", "harmony", "moonriver", "okc", "viction", "core", "sonic", "plasma", "katana", "hyperevm", "agoric", "akash", "axelar", "band-protocol", "bitsong", "canto", "chihuahua", "comdex", "coreum", "cosmos", "crescent", "cronos", "cudos", "desmos", "dydx", "evmos", "fetch-ai", "gravity-bridge", "injective", "irisnet", "juno", "kava", "ki-network", "mars-protocol", "nym", "okex-chain", "onomy", "osmosis", "persistence", "quicksilver", "regen", "secret", "sentinel", "sommelier", "stafi", "stargaze", "stride", "teritori", "tgrade", "umee", "sei", "mantra", "celestia", "saga", "zetachain", "dymension", "humansai", "neutron", "polkadot", "kusama", "westend", "bittensor", "binancebeacon", "cardano", "near", "solana", "solana-devnet", "stellar", "stellar-testnet", "sui", "tezos", "tron", "ton", "ton-testnet", "hyperliquid") {} +export class Networks extends S.Literal("ethereum", "ethereum-goerli", "ethereum-holesky", "ethereum-sepolia", "ethereum-hoodi", "arbitrum", "base", "base-sepolia", "gnosis", "optimism", "polygon", "polygon-amoy", "starknet", "zksync", "linea", "unichain", "monad-testnet", "monad", "avalanche-c", "avalanche-c-atomic", "avalanche-p", "binance", "celo", "fantom", "harmony", "moonriver", "okc", "viction", "core", "sonic", "plasma", "katana", "hyperevm", "agoric", "akash", "axelar", "band-protocol", "bitsong", "canto", "chihuahua", "comdex", "coreum", "cosmos", "crescent", "cronos", "cudos", "desmos", "dydx", "evmos", "fetch-ai", "gravity-bridge", "injective", "irisnet", "juno", "kava", "ki-network", "mars-protocol", "nym", "okex-chain", "onomy", "osmosis", "persistence", "quicksilver", "regen", "secret", "sentinel", "sommelier", "stafi", "stargaze", "stride", "teritori", "tgrade", "umee", "sei", "mantra", "celestia", "saga", "zetachain", "dymension", "humansai", "neutron", "polkadot", "kusama", "westend", "bittensor", "aptos", "binancebeacon", "cardano", "near", "solana", "solana-devnet", "stellar", "stellar-testnet", "sui", "tezos", "tron", "ton", "ton-testnet", "hyperliquid") {} export class TokenDto extends S.Class("TokenDto")({ - "name": S.String, + /** +* Token symbol +*/ +"symbol": S.String, + /** +* Token name +*/ +"name": S.optionalWith(S.String, { nullable: true }), "network": Networks, - "symbol": S.String, - "decimals": S.Number, - "address": S.optionalWith(S.String, { nullable: true }), - "coinGeckoId": S.optionalWith(S.String, { nullable: true }), - "logoURI": S.optionalWith(S.String, { nullable: true }), - "isPoints": S.optionalWith(S.Boolean, { nullable: true }), - "feeConfigurationId": S.optionalWith(S.String, { nullable: true }) + /** +* Token decimals +*/ +"decimals": S.optionalWith(S.Number, { nullable: true }), + /** +* Token contract address (optional for native tokens) +*/ +"address": S.optionalWith(S.String, { nullable: true }), + /** +* Token logo URI +*/ +"logoURI": S.optionalWith(S.String, { nullable: true }) }) {} export class MarketMetadataDto extends S.Class("MarketMetadataDto")({ @@ -235,7 +247,7 @@ export class PositionDtoMarginMode extends S.Literal("cross", "isolated") {} /** * Action type */ -export class PendingActionDtoType extends S.Literal("open", "close", "updateLeverage", "stopLoss", "takeProfit", "cancelOrder", "fund", "withdraw") {} +export class PendingActionDtoType extends S.Literal("open", "close", "updateLeverage", "stopLoss", "takeProfit", "cancelOrder", "fund", "withdraw", "approveAgent") {} /** * Position side - long (buy) or short (sell) @@ -303,7 +315,19 @@ export class ArgumentsDto extends S.Class("ArgumentsDto")({ /** * Source token for cross-chain funding (bridge/swap from another chain) */ -"fromToken": S.optionalWith(TokenIdentifierDto, { nullable: true }) +"fromToken": S.optionalWith(TokenIdentifierDto, { nullable: true }), + /** +* Agent wallet address to approve (for approveAgent action) +*/ +"agentAddress": S.optionalWith(S.String, { nullable: true }), + /** +* Name for the agent wallet (for approveAgent action). If not provided, defaults to "key". +*/ +"agentName": S.optionalWith(S.String, { nullable: true }), + /** +* Unix timestamp (seconds) when agent approval expires. If not provided, never expires. +*/ +"validUntil": S.optionalWith(S.Number, { nullable: true }) }) {} export class PendingActionDto extends S.Class("PendingActionDto")({ @@ -490,7 +514,7 @@ export class PortfolioControllerGetBalances429 extends S.Struct({ /** * Action to execute */ -export class ActionRequestDtoAction extends S.Literal("open", "close", "updateLeverage", "stopLoss", "takeProfit", "cancelOrder", "fund", "withdraw") {} +export class ActionRequestDtoAction extends S.Literal("open", "close", "updateLeverage", "stopLoss", "takeProfit", "cancelOrder", "fund", "withdraw", "approveAgent") {} export class ActionRequestDto extends S.Class("ActionRequestDto")({ /** @@ -514,7 +538,7 @@ export class ActionRequestDto extends S.Class("ActionRequestDt /** * Action type executed */ -export class ActionDtoAction extends S.Literal("open", "close", "updateLeverage", "stopLoss", "takeProfit", "cancelOrder", "fund", "withdraw") {} +export class ActionDtoAction extends S.Literal("open", "close", "updateLeverage", "stopLoss", "takeProfit", "cancelOrder", "fund", "withdraw", "approveAgent") {} /** * Current action status @@ -524,7 +548,7 @@ export class ActionDtoStatus extends S.Literal("CANCELED", "CREATED", "WAITING_F /** * Transaction type */ -export class TransactionDtoType extends S.Literal("APPROVAL", "OPEN_POSITION", "CLOSE_POSITION", "UPDATE_LEVERAGE", "STOP_LOSS", "TAKE_PROFIT", "CANCEL_ORDER", "FUND", "WITHDRAW") {} +export class TransactionDtoType extends S.Literal("APPROVAL", "OPEN_POSITION", "CLOSE_POSITION", "UPDATE_LEVERAGE", "STOP_LOSS", "TAKE_PROFIT", "CANCEL_ORDER", "FUND", "WITHDRAW", "APPROVE_BUILDER_FEE", "ENABLE_DEX_ABSTRACTION", "APPROVE_AGENT") {} /** * Current transaction status @@ -686,79 +710,6 @@ export class HealthStatusDto extends S.Class("HealthStatusDto") "timestamp": S.String }) {} -export class TokenControllerGetTokenPricesParams extends S.Struct({ - "X-API-KEY": S.optionalWith(S.String, { nullable: true }) -}) {} - -export class PriceRequestDto extends S.Class("PriceRequestDto")({ - "currency": S.String, - "tokenList": S.Array(TokenDto) -}) {} - -export class PriceResponseDto extends S.Class("PriceResponseDto")({ - -}) {} - -export class StakeKitErrorDto extends S.Class("StakeKitErrorDto")({ - "message": S.String, - "code": S.Number, - "type": S.optionalWith(S.String, { nullable: true }), - "details": S.optionalWith(S.Record({ key: S.String, value: S.Unknown }), { nullable: true }), - "path": S.optionalWith(S.String, { nullable: true }) -}) {} - -export class TokenControllerGetTokenBalancesParams extends S.Struct({ - "X-API-KEY": S.optionalWith(S.String, { nullable: true }) -}) {} - -export class CosmosAdditionalAddressesDto extends S.Class("CosmosAdditionalAddressesDto")({ - /** -* Cosmos SDK public key encoded in base64 for secp256k1 -*/ -"cosmosPubKey": S.String.pipe(S.minLength(44), S.maxLength(44)) -}) {} - -export class BinanceAdditionalAddressesDto extends S.Class("BinanceAdditionalAddressesDto")({ - "binanceBeaconAddress": S.String -}) {} - -export class SolanaAdditionalAddressesDto extends S.Class("SolanaAdditionalAddressesDto")({ - "stakeAccounts": S.Array(S.String), - "lidoStakeAccounts": S.Array(S.String) -}) {} - -export class TezosAdditionalAddressesDto extends S.Class("TezosAdditionalAddressesDto")({ - "tezosPubKey": S.String -}) {} - -export class AvalancheCAdditionalAddressesDto extends S.Class("AvalancheCAdditionalAddressesDto")({ - "cAddressBech": S.String, - "pAddressBech": S.String -}) {} - -export class AddressWithTokenDto extends S.Class("AddressWithTokenDto")({ - "address": S.String, - "additionalAddresses": S.optionalWith(S.Union(CosmosAdditionalAddressesDto, -BinanceAdditionalAddressesDto, -SolanaAdditionalAddressesDto, -TezosAdditionalAddressesDto, -AvalancheCAdditionalAddressesDto), { nullable: true }), - "network": Networks, - "tokenAddress": S.optionalWith(S.String, { nullable: true }) -}) {} - -export class BalancesRequestDto extends S.Class("BalancesRequestDto")({ - "addresses": S.Array(AddressWithTokenDto) -}) {} - -export class BalanceResponseDto extends S.Class("BalanceResponseDto")({ - "token": TokenDto, - "amount": S.String, - "availableYields": S.Array(S.String) -}) {} - -export class TokenControllerGetTokenBalances200 extends S.Array(BalanceResponseDto) {} - export const make = ( httpClient: HttpClient.HttpClient, options: { @@ -891,40 +842,6 @@ export const make = ( "2xx": decodeSuccess(HealthStatusDto), orElse: unexpectedStatus })) - ), - "TokenControllerGetTokenPrices": (options) => HttpClientRequest.post(`/v1/tokens/prices`).pipe( - HttpClientRequest.setHeaders({ "X-API-KEY": options.params?.["X-API-KEY"] ?? undefined }), - HttpClientRequest.bodyUnsafeJson(options.payload), - withResponse(HttpClientResponse.matchStatus({ - "2xx": decodeSuccess(PriceResponseDto), - "400": decodeError("StakeKitErrorDto", StakeKitErrorDto), - "401": decodeError("StakeKitErrorDto", StakeKitErrorDto), - "404": decodeError("StakeKitErrorDto", StakeKitErrorDto), - "408": decodeError("StakeKitErrorDto", StakeKitErrorDto), - "412": decodeError("StakeKitErrorDto", StakeKitErrorDto), - "429": decodeError("StakeKitErrorDto", StakeKitErrorDto), - "500": decodeError("StakeKitErrorDto", StakeKitErrorDto), - "501": decodeError("StakeKitErrorDto", StakeKitErrorDto), - "503": decodeError("StakeKitErrorDto", StakeKitErrorDto), - orElse: unexpectedStatus - })) - ), - "TokenControllerGetTokenBalances": (options) => HttpClientRequest.post(`/v1/tokens/balances`).pipe( - HttpClientRequest.setHeaders({ "X-API-KEY": options.params?.["X-API-KEY"] ?? undefined }), - HttpClientRequest.bodyUnsafeJson(options.payload), - withResponse(HttpClientResponse.matchStatus({ - "2xx": decodeSuccess(TokenControllerGetTokenBalances200), - "400": decodeError("StakeKitErrorDto", StakeKitErrorDto), - "401": decodeError("StakeKitErrorDto", StakeKitErrorDto), - "404": decodeError("StakeKitErrorDto", StakeKitErrorDto), - "408": decodeError("StakeKitErrorDto", StakeKitErrorDto), - "412": decodeError("StakeKitErrorDto", StakeKitErrorDto), - "429": decodeError("StakeKitErrorDto", StakeKitErrorDto), - "500": decodeError("StakeKitErrorDto", StakeKitErrorDto), - "501": decodeError("StakeKitErrorDto", StakeKitErrorDto), - "503": decodeError("StakeKitErrorDto", StakeKitErrorDto), - orElse: unexpectedStatus - })) ) } } @@ -971,14 +888,6 @@ readonly "TransactionsControllerSubmitTransaction": (transactionId: string, opti * Get the health status of the perps API with current timestamp */ readonly "HealthControllerHealth": () => Effect.Effect - /** -* Returns the token prices for a specific list of tokens -*/ -readonly "TokenControllerGetTokenPrices": (options: { readonly params?: typeof TokenControllerGetTokenPricesParams.Encoded | undefined; readonly payload: typeof PriceRequestDto.Encoded }) => Effect.Effect | SKClientError<"StakeKitErrorDto", typeof StakeKitErrorDto.Type> | SKClientError<"StakeKitErrorDto", typeof StakeKitErrorDto.Type> | SKClientError<"StakeKitErrorDto", typeof StakeKitErrorDto.Type> | SKClientError<"StakeKitErrorDto", typeof StakeKitErrorDto.Type> | SKClientError<"StakeKitErrorDto", typeof StakeKitErrorDto.Type> | SKClientError<"StakeKitErrorDto", typeof StakeKitErrorDto.Type> | SKClientError<"StakeKitErrorDto", typeof StakeKitErrorDto.Type> | SKClientError<"StakeKitErrorDto", typeof StakeKitErrorDto.Type>> - /** -* Returns the balances for specific addresses and token addresses -*/ -readonly "TokenControllerGetTokenBalances": (options: { readonly params?: typeof TokenControllerGetTokenBalancesParams.Encoded | undefined; readonly payload: typeof BalancesRequestDto.Encoded }) => Effect.Effect | SKClientError<"StakeKitErrorDto", typeof StakeKitErrorDto.Type> | SKClientError<"StakeKitErrorDto", typeof StakeKitErrorDto.Type> | SKClientError<"StakeKitErrorDto", typeof StakeKitErrorDto.Type> | SKClientError<"StakeKitErrorDto", typeof StakeKitErrorDto.Type> | SKClientError<"StakeKitErrorDto", typeof StakeKitErrorDto.Type> | SKClientError<"StakeKitErrorDto", typeof StakeKitErrorDto.Type> | SKClientError<"StakeKitErrorDto", typeof StakeKitErrorDto.Type> | SKClientError<"StakeKitErrorDto", typeof StakeKitErrorDto.Type>> } export interface SKClientError { diff --git a/src/services/api-client/client-factory.ts b/packages/common/src/services/api-client/client-factory.ts similarity index 83% rename from src/services/api-client/client-factory.ts rename to packages/common/src/services/api-client/client-factory.ts index 0c92fed..3ebcc5a 100644 --- a/src/services/api-client/client-factory.ts +++ b/packages/common/src/services/api-client/client-factory.ts @@ -40,7 +40,7 @@ readonly "metadata": ProviderMetadataDto; /** * Supported action types */ -readonly "supportedActions": ReadonlyArray<"open" | "close" | "updateLeverage" | "stopLoss" | "takeProfit" | "cancelOrder" | "fund" | "withdraw">; +readonly "supportedActions": ReadonlyArray<"open" | "close" | "updateLeverage" | "stopLoss" | "takeProfit" | "cancelOrder" | "fund" | "withdraw" | "approveAgent">; /** * Argument schemas for each supported action (JSON Schema format) */ @@ -84,18 +84,30 @@ export interface MarketsControllerGetMarketsParams { /** * Network identifier */ -export type Networks = "ethereum" | "ethereum-goerli" | "ethereum-holesky" | "ethereum-sepolia" | "ethereum-hoodi" | "arbitrum" | "base" | "base-sepolia" | "gnosis" | "optimism" | "polygon" | "polygon-amoy" | "starknet" | "zksync" | "linea" | "unichain" | "monad-testnet" | "monad" | "avalanche-c" | "avalanche-c-atomic" | "avalanche-p" | "binance" | "celo" | "fantom" | "harmony" | "moonriver" | "okc" | "viction" | "core" | "sonic" | "plasma" | "katana" | "hyperevm" | "agoric" | "akash" | "axelar" | "band-protocol" | "bitsong" | "canto" | "chihuahua" | "comdex" | "coreum" | "cosmos" | "crescent" | "cronos" | "cudos" | "desmos" | "dydx" | "evmos" | "fetch-ai" | "gravity-bridge" | "injective" | "irisnet" | "juno" | "kava" | "ki-network" | "mars-protocol" | "nym" | "okex-chain" | "onomy" | "osmosis" | "persistence" | "quicksilver" | "regen" | "secret" | "sentinel" | "sommelier" | "stafi" | "stargaze" | "stride" | "teritori" | "tgrade" | "umee" | "sei" | "mantra" | "celestia" | "saga" | "zetachain" | "dymension" | "humansai" | "neutron" | "polkadot" | "kusama" | "westend" | "bittensor" | "binancebeacon" | "cardano" | "near" | "solana" | "solana-devnet" | "stellar" | "stellar-testnet" | "sui" | "tezos" | "tron" | "ton" | "ton-testnet" | "hyperliquid" +export type Networks = "ethereum" | "ethereum-goerli" | "ethereum-holesky" | "ethereum-sepolia" | "ethereum-hoodi" | "arbitrum" | "base" | "base-sepolia" | "gnosis" | "optimism" | "polygon" | "polygon-amoy" | "starknet" | "zksync" | "linea" | "unichain" | "monad-testnet" | "monad" | "avalanche-c" | "avalanche-c-atomic" | "avalanche-p" | "binance" | "celo" | "fantom" | "harmony" | "moonriver" | "okc" | "viction" | "core" | "sonic" | "plasma" | "katana" | "hyperevm" | "agoric" | "akash" | "axelar" | "band-protocol" | "bitsong" | "canto" | "chihuahua" | "comdex" | "coreum" | "cosmos" | "crescent" | "cronos" | "cudos" | "desmos" | "dydx" | "evmos" | "fetch-ai" | "gravity-bridge" | "injective" | "irisnet" | "juno" | "kava" | "ki-network" | "mars-protocol" | "nym" | "okex-chain" | "onomy" | "osmosis" | "persistence" | "quicksilver" | "regen" | "secret" | "sentinel" | "sommelier" | "stafi" | "stargaze" | "stride" | "teritori" | "tgrade" | "umee" | "sei" | "mantra" | "celestia" | "saga" | "zetachain" | "dymension" | "humansai" | "neutron" | "polkadot" | "kusama" | "westend" | "bittensor" | "aptos" | "binancebeacon" | "cardano" | "near" | "solana" | "solana-devnet" | "stellar" | "stellar-testnet" | "sui" | "tezos" | "tron" | "ton" | "ton-testnet" | "hyperliquid" export interface TokenDto { - readonly "name": string; + /** +* Token symbol +*/ +readonly "symbol": string; + /** +* Token name +*/ +readonly "name"?: string | undefined; readonly "network": Networks; - readonly "symbol": string; - readonly "decimals": number; - readonly "address"?: string | undefined; - readonly "coinGeckoId"?: string | undefined; - readonly "logoURI"?: string | undefined; - readonly "isPoints"?: boolean | undefined; - readonly "feeConfigurationId"?: string | undefined + /** +* Token decimals +*/ +readonly "decimals"?: number | undefined; + /** +* Token contract address (optional for native tokens) +*/ +readonly "address"?: string | undefined; + /** +* Token logo URI +*/ +readonly "logoURI"?: string | undefined } export interface MarketMetadataDto { @@ -233,7 +245,7 @@ export type PositionDtoMarginMode = "cross" | "isolated" /** * Action type */ -export type PendingActionDtoType = "open" | "close" | "updateLeverage" | "stopLoss" | "takeProfit" | "cancelOrder" | "fund" | "withdraw" +export type PendingActionDtoType = "open" | "close" | "updateLeverage" | "stopLoss" | "takeProfit" | "cancelOrder" | "fund" | "withdraw" | "approveAgent" /** * Position side - long (buy) or short (sell) @@ -301,7 +313,19 @@ readonly "assetIndex"?: number | undefined; /** * Source token for cross-chain funding (bridge/swap from another chain) */ -readonly "fromToken"?: TokenIdentifierDto | undefined +readonly "fromToken"?: TokenIdentifierDto | undefined; + /** +* Agent wallet address to approve (for approveAgent action) +*/ +readonly "agentAddress"?: string | undefined; + /** +* Name for the agent wallet (for approveAgent action). If not provided, defaults to "key". +*/ +readonly "agentName"?: string | undefined; + /** +* Unix timestamp (seconds) when agent approval expires. If not provided, never expires. +*/ +readonly "validUntil"?: number | undefined } export interface PendingActionDto { @@ -488,7 +512,7 @@ export interface PortfolioControllerGetBalances429 { /** * Action to execute */ -export type ActionRequestDtoAction = "open" | "close" | "updateLeverage" | "stopLoss" | "takeProfit" | "cancelOrder" | "fund" | "withdraw" +export type ActionRequestDtoAction = "open" | "close" | "updateLeverage" | "stopLoss" | "takeProfit" | "cancelOrder" | "fund" | "withdraw" | "approveAgent" export interface ActionRequestDto { /** @@ -512,7 +536,7 @@ readonly "args": ArgumentsDto /** * Action type executed */ -export type ActionDtoAction = "open" | "close" | "updateLeverage" | "stopLoss" | "takeProfit" | "cancelOrder" | "fund" | "withdraw" +export type ActionDtoAction = "open" | "close" | "updateLeverage" | "stopLoss" | "takeProfit" | "cancelOrder" | "fund" | "withdraw" | "approveAgent" /** * Current action status @@ -522,7 +546,7 @@ export type ActionDtoStatus = "CANCELED" | "CREATED" | "WAITING_FOR_NEXT" | "PRO /** * Transaction type */ -export type TransactionDtoType = "APPROVAL" | "OPEN_POSITION" | "CLOSE_POSITION" | "UPDATE_LEVERAGE" | "STOP_LOSS" | "TAKE_PROFIT" | "CANCEL_ORDER" | "FUND" | "WITHDRAW" +export type TransactionDtoType = "APPROVAL" | "OPEN_POSITION" | "CLOSE_POSITION" | "UPDATE_LEVERAGE" | "STOP_LOSS" | "TAKE_PROFIT" | "CANCEL_ORDER" | "FUND" | "WITHDRAW" | "APPROVE_BUILDER_FEE" | "ENABLE_DEX_ABSTRACTION" | "APPROVE_AGENT" /** * Current transaction status @@ -684,75 +708,6 @@ export interface HealthStatusDto { readonly "timestamp": string } -export interface TokenControllerGetTokenPricesParams { - readonly "X-API-KEY"?: string | undefined -} - -export interface PriceRequestDto { - readonly "currency": string; - readonly "tokenList": ReadonlyArray -} - -export interface PriceResponseDto { - -} - -export interface StakeKitErrorDto { - readonly "message": string; - readonly "code": number; - readonly "type"?: string | undefined; - readonly "details"?: Record | undefined; - readonly "path"?: string | undefined -} - -export interface TokenControllerGetTokenBalancesParams { - readonly "X-API-KEY"?: string | undefined -} - -export interface CosmosAdditionalAddressesDto { - /** -* Cosmos SDK public key encoded in base64 for secp256k1 -*/ -readonly "cosmosPubKey": string -} - -export interface BinanceAdditionalAddressesDto { - readonly "binanceBeaconAddress": string -} - -export interface SolanaAdditionalAddressesDto { - readonly "stakeAccounts": ReadonlyArray; - readonly "lidoStakeAccounts": ReadonlyArray -} - -export interface TezosAdditionalAddressesDto { - readonly "tezosPubKey": string -} - -export interface AvalancheCAdditionalAddressesDto { - readonly "cAddressBech": string; - readonly "pAddressBech": string -} - -export interface AddressWithTokenDto { - readonly "address": string; - readonly "additionalAddresses"?: CosmosAdditionalAddressesDto | BinanceAdditionalAddressesDto | SolanaAdditionalAddressesDto | TezosAdditionalAddressesDto | AvalancheCAdditionalAddressesDto | undefined; - readonly "network": Networks; - readonly "tokenAddress"?: string | undefined -} - -export interface BalancesRequestDto { - readonly "addresses": ReadonlyArray -} - -export interface BalanceResponseDto { - readonly "token": TokenDto; - readonly "amount": string; - readonly "availableYields": ReadonlyArray -} - -export type TokenControllerGetTokenBalances200 = ReadonlyArray - export const make = ( httpClient: HttpClient.HttpClient, options: { @@ -856,16 +811,6 @@ export const make = ( ), "HealthControllerHealth": () => HttpClientRequest.get(`/health`).pipe( onRequest(["2xx"]) - ), - "TokenControllerGetTokenPrices": (options) => HttpClientRequest.post(`/v1/tokens/prices`).pipe( - HttpClientRequest.setHeaders({ "X-API-KEY": options.params?.["X-API-KEY"] ?? undefined }), - HttpClientRequest.bodyUnsafeJson(options.payload), - onRequest(["2xx"], {"400":"StakeKitErrorDto","401":"StakeKitErrorDto","404":"StakeKitErrorDto","408":"StakeKitErrorDto","412":"StakeKitErrorDto","429":"StakeKitErrorDto","500":"StakeKitErrorDto","501":"StakeKitErrorDto","503":"StakeKitErrorDto"}) - ), - "TokenControllerGetTokenBalances": (options) => HttpClientRequest.post(`/v1/tokens/balances`).pipe( - HttpClientRequest.setHeaders({ "X-API-KEY": options.params?.["X-API-KEY"] ?? undefined }), - HttpClientRequest.bodyUnsafeJson(options.payload), - onRequest(["2xx"], {"400":"StakeKitErrorDto","401":"StakeKitErrorDto","404":"StakeKitErrorDto","408":"StakeKitErrorDto","412":"StakeKitErrorDto","429":"StakeKitErrorDto","500":"StakeKitErrorDto","501":"StakeKitErrorDto","503":"StakeKitErrorDto"}) ) } } @@ -912,14 +857,6 @@ readonly "TransactionsControllerSubmitTransaction": (transactionId: string, opti * Get the health status of the perps API with current timestamp */ readonly "HealthControllerHealth": () => Effect.Effect - /** -* Returns the token prices for a specific list of tokens -*/ -readonly "TokenControllerGetTokenPrices": (options: { readonly params?: TokenControllerGetTokenPricesParams | undefined; readonly payload: PriceRequestDto }) => Effect.Effect | SKClientError<"StakeKitErrorDto", StakeKitErrorDto> | SKClientError<"StakeKitErrorDto", StakeKitErrorDto> | SKClientError<"StakeKitErrorDto", StakeKitErrorDto> | SKClientError<"StakeKitErrorDto", StakeKitErrorDto> | SKClientError<"StakeKitErrorDto", StakeKitErrorDto> | SKClientError<"StakeKitErrorDto", StakeKitErrorDto> | SKClientError<"StakeKitErrorDto", StakeKitErrorDto> | SKClientError<"StakeKitErrorDto", StakeKitErrorDto>> - /** -* Returns the balances for specific addresses and token addresses -*/ -readonly "TokenControllerGetTokenBalances": (options: { readonly params?: TokenControllerGetTokenBalancesParams | undefined; readonly payload: BalancesRequestDto }) => Effect.Effect | SKClientError<"StakeKitErrorDto", StakeKitErrorDto> | SKClientError<"StakeKitErrorDto", StakeKitErrorDto> | SKClientError<"StakeKitErrorDto", StakeKitErrorDto> | SKClientError<"StakeKitErrorDto", StakeKitErrorDto> | SKClientError<"StakeKitErrorDto", StakeKitErrorDto> | SKClientError<"StakeKitErrorDto", StakeKitErrorDto> | SKClientError<"StakeKitErrorDto", StakeKitErrorDto> | SKClientError<"StakeKitErrorDto", StakeKitErrorDto>> } export interface SKClientError { diff --git a/src/services/api-client/index.ts b/packages/common/src/services/api-client/index.ts similarity index 94% rename from src/services/api-client/index.ts rename to packages/common/src/services/api-client/index.ts index 3f0b9d3..6accf89 100644 --- a/src/services/api-client/index.ts +++ b/packages/common/src/services/api-client/index.ts @@ -1,8 +1,8 @@ import { HttpClient, HttpClientRequest } from "@effect/platform"; import { Effect, Schema } from "effect"; import { toast } from "sonner"; -import { ConfigService } from "@/services/config"; -import { HttpClientService } from "@/services/http-client"; +import { ConfigService } from "../config"; +import { HttpClientService } from "../http-client"; import * as ApiClientFactory from "./client-factory"; export class ApiClientService extends Effect.Service()( diff --git a/src/services/config.ts b/packages/common/src/services/config.ts similarity index 97% rename from src/services/config.ts rename to packages/common/src/services/config.ts index 651749d..7fd21da 100644 --- a/src/services/config.ts +++ b/packages/common/src/services/config.ts @@ -31,7 +31,6 @@ export class ConfigService extends Effect.Service()( }; }).pipe( Effect.withConfigProvider(ConfigProvider.fromJson(import.meta.env)), - Effect.orDie, ), }, ) {} diff --git a/src/services/constants.ts b/packages/common/src/services/constants.ts similarity index 100% rename from src/services/constants.ts rename to packages/common/src/services/constants.ts diff --git a/src/services/http-client/index.tsx b/packages/common/src/services/http-client/index.ts similarity index 100% rename from src/services/http-client/index.tsx rename to packages/common/src/services/http-client/index.ts diff --git a/packages/common/src/services/index.ts b/packages/common/src/services/index.ts new file mode 100644 index 0000000..5b34f1b --- /dev/null +++ b/packages/common/src/services/index.ts @@ -0,0 +1,12 @@ +export * from "./api-client"; +export * as ApiSchemas from "./api-client/api-schemas"; +// export type * from "./api-client/client-factory"; +export type * as ApiTypes from "./api-client/client-factory"; +export * from "./config"; +export * from "./constants"; +export * from "./http-client"; +export * from "./runtime"; +export * from "./wallet/browser-signer"; +export * from "./wallet/ledger-signer"; +export * from "./wallet/signer"; +export * from "./wallet/wallet-service"; diff --git a/src/services/runtime.ts b/packages/common/src/services/runtime.ts similarity index 68% rename from src/services/runtime.ts rename to packages/common/src/services/runtime.ts index fe41631..b90a64e 100644 --- a/src/services/runtime.ts +++ b/packages/common/src/services/runtime.ts @@ -1,12 +1,12 @@ import { Atom, Registry } from "@effect-atom/atom-react"; import { Cause, Effect, Layer, Logger } from "effect"; -import { ApiClientService } from "@/services/api-client"; -import { ConfigService } from "@/services/config"; -import { HttpClientService } from "@/services/http-client"; -import { BrowserSignerLayer } from "@/services/wallet/browser-signer"; -import { LedgerSignerLayer } from "@/services/wallet/ledger-signer"; -import { isLedgerDappBrowserProvider } from "@/services/wallet/ledger-signer/utils"; -import { WalletService } from "@/services/wallet/wallet-service"; +import { ApiClientService } from "./api-client"; +import { ConfigService } from "./config"; +import { HttpClientService } from "./http-client"; +import { BrowserSignerLayer } from "./wallet/browser-signer"; +import { LedgerSignerLayer } from "./wallet/ledger-signer"; +import { isLedgerDappBrowserProvider } from "./wallet/ledger-signer/utils"; +import { WalletService } from "./wallet/wallet-service"; const Signer = isLedgerDappBrowserProvider ? LedgerSignerLayer.pipe(Layer.orDie) diff --git a/src/services/wallet/browser-signer.ts b/packages/common/src/services/wallet/browser-signer.ts similarity index 96% rename from src/services/wallet/browser-signer.ts rename to packages/common/src/services/wallet/browser-signer.ts index 905c56b..9bc0dd6 100644 --- a/src/services/wallet/browser-signer.ts +++ b/packages/common/src/services/wallet/browser-signer.ts @@ -21,7 +21,7 @@ import { switchConnection, switchChain as wagmiSwitchChain, } from "wagmi/actions"; -import type { SupportedSKChains } from "@/domain/chains"; +import type { SupportedSKChains } from "../../domain/chains"; import { type AccountsState, type BrowserWalletAccount, @@ -29,14 +29,14 @@ import { SignTransactionError, SwitchAccountError, SwitchChainError, -} from "@/domain/signer"; +} from "../../domain/signer"; import { EIP712Tx, type Transaction, TransactionHash, -} from "@/domain/transactions"; -import { ConfigService } from "@/services/config"; -import { SignerService } from "@/services/wallet/signer"; +} from "../../domain/transactions"; +import { ConfigService } from "../config"; +import { SignerService } from "./signer"; const hyperLiquidL1 = defineChain({ id: 1337, diff --git a/src/services/wallet/ledger-signer/index.ts b/packages/common/src/services/wallet/ledger-signer/index.ts similarity index 94% rename from src/services/wallet/ledger-signer/index.ts rename to packages/common/src/services/wallet/ledger-signer/index.ts index 30c96d8..f204ee0 100644 --- a/src/services/wallet/ledger-signer/index.ts +++ b/packages/common/src/services/wallet/ledger-signer/index.ts @@ -10,28 +10,28 @@ import { Schema, SubscriptionRef, } from "effect"; -import { evmChainsMap } from "@/domain/chains/evm"; -import type { SupportedLedgerLiveFamilies } from "@/domain/chains/ledger"; +import { evmChainsMap } from "../../../domain/chains/evm"; +import type { SupportedLedgerLiveFamilies } from "../../../domain/chains/ledger"; import { type AccountsState, type LedgerWalletAccount, makeLedgerWalletAccount, SignTransactionError, SwitchAccountError, -} from "@/domain/signer"; +} from "../../../domain/signer"; import { EIP712Tx, EvmTx, type Transaction, TransactionHash, -} from "@/domain/transactions"; +} from "../../../domain/transactions"; +import { SignerService } from "../signer"; import { getFilteredSupportedLedgerFamiliesWithCurrency, getLedgerAccounts, getLedgerCurrencies, NoAccountsFoundError, -} from "@/services/wallet/ledger-signer/utils"; -import { SignerService } from "@/services/wallet/signer"; +} from "./utils"; export const LedgerSignerLayer = Effect.gen(function* () { const transport = new WindowMessageTransport(); diff --git a/src/services/wallet/ledger-signer/utils.ts b/packages/common/src/services/wallet/ledger-signer/utils.ts similarity index 93% rename from src/services/wallet/ledger-signer/utils.ts rename to packages/common/src/services/wallet/ledger-signer/utils.ts index 50f0f01..fa6bfcd 100644 --- a/src/services/wallet/ledger-signer/utils.ts +++ b/packages/common/src/services/wallet/ledger-signer/utils.ts @@ -6,12 +6,12 @@ import type { WalletAPIClient, } from "@ledgerhq/wallet-api-client"; import { Data, Effect, Option, Record } from "effect"; -import type { SupportedSKChains } from "@/domain/chains"; -import type { EvmChainsMap } from "@/domain/chains/evm"; +import type { SupportedSKChains } from "../../../domain/chains"; +import type { EvmChainsMap } from "../../../domain/chains/evm"; import { type SupportedLedgerLiveFamilies, supportedLedgerFamiliesWithCurrency, -} from "@/domain/chains/ledger"; +} from "../../../domain/chains/ledger"; export const getFilteredSupportedLedgerFamiliesWithCurrency = ({ accounts, @@ -67,7 +67,11 @@ export const getFilteredSupportedLedgerFamiliesWithCurrency = ({ type SubItemKey = keyof typeof subItem; const subItemMap = Object.keys(subItem).reduce((acc, subKey) => { - acc.set(subKey as SubItemKey, subItem[subKey as keyof typeof subItem]); + const val = Record.get(subItem, subKey).pipe(Option.getOrNull); + + if (!val) return acc; + + acc.set(subKey as SubItemKey, val); return acc; }, new Map()); diff --git a/src/services/wallet/signer.ts b/packages/common/src/services/wallet/signer.ts similarity index 75% rename from src/services/wallet/signer.ts rename to packages/common/src/services/wallet/signer.ts index b616e39..e178c37 100644 --- a/src/services/wallet/signer.ts +++ b/packages/common/src/services/wallet/signer.ts @@ -1,5 +1,5 @@ import { Context } from "effect"; -import type { Signer } from "@/domain/signer"; +import type { Signer } from "../../domain/signer"; export class SignerService extends Context.Tag( "perps/services/wallet/signer/SignerService", diff --git a/src/services/wallet/wallet-service.ts b/packages/common/src/services/wallet/wallet-service.ts similarity index 97% rename from src/services/wallet/wallet-service.ts rename to packages/common/src/services/wallet/wallet-service.ts index 4d46f2a..d377193 100644 --- a/src/services/wallet/wallet-service.ts +++ b/packages/common/src/services/wallet/wallet-service.ts @@ -9,17 +9,17 @@ import { Stream, SubscriptionRef, } from "effect"; -import type { BrowserSigner, LedgerSigner } from "@/domain/signer"; -import { Transaction } from "@/domain/transactions"; +import type { BrowserSigner, LedgerSigner } from "../../domain/signer"; +import { Transaction } from "../../domain/transactions"; import { type SignTransactionsState, TransactionFailedError, TransactionNotConfirmedError, type Wallet, -} from "@/domain/wallet"; -import { ApiClientService } from "@/services/api-client"; -import type { ActionDto } from "@/services/api-client/api-schemas"; -import { SignerService } from "@/services/wallet/signer"; +} from "../../domain/wallet"; +import { ApiClientService } from "../api-client"; +import type { ActionDto } from "../api-client/api-schemas"; +import { SignerService } from "./signer"; export class WalletService extends Effect.Service()( "perps/services/wallet-service/WalletService", diff --git a/packages/common/src/styles/base.css b/packages/common/src/styles/base.css new file mode 100644 index 0000000..a76d29a --- /dev/null +++ b/packages/common/src/styles/base.css @@ -0,0 +1,24 @@ +html { + interpolate-size: allow-keywords; +} + +body { + @apply m-0; + font-family: var(--font-family); + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +code { + font-family: + source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace; +} + +@layer base { + * { + @apply border-border outline-ring/50; + } + body { + @apply bg-background text-foreground; + } +} diff --git a/packages/common/src/styles/index.css b/packages/common/src/styles/index.css new file mode 100644 index 0000000..1d0eae3 --- /dev/null +++ b/packages/common/src/styles/index.css @@ -0,0 +1,6 @@ +@import "tailwindcss"; +@import "tw-animate-css"; +@import "./theme.css"; +@import "./base.css"; + +@custom-variant dark (&:is(.dark *)); diff --git a/packages/common/src/styles/theme.css b/packages/common/src/styles/theme.css new file mode 100644 index 0000000..2c8839d --- /dev/null +++ b/packages/common/src/styles/theme.css @@ -0,0 +1,97 @@ +:root { + --font-family: + -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", + "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; + --background: oklch(1 0 0); + --foreground: oklch(0.141 0.005 285.823); + --card: oklch(1 0 0); + --primary: oklch(0.21 0.006 285.885); + --primary-foreground: oklch(0.985 0 0); + --secondary: oklch(0.967 0.001 286.375); + --secondary-foreground: oklch(0.21 0.006 285.885); + --muted: oklch(0.967 0.001 286.375); + --muted-foreground: oklch(0.552 0.016 285.938); + --accent: oklch(0.967 0.001 286.375); + --destructive: oklch(0.577 0.245 27.325); + --border: oklch(0.92 0.004 286.32); + --input: oklch(0.92 0.004 286.32); + --ring: oklch(0.871 0.006 286.286); + --radius: 0.625rem; + + --gray-1: #f6f7f999; + --gray-2: #999999; + --gray-3: #ffffff0d; + --gray-4: #ffffff40; + --gray-5: #ffffff2e; + + --surface-1: #131517; + --surface-2: #121314; + --surface-3: #090909; + + --accent-green: #34c759; + --accent-red: #ff383c; +} + +.dark { + --background: #000000b2; + --foreground: oklch(0.985 0 0); + --card: oklch(0.141 0.005 285.823); + --primary: oklch(0.985 0 0); + --primary-foreground: oklch(0.21 0.006 285.885); + --secondary: oklch(0.274 0.006 286.033); + --secondary-foreground: oklch(0.985 0 0); + --muted: oklch(0.274 0.006 286.033); + --muted-foreground: oklch(0.705 0.015 286.067); + --accent: oklch(0.274 0.006 286.033); + --destructive: oklch(0.396 0.141 25.723); + --border: oklch(0.274 0.006 286.033); + --input: oklch(0.274 0.006 286.033); + --ring: oklch(0.442 0.017 285.786); + + --gray-1: #f6f7f999; + --gray-2: #999999; + --gray-3: #ffffff0d; + --gray-4: #ffffff40; + --gray-5: #ffffff2e; + + --surface-1: #131517; + --surface-2: #121314; + --surface-3: #090909; + + --accent-green: #34c759; + --accent-red: #ff383c; +} + +@theme inline { + --color-background: var(--background); + --color-foreground: var(--foreground); + --color-card: var(--card); + --color-primary: var(--primary); + --color-primary-foreground: var(--primary-foreground); + --color-secondary: var(--secondary); + --color-secondary-foreground: var(--secondary-foreground); + --color-muted: var(--muted); + --color-muted-foreground: var(--muted-foreground); + --color-accent: var(--accent); + --color-destructive: var(--destructive); + --color-border: var(--border); + --color-input: var(--input); + --color-ring: var(--ring); + --radius-sm: calc(var(--radius) - 4px); + --radius-md: calc(var(--radius) - 2px); + --radius-lg: var(--radius); + --radius-xl: calc(var(--radius) + 4px); + + --color-gray-1: var(--gray-1); + --color-gray-2: var(--gray-2); + --color-gray-3: var(--gray-3); + --color-gray-4: var(--gray-4); + --color-gray-5: var(--gray-5); + + --color-surface-1: var(--surface-1); + --color-surface-2: var(--surface-2); + --color-surface-3: var(--surface-3); + + --color-accent-green: var(--accent-green); + --color-accent-red: var(--accent-red); +} diff --git a/vite.config.ts b/packages/common/src/vite.config.ts similarity index 60% rename from vite.config.ts rename to packages/common/src/vite.config.ts index 586af8b..8c6e592 100644 --- a/vite.config.ts +++ b/packages/common/src/vite.config.ts @@ -1,10 +1,8 @@ -import { fileURLToPath, URL } from "node:url"; import tailwindcss from "@tailwindcss/vite"; -import { devtools } from "@tanstack/devtools-vite"; import { tanstackRouter } from "@tanstack/router-plugin/vite"; import viteReact from "@vitejs/plugin-react"; import { playwright } from "@vitest/browser-playwright"; -import { defineConfig } from "vite"; +import type { UserConfig } from "vite"; import { nodePolyfills } from "vite-plugin-node-polyfills"; import type { InlineConfig } from "vitest/node"; @@ -14,27 +12,22 @@ declare module "vite" { } } -// https://vitejs.dev/config/ -export default defineConfig({ - plugins: [ - devtools(), - tanstackRouter({ - target: "react", - autoCodeSplitting: true, - }), - viteReact({ - babel: { - plugins: ["babel-plugin-react-compiler"], - }, - }), - tailwindcss(), - nodePolyfills({ include: ["buffer"] }), - ], - resolve: { - alias: { - "@": fileURLToPath(new URL("./src", import.meta.url)), +export const commonPlugins = { + tanstackRouter: tanstackRouter({ + target: "react", + autoCodeSplitting: true, + }), + viteReact: viteReact({ + babel: { + plugins: ["babel-plugin-react-compiler"], }, - }, + }), + tailwindcss: tailwindcss(), + nodePolyfills: nodePolyfills({ include: ["buffer"] }), +}; + +export const commonViteConfig: UserConfig = { + plugins: Object.values(commonPlugins), test: { browser: { screenshotFailures: false, @@ -53,4 +46,4 @@ export default defineConfig({ "vite-plugin-node-polyfills/shims/process", ], }, -}); +}; diff --git a/tests/components/leverage-dialog.test.tsx b/packages/common/tests/components/leverage-dialog.test.tsx similarity index 99% rename from tests/components/leverage-dialog.test.tsx rename to packages/common/tests/components/leverage-dialog.test.tsx index e6bc2f1..23f6b61 100644 --- a/tests/components/leverage-dialog.test.tsx +++ b/packages/common/tests/components/leverage-dialog.test.tsx @@ -4,7 +4,7 @@ import { render } from "vitest-browser-react"; import { LeverageDialog, LeverageDialogContent, -} from "@/components/modules/Order/Overview/leverage-dialog"; +} from "../../src/components/molecules/leverage-dialog"; import { TestWrapper } from "./wrapper"; const defaultProps = { diff --git a/tests/components/limit-price-dialog.test.tsx b/packages/common/tests/components/limit-price-dialog.test.tsx similarity index 99% rename from tests/components/limit-price-dialog.test.tsx rename to packages/common/tests/components/limit-price-dialog.test.tsx index ceb9334..bed8f75 100644 --- a/tests/components/limit-price-dialog.test.tsx +++ b/packages/common/tests/components/limit-price-dialog.test.tsx @@ -1,7 +1,7 @@ import { beforeEach, describe, expect, test, vi } from "vitest"; import { userEvent } from "vitest/browser"; import { render } from "vitest-browser-react"; -import { LimitPriceDialog } from "@/components/modules/Order/Overview/limit-price-dialog"; +import { LimitPriceDialog } from "../../src/components/molecules/limit-price-dialog"; import { TestWrapper } from "./wrapper"; const defaultProps = { diff --git a/tests/components/order-type-dialog.test.tsx b/packages/common/tests/components/order-type-dialog.test.tsx similarity index 99% rename from tests/components/order-type-dialog.test.tsx rename to packages/common/tests/components/order-type-dialog.test.tsx index ba08cc0..5197288 100644 --- a/tests/components/order-type-dialog.test.tsx +++ b/packages/common/tests/components/order-type-dialog.test.tsx @@ -4,7 +4,7 @@ import { render } from "vitest-browser-react"; import { ORDER_TYPE_OPTIONS, OrderTypeDialog, -} from "@/components/modules/Order/Overview/order-type-dialog"; +} from "../../src/components/molecules/order-type-dialog"; import { TestWrapper } from "./wrapper"; const defaultProps = { diff --git a/tests/components/tp-sl-dialog.test.tsx b/packages/common/tests/components/tp-sl-dialog.test.tsx similarity index 99% rename from tests/components/tp-sl-dialog.test.tsx rename to packages/common/tests/components/tp-sl-dialog.test.tsx index a79e7b6..3452a20 100644 --- a/tests/components/tp-sl-dialog.test.tsx +++ b/packages/common/tests/components/tp-sl-dialog.test.tsx @@ -2,10 +2,10 @@ import { beforeEach, describe, expect, test, vi } from "vitest"; import { userEvent } from "vitest/browser"; import { render } from "vitest-browser-react"; import { - getTPOrSLConfigurationFromPosition, TPOrSLDialog, type TPOrSLSettings, -} from "@/components/molecules/tp-sl-dialog"; +} from "../../src/components/molecules/tp-sl-dialog"; +import { getTPOrSLConfigurationFromPosition } from "../../src/lib/math"; import { TestWrapper } from "./wrapper"; const defaultSettings: TPOrSLSettings = { diff --git a/tests/components/wrapper.tsx b/packages/common/tests/components/wrapper.tsx similarity index 56% rename from tests/components/wrapper.tsx rename to packages/common/tests/components/wrapper.tsx index f2e12a0..bf4ea7c 100644 --- a/tests/components/wrapper.tsx +++ b/packages/common/tests/components/wrapper.tsx @@ -1,6 +1,6 @@ -import "../../src/styles.css"; -import { Toaster } from "@/components/ui/toaster"; -import { RootContainerProvider } from "@/context/root-container"; +import { RootContainerProvider } from "../../src/context/root-container"; +import "../../src/styles/index.css"; +import { Toaster } from "sonner"; export const TestWrapper = ({ children }: { children: React.ReactNode }) => { return ( diff --git a/packages/common/tsconfig.json b/packages/common/tsconfig.json new file mode 100644 index 0000000..ac4d417 --- /dev/null +++ b/packages/common/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "declaration": true, + "noEmit": false, + "outDir": "./dist", + "rootDir": "." + }, + "include": ["src", "src/**/*.json", "scripts", "tests"] +} diff --git a/packages/common/vite.config.ts b/packages/common/vite.config.ts new file mode 100644 index 0000000..f961b21 --- /dev/null +++ b/packages/common/vite.config.ts @@ -0,0 +1,12 @@ +import { defineConfig } from "vite"; +import { commonPlugins, commonViteConfig } from "./src/vite.config"; + +export default defineConfig({ + plugins: [ + commonPlugins.viteReact, + commonPlugins.tailwindcss, + commonPlugins.nodePolyfills, + ], + test: commonViteConfig.test, + optimizeDeps: commonViteConfig.optimizeDeps, +}); diff --git a/packages/dashboard/.env.example b/packages/dashboard/.env.example new file mode 100644 index 0000000..6dc0341 --- /dev/null +++ b/packages/dashboard/.env.example @@ -0,0 +1,12 @@ +# Perps API Configuration +VITE_PERPS_BASE_URL= +VITE_PERPS_API_KEY= + +# Reown (WalletConnect) - Get your project ID at https://cloud.reown.com +VITE_REOWN_PROJECT_ID= + +# Moralis API - Get your API key at https://moralis.io +VITE_MORALIS_API_KEY= + +# Optional: Perps OpenAPI docs URL (for code generation) +# VITE_PERPS_DOCS_URL= diff --git a/packages/dashboard/index.html b/packages/dashboard/index.html new file mode 100644 index 0000000..a8f4c88 --- /dev/null +++ b/packages/dashboard/index.html @@ -0,0 +1,19 @@ + + + + + + + + + + Yield.xyz - Perps Dashboard + + +
+ + + diff --git a/packages/dashboard/package.json b/packages/dashboard/package.json new file mode 100644 index 0000000..35eb955 --- /dev/null +++ b/packages/dashboard/package.json @@ -0,0 +1,66 @@ +{ + "name": "@yieldxyz/perps-dashboard", + "type": "module", + "scripts": { + "dev": "vite --port 3001", + "build": "vite build && tsc -b", + "preview": "vite preview", + "lint": "biome check . && tsc -b", + "format": "biome format --write .", + "generate-routes": "tsr generate" + }, + "dependencies": { + "@yieldxyz/perps-common": "workspace:*", + "@base-ui/react": "catalog:", + "@effect-atom/atom-react": "catalog:", + "@effect/experimental": "^0.58.0", + "@effect/platform": "catalog:", + "@effect/platform-node": "catalog:", + "@ledgerhq/wallet-api-client": "catalog:", + "@lucas-barake/effect-form-react": "catalog:", + "@reown/appkit": "catalog:", + "@reown/appkit-adapter-wagmi": "catalog:", + "@stakekit/common": "catalog:", + "@tailwindcss/vite": "catalog:", + "@tanstack/react-devtools": "catalog:", + "@tanstack/react-query": "catalog:", + "@tanstack/react-router": "catalog:", + "@tanstack/react-router-devtools": "catalog:", + "@tanstack/react-virtual": "catalog:", + "class-variance-authority": "catalog:", + "clsx": "catalog:", + "effect": "catalog:", + "lucide-react": "catalog:", + "react": "catalog:", + "react-dom": "catalog:", + "sonner": "catalog:", + "tailwind-merge": "catalog:", + "tailwindcss": "catalog:", + "tw-animate-css": "catalog:", + "viem": "catalog:", + "wagmi": "catalog:" + }, + "devDependencies": { + "@tanstack/devtools-vite": "catalog:", + "@tanstack/router-cli": "catalog:", + "@testing-library/dom": "catalog:", + "@testing-library/react": "catalog:", + "@tim-smart/openapi-gen": "catalog:", + "@types/node": "catalog:", + "@types/react": "catalog:", + "@types/react-dom": "catalog:", + "@vite-pwa/assets-generator": "catalog:", + "@vitejs/plugin-react": "catalog:", + "@vitest/browser-playwright": "catalog:", + "babel-plugin-react-compiler": "catalog:", + "jsdom": "catalog:", + "openapi-filter": "catalog:", + "tsx": "catalog:", + "typescript": "catalog:", + "vite": "catalog:", + "vite-plugin-node-polyfills": "catalog:", + "vitest": "catalog:", + "vitest-browser-react": "catalog:", + "@tanstack/router-plugin": "catalog:" + } +} diff --git a/public/apple-touch-icon-180x180.png b/packages/dashboard/public/apple-touch-icon-180x180.png similarity index 100% rename from public/apple-touch-icon-180x180.png rename to packages/dashboard/public/apple-touch-icon-180x180.png diff --git a/public/favicon.ico b/packages/dashboard/public/favicon.ico similarity index 100% rename from public/favicon.ico rename to packages/dashboard/public/favicon.ico diff --git a/public/logo-192x192.png b/packages/dashboard/public/logo-192x192.png similarity index 100% rename from public/logo-192x192.png rename to packages/dashboard/public/logo-192x192.png diff --git a/public/logo-512x512.png b/packages/dashboard/public/logo-512x512.png similarity index 100% rename from public/logo-512x512.png rename to packages/dashboard/public/logo-512x512.png diff --git a/public/logo-64x64.png b/packages/dashboard/public/logo-64x64.png similarity index 100% rename from public/logo-64x64.png rename to packages/dashboard/public/logo-64x64.png diff --git a/public/maskable-icon-512x512.png b/packages/dashboard/public/maskable-icon-512x512.png similarity index 100% rename from public/maskable-icon-512x512.png rename to packages/dashboard/public/maskable-icon-512x512.png diff --git a/public/yield_xyz.png b/packages/dashboard/public/yield_xyz.png similarity index 100% rename from public/yield_xyz.png rename to packages/dashboard/public/yield_xyz.png diff --git a/packages/dashboard/src/app.tsx b/packages/dashboard/src/app.tsx new file mode 100644 index 0000000..b88372c --- /dev/null +++ b/packages/dashboard/src/app.tsx @@ -0,0 +1,44 @@ +import "./styles.css"; +import { createRouter, RouterProvider } from "@tanstack/react-router"; +import { Providers, useRootContainer } from "@yieldxyz/perps-common/context"; +import { Preload } from "./components/modules/root/Preload"; +import { SignTransactionsDialog } from "./components/modules/trade/order-form/sign-dialog"; +import { routeTree } from "./routeTree.gen"; + +const router = createRouter({ + routeTree, + context: {}, + defaultPreload: "intent", + scrollRestoration: true, + defaultStructuralSharing: true, + defaultPreloadStaleTime: 0, +}); + +declare module "@tanstack/react-router" { + interface Register { + router: typeof router; + } +} + +const App = () => { + const rootContainer = useRootContainer(); + + return ( +
+ + +
+ ); +}; + +export const Dashboard = () => { + return ( + + + + + ); +}; diff --git a/packages/dashboard/src/atoms/selected-market-atom.ts b/packages/dashboard/src/atoms/selected-market-atom.ts new file mode 100644 index 0000000..8271094 --- /dev/null +++ b/packages/dashboard/src/atoms/selected-market-atom.ts @@ -0,0 +1,22 @@ +import { Atom, type AtomRef, Result } from "@effect-atom/atom-react"; +import { MarketNotFoundError, marketsAtom } from "@yieldxyz/perps-common/atoms"; +import { type ApiTypes, runtimeAtom } from "@yieldxyz/perps-common/services"; +import { Array as _Array, Effect, Option, Record } from "effect"; + +const initMarketAtom = runtimeAtom.atom((ctx) => + ctx.resultOnce(marketsAtom).pipe( + Effect.andThen((markets) => + Record.findFirst(markets, (m) => m.value.baseAsset.symbol === "BTC").pipe( + Option.map((v) => v[1]), + Option.orElse(() => _Array.head(Record.values(markets))), + ), + ), + Effect.catchTag("NoSuchElementException", () => new MarketNotFoundError()), + ), +); + +export const selectedMarketAtom = Atom.writable( + (ctx) => ctx.get(initMarketAtom), + (ctx, value: AtomRef.AtomRef) => + ctx.setSelf(Result.success(value)), +); diff --git a/packages/dashboard/src/components/atoms/logo.tsx b/packages/dashboard/src/components/atoms/logo.tsx new file mode 100644 index 0000000..9610a08 --- /dev/null +++ b/packages/dashboard/src/components/atoms/logo.tsx @@ -0,0 +1,28 @@ +export const Logo = () => { + return ( + + Yield.xyz Logo + + + + + + + + + + + ); +}; diff --git a/packages/dashboard/src/components/modules/root/Preload.tsx b/packages/dashboard/src/components/modules/root/Preload.tsx new file mode 100644 index 0000000..654325d --- /dev/null +++ b/packages/dashboard/src/components/modules/root/Preload.tsx @@ -0,0 +1,45 @@ +import { Result, useAtomMount, useAtomValue } from "@effect-atom/atom-react"; +import { + marketsAtom, + moralisTokenBalancesAtom, + ordersAtom, + positionsAtom, + providersAtom, + providersBalancesAtom, + refreshMarketsAtom, + walletAtom, +} from "@yieldxyz/perps-common/atoms"; +import { + isWalletConnected, + type WalletConnected, +} from "@yieldxyz/perps-common/domain"; +import { TRADING_VIEW_WIDGET_SCRIPT_URL } from "@yieldxyz/perps-common/services"; +import { preload } from "react-dom"; + +const PreloadWalletConnectedAtoms = ({ + wallet, +}: { + wallet: WalletConnected; +}) => { + useAtomMount(moralisTokenBalancesAtom(wallet.currentAccount.address)); + useAtomMount(providersBalancesAtom(wallet.currentAccount.address)); + useAtomMount(positionsAtom(wallet.currentAccount.address)); + useAtomMount(ordersAtom(wallet.currentAccount.address)); + + return null; +}; + +export const Preload = () => { + preload(TRADING_VIEW_WIDGET_SCRIPT_URL, { as: "script" }); + + const wallet = useAtomValue(walletAtom); + useAtomMount(providersAtom); + useAtomMount(marketsAtom); + useAtomMount(refreshMarketsAtom); + + if (Result.isSuccess(wallet) && isWalletConnected(wallet.value)) { + return ; + } + + return null; +}; diff --git a/packages/dashboard/src/components/modules/trade/chart.tsx b/packages/dashboard/src/components/modules/trade/chart.tsx new file mode 100644 index 0000000..ec9e352 --- /dev/null +++ b/packages/dashboard/src/components/modules/trade/chart.tsx @@ -0,0 +1,59 @@ +import { + type AtomRef, + Result, + useAtomRef, + useAtomValue, +} from "@effect-atom/atom-react"; +import { Chart as ChartView, Text } from "@yieldxyz/perps-common/components"; +import type { ApiTypes } from "@yieldxyz/perps-common/services"; +import { TriangleAlertIcon } from "lucide-react"; +import { selectedMarketAtom } from "../../../atoms/selected-market-atom"; + +const ChartLoading = () => ( +
+
+
+ + Loading chart... + +
+
+); + +const ChartError = ({ message }: { message: string }) => ( +
+
+
+ + {message} +
+
+
+); + +const ChartContent = ({ + marketRef, +}: { + marketRef: AtomRef.AtomRef; +}) => { + const market = useAtomRef(marketRef); + + return ; +}; + +export const Chart = () => { + const selectedMarketResult = useAtomValue(selectedMarketAtom); + + return ( +
+ {Result.matchWithWaiting(selectedMarketResult, { + onWaiting: () => , + onSuccess: ({ value: selectedMarket }) => ( + + ), + onError: () => , + onDefect: () => , + })} +
+ ); +}; diff --git a/packages/dashboard/src/components/modules/trade/index.tsx b/packages/dashboard/src/components/modules/trade/index.tsx new file mode 100644 index 0000000..5b45f83 --- /dev/null +++ b/packages/dashboard/src/components/modules/trade/index.tsx @@ -0,0 +1,20 @@ +import { PositionsTable } from "../../molecules/positions"; +import { Chart } from "./chart"; +import { MarketInfoBar } from "./market-info"; +import { OrderForm } from "./order-form"; + +export function TradePage() { + return ( +
+
+ + + + + +
+ + +
+ ); +} diff --git a/packages/dashboard/src/components/modules/trade/market-info/bar-skeleton.tsx b/packages/dashboard/src/components/modules/trade/market-info/bar-skeleton.tsx new file mode 100644 index 0000000..1fe229b --- /dev/null +++ b/packages/dashboard/src/components/modules/trade/market-info/bar-skeleton.tsx @@ -0,0 +1,60 @@ +import { Skeleton } from "@yieldxyz/perps-common/components"; +import { cn } from "@yieldxyz/perps-common/lib"; + +export function MarketInfoBarSkeleton({ className }: { className?: string }) { + return ( +
+ {/* Asset Selector Skeleton */} +
+ + + + +
+ + {/* Divider */} +
+ + {/* Price Skeleton */} +
+ + +
+ + {/* 24H Change Skeleton */} +
+ + +
+ + {/* 24H Volume Skeleton */} +
+ + +
+ + {/* Open Interest Skeleton */} +
+ + +
+ + {/* Maker Fee Skeleton */} +
+ + +
+ + {/* Taker Fee Skeleton */} +
+ + +
+
+ ); +} diff --git a/packages/dashboard/src/components/modules/trade/market-info/index.tsx b/packages/dashboard/src/components/modules/trade/market-info/index.tsx new file mode 100644 index 0000000..44801ea --- /dev/null +++ b/packages/dashboard/src/components/modules/trade/market-info/index.tsx @@ -0,0 +1,174 @@ +import { + type AtomRef, + Result, + useAtomRef, + useAtomSet, + useAtomValue, +} from "@effect-atom/atom-react"; +import { Popover, Text, TokenIcon } from "@yieldxyz/perps-common/components"; +import { + cn, + formatAmount, + formatCompactUsdAmount, + formatPercentage, + formatRate, + getTokenLogo, +} from "@yieldxyz/perps-common/lib"; +import type { ApiTypes } from "@yieldxyz/perps-common/services"; +import { ChevronDown } from "lucide-react"; +import { useState } from "react"; +import { selectedMarketAtom } from "../../../../atoms/selected-market-atom"; +import { MarketInfoBarSkeleton } from "./bar-skeleton"; +import { MarketSelectorContent } from "./market-selector-popover"; + +interface MarketInfoBarProps { + className?: string; +} + +function MarketInfoBarContent({ + marketRef, + className, +}: { + marketRef: AtomRef.AtomRef; + className?: string; +}) { + const market = useAtomRef(marketRef); + const setSelectedMarket = useAtomSet(selectedMarketAtom); + const [isOpen, setIsOpen] = useState(false); + const isPositiveChange = market.priceChangePercent24h >= 0; + const logo = + market.baseAsset.logoURI ?? getTokenLogo(market.baseAsset.symbol); + + const handleMarketSelect = ( + marketRef: AtomRef.AtomRef, + ) => { + setSelectedMarket(marketRef); + setIsOpen(false); + }; + + return ( +
+ {/* Asset Selector */} + + +
+ + + {market.baseAsset.symbol} + +
+ + + Perp + +
+ + + + + + + +
+ + {/* Divider */} +
+ + {/* Price */} +
+ + Price + + + {formatAmount(market.markPrice)} + +
+ + {/* 24H Change */} +
+ + 24H Change + + + {isPositiveChange ? "+" : ""} + {formatAmount(market.priceChange24h)} / {isPositiveChange ? "+" : ""} + {formatPercentage(market.priceChangePercent24h)} + +
+ + {/* 24H Volume */} +
+ + 24H Volume + + + {formatCompactUsdAmount(market.volume24h)} USDC + +
+ + {/* Open Interest */} +
+ + Open Interest + + + {formatCompactUsdAmount(market.openInterest)} USDC + +
+ + {/* Maker Fee */} +
+ + Maker Fee + + + {market.makerFee ? formatRate(market.makerFee) : "-"} + +
+ + {/* Taker Fee */} +
+ + Taker Fee + + + {market.takerFee ? formatRate(market.takerFee) : "-"} + +
+
+ ); +} + +export function MarketInfoBar({ className }: MarketInfoBarProps) { + const marketResult = useAtomValue(selectedMarketAtom); + + if (Result.isInitial(marketResult) || Result.isWaiting(marketResult)) { + return ; + } + + if (!Result.isSuccess(marketResult)) { + return ; + } + + return ( + + ); +} diff --git a/packages/dashboard/src/components/modules/trade/market-info/market-selector-popover.tsx b/packages/dashboard/src/components/modules/trade/market-info/market-selector-popover.tsx new file mode 100644 index 0000000..577f5e2 --- /dev/null +++ b/packages/dashboard/src/components/modules/trade/market-info/market-selector-popover.tsx @@ -0,0 +1,248 @@ +import { + type AtomRef, + Result, + useAtomRef, + useAtomValue, +} from "@effect-atom/atom-react"; +import { useVirtualizer } from "@tanstack/react-virtual"; +import { marketsAtom } from "@yieldxyz/perps-common/atoms"; +import { Skeleton, Text, TokenIcon } from "@yieldxyz/perps-common/components"; +import { + cn, + formatAmount, + formatCompactUsdAmount, + formatPercentage, + formatRate, + getMaxLeverage, + getTokenLogo, +} from "@yieldxyz/perps-common/lib"; +import type { ApiTypes } from "@yieldxyz/perps-common/services"; +import { Array as _Array, Option, Record } from "effect"; +import { Search, X } from "lucide-react"; +import { useRef, useState } from "react"; + +interface MarketSelectorContentProps { + onSelect: (marketRef: AtomRef.AtomRef) => void; +} + +interface MarketRowProps { + marketRef: AtomRef.AtomRef; + onSelect: (marketRef: AtomRef.AtomRef) => void; +} + +function MarketRow({ marketRef, onSelect }: MarketRowProps) { + const market = useAtomRef(marketRef); + const isPositiveChange = market.priceChangePercent24h >= 0; + const isPositiveFunding = Number(market.fundingRate) >= 0; + const maxLeverage = getMaxLeverage(market.leverageRange); + const logo = getTokenLogo(market.baseAsset.symbol); + + return ( + + ); +} + +function MarketRowSkeleton() { + return ( +
+
+ + + +
+ + + + + +
+ ); +} + +export function MarketSelectorContent({ + onSelect, +}: MarketSelectorContentProps) { + const [searchQuery, setSearchQuery] = useState(""); + const parentRef = useRef(null); + + const markets = useAtomValue(marketsAtom); + + const isLoading = Result.isInitial(markets) || Result.isWaiting(markets); + + const marketData = markets.pipe( + Result.map(Record.values), + Result.map((v) => + searchQuery.trim() + ? v.filter((market) => + market.value.baseAsset.symbol + .toLowerCase() + .includes(searchQuery.toLowerCase()), + ) + : v, + ), + Result.getOrElse(() => []), + ); + + const rowVirtualizer = useVirtualizer({ + count: marketData.length, + getScrollElement: () => parentRef.current, + estimateSize: () => 46, + overscan: 5, + }); + + const hasNoResults = + marketData.length === 0 && + searchQuery.trim() !== "" && + !Result.isInitial(markets); + + return ( +
+ {/* Search input */} +
+
+ + setSearchQuery(e.target.value)} + placeholder="Search" + className="flex-1 bg-transparent border-none outline-none text-sm text-white placeholder:text-gray-2" + /> + {searchQuery && ( + + )} +
+
+ + {/* Table header */} +
+ Symbol + Last Price + 24H Change + 8H Funding + Volume + Open Interest +
+ + {/* Empty state */} + {hasNoResults ? ( +
+ + + No markets found + + + Try searching for a different symbol + +
+ ) : isLoading ? ( +
+ + + + + +
+ ) : ( + /* Market list with virtualization */ +
+
+ {rowVirtualizer.getVirtualItems().map((virtualItem) => { + const market = _Array + .get(marketData, virtualItem.index) + .pipe(Option.getOrThrow); + + return ( +
+ +
+ ); + })} +
+
+ )} +
+ ); +} diff --git a/packages/dashboard/src/components/modules/trade/order-form/index.tsx b/packages/dashboard/src/components/modules/trade/order-form/index.tsx new file mode 100644 index 0000000..8cf26d5 --- /dev/null +++ b/packages/dashboard/src/components/modules/trade/order-form/index.tsx @@ -0,0 +1,545 @@ +import { + type AtomRef, + Result, + useAtomRef, + useAtomValue, +} from "@effect-atom/atom-react"; +import { + LeverageRangesSchema, + orderFormAtom, + walletAtom, +} from "@yieldxyz/perps-common/atoms"; +import { + Button, + LeverageDialog, + LimitPriceDialog, + PercentageSlider, + Text, + TPOrSLDialog, +} from "@yieldxyz/perps-common/components"; +import { + isWalletConnected, + type WalletConnected, +} from "@yieldxyz/perps-common/domain"; +import { + useCurrentPosition, + useHandlePercentageChange, + useLeverage, + useLimitPrice, + useOrderCalculations, + useOrderFormSubmit, + useOrderPercentage, + useOrderSide, + useOrderType, + useProviderBalance, + useTPOrSLSettings, +} from "@yieldxyz/perps-common/hooks"; +import { + cn, + formatAmount, + formatTPOrSLSettings, + getMaxLeverage, + round, +} from "@yieldxyz/perps-common/lib"; +import type { ApiTypes } from "@yieldxyz/perps-common/services"; +import { Schema } from "effect"; +import { ChevronDown, Info } from "lucide-react"; +import { selectedMarketAtom } from "../../../../atoms/selected-market-atom"; + +interface OrderFormProps { + className?: string; +} + +export function OrderForm({ className }: OrderFormProps) { + const wallet = useAtomValue(walletAtom).pipe(Result.getOrElse(() => null)); + const marketResult = useAtomValue(selectedMarketAtom); + + if (!Result.isSuccess(marketResult)) { + return ; + } + + if (!isWalletConnected(wallet)) { + return ( + + ); + } + + return ( + + ); +} + +function OrderFormLoading({ className }: { className?: string }) { + return ( +
+ Loading market... +
+ ); +} + +function OrderFormDisconnected({ + className, + marketRef, +}: { + className?: string; + marketRef: AtomRef.AtomRef; +}) { + const market = useAtomRef(marketRef); + const { orderType, setOrderType } = useOrderType(); + const { orderSide, setOrderSide } = useOrderSide(); + + const leverageRanges = Schema.decodeSync(LeverageRangesSchema)( + market.leverageRange, + ); + const { leverage } = useLeverage(leverageRanges); + const { tpOrSLSettings } = useTPOrSLSettings(); + + const maxLeverage = getMaxLeverage(leverageRanges); + + return ( +
+ {/* Market/Limit Tabs */} + + +
+ {/* Buy/Sell Toggle */} + + + {/* Available to Trade & Current Position */} +
+
+ + Available to Trade + + + -- + +
+
+ + Current Position + + -- +
+
+ + {/* Amount Display */} +
+ + $0 + + + 0.000000 {market.baseAsset.symbol} + +
+ + {/* Percentage Slider (disabled) */} + {}} /> + + {/* Leverage */} + + + {/* Limit Price (when limit order) */} + {orderType === "limit" && ( + + )} + + {/* Advanced Orders */} + +
+ + {/* Order Details */} +
+ + + +
+ + {/* Connect Wallet Button */} +
+ +
+
+ ); +} + +function OrderFormContent({ + className, + wallet, + marketRef, +}: { + className?: string; + wallet: WalletConnected; + marketRef: AtomRef.AtomRef; +}) { + const market = useAtomRef(marketRef); + const leverageRanges = Schema.decodeSync(LeverageRangesSchema)( + market.leverageRange, + ); + + const { orderType, setOrderType } = useOrderType(); + const { orderSide, setOrderSide } = useOrderSide(); + const { setLeverage } = useLeverage(leverageRanges); + const { tpOrSLSettings, setTPOrSLSettings } = useTPOrSLSettings(); + const { limitPrice, setLimitPrice } = useLimitPrice(); + const { providerBalance } = useProviderBalance(wallet); + const { currentPosition } = useCurrentPosition(wallet, market.id); + + const { form: OrderFormComponent } = useAtomValue( + orderFormAtom(leverageRanges), + ); + + const { submit, submitResult } = useOrderFormSubmit(leverageRanges); + const { handlePercentageChange } = useHandlePercentageChange( + wallet, + leverageRanges, + ); + const { percentage } = useOrderPercentage(wallet, leverageRanges); + const calculations = useOrderCalculations(market, orderSide, leverageRanges); + + const maxLeverage = getMaxLeverage(leverageRanges); + const currentPrice = market.markPrice; + const symbol = market.baseAsset.symbol; + + const availableBalance = providerBalance?.availableBalance ?? 0; + + // Format current position display + const currentPositionDisplay = currentPosition + ? `${currentPosition.side === "long" ? "+" : "-"}${currentPosition.size} ${symbol}` + : "--"; + + const handleSubmit = () => { + submit({ wallet, market, side: orderSide }); + }; + + return ( +
+ {/* Market/Limit Tabs */} + + +
+ {/* Buy/Sell Toggle */} + + + {/* Available to Trade & Current Position */} +
+
+ + Available to Trade + + + {formatAmount(availableBalance)} + +
+
+ + Current Position + + + {currentPositionDisplay} + +
+
+ + {/* Amount Input */} + +
+ + + {round(calculations.cryptoAmount, 6).toString()} {symbol} + +
+
+ + {/* Percentage Slider */} + + + {/* Leverage */} + + + + + {/* Limit Price (when limit order) */} + {orderType === "limit" && ( + + + + )} + + {/* Advanced Orders (TP/SL) */} + + + +
+ + {/* Order Details */} +
+ + + +
+ + {/* Place Order Button */} +
+ +
+
+ ); +} + +// Shared Components + +function OrderTypeTabs({ + orderType, + setOrderType, +}: { + orderType: "market" | "limit"; + setOrderType: (type: "market" | "limit") => void; +}) { + return ( +
+ + +
+ ); +} + +function OrderSideToggle({ + orderSide, + setOrderSide, +}: { + orderSide: "long" | "short"; + setOrderSide: (side: "long" | "short") => void; +}) { + return ( +
+ + +
+ ); +} + +function SettingsRow({ + label, + value, + maxLeverage, +}: { + label: string; + value: string; + maxLeverage?: number; +}) { + return ( +
+
+ {label} + +
+
+ {value} + {maxLeverage && ( + / {maxLeverage}x + )} +
+
+ ); +} + +interface OrderDetailRowProps { + label: string; + value: string; + isLast?: boolean; +} + +function OrderDetailRow({ label, value, isLast }: OrderDetailRowProps) { + return ( +
+ + {label} + + {value} +
+ ); +} diff --git a/packages/dashboard/src/components/modules/trade/order-form/sign-dialog.tsx b/packages/dashboard/src/components/modules/trade/order-form/sign-dialog.tsx new file mode 100644 index 0000000..20fac08 --- /dev/null +++ b/packages/dashboard/src/components/modules/trade/order-form/sign-dialog.tsx @@ -0,0 +1,86 @@ +import { Result, useAtomSet, useAtomValue } from "@effect-atom/atom-react"; +import { + actionAtom, + signActionAtoms, + walletAtom, +} from "@yieldxyz/perps-common/atoms"; +import { + Dialog, + Skeleton, + TransactionProgress, +} from "@yieldxyz/perps-common/components"; +import { isWalletConnected } from "@yieldxyz/perps-common/domain"; + +export function SignTransactionsDialog() { + const wallet = useAtomValue(walletAtom).pipe(Result.getOrElse(() => null)); + const action = useAtomValue(actionAtom); + const setAction = useAtomSet(actionAtom); + + const isOpen = action !== null && isWalletConnected(wallet); + + const handleClose = () => { + setAction(null); + }; + + if (!isWalletConnected(wallet)) { + return null; + } + + const machineAtoms = signActionAtoms(wallet.signTransactions); + + return ( + !open && handleClose()}> + + + + + + Transaction Progress + + + + + + + + ); +} + +interface SignTransactionsContentProps { + machineAtoms: ReturnType; + onClose: () => void; +} + +function SignTransactionsContent({ + machineAtoms, + onClose, +}: SignTransactionsContentProps) { + const { machineStreamAtom, retryMachineAtom } = machineAtoms; + const state = useAtomValue(machineStreamAtom); + const retry = useAtomSet(retryMachineAtom); + + const result = Result.all({ state, retry }); + + if (Result.isFailure(result)) { + return ( +
+ +
+ ); + } + + if (Result.isSuccess(result)) { + return ( + + ); + } + + return ; +} diff --git a/packages/dashboard/src/components/molecules/header/deposit/deposit-dialog.tsx b/packages/dashboard/src/components/molecules/header/deposit/deposit-dialog.tsx new file mode 100644 index 0000000..d4f3fe3 --- /dev/null +++ b/packages/dashboard/src/components/molecules/header/deposit/deposit-dialog.tsx @@ -0,0 +1,362 @@ +import { Result, useAtomValue } from "@effect-atom/atom-react"; +import hyperliquidLogo from "@yieldxyz/perps-common/assets/hyperliquid.png"; +import { + providersAtom, + yieldApiNetworkToMoralisChain, +} from "@yieldxyz/perps-common/atoms"; +import { + Button, + Dialog, + Select, + Text, + TokenIcon, +} from "@yieldxyz/perps-common/components"; +import type { + WalletAccount, + WalletConnected, +} from "@yieldxyz/perps-common/domain"; +import { + useSelectedTokenBalance, + useTokenBalances, +} from "@yieldxyz/perps-common/hooks"; +import { + formatSnakeCase, + formatTokenAmount, + getNetworkLogo, +} from "@yieldxyz/perps-common/lib"; +import type { ApiSchemas } from "@yieldxyz/perps-common/services"; +import { Array as _Array, Option, Record } from "effect"; +import { + DepositForm, + useDepositForm, + useProviders, + useSelectedChain, +} from "./state"; + +interface DepositDialogProps { + wallet: WalletConnected; + open: boolean; + onOpenChange: (open: boolean) => void; +} + +export function DepositDialog({ + wallet, + open, + onOpenChange, +}: DepositDialogProps) { + return ( + + + + + + + Deposit funds + + + + + + + + ); +} + +interface DepositDialogContentProps { + wallet: WalletConnected; +} + +function DepositDialogContent({ wallet }: DepositDialogContentProps) { + const { submit, submitResult } = useDepositForm(); + + const handleSubmit = () => { + submit(); + }; + + return ( + +
+
+ {/* Provider Select */} + + + {/* Chain and Token Selects */} +
+
+ +
+
+ +
+
+ + {/* Amount Input */} + +
+ + {/* Deposit Button */} + +
+
+ ); +} + +function ProviderSelect() { + const providers = useAtomValue(providersAtom).pipe( + Result.getOrElse(() => [] as ReadonlyArray), + ); + const { selectedProvider, setSelectedProvider } = useProviders(); + + const items = providers.map((provider) => ({ + value: provider.id, + label: provider.name, + provider, + })); + + return ( +
+ + Select provider + + { + if (!value) return; + const provider = providers.find((p) => p.id === value); + if (provider) setSelectedProvider(provider); + }} + > + +
+ {selectedProvider?.name + + {selectedProvider?.name ?? "Select provider"} + +
+
+ + + + {items.map((item) => ( + + } + > + {item.label} + + ))} + + + +
+
+ ); +} + +interface ChainSelectProps { + walletAddress: WalletAccount["address"]; +} + +function ChainSelect({ walletAddress }: ChainSelectProps) { + const { selectedChain, setSelectedChain } = useSelectedChain(); + const { handleSelectTokenBalance } = useSelectedTokenBalance(walletAddress); + const { tokenBalances } = useTokenBalances(walletAddress); + + const chains = Record.keys(yieldApiNetworkToMoralisChain); + + const handleChainChange = (value: string | null) => { + if (!value) return; + const chain = value as keyof typeof yieldApiNetworkToMoralisChain; + setSelectedChain(chain); + // Select first token of the new chain + const chainTokens = tokenBalances[chain] ?? []; + const firstToken = _Array.head(chainTokens); + if (Option.isSome(firstToken)) { + handleSelectTokenBalance(firstToken.value); + } + }; + + return ( +
+ + Select chain + + + +
+ + + {formatSnakeCase(selectedChain)} + +
+
+ + + + {chains.map((chain) => ( + + } + > + {formatSnakeCase(chain)} + + ))} + + + +
+
+ ); +} + +interface TokenSelectProps { + walletAddress: WalletAccount["address"]; +} + +function TokenSelect({ walletAddress }: TokenSelectProps) { + const { selectedChain } = useSelectedChain(); + const { selectedTokenBalance, handleSelectTokenBalance } = + useSelectedTokenBalance(walletAddress); + const { tokenBalances } = useTokenBalances(walletAddress); + + const chainTokens = tokenBalances[selectedChain] ?? []; + + return ( +
+ + Select token + + { + if (!value) return; + const token = chainTokens.find( + (t) => `${t.token.network}-${t.token.address}` === value, + ); + if (token) handleSelectTokenBalance(token); + }} + > + +
+ {selectedTokenBalance?.token.logoURI && ( + + )} + + {selectedTokenBalance?.token.symbol ?? "Select token"} + +
+
+ + + + {chainTokens.map((tokenBalance) => ( + + ) : undefined + } + > +
+ {tokenBalance.token.symbol} + + {formatTokenAmount({ + amount: tokenBalance.amount, + symbol: tokenBalance.token.symbol, + })} + +
+
+ ))} +
+
+
+
+
+ ); +} + +interface AmountInputProps { + walletAddress: WalletAccount["address"]; +} + +function AmountInput({ walletAddress }: AmountInputProps) { + const { selectedTokenBalance } = useSelectedTokenBalance(walletAddress); + + const availableBalance = selectedTokenBalance + ? formatTokenAmount({ + amount: selectedTokenBalance.amount, + symbol: selectedTokenBalance.token.symbol, + }) + : null; + + return ( +
+
+ + Enter amount + + {availableBalance && ( + + Available: {availableBalance} + + )} +
+ +
+ ); +} diff --git a/packages/dashboard/src/components/molecules/header/deposit/state.tsx b/packages/dashboard/src/components/molecules/header/deposit/state.tsx new file mode 100644 index 0000000..cfb3a13 --- /dev/null +++ b/packages/dashboard/src/components/molecules/header/deposit/state.tsx @@ -0,0 +1,247 @@ +import { + Atom, + Result, + useAtomSet, + useAtomValue, +} from "@effect-atom/atom-react"; +import type { FormReact } from "@lucas-barake/effect-form-react"; +import { EvmNetworks } from "@stakekit/common"; +import { + selectedProviderAtom, + type yieldApiNetworkToMoralisChain, +} from "@yieldxyz/perps-common/atoms"; +import { Text } from "@yieldxyz/perps-common/components"; +import type { + TokenBalance, + WalletAccount, +} from "@yieldxyz/perps-common/domain"; +import { + createDepositForm, + selectedTokenBalanceAtom, +} from "@yieldxyz/perps-common/hooks"; +import { + calcBaseAmountFromUsd, + clampPercent, + formatTokenAmount, + percentOf, + round, + valueFromPercent, +} from "@yieldxyz/perps-common/lib"; +import { type ApiTypes, runtimeAtom } from "@yieldxyz/perps-common/services"; +import { Effect, Option } from "effect"; + +// Selected chain atom (network) +type ChainKey = keyof typeof yieldApiNetworkToMoralisChain; + +const initialChainAtom = Atom.make(EvmNetworks.Ethereum); + +export const selectedChainAtom = Atom.writable( + (ctx) => ctx.get(initialChainAtom), + (_ctx, value: ChainKey) => _ctx.setSelf(value), +); + +// Hooks for using atoms in components +export const useProviders = (): { + selectedProvider: ApiTypes.ProviderDto | null; + setSelectedProvider: (value: ApiTypes.ProviderDto) => void; +} => { + const selectedProvider = useAtomValue(selectedProviderAtom).pipe( + Result.getOrElse(() => null), + ); + const setSelectedProvider = useAtomSet(selectedProviderAtom); + + return { + selectedProvider, + setSelectedProvider, + }; +}; + +export const useSelectedChain = () => { + const selectedChain = useAtomValue(selectedChainAtom); + const setSelectedChain = useAtomSet(selectedChainAtom); + + return { + selectedChain, + setSelectedChain, + }; +}; + +// Custom amount field component that matches the Figma design +const DepositAmountField: FormReact.FieldComponent = ({ field }) => { + const onChange: (typeof field)["onChange"] = (newValue) => { + const value = newValue.replace(/[^0-9.,]/g, ""); + const parts = value.split(/[.,]/); + if (parts.length > 2) return; + field.onChange(value); + }; + + return ( +
+
+ { + if (field.value === "0") { + onChange(""); + } + }} + onBlurCapture={() => { + if (field.value === "" || field.value.startsWith("00")) { + onChange("0"); + } + }} + onChange={(e) => onChange(e.target.value)} + autoComplete="off" + autoCorrect="off" + spellCheck="false" + pattern="^(?!0\d)\d*([.,])?(\d+)?$" + minLength={1} + maxLength={79} + onBlur={field.onBlur} + placeholder="0.00" + className="h-10 text-white text-sm font-semibold tracking-[-0.42px] leading-[1.25] bg-transparent border-none outline-none placeholder:text-gray-4 w-full caret-accent-green" + /> +
+ {Option.isSome(field.error) && ( +
+
+ + ! + +
+ + {field.error.value} + +
+ )} +
+ ); +}; + +export const DepositForm = createDepositForm(DepositAmountField); + +const amountAtom = DepositForm.getFieldValue(DepositForm.fields.Amount); +const setAmountFieldAtom = DepositForm.setValue(DepositForm.fields.Amount); + +export const useDepositForm = () => { + const submit = useAtomSet(DepositForm.submit); + const submitResult = useAtomValue(DepositForm.submit); + + return { + submit, + submitResult, + }; +}; + +export const useDashboardSelectedTokenBalance = ( + walletAddress: WalletAccount["address"], +) => { + const selectedTokenBalance = useAtomValue( + selectedTokenBalanceAtom(walletAddress), + ).pipe(Result.getOrElse(() => null)); + const setSelectedTokenBalance = useAtomSet( + selectedTokenBalanceAtom(walletAddress), + ); + const setAmount = useAtomSet(setAmountFieldAtom); + + const handleSelectTokenBalance = (tokenBalance: TokenBalance) => { + setSelectedTokenBalance(tokenBalance); + setAmount("0"); + }; + + return { + selectedTokenBalance, + handleSelectTokenBalance, + }; +}; + +export const useDashboardDepositPercentage = ( + walletAddress: WalletAccount["address"], +) => { + const amount = useAtomValue(amountAtom).pipe( + Option.map(Number), + Option.filter((v) => !Number.isNaN(v)), + Option.getOrElse(() => 0), + ); + + const setAmount = useAtomSet(setAmountFieldAtom); + + const { selectedTokenBalance } = + useDashboardSelectedTokenBalance(walletAddress); + const availableBalanceUsd = selectedTokenBalance + ? Number(selectedTokenBalance.amount) * selectedTokenBalance.price + : 0; + + const percentage = clampPercent( + percentOf({ part: amount, whole: availableBalanceUsd }), + ); + + const handlePercentageChange = (newPercentage: number) => { + if (newPercentage >= 100) { + return setAmount(availableBalanceUsd.toString()); + } + + const newAmount = valueFromPercent({ + total: availableBalanceUsd, + percent: newPercentage, + }); + setAmount(round(newAmount).toString()); + }; + + return { + handlePercentageChange, + percentage: Math.round(percentage), + }; +}; + +const tokenAmountValueAtom = Atom.family( + (walletAddress: WalletAccount["address"]) => + runtimeAtom.atom((ctx) => + Effect.gen(function* () { + const tokenBalance = yield* ctx.result( + selectedTokenBalanceAtom(walletAddress), + ); + + ctx.subscribe(amountAtom, () => {}); + + const amount = ctx.get(amountAtom).pipe( + Option.map(parseFloat), + Option.filter((v) => !Number.isNaN(v)), + Option.getOrElse(() => 0), + ); + + if (!tokenBalance) { + return ""; + } + + return formatTokenAmount({ + amount: calcBaseAmountFromUsd({ + usdAmount: amount, + priceUsd: tokenBalance.price, + }), + symbol: tokenBalance.token.symbol, + }); + }), + ), +); + +export const useDashboardTokenAmountValue = ( + walletAddress: WalletAccount["address"], +) => { + const tokenAmountValue = useAtomValue( + tokenAmountValueAtom(walletAddress), + ).pipe(Result.getOrElse(() => null)); + + return { + tokenAmountValue, + }; +}; diff --git a/packages/dashboard/src/components/molecules/header/index.tsx b/packages/dashboard/src/components/molecules/header/index.tsx new file mode 100644 index 0000000..cbf42b3 --- /dev/null +++ b/packages/dashboard/src/components/molecules/header/index.tsx @@ -0,0 +1,230 @@ +import { Result, useAtomSet, useAtomValue } from "@effect-atom/atom-react"; +import { useAppKit } from "@reown/appkit/react"; +import { Link } from "@tanstack/react-router"; +import hyperliquidLogo from "@yieldxyz/perps-common/assets/hyperliquid.png"; +import { + providersAtom, + selectedProviderAtom, + walletAtom, +} from "@yieldxyz/perps-common/atoms"; +import { + AddressSwitcher, + Button, + Dialog, + Text, +} from "@yieldxyz/perps-common/components"; +import { + isBrowserWallet, + isWalletConnected, + type WalletConnected, +} from "@yieldxyz/perps-common/domain"; +import { cn, truncateAddress } from "@yieldxyz/perps-common/lib"; +import type { ApiTypes } from "@yieldxyz/perps-common/services"; +import { ChevronRight } from "lucide-react"; +import { useState } from "react"; +import { Logo } from "../../atoms/logo"; +import { DepositDialog } from "./deposit/deposit-dialog"; +import { WithdrawDialog } from "./withdraw/withdraw-dialog"; + +interface HeaderProps { + className?: string; +} + +export function Header({ className }: HeaderProps) { + return ( +
+
+ {/* Left side: Logo + Navigation */} +
+ {/* Logo */} + + + + + {/* Navigation */} + +
+ + {/* Right side: Wallet section */} + +
+
+ ); +} + +function HeaderWalletSection() { + const { open } = useAppKit(); + const wallet = useAtomValue(walletAtom).pipe(Result.getOrElse(() => null)); + + const browserWallet = isBrowserWallet(wallet); + const walletConnected = isWalletConnected(wallet); + + // Disconnected state - show Connect button + if (!walletConnected) { + return ( +
+ +
+ ); + } + + // Connected state - show provider selector, address, and deposit button + return ; +} + +function ConnectedWalletSection({ wallet }: { wallet: WalletConnected }) { + const [providerDialogOpen, setProviderDialogOpen] = useState(false); + const [depositDialogOpen, setDepositDialogOpen] = useState(false); + const [withdrawDialogOpen, setWithdrawDialogOpen] = useState(false); + + const providers = useAtomValue(providersAtom).pipe( + Result.getOrElse(() => [] as ReadonlyArray), + ); + const selectedProvider = useAtomValue(selectedProviderAtom).pipe( + Result.getOrElse(() => null), + ); + const setSelectedProvider = useAtomSet(selectedProviderAtom); + + const handleProviderSelect = (provider: ApiTypes.ProviderDto) => { + setSelectedProvider(provider); + setProviderDialogOpen(false); + }; + + return ( +
+ {/* Provider selector */} + + + {/* Provider dialog */} + + + + + + + Select Provider + + +
+ {providers.map((provider) => ( + + ))} +
+
+
+
+
+ + {/* Address display with switcher */} + + + {truncateAddress(wallet.currentAccount.address)} + + + + } + /> + + {/* Withdraw button */} + + + {/* Deposit button */} + + + {/* Withdraw dialog */} + + + {/* Deposit dialog */} + +
+ ); +} diff --git a/packages/dashboard/src/components/molecules/header/withdraw/state.tsx b/packages/dashboard/src/components/molecules/header/withdraw/state.tsx new file mode 100644 index 0000000..c99898a --- /dev/null +++ b/packages/dashboard/src/components/molecules/header/withdraw/state.tsx @@ -0,0 +1,181 @@ +import { + Atom, + Result, + useAtomSet, + useAtomValue, +} from "@effect-atom/atom-react"; +import type { FormReact } from "@lucas-barake/effect-form-react"; +import { + providersAtom, + selectedProviderAtom, + selectedProviderBalancesAtom, +} from "@yieldxyz/perps-common/atoms"; +import { Text } from "@yieldxyz/perps-common/components"; +import type { WalletAccount } from "@yieldxyz/perps-common/domain"; +import { createWithdrawForm } from "@yieldxyz/perps-common/hooks"; +import { + clampPercent, + percentOf, + round, + valueFromPercent, +} from "@yieldxyz/perps-common/lib"; +import type { ApiTypes } from "@yieldxyz/perps-common/services"; +import { Array as _Array, Option } from "effect"; + +const withdrawSelectedProviderAtom = Atom.writable( + (ctx) => + ctx + .get(providersAtom) + .pipe(Result.map(_Array.head), Result.map(Option.getOrNull)), + (ctx, value: ApiTypes.ProviderDto) => ctx.setSelf(Result.success(value)), +); + +export const useProviders = (): { + selectedProvider: ApiTypes.ProviderDto | null; + setSelectedProvider: (value: ApiTypes.ProviderDto) => void; +} => { + const selectedProvider = useAtomValue(selectedProviderAtom).pipe( + Result.getOrElse(() => null), + ); + const setSelectedProvider = useAtomSet(withdrawSelectedProviderAtom); + + return { + selectedProvider, + setSelectedProvider, + }; +}; + +export const useProviderBalance = (walletAddress: WalletAccount["address"]) => { + const providerBalance = useAtomValue( + selectedProviderBalancesAtom(walletAddress), + ).pipe(Result.getOrElse(() => null)); + + return { + providerBalance, + }; +}; + +// Custom amount field component that matches the deposit dialog design +const WithdrawAmountField: FormReact.FieldComponent = ({ field }) => { + const onChange: (typeof field)["onChange"] = (newValue) => { + const value = newValue.replace(/[^0-9.,]/g, ""); + const parts = value.split(/[.,]/); + if (parts.length > 2) return; + field.onChange(value); + }; + + return ( +
+
+ { + if (field.value === "0") { + onChange(""); + } + }} + onBlurCapture={() => { + if (field.value === "" || field.value.startsWith("00")) { + onChange("0"); + } + }} + onChange={(e) => onChange(e.target.value)} + autoComplete="off" + autoCorrect="off" + spellCheck="false" + pattern="^(?!0\d)\d*([.,])?(\d+)?$" + minLength={1} + maxLength={79} + onBlur={field.onBlur} + placeholder="0.00" + className="h-10 text-white text-sm font-semibold tracking-[-0.42px] leading-tight bg-transparent border-none outline-none placeholder:text-gray-4 w-full caret-accent-green" + /> +
+ {Option.isSome(field.error) && ( +
+
+ + ! + +
+ + {field.error.value} + +
+ )} +
+ ); +}; + +export const WithdrawForm = createWithdrawForm(WithdrawAmountField); + +const setAmountFieldAtom = WithdrawForm.setValue(WithdrawForm.fields.Amount); +const amountFieldAtom = WithdrawForm.getFieldValue(WithdrawForm.fields.Amount); + +export const useWithdrawForm = () => { + const submit = useAtomSet(WithdrawForm.submit); + const submitResult = useAtomValue(WithdrawForm.submit); + + return { + submit, + submitResult, + }; +}; + +export const useSetWithdrawAmount = () => { + const setAmount = useAtomSet(setAmountFieldAtom); + + return { + setAmount, + }; +}; + +export const useWithdrawPercentage = ( + walletAddress: WalletAccount["address"], +) => { + const amount = useAtomValue(amountFieldAtom).pipe( + Option.map(Number), + Option.filter((v) => !Number.isNaN(v)), + Option.getOrElse(() => 0), + ); + + const setAmount = useAtomSet(setAmountFieldAtom); + + const availableBalance = useAtomValue( + selectedProviderBalancesAtom(walletAddress), + ).pipe( + Result.value, + Option.map((v) => v.availableBalance), + Option.getOrElse(() => 0), + ); + + const handlePercentageChange = (newPercentage: number) => { + if (newPercentage >= 100) { + return setAmount(availableBalance.toString()); + } + + const newAmount = valueFromPercent({ + total: availableBalance, + percent: newPercentage, + }); + setAmount(round(newAmount, 6).toString()); + }; + + const percentage = clampPercent( + percentOf({ part: amount, whole: availableBalance }), + ); + + return { + percentage: Math.round(percentage), + handlePercentageChange, + }; +}; diff --git a/packages/dashboard/src/components/molecules/header/withdraw/withdraw-dialog.tsx b/packages/dashboard/src/components/molecules/header/withdraw/withdraw-dialog.tsx new file mode 100644 index 0000000..3ca867c --- /dev/null +++ b/packages/dashboard/src/components/molecules/header/withdraw/withdraw-dialog.tsx @@ -0,0 +1,224 @@ +import { Result, useAtomValue } from "@effect-atom/atom-react"; +import hyperliquidLogo from "@yieldxyz/perps-common/assets/hyperliquid.png"; +import { providersAtom } from "@yieldxyz/perps-common/atoms"; +import { + Button, + Dialog, + PercentageSlider, + Select, + Text, +} from "@yieldxyz/perps-common/components"; +import type { + WalletAccount, + WalletConnected, +} from "@yieldxyz/perps-common/domain"; +import { formatTokenAmount, round } from "@yieldxyz/perps-common/lib"; +import type { ApiSchemas } from "@yieldxyz/perps-common/services"; +import { + useProviderBalance, + useProviders, + useWithdrawForm, + useWithdrawPercentage, + WithdrawForm, +} from "./state"; + +interface WithdrawDialogProps { + wallet: WalletConnected; + open: boolean; + onOpenChange: (open: boolean) => void; +} + +export function WithdrawDialog({ + wallet, + open, + onOpenChange, +}: WithdrawDialogProps) { + return ( + + + + + + + Withdraw funds + + + + + + + + ); +} + +interface WithdrawDialogContentProps { + wallet: WalletConnected; +} + +function WithdrawDialogContent({ wallet }: WithdrawDialogContentProps) { + const { submit, submitResult } = useWithdrawForm(); + const { providerBalance } = useProviderBalance(wallet.currentAccount.address); + + const handleSubmit = () => { + submit(); + }; + + const initialAmount = providerBalance + ? round(providerBalance.availableBalance / 2, 2).toString() + : "0"; + + return ( + +
+
+ {/* Provider Select */} + + + {/* Amount Input */} + + + {/* Percentage Slider */} + +
+ + {/* Withdraw Button */} + +
+
+ ); +} + +function ProviderSelect() { + const providers = useAtomValue(providersAtom).pipe( + Result.getOrElse(() => [] as ReadonlyArray), + ); + const { selectedProvider, setSelectedProvider } = useProviders(); + + const items = providers.map((provider) => ({ + value: provider.id, + label: provider.name, + provider, + })); + + return ( +
+ + Select provider + + { + if (!value) return; + const provider = providers.find((p) => p.id === value); + if (provider) setSelectedProvider(provider); + }} + > + +
+ {selectedProvider?.name + + {selectedProvider?.name ?? "Select provider"} + +
+
+ + + + {items.map((item) => ( + + } + > + {item.label} + + ))} + + + +
+
+ ); +} + +interface AmountInputProps { + walletAddress: WalletAccount["address"]; +} + +function AmountInput({ walletAddress }: AmountInputProps) { + const { providerBalance } = useProviderBalance(walletAddress); + + const availableBalance = providerBalance + ? formatTokenAmount({ + amount: providerBalance.availableBalance, + symbol: providerBalance.collateral.symbol, + }) + : null; + + return ( +
+
+ + Enter amount + + {availableBalance && ( + + Available: {availableBalance} + + )} +
+ +
+ ); +} + +interface PercentageSliderSectionProps { + walletAddress: WalletAccount["address"]; +} + +function PercentageSliderSection({ + walletAddress, +}: PercentageSliderSectionProps) { + const { percentage, handlePercentageChange } = + useWithdrawPercentage(walletAddress); + + return ( +
+ + Withdraw: {percentage}% + + +
+ ); +} diff --git a/packages/dashboard/src/components/molecules/positions/close-position-dialog.tsx b/packages/dashboard/src/components/molecules/positions/close-position-dialog.tsx new file mode 100644 index 0000000..bb6d772 --- /dev/null +++ b/packages/dashboard/src/components/molecules/positions/close-position-dialog.tsx @@ -0,0 +1,179 @@ +import type { DialogRootActions } from "@base-ui/react/dialog"; +import { Result } from "@effect-atom/atom-react"; +import { + Button, + Dialog, + Divider, + PercentageSlider, + Text, +} from "@yieldxyz/perps-common/components"; +import type { WalletConnected } from "@yieldxyz/perps-common/domain"; +import { + useCloseCalculations, + useClosePercentage, + useSubmitClose, +} from "@yieldxyz/perps-common/hooks"; +import { formatAmount, formatTokenAmount } from "@yieldxyz/perps-common/lib"; +import type { ApiTypes } from "@yieldxyz/perps-common/services"; +import { X } from "lucide-react"; +import { useRef } from "react"; + +interface ClosePositionDialogProps { + position: ApiTypes.PositionDto; + wallet: WalletConnected; + children: React.ReactElement; + onClose?: () => void; +} + +export function ClosePositionDialog({ + position, + wallet, + children, + onClose, +}: ClosePositionDialogProps) { + const actionsRef = useRef({ + close: () => {}, + unmount: () => {}, + }); + + const handleClose = () => { + actionsRef.current.close(); + onClose?.(); + }; + + return ( + + + + + + + + + + + + ); +} + +interface ClosePositionDialogContentProps { + position: ApiTypes.PositionDto; + wallet: WalletConnected; + onClose: () => void; +} + +function ClosePositionDialogContent({ + position, + wallet, + onClose, +}: ClosePositionDialogContentProps) { + const { closePercentage, setClosePercentage } = useClosePercentage(); + const calculations = useCloseCalculations(position); + const { submitClose, submitResult } = useSubmitClose(); + + const isPnlPositive = position.unrealizedPnl >= 0; + + const handleSubmit = () => { + submitClose({ position, wallet }); + }; + + // Close dialog on successful submit (action will be handled by SignTransactionsDialog) + if (Result.isSuccess(submitResult)) { + onClose(); + } + + return ( +
+ {/* Header */} +
+ + Close Position + + +
+ + {/* Amount Display */} +
+ + Select amount to close + + + {formatAmount(calculations.closeValue)} + + + {formatTokenAmount({ + amount: calculations.closeSize, + symbol: "Size:", + })} + +
+ + {/* Slider */} +
+ +
+ + {/* Details Section */} +
+
+
+
+ + Margin + +
+ + {formatAmount(calculations.marginReturn)} + + + {isPnlPositive ? "+" : ""} + {formatAmount(calculations.pnlReturn)} + +
+
+ + + +
+ + You will receive + + + {formatAmount(calculations.youWillReceive)} + +
+
+
+ + {/* Submit Button */} + +
+ ); +} diff --git a/packages/dashboard/src/components/molecules/positions/index.tsx b/packages/dashboard/src/components/molecules/positions/index.tsx new file mode 100644 index 0000000..8367c07 --- /dev/null +++ b/packages/dashboard/src/components/molecules/positions/index.tsx @@ -0,0 +1,70 @@ +import { Result, useAtomValue } from "@effect-atom/atom-react"; +import { marketsAtom, walletAtom } from "@yieldxyz/perps-common/atoms"; +import { + Tabs, + TabsContent, + TabsList, + TabsTrigger, +} from "@yieldxyz/perps-common/components"; +import { isWalletConnected } from "@yieldxyz/perps-common/domain"; +import { cn } from "@yieldxyz/perps-common/lib"; +import { OrdersTabWithWallet } from "./orders-tab"; +import { PositionsTabWithWallet } from "./positions-tab"; +import { TableDisconnected } from "./shared"; + +interface PositionsTableProps { + className?: string; +} + +export function PositionsTable({ className }: PositionsTableProps) { + const wallet = useAtomValue(walletAtom).pipe(Result.getOrElse(() => null)); + const walletConnected = isWalletConnected(wallet); + useAtomValue(marketsAtom); // TODO: investigate why this is needed + + return ( +
+ + {/* Tab Headers */} +
+ + + Positions + + + Open orders + + +
+ + {/* Positions Tab */} + + {walletConnected ? ( + + ) : ( + + )} + + + {/* Orders Tab */} + + {walletConnected ? ( + + ) : ( + + )} + +
+
+ ); +} diff --git a/packages/dashboard/src/components/molecules/positions/orders-tab.tsx b/packages/dashboard/src/components/molecules/positions/orders-tab.tsx new file mode 100644 index 0000000..14deb24 --- /dev/null +++ b/packages/dashboard/src/components/molecules/positions/orders-tab.tsx @@ -0,0 +1,196 @@ +import { Result, useAtomSet, useAtomValue } from "@effect-atom/atom-react"; +import { + cancelOrderAtom, + marketsAtom, + ordersAtom, +} from "@yieldxyz/perps-common/atoms"; +import { Text } from "@yieldxyz/perps-common/components"; +import type { WalletConnected } from "@yieldxyz/perps-common/domain"; +import { useOrderActions } from "@yieldxyz/perps-common/hooks"; +import { + calcNotionalUsd, + cn, + formatAmount, + formatDate, + formatSnakeCase, +} from "@yieldxyz/perps-common/lib"; +import type { ApiSchemas } from "@yieldxyz/perps-common/services"; +import { Array as _Array, Option, Record } from "effect"; +import { + OrdersTableSkeleton, + tableCellClass, + tableHeaderClass, +} from "./shared"; + +interface OrderWithMarket { + order: ApiSchemas.OrderDto; + market: ApiSchemas.MarketDto; + wallet: WalletConnected; +} + +interface OrdersTableContentProps { + orders: OrderWithMarket[]; + isLoading: boolean; + wallet: WalletConnected; +} + +export function OrdersTabWithWallet({ wallet }: { wallet: WalletConnected }) { + const ordersResult = useAtomValue(ordersAtom(wallet.currentAccount.address)); + const marketsMapResult = useAtomValue(marketsAtom); + + const isLoading = + Result.isInitial(ordersResult) || Result.isInitial(marketsMapResult); + + const marketsMap = marketsMapResult.pipe(Result.getOrElse(Record.empty)); + + const ordersWithMarket = ordersResult.pipe( + Result.map((orders) => + _Array.filterMap(orders, (o) => + Record.get(marketsMap, o.marketId).pipe( + Option.map((marketRef) => ({ + order: o, + market: marketRef.value, + wallet, + })), + ), + ), + ), + Result.getOrElse(() => []), + ); + + return ( + + ); +} + +function OrderRow({ order, market, wallet }: OrderWithMarket) { + const { cancelOrderAction } = useOrderActions(order); + const price = order.limitPrice ?? order.triggerPrice ?? 0; + const value = calcNotionalUsd({ priceUsd: price, sizeBase: order.size }); + const symbol = market.baseAsset.symbol; + const isLong = order.side === "long"; + + return ( + + + {formatSnakeCase(order.type)} + + + {formatDate(order.createdAt)} + + + + {isLong ? "Long" : "Short"} + + + + {order.size} {symbol} + + {formatAmount(price)} + + {formatAmount(market.markPrice)} + + {formatAmount(value)} + + {cancelOrderAction && ( + + )} + + + ); +} + +function CancelOrderButton({ + wallet, + marketId, + orderId, +}: { + wallet: WalletConnected; + marketId: string; + orderId: string; +}) { + const cancelOrderResult = useAtomValue(cancelOrderAtom(orderId)); + const submitCancelOrder = useAtomSet(cancelOrderAtom(orderId)); + + const handleCancelOrder = () => + submitCancelOrder({ + marketId, + walletAddress: wallet.currentAccount.address, + }); + + const isLoading = Result.isWaiting(cancelOrderResult); + + return ( + + ); +} + +function OrdersTableContent({ + orders, + isLoading, + wallet, +}: OrdersTableContentProps) { + if (isLoading) { + return ; + } + + if (orders.length === 0) { + return ( +
+ No open orders + + Place an order to see it here + +
+ ); + } + + return ( +
+ + + + + + + + + + + + + + + {orders.map(({ order, market }, idx) => ( + + ))} + +
TypeCreatedSideSizePriceMarketValueActions
+
+ ); +} diff --git a/packages/dashboard/src/components/molecules/positions/positions-tab.tsx b/packages/dashboard/src/components/molecules/positions/positions-tab.tsx new file mode 100644 index 0000000..e201e1f --- /dev/null +++ b/packages/dashboard/src/components/molecules/positions/positions-tab.tsx @@ -0,0 +1,387 @@ +import { Result, useAtomValue } from "@effect-atom/atom-react"; +import { + marketsAtom, + ordersAtom, + positionsAtom, +} from "@yieldxyz/perps-common/atoms"; +import { + LeverageDialog, + Text, + TPOrSLDialog, + type TPOrSLOption, + type TPOrSLSettings, +} from "@yieldxyz/perps-common/components"; +import type { WalletConnected } from "@yieldxyz/perps-common/domain"; +import { + useEditSLTP, + usePositionActions, + useTpSlOrders, + useUpdateLeverage, +} from "@yieldxyz/perps-common/hooks"; +import { + calcNotionalUsd, + calcPnlPercent, + cn, + formatAmount, + formatPercentage, + getMaxLeverage, + getTPOrSLConfigurationFromPosition, +} from "@yieldxyz/perps-common/lib"; +import type { ApiSchemas, ApiTypes } from "@yieldxyz/perps-common/services"; +import { Array as _Array, Option, Record } from "effect"; +import { Pencil } from "lucide-react"; +import { ClosePositionDialog } from "./close-position-dialog"; +import { + PositionsTableSkeleton, + tableCellClass, + tableHeaderClass, +} from "./shared"; + +interface PositionWithMarket { + position: ApiSchemas.PositionDto; + market: ApiSchemas.MarketDto; +} + +interface PositionsTableContentProps { + positions: PositionWithMarket[]; + orders: ApiTypes.OrderDto[]; + wallet: WalletConnected; + isLoading: boolean; +} + +export function PositionsTabWithWallet({ + wallet, +}: { + wallet: WalletConnected; +}) { + const positionsResult = useAtomValue( + positionsAtom(wallet.currentAccount.address), + ); + const marketsMapResult = useAtomValue(marketsAtom); + + const ordersResult = useAtomValue(ordersAtom(wallet.currentAccount.address)); + + const isLoading = + Result.isInitial(positionsResult) || + Result.isInitial(marketsMapResult) || + Result.isInitial(ordersResult); + + const marketsMap = marketsMapResult.pipe(Result.getOrElse(Record.empty)); + + const positionsWithMarket = positionsResult.pipe( + Result.map((positions) => + _Array.filterMap(positions, (p) => + Record.get(marketsMap, p.marketId).pipe( + Option.map((marketRef) => ({ + position: p, + market: marketRef.value, + })), + ), + ), + ), + Result.getOrElse(() => []), + ); + + const orders = ordersResult.pipe( + Result.map((o) => [...o]), + Result.getOrElse(() => [] as ApiTypes.OrderDto[]), + ); + + return ( + + ); +} + +function PositionsTableContent({ + positions, + orders, + wallet, + isLoading, +}: PositionsTableContentProps) { + if (isLoading) { + return ; + } + + if (positions.length === 0) { + return ( +
+ No open positions + + Start trading to see your positions here + +
+ ); + } + + return ( +
+ + + + + + + + + + + + + + + + + + {positions.map(({ position, market }) => { + const marketOrders = orders.filter( + (o) => o.marketId === position.marketId, + ); + + return ( + + ); + })} + +
CoinSize + Position value + Entry PriceMark PricePNL (ROE %)Liq. PriceMarginCloseTake Profit + Stop Loss +
+
+ ); +} + +interface PositionRowProps { + position: ApiSchemas.PositionDto; + market: ApiSchemas.MarketDto; + orders: ApiTypes.OrderDto[]; + wallet: WalletConnected; +} + +function PositionRow({ position, market, orders, wallet }: PositionRowProps) { + const { updateLeverage } = useUpdateLeverage(); + const { editTP, editSL } = useEditSLTP(); + + const positionActions = usePositionActions(position); + const tpSlOrders = useTpSlOrders(orders); + + const symbol = market.baseAsset.symbol; + const value = calcNotionalUsd({ + priceUsd: position.markPrice, + sizeBase: position.size, + }); + const pnlPercent = calcPnlPercent({ + pnlUsd: position.unrealizedPnl, + marginUsd: position.margin, + }); + const isPnlPositive = position.unrealizedPnl >= 0; + const isLong = position.side === "long"; + + const initialAutoCloseSettings: TPOrSLSettings = { + takeProfit: getTPOrSLConfigurationFromPosition({ + amount: tpSlOrders.takeProfit?.triggerPrice ?? undefined, + entryPrice: position.entryPrice, + tpOrSl: "takeProfit", + side: position.side, + }), + stopLoss: getTPOrSLConfigurationFromPosition({ + amount: tpSlOrders.stopLoss?.triggerPrice ?? undefined, + entryPrice: position.entryPrice, + tpOrSl: "stopLoss", + side: position.side, + }), + }; + + const handleAutoCloseSubmit = ( + settings: TPOrSLSettings, + actionType: TPOrSLOption, + ) => { + if (actionType === "takeProfit") { + editTP({ position, wallet, tpOrSLSettings: settings }); + } else { + editSL({ position, wallet, tpOrSLSettings: settings }); + } + }; + + const handleLeverageChange = (newLeverage: number) => { + updateLeverage({ + position, + wallet, + newLeverage, + }); + }; + + const tpValue = tpSlOrders.takeProfit?.triggerPrice; + const slValue = tpSlOrders.stopLoss?.triggerPrice; + + return ( + + {/* Coin column with clickable leverage */} + + + {symbol}{" "} + {positionActions.updateLeverage ? ( + + + + ) : ( + {position.leverage}x + )} + + + + {/* Size */} + + + {position.size} {symbol} + + + + {/* Position value */} + {formatAmount(value)} + + {/* Entry Price */} + + {formatAmount(position.entryPrice)} + + + {/* Mark Price */} + + {formatAmount(position.markPrice)} + + + {/* PNL */} + + + {isPnlPositive ? "+" : ""} + {formatAmount(position.unrealizedPnl)} ({formatPercentage(pnlPercent)} + ) + + + + {/* Liq. Price */} + + {formatAmount(position.liquidationPrice)} + + + {/* Margin */} + + + {formatAmount(position.margin)} ( + {position.marginMode === "isolated" ? "Isolated" : "Cross"}) + + + + {/* Close column */} + + + + + + + {/* TP column */} + + {positionActions.takeProfit ? ( + + handleAutoCloseSubmit(settings, "takeProfit") + } + entryPrice={position.entryPrice} + currentPrice={position.markPrice} + liquidationPrice={position.liquidationPrice} + side={position.side} + mode="takeProfit" + > + + + ) : ( + + {tpValue ? formatAmount(tpValue) : "--"} + + )} + + + {/* SL column */} + + {positionActions.stopLoss ? ( + + handleAutoCloseSubmit(settings, "stopLoss") + } + entryPrice={position.entryPrice} + currentPrice={position.markPrice} + liquidationPrice={position.liquidationPrice} + side={position.side} + mode="stopLoss" + > + + + ) : ( + + {slValue ? formatAmount(slValue) : "--"} + + )} + + + ); +} diff --git a/packages/dashboard/src/components/molecules/positions/shared.tsx b/packages/dashboard/src/components/molecules/positions/shared.tsx new file mode 100644 index 0000000..c79b193 --- /dev/null +++ b/packages/dashboard/src/components/molecules/positions/shared.tsx @@ -0,0 +1,136 @@ +import { Skeleton, Text } from "@yieldxyz/perps-common/components"; +import { cn } from "@yieldxyz/perps-common/lib"; + +export const tableHeaderClass = + "text-xs text-[#707070] font-normal tracking-tight text-left"; + +export const tableCellClass = "text-xs text-white font-normal tracking-tight"; + +export function TableDisconnected({ + message = "Connect your wallet to see your positions", +}: { + message?: string; +}) { + return ( +
+ Wallet not connected + {message} +
+ ); +} + +export function OrdersTableSkeleton() { + return ( +
+ + + + + + + + + + + + + + + {[1, 2, 3].map((i) => ( + + + + + + + + + + + ))} + +
TypeCreatedSideSizePriceMarketValueActions
+ + + + + + + + + + + + + + + +
+
+ ); +} + +export function PositionsTableSkeleton() { + return ( +
+ + + + + + + + + + + + + + + + + + {[1, 2, 3].map((i) => ( + + + + + + + + + + + + + + ))} + +
CoinSize + Position value + Entry PriceMark PricePNL (ROE %)Liq. PriceMarginCloseTPSL
+ + + + + + + + + + + + + + + + + + + + + +
+
+ ); +} diff --git a/packages/dashboard/src/main.css b/packages/dashboard/src/main.css new file mode 100644 index 0000000..adef89f --- /dev/null +++ b/packages/dashboard/src/main.css @@ -0,0 +1,11 @@ +html { + background: var(--surface-2); +} + +#app { + background: var(--surface-2); +} + +#widget-container { + border-radius: 12px; +} diff --git a/src/main.tsx b/packages/dashboard/src/main.tsx similarity index 76% rename from src/main.tsx rename to packages/dashboard/src/main.tsx index fcdc99a..a66448c 100644 --- a/src/main.tsx +++ b/packages/dashboard/src/main.tsx @@ -1,9 +1,9 @@ -import ReactDOM from "react-dom/client"; import "./main.css"; -import App from "@/app"; +import ReactDOM from "react-dom/client"; +import { Dashboard } from "./app"; const rootElement = document.getElementById("app"); if (rootElement && !rootElement.innerHTML) { const root = ReactDOM.createRoot(rootElement); - root.render(); + root.render(); } diff --git a/packages/dashboard/src/routeTree.gen.ts b/packages/dashboard/src/routeTree.gen.ts new file mode 100644 index 0000000..d204c26 --- /dev/null +++ b/packages/dashboard/src/routeTree.gen.ts @@ -0,0 +1,59 @@ +/* eslint-disable */ + +// @ts-nocheck + +// noinspection JSUnusedGlobalSymbols + +// This file was automatically generated by TanStack Router. +// You should NOT make any changes in this file as it will be overwritten. +// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. + +import { Route as rootRouteImport } from './routes/__root' +import { Route as IndexRouteImport } from './routes/index' + +const IndexRoute = IndexRouteImport.update({ + id: '/', + path: '/', + getParentRoute: () => rootRouteImport, +} as any) + +export interface FileRoutesByFullPath { + '/': typeof IndexRoute +} +export interface FileRoutesByTo { + '/': typeof IndexRoute +} +export interface FileRoutesById { + __root__: typeof rootRouteImport + '/': typeof IndexRoute +} +export interface FileRouteTypes { + fileRoutesByFullPath: FileRoutesByFullPath + fullPaths: '/' + fileRoutesByTo: FileRoutesByTo + to: '/' + id: '__root__' | '/' + fileRoutesById: FileRoutesById +} +export interface RootRouteChildren { + IndexRoute: typeof IndexRoute +} + +declare module '@tanstack/react-router' { + interface FileRoutesByPath { + '/': { + id: '/' + path: '/' + fullPath: '/' + preLoaderRoute: typeof IndexRouteImport + parentRoute: typeof rootRouteImport + } + } +} + +const rootRouteChildren: RootRouteChildren = { + IndexRoute: IndexRoute, +} +export const routeTree = rootRouteImport + ._addFileChildren(rootRouteChildren) + ._addFileTypes() diff --git a/packages/dashboard/src/routes/__root.tsx b/packages/dashboard/src/routes/__root.tsx new file mode 100644 index 0000000..840d417 --- /dev/null +++ b/packages/dashboard/src/routes/__root.tsx @@ -0,0 +1,17 @@ +import { createRootRoute, Outlet } from "@tanstack/react-router"; +import { Header } from "../components/molecules/header"; + +function RootLayout() { + return ( + <> +
+
+ +
+ + ); +} + +export const Route = createRootRoute({ + component: RootLayout, +}); diff --git a/packages/dashboard/src/routes/index.tsx b/packages/dashboard/src/routes/index.tsx new file mode 100644 index 0000000..a2cd5b0 --- /dev/null +++ b/packages/dashboard/src/routes/index.tsx @@ -0,0 +1,6 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { TradePage } from "../components/modules/trade"; + +export const Route = createFileRoute("/")({ + component: TradePage, +}); diff --git a/packages/dashboard/src/styles.css b/packages/dashboard/src/styles.css new file mode 100644 index 0000000..996bc2a --- /dev/null +++ b/packages/dashboard/src/styles.css @@ -0,0 +1,17 @@ +@import "@yieldxyz/perps-common/styles"; +@source "../../common/src"; + +:root { + --background: #202020; + --content-background: #111; +} + +.dark { + --background: #202020; + --content-background: #111; +} + +@theme inline { + --color-background: var(--background); + --color-content-background: var(--content-background); +} diff --git a/packages/dashboard/tsconfig.json b/packages/dashboard/tsconfig.json new file mode 100644 index 0000000..6578f19 --- /dev/null +++ b/packages/dashboard/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "declaration": true, + "emitDeclarationOnly": true, + "noEmit": false, + "outDir": "./dist", + "rootDir": "." + }, + "references": [{ "path": "../common" }], + "include": ["src"] +} diff --git a/packages/dashboard/vite.config.ts b/packages/dashboard/vite.config.ts new file mode 100644 index 0000000..c02ea85 --- /dev/null +++ b/packages/dashboard/vite.config.ts @@ -0,0 +1,4 @@ +import { commonViteConfig } from "@yieldxyz/perps-common/vite.config"; +import { defineConfig } from "vite"; + +export default defineConfig(commonViteConfig); diff --git a/packages/widget/.env.example b/packages/widget/.env.example new file mode 100644 index 0000000..6dc0341 --- /dev/null +++ b/packages/widget/.env.example @@ -0,0 +1,12 @@ +# Perps API Configuration +VITE_PERPS_BASE_URL= +VITE_PERPS_API_KEY= + +# Reown (WalletConnect) - Get your project ID at https://cloud.reown.com +VITE_REOWN_PROJECT_ID= + +# Moralis API - Get your API key at https://moralis.io +VITE_MORALIS_API_KEY= + +# Optional: Perps OpenAPI docs URL (for code generation) +# VITE_PERPS_DOCS_URL= diff --git a/packages/widget/index.html b/packages/widget/index.html new file mode 100644 index 0000000..b92d082 --- /dev/null +++ b/packages/widget/index.html @@ -0,0 +1,19 @@ + + + + + + + + + + Yield.xyz - Perps Widget + + +
+ + + diff --git a/packages/widget/package.json b/packages/widget/package.json new file mode 100644 index 0000000..5be4692 --- /dev/null +++ b/packages/widget/package.json @@ -0,0 +1,66 @@ +{ + "name": "@yieldxyz/perps-widget", + "type": "module", + "scripts": { + "dev": "vite --port 3000", + "build": "vite build && tsc -b", + "preview": "vite preview", + "lint": "biome check . && tsc -b", + "format": "biome format --write .", + "generate-routes": "tsr generate" + }, + "dependencies": { + "@yieldxyz/perps-common": "workspace:*", + "@base-ui/react": "catalog:", + "@effect-atom/atom-react": "catalog:", + "@effect/experimental": "^0.58.0", + "@effect/platform": "catalog:", + "@effect/platform-node": "catalog:", + "@ledgerhq/wallet-api-client": "catalog:", + "@lucas-barake/effect-form-react": "catalog:", + "@reown/appkit": "catalog:", + "@reown/appkit-adapter-wagmi": "catalog:", + "@stakekit/common": "catalog:", + "@tailwindcss/vite": "catalog:", + "@tanstack/react-devtools": "catalog:", + "@tanstack/react-query": "catalog:", + "@tanstack/react-router": "catalog:", + "@tanstack/react-router-devtools": "catalog:", + "@tanstack/react-virtual": "catalog:", + "class-variance-authority": "catalog:", + "clsx": "catalog:", + "effect": "catalog:", + "lucide-react": "catalog:", + "react": "catalog:", + "react-dom": "catalog:", + "sonner": "catalog:", + "tailwind-merge": "catalog:", + "tailwindcss": "catalog:", + "tw-animate-css": "catalog:", + "viem": "catalog:", + "wagmi": "catalog:" + }, + "devDependencies": { + "@tanstack/devtools-vite": "catalog:", + "@tanstack/router-cli": "catalog:", + "@testing-library/dom": "catalog:", + "@testing-library/react": "catalog:", + "@tim-smart/openapi-gen": "catalog:", + "@types/node": "catalog:", + "@types/react": "catalog:", + "@types/react-dom": "catalog:", + "@vite-pwa/assets-generator": "catalog:", + "@vitejs/plugin-react": "catalog:", + "@vitest/browser-playwright": "catalog:", + "babel-plugin-react-compiler": "catalog:", + "jsdom": "catalog:", + "openapi-filter": "catalog:", + "tsx": "catalog:", + "typescript": "catalog:", + "vite": "catalog:", + "vite-plugin-node-polyfills": "catalog:", + "vitest": "catalog:", + "vitest-browser-react": "catalog:", + "@tanstack/router-plugin": "catalog:" + } +} diff --git a/packages/widget/public/apple-touch-icon-180x180.png b/packages/widget/public/apple-touch-icon-180x180.png new file mode 100644 index 0000000..a23de91 Binary files /dev/null and b/packages/widget/public/apple-touch-icon-180x180.png differ diff --git a/packages/widget/public/favicon.ico b/packages/widget/public/favicon.ico new file mode 100644 index 0000000..e2950e3 Binary files /dev/null and b/packages/widget/public/favicon.ico differ diff --git a/packages/widget/public/logo-192x192.png b/packages/widget/public/logo-192x192.png new file mode 100644 index 0000000..b49da70 Binary files /dev/null and b/packages/widget/public/logo-192x192.png differ diff --git a/packages/widget/public/logo-512x512.png b/packages/widget/public/logo-512x512.png new file mode 100644 index 0000000..9aef598 Binary files /dev/null and b/packages/widget/public/logo-512x512.png differ diff --git a/packages/widget/public/logo-64x64.png b/packages/widget/public/logo-64x64.png new file mode 100644 index 0000000..903da1e Binary files /dev/null and b/packages/widget/public/logo-64x64.png differ diff --git a/packages/widget/public/maskable-icon-512x512.png b/packages/widget/public/maskable-icon-512x512.png new file mode 100644 index 0000000..a5a42f5 Binary files /dev/null and b/packages/widget/public/maskable-icon-512x512.png differ diff --git a/packages/widget/public/yield_xyz.png b/packages/widget/public/yield_xyz.png new file mode 100644 index 0000000..1bbfc87 Binary files /dev/null and b/packages/widget/public/yield_xyz.png differ diff --git a/src/app.tsx b/packages/widget/src/app.tsx similarity index 59% rename from src/app.tsx rename to packages/widget/src/app.tsx index 38a30a8..d6d946e 100644 --- a/src/app.tsx +++ b/packages/widget/src/app.tsx @@ -1,17 +1,10 @@ -import { - // createMemoryHistory, - createRouter, - RouterProvider, -} from "@tanstack/react-router"; -import { useRootContainer } from "@/context/root-container.tsx"; +import { createRouter, RouterProvider } from "@tanstack/react-router"; import "./styles.css"; +import { Providers, useRootContainer } from "@yieldxyz/perps-common/context"; +import { TRADING_VIEW_WIDGET_SCRIPT_URL } from "@yieldxyz/perps-common/services"; import { preload } from "react-dom"; -import { PreloadAtoms } from "@/components/modules/Root/PreloadAtoms.tsx"; -import { Providers } from "@/context/index.tsx"; -import { TRADING_VIEW_WIDGET_SCRIPT_URL } from "@/services/constants.ts"; -import { routeTree } from "./routeTree.gen.ts"; - -// const history = createMemoryHistory(); +import { PreloadAtoms } from "./components/modules/Root/PreloadAtoms"; +import { routeTree } from "./routeTree.gen"; const router = createRouter({ routeTree, @@ -20,7 +13,6 @@ const router = createRouter({ scrollRestoration: true, defaultStructuralSharing: true, defaultPreloadStaleTime: 0, - // history, }); declare module "@tanstack/react-router" { @@ -42,7 +34,7 @@ const App = () => { ); }; -const AppWithProviders = () => { +export const Widget = () => { preload(TRADING_VIEW_WIDGET_SCRIPT_URL, { as: "script" }); return ( @@ -52,5 +44,3 @@ const AppWithProviders = () => { ); }; - -export default AppWithProviders; diff --git a/src/components/modules/Account/Deposit/index.tsx b/packages/widget/src/components/modules/Account/Deposit/index.tsx similarity index 79% rename from src/components/modules/Account/Deposit/index.tsx rename to packages/widget/src/components/modules/Account/Deposit/index.tsx index 117d17b..c960ba9 100644 --- a/src/components/modules/Account/Deposit/index.tsx +++ b/packages/widget/src/components/modules/Account/Deposit/index.tsx @@ -1,26 +1,30 @@ import { Result } from "@effect-atom/atom-react"; import { Navigate } from "@tanstack/react-router"; +import { + Button, + PercentageSlider, + Skeleton, + Text, +} from "@yieldxyz/perps-common/components"; +import type { + TokenBalance, + WalletConnected, +} from "@yieldxyz/perps-common/domain"; import { DepositForm, useDepositForm, useDepositPercentage, - useProviders, - useSelectedProvider, useSelectedTokenBalance, useTokenAmountValue, useTokenBalances, -} from "@/components/modules/Account/Deposit/state"; -import { BackButton } from "@/components/molecules/navigation/back-button"; -import { WalletProtectedRoute } from "@/components/molecules/navigation/wallet-protected-route"; -import { PercentageSlider } from "@/components/molecules/percentage-slider"; -import { ProviderSelect } from "@/components/molecules/provider-select"; -import { TokenBalanceSelect } from "@/components/molecules/token-balances-select"; -import { Button } from "@/components/ui/button"; -import { Skeleton } from "@/components/ui/skeleton"; -import type { TokenBalance } from "@/domain/types"; -import type { WalletConnected } from "@/domain/wallet"; -import { formatTokenAmount } from "@/lib/utils"; -import type { ProviderDto } from "@/services/api-client/api-schemas"; +} from "@yieldxyz/perps-common/hooks"; +import { formatTokenAmount } from "@yieldxyz/perps-common/lib"; +import type { ApiSchemas } from "@yieldxyz/perps-common/services"; +import { BackButton } from "../../../molecules/navigation/back-button"; +import { WalletProtectedRoute } from "../../../molecules/navigation/wallet-protected-route"; +import { ProviderSelect } from "../../../molecules/provider-select"; +import { TokenBalanceSelect } from "../../../molecules/token-balances-select"; +import { useProviders, useSelectedProvider } from "./state"; function AccountDepositContent({ wallet, @@ -32,9 +36,9 @@ function AccountDepositContent({ }: { wallet: WalletConnected; selectedTokenBalance: TokenBalance; - selectedProvider: ProviderDto; - providers: ReadonlyArray; - setSelectedProvider: (provider: ProviderDto) => void; + selectedProvider: ApiSchemas.ProviderDto; + providers: ReadonlyArray; + setSelectedProvider: (provider: ApiSchemas.ProviderDto) => void; setSelectedTokenBalance: (tokenBalance: TokenBalance) => void; }) { const { tokenAmountValue } = useTokenAmountValue( @@ -51,9 +55,9 @@ function AccountDepositContent({
{/* Protocol Selector */} -

+ Select provider -

+ -

+ {tokenAmountValue} -

+
{/* Token Selector */} @@ -87,19 +91,19 @@ function AccountDepositContent({ -

+ Available:{" "} {formatTokenAmount({ amount: selectedTokenBalance.amount, symbol: selectedTokenBalance.token.symbol, })}{" "} -

+ {/* Slider Section */}
-

+ Deposit: {percentage}% -

+ -

+ Deposit -

+
{/* Content */} @@ -189,7 +193,7 @@ export function AccountDepositWithWallet({
diff --git a/src/components/modules/Home/Positions/index.tsx b/packages/widget/src/components/modules/Home/Positions/index.tsx similarity index 78% rename from src/components/modules/Home/Positions/index.tsx rename to packages/widget/src/components/modules/Home/Positions/index.tsx index a2fa436..b081ac2 100644 --- a/src/components/modules/Home/Positions/index.tsx +++ b/packages/widget/src/components/modules/Home/Positions/index.tsx @@ -1,19 +1,22 @@ import { Result, useAtomValue } from "@effect-atom/atom-react"; -import { Array as _Array, Match, Option, Record } from "effect"; -import { useState } from "react"; -import { marketsAtom } from "@/atoms/markets-atoms"; import { + marketsAtom, ordersAtom, positionsAtom, selectedProviderBalancesAtom, -} from "@/atoms/portfolio-atoms"; -import { walletAtom } from "@/atoms/wallet-atom"; -import { OrderCard } from "@/components/modules/Home/Positions/order-card"; -import { PositionCard } from "@/components/modules/Home/Positions/position-card"; -import { Skeleton } from "@/components/ui/skeleton"; -import { isWalletConnected, type WalletConnected } from "@/domain/wallet"; -import { formatAmount, formatPercentage } from "@/lib/utils"; -import type { OrderDto } from "@/services/api-client/client-factory"; + walletAtom, +} from "@yieldxyz/perps-common/atoms"; +import { Skeleton, Text } from "@yieldxyz/perps-common/components"; +import { + isWalletConnected, + type WalletConnected, +} from "@yieldxyz/perps-common/domain"; +import { formatAmount, formatPercentage } from "@yieldxyz/perps-common/lib"; +import type { ApiSchemas } from "@yieldxyz/perps-common/services"; +import { Array as _Array, Match, Option, Record } from "effect"; +import { useState } from "react"; +import { OrderCard } from "./order-card"; +import { PositionCard } from "./position-card"; function PositionsWithWallet({ wallet }: { wallet: WalletConnected }) { const [activeTab, setActiveTab] = useState<"positions" | "orders">( @@ -89,7 +92,7 @@ function PositionsWithWallet({ wallet }: { wallet: WalletConnected }) { marketRef: m, position: p, orders: Record.get(ordersMap, p.marketId).pipe( - Option.getOrElse(() => [] as OrderDto[]), + Option.getOrElse(() => [] as ApiSchemas.OrderDto[]), ), })), ), @@ -114,12 +117,12 @@ function PositionsWithWallet({ wallet }: { wallet: WalletConnected }) { if (!totalsData) { return (
-

+ Unable to load data -

-

+ + Please try again later -

+
); } @@ -130,31 +133,31 @@ function PositionsWithWallet({ wallet }: { wallet: WalletConnected }) {
{/* Total value section */}
- + {formatAmount(totalsData.accountValue)} - +
- {isPnlPositive ? "+" : ""} {formatAmount(totalsData.unrealizedPnl)} - - + {isPnlPositive ? "+" : ""} {formatPercentage(totalsData.pnlPercent)} - +
{/* Positions/Orders tabs */} -
+
@@ -296,7 +310,7 @@ function MarketOrderContent({ mode, }: { wallet: WalletConnected; - side: PositionDtoSide; + side: ApiTypes.PositionDtoSide; mode: OrderMode; }) { const { marketId } = useParams({ strict: false }) as { marketId: string }; @@ -324,7 +338,7 @@ export function MarketOrder({ side, mode = "open", }: { - side: PositionDtoSide; + side: ApiTypes.PositionDtoSide; mode: OrderMode; }) { return ( diff --git a/src/components/modules/Order/Overview/loading.tsx b/packages/widget/src/components/modules/Order/Overview/loading.tsx similarity index 92% rename from src/components/modules/Order/Overview/loading.tsx rename to packages/widget/src/components/modules/Order/Overview/loading.tsx index 71a0657..53f7132 100644 --- a/src/components/modules/Order/Overview/loading.tsx +++ b/packages/widget/src/components/modules/Order/Overview/loading.tsx @@ -1,5 +1,5 @@ -import { SLIDER_STOPS } from "@/components/modules/Order/Overview/state"; -import { Skeleton } from "@/components/ui/skeleton"; +import { SLIDER_STOPS } from "@yieldxyz/perps-common/atoms"; +import { Skeleton } from "@yieldxyz/perps-common/components"; export function OrderLoading() { return ( diff --git a/src/components/modules/Order/sign.tsx b/packages/widget/src/components/modules/Order/sign.tsx similarity index 57% rename from src/components/modules/Order/sign.tsx rename to packages/widget/src/components/modules/Order/sign.tsx index ab2f793..76f7102 100644 --- a/src/components/modules/Order/sign.tsx +++ b/packages/widget/src/components/modules/Order/sign.tsx @@ -1,4 +1,4 @@ -import { SignTransactionsRoute } from "@/components/molecules/sign"; +import { SignTransactionsRoute } from "../../molecules/sign"; export function OrderSignRoute() { return ; diff --git a/src/components/modules/PositionDetails/Close/index.tsx b/packages/widget/src/components/modules/PositionDetails/Close/index.tsx similarity index 71% rename from src/components/modules/PositionDetails/Close/index.tsx rename to packages/widget/src/components/modules/PositionDetails/Close/index.tsx index 95e62fe..4b30a2a 100644 --- a/src/components/modules/PositionDetails/Close/index.tsx +++ b/packages/widget/src/components/modules/PositionDetails/Close/index.tsx @@ -1,22 +1,29 @@ import { Result } from "@effect-atom/atom-react"; import { Navigate, useParams } from "@tanstack/react-router"; +import { SLIDER_STOPS } from "@yieldxyz/perps-common/atoms"; +import { + Button, + Divider, + PercentageSlider, + Skeleton, + Text, +} from "@yieldxyz/perps-common/components"; +import type { WalletConnected } from "@yieldxyz/perps-common/domain"; import { - SLIDER_STOPS, useCloseCalculations, useClosePercentage, - usePosition, useSubmitClose, -} from "@/components/modules/PositionDetails/Close/state"; -import { BackButton } from "@/components/molecules/navigation/back-button"; -import { WalletProtectedRoute } from "@/components/molecules/navigation/wallet-protected-route"; -import { PercentageSlider } from "@/components/molecules/percentage-slider"; -import { Button } from "@/components/ui/button"; -import { Divider } from "@/components/ui/divider"; -import { Skeleton } from "@/components/ui/skeleton"; -import { getPositionChangePercent } from "@/domain/position"; -import type { WalletConnected } from "@/domain/wallet"; -import { formatAmount, formatPercentage, formatTokenAmount } from "@/lib/utils"; -import type { PositionDto } from "@/services/api-client/api-schemas"; +} from "@yieldxyz/perps-common/hooks"; +import { + formatAmount, + formatPercentage, + formatTokenAmount, + getPositionChangePercent, +} from "@yieldxyz/perps-common/lib"; +import type { ApiTypes } from "@yieldxyz/perps-common/services"; +import { BackButton } from "../../../molecules/navigation/back-button"; +import { WalletProtectedRoute } from "../../../molecules/navigation/wallet-protected-route"; +import { usePosition } from "./state"; function ClosePositionLoading() { return ( @@ -68,7 +75,7 @@ function ClosePositionContent({ position, }: { wallet: WalletConnected; - position: PositionDto; + position: ApiTypes.PositionDto; }) { const { closePercentage, setClosePercentage } = useClosePercentage(); const calculations = useCloseCalculations(position); @@ -88,22 +95,22 @@ function ClosePositionContent({
- + Close amount - +
- + {formatAmount(position.markPrice)} - - + {isPositive ? "+" : ""} {formatPercentage(priceChangePercent)} - +
@@ -112,18 +119,18 @@ function ClosePositionContent({
{/* Amount Display */}
-

+ Select amount to close -

-

+ + {formatAmount(calculations.closeValue)} -

-

+ + {formatTokenAmount({ amount: calculations.closeSize, symbol: "Size:", })} -

+
{/* Slider */} @@ -138,21 +145,23 @@ function ClosePositionContent({
{/* Margin Row */}
- + Margin - +
- + {formatAmount(calculations.marginReturn)} - - + {isPnlPositive ? "+" : ""} {formatAmount(calculations.pnlReturn)} - +
@@ -160,12 +169,12 @@ function ClosePositionContent({ {/* You will receive Row */}
- + You will receive - - + + {formatAmount(calculations.youWillReceive)} - +
@@ -176,7 +185,8 @@ function ClosePositionContent({ onClick={handleSubmit} loading={submitResult.waiting} disabled={submitResult.waiting || closePercentage === 0} - className="w-full h-14 bg-white text-black hover:bg-white/90 text-base font-semibold" + size="lg" + className="w-full text-base font-semibold bg-white text-black hover:bg-white/90" > {submitResult.waiting ? "Processing..." : "Close position"} diff --git a/src/components/modules/PositionDetails/Close/sign.tsx b/packages/widget/src/components/modules/PositionDetails/Close/sign.tsx similarity index 59% rename from src/components/modules/PositionDetails/Close/sign.tsx rename to packages/widget/src/components/modules/PositionDetails/Close/sign.tsx index 983a448..61010aa 100644 --- a/src/components/modules/PositionDetails/Close/sign.tsx +++ b/packages/widget/src/components/modules/PositionDetails/Close/sign.tsx @@ -1,4 +1,4 @@ -import { SignTransactionsRoute } from "@/components/molecules/sign"; +import { SignTransactionsRoute } from "../../../molecules/sign"; export function CloseSignRoute() { return ; diff --git a/packages/widget/src/components/modules/PositionDetails/Close/state.tsx b/packages/widget/src/components/modules/PositionDetails/Close/state.tsx new file mode 100644 index 0000000..1c15c7b --- /dev/null +++ b/packages/widget/src/components/modules/PositionDetails/Close/state.tsx @@ -0,0 +1,33 @@ +import { Atom, useAtomValue } from "@effect-atom/atom-react"; +import { positionsAtom } from "@yieldxyz/perps-common/atoms"; +import type { WalletAccount } from "@yieldxyz/perps-common/domain"; +import { type ApiTypes, runtimeAtom } from "@yieldxyz/perps-common/services"; +import { Data, Effect } from "effect"; + +export type { ApiTypes }; + +const closePositionAtom = Atom.family( + (args: { walletAddress: WalletAccount["address"]; marketId: string }) => + runtimeAtom.atom( + Effect.fn(function* (ctx) { + const positions = yield* ctx.result(positionsAtom(args.walletAddress)); + + const position = positions.find((p) => p.marketId === args.marketId); + + if (!position) { + return yield* Effect.dieMessage("Position not found"); + } + + return position; + }), + ), +); + +export const usePosition = ( + walletAddress: WalletAccount["address"], + marketId: string, +) => { + return useAtomValue( + closePositionAtom(Data.struct({ walletAddress, marketId })), + ); +}; diff --git a/src/components/modules/PositionDetails/Overview/CancelOrder/sign.tsx b/packages/widget/src/components/modules/PositionDetails/Overview/CancelOrder/sign.tsx similarity index 60% rename from src/components/modules/PositionDetails/Overview/CancelOrder/sign.tsx rename to packages/widget/src/components/modules/PositionDetails/Overview/CancelOrder/sign.tsx index 8f18800..970d176 100644 --- a/src/components/modules/PositionDetails/Overview/CancelOrder/sign.tsx +++ b/packages/widget/src/components/modules/PositionDetails/Overview/CancelOrder/sign.tsx @@ -1,4 +1,4 @@ -import { SignTransactionsRoute } from "@/components/molecules/sign"; +import { SignTransactionsRoute } from "../../../../molecules/sign"; export function CancelOrderSignRoute() { return ; diff --git a/src/components/modules/PositionDetails/Overview/EditLeverage/sign.tsx b/packages/widget/src/components/modules/PositionDetails/Overview/EditLeverage/sign.tsx similarity index 61% rename from src/components/modules/PositionDetails/Overview/EditLeverage/sign.tsx rename to packages/widget/src/components/modules/PositionDetails/Overview/EditLeverage/sign.tsx index b0d45fd..604b7ff 100644 --- a/src/components/modules/PositionDetails/Overview/EditLeverage/sign.tsx +++ b/packages/widget/src/components/modules/PositionDetails/Overview/EditLeverage/sign.tsx @@ -1,4 +1,4 @@ -import { SignTransactionsRoute } from "@/components/molecules/sign"; +import { SignTransactionsRoute } from "../../../../molecules/sign"; export function EditLeverageSignRoute() { return ; diff --git a/src/components/modules/PositionDetails/Overview/Orders/index.tsx b/packages/widget/src/components/modules/PositionDetails/Overview/Orders/index.tsx similarity index 68% rename from src/components/modules/PositionDetails/Overview/Orders/index.tsx rename to packages/widget/src/components/modules/PositionDetails/Overview/Orders/index.tsx index 5e224e3..17af430 100644 --- a/src/components/modules/PositionDetails/Overview/Orders/index.tsx +++ b/packages/widget/src/components/modules/PositionDetails/Overview/Orders/index.tsx @@ -1,28 +1,41 @@ import { Result, useAtomSet, useAtomValue } from "@effect-atom/atom-react"; import { Navigate } from "@tanstack/react-router"; -import { cancelOrderAtom } from "@/atoms/orders-pending-actions-atom"; -import { ordersAtom } from "@/atoms/portfolio-atoms"; -import { walletAtom } from "@/atoms/wallet-atom"; -import { Button } from "@/components/ui/button"; -import { Card, CardSection } from "@/components/ui/card"; -import { Skeleton } from "@/components/ui/skeleton"; -import { isWalletConnected, type WalletConnected } from "@/domain/wallet"; -import { useOrderActions } from "@/hooks/use-order-actions"; -import { formatAmount, formatDate, formatSnakeCase } from "@/lib/utils"; -import type { MarketDto, OrderDto } from "@/services/api-client/client-factory"; +import { + cancelOrderAtom, + ordersAtom, + walletAtom, +} from "@yieldxyz/perps-common/atoms"; +import { + Button, + Card, + CardSection, + Skeleton, + Text, +} from "@yieldxyz/perps-common/components"; +import { + isWalletConnected, + type WalletConnected, +} from "@yieldxyz/perps-common/domain"; +import { useOrderActions } from "@yieldxyz/perps-common/hooks"; +import { + calcNotionalUsd, + formatAmount, + formatDate, + formatSnakeCase, +} from "@yieldxyz/perps-common/lib"; +import type { ApiTypes } from "@yieldxyz/perps-common/services"; function OrderCard({ order, market, wallet, }: { - order: OrderDto; - market: MarketDto; + order: ApiTypes.OrderDto; + market: ApiTypes.MarketDto; wallet: WalletConnected; }) { const price = order.limitPrice ?? order.triggerPrice ?? 0; - const sizeNum = Number.parseFloat(order.size); - const value = price * sizeNum; + const value = calcNotionalUsd({ priceUsd: price, sizeBase: order.size }); const { cancelOrderAction } = useOrderActions(order); @@ -32,22 +45,22 @@ function OrderCard({ {/* Order info */}
- + {formatSnakeCase(order.type)} - - + + {formatDate(order.createdAt)} - +
{/* Value and size */}
- + {formatAmount(value)} - - + + {order.size} {market.baseAsset.symbol} - +
@@ -57,32 +70,34 @@ function OrderCard({ className="flex items-start gap-4" >
- + {order.limitPrice ? "Limit" : "Trigger"} - - + + {formatAmount(price)} - +
- + Market - - + + {formatAmount(market.markPrice)} - +
- + Side - - + {order.side === "long" ? "Long" : "Short"} - +
@@ -146,7 +161,7 @@ function OrdersTabContentWithWallet({ market, }: { wallet: WalletConnected; - market: MarketDto; + market: ApiTypes.MarketDto; }) { const ordersResult = useAtomValue(ordersAtom(wallet.currentAccount.address)); @@ -162,7 +177,7 @@ function OrdersTabContentWithWallet({ Result.map((allOrders) => allOrders.filter((o) => o.marketId === market.id), ), - Result.getOrElse(() => [] as OrderDto[]), + Result.getOrElse(() => [] as ApiTypes.OrderDto[]), ); if (orders.length === 0) { @@ -172,9 +187,9 @@ function OrdersTabContentWithWallet({ position="only" className="flex flex-col items-center py-8" > - + No open orders for this market - + ); @@ -194,18 +209,18 @@ function OrdersTabContentWithWallet({ ); } -export function OrdersTabContent({ market }: { market: MarketDto }) { +export function OrdersTabContent({ market }: { market: ApiTypes.MarketDto }) { const wallet = useAtomValue(walletAtom).pipe(Result.getOrElse(() => null)); if (!isWalletConnected(wallet)) { return (
-

+ Wallet not connected -

-

+ + Connect your wallet to see your orders -

+
); } diff --git a/src/components/modules/PositionDetails/Overview/Position/index.tsx b/packages/widget/src/components/modules/PositionDetails/Overview/Position/index.tsx similarity index 71% rename from src/components/modules/PositionDetails/Overview/Position/index.tsx rename to packages/widget/src/components/modules/PositionDetails/Overview/Position/index.tsx index a102574..9679dfd 100644 --- a/src/components/modules/PositionDetails/Overview/Position/index.tsx +++ b/packages/widget/src/components/modules/PositionDetails/Overview/Position/index.tsx @@ -1,28 +1,40 @@ import { Result, useAtomValue } from "@effect-atom/atom-react"; import { Link, Navigate } from "@tanstack/react-router"; -import { ordersAtom, positionsAtom } from "@/atoms/portfolio-atoms"; -import { walletAtom } from "@/atoms/wallet-atom"; -import { LeverageDialog } from "@/components/modules/Order/Overview/leverage-dialog"; import { - getTPOrSLConfigurationFromPosition, + ordersAtom, + positionsAtom, + walletAtom, +} from "@yieldxyz/perps-common/atoms"; +import { + Button, + Card, + CardSection, + LeverageDialog, + Skeleton, + Text, TPOrSLDialog, type TPOrSLOption, type TPOrSLSettings, -} from "@/components/molecules/tp-sl-dialog"; -import { Button } from "@/components/ui/button"; -import { Card, CardSection } from "@/components/ui/card"; -import { Skeleton } from "@/components/ui/skeleton"; -import { getMaxLeverage } from "@/domain/market"; -import { isWalletConnected, type WalletConnected } from "@/domain/wallet"; -import { usePositionActions } from "@/hooks/use-position-actions"; -import { useTpSlOrders } from "@/hooks/use-tp-sl-orders"; -import { formatAmount, formatPercentage } from "@/lib/utils"; -import type { OrderDto } from "@/services/api-client/api-schemas"; -import type { - MarketDto, - PositionDto, -} from "@/services/api-client/client-factory"; -import { useEditSLTP, useUpdateLeverage } from "./state"; +} from "@yieldxyz/perps-common/components"; +import { + isWalletConnected, + type WalletConnected, +} from "@yieldxyz/perps-common/domain"; +import { + useEditSLTP, + usePositionActions, + useTpSlOrders, + useUpdateLeverage, +} from "@yieldxyz/perps-common/hooks"; +import { + calcNotionalUsd, + calcPnlPercent, + formatAmount, + formatPercentage, + getMaxLeverage, + getTPOrSLConfigurationFromPosition, +} from "@yieldxyz/perps-common/lib"; +import type { ApiTypes } from "@yieldxyz/perps-common/services"; function PositionCardContent({ position, @@ -30,9 +42,9 @@ function PositionCardContent({ wallet, orders, }: { - orders: OrderDto[]; - position: PositionDto; - market: MarketDto; + orders: ApiTypes.OrderDto[]; + position: ApiTypes.PositionDto; + market: ApiTypes.MarketDto; wallet: WalletConnected; }) { const { editTPResult, editTP, editSLResult, editSL } = useEditSLTP(); @@ -76,10 +88,14 @@ function PositionCardContent({ }; const symbol = market.baseAsset.symbol; - const sizeNum = Number.parseFloat(position.size); - const value = position.markPrice * sizeNum; - const pnlPercent = - position.margin > 0 ? (position.unrealizedPnl / position.margin) * 100 : 0; + const value = calcNotionalUsd({ + priceUsd: position.markPrice, + sizeBase: position.size, + }); + const pnlPercent = calcPnlPercent({ + pnlUsd: position.unrealizedPnl, + marginUsd: position.margin, + }); const isPnlPositive = position.unrealizedPnl >= 0; if (Result.isSuccess(editTPResult) || Result.isSuccess(editSLResult)) { @@ -105,90 +121,92 @@ function PositionCardContent({ {/* Header Row - Symbol & PnL */}
- + {symbol} {position.leverage}x - - + + {position.size} {symbol} - +
- + {formatAmount(value)} - - + {isPnlPositive ? "+" : ""} {formatAmount(position.unrealizedPnl)} ({isPnlPositive ? "+" : ""} {formatPercentage(pnlPercent)}) - +
{/* Second Row - Entry, Liq. Price, Margin */}
- + Entry - - + + {formatAmount(position.entryPrice)} - +
- + Liq. Price - - + + {formatAmount(position.liquidationPrice)} - +
- + Margin - - + + {formatAmount(position.margin)} - +
{/* Third Row - Take profit, Stop loss, Side */}
- + Take profit - - + + {tpSlOrders.takeProfit?.triggerPrice ? formatAmount(tpSlOrders.takeProfit.triggerPrice) : "Not set"} - +
- + Stop loss - - + + {tpSlOrders.stopLoss?.triggerPrice ? formatAmount(tpSlOrders.stopLoss.triggerPrice) : "Not set"} - +
- + Side - - + {position.side === "long" ? "Long" : "Short"} - +
@@ -212,8 +230,7 @@ function PositionCardContent({ > @@ -73,7 +85,10 @@ function BottomButtonsContent({ params={{ marketId: market.id, side: "short" }} className="flex-1" > - @@ -86,7 +101,7 @@ function BottomButtonsContent({ ); } -function BottomButtons({ market }: { market: MarketDto }) { +function BottomButtons({ market }: { market: ApiTypes.MarketDto }) { const wallet = useAtomValue(walletAtom).pipe(Result.getOrElse(() => null)); if (!isWalletConnected(wallet)) { @@ -101,7 +116,7 @@ function PositionDetailsContent({ marketRef, initialTab, }: { - marketRef: AtomRef.AtomRef; + marketRef: AtomRef.AtomRef; initialTab?: "overview" | "position" | "orders"; }) { const market = useAtomRef(marketRef); @@ -130,32 +145,32 @@ function PositionDetailsContent({
- + {symbol} - - + + {maxLeverage}x - +
- + {formatAmount(market.markPrice)} - - + {isPositive ? "+" : ""} {formatPercentage(market.priceChangePercent24h)} - +
{/* Chart Placeholder */}
- +
{/* Tabs */} @@ -203,12 +218,12 @@ export function PositionDetails() { if (!Result.isSuccess(marketRef)) { return (
-

+ Market not found -

-

+ + The market you're looking for doesn't exist -

+ diff --git a/src/components/modules/PositionDetails/Overview/loading.tsx b/packages/widget/src/components/modules/PositionDetails/Overview/loading.tsx similarity index 92% rename from src/components/modules/PositionDetails/Overview/loading.tsx rename to packages/widget/src/components/modules/PositionDetails/Overview/loading.tsx index 0a776af..a24c8cb 100644 --- a/src/components/modules/PositionDetails/Overview/loading.tsx +++ b/packages/widget/src/components/modules/PositionDetails/Overview/loading.tsx @@ -1,4 +1,4 @@ -import { Skeleton } from "@/components/ui/skeleton"; +import { Skeleton } from "@yieldxyz/perps-common/components"; export function PositionDetailsLoading() { return ( diff --git a/src/components/modules/PositionDetails/Overview/modify-dialog.tsx b/packages/widget/src/components/modules/PositionDetails/Overview/modify-dialog.tsx similarity index 79% rename from src/components/modules/PositionDetails/Overview/modify-dialog.tsx rename to packages/widget/src/components/modules/PositionDetails/Overview/modify-dialog.tsx index 2a3242f..18c8adf 100644 --- a/src/components/modules/PositionDetails/Overview/modify-dialog.tsx +++ b/packages/widget/src/components/modules/PositionDetails/Overview/modify-dialog.tsx @@ -1,8 +1,7 @@ import { Link } from "@tanstack/react-router"; +import { Button, Dialog, Text } from "@yieldxyz/perps-common/components"; +import type { ApiTypes } from "@yieldxyz/perps-common/services"; import { ArrowDownRight, ArrowUpRight } from "lucide-react"; -import { Button } from "@/components/ui/button"; -import { Dialog } from "@/components/ui/dialog"; -import type { PositionDtoSide } from "@/services/api-client/client-factory"; const MODIFY_OPTIONS = [ { @@ -24,7 +23,7 @@ export function ModifyDialog({ side, }: { marketId: string; - side: PositionDtoSide; + side: ApiTypes.PositionDtoSide; }) { return ( @@ -33,7 +32,8 @@ export function ModifyDialog({ render={(props) => ( @@ -67,12 +67,12 @@ export function ModifyDialog({
- + {option.label} - - + + {option.description} - +
); diff --git a/packages/widget/src/components/modules/PositionDetails/Overview/overview-tab-content.tsx b/packages/widget/src/components/modules/PositionDetails/Overview/overview-tab-content.tsx new file mode 100644 index 0000000..7e3c99c --- /dev/null +++ b/packages/widget/src/components/modules/PositionDetails/Overview/overview-tab-content.tsx @@ -0,0 +1,96 @@ +import { Card, CardSection, Text } from "@yieldxyz/perps-common/components"; +import { + estimateLowHighFromAbsoluteChange, + formatAmount, + formatCompactUsdAmount, + formatRate, +} from "@yieldxyz/perps-common/lib"; +import type { ApiTypes } from "@yieldxyz/perps-common/services"; + +export function OverviewTabContent({ market }: { market: ApiTypes.MarketDto }) { + const currentPrice = market.markPrice; + const priceChange24h = market.priceChange24h; + + const { low: estimatedLow, high: estimatedHigh } = + estimateLowHighFromAbsoluteChange({ + currentPrice, + priceChange24h, + }); + + return ( + + +
+ + 24h low + + + {formatAmount(estimatedLow)} + +
+
+ + 24h high + + + {formatAmount(estimatedHigh)} + +
+
+ +
+ + 24h volume + + + {formatCompactUsdAmount(market.volume24h)} + +
+
+ + Open Interest + + + {formatCompactUsdAmount(market.openInterest)} + +
+
+ +
+ + Funding Rate + + + {formatRate(market.fundingRate, { maximumFractionDigits: 4 })} + +
+
+ + Funding Interval + + + {market.fundingRateIntervalHours}h + +
+
+ +
+ + Maker Fee + + + {market.makerFee ? formatRate(market.makerFee) : "-"} + +
+
+ + Taker Fee + + + {market.takerFee ? formatRate(market.takerFee) : "-"} + +
+
+
+ ); +} diff --git a/src/components/modules/Root/PreloadAtoms.tsx b/packages/widget/src/components/modules/Root/PreloadAtoms.tsx similarity index 70% rename from src/components/modules/Root/PreloadAtoms.tsx rename to packages/widget/src/components/modules/Root/PreloadAtoms.tsx index 49bba95..06dfdca 100644 --- a/src/components/modules/Root/PreloadAtoms.tsx +++ b/packages/widget/src/components/modules/Root/PreloadAtoms.tsx @@ -1,14 +1,18 @@ import { Result, useAtomMount, useAtomValue } from "@effect-atom/atom-react"; -import { marketsAtom, refreshMarketsAtom } from "@/atoms/markets-atoms"; import { + marketsAtom, + moralisTokenBalancesAtom, ordersAtom, positionsAtom, + providersAtom, providersBalancesAtom, -} from "@/atoms/portfolio-atoms"; -import { providersAtom } from "@/atoms/providers-atoms"; -import { moralisTokenBalancesAtom } from "@/atoms/tokens-atoms"; -import { walletAtom } from "@/atoms/wallet-atom"; -import { isWalletConnected, type WalletConnected } from "@/domain/wallet"; + refreshMarketsAtom, + walletAtom, +} from "@yieldxyz/perps-common/atoms"; +import { + isWalletConnected, + type WalletConnected, +} from "@yieldxyz/perps-common/domain"; const PreloadWalletConnectedAtoms = ({ wallet, diff --git a/src/components/molecules/account-value-display.tsx b/packages/widget/src/components/molecules/account-value-display.tsx similarity index 62% rename from src/components/molecules/account-value-display.tsx rename to packages/widget/src/components/molecules/account-value-display.tsx index be6948f..8d2ce7d 100644 --- a/src/components/molecules/account-value-display.tsx +++ b/packages/widget/src/components/molecules/account-value-display.tsx @@ -1,8 +1,8 @@ import { Result, useAtomValue } from "@effect-atom/atom-react"; -import { selectedProviderBalancesAtom } from "@/atoms/portfolio-atoms"; -import { Skeleton } from "@/components/ui/skeleton"; -import type { WalletConnected } from "@/domain/wallet"; -import { cn, formatAmount, getTokenLogo } from "@/lib/utils"; +import { selectedProviderBalancesAtom } from "@yieldxyz/perps-common/atoms"; +import { Skeleton, Text } from "@yieldxyz/perps-common/components"; +import type { WalletConnected } from "@yieldxyz/perps-common/domain"; +import { cn, formatAmount, getTokenLogo } from "@yieldxyz/perps-common/lib"; export function AccountValueDisplay({ wallet }: { wallet: WalletConnected }) { const selectedProviderBalances = useAtomValue( @@ -18,12 +18,12 @@ export function AccountValueDisplay({ wallet }: { wallet: WalletConnected }) { className="size-9" />
-

+ Account value -

-

+ + {formatAmount(selectedProviderBalances.value.accountValue)} -

+
); diff --git a/src/components/molecules/navigation/back-button.tsx b/packages/widget/src/components/molecules/navigation/back-button.tsx similarity index 84% rename from src/components/molecules/navigation/back-button.tsx rename to packages/widget/src/components/molecules/navigation/back-button.tsx index 615dfee..09991ca 100644 --- a/src/components/molecules/navigation/back-button.tsx +++ b/packages/widget/src/components/molecules/navigation/back-button.tsx @@ -1,6 +1,6 @@ import { useRouter } from "@tanstack/react-router"; +import { Button } from "@yieldxyz/perps-common/components"; import { ChevronLeft } from "lucide-react"; -import { Button } from "@/components/ui/button"; export function BackButton() { const { history } = useRouter(); diff --git a/src/components/molecules/navigation/wallet-protected-route.tsx b/packages/widget/src/components/molecules/navigation/wallet-protected-route.tsx similarity index 73% rename from src/components/molecules/navigation/wallet-protected-route.tsx rename to packages/widget/src/components/molecules/navigation/wallet-protected-route.tsx index 43ee7cc..05d5df1 100644 --- a/src/components/molecules/navigation/wallet-protected-route.tsx +++ b/packages/widget/src/components/molecules/navigation/wallet-protected-route.tsx @@ -1,7 +1,10 @@ import { Result, useAtomValue } from "@effect-atom/atom-react"; import { Navigate } from "@tanstack/react-router"; -import { walletAtom } from "@/atoms/wallet-atom"; -import { isWalletConnected, type WalletConnected } from "@/domain/wallet"; +import { walletAtom } from "@yieldxyz/perps-common/atoms"; +import { + isWalletConnected, + type WalletConnected, +} from "@yieldxyz/perps-common/domain"; export const WalletProtectedRoute = ({ children, diff --git a/src/components/molecules/provider-select.tsx b/packages/widget/src/components/molecules/provider-select.tsx similarity index 82% rename from src/components/molecules/provider-select.tsx rename to packages/widget/src/components/molecules/provider-select.tsx index 4266aee..2449ca7 100644 --- a/src/components/molecules/provider-select.tsx +++ b/packages/widget/src/components/molecules/provider-select.tsx @@ -1,4 +1,9 @@ import { Result, useAtomValue } from "@effect-atom/atom-react"; +import hyperliquidLogo from "@yieldxyz/perps-common/assets/hyperliquid.png"; +import { providersAtom } from "@yieldxyz/perps-common/atoms"; +import { Button, Dialog, Text } from "@yieldxyz/perps-common/components"; +import { cn } from "@yieldxyz/perps-common/lib"; +import type { ApiTypes } from "@yieldxyz/perps-common/services"; import { ChevronDown } from "lucide-react"; import { type ComponentProps, @@ -7,20 +12,14 @@ import { useContext, useState, } from "react"; -import hyperliquidLogo from "@/assets/hyperliquid.png"; -import { providersAtom } from "@/atoms/providers-atoms"; -import { Button } from "@/components/ui/button"; -import { Dialog } from "@/components/ui/dialog"; -import { cn } from "@/lib/utils"; -import type { ProviderDto } from "@/services/api-client/api-schemas"; // Context for sharing state between components interface ProviderSelectContextValue { open: boolean; setOpen: (open: boolean) => void; - selectedProvider: ProviderDto | null; - setSelectedProvider: (provider: ProviderDto) => void; - providers: ReadonlyArray; + selectedProvider: ApiTypes.ProviderDto | null; + setSelectedProvider: (provider: ApiTypes.ProviderDto) => void; + providers: ReadonlyArray; emptyContent: ReactNode; } @@ -42,7 +41,9 @@ function useProviderSelect() { function DefaultEmptyContent() { return (
- No providers available + + No providers available +
); } @@ -50,10 +51,10 @@ function DefaultEmptyContent() { // Root component - handles state interface RootProps { children: ReactNode; - defaultProvider?: ProviderDto; - value?: ProviderDto; - onValueChange?: (provider: ProviderDto) => void; - providers: ReadonlyArray; + defaultProvider?: ApiTypes.ProviderDto; + value?: ApiTypes.ProviderDto; + onValueChange?: (provider: ApiTypes.ProviderDto) => void; + providers: ReadonlyArray; emptyContent?: ReactNode; } @@ -66,12 +67,13 @@ function Root({ emptyContent = , }: RootProps) { const [open, setOpen] = useState(false); - const [internalProvider, setInternalProvider] = useState( - defaultProvider ?? providers[0] ?? null, - ); + const [internalProvider, setInternalProvider] = + useState( + defaultProvider ?? providers[0] ?? null, + ); const selectedProvider = value ?? internalProvider; - const setSelectedProvider = (provider: ProviderDto) => { + const setSelectedProvider = (provider: ApiTypes.ProviderDto) => { if (!value) { setInternalProvider(provider); } @@ -120,16 +122,16 @@ function Trigger({ className, children, ...props }: TriggerProps) { alt={selectedProvider.name} className="size-6 rounded-full" /> - + {selectedProvider.name} - + ) : ( <> - + Select provider - + ))} @@ -231,9 +233,9 @@ function List({ className, children, ...props }: ListProps) { // Item component - individual provider item interface ItemProps extends Omit, "onSelect"> { - provider: ProviderDto; + provider: ApiTypes.ProviderDto; selected?: boolean; - onSelect?: (provider: ProviderDto) => void; + onSelect?: (provider: ApiTypes.ProviderDto) => void; } function Item({ @@ -277,9 +279,9 @@ function Item({ className="size-[26px] rounded-full object-cover" />
- + {provider.name} - +
); diff --git a/src/components/molecules/sign/index.tsx b/packages/widget/src/components/molecules/sign/index.tsx similarity index 67% rename from src/components/molecules/sign/index.tsx rename to packages/widget/src/components/molecules/sign/index.tsx index 84a5820..c440b50 100644 --- a/src/components/molecules/sign/index.tsx +++ b/packages/widget/src/components/molecules/sign/index.tsx @@ -1,10 +1,10 @@ import { useNavigate } from "@tanstack/react-router"; -import { signActionAtoms } from "@/atoms/actions-atoms"; -import { BackButton } from "@/components/molecules/navigation/back-button"; -import { WalletProtectedRoute } from "@/components/molecules/navigation/wallet-protected-route"; -import { SignTransactions } from "@/components/molecules/sign/sign-content"; -import { Button } from "@/components/ui/button"; -import type { WalletConnected } from "@/domain/wallet"; +import { signActionAtoms } from "@yieldxyz/perps-common/atoms"; +import { Button, Text } from "@yieldxyz/perps-common/components"; +import type { WalletConnected } from "@yieldxyz/perps-common/domain"; +import { BackButton } from "../navigation/back-button"; +import { WalletProtectedRoute } from "../navigation/wallet-protected-route"; +import { SignTransactions } from "./sign-content"; function SignTransactionsWithWallet({ wallet, @@ -22,9 +22,9 @@ function SignTransactionsWithWallet({ {/* Header */}
-

+ {title} -

+
{/* Sign Transactions Component */} diff --git a/packages/widget/src/components/molecules/sign/sign-content.tsx b/packages/widget/src/components/molecules/sign/sign-content.tsx new file mode 100644 index 0000000..386bdfd --- /dev/null +++ b/packages/widget/src/components/molecules/sign/sign-content.tsx @@ -0,0 +1,57 @@ +import { Result, useAtomSet, useAtomValue } from "@effect-atom/atom-react"; +import { Navigate } from "@tanstack/react-router"; +import type { signActionAtoms } from "@yieldxyz/perps-common/atoms"; +import { + Skeleton, + TransactionProgress, +} from "@yieldxyz/perps-common/components"; +import type { SignTransactionsState } from "@yieldxyz/perps-common/domain"; + +interface SignTransactionsProps { + state: SignTransactionsState; + retry: () => void; +} + +function SignTransactionsWithState({ state, retry }: SignTransactionsProps) { + return ( +
+

+ Progress +

+ + retry()} /> +
+ ); +} + +export function SignTransactions({ + machineAtoms, +}: { + machineAtoms: ReturnType; +}) { + const { machineStreamAtom, retryMachineAtom } = machineAtoms; + const state = useAtomValue(machineStreamAtom); + const retry = useAtomSet(retryMachineAtom); + + const result = Result.all({ state, retry }); + + if (Result.isFailure(result)) { + return ( + <> + + + + ); + } + + if (Result.isSuccess(result)) { + return ( + + ); + } + + return ; +} diff --git a/src/components/molecules/token-balances-select.tsx b/packages/widget/src/components/molecules/token-balances-select.tsx similarity index 91% rename from src/components/molecules/token-balances-select.tsx rename to packages/widget/src/components/molecules/token-balances-select.tsx index 9bd4fb0..16cb074 100644 --- a/src/components/molecules/token-balances-select.tsx +++ b/packages/widget/src/components/molecules/token-balances-select.tsx @@ -1,32 +1,36 @@ import { EvmNetworks } from "@stakekit/common"; -import { Record } from "effect"; -import { ChevronDown } from "lucide-react"; -import { - type ComponentProps, - createContext, - type ReactNode, - useContext, - useState, -} from "react"; import { type TokenBalances, yieldApiNetworkToMoralisChain, -} from "@/atoms/tokens-atoms"; +} from "@yieldxyz/perps-common/atoms"; import { + Button, + Dialog, + Tabs, + TabsContent, + TabsList, + TabsTrigger, + Text, TokenIcon, type TokenIconProps, -} from "@/components/molecules/token-icon"; -import { Button } from "@/components/ui/button"; -import { Dialog } from "@/components/ui/dialog"; -import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; -import type { TokenBalance } from "@/domain/types"; +} from "@yieldxyz/perps-common/components"; +import type { TokenBalance } from "@yieldxyz/perps-common/domain"; import { cn, formatSnakeCase, formatTokenAmount, getNetworkLogo, getTokenString, -} from "@/lib/utils"; +} from "@yieldxyz/perps-common/lib"; +import { Record } from "effect"; +import { ChevronDown } from "lucide-react"; +import { + type ComponentProps, + createContext, + type ReactNode, + useContext, + useState, +} from "react"; interface TokenBalanceSelectContextValue { open: boolean; @@ -54,7 +58,9 @@ function useTokenBalanceSelect() { function DefaultEmptyContent() { return (
- No tokens available + + No tokens available +
); } @@ -125,7 +131,7 @@ function TokenBalanceLogo({ )} @@ -154,16 +160,16 @@ function Trigger({ className, children, ...props }: TriggerProps) { (selectedTokenBalance ? ( <> - + {selectedTokenBalance.token.symbol} - + ) : ( <> - + Select token - + ))} @@ -184,7 +190,9 @@ function NetworkTabTrigger({ network }: NetworkTabTriggerProps) { name={formatSnakeCase(network)} size="xs" /> - {formatSnakeCase(network)} + + {formatSnakeCase(network)} + ); } @@ -405,22 +413,22 @@ function Item({ >
- + {tokenBalance.token.symbol} - - + + {tokenBalance.token.name} •{" "} {formatSnakeCase(tokenBalance.token.network)} - +
{tokenBalance.amount && ( - + {formatTokenAmount({ amount: tokenBalance.amount, symbol: tokenBalance.token.symbol, })} - + )}
diff --git a/packages/widget/src/main.css b/packages/widget/src/main.css new file mode 100644 index 0000000..7bdd4b1 --- /dev/null +++ b/packages/widget/src/main.css @@ -0,0 +1,19 @@ +html { + background: var(--surface-1); +} + +#app { + min-height: 100vh; + padding: 16px; + display: flex; + justify-content: center; + align-items: flex-start; + padding-top: 60px; + background: var(--surface-1); +} + +@media (min-width: 768px) { + #app { + padding: 32px; + } +} diff --git a/packages/widget/src/main.tsx b/packages/widget/src/main.tsx new file mode 100644 index 0000000..ba90f6b --- /dev/null +++ b/packages/widget/src/main.tsx @@ -0,0 +1,11 @@ +import "./main.css"; +import ReactDOM from "react-dom/client"; +import { Widget } from "./app"; + +import "@yieldxyz/perps-common/styles"; + +const rootElement = document.getElementById("app"); +if (rootElement && !rootElement.innerHTML) { + const root = ReactDOM.createRoot(rootElement); + root.render(); +} diff --git a/src/routeTree.gen.ts b/packages/widget/src/routeTree.gen.ts similarity index 100% rename from src/routeTree.gen.ts rename to packages/widget/src/routeTree.gen.ts diff --git a/src/routes/__root.tsx b/packages/widget/src/routes/__root.tsx similarity index 100% rename from src/routes/__root.tsx rename to packages/widget/src/routes/__root.tsx diff --git a/src/routes/account/deposit.tsx b/packages/widget/src/routes/account/deposit.tsx similarity index 66% rename from src/routes/account/deposit.tsx rename to packages/widget/src/routes/account/deposit.tsx index eb98155..4514716 100644 --- a/src/routes/account/deposit.tsx +++ b/packages/widget/src/routes/account/deposit.tsx @@ -1,5 +1,5 @@ import { createFileRoute } from "@tanstack/react-router"; -import { AccountDeposit } from "@/components/modules/Account/Deposit"; +import { AccountDeposit } from "../../components/modules/Account/Deposit"; export const Route = createFileRoute("/account/deposit")({ component: AccountDeposit, diff --git a/src/routes/account/deposit_/sign.tsx b/packages/widget/src/routes/account/deposit_/sign.tsx similarity index 65% rename from src/routes/account/deposit_/sign.tsx rename to packages/widget/src/routes/account/deposit_/sign.tsx index e6840f7..7f4b74d 100644 --- a/src/routes/account/deposit_/sign.tsx +++ b/packages/widget/src/routes/account/deposit_/sign.tsx @@ -1,5 +1,5 @@ import { createFileRoute } from "@tanstack/react-router"; -import { DepositSignRoute } from "@/components/modules/Account/Deposit/sign"; +import { DepositSignRoute } from "../../../components/modules/Account/Deposit/sign"; export const Route = createFileRoute("/account/deposit_/sign")({ component: DepositSignRoute, diff --git a/src/routes/account/index.tsx b/packages/widget/src/routes/account/index.tsx similarity index 65% rename from src/routes/account/index.tsx rename to packages/widget/src/routes/account/index.tsx index 31145b0..4e0518e 100644 --- a/src/routes/account/index.tsx +++ b/packages/widget/src/routes/account/index.tsx @@ -1,5 +1,5 @@ import { createFileRoute } from "@tanstack/react-router"; -import { AccountBalances } from "@/components/modules/Account/balance"; +import { AccountBalances } from "../../components/modules/Account/balance"; export const Route = createFileRoute("/account/")({ component: AccountBalances, diff --git a/src/routes/account/withdraw.tsx b/packages/widget/src/routes/account/withdraw.tsx similarity index 65% rename from src/routes/account/withdraw.tsx rename to packages/widget/src/routes/account/withdraw.tsx index 5b0112c..09b1f8d 100644 --- a/src/routes/account/withdraw.tsx +++ b/packages/widget/src/routes/account/withdraw.tsx @@ -1,5 +1,5 @@ import { createFileRoute } from "@tanstack/react-router"; -import { AccountWithdraw } from "@/components/modules/Account/Withdraw/index"; +import { AccountWithdraw } from "../../components/modules/Account/Withdraw"; export const Route = createFileRoute("/account/withdraw")({ component: AccountWithdraw, diff --git a/src/routes/account/withdraw_/sign.tsx b/packages/widget/src/routes/account/withdraw_/sign.tsx similarity index 64% rename from src/routes/account/withdraw_/sign.tsx rename to packages/widget/src/routes/account/withdraw_/sign.tsx index bbb56e8..c3f260d 100644 --- a/src/routes/account/withdraw_/sign.tsx +++ b/packages/widget/src/routes/account/withdraw_/sign.tsx @@ -1,5 +1,5 @@ import { createFileRoute } from "@tanstack/react-router"; -import { WithdrawSignRoute } from "@/components/modules/Account/Withdraw/sign"; +import { WithdrawSignRoute } from "../../../components/modules/Account/Withdraw/sign"; export const Route = createFileRoute("/account/withdraw_/sign")({ component: WithdrawSignRoute, diff --git a/src/routes/index.tsx b/packages/widget/src/routes/index.tsx similarity index 71% rename from src/routes/index.tsx rename to packages/widget/src/routes/index.tsx index 079f498..a1797e0 100644 --- a/src/routes/index.tsx +++ b/packages/widget/src/routes/index.tsx @@ -1,5 +1,5 @@ import { createFileRoute } from "@tanstack/react-router"; -import { Home } from "@/components/modules/Home"; +import { Home } from "../components/modules/Home"; export const Route = createFileRoute("/")({ component: Home, diff --git a/src/routes/order/$marketId/$side/increase_/index.tsx b/packages/widget/src/routes/order/$marketId/$side/increase_/index.tsx similarity index 85% rename from src/routes/order/$marketId/$side/increase_/index.tsx rename to packages/widget/src/routes/order/$marketId/$side/increase_/index.tsx index 6990c72..9dda263 100644 --- a/src/routes/order/$marketId/$side/increase_/index.tsx +++ b/packages/widget/src/routes/order/$marketId/$side/increase_/index.tsx @@ -1,5 +1,5 @@ import { createFileRoute, getRouteApi, Navigate } from "@tanstack/react-router"; -import { MarketOrder } from "@/components/modules/Order/Overview"; +import { MarketOrder } from "../../../../../components/modules/Order/Overview"; export const Route = createFileRoute("/order/$marketId/$side/increase_/")({ component: RouteComponent, diff --git a/src/routes/order/$marketId/$side/index.tsx b/packages/widget/src/routes/order/$marketId/$side/index.tsx similarity index 85% rename from src/routes/order/$marketId/$side/index.tsx rename to packages/widget/src/routes/order/$marketId/$side/index.tsx index f50e724..ac45309 100644 --- a/src/routes/order/$marketId/$side/index.tsx +++ b/packages/widget/src/routes/order/$marketId/$side/index.tsx @@ -1,5 +1,5 @@ import { createFileRoute, getRouteApi, Navigate } from "@tanstack/react-router"; -import { MarketOrder } from "@/components/modules/Order/Overview"; +import { MarketOrder } from "../../../../components/modules/Order/Overview"; export const Route = createFileRoute("/order/$marketId/$side/")({ component: RouteComponent, diff --git a/src/routes/order/$marketId/$side/sign.tsx b/packages/widget/src/routes/order/$marketId/$side/sign.tsx similarity index 68% rename from src/routes/order/$marketId/$side/sign.tsx rename to packages/widget/src/routes/order/$marketId/$side/sign.tsx index 29eb7e4..061019e 100644 --- a/src/routes/order/$marketId/$side/sign.tsx +++ b/packages/widget/src/routes/order/$marketId/$side/sign.tsx @@ -1,5 +1,5 @@ import { createFileRoute } from "@tanstack/react-router"; -import { OrderSignRoute } from "@/components/modules/Order/sign"; +import { OrderSignRoute } from "../../../../components/modules/Order/sign"; export const Route = createFileRoute("/order/$marketId/$side/sign")({ component: OrderSignRoute, diff --git a/src/routes/position-details/$marketId/cancel-order_/sign.tsx b/packages/widget/src/routes/position-details/$marketId/cancel-order_/sign.tsx similarity index 62% rename from src/routes/position-details/$marketId/cancel-order_/sign.tsx rename to packages/widget/src/routes/position-details/$marketId/cancel-order_/sign.tsx index 0d53bc2..1f2ca50 100644 --- a/src/routes/position-details/$marketId/cancel-order_/sign.tsx +++ b/packages/widget/src/routes/position-details/$marketId/cancel-order_/sign.tsx @@ -1,5 +1,5 @@ import { createFileRoute } from "@tanstack/react-router"; -import { CancelOrderSignRoute } from "@/components/modules/PositionDetails/Overview/CancelOrder/sign"; +import { CancelOrderSignRoute } from "../../../../components/modules/PositionDetails/Overview/CancelOrder/sign"; export const Route = createFileRoute( "/position-details/$marketId/cancel-order_/sign", diff --git a/src/routes/position-details/$marketId/close.tsx b/packages/widget/src/routes/position-details/$marketId/close.tsx similarity index 66% rename from src/routes/position-details/$marketId/close.tsx rename to packages/widget/src/routes/position-details/$marketId/close.tsx index 86cfcff..5911589 100644 --- a/src/routes/position-details/$marketId/close.tsx +++ b/packages/widget/src/routes/position-details/$marketId/close.tsx @@ -1,5 +1,5 @@ import { createFileRoute } from "@tanstack/react-router"; -import { ClosePositionRoute } from "@/components/modules/PositionDetails/Close"; +import { ClosePositionRoute } from "../../../components/modules/PositionDetails/Close"; export const Route = createFileRoute("/position-details/$marketId/close")({ component: ClosePositionRoute, diff --git a/src/routes/position-details/$marketId/close_/sign.tsx b/packages/widget/src/routes/position-details/$marketId/close_/sign.tsx similarity index 66% rename from src/routes/position-details/$marketId/close_/sign.tsx rename to packages/widget/src/routes/position-details/$marketId/close_/sign.tsx index 76f9de8..1aa3400 100644 --- a/src/routes/position-details/$marketId/close_/sign.tsx +++ b/packages/widget/src/routes/position-details/$marketId/close_/sign.tsx @@ -1,5 +1,5 @@ import { createFileRoute } from "@tanstack/react-router"; -import { CloseSignRoute } from "@/components/modules/PositionDetails/Close/sign"; +import { CloseSignRoute } from "../../../../components/modules/PositionDetails/Close/sign"; export const Route = createFileRoute("/position-details/$marketId/close_/sign")( { diff --git a/src/routes/position-details/$marketId/edit-leverage_/index.tsx b/packages/widget/src/routes/position-details/$marketId/edit-leverage_/index.tsx similarity index 62% rename from src/routes/position-details/$marketId/edit-leverage_/index.tsx rename to packages/widget/src/routes/position-details/$marketId/edit-leverage_/index.tsx index 5aab6ed..ded07ed 100644 --- a/src/routes/position-details/$marketId/edit-leverage_/index.tsx +++ b/packages/widget/src/routes/position-details/$marketId/edit-leverage_/index.tsx @@ -1,5 +1,5 @@ import { createFileRoute } from "@tanstack/react-router"; -import { EditLeverageSignRoute } from "@/components/modules/PositionDetails/Overview/EditLeverage/sign"; +import { EditLeverageSignRoute } from "../../../../components/modules/PositionDetails/Overview/EditLeverage/sign"; export const Route = createFileRoute( "/position-details/$marketId/edit-leverage_/", diff --git a/src/routes/position-details/$marketId/edit-sl-tp_/sign.tsx b/packages/widget/src/routes/position-details/$marketId/edit-sl-tp_/sign.tsx similarity index 63% rename from src/routes/position-details/$marketId/edit-sl-tp_/sign.tsx rename to packages/widget/src/routes/position-details/$marketId/edit-sl-tp_/sign.tsx index 203bcbf..2b5a1fe 100644 --- a/src/routes/position-details/$marketId/edit-sl-tp_/sign.tsx +++ b/packages/widget/src/routes/position-details/$marketId/edit-sl-tp_/sign.tsx @@ -1,5 +1,5 @@ import { createFileRoute } from "@tanstack/react-router"; -import { EditSLTPSignRoute } from "@/components/modules/PositionDetails/Overview/Position/sign"; +import { EditSLTPSignRoute } from "../../../../components/modules/PositionDetails/Overview/Position/sign"; export const Route = createFileRoute( "/position-details/$marketId/edit-sl-tp_/sign", diff --git a/src/routes/position-details/$marketId/index.tsx b/packages/widget/src/routes/position-details/$marketId/index.tsx similarity index 80% rename from src/routes/position-details/$marketId/index.tsx rename to packages/widget/src/routes/position-details/$marketId/index.tsx index bfc27bd..a92a4e6 100644 --- a/src/routes/position-details/$marketId/index.tsx +++ b/packages/widget/src/routes/position-details/$marketId/index.tsx @@ -1,6 +1,6 @@ import { createFileRoute } from "@tanstack/react-router"; import { Schema } from "effect"; -import PositionDetails from "@/components/modules/PositionDetails/Overview"; +import PositionDetails from "../../../components/modules/PositionDetails/Overview"; export const Route = createFileRoute("/position-details/$marketId/")({ component: PositionDetails, diff --git a/packages/widget/src/styles.css b/packages/widget/src/styles.css new file mode 100644 index 0000000..58f9b3d --- /dev/null +++ b/packages/widget/src/styles.css @@ -0,0 +1,2 @@ +@import "@yieldxyz/perps-common/styles"; +@source "../../common/src"; diff --git a/packages/widget/tsconfig.json b/packages/widget/tsconfig.json new file mode 100644 index 0000000..6578f19 --- /dev/null +++ b/packages/widget/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "declaration": true, + "emitDeclarationOnly": true, + "noEmit": false, + "outDir": "./dist", + "rootDir": "." + }, + "references": [{ "path": "../common" }], + "include": ["src"] +} diff --git a/packages/widget/vite.config.ts b/packages/widget/vite.config.ts new file mode 100644 index 0000000..c02ea85 --- /dev/null +++ b/packages/widget/vite.config.ts @@ -0,0 +1,4 @@ +import { commonViteConfig } from "@yieldxyz/perps-common/vite.config"; +import { defineConfig } from "vite"; + +export default defineConfig(commonViteConfig); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bf4f414..52c2047 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,6 +4,171 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +catalogs: + default: + '@base-ui/react': + specifier: ^1.1.0 + version: 1.1.0 + '@biomejs/biome': + specifier: ^2.3.14 + version: 2.3.14 + '@commitlint/cli': + specifier: ^20.4.1 + version: 20.4.1 + '@commitlint/config-conventional': + specifier: ^20.4.1 + version: 20.4.1 + '@effect-atom/atom-react': + specifier: ^0.5.0 + version: 0.5.0 + '@effect/language-service': + specifier: ^0.73.0 + version: 0.73.0 + '@effect/platform': + specifier: ^0.94.3 + version: 0.94.3 + '@effect/platform-node': + specifier: ^0.104.1 + version: 0.104.1 + '@ledgerhq/wallet-api-client': + specifier: ^1.12.6 + version: 1.12.6 + '@lucas-barake/effect-form-react': + specifier: ^0.18.0 + version: 0.18.0 + '@reown/appkit': + specifier: ^1.8.17 + version: 1.8.17 + '@reown/appkit-adapter-wagmi': + specifier: ^1.8.17 + version: 1.8.17 + '@stakekit/common': + specifier: ^0.0.61 + version: 0.0.61 + '@tailwindcss/vite': + specifier: ^4.0.6 + version: 4.1.18 + '@tanstack/devtools-vite': + specifier: ^0.5.0 + version: 0.5.0 + '@tanstack/react-devtools': + specifier: ^0.9.4 + version: 0.9.4 + '@tanstack/react-query': + specifier: ^5.90.20 + version: 5.90.20 + '@tanstack/react-router': + specifier: ^1.158.0 + version: 1.158.0 + '@tanstack/react-router-devtools': + specifier: ^1.158.0 + version: 1.158.0 + '@tanstack/react-virtual': + specifier: ^3.13.18 + version: 3.13.18 + '@tanstack/router-cli': + specifier: ^1.158.0 + version: 1.158.0 + '@tanstack/router-plugin': + specifier: ^1.157.8 + version: 1.158.0 + '@testing-library/dom': + specifier: ^10.4.0 + version: 10.4.1 + '@testing-library/react': + specifier: ^16.3.2 + version: 16.3.2 + '@tim-smart/openapi-gen': + specifier: ^0.4.13 + version: 0.4.13 + '@types/node': + specifier: ^25.2.0 + version: 25.2.0 + '@types/react': + specifier: ^19.2.11 + version: 19.2.11 + '@types/react-dom': + specifier: ^19.2.0 + version: 19.2.3 + '@vite-pwa/assets-generator': + specifier: ^1.0.2 + version: 1.0.2 + '@vitejs/plugin-react': + specifier: ^5.1.3 + version: 5.1.3 + '@vitest/browser-playwright': + specifier: ^4.0.18 + version: 4.0.18 + babel-plugin-react-compiler: + specifier: ^1.0.0 + version: 1.0.0 + class-variance-authority: + specifier: ^0.7.1 + version: 0.7.1 + clsx: + specifier: ^2.1.1 + version: 2.1.1 + effect: + specifier: ^3.19.16 + version: 3.19.16 + husky: + specifier: ^9.1.7 + version: 9.1.7 + jsdom: + specifier: ^28.0.0 + version: 28.0.0 + lucide-react: + specifier: ^0.563.0 + version: 0.563.0 + openapi-filter: + specifier: ^3.2.3 + version: 3.2.3 + react: + specifier: ^19.2.0 + version: 19.2.4 + react-dom: + specifier: ^19.2.0 + version: 19.2.4 + sonner: + specifier: ^2.0.7 + version: 2.0.7 + tailwind-merge: + specifier: ^3.0.2 + version: 3.4.0 + tailwindcss: + specifier: ^4.0.6 + version: 4.1.18 + tsx: + specifier: ^4.21.0 + version: 4.21.0 + turbo: + specifier: ^2.8.3 + version: 2.8.3 + tw-animate-css: + specifier: ^1.3.6 + version: 1.4.0 + typescript: + specifier: ^5.7.2 + version: 5.9.3 + viem: + specifier: ^2.45.0 + version: 2.45.1 + vite: + specifier: ^7.3.1 + version: 7.3.1 + vite-plugin-node-polyfills: + specifier: ^0.25.0 + version: 0.25.0 + vitest: + specifier: ^4.0.18 + version: 4.0.18 + vitest-browser-react: + specifier: ^2.0.4 + version: 2.0.5 + wagmi: + specifier: ^3.4.2 + version: 3.4.2 + patchedDependencies: '@tim-smart/openapi-gen': hash: 36720013d0f70c201ce8f233e38a7b93fc9fce74a17f9bc4293c3cf891b4fdc6 @@ -12,166 +177,486 @@ patchedDependencies: importers: .: + devDependencies: + '@biomejs/biome': + specifier: 'catalog:' + version: 2.3.14 + '@commitlint/cli': + specifier: 'catalog:' + version: 20.4.1(@types/node@25.2.0)(typescript@5.9.3) + '@commitlint/config-conventional': + specifier: 'catalog:' + version: 20.4.1 + '@effect/language-service': + specifier: 'catalog:' + version: 0.73.0 + husky: + specifier: 'catalog:' + version: 9.1.7 + turbo: + specifier: 'catalog:' + version: 2.8.3 + + packages/common: + dependencies: + '@base-ui/react': + specifier: 'catalog:' + version: 1.1.0(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@effect-atom/atom-react': + specifier: 'catalog:' + version: 0.5.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(effect@3.19.16)(react@19.2.4)(scheduler@0.27.0) + '@effect/experimental': + specifier: ^0.58.0 + version: 0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16) + '@effect/platform': + specifier: 'catalog:' + version: 0.94.3(effect@3.19.16) + '@effect/platform-node': + specifier: 'catalog:' + version: 0.104.1(@effect/cluster@0.56.1(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/sql@0.49.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/workflow@0.16.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/sql@0.49.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(bufferutil@4.1.0)(effect@3.19.16)(utf-8-validate@5.0.10) + '@ledgerhq/wallet-api-client': + specifier: 'catalog:' + version: 1.12.6(@ton/crypto@3.3.0) + '@lucas-barake/effect-form-react': + specifier: 'catalog:' + version: 0.18.0(@effect-atom/atom-react@0.5.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(effect@3.19.16)(react@19.2.4)(scheduler@0.27.0))(@effect-atom/atom@0.5.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(effect@3.19.16))(effect@3.19.16)(react@19.2.4) + '@reown/appkit': + specifier: 'catalog:' + version: 1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.4))(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-adapter-wagmi': + specifier: 'catalog:' + version: 1.8.17(0a70dc20fe0c1a07d4cc186a53526855) + '@stakekit/common': + specifier: 'catalog:' + version: 0.0.61 + '@tailwindcss/vite': + specifier: 'catalog:' + version: 4.1.18(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) + '@tanstack/react-devtools': + specifier: 'catalog:' + version: 0.9.4(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(bufferutil@4.1.0)(csstype@3.2.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(solid-js@1.9.11)(utf-8-validate@5.0.10) + '@tanstack/react-query': + specifier: 'catalog:' + version: 5.90.20(react@19.2.4) + '@tanstack/react-router': + specifier: 'catalog:' + version: 1.158.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@tanstack/react-router-devtools': + specifier: 'catalog:' + version: 1.158.0(@tanstack/react-router@1.158.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(@tanstack/router-core@1.158.0)(csstype@3.2.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@tanstack/react-virtual': + specifier: 'catalog:' + version: 3.13.18(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + class-variance-authority: + specifier: 'catalog:' + version: 0.7.1 + clsx: + specifier: 'catalog:' + version: 2.1.1 + effect: + specifier: 'catalog:' + version: 3.19.16 + lucide-react: + specifier: 'catalog:' + version: 0.563.0(react@19.2.4) + react: + specifier: 'catalog:' + version: 19.2.4 + react-dom: + specifier: 'catalog:' + version: 19.2.4(react@19.2.4) + sonner: + specifier: 'catalog:' + version: 2.0.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + tailwind-merge: + specifier: 'catalog:' + version: 3.4.0 + tailwindcss: + specifier: 'catalog:' + version: 4.1.18 + tw-animate-css: + specifier: 'catalog:' + version: 1.4.0 + viem: + specifier: 'catalog:' + version: 2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + wagmi: + specifier: 'catalog:' + version: 3.4.2(@safe-global/safe-apps-provider@0.18.6(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.20(react@19.2.4))(@types/react@19.2.11)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.2.4)(typescript@5.9.3)(viem@2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + devDependencies: + '@tanstack/devtools-vite': + specifier: 'catalog:' + version: 0.5.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) + '@tanstack/router-cli': + specifier: 'catalog:' + version: 1.158.0 + '@testing-library/dom': + specifier: 'catalog:' + version: 10.4.1 + '@testing-library/react': + specifier: 'catalog:' + version: 16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@tim-smart/openapi-gen': + specifier: 'catalog:' + version: 0.4.13(patch_hash=36720013d0f70c201ce8f233e38a7b93fc9fce74a17f9bc4293c3cf891b4fdc6) + '@types/node': + specifier: 'catalog:' + version: 25.2.0 + '@types/react': + specifier: 'catalog:' + version: 19.2.11 + '@types/react-dom': + specifier: 'catalog:' + version: 19.2.3(@types/react@19.2.11) + '@vite-pwa/assets-generator': + specifier: 'catalog:' + version: 1.0.2 + '@vitejs/plugin-react': + specifier: 'catalog:' + version: 5.1.3(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) + '@vitest/browser-playwright': + specifier: 'catalog:' + version: 4.0.18(bufferutil@4.1.0)(playwright@1.58.0)(utf-8-validate@5.0.10)(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18) + babel-plugin-react-compiler: + specifier: 'catalog:' + version: 1.0.0 + jsdom: + specifier: 'catalog:' + version: 28.0.0(@noble/hashes@1.8.0) + openapi-filter: + specifier: 'catalog:' + version: 3.2.3 + tsx: + specifier: 'catalog:' + version: 4.21.0 + typescript: + specifier: 'catalog:' + version: 5.9.3 + vite: + specifier: 'catalog:' + version: 7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + vite-plugin-node-polyfills: + specifier: 'catalog:' + version: 0.25.0(rollup@4.57.1)(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) + vitest: + specifier: 'catalog:' + version: 4.0.18(@types/node@25.2.0)(@vitest/browser-playwright@4.0.18)(jiti@2.6.1)(jsdom@28.0.0(@noble/hashes@1.8.0))(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + vitest-browser-react: + specifier: 'catalog:' + version: 2.0.5(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@4.0.18) + + packages/dashboard: dependencies: '@base-ui/react': - specifier: ^1.1.0 - version: 1.1.0(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: 'catalog:' + version: 1.1.0(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@effect-atom/atom-react': - specifier: ^0.4.6 - version: 0.4.6(@effect/experimental@0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(@effect/rpc@0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(effect@3.19.15)(react@19.2.3)(scheduler@0.27.0) + specifier: 'catalog:' + version: 0.5.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(effect@3.19.16)(react@19.2.4)(scheduler@0.27.0) '@effect/experimental': specifier: ^0.58.0 - version: 0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15) + version: 0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16) '@effect/platform': - specifier: ^0.94.2 - version: 0.94.2(effect@3.19.15) + specifier: 'catalog:' + version: 0.94.3(effect@3.19.16) '@effect/platform-node': - specifier: ^0.104.1 - version: 0.104.1(@effect/cluster@0.56.1(@effect/platform@0.94.2(effect@3.19.15))(@effect/rpc@0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/sql@0.49.0(@effect/experimental@0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/workflow@0.16.0(@effect/experimental@0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(@effect/rpc@0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(@effect/rpc@0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/sql@0.49.0(@effect/experimental@0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(bufferutil@4.1.0)(effect@3.19.15)(utf-8-validate@5.0.10) + specifier: 'catalog:' + version: 0.104.1(@effect/cluster@0.56.1(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/sql@0.49.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/workflow@0.16.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/sql@0.49.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(bufferutil@4.1.0)(effect@3.19.16)(utf-8-validate@5.0.10) '@ledgerhq/wallet-api-client': - specifier: ^1.12.6 + specifier: 'catalog:' version: 1.12.6(@ton/crypto@3.3.0) '@lucas-barake/effect-form-react': - specifier: ^0.14.0 - version: 0.14.0(@effect-atom/atom-react@0.4.6(@effect/experimental@0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(@effect/rpc@0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(effect@3.19.15)(react@19.2.3)(scheduler@0.27.0))(@effect-atom/atom@0.4.13(@effect/experimental@0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(@effect/rpc@0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(effect@3.19.15))(effect@3.19.15)(react@19.2.3) + specifier: 'catalog:' + version: 0.18.0(@effect-atom/atom-react@0.5.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(effect@3.19.16)(react@19.2.4)(scheduler@0.27.0))(@effect-atom/atom@0.5.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(effect@3.19.16))(effect@3.19.16)(react@19.2.4) '@reown/appkit': - specifier: ^1.8.17 - version: 1.8.17(@types/react@19.2.9)(bufferutil@4.1.0)(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(utf-8-validate@5.0.10)(zod@3.25.76) + specifier: 'catalog:' + version: 1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.2.4))(utf-8-validate@5.0.10)(zod@3.25.76) '@reown/appkit-adapter-wagmi': - specifier: ^1.8.17 - version: 1.8.17(ddefe6db690784ffc0b4049c81f77f80) + specifier: 'catalog:' + version: 1.8.17(588bfcce98e97548479faa9aa8a7b8c9) '@stakekit/common': - specifier: ^0.0.61 + specifier: 'catalog:' version: 0.0.61 '@tailwindcss/vite': - specifier: ^4.0.6 - version: 4.1.18(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) + specifier: 'catalog:' + version: 4.1.18(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) '@tanstack/react-devtools': - specifier: ^0.9.2 - version: 0.9.2(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(bufferutil@4.1.0)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(solid-js@1.9.10)(utf-8-validate@5.0.10) + specifier: 'catalog:' + version: 0.9.4(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(bufferutil@4.1.0)(csstype@3.2.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(solid-js@1.9.11)(utf-8-validate@5.0.10) '@tanstack/react-query': - specifier: ^5.90.20 - version: 5.90.20(react@19.2.3) + specifier: 'catalog:' + version: 5.90.20(react@19.2.4) '@tanstack/react-router': - specifier: ^1.157.8 - version: 1.157.8(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: 'catalog:' + version: 1.158.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@tanstack/react-router-devtools': - specifier: ^1.157.8 - version: 1.157.8(@tanstack/react-router@1.157.8(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.157.15)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: 'catalog:' + version: 1.158.0(@tanstack/react-router@1.158.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(@tanstack/router-core@1.158.0)(csstype@3.2.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@tanstack/react-virtual': - specifier: ^3.13.18 - version: 3.13.18(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: 'catalog:' + version: 3.13.18(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@yieldxyz/perps-common': + specifier: workspace:* + version: link:../common + class-variance-authority: + specifier: 'catalog:' + version: 0.7.1 + clsx: + specifier: 'catalog:' + version: 2.1.1 + effect: + specifier: 'catalog:' + version: 3.19.16 + lucide-react: + specifier: 'catalog:' + version: 0.563.0(react@19.2.4) + react: + specifier: 'catalog:' + version: 19.2.4 + react-dom: + specifier: 'catalog:' + version: 19.2.4(react@19.2.4) + sonner: + specifier: 'catalog:' + version: 2.0.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + tailwind-merge: + specifier: 'catalog:' + version: 3.4.0 + tailwindcss: + specifier: 'catalog:' + version: 4.1.18 + tw-animate-css: + specifier: 'catalog:' + version: 1.4.0 + viem: + specifier: 'catalog:' + version: 2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + wagmi: + specifier: 'catalog:' + version: 3.4.2(@safe-global/safe-apps-provider@0.18.6(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.20(react@19.2.4))(@types/react@19.2.11)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.2.4)(typescript@5.9.3)(viem@2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + devDependencies: + '@tanstack/devtools-vite': + specifier: 'catalog:' + version: 0.5.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) + '@tanstack/router-cli': + specifier: 'catalog:' + version: 1.158.0 '@tanstack/router-plugin': - specifier: ^1.157.8 - version: 1.157.8(@tanstack/react-router@1.157.8(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) + specifier: 'catalog:' + version: 1.158.0(@tanstack/react-router@1.158.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) + '@testing-library/dom': + specifier: 'catalog:' + version: 10.4.1 + '@testing-library/react': + specifier: 'catalog:' + version: 16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@tim-smart/openapi-gen': + specifier: 'catalog:' + version: 0.4.13(patch_hash=36720013d0f70c201ce8f233e38a7b93fc9fce74a17f9bc4293c3cf891b4fdc6) + '@types/node': + specifier: 'catalog:' + version: 25.2.0 + '@types/react': + specifier: 'catalog:' + version: 19.2.11 + '@types/react-dom': + specifier: 'catalog:' + version: 19.2.3(@types/react@19.2.11) + '@vite-pwa/assets-generator': + specifier: 'catalog:' + version: 1.0.2 + '@vitejs/plugin-react': + specifier: 'catalog:' + version: 5.1.3(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) + '@vitest/browser-playwright': + specifier: 'catalog:' + version: 4.0.18(bufferutil@4.1.0)(playwright@1.58.0)(utf-8-validate@5.0.10)(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18) + babel-plugin-react-compiler: + specifier: 'catalog:' + version: 1.0.0 + jsdom: + specifier: 'catalog:' + version: 28.0.0(@noble/hashes@1.8.0) + openapi-filter: + specifier: 'catalog:' + version: 3.2.3 + tsx: + specifier: 'catalog:' + version: 4.21.0 + typescript: + specifier: 'catalog:' + version: 5.9.3 + vite: + specifier: 'catalog:' + version: 7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + vite-plugin-node-polyfills: + specifier: 'catalog:' + version: 0.25.0(rollup@4.57.1)(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) + vitest: + specifier: 'catalog:' + version: 4.0.18(@types/node@25.2.0)(@vitest/browser-playwright@4.0.18)(jiti@2.6.1)(jsdom@28.0.0(@noble/hashes@1.8.0))(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + vitest-browser-react: + specifier: 'catalog:' + version: 2.0.5(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@4.0.18) + + packages/widget: + dependencies: + '@base-ui/react': + specifier: 'catalog:' + version: 1.1.0(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@effect-atom/atom-react': + specifier: 'catalog:' + version: 0.5.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(effect@3.19.16)(react@19.2.4)(scheduler@0.27.0) + '@effect/experimental': + specifier: ^0.58.0 + version: 0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16) + '@effect/platform': + specifier: 'catalog:' + version: 0.94.3(effect@3.19.16) + '@effect/platform-node': + specifier: 'catalog:' + version: 0.104.1(@effect/cluster@0.56.1(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/sql@0.49.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/workflow@0.16.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/sql@0.49.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(bufferutil@4.1.0)(effect@3.19.16)(utf-8-validate@5.0.10) + '@ledgerhq/wallet-api-client': + specifier: 'catalog:' + version: 1.12.6(@ton/crypto@3.3.0) + '@lucas-barake/effect-form-react': + specifier: 'catalog:' + version: 0.18.0(@effect-atom/atom-react@0.5.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(effect@3.19.16)(react@19.2.4)(scheduler@0.27.0))(@effect-atom/atom@0.5.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(effect@3.19.16))(effect@3.19.16)(react@19.2.4) + '@reown/appkit': + specifier: 'catalog:' + version: 1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.2.4))(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-adapter-wagmi': + specifier: 'catalog:' + version: 1.8.17(588bfcce98e97548479faa9aa8a7b8c9) + '@stakekit/common': + specifier: 'catalog:' + version: 0.0.61 + '@tailwindcss/vite': + specifier: 'catalog:' + version: 4.1.18(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) + '@tanstack/react-devtools': + specifier: 'catalog:' + version: 0.9.4(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(bufferutil@4.1.0)(csstype@3.2.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(solid-js@1.9.11)(utf-8-validate@5.0.10) + '@tanstack/react-query': + specifier: 'catalog:' + version: 5.90.20(react@19.2.4) + '@tanstack/react-router': + specifier: 'catalog:' + version: 1.158.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@tanstack/react-router-devtools': + specifier: 'catalog:' + version: 1.158.0(@tanstack/react-router@1.158.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(@tanstack/router-core@1.158.0)(csstype@3.2.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@tanstack/react-virtual': + specifier: 'catalog:' + version: 3.13.18(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@yieldxyz/perps-common': + specifier: workspace:* + version: link:../common class-variance-authority: - specifier: ^0.7.1 + specifier: 'catalog:' version: 0.7.1 clsx: - specifier: ^2.1.1 + specifier: 'catalog:' version: 2.1.1 effect: - specifier: ^3.19.15 - version: 3.19.15 + specifier: 'catalog:' + version: 3.19.16 lucide-react: - specifier: ^0.563.0 - version: 0.563.0(react@19.2.3) + specifier: 'catalog:' + version: 0.563.0(react@19.2.4) react: - specifier: ^19.2.0 - version: 19.2.3 + specifier: 'catalog:' + version: 19.2.4 react-dom: - specifier: ^19.2.0 - version: 19.2.3(react@19.2.3) + specifier: 'catalog:' + version: 19.2.4(react@19.2.4) sonner: - specifier: ^2.0.7 - version: 2.0.7(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: 'catalog:' + version: 2.0.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4) tailwind-merge: - specifier: ^3.0.2 + specifier: 'catalog:' version: 3.4.0 tailwindcss: - specifier: ^4.0.6 + specifier: 'catalog:' version: 4.1.18 tw-animate-css: - specifier: ^1.3.6 + specifier: 'catalog:' version: 1.4.0 viem: - specifier: ^2.45.0 - version: 2.45.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + specifier: 'catalog:' + version: 2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) wagmi: - specifier: ^3.4.1 - version: 3.4.1(@safe-global/safe-apps-provider@0.18.6(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.20(react@19.2.3))(@types/react@19.2.9)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.2.3)(typescript@5.9.3)(viem@2.45.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + specifier: 'catalog:' + version: 3.4.2(@safe-global/safe-apps-provider@0.18.6(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.20(react@19.2.4))(@types/react@19.2.11)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.2.4)(typescript@5.9.3)(viem@2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) devDependencies: - '@biomejs/biome': - specifier: 2.3.12 - version: 2.3.12 - '@effect/language-service': - specifier: ^0.72.0 - version: 0.72.0 '@tanstack/devtools-vite': - specifier: ^0.4.1 - version: 0.4.1(bufferutil@4.1.0)(utf-8-validate@5.0.10)(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) + specifier: 'catalog:' + version: 0.5.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) '@tanstack/router-cli': - specifier: ^1.157.15 - version: 1.157.15 + specifier: 'catalog:' + version: 1.158.0 + '@tanstack/router-plugin': + specifier: 'catalog:' + version: 1.158.0(@tanstack/react-router@1.158.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) '@testing-library/dom': - specifier: ^10.4.0 + specifier: 'catalog:' version: 10.4.1 '@testing-library/react': - specifier: ^16.3.2 - version: 16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: 'catalog:' + version: 16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@tim-smart/openapi-gen': - specifier: ^0.4.13 + specifier: 'catalog:' version: 0.4.13(patch_hash=36720013d0f70c201ce8f233e38a7b93fc9fce74a17f9bc4293c3cf891b4fdc6) '@types/node': - specifier: ^25.0.10 - version: 25.0.10 + specifier: 'catalog:' + version: 25.2.0 '@types/react': - specifier: ^19.2.9 - version: 19.2.9 + specifier: 'catalog:' + version: 19.2.11 '@types/react-dom': - specifier: ^19.2.0 - version: 19.2.3(@types/react@19.2.9) + specifier: 'catalog:' + version: 19.2.3(@types/react@19.2.11) '@vite-pwa/assets-generator': - specifier: ^1.0.2 + specifier: 'catalog:' version: 1.0.2 '@vitejs/plugin-react': - specifier: ^5.0.4 - version: 5.1.2(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) + specifier: 'catalog:' + version: 5.1.3(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) '@vitest/browser-playwright': - specifier: ^4.0.18 - version: 4.0.18(bufferutil@4.1.0)(playwright@1.58.0)(utf-8-validate@5.0.10)(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18) + specifier: 'catalog:' + version: 4.0.18(bufferutil@4.1.0)(playwright@1.58.0)(utf-8-validate@5.0.10)(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18) babel-plugin-react-compiler: - specifier: ^1.0.0 + specifier: 'catalog:' version: 1.0.0 jsdom: - specifier: ^27.0.0 - version: 27.4.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) + specifier: 'catalog:' + version: 28.0.0(@noble/hashes@1.8.0) openapi-filter: - specifier: ^3.2.3 + specifier: 'catalog:' version: 3.2.3 tsx: - specifier: ^4.21.0 + specifier: 'catalog:' version: 4.21.0 typescript: - specifier: ^5.7.2 + specifier: 'catalog:' version: 5.9.3 vite: - specifier: ^7.3.1 - version: 7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + specifier: 'catalog:' + version: 7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) vite-plugin-node-polyfills: - specifier: ^0.25.0 - version: 0.25.0(rollup@4.56.0)(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) + specifier: 'catalog:' + version: 0.25.0(rollup@4.57.1)(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) vitest: - specifier: ^4.0.18 - version: 4.0.18(@types/node@25.0.10)(@vitest/browser-playwright@4.0.18)(jiti@2.6.1)(jsdom@27.4.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + specifier: 'catalog:' + version: 4.0.18(@types/node@25.2.0)(@vitest/browser-playwright@4.0.18)(jiti@2.6.1)(jsdom@28.0.0(@noble/hashes@1.8.0))(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) vitest-browser-react: - specifier: ^2.0.4 - version: 2.0.4(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vitest@4.0.18) + specifier: 'catalog:' + version: 2.0.5(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@4.0.18) packages: - '@acemir/cssom@0.9.30': - resolution: {integrity: sha512-9CnlMCI0LmCIq0olalQqdWrJHPzm0/tw3gzOA9zJSgvFX7Xau3D24mAGa4BtwxwY69nsuJW6kQqqCzf/mEcQgg==} + '@acemir/cssom@0.9.31': + resolution: {integrity: sha512-ZnR3GSaH+/vJ0YlHau21FjfLYjMpYVIzTD8M8vIEQvIGxeOXyXdzCI140rrCY862p/C/BbzWsjc1dgnM9mkoTA==} '@adraffy/ens-normalize@1.11.1': resolution: {integrity: sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ==} @@ -179,46 +664,38 @@ packages: '@asamuzakjp/css-color@4.1.1': resolution: {integrity: sha512-B0Hv6G3gWGMn0xKJ0txEi/jM5iFpT3MfDxmhZFb4W047GvytCf1DHQ1D69W3zHI4yWe2aTZAA0JnbMZ7Xc8DuQ==} - '@asamuzakjp/dom-selector@6.7.6': - resolution: {integrity: sha512-hBaJER6A9MpdG3WgdlOolHmbOYvSk46y7IQN/1+iqiCuUu6iWdQrs9DGKF8ocqsEqWujWf/V7b7vaDgiUmIvUg==} + '@asamuzakjp/dom-selector@6.7.7': + resolution: {integrity: sha512-8CO/UQ4tzDd7ula+/CVimJIVWez99UJlbMyIgk8xOnhAVPKLnBZmUFYVgugS441v2ZqUq5EnSh6B0Ua0liSFAA==} '@asamuzakjp/nwsapi@2.3.9': resolution: {integrity: sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==} - '@babel/code-frame@7.27.1': - resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} - engines: {node: '>=6.9.0'} - '@babel/code-frame@7.28.6': resolution: {integrity: sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.28.5': - resolution: {integrity: sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==} + '@babel/code-frame@7.29.0': + resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} engines: {node: '>=6.9.0'} '@babel/compat-data@7.28.6': resolution: {integrity: sha512-2lfu57JtzctfIrcGMz992hyLlByuzgIk58+hhGCxjKZ3rWI82NnVLjXcaTqkI2NvlcvOskZaiZ5kjUALo3Lpxg==} engines: {node: '>=6.9.0'} - '@babel/core@7.28.5': - resolution: {integrity: sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==} - engines: {node: '>=6.9.0'} - '@babel/core@7.28.6': resolution: {integrity: sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw==} engines: {node: '>=6.9.0'} - '@babel/generator@7.28.5': - resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==} + '@babel/core@7.29.0': + resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} engines: {node: '>=6.9.0'} '@babel/generator@7.28.6': resolution: {integrity: sha512-lOoVRwADj8hjf7al89tvQ2a1lf53Z+7tiXMgpZJL3maQPDxh0DgLMN62B2MKUOFcoodBHLMbDM6WAbKgNy5Suw==} engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@7.27.2': - resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} + '@babel/generator@7.29.1': + resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} engines: {node: '>=6.9.0'} '@babel/helper-compilation-targets@7.28.6': @@ -229,30 +706,16 @@ packages: resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} engines: {node: '>=6.9.0'} - '@babel/helper-module-imports@7.27.1': - resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} - engines: {node: '>=6.9.0'} - '@babel/helper-module-imports@7.28.6': resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} engines: {node: '>=6.9.0'} - '@babel/helper-module-transforms@7.28.3': - resolution: {integrity: sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - '@babel/helper-module-transforms@7.28.6': resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-plugin-utils@7.27.1': - resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} - engines: {node: '>=6.9.0'} - '@babel/helper-plugin-utils@7.28.6': resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==} engines: {node: '>=6.9.0'} @@ -269,21 +732,17 @@ packages: resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.28.4': - resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==} - engines: {node: '>=6.9.0'} - '@babel/helpers@7.28.6': resolution: {integrity: sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==} engines: {node: '>=6.9.0'} - '@babel/parser@7.28.5': - resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==} + '@babel/parser@7.28.6': + resolution: {integrity: sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/parser@7.28.6': - resolution: {integrity: sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==} + '@babel/parser@7.29.0': + resolution: {integrity: sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==} engines: {node: '>=6.0.0'} hasBin: true @@ -311,38 +770,30 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/runtime@7.28.4': - resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} - engines: {node: '>=6.9.0'} - '@babel/runtime@7.28.6': resolution: {integrity: sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==} engines: {node: '>=6.9.0'} - '@babel/template@7.27.2': - resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} - engines: {node: '>=6.9.0'} - '@babel/template@7.28.6': resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.28.5': - resolution: {integrity: sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==} - engines: {node: '>=6.9.0'} - '@babel/traverse@7.28.6': resolution: {integrity: sha512-fgWX62k02qtjqdSNTAGxmKYY/7FSL9WAS1o2Hu5+I5m9T0yxZzr4cnrfXQ/MX0rIifthCSs6FKTlzYbJcPtMNg==} engines: {node: '>=6.9.0'} - '@babel/types@7.28.5': - resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} + '@babel/traverse@7.29.0': + resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} engines: {node: '>=6.9.0'} '@babel/types@7.28.6': resolution: {integrity: sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==} engines: {node: '>=6.9.0'} + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} + engines: {node: '>=6.9.0'} + '@base-org/account@2.4.0': resolution: {integrity: sha512-A4Umpi8B9/pqR78D1Yoze4xHyQaujioVRqqO3d6xuDFw9VRtjg6tK3bPlwE0aW+nVH/ntllCpPa2PbI8Rnjcug==} @@ -367,55 +818,59 @@ packages: '@types/react': optional: true - '@biomejs/biome@2.3.12': - resolution: {integrity: sha512-AR7h4aSlAvXj7TAajW/V12BOw2EiS0AqZWV5dGozf4nlLoUF/ifvD0+YgKSskT0ylA6dY1A8AwgP8kZ6yaCQnA==} + '@biomejs/biome@2.3.14': + resolution: {integrity: sha512-QMT6QviX0WqXJCaiqVMiBUCr5WRQ1iFSjvOLoTk6auKukJMvnMzWucXpwZB0e8F00/1/BsS9DzcKgWH+CLqVuA==} engines: {node: '>=14.21.3'} hasBin: true - '@biomejs/cli-darwin-arm64@2.3.12': - resolution: {integrity: sha512-cO6fn+KiMBemva6EARDLQBxeyvLzgidaFRJi8G7OeRqz54kWK0E+uSjgFaiHlc3DZYoa0+1UFE8mDxozpc9ieg==} + '@biomejs/cli-darwin-arm64@2.3.14': + resolution: {integrity: sha512-UJGPpvWJMkLxSRtpCAKfKh41Q4JJXisvxZL8ChN1eNW3m/WlPFJ6EFDCE7YfUb4XS8ZFi3C1dFpxUJ0Ety5n+A==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [darwin] - '@biomejs/cli-darwin-x64@2.3.12': - resolution: {integrity: sha512-/fiF/qmudKwSdvmSrSe/gOTkW77mHHkH8Iy7YC2rmpLuk27kbaUOPa7kPiH5l+3lJzTUfU/t6x1OuIq/7SGtxg==} + '@biomejs/cli-darwin-x64@2.3.14': + resolution: {integrity: sha512-PNkLNQG6RLo8lG7QoWe/hhnMxJIt1tEimoXpGQjwS/dkdNiKBLPv4RpeQl8o3s1OKI3ZOR5XPiYtmbGGHAOnLA==} engines: {node: '>=14.21.3'} cpu: [x64] os: [darwin] - '@biomejs/cli-linux-arm64-musl@2.3.12': - resolution: {integrity: sha512-aqkeSf7IH+wkzFpKeDVPSXy9uDjxtLpYA6yzkYsY+tVjwFFirSuajHDI3ul8en90XNs1NA0n8kgBrjwRi5JeyA==} + '@biomejs/cli-linux-arm64-musl@2.3.14': + resolution: {integrity: sha512-LInRbXhYujtL3sH2TMCH/UBwJZsoGwfQjBrMfl84CD4hL/41C/EU5mldqf1yoFpsI0iPWuU83U+nB2TUUypWeg==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] + libc: [musl] - '@biomejs/cli-linux-arm64@2.3.12': - resolution: {integrity: sha512-nbOsuQROa3DLla5vvsTZg+T5WVPGi9/vYxETm9BOuLHBJN3oWQIg3MIkE2OfL18df1ZtNkqXkH6Yg9mdTPem7A==} + '@biomejs/cli-linux-arm64@2.3.14': + resolution: {integrity: sha512-KT67FKfzIw6DNnUNdYlBg+eU24Go3n75GWK6NwU4+yJmDYFe9i/MjiI+U/iEzKvo0g7G7MZqoyrhIYuND2w8QQ==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] + libc: [glibc] - '@biomejs/cli-linux-x64-musl@2.3.12': - resolution: {integrity: sha512-kVGWtupRRsOjvw47YFkk5mLiAdpCPMWBo1jOwAzh+juDpUb2sWarIp+iq+CPL1Wt0LLZnYtP7hH5kD6fskcxmg==} + '@biomejs/cli-linux-x64-musl@2.3.14': + resolution: {integrity: sha512-KQU7EkbBBuHPW3/rAcoiVmhlPtDSGOGRPv9js7qJVpYTzjQmVR+C9Rfcz+ti8YCH+zT1J52tuBybtP4IodjxZQ==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] + libc: [musl] - '@biomejs/cli-linux-x64@2.3.12': - resolution: {integrity: sha512-CQtqrJ+qEEI8tgRSTjjzk6wJAwfH3wQlkIGsM5dlecfRZaoT+XCms/mf7G4kWNexrke6mnkRzNy6w8ebV177ow==} + '@biomejs/cli-linux-x64@2.3.14': + resolution: {integrity: sha512-ZsZzQsl9U+wxFrGGS4f6UxREUlgHwmEfu1IrXlgNFrNnd5Th6lIJr8KmSzu/+meSa9f4rzFrbEW9LBBA6ScoMA==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] + libc: [glibc] - '@biomejs/cli-win32-arm64@2.3.12': - resolution: {integrity: sha512-Re4I7UnOoyE4kHMqpgtG6UvSBGBbbtvsOvBROgCCoH7EgANN6plSQhvo2W7OCITvTp7gD6oZOyZy72lUdXjqZg==} + '@biomejs/cli-win32-arm64@2.3.14': + resolution: {integrity: sha512-+IKYkj/pUBbnRf1G1+RlyA3LWiDgra1xpS7H2g4BuOzzRbRB+hmlw0yFsLprHhbbt7jUzbzAbAjK/Pn0FDnh1A==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [win32] - '@biomejs/cli-win32-x64@2.3.12': - resolution: {integrity: sha512-qqGVWqNNek0KikwPZlOIoxtXgsNGsX+rgdEzgw82Re8nF02W+E2WokaQhpF5TdBh/D/RQ3TLppH+otp6ztN0lw==} + '@biomejs/cli-win32-x64@2.3.14': + resolution: {integrity: sha512-oizCjdyQ3WJEswpb3Chdngeat56rIdSYK12JI3iI11Mt5T5EXcZ7WLuowzEaFPNJ3zmOQFliMN8QY1Pi+qsfdQ==} engines: {node: '>=14.21.3'} cpu: [x64] os: [win32] @@ -423,8 +878,77 @@ packages: '@canvas/image-data@1.1.0': resolution: {integrity: sha512-QdObRRjRbcXGmM1tmJ+MrHcaz1MftF2+W7YI+MsphnsCrmtyfS0d5qJbk0MeSbUeyM/jCb0hmnkXPsy026L7dA==} - '@coinbase/cdp-sdk@1.43.1': - resolution: {integrity: sha512-3eXP24p5q68agRgu8grGlF+ASidf3xYSDQtdRuDOFCMZafbqANsjl/JxLwYDmUenRodhxBBJgYJ65nOALP58tA==} + '@coinbase/cdp-sdk@1.44.0': + resolution: {integrity: sha512-0I5O1DzbchR91GAYQAU8lxx6q9DBvN0no9IBwrTKLHW8t5bABMg8dzQ/jrGRd6lr/QFJJW4L0ZSLGae5jsxGWw==} + + '@commitlint/cli@20.4.1': + resolution: {integrity: sha512-uuFKKpc7OtQM+6SRqT+a4kV818o1pS+uvv/gsRhyX7g4x495jg+Q7P0+O9VNGyLXBYP0syksS7gMRDJKcekr6A==} + engines: {node: '>=v18'} + hasBin: true + + '@commitlint/config-conventional@20.4.1': + resolution: {integrity: sha512-0YUvIeBtpi86XriqrR+TCULVFiyYTIOEPjK7tTRMxjcBm1qlzb+kz7IF2WxL6Fq5DaundG8VO37BNgMkMTBwqA==} + engines: {node: '>=v18'} + + '@commitlint/config-validator@20.4.0': + resolution: {integrity: sha512-zShmKTF+sqyNOfAE0vKcqnpvVpG0YX8F9G/ZIQHI2CoKyK+PSdladXMSns400aZ5/QZs+0fN75B//3Q5CHw++w==} + engines: {node: '>=v18'} + + '@commitlint/ensure@20.4.1': + resolution: {integrity: sha512-WLQqaFx1pBooiVvBrA1YfJNFqZF8wS/YGOtr5RzApDbV9tQ52qT5VkTsY65hFTnXhW8PcDfZLaknfJTmPejmlw==} + engines: {node: '>=v18'} + + '@commitlint/execute-rule@20.0.0': + resolution: {integrity: sha512-xyCoOShoPuPL44gVa+5EdZsBVao/pNzpQhkzq3RdtlFdKZtjWcLlUFQHSWBuhk5utKYykeJPSz2i8ABHQA+ZZw==} + engines: {node: '>=v18'} + + '@commitlint/format@20.4.0': + resolution: {integrity: sha512-i3ki3WR0rgolFVX6r64poBHXM1t8qlFel1G1eCBvVgntE3fCJitmzSvH5JD/KVJN/snz6TfaX2CLdON7+s4WVQ==} + engines: {node: '>=v18'} + + '@commitlint/is-ignored@20.4.1': + resolution: {integrity: sha512-In5EO4JR1lNsAv1oOBBO24V9ND1IqdAJDKZiEpdfjDl2HMasAcT7oA+5BKONv1pRoLG380DGPE2W2RIcUwdgLA==} + engines: {node: '>=v18'} + + '@commitlint/lint@20.4.1': + resolution: {integrity: sha512-g94LrGl/c6UhuhDQqNqU232aslLEN2vzc7MPfQTHzwzM4GHNnEAwVWWnh0zX8S5YXecuLXDwbCsoGwmpAgPWKA==} + engines: {node: '>=v18'} + + '@commitlint/load@20.4.0': + resolution: {integrity: sha512-Dauup/GfjwffBXRJUdlX/YRKfSVXsXZLnINXKz0VZkXdKDcaEILAi9oflHGbfydonJnJAbXEbF3nXPm9rm3G6A==} + engines: {node: '>=v18'} + + '@commitlint/message@20.4.0': + resolution: {integrity: sha512-B5lGtvHgiLAIsK5nLINzVW0bN5hXv+EW35sKhYHE8F7V9Uz1fR4tx3wt7mobA5UNhZKUNgB/+ldVMQE6IHZRyA==} + engines: {node: '>=v18'} + + '@commitlint/parse@20.4.1': + resolution: {integrity: sha512-XNtZjeRcFuAfUnhYrCY02+mpxwY4OmnvD3ETbVPs25xJFFz1nRo/25nHj+5eM+zTeRFvWFwD4GXWU2JEtoK1/w==} + engines: {node: '>=v18'} + + '@commitlint/read@20.4.0': + resolution: {integrity: sha512-QfpFn6/I240ySEGv7YWqho4vxqtPpx40FS7kZZDjUJ+eHxu3azfhy7fFb5XzfTqVNp1hNoI3tEmiEPbDB44+cg==} + engines: {node: '>=v18'} + + '@commitlint/resolve-extends@20.4.0': + resolution: {integrity: sha512-ay1KM8q0t+/OnlpqXJ+7gEFQNlUtSU5Gxr8GEwnVf2TPN3+ywc5DzL3JCxmpucqxfHBTFwfRMXxPRRnR5Ki20g==} + engines: {node: '>=v18'} + + '@commitlint/rules@20.4.1': + resolution: {integrity: sha512-WtqypKEPbQEuJwJS4aKs0OoJRBKz1HXPBC9wRtzVNH68FLhPWzxXlF09hpUXM9zdYTpm4vAdoTGkWiBgQ/vL0g==} + engines: {node: '>=v18'} + + '@commitlint/to-lines@20.0.0': + resolution: {integrity: sha512-2l9gmwiCRqZNWgV+pX1X7z4yP0b3ex/86UmUFgoRt672Ez6cAM2lOQeHFRUTuE6sPpi8XBCGnd8Kh3bMoyHwJw==} + engines: {node: '>=v18'} + + '@commitlint/top-level@20.4.0': + resolution: {integrity: sha512-NDzq8Q6jmFaIIBC/GG6n1OQEaHdmaAAYdrZRlMgW6glYWGZ+IeuXmiymDvQNXPc82mVxq2KiE3RVpcs+1OeDeA==} + engines: {node: '>=v18'} + + '@commitlint/types@20.4.0': + resolution: {integrity: sha512-aO5l99BQJ0X34ft8b0h7QFkQlqxC6e7ZPVmBKz13xM9O8obDaM1Cld4sQlJDXXU/VFuUzQ30mVtHjVz74TuStw==} + engines: {node: '>=v18'} '@csstools/color-helpers@5.1.0': resolution: {integrity: sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==} @@ -450,28 +974,27 @@ packages: peerDependencies: '@csstools/css-tokenizer': ^3.0.4 - '@csstools/css-syntax-patches-for-csstree@1.0.22': - resolution: {integrity: sha512-qBcx6zYlhleiFfdtzkRgwNC7VVoAwfK76Vmsw5t+PbvtdknO9StgRk7ROvq9so1iqbdW4uLIDAsXRsTfUrIoOw==} - engines: {node: '>=18'} + '@csstools/css-syntax-patches-for-csstree@1.0.26': + resolution: {integrity: sha512-6boXK0KkzT5u5xOgF6TKB+CLq9SOpEGmkZw0g5n9/7yg85wab3UzSxB8TxhLJ31L4SGJ6BCFRw/iftTha1CJXA==} '@csstools/css-tokenizer@3.0.4': resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==} engines: {node: '>=18'} - '@effect-atom/atom-react@0.4.6': - resolution: {integrity: sha512-ZvncuSQsCcUrsddD00JcKDMraPge0AiDMGiJqKc7ProvagCVrxB+Emy5uHM0l0SLGUx4X56bFE0d1tp9Z/Bf+g==} + '@effect-atom/atom-react@0.5.0': + resolution: {integrity: sha512-aFfjWi4rEJCqfM12Oi36/EKaDm/W6n4/N6yM5vL0t/QozKhJhK05rQL/GY4XMxlH2eqkQ4ih8jBQa3Yyp0Fiqw==} peerDependencies: effect: ^3.19 react: '>=18 <20' scheduler: '*' - '@effect-atom/atom@0.4.13': - resolution: {integrity: sha512-wYCPDg/vN2IWTqxho7kTTSivh//V2TSAcdkQvLXMJWww8YzhcCGmCiDpT6cefyNXvHj+qZrqYB54mrUqG6EYCA==} + '@effect-atom/atom@0.5.0': + resolution: {integrity: sha512-qg6Qpf+ESi63taFJrufPtYDHghRLXxAte/xgpKqN+m7T6I3Lw1jgiNxR4AJeNG7f2UOkpmPhA8AYdWMgaUU61w==} peerDependencies: - '@effect/experimental': ^0.57.0 - '@effect/platform': ^0.93.0 - '@effect/rpc': ^0.72.1 - effect: ^3.19.0 + '@effect/experimental': ^0.58.0 + '@effect/platform': ^0.94.2 + '@effect/rpc': ^0.73.0 + effect: ^3.19.15 '@effect/cluster@0.56.1': resolution: {integrity: sha512-gnrsH6kfrUjn+82j/bw1IR4yFqJqV8tc7xZvrbJPRgzANycc6K1hu3LMg548uYbUkTzD8YYyqrSatMO1mkQpzw==} @@ -495,8 +1018,8 @@ packages: lmdb: optional: true - '@effect/language-service@0.72.0': - resolution: {integrity: sha512-MWkyTPCXSs5Q3OIBWR3q24SA+ipkdWW7EBJBt6EPUzlzZxjJLXtLBhXpMoCFheSEM0FTWOHT4BRLh5lufsmjVw==} + '@effect/language-service@0.73.0': + resolution: {integrity: sha512-/SGoq50VDm/XwQI6d0cReYcLjwfdqwZv7uEJp92+ssx5vLCsm+QvHf4Ul6l6PYVzorsgAp/b6fhAwI2VSkqcJQ==} hasBin: true '@effect/platform-node-shared@0.57.1': @@ -517,10 +1040,10 @@ packages: '@effect/sql': ^0.49.0 effect: ^3.19.15 - '@effect/platform@0.94.2': - resolution: {integrity: sha512-85vdwpnK4oH/rJ3EuX/Gi2Hkt+K4HvXWr9bxCuqvty9hxyEcRxkJcqTesYrcVoQB6aULb1Za2B0MKoTbvffB3Q==} + '@effect/platform@0.94.3': + resolution: {integrity: sha512-bvTR8xLQoRpKgHuprZDOeQdPkhyVw+WT05iI9jl2s8Qiblyk5Dz2JLwJU+EFeksIBaPYz49xa635Om91T1CefQ==} peerDependencies: - effect: ^3.19.15 + effect: ^3.19.16 '@effect/rpc@0.73.0': resolution: {integrity: sha512-iMPf6tTriz8sK0l5x4koFId8Hz5nFptHYg8WqyjHGIIVLTpZxuiSqhmXZG7FnAs5N2n6uCEws4wWGcIgXNUrFg==} @@ -702,23 +1225,23 @@ packages: cpu: [x64] os: [win32] - '@exodus/bytes@1.8.0': - resolution: {integrity: sha512-8JPn18Bcp8Uo1T82gR8lh2guEOa5KKU/IEKvvdp0sgmi7coPBWf1Doi1EXsGZb2ehc8ym/StJCjffYV+ne7sXQ==} + '@exodus/bytes@1.11.0': + resolution: {integrity: sha512-wO3vd8nsEHdumsXrjGO/v4p6irbg7hy9kvIeR6i2AwylZSk4HJdWgL0FNaVquW1+AweJcdvU1IEpuIWk/WaPnA==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} peerDependencies: - '@exodus/crypto': ^1.0.0-rc.4 + '@noble/hashes': ^1.8.0 || ^2.0.0 peerDependenciesMeta: - '@exodus/crypto': + '@noble/hashes': optional: true - '@floating-ui/core@1.7.3': - resolution: {integrity: sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==} + '@floating-ui/core@1.7.4': + resolution: {integrity: sha512-C3HlIdsBxszvm5McXlB8PeOEWfBhcGBTZGkGlWc2U0KFY5IwG5OQEuQ8rq52DZmcHDlPLd+YFBK+cZcytwIFWg==} - '@floating-ui/dom@1.7.4': - resolution: {integrity: sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==} + '@floating-ui/dom@1.7.5': + resolution: {integrity: sha512-N0bD2kIPInNHUHehXhMke1rBGs1dwqvC9O9KYMyyjK7iXt7GAhnro7UlcuYcGdS/yYOlq0MAVgrow8IbWJwyqg==} - '@floating-ui/react-dom@2.1.6': - resolution: {integrity: sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==} + '@floating-ui/react-dom@2.1.7': + resolution: {integrity: sha512-0tLRojf/1Go2JgEVm+3Frg9A3IW8bJgKgdO0BN5RkF//ufuz2joZM63Npau2ff3J6lUVYgDSNzNkR+aH3IVfjg==} peerDependencies: react: '>=16.8.0' react-dom: '>=16.8.0' @@ -752,67 +1275,79 @@ packages: resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} cpu: [arm64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-arm@1.0.5': resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} cpu: [arm] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-s390x@1.0.4': resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} cpu: [s390x] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-x64@1.0.4': resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} cpu: [x64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linuxmusl-arm64@1.0.4': resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} cpu: [arm64] os: [linux] + libc: [musl] '@img/sharp-libvips-linuxmusl-x64@1.0.4': resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} cpu: [x64] os: [linux] + libc: [musl] '@img/sharp-linux-arm64@0.33.5': resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] + libc: [glibc] '@img/sharp-linux-arm@0.33.5': resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm] os: [linux] + libc: [glibc] '@img/sharp-linux-s390x@0.33.5': resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [s390x] os: [linux] + libc: [glibc] '@img/sharp-linux-x64@0.33.5': resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] + libc: [glibc] '@img/sharp-linuxmusl-arm64@0.33.5': resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] + libc: [musl] '@img/sharp-linuxmusl-x64@0.33.5': resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] + libc: [musl] '@img/sharp-wasm32@0.33.5': resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} @@ -876,19 +1411,19 @@ packages: '@lit/reactive-element@2.1.2': resolution: {integrity: sha512-pbCDiVMnne1lYUIaYNN5wrwQXDtHaYtg7YEFPeW+hws6U47WeFvISGUWekPGKWOP1ygrs0ef0o1VJMk1exos5A==} - '@lucas-barake/effect-form-react@0.14.0': - resolution: {integrity: sha512-Yxiq/zfaF9ACJEfiKq/QvoRuWdrtRz+6ENZOoVe8tbSok016hWfV4fG373sGXyhr8tyZDMkqoiwwaIx60oCONw==} + '@lucas-barake/effect-form-react@0.18.0': + resolution: {integrity: sha512-XW2jUKzxfR+tSq+RV2zAdV3relOUr32h5qpxhaGsChYXu0sKV08+01rvgH2dh1JQM+NXYVvmWvM9Dlc0FxY/iQ==} peerDependencies: - '@effect-atom/atom': ^0.4.8 - '@effect-atom/atom-react': ^0.4.3 - effect: ^3.19.0 + '@effect-atom/atom': ^0.5.0 + '@effect-atom/atom-react': ^0.5.0 + effect: ^3.19.15 react: ^18.0.0 || ^19.0.0 - '@lucas-barake/effect-form@0.14.0': - resolution: {integrity: sha512-mXf7wBHAydUeOFUj8VDWG9eIQVxWLtbv3p2KidrzQlxGCx9mZpYIpRbrDmfsBAGOYC5SVSTIQd8KUvxdXMNaoQ==} + '@lucas-barake/effect-form@0.18.0': + resolution: {integrity: sha512-ecJM7fCzmYKmxUMvO/JT74CXG1ZokxeNoQLQcNF2VnouVKfT+4Bc+fBNc1ANDJKjcj2IjJWMjnnyQ2w1dupsUA==} peerDependencies: - '@effect-atom/atom': ^0.4.8 - effect: ^3.19.0 + '@effect-atom/atom': ^0.5.0 + effect: ^3.19.15 '@msgpack/msgpack@3.1.2': resolution: {integrity: sha512-JEW4DEtBzfe8HvUYecLU9e6+XJnKDlUAIve8FvPzF3Kzs6Xo/KuZkZJsDH0wJXl/qEZbeeE7edxDNY3kMs39hQ==} @@ -987,36 +1522,42 @@ packages: engines: {node: '>= 10.0.0'} cpu: [arm] os: [linux] + libc: [glibc] '@parcel/watcher-linux-arm-musl@2.5.6': resolution: {integrity: sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==} engines: {node: '>= 10.0.0'} cpu: [arm] os: [linux] + libc: [musl] '@parcel/watcher-linux-arm64-glibc@2.5.6': resolution: {integrity: sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] '@parcel/watcher-linux-arm64-musl@2.5.6': resolution: {integrity: sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] + libc: [musl] '@parcel/watcher-linux-x64-glibc@2.5.6': resolution: {integrity: sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] + libc: [glibc] '@parcel/watcher-linux-x64-musl@2.5.6': resolution: {integrity: sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] + libc: [musl] '@parcel/watcher-win32-arm64@2.5.6': resolution: {integrity: sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==} @@ -1085,8 +1626,8 @@ packages: '@reown/appkit@1.8.17': resolution: {integrity: sha512-svov4ShvEi4YboVe+kXT8xGQvDrYsgQBrBmccOel9nT7/lOEDUimFu5Irna8g/8Zji9/XbRrYi49cLPJrzd45Q==} - '@rolldown/pluginutils@1.0.0-beta.53': - resolution: {integrity: sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ==} + '@rolldown/pluginutils@1.0.0-rc.2': + resolution: {integrity: sha512-izyXV/v+cHiRfozX62W9htOAvwMo4/bXKDrQ+vom1L1qRuexPock/7VZDAhnpHCLNejd3NJ6hiab+tO0D44Rgw==} '@rollup/plugin-inject@5.0.5': resolution: {integrity: sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg==} @@ -1106,128 +1647,141 @@ packages: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.56.0': - resolution: {integrity: sha512-LNKIPA5k8PF1+jAFomGe3qN3bbIgJe/IlpDBwuVjrDKrJhVWywgnJvflMt/zkbVNLFtF1+94SljYQS6e99klnw==} + '@rollup/rollup-android-arm-eabi@4.57.1': + resolution: {integrity: sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.56.0': - resolution: {integrity: sha512-lfbVUbelYqXlYiU/HApNMJzT1E87UPGvzveGg2h0ktUNlOCxKlWuJ9jtfvs1sKHdwU4fzY7Pl8sAl49/XaEk6Q==} + '@rollup/rollup-android-arm64@4.57.1': + resolution: {integrity: sha512-dQaAddCY9YgkFHZcFNS/606Exo8vcLHwArFZ7vxXq4rigo2bb494/xKMMwRRQW6ug7Js6yXmBZhSBRuBvCCQ3w==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.56.0': - resolution: {integrity: sha512-EgxD1ocWfhoD6xSOeEEwyE7tDvwTgZc8Bss7wCWe+uc7wO8G34HHCUH+Q6cHqJubxIAnQzAsyUsClt0yFLu06w==} + '@rollup/rollup-darwin-arm64@4.57.1': + resolution: {integrity: sha512-crNPrwJOrRxagUYeMn/DZwqN88SDmwaJ8Cvi/TN1HnWBU7GwknckyosC2gd0IqYRsHDEnXf328o9/HC6OkPgOg==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.56.0': - resolution: {integrity: sha512-1vXe1vcMOssb/hOF8iv52A7feWW2xnu+c8BV4t1F//m9QVLTfNVpEdja5ia762j/UEJe2Z1jAmEqZAK42tVW3g==} + '@rollup/rollup-darwin-x64@4.57.1': + resolution: {integrity: sha512-Ji8g8ChVbKrhFtig5QBV7iMaJrGtpHelkB3lsaKzadFBe58gmjfGXAOfI5FV0lYMH8wiqsxKQ1C9B0YTRXVy4w==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.56.0': - resolution: {integrity: sha512-bof7fbIlvqsyv/DtaXSck4VYQ9lPtoWNFCB/JY4snlFuJREXfZnm+Ej6yaCHfQvofJDXLDMTVxWscVSuQvVWUQ==} + '@rollup/rollup-freebsd-arm64@4.57.1': + resolution: {integrity: sha512-R+/WwhsjmwodAcz65guCGFRkMb4gKWTcIeLy60JJQbXrJ97BOXHxnkPFrP+YwFlaS0m+uWJTstrUA9o+UchFug==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.56.0': - resolution: {integrity: sha512-KNa6lYHloW+7lTEkYGa37fpvPq+NKG/EHKM8+G/g9WDU7ls4sMqbVRV78J6LdNuVaeeK5WB9/9VAFbKxcbXKYg==} + '@rollup/rollup-freebsd-x64@4.57.1': + resolution: {integrity: sha512-IEQTCHeiTOnAUC3IDQdzRAGj3jOAYNr9kBguI7MQAAZK3caezRrg0GxAb6Hchg4lxdZEI5Oq3iov/w/hnFWY9Q==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.56.0': - resolution: {integrity: sha512-E8jKK87uOvLrrLN28jnAAAChNq5LeCd2mGgZF+fGF5D507WlG/Noct3lP/QzQ6MrqJ5BCKNwI9ipADB6jyiq2A==} + '@rollup/rollup-linux-arm-gnueabihf@4.57.1': + resolution: {integrity: sha512-F8sWbhZ7tyuEfsmOxwc2giKDQzN3+kuBLPwwZGyVkLlKGdV1nvnNwYD0fKQ8+XS6hp9nY7B+ZeK01EBUE7aHaw==} cpu: [arm] os: [linux] + libc: [glibc] - '@rollup/rollup-linux-arm-musleabihf@4.56.0': - resolution: {integrity: sha512-jQosa5FMYF5Z6prEpTCCmzCXz6eKr/tCBssSmQGEeozA9tkRUty/5Vx06ibaOP9RCrW1Pvb8yp3gvZhHwTDsJw==} + '@rollup/rollup-linux-arm-musleabihf@4.57.1': + resolution: {integrity: sha512-rGfNUfn0GIeXtBP1wL5MnzSj98+PZe/AXaGBCRmT0ts80lU5CATYGxXukeTX39XBKsxzFpEeK+Mrp9faXOlmrw==} cpu: [arm] os: [linux] + libc: [musl] - '@rollup/rollup-linux-arm64-gnu@4.56.0': - resolution: {integrity: sha512-uQVoKkrC1KGEV6udrdVahASIsaF8h7iLG0U0W+Xn14ucFwi6uS539PsAr24IEF9/FoDtzMeeJXJIBo5RkbNWvQ==} + '@rollup/rollup-linux-arm64-gnu@4.57.1': + resolution: {integrity: sha512-MMtej3YHWeg/0klK2Qodf3yrNzz6CGjo2UntLvk2RSPlhzgLvYEB3frRvbEF2wRKh1Z2fDIg9KRPe1fawv7C+g==} cpu: [arm64] os: [linux] + libc: [glibc] - '@rollup/rollup-linux-arm64-musl@4.56.0': - resolution: {integrity: sha512-vLZ1yJKLxhQLFKTs42RwTwa6zkGln+bnXc8ueFGMYmBTLfNu58sl5/eXyxRa2RarTkJbXl8TKPgfS6V5ijNqEA==} + '@rollup/rollup-linux-arm64-musl@4.57.1': + resolution: {integrity: sha512-1a/qhaaOXhqXGpMFMET9VqwZakkljWHLmZOX48R0I/YLbhdxr1m4gtG1Hq7++VhVUmf+L3sTAf9op4JlhQ5u1Q==} cpu: [arm64] os: [linux] + libc: [musl] - '@rollup/rollup-linux-loong64-gnu@4.56.0': - resolution: {integrity: sha512-FWfHOCub564kSE3xJQLLIC/hbKqHSVxy8vY75/YHHzWvbJL7aYJkdgwD/xGfUlL5UV2SB7otapLrcCj2xnF1dg==} + '@rollup/rollup-linux-loong64-gnu@4.57.1': + resolution: {integrity: sha512-QWO6RQTZ/cqYtJMtxhkRkidoNGXc7ERPbZN7dVW5SdURuLeVU7lwKMpo18XdcmpWYd0qsP1bwKPf7DNSUinhvA==} cpu: [loong64] os: [linux] + libc: [glibc] - '@rollup/rollup-linux-loong64-musl@4.56.0': - resolution: {integrity: sha512-z1EkujxIh7nbrKL1lmIpqFTc/sr0u8Uk0zK/qIEFldbt6EDKWFk/pxFq3gYj4Bjn3aa9eEhYRlL3H8ZbPT1xvA==} + '@rollup/rollup-linux-loong64-musl@4.57.1': + resolution: {integrity: sha512-xpObYIf+8gprgWaPP32xiN5RVTi/s5FCR+XMXSKmhfoJjrpRAjCuuqQXyxUa/eJTdAE6eJ+KDKaoEqjZQxh3Gw==} cpu: [loong64] os: [linux] + libc: [musl] - '@rollup/rollup-linux-ppc64-gnu@4.56.0': - resolution: {integrity: sha512-iNFTluqgdoQC7AIE8Q34R3AuPrJGJirj5wMUErxj22deOcY7XwZRaqYmB6ZKFHoVGqRcRd0mqO+845jAibKCkw==} + '@rollup/rollup-linux-ppc64-gnu@4.57.1': + resolution: {integrity: sha512-4BrCgrpZo4hvzMDKRqEaW1zeecScDCR+2nZ86ATLhAoJ5FQ+lbHVD3ttKe74/c7tNT9c6F2viwB3ufwp01Oh2w==} cpu: [ppc64] os: [linux] + libc: [glibc] - '@rollup/rollup-linux-ppc64-musl@4.56.0': - resolution: {integrity: sha512-MtMeFVlD2LIKjp2sE2xM2slq3Zxf9zwVuw0jemsxvh1QOpHSsSzfNOTH9uYW9i1MXFxUSMmLpeVeUzoNOKBaWg==} + '@rollup/rollup-linux-ppc64-musl@4.57.1': + resolution: {integrity: sha512-NOlUuzesGauESAyEYFSe3QTUguL+lvrN1HtwEEsU2rOwdUDeTMJdO5dUYl/2hKf9jWydJrO9OL/XSSf65R5+Xw==} cpu: [ppc64] os: [linux] + libc: [musl] - '@rollup/rollup-linux-riscv64-gnu@4.56.0': - resolution: {integrity: sha512-in+v6wiHdzzVhYKXIk5U74dEZHdKN9KH0Q4ANHOTvyXPG41bajYRsy7a8TPKbYPl34hU7PP7hMVHRvv/5aCSew==} + '@rollup/rollup-linux-riscv64-gnu@4.57.1': + resolution: {integrity: sha512-ptA88htVp0AwUUqhVghwDIKlvJMD/fmL/wrQj99PRHFRAG6Z5nbWoWG4o81Nt9FT+IuqUQi+L31ZKAFeJ5Is+A==} cpu: [riscv64] os: [linux] + libc: [glibc] - '@rollup/rollup-linux-riscv64-musl@4.56.0': - resolution: {integrity: sha512-yni2raKHB8m9NQpI9fPVwN754mn6dHQSbDTwxdr9SE0ks38DTjLMMBjrwvB5+mXrX+C0npX0CVeCUcvvvD8CNQ==} + '@rollup/rollup-linux-riscv64-musl@4.57.1': + resolution: {integrity: sha512-S51t7aMMTNdmAMPpBg7OOsTdn4tySRQvklmL3RpDRyknk87+Sp3xaumlatU+ppQ+5raY7sSTcC2beGgvhENfuw==} cpu: [riscv64] os: [linux] + libc: [musl] - '@rollup/rollup-linux-s390x-gnu@4.56.0': - resolution: {integrity: sha512-zhLLJx9nQPu7wezbxt2ut+CI4YlXi68ndEve16tPc/iwoylWS9B3FxpLS2PkmfYgDQtosah07Mj9E0khc3Y+vQ==} + '@rollup/rollup-linux-s390x-gnu@4.57.1': + resolution: {integrity: sha512-Bl00OFnVFkL82FHbEqy3k5CUCKH6OEJL54KCyx2oqsmZnFTR8IoNqBF+mjQVcRCT5sB6yOvK8A37LNm/kPJiZg==} cpu: [s390x] os: [linux] + libc: [glibc] - '@rollup/rollup-linux-x64-gnu@4.56.0': - resolution: {integrity: sha512-MVC6UDp16ZSH7x4rtuJPAEoE1RwS8N4oK9DLHy3FTEdFoUTCFVzMfJl/BVJ330C+hx8FfprA5Wqx4FhZXkj2Kw==} + '@rollup/rollup-linux-x64-gnu@4.57.1': + resolution: {integrity: sha512-ABca4ceT4N+Tv/GtotnWAeXZUZuM/9AQyCyKYyKnpk4yoA7QIAuBt6Hkgpw8kActYlew2mvckXkvx0FfoInnLg==} cpu: [x64] os: [linux] + libc: [glibc] - '@rollup/rollup-linux-x64-musl@4.56.0': - resolution: {integrity: sha512-ZhGH1eA4Qv0lxaV00azCIS1ChedK0V32952Md3FtnxSqZTBTd6tgil4nZT5cU8B+SIw3PFYkvyR4FKo2oyZIHA==} + '@rollup/rollup-linux-x64-musl@4.57.1': + resolution: {integrity: sha512-HFps0JeGtuOR2convgRRkHCekD7j+gdAuXM+/i6kGzQtFhlCtQkpwtNzkNj6QhCDp7DRJ7+qC/1Vg2jt5iSOFw==} cpu: [x64] os: [linux] + libc: [musl] - '@rollup/rollup-openbsd-x64@4.56.0': - resolution: {integrity: sha512-O16XcmyDeFI9879pEcmtWvD/2nyxR9mF7Gs44lf1vGGx8Vg2DRNx11aVXBEqOQhWb92WN4z7fW/q4+2NYzCbBA==} + '@rollup/rollup-openbsd-x64@4.57.1': + resolution: {integrity: sha512-H+hXEv9gdVQuDTgnqD+SQffoWoc0Of59AStSzTEj/feWTBAnSfSD3+Dql1ZruJQxmykT/JVY0dE8Ka7z0DH1hw==} cpu: [x64] os: [openbsd] - '@rollup/rollup-openharmony-arm64@4.56.0': - resolution: {integrity: sha512-LhN/Reh+7F3RCgQIRbgw8ZMwUwyqJM+8pXNT6IIJAqm2IdKkzpCh/V9EdgOMBKuebIrzswqy4ATlrDgiOwbRcQ==} + '@rollup/rollup-openharmony-arm64@4.57.1': + resolution: {integrity: sha512-4wYoDpNg6o/oPximyc/NG+mYUejZrCU2q+2w6YZqrAs2UcNUChIZXjtafAiiZSUc7On8v5NyNj34Kzj/Ltk6dQ==} cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.56.0': - resolution: {integrity: sha512-kbFsOObXp3LBULg1d3JIUQMa9Kv4UitDmpS+k0tinPBz3watcUiV2/LUDMMucA6pZO3WGE27P7DsfaN54l9ing==} + '@rollup/rollup-win32-arm64-msvc@4.57.1': + resolution: {integrity: sha512-O54mtsV/6LW3P8qdTcamQmuC990HDfR71lo44oZMZlXU4tzLrbvTii87Ni9opq60ds0YzuAlEr/GNwuNluZyMQ==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.56.0': - resolution: {integrity: sha512-vSSgny54D6P4vf2izbtFm/TcWYedw7f8eBrOiGGecyHyQB9q4Kqentjaj8hToe+995nob/Wv48pDqL5a62EWtg==} + '@rollup/rollup-win32-ia32-msvc@4.57.1': + resolution: {integrity: sha512-P3dLS+IerxCT/7D2q2FYcRdWRl22dNbrbBEtxdWhXrfIMPP9lQhb5h4Du04mdl5Woq05jVCDPCMF7Ub0NAjIew==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.56.0': - resolution: {integrity: sha512-FeCnkPCTHQJFbiGG49KjV5YGW/8b9rrXAM2Mz2kiIoktq2qsJxRD5giEMEOD2lPdgs72upzefaUvS+nc8E3UzQ==} + '@rollup/rollup-win32-x64-gnu@4.57.1': + resolution: {integrity: sha512-VMBH2eOOaKGtIJYleXsi2B8CPVADrh+TyNxJ4mWPnKfLB/DBUmzW+5m1xUrcwWoMfSLagIRpjUFeW5CO5hyciQ==} cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.56.0': - resolution: {integrity: sha512-H8AE9Ur/t0+1VXujj90w0HrSOuv0Nq9r1vSZF2t5km20NTfosQsGGUXDaKdQZzwuLts7IyL1fYT4hM95TI9c4g==} + '@rollup/rollup-win32-x64-msvc@4.57.1': + resolution: {integrity: sha512-mxRFDdHIWRxg3UfIIAwCm6NzvxG0jDX/wBN6KsQFTvKFqqg9vTrWUE68qEjHt19A5wwx5X5aUi2zuZT7YR0jrA==} cpu: [x64] os: [win32] @@ -1260,8 +1814,8 @@ packages: peerDependencies: '@solana/kit': ^5.0 - '@solana/accounts@5.4.0': - resolution: {integrity: sha512-qHtAtwCcCFTXcya6JOOG1nzYicivivN/JkcYNHr10qOp9b4MVRkfW1ZAAG1CNzjMe5+mwtEl60RwdsY9jXNb+Q==} + '@solana/accounts@5.5.1': + resolution: {integrity: sha512-TfOY9xixg5rizABuLVuZ9XI2x2tmWUC/OoN556xwfDlhBHBjKfszicYYOyD6nbFmwTGYarCmyGIdteXxTXIdhQ==} engines: {node: '>=20.18.0'} peerDependencies: typescript: ^5.0.0 @@ -1269,8 +1823,8 @@ packages: typescript: optional: true - '@solana/addresses@5.4.0': - resolution: {integrity: sha512-YRHiH30S8qDV4bZ+mtEk589PGfBuXHzD/fK2Z+YI5f/+s+yi/5le/fVw7PN6LxnnmVQKiRCDUiNF+WmFFKi6QQ==} + '@solana/addresses@5.5.1': + resolution: {integrity: sha512-5xoah3Q9G30HQghu/9BiHLb5pzlPKRC3zydQDmE3O9H//WfayxTFppsUDCL6FjYUHqj/wzK6CWHySglc2RkpdA==} engines: {node: '>=20.18.0'} peerDependencies: typescript: ^5.0.0 @@ -1278,8 +1832,8 @@ packages: typescript: optional: true - '@solana/assertions@5.4.0': - resolution: {integrity: sha512-8EP7mkdnrPc9y67FqWeAPzdWq2qAOkxsuo+ZBIXNWtIixDtXIdHrgjZ/wqbWxLgSTtXEfBCjpZU55Xw2Qfbwyg==} + '@solana/assertions@5.5.1': + resolution: {integrity: sha512-YTCSWAlGwSlVPnWtWLm3ukz81wH4j2YaCveK+TjpvUU88hTy6fmUqxi0+hvAMAe4zKXpJyj3Az7BrLJRxbIm4Q==} engines: {node: '>=20.18.0'} peerDependencies: typescript: ^5.0.0 @@ -1297,8 +1851,8 @@ packages: peerDependencies: typescript: '>=5.3.3' - '@solana/codecs-core@5.4.0': - resolution: {integrity: sha512-rQ5jXgiDe2vIU+mYCHDjgwMd9WdzZfh4sc5H6JgYleAUjeTUX6mx8hTV2+pcXvvn27LPrgrt9jfxswbDb8O8ww==} + '@solana/codecs-core@5.5.1': + resolution: {integrity: sha512-TgBt//bbKBct0t6/MpA8ElaOA3sa8eYVvR7LGslCZ84WiAwwjCY0lW/lOYsFHJQzwREMdUyuEyy5YWBKtdh8Rw==} engines: {node: '>=20.18.0'} peerDependencies: typescript: ^5.0.0 @@ -1306,8 +1860,8 @@ packages: typescript: optional: true - '@solana/codecs-data-structures@5.4.0': - resolution: {integrity: sha512-LVssbdQ1GfY6upnxW3mufYsNfvTWKnHNk5Hx2gHuOYJhm3HZlp+Y8zvuoY65G1d1xAXkPz5YVGxaSeVIRWLGWg==} + '@solana/codecs-data-structures@5.5.1': + resolution: {integrity: sha512-97bJWGyUY9WvBz3mX1UV3YPWGDTez6btCfD0ip3UVEXJbItVuUiOkzcO5iFDUtQT5riKT6xC+Mzl+0nO76gd0w==} engines: {node: '>=20.18.0'} peerDependencies: typescript: ^5.0.0 @@ -1321,8 +1875,8 @@ packages: peerDependencies: typescript: '>=5.3.3' - '@solana/codecs-numbers@5.4.0': - resolution: {integrity: sha512-z6LMkY+kXWx1alrvIDSAxexY5QLhsso638CjM7XI1u6dB7drTLWKhifyjnm1vOQc1VPVFmbYxTgKKpds8TY8tg==} + '@solana/codecs-numbers@5.5.1': + resolution: {integrity: sha512-rllMIZAHqmtvC0HO/dc/21wDuWaD0B8Ryv8o+YtsICQBuiL/0U4AGwH7Pi5GNFySYk0/crSuwfIqQFtmxNSPFw==} engines: {node: '>=20.18.0'} peerDependencies: typescript: ^5.0.0 @@ -1330,8 +1884,8 @@ packages: typescript: optional: true - '@solana/codecs-strings@5.4.0': - resolution: {integrity: sha512-w0trrjfQDhkCVz7O1GTmHBk9m+MkljKx2uNBbQAD3/yW2Qn9dYiTrZ1/jDVq0/+lPPAUkbT3s3Yo7HUZ2QFmHw==} + '@solana/codecs-strings@5.5.1': + resolution: {integrity: sha512-7klX4AhfHYA+uKKC/nxRGP2MntbYQCR3N6+v7bk1W/rSxYuhNmt+FN8aoThSZtWIKwN6BEyR1167ka8Co1+E7A==} engines: {node: '>=20.18.0'} peerDependencies: fastestsmallesttextencoderdecoder: ^1.0.22 @@ -1342,8 +1896,8 @@ packages: typescript: optional: true - '@solana/codecs@5.4.0': - resolution: {integrity: sha512-IbDCUvNX0MrkQahxiXj9rHzkd/fYfp1F2nTJkHGH8v+vPfD+YPjl007ZBM38EnCeXj/Xn+hxqBBivPvIHP29dA==} + '@solana/codecs@5.5.1': + resolution: {integrity: sha512-Vea29nJub/bXjfzEV7ZZQ/PWr1pYLZo3z0qW0LQL37uKKVzVFRQlwetd7INk3YtTD3xm9WUYr7bCvYUk3uKy2g==} engines: {node: '>=20.18.0'} peerDependencies: typescript: ^5.0.0 @@ -1358,8 +1912,8 @@ packages: peerDependencies: typescript: '>=5.3.3' - '@solana/errors@5.4.0': - resolution: {integrity: sha512-hNoAOmlZAszaVBrAy1Jf7amHJ8wnUnTU0BqhNQXknbSvirvsYr81yEud2iq18YiCqhyJ9SuQ5kWrSAT0x7S0oA==} + '@solana/errors@5.5.1': + resolution: {integrity: sha512-vFO3p+S7HoyyrcAectnXbdsMfwUzY2zYFUc2DEe5BwpiE9J1IAxPBGjOWO6hL1bbYdBrlmjNx8DXCslqS+Kcmg==} engines: {node: '>=20.18.0'} hasBin: true peerDependencies: @@ -1368,8 +1922,8 @@ packages: typescript: optional: true - '@solana/fast-stable-stringify@5.4.0': - resolution: {integrity: sha512-KB7PUL7yalPvbWCezzyUDVRDp39eHLPH7OJ6S8VFT8YNIFUANwwj5ctui50Fim76kvSYDdYJOclXV45O2gfQ8Q==} + '@solana/fast-stable-stringify@5.5.1': + resolution: {integrity: sha512-Ni7s2FN33zTzhTFgRjEbOVFO+UAmK8qi3Iu0/GRFYK4jN696OjKHnboSQH/EacQ+yGqS54bfxf409wU5dsLLCw==} engines: {node: '>=20.18.0'} peerDependencies: typescript: ^5.0.0 @@ -1377,8 +1931,8 @@ packages: typescript: optional: true - '@solana/functional@5.4.0': - resolution: {integrity: sha512-32ghHO0bg6GgX/7++0/7Lps6RgeXD2gKF1okiuyEGuVfKENIapgaQdcGhUwb3q6D6fv6MRAVn/Yve4jopGVNMQ==} + '@solana/functional@5.5.1': + resolution: {integrity: sha512-tTHoJcEQq3gQx5qsdsDJ0LEJeFzwNpXD80xApW9o/PPoCNimI3SALkZl+zNW8VnxRrV3l3yYvfHWBKe/X3WG3w==} engines: {node: '>=20.18.0'} peerDependencies: typescript: ^5.0.0 @@ -1386,8 +1940,8 @@ packages: typescript: optional: true - '@solana/instruction-plans@5.4.0': - resolution: {integrity: sha512-5xbJ+I/pP2aWECmK75bEM1zCnIITlohAK83dVN+t5X2vBFrr6M9gifo8r4Opdnibsgo6QVVkKPxRo5zow5j0ig==} + '@solana/instruction-plans@5.5.1': + resolution: {integrity: sha512-7z3CB7YMcFKuVvgcnNY8bY6IsZ8LG61Iytbz7HpNVGX2u1RthOs1tRW8luTzSG1MPL0Ox7afyAVMYeFqSPHnaQ==} engines: {node: '>=20.18.0'} peerDependencies: typescript: ^5.0.0 @@ -1395,8 +1949,8 @@ packages: typescript: optional: true - '@solana/instructions@5.4.0': - resolution: {integrity: sha512-//a7jpHbNoAgTqy3YyqG1X6QhItJLKzJa6zuYJGCwaAAJye7BxS9pxJBgb2mUt7CGidhUksf+U8pmLlxCNWYyg==} + '@solana/instructions@5.5.1': + resolution: {integrity: sha512-h0G1CG6S+gUUSt0eo6rOtsaXRBwCq1+Js2a+Ps9Bzk9q7YHNFA75/X0NWugWLgC92waRp66hrjMTiYYnLBoWOQ==} engines: {node: '>=20.18.0'} peerDependencies: typescript: ^5.0.0 @@ -1404,8 +1958,8 @@ packages: typescript: optional: true - '@solana/keys@5.4.0': - resolution: {integrity: sha512-zQVbAwdoXorgXjlhlVTZaymFG6N8n1zn2NT+xI6S8HtbrKIB/42xPdXFh+zIihGzRw+9k8jzU7Axki/IPm6qWQ==} + '@solana/keys@5.5.1': + resolution: {integrity: sha512-KRD61cL7CRL+b4r/eB9dEoVxIf/2EJ1Pm1DmRYhtSUAJD2dJ5Xw8QFuehobOGm9URqQ7gaQl+Fkc1qvDlsWqKg==} engines: {node: '>=20.18.0'} peerDependencies: typescript: ^5.0.0 @@ -1413,8 +1967,8 @@ packages: typescript: optional: true - '@solana/kit@5.4.0': - resolution: {integrity: sha512-aVjN26jOEzJA6UBYxSTQciZPXgTxWnO/WysHrw+yeBL/5AaTZnXEgb4j5xV6cUFzOlVxhJBrx51xtoxSqJ0u3g==} + '@solana/kit@5.5.1': + resolution: {integrity: sha512-irKUGiV2yRoyf+4eGQ/ZeCRxa43yjFEL1DUI5B0DkcfZw3cr0VJtVJnrG8OtVF01vT0OUfYOcUn6zJW5TROHvQ==} engines: {node: '>=20.18.0'} peerDependencies: typescript: ^5.0.0 @@ -1422,8 +1976,8 @@ packages: typescript: optional: true - '@solana/nominal-types@5.4.0': - resolution: {integrity: sha512-h4dTRQwTerzksE5B1WmObN6TvLo8dYUd7kpUUynGd8WJjK0zz3zkDhq0MkA3aF6A1C2C82BSGqSsN9EN0E6Exg==} + '@solana/nominal-types@5.5.1': + resolution: {integrity: sha512-I1ImR+kfrLFxN5z22UDiTWLdRZeKtU0J/pkWkO8qm/8WxveiwdIv4hooi8pb6JnlR4mSrWhq0pCIOxDYrL9GIQ==} engines: {node: '>=20.18.0'} peerDependencies: typescript: ^5.0.0 @@ -1431,8 +1985,8 @@ packages: typescript: optional: true - '@solana/offchain-messages@5.4.0': - resolution: {integrity: sha512-DjdlYJCcKfgh4dkdk+owH1bP+Q4BRqCs55mgWWp9PTwm/HHy/a5vcMtCi1GyIQXfhtNNvKBLbXrUE0Fxej8qlg==} + '@solana/offchain-messages@5.5.1': + resolution: {integrity: sha512-g+xHH95prTU+KujtbOzj8wn+C7ZNoiLhf3hj6nYq3MTyxOXtBEysguc97jJveUZG0K97aIKG6xVUlMutg5yxhw==} engines: {node: '>=20.18.0'} peerDependencies: typescript: ^5.0.0 @@ -1440,8 +1994,8 @@ packages: typescript: optional: true - '@solana/options@5.4.0': - resolution: {integrity: sha512-h4vTWRChEXPhaHo9i1pCyQBWWs+NqYPQRXSAApqpUYvHb9Kct/C6KbHjfyaRMyqNQnDHLcJCX7oW9tk0iRDzIg==} + '@solana/options@5.5.1': + resolution: {integrity: sha512-eo971c9iLNLmk+yOFyo7yKIJzJ/zou6uKpy6mBuyb/thKtS/haiKIc3VLhyTXty3OH2PW8yOlORJnv4DexJB8A==} engines: {node: '>=20.18.0'} peerDependencies: typescript: ^5.0.0 @@ -1449,8 +2003,8 @@ packages: typescript: optional: true - '@solana/plugin-core@5.4.0': - resolution: {integrity: sha512-e1aLGLldW7C5113qTOjFYSGq95a4QC9TWb77iq+8l6h085DcNj+195r4E2zKaINrevQjQTwvxo00oUyHP7hSJA==} + '@solana/plugin-core@5.5.1': + resolution: {integrity: sha512-VUZl30lDQFJeiSyNfzU1EjYt2QZvoBFKEwjn1lilUJw7KgqD5z7mbV7diJhT+dLFs36i0OsjXvq5kSygn8YJ3A==} engines: {node: '>=20.18.0'} peerDependencies: typescript: ^5.0.0 @@ -1458,8 +2012,8 @@ packages: typescript: optional: true - '@solana/programs@5.4.0': - resolution: {integrity: sha512-Sc90WK9ZZ7MghOflIvkrIm08JwsFC99yqSJy28/K+hDP2tcx+1x+H6OFP9cumW9eUA1+JVRDeKAhA8ak7e/kUA==} + '@solana/programs@5.5.1': + resolution: {integrity: sha512-7U9kn0Jsx1NuBLn5HRTFYh78MV4XN145Yc3WP/q5BlqAVNlMoU9coG5IUTJIG847TUqC1lRto3Dnpwm6T4YRpA==} engines: {node: '>=20.18.0'} peerDependencies: typescript: ^5.0.0 @@ -1467,8 +2021,8 @@ packages: typescript: optional: true - '@solana/promises@5.4.0': - resolution: {integrity: sha512-23mfgNBbuP6Q+4vsixGy+GkyZ7wBLrxTBNXqrG/XWrJhjuuSkjEUGaK4Fx5o7LIrBi6KGqPknKxmTlvqnJhy2Q==} + '@solana/promises@5.5.1': + resolution: {integrity: sha512-T9lfuUYkGykJmppEcssNiCf6yiYQxJkhiLPP+pyAc2z84/7r3UVIb2tNJk4A9sucS66pzJnVHZKcZVGUUp6wzA==} engines: {node: '>=20.18.0'} peerDependencies: typescript: ^5.0.0 @@ -1476,8 +2030,8 @@ packages: typescript: optional: true - '@solana/rpc-api@5.4.0': - resolution: {integrity: sha512-FJL6KaAsQ4DhfhLKKMcqbTpToNFwHlABCemIpOunE3OSqJFDrmc/NbsEaLIoeHyIg3d1Imo49GIUOn2TEouFUA==} + '@solana/rpc-api@5.5.1': + resolution: {integrity: sha512-XWOQQPhKl06Vj0xi3RYHAc6oEQd8B82okYJ04K7N0Vvy3J4PN2cxeK7klwkjgavdcN9EVkYCChm2ADAtnztKnA==} engines: {node: '>=20.18.0'} peerDependencies: typescript: ^5.0.0 @@ -1485,8 +2039,8 @@ packages: typescript: optional: true - '@solana/rpc-parsed-types@5.4.0': - resolution: {integrity: sha512-IRQuSzx+Sj1A3XGiIzguNZlMjMMybXTTjV/RnTwBgnJQPd/H4us4pfPD94r+/yolWDVfGjJRm04hnKVMjJU8Rg==} + '@solana/rpc-parsed-types@5.5.1': + resolution: {integrity: sha512-HEi3G2nZqGEsa3vX6U0FrXLaqnUCg4SKIUrOe8CezD+cSFbRTOn3rCLrUmJrhVyXlHoQVaRO9mmeovk31jWxJg==} engines: {node: '>=20.18.0'} peerDependencies: typescript: ^5.0.0 @@ -1494,8 +2048,8 @@ packages: typescript: optional: true - '@solana/rpc-spec-types@5.4.0': - resolution: {integrity: sha512-JU9hC5/iyJx30ym17gpoXDtT9rCbO6hLpB6UDhSFFoNeirxtTVb4OdnKtsjJDfXAiXsynJRsZRwfj3vGxRLgQw==} + '@solana/rpc-spec-types@5.5.1': + resolution: {integrity: sha512-6OFKtRpIEJQs8Jb2C4OO8KyP2h2Hy1MFhatMAoXA+0Ik8S3H+CicIuMZvGZ91mIu/tXicuOOsNNLu3HAkrakrw==} engines: {node: '>=20.18.0'} peerDependencies: typescript: ^5.0.0 @@ -1503,8 +2057,8 @@ packages: typescript: optional: true - '@solana/rpc-spec@5.4.0': - resolution: {integrity: sha512-XMhxBb1GuZ3Kaeu5WNHB5KteCQ/aVuMByZmUKPqaanD+gs5MQZr0g62CvN7iwRlFU7GC18Q73ROWR3/JjzbXTA==} + '@solana/rpc-spec@5.5.1': + resolution: {integrity: sha512-m3LX2bChm3E3by4mQrH4YwCAFY57QBzuUSWqlUw7ChuZ+oLLOq7b2czi4i6L4Vna67j3eCmB3e+4tqy1j5wy7Q==} engines: {node: '>=20.18.0'} peerDependencies: typescript: ^5.0.0 @@ -1512,8 +2066,8 @@ packages: typescript: optional: true - '@solana/rpc-subscriptions-api@5.4.0': - resolution: {integrity: sha512-euAFIG6ruEsqK+MsrL1tGSMbbOumm8UAyGzlD/kmXsAqqhcVsSeZdv5+BMIHIBsQ93GHcloA8UYw1BTPhpgl9w==} + '@solana/rpc-subscriptions-api@5.5.1': + resolution: {integrity: sha512-5Oi7k+GdeS8xR2ly1iuSFkAv6CZqwG0Z6b1QZKbEgxadE1XGSDrhM2cn59l+bqCozUWCqh4c/A2znU/qQjROlw==} engines: {node: '>=20.18.0'} peerDependencies: typescript: ^5.0.0 @@ -1521,8 +2075,8 @@ packages: typescript: optional: true - '@solana/rpc-subscriptions-channel-websocket@5.4.0': - resolution: {integrity: sha512-kWCmlW65MccxqXwKsIz+LkXUYQizgvBrrgYOkyclJHPa+zx4gqJjam87+wzvO9cfbDZRer3wtJBaRm61gTHNbw==} + '@solana/rpc-subscriptions-channel-websocket@5.5.1': + resolution: {integrity: sha512-7tGfBBrYY8TrngOyxSHoCU5shy86iA9SRMRrPSyBhEaZRAk6dnbdpmUTez7gtdVo0BCvh9nzQtUycKWSS7PnFQ==} engines: {node: '>=20.18.0'} peerDependencies: typescript: ^5.0.0 @@ -1530,8 +2084,8 @@ packages: typescript: optional: true - '@solana/rpc-subscriptions-spec@5.4.0': - resolution: {integrity: sha512-ELaV9Z39GtKyUO0++he00ymWleb07QXYJhSfA0e1N5Q9hXu/Y366kgXHDcbZ/oUJkT3ylNgTupkrsdtiy8Ryow==} + '@solana/rpc-subscriptions-spec@5.5.1': + resolution: {integrity: sha512-iq+rGq5fMKP3/mKHPNB6MC8IbVW41KGZg83Us/+LE3AWOTWV1WT20KT2iH1F1ik9roi42COv/TpoZZvhKj45XQ==} engines: {node: '>=20.18.0'} peerDependencies: typescript: ^5.0.0 @@ -1539,8 +2093,8 @@ packages: typescript: optional: true - '@solana/rpc-subscriptions@5.4.0': - resolution: {integrity: sha512-051t1CEjjAzM9ohjj2zb3ED70yeS3ZY8J5wSytL6tthTGImw/JB2a0D9DWMOKriFKt496n95IC+IdpJ35CpBWA==} + '@solana/rpc-subscriptions@5.5.1': + resolution: {integrity: sha512-CTMy5bt/6mDh4tc6vUJms9EcuZj3xvK0/xq8IQ90rhkpYvate91RjBP+egvjgSayUg9yucU9vNuUpEjz4spM7w==} engines: {node: '>=20.18.0'} peerDependencies: typescript: ^5.0.0 @@ -1548,8 +2102,8 @@ packages: typescript: optional: true - '@solana/rpc-transformers@5.4.0': - resolution: {integrity: sha512-dZ8keYloLW+eRAwAPb471uWCFs58yHloLoI+QH0FulYpsSJ7F2BNWYcdnjSS/WiggsNcU6DhpWzYAzlEY66lGQ==} + '@solana/rpc-transformers@5.5.1': + resolution: {integrity: sha512-OsWqLCQdcrRJKvHiMmwFhp9noNZ4FARuMkHT5us3ustDLXaxOjF0gfqZLnMkulSLcKt7TGXqMhBV+HCo7z5M8Q==} engines: {node: '>=20.18.0'} peerDependencies: typescript: ^5.0.0 @@ -1557,8 +2111,8 @@ packages: typescript: optional: true - '@solana/rpc-transport-http@5.4.0': - resolution: {integrity: sha512-vidA+Qtqrnqp3QSVumWHdWJ/986yCr5+qX3fbc9KPm9Ofoto88OMWB/oLJvi2Tfges1UBu/jl+lJdsVckCM1bA==} + '@solana/rpc-transport-http@5.5.1': + resolution: {integrity: sha512-yv8GoVSHqEV0kUJEIhkdOVkR2SvJ6yoWC51cJn2rSV7plr6huLGe0JgujCmB7uZhhaLbcbP3zxXxu9sOjsi7Fg==} engines: {node: '>=20.18.0'} peerDependencies: typescript: ^5.0.0 @@ -1566,8 +2120,8 @@ packages: typescript: optional: true - '@solana/rpc-types@5.4.0': - resolution: {integrity: sha512-+C4N4/5AYzBdt3Y2yzkScknScy/jTx6wfvuJIY9XjOXtdDyZ8TmrnMwdPMTZPGLdLuHplJwlwy1acu/4hqmrBQ==} + '@solana/rpc-types@5.5.1': + resolution: {integrity: sha512-bibTFQ7PbHJJjGJPmfYC2I+/5CRFS4O2p9WwbFraX1Keeel+nRrt/NBXIy8veP5AEn2sVJIyJPpWBRpCx1oATA==} engines: {node: '>=20.18.0'} peerDependencies: typescript: ^5.0.0 @@ -1575,8 +2129,8 @@ packages: typescript: optional: true - '@solana/rpc@5.4.0': - resolution: {integrity: sha512-S6GRG+usnubDs0JSpgc0ZWEh9IPL5KPWMuBoD8ggGVOIVWntp53FpvhYslNzbxWBXlTvJecr2todBipGVM/AqQ==} + '@solana/rpc@5.5.1': + resolution: {integrity: sha512-ku8zTUMrkCWci66PRIBC+1mXepEnZH/q1f3ck0kJZ95a06bOTl5KU7HeXWtskkyefzARJ5zvCs54AD5nxjQJ+A==} engines: {node: '>=20.18.0'} peerDependencies: typescript: ^5.0.0 @@ -1584,8 +2138,8 @@ packages: typescript: optional: true - '@solana/signers@5.4.0': - resolution: {integrity: sha512-s+fZxpi6UPr6XNk2pH/R84WjNRoSktrgG8AGNfsj/V8MJ++eKX7hhIf4JsHZtnnQXXrHmS3ozB2oHlc8yEJvCQ==} + '@solana/signers@5.5.1': + resolution: {integrity: sha512-FY0IVaBT2kCAze55vEieR6hag4coqcuJ31Aw3hqRH7mv6sV8oqwuJmUrx+uFwOp1gwd5OEAzlv6N4hOOple4sQ==} engines: {node: '>=20.18.0'} peerDependencies: typescript: ^5.0.0 @@ -1593,8 +2147,8 @@ packages: typescript: optional: true - '@solana/subscribable@5.4.0': - resolution: {integrity: sha512-72LmfNX7UENgA24sn/xjlWpPAOsrxkWb9DQhuPZxly/gq8rl/rvr7Xu9qBkvFF2po9XpdUrKlccqY4awvfpltA==} + '@solana/subscribable@5.5.1': + resolution: {integrity: sha512-9K0PsynFq0CsmK1CDi5Y2vUIJpCqkgSS5yfDN0eKPgHqEptLEaia09Kaxc90cSZDZU5mKY/zv1NBmB6Aro9zQQ==} engines: {node: '>=20.18.0'} peerDependencies: typescript: ^5.0.0 @@ -1602,8 +2156,8 @@ packages: typescript: optional: true - '@solana/sysvars@5.4.0': - resolution: {integrity: sha512-A5NES7sOlFmpnsiEts5vgyL3NXrt/tGGVSEjlEGvsgwl5EDZNv+xWnNA400uMDqd9O3a5PmH7p/6NsgR+kUzSg==} + '@solana/sysvars@5.5.1': + resolution: {integrity: sha512-k3Quq87Mm+geGUu1GWv6knPk0ALsfY6EKSJGw9xUJDHzY/RkYSBnh0RiOrUhtFm2TDNjOailg8/m0VHmi3reFA==} engines: {node: '>=20.18.0'} peerDependencies: typescript: ^5.0.0 @@ -1611,8 +2165,8 @@ packages: typescript: optional: true - '@solana/transaction-confirmation@5.4.0': - resolution: {integrity: sha512-EdSDgxs84/4gkjQw2r7N+Kgus8x9U+NFo0ufVG+48V8Hzy2t0rlBuXgIxwx0zZwUuTIgaKhpIutJgVncwZ5koA==} + '@solana/transaction-confirmation@5.5.1': + resolution: {integrity: sha512-j4mKlYPHEyu+OD7MBt3jRoX4ScFgkhZC6H65on4Fux6LMScgivPJlwnKoZMnsgxFgWds0pl+BYzSiALDsXlYtw==} engines: {node: '>=20.18.0'} peerDependencies: typescript: ^5.0.0 @@ -1620,8 +2174,8 @@ packages: typescript: optional: true - '@solana/transaction-messages@5.4.0': - resolution: {integrity: sha512-qd/3kZDaPiHM0amhn3vXnupfcsFTVz6CYuHXvq9HFv/fq32+5Kp1FMLnmHwoSxQxdTMDghPdOhC4vhNhuWmuVQ==} + '@solana/transaction-messages@5.5.1': + resolution: {integrity: sha512-aXyhMCEaAp3M/4fP0akwBBQkFPr4pfwoC5CLDq999r/FUwDax2RE/h4Ic7h2Xk+JdcUwsb+rLq85Y52hq84XvQ==} engines: {node: '>=20.18.0'} peerDependencies: typescript: ^5.0.0 @@ -1629,8 +2183,8 @@ packages: typescript: optional: true - '@solana/transactions@5.4.0': - resolution: {integrity: sha512-OuY4M4x/xna8KZQIrz8tSrI9EEul9Od97XejqFmGGkEjbRsUOfJW8705TveTW8jU3bd5RGecFYscPgS2F+m7jQ==} + '@solana/transactions@5.5.1': + resolution: {integrity: sha512-8hHtDxtqalZ157pnx6p8k10D7J/KY/biLzfgh9R09VNLLY3Fqi7kJvJCr7M2ik3oRll56pxhraAGCC9yIT6eOA==} engines: {node: '>=20.18.0'} peerDependencies: typescript: ^5.0.0 @@ -1727,24 +2281,28 @@ packages: engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [glibc] '@tailwindcss/oxide-linux-arm64-musl@4.1.18': resolution: {integrity: sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [musl] '@tailwindcss/oxide-linux-x64-gnu@4.1.18': resolution: {integrity: sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [glibc] '@tailwindcss/oxide-linux-x64-musl@4.1.18': resolution: {integrity: sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [musl] '@tailwindcss/oxide-wasm32-wasi@4.1.18': resolution: {integrity: sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==} @@ -1797,14 +2355,14 @@ packages: peerDependencies: solid-js: '>=1.9.7' - '@tanstack/devtools-vite@0.4.1': - resolution: {integrity: sha512-PkMOomcWnl/pUkCqIjqL/csjPHtkMVBirDpJVOZR7XJZDxo5CuD7B+3KsujFCF4Dsn6QYlae97gCZvxi/CB76Q==} + '@tanstack/devtools-vite@0.5.0': + resolution: {integrity: sha512-Ew+ZdTnmTlVjm4q+/XY/dolx/E1BWMYpiRDyU/MXqHf5epri4MLl5C4UZJaO+ZuUCsKPpsW+ufoM99E2Z4rhug==} engines: {node: '>=18'} peerDependencies: vite: ^6.0.0 || ^7.0.0 - '@tanstack/devtools@0.10.3': - resolution: {integrity: sha512-M2HnKtaNf3Z8JDTNDq+X7/1gwOqSwTnCyC0GR+TYiRZM9mkY9GpvTqp6p6bx3DT8onu2URJiVxgHD9WK2e3MNQ==} + '@tanstack/devtools@0.10.5': + resolution: {integrity: sha512-aptV4sMcdEn/zB8zqNqKSKi8pLzfB7BhdP2MuVmyfWgBDYNchqJjhviaxEXW3tJTolbWwc30o+jszwqxOIcIaA==} engines: {node: '>=18'} peerDependencies: solid-js: '>=1.9.7' @@ -1816,8 +2374,8 @@ packages: '@tanstack/query-core@5.90.20': resolution: {integrity: sha512-OMD2HLpNouXEfZJWcKeVKUgQ5n+n3A2JFmBaScpNDUqSrQSjiveC7dKMe53uJUg1nDG16ttFPz2xfilz6i2uVg==} - '@tanstack/react-devtools@0.9.2': - resolution: {integrity: sha512-JNXvBO3jgq16GzTVm7p65n5zHNfMhnqF6Bm7CawjoqZrjEakxbM6Yvy63aKSIpbrdf+Wun2Xn8P0qD+vp56e1g==} + '@tanstack/react-devtools@0.9.4': + resolution: {integrity: sha512-6wQf8gVKDks1VL+LI5SS4XWK8dQLIjcDF3iMZfidyesWJNmodWbWlRkdgCmK5SpDSbcygjbp3p+LG2nE/SZ1bQ==} engines: {node: '>=18'} peerDependencies: '@types/react': '>=16.8' @@ -1830,20 +2388,20 @@ packages: peerDependencies: react: ^18 || ^19 - '@tanstack/react-router-devtools@1.157.8': - resolution: {integrity: sha512-cD7pJ+IpNBWsHv91bLamdUf5/jByy/He7nSveC/LCvc7mK2sssTQeblhg5km3GeNmBqW7kI6Ah/Rh+LmBBZvgA==} + '@tanstack/react-router-devtools@1.158.0': + resolution: {integrity: sha512-uhciBlsPW67xbDCFyc2RQS00OergfNXYxendGUO2HGy4uTr79aQSCb4l6v+sdlPwUTlzwkAtM6e1illIexF15Q==} engines: {node: '>=12'} peerDependencies: - '@tanstack/react-router': ^1.157.8 - '@tanstack/router-core': ^1.157.8 + '@tanstack/react-router': ^1.158.0 + '@tanstack/router-core': ^1.158.0 react: '>=18.0.0 || >=19.0.0' react-dom: '>=18.0.0 || >=19.0.0' peerDependenciesMeta: '@tanstack/router-core': optional: true - '@tanstack/react-router@1.157.8': - resolution: {integrity: sha512-kl95/8/wQz6bajOg/+HVbQcIDmv0K+M2EflYmulUThyUSWh2ME4OLKDMpTjPpUMQcwsSV/3/Fp9AiUps3Bh+fw==} + '@tanstack/react-router@1.158.0': + resolution: {integrity: sha512-kvTaO6zjq9WWPyo1wwSZx95AjJ9KOvu23cOMgKeDdDQWKF3Z9q3fwhToKMKJoC11T2Vuivz+o/anrxCcOvdRzw==} engines: {node: '>=12'} peerDependencies: react: '>=18.0.0 || >=19.0.0' @@ -1861,43 +2419,35 @@ packages: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - '@tanstack/router-cli@1.157.15': - resolution: {integrity: sha512-a3ni8JUh9svDd4IenJx+9za/Gd1gHzYi4iH36Lf/hgf+zPl6ZBK6cGsveVo2xRVz94iWgpDSWOkgXC0d9fuJ7w==} + '@tanstack/router-cli@1.158.0': + resolution: {integrity: sha512-HydE08MrYY93JQhoB377YOONmtNAhPUw/6pdIUmnRICUx2GV2EK+qXGJ67SDC4YIU/z9X0TDeoZjCO1MDFwiQQ==} engines: {node: '>=12'} hasBin: true - '@tanstack/router-core@1.157.15': - resolution: {integrity: sha512-KaYz6s+wYcg92kRQ7HXlTJLhBaBXOYiiqRBv5tsRbKRIqqhWNyeGz5+NfDwaYFHg5XLSDs3DvN0elMtxcj4dTg==} + '@tanstack/router-core@1.158.0': + resolution: {integrity: sha512-dRMcWY0UB/6OZqSCx/7iUvom0ol18rHSQladygVT8mlth7uxYx3n5BNse8C03efIE8y1Bx+VDOBAKpAZ9BgKog==} engines: {node: '>=12'} - '@tanstack/router-core@1.157.8': - resolution: {integrity: sha512-2fxuhHIZ3yBXN9rxcDOgCsezuwk1VoWvprIDMe+HDi6FBdpWgEREMp0CWEYn33Lxla44iwaTpwvVcFDk8QC/rA==} - engines: {node: '>=12'} - - '@tanstack/router-devtools-core@1.157.8': - resolution: {integrity: sha512-sFVaw7nPQu/U1/y6jEkoMuO9GJ/8OEaDpAnD5zeXHSlZpuhwtwuPnyI02XA75JSrLp4hZUj46BvF5E4uW3ZA+w==} + '@tanstack/router-devtools-core@1.158.0': + resolution: {integrity: sha512-8FUKfjh8Xz9T9O5yYaiVE0Va5aCMncQyVPKb7yy5M/buDnx9Kh0bPjw/eUZJWftOyxW6/WeR605yjOdx/PnqNw==} engines: {node: '>=12'} peerDependencies: - '@tanstack/router-core': ^1.157.8 + '@tanstack/router-core': ^1.158.0 csstype: ^3.0.10 peerDependenciesMeta: csstype: optional: true - '@tanstack/router-generator@1.157.15': - resolution: {integrity: sha512-zGac6tyRFz/X86fk9/CAmS6z8lyZf4p9lhAqLBCKVkFiFPmU4eAJp1ODvs81EtV0uJdRL1/rb+uvgHLGUsmQ0g==} - engines: {node: '>=12'} - - '@tanstack/router-generator@1.157.8': - resolution: {integrity: sha512-P0uvoFkhqrkmn/npgJJ02aGGsw2CMtoEAWQkiJGg00aXyA+026Ny1G/4FPuYsGK11c6yMsOl6FHk/sipNY+2YA==} + '@tanstack/router-generator@1.158.0': + resolution: {integrity: sha512-hVkXQSN/fMD9q3Zn3wNa4PV0Y9VNwQB2bLaecA5i4vc43GX75vmgyiKoMr44BJheUssfVoL/po9a/7sv+N6lKA==} engines: {node: '>=12'} - '@tanstack/router-plugin@1.157.8': - resolution: {integrity: sha512-k3pMbV4DGBAf9rjZL5bdPUAPiFypV4ys6UB8JAK/9EO6zdaF0BksD8KxWgJypuxaaeCMJL/RspOUqCmwbwAXVA==} + '@tanstack/router-plugin@1.158.0': + resolution: {integrity: sha512-FxTOo/icU373jlOu9nlzR0B1vqc47tKZLw3HwOQwCBL4P4EihOBz+L7dcGyKR8bRBL0rCRWvHQTSHNMOr+fGYQ==} engines: {node: '>=12'} peerDependencies: '@rsbuild/core': '>=1.0.2' - '@tanstack/react-router': ^1.157.8 + '@tanstack/react-router': ^1.158.0 vite: '>=5.0.0 || >=6.0.0 || >=7.0.0' vite-plugin-solid: ^2.11.10 webpack: '>=5.92.0' @@ -1913,8 +2463,8 @@ packages: webpack: optional: true - '@tanstack/router-utils@1.154.7': - resolution: {integrity: sha512-61bGx32tMKuEpVRseu2sh1KQe8CfB7793Mch/kyQt0EP3tD7X0sXmimCl3truRiDGUtI0CaSoQV1NPjAII1RBA==} + '@tanstack/router-utils@1.158.0': + resolution: {integrity: sha512-qZ76eaLKU6Ae9iI/mc5zizBX149DXXZkBVVO3/QRIll79uKLJZHQlMKR++2ba7JsciBWz1pgpIBcCJPE9S0LVg==} engines: {node: '>=12'} '@tanstack/store@0.8.0': @@ -1997,16 +2547,16 @@ packages: '@types/node@18.19.130': resolution: {integrity: sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==} - '@types/node@25.0.10': - resolution: {integrity: sha512-zWW5KPngR/yvakJgGOmZ5vTBemDoSqF3AcV/LrO5u5wTWyEAVVh+IT39G4gtyAkh3CtTZs8aX/yRM82OfzHJRg==} + '@types/node@25.2.0': + resolution: {integrity: sha512-DZ8VwRFUNzuqJ5khrvwMXHmvPe+zGayJhr2CDNiKB1WBE1ST8Djl00D0IC4vvNmHMdj6DlbYRIaFE7WHjlDl5w==} '@types/react-dom@19.2.3': resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} peerDependencies: '@types/react': ^19.2.0 - '@types/react@19.2.9': - resolution: {integrity: sha512-Lpo8kgb/igvMIPeNV2rsYKTgaORYdO1XGVZ4Qz3akwOj0ySGYMPlQWa8BaLn0G63D1aSaAQ5ldR06wCpChQCjA==} + '@types/react@19.2.11': + resolution: {integrity: sha512-tORuanb01iEzWvMGVGv2ZDhYZVeRMrw453DCSAIn/5yvcSVnMoUMTyf33nQJLahYEnv9xqrTNbgz4qY5EfSh0g==} '@types/trusted-types@2.0.7': resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} @@ -2025,8 +2575,8 @@ packages: engines: {node: '>=16.14.0'} hasBin: true - '@vitejs/plugin-react@5.1.2': - resolution: {integrity: sha512-EcA07pHJouywpzsoTUqNh5NwGayl2PPVEJKUSinGGSxFGYn+shYbqMGBg6FXDqgXum9Ou/ecb+411ssw8HImJQ==} + '@vitejs/plugin-react@5.1.3': + resolution: {integrity: sha512-NVUnA6gQCl8jfoYqKqQU5Clv0aPw14KkZYCsX6T9Lfu9slI0LOU10OTwFHS/WmptsMMpshNd/1tuWsHQ2Uk+cg==} engines: {node: ^20.19.0 || >=22.12.0} peerDependencies: vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 @@ -2105,8 +2655,42 @@ packages: typescript: optional: true - '@wagmi/core@3.3.1': - resolution: {integrity: sha512-0Q8VYnVNPHe/gZsvj+Zddt8VpmKoMHXoVd887svL21QGKXEIVYiV/8R3qMv0SyC7q+GbQ5x9xezB56u3S8bWAQ==} + '@wagmi/connectors@7.1.6': + resolution: {integrity: sha512-TKBTxSmiUh17tHdD7X1TQLtNIA4exuodPCwC0YuSaIRw8co1EivrUHjsHVsrJ7XKEsQhfp97ZRAVEssGcA4DPA==} + peerDependencies: + '@base-org/account': ^2.5.1 + '@coinbase/wallet-sdk': ^4.3.6 + '@gemini-wallet/core': ~0.3.1 + '@metamask/sdk': ~0.33.1 + '@safe-global/safe-apps-provider': ~0.18.6 + '@safe-global/safe-apps-sdk': ^9.1.0 + '@wagmi/core': 3.3.2 + '@walletconnect/ethereum-provider': ^2.21.1 + porto: ~0.2.35 + typescript: '>=5.7.3' + viem: 2.x + peerDependenciesMeta: + '@base-org/account': + optional: true + '@coinbase/wallet-sdk': + optional: true + '@gemini-wallet/core': + optional: true + '@metamask/sdk': + optional: true + '@safe-global/safe-apps-provider': + optional: true + '@safe-global/safe-apps-sdk': + optional: true + '@walletconnect/ethereum-provider': + optional: true + porto: + optional: true + typescript: + optional: true + + '@wagmi/core@3.3.2': + resolution: {integrity: sha512-e4aefdzEki657u7P6miuBijp0WKmtSsuY2/NT9e3zfJxr+QX5Edr5EcFF0Cg5OMMQ1y32x+g8ogMDppD9aX3kw==} peerDependencies: '@tanstack/query-core': '>=5.0.0' ox: '>=0.11.1' @@ -2232,6 +2816,9 @@ packages: resolution: {integrity: sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==} engines: {node: '>= 8.0.0'} + ajv@8.17.1: + resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} @@ -2252,9 +2839,15 @@ packages: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + aria-query@5.3.0: resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + array-ify@1.0.0: + resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} + asn1.js@4.10.1: resolution: {integrity: sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==} @@ -2285,8 +2878,8 @@ packages: peerDependencies: axios: 0.x || 1.x - axios@1.13.3: - resolution: {integrity: sha512-ERT8kdX7DZjtUm7IitEyV7InTHAF42iJuMArIiDIV5YtPanJkgw4hw5Dyg9fh0mihdWNn1GKaeIWErfe56UQ1g==} + axios@1.13.4: + resolution: {integrity: sha512-1wVkUaAO6WyaYtCkcYCOx12ZgpGf9Zif+qXa4n+oYzK558YryKqiL6UWwd5DqiH3VRW0GYhTZQ/vlgJrCoNQlg==} babel-dead-code-elimination@1.0.12: resolution: {integrity: sha512-GERT7L2TiYcYDtYk1IpD+ASAYXjKbLTDPhBtYj7X1NuRMDTMtAx9kyBenub1Ev41lo91OHCKdmP+egTDmfQ7Ig==} @@ -2306,8 +2899,8 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - baseline-browser-mapping@2.9.11: - resolution: {integrity: sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ==} + baseline-browser-mapping@2.9.19: + resolution: {integrity: sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==} hasBin: true bidi-js@1.0.3: @@ -2412,12 +3005,16 @@ packages: resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} engines: {node: '>= 0.4'} + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + camelcase@5.3.1: resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} engines: {node: '>=6'} - caniuse-lite@1.0.30001762: - resolution: {integrity: sha512-PxZwGNvH7Ak8WX5iXzoK1KPZttBXNPuaOvI2ZYU7NrlM+d9Ov+TUvlLOBNGzVXAntMSMMlJPd+jY6ovrVjSmUw==} + caniuse-lite@1.0.30001766: + resolution: {integrity: sha512-4C0lfJ0/YPjJQHagaE9x2Elb69CIqEPZeG0anQt9SIvIoOH4a4uaRl73IavyO+0qZh6MDLH//DrXThEYKHkmYA==} chai@6.2.2: resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} @@ -2488,6 +3085,9 @@ packages: commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + compare-func@2.0.0: + resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==} + consola@3.4.2: resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} engines: {node: ^14.18.0 || >=16.10.0} @@ -2498,6 +3098,19 @@ packages: constants-browserify@1.0.0: resolution: {integrity: sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==} + conventional-changelog-angular@8.1.0: + resolution: {integrity: sha512-GGf2Nipn1RUCAktxuVauVr1e3r8QrLP/B0lEUsFktmGqc3ddbQkhoJZHJctVU829U1c6mTSWftrVOCHaL85Q3w==} + engines: {node: '>=18'} + + conventional-changelog-conventionalcommits@9.1.0: + resolution: {integrity: sha512-MnbEysR8wWa8dAEvbj5xcBgJKQlX/m0lhS8DsyAAWDHdfs2faDJxTgzRYlRYpXSe7UiKrIIlB4TrBKU9q9DgkA==} + engines: {node: '>=18'} + + conventional-commits-parser@6.2.1: + resolution: {integrity: sha512-20pyHgnO40rvfI0NGF/xiEoFMkXDtkF8FwHvk5BokoFoCuTQRI8vrNCNFWUOfuolKJMm1tPCHc8GgYEtr1XRNA==} + engines: {node: '>=18'} + hasBin: true + convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} @@ -2510,6 +3123,23 @@ packages: core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + cosmiconfig-typescript-loader@6.2.0: + resolution: {integrity: sha512-GEN39v7TgdxgIoNcdkRE3uiAzQt3UXLyHbRHD6YoL048XAeOomyxaP+Hh/+2C6C2wYjxJ2onhJcsQp+L4YEkVQ==} + engines: {node: '>=v18'} + peerDependencies: + '@types/node': '*' + cosmiconfig: '>=9' + typescript: '>=5' + + cosmiconfig@9.0.0: + resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + create-ecdh@4.0.4: resolution: {integrity: sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==} @@ -2546,9 +3176,13 @@ packages: csstype@3.2.3: resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} - data-urls@6.0.0: - resolution: {integrity: sha512-BnBS08aLUM+DKamupXs3w2tJJoqU+AkaE/+6vQxi/G/DPmIZFJJp9Dkb1kM03AZx8ADehDUZgsNxju3mPXZYIA==} - engines: {node: '>=20'} + dargs@8.1.0: + resolution: {integrity: sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==} + engines: {node: '>=12'} + + data-urls@7.0.0: + resolution: {integrity: sha512-23XHcCF+coGYevirZceTVD7NdJOqVn+49IHyxgszm+JIiHLoB2TkmPtsYkNWT1pvRSGkc35L6NHs0yHkN2SumA==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} dayjs@1.11.13: resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} @@ -2630,15 +3264,19 @@ packages: resolution: {integrity: sha512-IGBwjF7tNk3cwypFNH/7bfzBcgSCbaMOD3GsaY1AU/JRrnHnYgEM0+9kQt52iZxjNsjBtJYtao146V+f8jFZNw==} engines: {node: '>=10'} + dot-prop@5.3.0: + resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} + engines: {node: '>=8'} + dunder-proto@1.0.1: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} - effect@3.19.15: - resolution: {integrity: sha512-vzMmgfZKLcojmUjBdlQx+uaKryO7yULlRxjpDnHdnvcp1NPHxJyoM6IOXBLlzz2I/uPtZpGKavt5hBv7IvGZkA==} + effect@3.19.16: + resolution: {integrity: sha512-7+XC3vGrbAhCHd8LTFHvnZjRpZKZ8YHRZqJTkpNoxcJ2mCyNs2SwI+6VkV/ij8Y3YW7wfBN4EbU06/F5+m/wkQ==} - electron-to-chromium@1.5.267: - resolution: {integrity: sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==} + electron-to-chromium@1.5.283: + resolution: {integrity: sha512-3vifjt1HgrGW/h76UEeny+adYApveS9dH2h3p57JYzBSXJIKUJAvtmIytDKjcSCt9xHfrNCFJ7gts6vkhuq++w==} elliptic@6.6.1: resolution: {integrity: sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==} @@ -2657,8 +3295,15 @@ packages: resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} engines: {node: '>=0.12'} - es-define-property@1.0.1: - resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + + error-ex@1.3.4: + resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} engines: {node: '>= 0.4'} es-errors@1.3.0: @@ -2727,9 +3372,15 @@ packages: resolution: {integrity: sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==} engines: {node: '>=8.0.0'} + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + fast-stable-stringify@1.0.0: resolution: {integrity: sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==} + fast-uri@3.1.0: + resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} + fdir@6.5.0: resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} engines: {node: '>=12.0.0'} @@ -2807,10 +3458,19 @@ packages: get-tsconfig@4.13.0: resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==} + git-raw-commits@4.0.0: + resolution: {integrity: sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==} + engines: {node: '>=16'} + hasBin: true + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} + global-directory@4.0.1: + resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} + engines: {node: '>=18'} + goober@2.1.18: resolution: {integrity: sha512-2vFqsaDVIT9Gz7N6kAL++pLpp41l3PfDuusHcjnGLfR6+huZkl6ziX+zgVC3ZxpqWhzH6pyDdGrCeDhMIvwaxw==} peerDependencies: @@ -2873,6 +3533,11 @@ packages: humanize-ms@1.2.1: resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + husky@9.1.7: + resolution: {integrity: sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==} + engines: {node: '>=18'} + hasBin: true + ico-endec@0.1.6: resolution: {integrity: sha512-ZdLU38ZoED3g1j3iEyzcQj+wAkY2xfWNkymszfJPoxucIUhK7NayQ+/C4Kv0nDFMIsbtbEHldv3V8PU494/ueQ==} @@ -2885,9 +3550,20 @@ packages: ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + import-meta-resolve@4.2.0: + resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} + inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + ini@4.1.1: + resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + iron-webcrypto@1.2.1: resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} @@ -2895,6 +3571,9 @@ packages: resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==} engines: {node: '>= 0.4'} + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + is-arrayish@0.3.4: resolution: {integrity: sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==} @@ -2937,6 +3616,14 @@ packages: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} + is-obj@2.0.0: + resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} + engines: {node: '>=8'} + + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + is-potential-custom-element-name@1.0.1: resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} @@ -2958,8 +3645,8 @@ packages: isarray@2.0.5: resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} - isbot@5.1.33: - resolution: {integrity: sha512-P4Hgb5NqswjkI0J1CM6XKXon/sxKY1SuowE7Qx2hrBhIwICFyXy54mfgB5eMHXsbe/eStzzpbIGNOvGmz+dlKg==} + isbot@5.1.34: + resolution: {integrity: sha512-aCMIBSKd/XPRYdiCQTLC8QHH4YT8B3JUADu+7COgYIZPvkeoMcUHMRjZLM9/7V8fCj+l7FSREc1lOPNjzogo/A==} engines: {node: '>=18'} isomorphic-timers-promises@1.0.1: @@ -2991,8 +3678,12 @@ packages: js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - jsdom@27.4.0: - resolution: {integrity: sha512-mjzqwWRD9Y1J1KUi7W97Gja1bwOOM5Ug0EZ6UDK3xS7j7mndrkwozHtSblfomlzyB4NepioNt+B2sOSzczVgtQ==} + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + hasBin: true + + jsdom@28.0.0: + resolution: {integrity: sha512-KDYJgZ6T2TKdU8yBfYueq5EPG/EylMsBvCaenWMJb2OXmjgczzwveRCoJ+Hgj1lXPDyasvrgneSn4GBuR1hYyA==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} peerDependencies: canvas: ^3.0.0 @@ -3005,6 +3696,12 @@ packages: engines: {node: '>=6'} hasBin: true + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + json-stringify-safe@5.0.1: resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} @@ -3060,24 +3757,28 @@ packages: engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] lightningcss-linux-arm64-musl@1.30.2: resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [musl] lightningcss-linux-x64-gnu@1.30.2: resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [glibc] lightningcss-linux-x64-musl@1.30.2: resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [musl] lightningcss-win32-arm64-msvc@1.30.2: resolution: {integrity: sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==} @@ -3095,6 +3796,9 @@ packages: resolution: {integrity: sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==} engines: {node: '>= 12.0.0'} + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + lit-element@4.2.2: resolution: {integrity: sha512-aFKhNToWxoyhkNDmWZwEva2SlQia+jfG0fjIWV//YeTaWrVnOxD89dPKfigCUspXFmjzOEUQpOkejH5Ly6sG0w==} @@ -3112,11 +3816,29 @@ packages: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} + lodash.camelcase@4.3.0: + resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} + lodash.clonedeep@4.5.0: resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==} - lru-cache@11.2.4: - resolution: {integrity: sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==} + lodash.kebabcase@4.1.1: + resolution: {integrity: sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==} + + lodash.mergewith@4.6.2: + resolution: {integrity: sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==} + + lodash.snakecase@4.1.1: + resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==} + + lodash.startcase@4.4.0: + resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} + + lodash.upperfirst@4.3.1: + resolution: {integrity: sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==} + + lru-cache@11.2.5: + resolution: {integrity: sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==} engines: {node: 20 || >=22} lru-cache@5.1.1: @@ -3147,6 +3869,14 @@ packages: mdn-data@2.12.2: resolution: {integrity: sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==} + meow@12.1.1: + resolution: {integrity: sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==} + engines: {node: '>=16.10'} + + meow@13.2.0: + resolution: {integrity: sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==} + engines: {node: '>=18'} + miller-rabin@4.0.1: resolution: {integrity: sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==} hasBin: true @@ -3170,6 +3900,9 @@ packages: minimalistic-crypto-utils@1.0.1: resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + mipd@0.0.7: resolution: {integrity: sha512-aAPZPNDQ3uMTdKbuO2YmAw2TxLHO0moa4YKAyETM/DTj5FloZo+a+8tU+iv4GmW+sOxKLSRwcSFuczk+Cpt6fg==} peerDependencies: @@ -3320,10 +4053,18 @@ packages: pako@1.0.11: resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + parse-asn1@5.1.9: resolution: {integrity: sha512-fIYNuZ/HastSb80baGOuPRo1O9cf4baWw5WsAp7dBuUzeTD/BoaG8sVTdlPFksBE2lF21dN+A1AnrpIjSWqHHg==} engines: {node: '>= 0.10'} + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + parse5@8.0.0: resolution: {integrity: sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA==} @@ -3468,10 +4209,10 @@ packages: randomfill@1.0.4: resolution: {integrity: sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==} - react-dom@19.2.3: - resolution: {integrity: sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==} + react-dom@19.2.4: + resolution: {integrity: sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==} peerDependencies: - react: ^19.2.3 + react: ^19.2.4 react-is@17.0.2: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} @@ -3480,8 +4221,8 @@ packages: resolution: {integrity: sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==} engines: {node: '>=0.10.0'} - react@19.2.3: - resolution: {integrity: sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==} + react@19.2.4: + resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==} engines: {node: '>=0.10.0'} readable-stream@2.3.8: @@ -3524,6 +4265,14 @@ packages: reselect@5.1.1: resolution: {integrity: sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==} + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} @@ -3536,8 +4285,8 @@ packages: resolution: {integrity: sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA==} engines: {node: '>= 0.8'} - rollup@4.56.0: - resolution: {integrity: sha512-9FwVqlgUHzbXtDg9RCMgodF3Ua4Na6Gau+Sdt9vyCN4RhHfVKX2DCHy3BjMLTDd47ITDhYAnTwGulWTblJSDLg==} + rollup@4.57.1: + resolution: {integrity: sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -3582,22 +4331,12 @@ packages: engines: {node: '>=10'} hasBin: true - seroval-plugins@1.3.3: - resolution: {integrity: sha512-16OL3NnUBw8JG1jBLUoZJsLnQq0n5Ua6aHalhJK4fMQkz1lqR7Osz1sA30trBtd9VUDc2NgkuRCn8+/pBwqZ+w==} - engines: {node: '>=10'} - peerDependencies: - seroval: ^1.0 - seroval-plugins@1.5.0: resolution: {integrity: sha512-EAHqADIQondwRZIdeW2I636zgsODzoBDwb3PT/+7TLDWyw1Dy/Xv7iGUIEXXav7usHDE9HVhOU61irI3EnyyHA==} engines: {node: '>=10'} peerDependencies: seroval: ^1.0 - seroval@1.3.2: - resolution: {integrity: sha512-RbcPH1n5cfwKrru7v7+zrZvjLurgHhGyso3HTyGtRivGWgYjbOmGuivCQaORNELjNONoK35nj28EoWul9sb1zQ==} - engines: {node: '>=10'} - seroval@1.5.0: resolution: {integrity: sha512-OE4cvmJ1uSPrKorFIH9/w/Qwuvi/IMcGbv5RKgcJ/zjA/IohDLU6SVaxFN9FwajbP7nsX0dQqMDes1whk3y+yw==} engines: {node: '>=10'} @@ -3657,8 +4396,8 @@ packages: slow-redact@0.3.2: resolution: {integrity: sha512-MseHyi2+E/hBRqdOi5COy6wZ7j7DxXRz9NkseavNYSvvWC06D8a5cidVZX3tcG5eCW3NIyVU4zT63hw0Q486jw==} - solid-js@1.9.10: - resolution: {integrity: sha512-Coz956cos/EPDlhs6+jsdTxKuJDPT7B5SVIWgABwROyxjY7Xbr8wkzD68Et+NxnV7DLJ3nJdAC2r9InuV/4Jew==} + solid-js@1.9.11: + resolution: {integrity: sha512-WEJtcc5mkh/BnHA6Yrg4whlF8g6QwpmXXRg4P2ztPmcKeHHlH4+djYecBLhSpecZY2RRECXYUwIc/C2r3yzQ4Q==} sonic-boom@4.2.0: resolution: {integrity: sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==} @@ -3772,11 +4511,11 @@ packages: resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==} engines: {node: '>=14.0.0'} - tldts-core@7.0.19: - resolution: {integrity: sha512-lJX2dEWx0SGH4O6p+7FPwYmJ/bu1JbcGJ8RLaG9b7liIgZ85itUVEPbMtWRVrde/0fnDPEPHW10ZsKW3kVsE9A==} + tldts-core@7.0.22: + resolution: {integrity: sha512-KgbTDC5wzlL6j/x6np6wCnDSMUq4kucHNm00KXPbfNzmllCmtmvtykJHfmgdHntwIeupW04y8s1N/43S1PkQDw==} - tldts@7.0.19: - resolution: {integrity: sha512-8PWx8tvC4jDB39BQw1m4x8y5MH1BcQ5xHeL2n7UVFulMPH/3Q0uiamahFJ3lXA0zO2SUyRXuVVbWSDmstlt9YA==} + tldts@7.0.22: + resolution: {integrity: sha512-nqpKFC53CgopKPjT6Wfb6tpIcZXHcI6G37hesvikhx0EmUGPkZrujRyAjgnmp1SHNgpQfKVanZ+KfpANFt2Hxw==} hasBin: true to-buffer@1.2.2: @@ -3819,6 +4558,40 @@ packages: tty-browserify@0.0.1: resolution: {integrity: sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==} + turbo-darwin-64@2.8.3: + resolution: {integrity: sha512-4kXRLfcygLOeNcP6JquqRLmGB/ATjjfehiojL2dJkL7GFm3SPSXbq7oNj8UbD8XriYQ5hPaSuz59iF1ijPHkTw==} + cpu: [x64] + os: [darwin] + + turbo-darwin-arm64@2.8.3: + resolution: {integrity: sha512-xF7uCeC0UY0Hrv/tqax0BMbFlVP1J/aRyeGQPZT4NjvIPj8gSPDgFhfkfz06DhUwDg5NgMo04uiSkAWE8WB/QQ==} + cpu: [arm64] + os: [darwin] + + turbo-linux-64@2.8.3: + resolution: {integrity: sha512-vxMDXwaOjweW/4etY7BxrXCSkvtwh0PbwVafyfT1Ww659SedUxd5rM3V2ZCmbwG8NiCfY7d6VtxyHx3Wh1GoZA==} + cpu: [x64] + os: [linux] + + turbo-linux-arm64@2.8.3: + resolution: {integrity: sha512-mQX7uYBZFkuPLLlKaNe9IjR1JIef4YvY8f21xFocvttXvdPebnq3PK1Zjzl9A1zun2BEuWNUwQIL8lgvN9Pm3Q==} + cpu: [arm64] + os: [linux] + + turbo-windows-64@2.8.3: + resolution: {integrity: sha512-YLGEfppGxZj3VWcNOVa08h6ISsVKiG85aCAWosOKNUjb6yErWEuydv6/qImRJUI+tDLvDvW7BxopAkujRnWCrw==} + cpu: [x64] + os: [win32] + + turbo-windows-arm64@2.8.3: + resolution: {integrity: sha512-afTUGKBRmOJU1smQSBnFGcbq0iabAPwh1uXu2BVk7BREg30/1gMnJh9DFEQTah+UD3n3ru8V55J83RQNFfqoyw==} + cpu: [arm64] + os: [win32] + + turbo@2.8.3: + resolution: {integrity: sha512-8Osxz5Tu/Dw2kb31EAY+nhq/YZ3wzmQSmYa1nIArqxgCAldxv9TPlrAiaBUDVnKA4aiPn0OFBD1ACcpc5VFOAQ==} + hasBin: true + tw-animate-css@1.4.0: resolution: {integrity: sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==} @@ -3855,11 +4628,15 @@ packages: undici-types@7.16.0: resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} - undici-types@7.19.1: - resolution: {integrity: sha512-z2f4eae6/P3L9bogRUfLEZfRRxyrH4ssRq8s2/NOOgXEwwM5w0hsaj+mtDJPN7sBXQQNlagCzYUfjHywUiTETw==} + undici-types@7.19.2: + resolution: {integrity: sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==} + + undici@7.19.2: + resolution: {integrity: sha512-4VQSpGEGsWzk0VYxyB/wVX/Q7qf9t5znLRgs0dzszr9w9Fej/8RVNQ+S20vdXSAyra/bJ7ZQfGv6ZMj7UEbzSg==} + engines: {node: '>=20.18.1'} - undici@7.19.1: - resolution: {integrity: sha512-Gpq0iNm5M6cQWlyHQv9MV+uOj1jWk7LpkoE5vSp/7zjb4zMdAcUD+VL5y0nH4p9EbUklq00eVIIX/XcDHzu5xg==} + undici@7.20.0: + resolution: {integrity: sha512-MJZrkjyd7DeC+uPZh+5/YaMDxFiiEEaDgbUSVMXayofAkDWF1088CDo+2RPg7B1BuS1qf1vgNE7xqwPxE0DuSQ==} engines: {node: '>=20.18.1'} unplugin@2.3.11: @@ -3982,8 +4759,8 @@ packages: react: optional: true - viem@2.45.0: - resolution: {integrity: sha512-iVA9qrAgRdtpWa80lCZ6Jri6XzmLOwwA1wagX2HnKejKeliFLpON0KOdyfqvcy+gUpBVP59LBxP2aKiL3aj8fg==} + viem@2.45.1: + resolution: {integrity: sha512-LN6Pp7vSfv50LgwhkfSbIXftAM5J89lP9x8TeDa8QM7o41IxlHrDh0F9X+FfnCWtsz11pEVV5sn+yBUoOHNqYA==} peerDependencies: typescript: '>=5.0.4' peerDependenciesMeta: @@ -4035,8 +4812,8 @@ packages: yaml: optional: true - vitest-browser-react@2.0.4: - resolution: {integrity: sha512-FQq2z519Bwp/rANaQXU+ox7M4d0q/bTQkF2pgwRAehE+pqJ6myYOLp+P2Dy2kuk+K4IQJHMyijMCSQ1da/xW8w==} + vitest-browser-react@2.0.5: + resolution: {integrity: sha512-YODQX8mHTJCyKNVYTWJrLEYrUtw+QfLl78owgvuE7C5ydgmGBq6v5s4jK2w6wdPhIZsN9PpV1rQbmAevWJjO9g==} peerDependencies: '@types/react': ^18.0.0 || ^19.0.0 '@types/react-dom': ^18.0.0 || ^19.0.0 @@ -4090,8 +4867,8 @@ packages: resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} engines: {node: '>=18'} - wagmi@3.4.1: - resolution: {integrity: sha512-v6svxWxfIqV82lXNclOMn+h0SYCtXtxf0HWCwyjIJPZH1SR7yRqyQguWUDQtzvNSefFQEoCk+MVOX9nTR5d4Zw==} + wagmi@3.4.2: + resolution: {integrity: sha512-ZPZUquVh75NCHvb0qI+SBegUzcFHGIGtIKCL6gtHLcYHMcEMllqZGXtkIpc98IUq5Vq7Qey4FSG4ohTtMfQ/Yw==} peerDependencies: '@tanstack/react-query': '>=5.0.0' react: '>=18' @@ -4111,14 +4888,14 @@ packages: webpack-virtual-modules@0.6.2: resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} - whatwg-mimetype@4.0.0: - resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} - engines: {node: '>=18'} - - whatwg-url@15.1.0: - resolution: {integrity: sha512-2ytDk0kiEj/yu90JOAp44PVPUkO9+jVhyf+SybKlRHSDlvOOZhdPIrr7xTH64l4WixO2cP+wQIcgujkGBPPz6g==} + whatwg-mimetype@5.0.0: + resolution: {integrity: sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==} engines: {node: '>=20'} + whatwg-url@16.0.0: + resolution: {integrity: sha512-9CcxtEKsf53UFwkSUZjG+9vydAsFO4lFHBpJUtjBcoJOCJpKnSJNwCw813zrYJHpCJ7sgfbtOe0V5Ku7Pa1XMQ==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} @@ -4272,7 +5049,7 @@ packages: snapshots: - '@acemir/cssom@0.9.30': {} + '@acemir/cssom@0.9.31': {} '@adraffy/ens-normalize@1.11.1': {} @@ -4282,54 +5059,32 @@ snapshots: '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 - lru-cache: 11.2.4 + lru-cache: 11.2.5 - '@asamuzakjp/dom-selector@6.7.6': + '@asamuzakjp/dom-selector@6.7.7': dependencies: '@asamuzakjp/nwsapi': 2.3.9 bidi-js: 1.0.3 css-tree: 3.1.0 is-potential-custom-element-name: 1.0.1 - lru-cache: 11.2.4 + lru-cache: 11.2.5 '@asamuzakjp/nwsapi@2.3.9': {} - '@babel/code-frame@7.27.1': + '@babel/code-frame@7.28.6': dependencies: '@babel/helper-validator-identifier': 7.28.5 js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/code-frame@7.28.6': + '@babel/code-frame@7.29.0': dependencies: '@babel/helper-validator-identifier': 7.28.5 js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/compat-data@7.28.5': {} - '@babel/compat-data@7.28.6': {} - '@babel/core@7.28.5': - dependencies: - '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.5 - '@babel/helper-compilation-targets': 7.27.2 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) - '@babel/helpers': 7.28.4 - '@babel/parser': 7.28.5 - '@babel/template': 7.27.2 - '@babel/traverse': 7.28.5 - '@babel/types': 7.28.5 - '@jridgewell/remapping': 2.3.5 - convert-source-map: 2.0.0 - debug: 4.4.3 - gensync: 1.0.0-beta.2 - json5: 2.2.3 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - '@babel/core@7.28.6': dependencies: '@babel/code-frame': 7.28.6 @@ -4350,13 +5105,25 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/generator@7.28.5': + '@babel/core@7.29.0': dependencies: - '@babel/parser': 7.28.5 - '@babel/types': 7.28.5 - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 - jsesc: 3.1.0 + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helpers': 7.28.6 + '@babel/parser': 7.29.0 + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color '@babel/generator@7.28.6': dependencies: @@ -4366,13 +5133,13 @@ snapshots: '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 - '@babel/helper-compilation-targets@7.27.2': + '@babel/generator@7.29.1': dependencies: - '@babel/compat-data': 7.28.5 - '@babel/helper-validator-option': 7.27.1 - browserslist: 4.28.1 - lru-cache: 5.1.1 - semver: 6.3.1 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 '@babel/helper-compilation-targets@7.28.6': dependencies: @@ -4384,13 +5151,6 @@ snapshots: '@babel/helper-globals@7.28.0': {} - '@babel/helper-module-imports@7.27.1': - dependencies: - '@babel/traverse': 7.28.5 - '@babel/types': 7.28.5 - transitivePeerDependencies: - - supports-color - '@babel/helper-module-imports@7.28.6': dependencies: '@babel/traverse': 7.28.6 @@ -4398,26 +5158,24 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.5)': + '@babel/helper-module-transforms@7.28.6(@babel/core@7.28.6)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-module-imports': 7.27.1 + '@babel/core': 7.28.6 + '@babel/helper-module-imports': 7.28.6 '@babel/helper-validator-identifier': 7.28.5 - '@babel/traverse': 7.28.5 + '@babel/traverse': 7.28.6 transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.28.6(@babel/core@7.28.6)': + '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-module-imports': 7.28.6 '@babel/helper-validator-identifier': 7.28.5 '@babel/traverse': 7.28.6 transitivePeerDependencies: - supports-color - '@babel/helper-plugin-utils@7.27.1': {} - '@babel/helper-plugin-utils@7.28.6': {} '@babel/helper-string-parser@7.27.1': {} @@ -4426,24 +5184,19 @@ snapshots: '@babel/helper-validator-option@7.27.1': {} - '@babel/helpers@7.28.4': - dependencies: - '@babel/template': 7.27.2 - '@babel/types': 7.28.5 - '@babel/helpers@7.28.6': dependencies: '@babel/template': 7.28.6 '@babel/types': 7.28.6 - '@babel/parser@7.28.5': - dependencies: - '@babel/types': 7.28.5 - '@babel/parser@7.28.6': dependencies: '@babel/types': 7.28.6 + '@babel/parser@7.29.0': + dependencies: + '@babel/types': 7.29.0 + '@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -4454,77 +5207,94 @@ snapshots: '@babel/core': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/runtime@7.28.4': {} + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 '@babel/runtime@7.28.6': {} - '@babel/template@7.27.2': - dependencies: - '@babel/code-frame': 7.27.1 - '@babel/parser': 7.28.5 - '@babel/types': 7.28.5 - '@babel/template@7.28.6': dependencies: '@babel/code-frame': 7.28.6 '@babel/parser': 7.28.6 '@babel/types': 7.28.6 - '@babel/traverse@7.28.5': + '@babel/traverse@7.28.6': dependencies: - '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.5 + '@babel/code-frame': 7.28.6 + '@babel/generator': 7.28.6 '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.28.5 - '@babel/template': 7.27.2 - '@babel/types': 7.28.5 + '@babel/parser': 7.28.6 + '@babel/template': 7.28.6 + '@babel/types': 7.28.6 debug: 4.4.3 transitivePeerDependencies: - supports-color - '@babel/traverse@7.28.6': + '@babel/traverse@7.29.0': dependencies: - '@babel/code-frame': 7.28.6 - '@babel/generator': 7.28.6 + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.28.6 + '@babel/parser': 7.29.0 '@babel/template': 7.28.6 - '@babel/types': 7.28.6 + '@babel/types': 7.29.0 debug: 4.4.3 transitivePeerDependencies: - supports-color - '@babel/types@7.28.5': + '@babel/types@7.28.6': dependencies: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 - '@babel/types@7.28.6': + '@babel/types@7.29.0': dependencies: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 - '@base-org/account@2.4.0(@types/react@19.2.9)(bufferutil@4.1.0)(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(utf-8-validate@5.0.10)(zod@3.25.76)': + '@base-org/account@2.4.0(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.4))(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@coinbase/cdp-sdk': 1.44.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) + '@noble/hashes': 1.4.0 + clsx: 1.2.1 + eventemitter3: 5.0.1 + idb-keyval: 6.2.1 + ox: 0.6.9(typescript@5.9.3)(zod@3.25.76) + preact: 10.24.2 + viem: 2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + zustand: 5.0.3(@types/react@19.2.11)(react@19.2.4)(use-sync-external-store@1.4.0(react@19.2.4)) + transitivePeerDependencies: + - '@types/react' + - bufferutil + - debug + - encoding + - fastestsmallesttextencoderdecoder + - immer + - react + - typescript + - use-sync-external-store + - utf-8-validate + - zod + optional: true + + '@base-org/account@2.4.0(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.2.4))(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: - '@coinbase/cdp-sdk': 1.43.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) + '@coinbase/cdp-sdk': 1.44.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) '@noble/hashes': 1.4.0 clsx: 1.2.1 eventemitter3: 5.0.1 idb-keyval: 6.2.1 ox: 0.6.9(typescript@5.9.3)(zod@3.25.76) preact: 10.24.2 - viem: 2.45.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) - zustand: 5.0.3(@types/react@19.2.9)(react@19.2.3)(use-sync-external-store@1.4.0(react@19.2.3)) + viem: 2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + zustand: 5.0.3(@types/react@19.2.11)(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4)) transitivePeerDependencies: - '@types/react' - bufferutil @@ -4539,81 +5309,81 @@ snapshots: - zod optional: true - '@base-ui/react@1.1.0(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@base-ui/react@1.1.0(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@babel/runtime': 7.28.6 - '@base-ui/utils': 0.2.4(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@floating-ui/react-dom': 2.1.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@base-ui/utils': 0.2.4(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@floating-ui/react-dom': 2.1.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@floating-ui/utils': 0.2.10 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) reselect: 5.1.1 tabbable: 6.4.0 - use-sync-external-store: 1.6.0(react@19.2.3) + use-sync-external-store: 1.6.0(react@19.2.4) optionalDependencies: - '@types/react': 19.2.9 + '@types/react': 19.2.11 - '@base-ui/utils@0.2.4(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@base-ui/utils@0.2.4(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@babel/runtime': 7.28.6 '@floating-ui/utils': 0.2.10 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) reselect: 5.1.1 - use-sync-external-store: 1.6.0(react@19.2.3) + use-sync-external-store: 1.6.0(react@19.2.4) optionalDependencies: - '@types/react': 19.2.9 + '@types/react': 19.2.11 - '@biomejs/biome@2.3.12': + '@biomejs/biome@2.3.14': optionalDependencies: - '@biomejs/cli-darwin-arm64': 2.3.12 - '@biomejs/cli-darwin-x64': 2.3.12 - '@biomejs/cli-linux-arm64': 2.3.12 - '@biomejs/cli-linux-arm64-musl': 2.3.12 - '@biomejs/cli-linux-x64': 2.3.12 - '@biomejs/cli-linux-x64-musl': 2.3.12 - '@biomejs/cli-win32-arm64': 2.3.12 - '@biomejs/cli-win32-x64': 2.3.12 + '@biomejs/cli-darwin-arm64': 2.3.14 + '@biomejs/cli-darwin-x64': 2.3.14 + '@biomejs/cli-linux-arm64': 2.3.14 + '@biomejs/cli-linux-arm64-musl': 2.3.14 + '@biomejs/cli-linux-x64': 2.3.14 + '@biomejs/cli-linux-x64-musl': 2.3.14 + '@biomejs/cli-win32-arm64': 2.3.14 + '@biomejs/cli-win32-x64': 2.3.14 - '@biomejs/cli-darwin-arm64@2.3.12': + '@biomejs/cli-darwin-arm64@2.3.14': optional: true - '@biomejs/cli-darwin-x64@2.3.12': + '@biomejs/cli-darwin-x64@2.3.14': optional: true - '@biomejs/cli-linux-arm64-musl@2.3.12': + '@biomejs/cli-linux-arm64-musl@2.3.14': optional: true - '@biomejs/cli-linux-arm64@2.3.12': + '@biomejs/cli-linux-arm64@2.3.14': optional: true - '@biomejs/cli-linux-x64-musl@2.3.12': + '@biomejs/cli-linux-x64-musl@2.3.14': optional: true - '@biomejs/cli-linux-x64@2.3.12': + '@biomejs/cli-linux-x64@2.3.14': optional: true - '@biomejs/cli-win32-arm64@2.3.12': + '@biomejs/cli-win32-arm64@2.3.14': optional: true - '@biomejs/cli-win32-x64@2.3.12': + '@biomejs/cli-win32-x64@2.3.14': optional: true '@canvas/image-data@1.1.0': {} - '@coinbase/cdp-sdk@1.43.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)': + '@coinbase/cdp-sdk@1.44.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)': dependencies: - '@solana-program/system': 0.10.0(@solana/kit@5.4.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)) - '@solana-program/token': 0.9.0(@solana/kit@5.4.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)) - '@solana/kit': 5.4.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) + '@solana-program/system': 0.10.0(@solana/kit@5.5.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)) + '@solana-program/token': 0.9.0(@solana/kit@5.5.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)) + '@solana/kit': 5.5.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) '@solana/web3.js': 1.98.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) abitype: 1.0.6(typescript@5.9.3)(zod@3.25.76) - axios: 1.13.3 - axios-retry: 4.5.0(axios@1.13.3) + axios: 1.13.4 + axios-retry: 4.5.0(axios@1.13.4) jose: 6.1.3 md5: 2.3.0 uncrypto: 0.1.3 - viem: 2.45.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) zod: 3.25.76 transitivePeerDependencies: - bufferutil @@ -4624,6 +5394,115 @@ snapshots: - utf-8-validate optional: true + '@commitlint/cli@20.4.1(@types/node@25.2.0)(typescript@5.9.3)': + dependencies: + '@commitlint/format': 20.4.0 + '@commitlint/lint': 20.4.1 + '@commitlint/load': 20.4.0(@types/node@25.2.0)(typescript@5.9.3) + '@commitlint/read': 20.4.0 + '@commitlint/types': 20.4.0 + tinyexec: 1.0.2 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - typescript + + '@commitlint/config-conventional@20.4.1': + dependencies: + '@commitlint/types': 20.4.0 + conventional-changelog-conventionalcommits: 9.1.0 + + '@commitlint/config-validator@20.4.0': + dependencies: + '@commitlint/types': 20.4.0 + ajv: 8.17.1 + + '@commitlint/ensure@20.4.1': + dependencies: + '@commitlint/types': 20.4.0 + lodash.camelcase: 4.3.0 + lodash.kebabcase: 4.1.1 + lodash.snakecase: 4.1.1 + lodash.startcase: 4.4.0 + lodash.upperfirst: 4.3.1 + + '@commitlint/execute-rule@20.0.0': {} + + '@commitlint/format@20.4.0': + dependencies: + '@commitlint/types': 20.4.0 + picocolors: 1.1.1 + + '@commitlint/is-ignored@20.4.1': + dependencies: + '@commitlint/types': 20.4.0 + semver: 7.7.3 + + '@commitlint/lint@20.4.1': + dependencies: + '@commitlint/is-ignored': 20.4.1 + '@commitlint/parse': 20.4.1 + '@commitlint/rules': 20.4.1 + '@commitlint/types': 20.4.0 + + '@commitlint/load@20.4.0(@types/node@25.2.0)(typescript@5.9.3)': + dependencies: + '@commitlint/config-validator': 20.4.0 + '@commitlint/execute-rule': 20.0.0 + '@commitlint/resolve-extends': 20.4.0 + '@commitlint/types': 20.4.0 + cosmiconfig: 9.0.0(typescript@5.9.3) + cosmiconfig-typescript-loader: 6.2.0(@types/node@25.2.0)(cosmiconfig@9.0.0(typescript@5.9.3))(typescript@5.9.3) + is-plain-obj: 4.1.0 + lodash.mergewith: 4.6.2 + picocolors: 1.1.1 + transitivePeerDependencies: + - '@types/node' + - typescript + + '@commitlint/message@20.4.0': {} + + '@commitlint/parse@20.4.1': + dependencies: + '@commitlint/types': 20.4.0 + conventional-changelog-angular: 8.1.0 + conventional-commits-parser: 6.2.1 + + '@commitlint/read@20.4.0': + dependencies: + '@commitlint/top-level': 20.4.0 + '@commitlint/types': 20.4.0 + git-raw-commits: 4.0.0 + minimist: 1.2.8 + tinyexec: 1.0.2 + + '@commitlint/resolve-extends@20.4.0': + dependencies: + '@commitlint/config-validator': 20.4.0 + '@commitlint/types': 20.4.0 + global-directory: 4.0.1 + import-meta-resolve: 4.2.0 + lodash.mergewith: 4.6.2 + resolve-from: 5.0.0 + + '@commitlint/rules@20.4.1': + dependencies: + '@commitlint/ensure': 20.4.1 + '@commitlint/message': 20.4.0 + '@commitlint/to-lines': 20.0.0 + '@commitlint/types': 20.4.0 + + '@commitlint/to-lines@20.0.0': {} + + '@commitlint/top-level@20.4.0': + dependencies: + escalade: 3.2.0 + + '@commitlint/types@20.4.0': + dependencies: + conventional-commits-parser: 6.2.1 + picocolors: 1.1.1 + '@csstools/color-helpers@5.1.0': {} '@csstools/css-calc@2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': @@ -4642,100 +5521,100 @@ snapshots: dependencies: '@csstools/css-tokenizer': 3.0.4 - '@csstools/css-syntax-patches-for-csstree@1.0.22': {} + '@csstools/css-syntax-patches-for-csstree@1.0.26': {} '@csstools/css-tokenizer@3.0.4': {} - '@effect-atom/atom-react@0.4.6(@effect/experimental@0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(@effect/rpc@0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(effect@3.19.15)(react@19.2.3)(scheduler@0.27.0)': + '@effect-atom/atom-react@0.5.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(effect@3.19.16)(react@19.2.4)(scheduler@0.27.0)': dependencies: - '@effect-atom/atom': 0.4.13(@effect/experimental@0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(@effect/rpc@0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(effect@3.19.15) - effect: 3.19.15 - react: 19.2.3 + '@effect-atom/atom': 0.5.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(effect@3.19.16) + effect: 3.19.16 + react: 19.2.4 scheduler: 0.27.0 transitivePeerDependencies: - '@effect/experimental' - '@effect/platform' - '@effect/rpc' - '@effect-atom/atom@0.4.13(@effect/experimental@0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(@effect/rpc@0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(effect@3.19.15)': + '@effect-atom/atom@0.5.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(effect@3.19.16)': dependencies: - '@effect/experimental': 0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15) - '@effect/platform': 0.94.2(effect@3.19.15) - '@effect/rpc': 0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15) - effect: 3.19.15 + '@effect/experimental': 0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16) + '@effect/platform': 0.94.3(effect@3.19.16) + '@effect/rpc': 0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16) + effect: 3.19.16 - '@effect/cluster@0.56.1(@effect/platform@0.94.2(effect@3.19.15))(@effect/rpc@0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/sql@0.49.0(@effect/experimental@0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/workflow@0.16.0(@effect/experimental@0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(@effect/rpc@0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(effect@3.19.15))(effect@3.19.15)': + '@effect/cluster@0.56.1(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/sql@0.49.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/workflow@0.16.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(effect@3.19.16))(effect@3.19.16)': dependencies: - '@effect/platform': 0.94.2(effect@3.19.15) - '@effect/rpc': 0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15) - '@effect/sql': 0.49.0(@effect/experimental@0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15) - '@effect/workflow': 0.16.0(@effect/experimental@0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(@effect/rpc@0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(effect@3.19.15) - effect: 3.19.15 + '@effect/platform': 0.94.3(effect@3.19.16) + '@effect/rpc': 0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16) + '@effect/sql': 0.49.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16) + '@effect/workflow': 0.16.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(effect@3.19.16) + effect: 3.19.16 kubernetes-types: 1.30.0 - '@effect/experimental@0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15)': + '@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16)': dependencies: - '@effect/platform': 0.94.2(effect@3.19.15) - effect: 3.19.15 + '@effect/platform': 0.94.3(effect@3.19.16) + effect: 3.19.16 uuid: 11.1.0 - '@effect/language-service@0.72.0': {} + '@effect/language-service@0.73.0': {} - '@effect/platform-node-shared@0.57.1(@effect/cluster@0.56.1(@effect/platform@0.94.2(effect@3.19.15))(@effect/rpc@0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/sql@0.49.0(@effect/experimental@0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/workflow@0.16.0(@effect/experimental@0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(@effect/rpc@0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(@effect/rpc@0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/sql@0.49.0(@effect/experimental@0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(bufferutil@4.1.0)(effect@3.19.15)(utf-8-validate@5.0.10)': + '@effect/platform-node-shared@0.57.1(@effect/cluster@0.56.1(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/sql@0.49.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/workflow@0.16.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/sql@0.49.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(bufferutil@4.1.0)(effect@3.19.16)(utf-8-validate@5.0.10)': dependencies: - '@effect/cluster': 0.56.1(@effect/platform@0.94.2(effect@3.19.15))(@effect/rpc@0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/sql@0.49.0(@effect/experimental@0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/workflow@0.16.0(@effect/experimental@0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(@effect/rpc@0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(effect@3.19.15))(effect@3.19.15) - '@effect/platform': 0.94.2(effect@3.19.15) - '@effect/rpc': 0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15) - '@effect/sql': 0.49.0(@effect/experimental@0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15) + '@effect/cluster': 0.56.1(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/sql@0.49.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/workflow@0.16.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(effect@3.19.16))(effect@3.19.16) + '@effect/platform': 0.94.3(effect@3.19.16) + '@effect/rpc': 0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16) + '@effect/sql': 0.49.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16) '@parcel/watcher': 2.5.6 - effect: 3.19.15 + effect: 3.19.16 multipasta: 0.2.7 ws: 8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) transitivePeerDependencies: - bufferutil - utf-8-validate - '@effect/platform-node@0.104.1(@effect/cluster@0.56.1(@effect/platform@0.94.2(effect@3.19.15))(@effect/rpc@0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/sql@0.49.0(@effect/experimental@0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/workflow@0.16.0(@effect/experimental@0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(@effect/rpc@0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(@effect/rpc@0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/sql@0.49.0(@effect/experimental@0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(bufferutil@4.1.0)(effect@3.19.15)(utf-8-validate@5.0.10)': + '@effect/platform-node@0.104.1(@effect/cluster@0.56.1(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/sql@0.49.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/workflow@0.16.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/sql@0.49.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(bufferutil@4.1.0)(effect@3.19.16)(utf-8-validate@5.0.10)': dependencies: - '@effect/cluster': 0.56.1(@effect/platform@0.94.2(effect@3.19.15))(@effect/rpc@0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/sql@0.49.0(@effect/experimental@0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/workflow@0.16.0(@effect/experimental@0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(@effect/rpc@0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(effect@3.19.15))(effect@3.19.15) - '@effect/platform': 0.94.2(effect@3.19.15) - '@effect/platform-node-shared': 0.57.1(@effect/cluster@0.56.1(@effect/platform@0.94.2(effect@3.19.15))(@effect/rpc@0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/sql@0.49.0(@effect/experimental@0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/workflow@0.16.0(@effect/experimental@0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(@effect/rpc@0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(@effect/rpc@0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/sql@0.49.0(@effect/experimental@0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(bufferutil@4.1.0)(effect@3.19.15)(utf-8-validate@5.0.10) - '@effect/rpc': 0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15) - '@effect/sql': 0.49.0(@effect/experimental@0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15) - effect: 3.19.15 + '@effect/cluster': 0.56.1(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/sql@0.49.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/workflow@0.16.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(effect@3.19.16))(effect@3.19.16) + '@effect/platform': 0.94.3(effect@3.19.16) + '@effect/platform-node-shared': 0.57.1(@effect/cluster@0.56.1(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/sql@0.49.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/workflow@0.16.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/sql@0.49.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(bufferutil@4.1.0)(effect@3.19.16)(utf-8-validate@5.0.10) + '@effect/rpc': 0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16) + '@effect/sql': 0.49.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16) + effect: 3.19.16 mime: 3.0.0 - undici: 7.19.1 + undici: 7.19.2 ws: 8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) transitivePeerDependencies: - bufferutil - utf-8-validate - '@effect/platform@0.94.2(effect@3.19.15)': + '@effect/platform@0.94.3(effect@3.19.16)': dependencies: - effect: 3.19.15 + effect: 3.19.16 find-my-way-ts: 0.1.6 msgpackr: 1.11.8 multipasta: 0.2.7 - '@effect/rpc@0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15)': + '@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16)': dependencies: - '@effect/platform': 0.94.2(effect@3.19.15) - effect: 3.19.15 + '@effect/platform': 0.94.3(effect@3.19.16) + effect: 3.19.16 msgpackr: 1.11.8 - '@effect/sql@0.49.0(@effect/experimental@0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15)': + '@effect/sql@0.49.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16)': dependencies: - '@effect/experimental': 0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15) - '@effect/platform': 0.94.2(effect@3.19.15) - effect: 3.19.15 + '@effect/experimental': 0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16) + '@effect/platform': 0.94.3(effect@3.19.16) + effect: 3.19.16 uuid: 11.1.0 - '@effect/workflow@0.16.0(@effect/experimental@0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(@effect/rpc@0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(effect@3.19.15)': + '@effect/workflow@0.16.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(effect@3.19.16)': dependencies: - '@effect/experimental': 0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15) - '@effect/platform': 0.94.2(effect@3.19.15) - '@effect/rpc': 0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15) - effect: 3.19.15 + '@effect/experimental': 0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16) + '@effect/platform': 0.94.3(effect@3.19.16) + '@effect/rpc': 0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16) + effect: 3.19.16 '@emnapi/runtime@1.8.1': dependencies: @@ -4820,22 +5699,24 @@ snapshots: '@esbuild/win32-x64@0.27.2': optional: true - '@exodus/bytes@1.8.0': {} + '@exodus/bytes@1.11.0(@noble/hashes@1.8.0)': + optionalDependencies: + '@noble/hashes': 1.8.0 - '@floating-ui/core@1.7.3': + '@floating-ui/core@1.7.4': dependencies: '@floating-ui/utils': 0.2.10 - '@floating-ui/dom@1.7.4': + '@floating-ui/dom@1.7.5': dependencies: - '@floating-ui/core': 1.7.3 + '@floating-ui/core': 1.7.4 '@floating-ui/utils': 0.2.10 - '@floating-ui/react-dom@2.1.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@floating-ui/react-dom@2.1.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@floating-ui/dom': 1.7.4 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + '@floating-ui/dom': 1.7.5 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) '@floating-ui/utils@0.2.10': {} @@ -4974,27 +5855,27 @@ snapshots: '@lit-labs/ssr-dom-shim@1.5.1': {} - '@lit/react@1.0.8(@types/react@19.2.9)': + '@lit/react@1.0.8(@types/react@19.2.11)': dependencies: - '@types/react': 19.2.9 + '@types/react': 19.2.11 optional: true '@lit/reactive-element@2.1.2': dependencies: '@lit-labs/ssr-dom-shim': 1.5.1 - '@lucas-barake/effect-form-react@0.14.0(@effect-atom/atom-react@0.4.6(@effect/experimental@0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(@effect/rpc@0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(effect@3.19.15)(react@19.2.3)(scheduler@0.27.0))(@effect-atom/atom@0.4.13(@effect/experimental@0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(@effect/rpc@0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(effect@3.19.15))(effect@3.19.15)(react@19.2.3)': + '@lucas-barake/effect-form-react@0.18.0(@effect-atom/atom-react@0.5.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(effect@3.19.16)(react@19.2.4)(scheduler@0.27.0))(@effect-atom/atom@0.5.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(effect@3.19.16))(effect@3.19.16)(react@19.2.4)': dependencies: - '@effect-atom/atom': 0.4.13(@effect/experimental@0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(@effect/rpc@0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(effect@3.19.15) - '@effect-atom/atom-react': 0.4.6(@effect/experimental@0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(@effect/rpc@0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(effect@3.19.15)(react@19.2.3)(scheduler@0.27.0) - '@lucas-barake/effect-form': 0.14.0(@effect-atom/atom@0.4.13(@effect/experimental@0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(@effect/rpc@0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(effect@3.19.15))(effect@3.19.15) - effect: 3.19.15 - react: 19.2.3 + '@effect-atom/atom': 0.5.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(effect@3.19.16) + '@effect-atom/atom-react': 0.5.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(effect@3.19.16)(react@19.2.4)(scheduler@0.27.0) + '@lucas-barake/effect-form': 0.18.0(@effect-atom/atom@0.5.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(effect@3.19.16))(effect@3.19.16) + effect: 3.19.16 + react: 19.2.4 - '@lucas-barake/effect-form@0.14.0(@effect-atom/atom@0.4.13(@effect/experimental@0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(@effect/rpc@0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(effect@3.19.15))(effect@3.19.15)': + '@lucas-barake/effect-form@0.18.0(@effect-atom/atom@0.5.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(effect@3.19.16))(effect@3.19.16)': dependencies: - '@effect-atom/atom': 0.4.13(@effect/experimental@0.58.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(@effect/platform@0.94.2(effect@3.19.15))(@effect/rpc@0.73.0(@effect/platform@0.94.2(effect@3.19.15))(effect@3.19.15))(effect@3.19.15) - effect: 3.19.15 + '@effect-atom/atom': 0.5.0(@effect/experimental@0.58.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(@effect/platform@0.94.3(effect@3.19.16))(@effect/rpc@0.73.0(@effect/platform@0.94.3(effect@3.19.16))(effect@3.19.16))(effect@3.19.16) + effect: 3.19.16 '@msgpack/msgpack@3.1.2': {} @@ -5111,22 +5992,78 @@ snapshots: dependencies: quansync: 1.0.0 - '@reown/appkit-adapter-wagmi@1.8.17(ddefe6db690784ffc0b4049c81f77f80)': + '@reown/appkit-adapter-wagmi@1.8.17(0a70dc20fe0c1a07d4cc186a53526855)': + dependencies: + '@reown/appkit': 1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.4))(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-common': 1.8.17(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-polyfills': 1.8.17 + '@reown/appkit-scaffold-ui': 1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.4))(utf-8-validate@5.0.10)(valtio@2.1.7(@types/react@19.2.11)(react@19.2.4))(zod@3.25.76) + '@reown/appkit-utils': 1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.4))(utf-8-validate@5.0.10)(valtio@2.1.7(@types/react@19.2.11)(react@19.2.4))(zod@3.25.76) + '@reown/appkit-wallet': 1.8.17(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) + '@wagmi/core': 3.3.2(@tanstack/query-core@5.90.20)(@types/react@19.2.11)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.4))(viem@2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@walletconnect/universal-provider': 2.23.2(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + valtio: 2.1.7(@types/react@19.2.11)(react@19.2.4) + viem: 2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + wagmi: 3.4.2(@safe-global/safe-apps-provider@0.18.6(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.20(react@19.2.4))(@types/react@19.2.11)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.2.4)(typescript@5.9.3)(viem@2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + optionalDependencies: + '@wagmi/connectors': 7.1.5(@safe-global/safe-apps-provider@0.18.6(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@wagmi/core@3.3.2(@tanstack/query-core@5.90.20)(@types/react@19.2.11)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.4))(viem@2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(typescript@5.9.3)(viem@2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@base-org/account' + - '@capacitor/preferences' + - '@coinbase/wallet-sdk' + - '@deno/kv' + - '@gemini-wallet/core' + - '@metamask/sdk' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@safe-global/safe-apps-provider' + - '@safe-global/safe-apps-sdk' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - '@walletconnect/ethereum-provider' + - aws4fetch + - bufferutil + - db0 + - debug + - encoding + - fastestsmallesttextencoderdecoder + - immer + - ioredis + - porto + - react + - typescript + - uploadthing + - use-sync-external-store + - utf-8-validate + - zod + + '@reown/appkit-adapter-wagmi@1.8.17(588bfcce98e97548479faa9aa8a7b8c9)': dependencies: - '@reown/appkit': 1.8.17(@types/react@19.2.9)(bufferutil@4.1.0)(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit': 1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.2.4))(utf-8-validate@5.0.10)(zod@3.25.76) '@reown/appkit-common': 1.8.17(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-controllers': 1.8.17(@types/react@19.2.9)(bufferutil@4.1.0)(react@19.2.3)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) '@reown/appkit-polyfills': 1.8.17 - '@reown/appkit-scaffold-ui': 1.8.17(@types/react@19.2.9)(bufferutil@4.1.0)(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(utf-8-validate@5.0.10)(valtio@2.1.7(@types/react@19.2.9)(react@19.2.3))(zod@3.25.76) - '@reown/appkit-utils': 1.8.17(@types/react@19.2.9)(bufferutil@4.1.0)(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(utf-8-validate@5.0.10)(valtio@2.1.7(@types/react@19.2.9)(react@19.2.3))(zod@3.25.76) + '@reown/appkit-scaffold-ui': 1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.2.4))(utf-8-validate@5.0.10)(valtio@2.1.7(@types/react@19.2.11)(react@19.2.4))(zod@3.25.76) + '@reown/appkit-utils': 1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.2.4))(utf-8-validate@5.0.10)(valtio@2.1.7(@types/react@19.2.11)(react@19.2.4))(zod@3.25.76) '@reown/appkit-wallet': 1.8.17(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) - '@wagmi/core': 3.3.1(@tanstack/query-core@5.90.20)(@types/react@19.2.9)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(viem@2.45.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@wagmi/core': 3.3.2(@tanstack/query-core@5.90.20)(@types/react@19.2.11)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.2.4))(viem@2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) '@walletconnect/universal-provider': 2.23.2(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) - valtio: 2.1.7(@types/react@19.2.9)(react@19.2.3) - viem: 2.45.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) - wagmi: 3.4.1(@safe-global/safe-apps-provider@0.18.6(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.20(react@19.2.3))(@types/react@19.2.9)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.2.3)(typescript@5.9.3)(viem@2.45.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + valtio: 2.1.7(@types/react@19.2.11)(react@19.2.4) + viem: 2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + wagmi: 3.4.2(@safe-global/safe-apps-provider@0.18.6(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.20(react@19.2.4))(@types/react@19.2.11)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.2.4)(typescript@5.9.3)(viem@2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) optionalDependencies: - '@wagmi/connectors': 7.1.5(@safe-global/safe-apps-provider@0.18.6(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@wagmi/core@3.3.1(@tanstack/query-core@5.90.20)(@types/react@19.2.9)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(viem@2.45.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(typescript@5.9.3)(viem@2.45.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@wagmi/connectors': 7.1.5(@safe-global/safe-apps-provider@0.18.6(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@wagmi/core@3.3.2(@tanstack/query-core@5.90.20)(@types/react@19.2.11)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.2.4))(viem@2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(typescript@5.9.3)(viem@2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -5143,14 +6080,152 @@ snapshots: - '@netlify/blobs' - '@planetscale/database' - '@react-native-async-storage/async-storage' - - '@safe-global/safe-apps-provider' - - '@safe-global/safe-apps-sdk' + - '@safe-global/safe-apps-provider' + - '@safe-global/safe-apps-sdk' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - '@walletconnect/ethereum-provider' + - aws4fetch + - bufferutil + - db0 + - debug + - encoding + - fastestsmallesttextencoderdecoder + - immer + - ioredis + - porto + - react + - typescript + - uploadthing + - use-sync-external-store + - utf-8-validate + - zod + + '@reown/appkit-common@1.8.17(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + dependencies: + big.js: 6.2.2 + dayjs: 1.11.13 + viem: 2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.22.4) + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + + '@reown/appkit-common@1.8.17(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + big.js: 6.2.2 + dayjs: 1.11.13 + viem: 2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + + '@reown/appkit-controllers@1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@reown/appkit-common': 1.8.17(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-wallet': 1.8.17(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) + '@walletconnect/universal-provider': 2.23.2(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + valtio: 2.1.7(@types/react@19.2.11)(react@19.2.4) + viem: 2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - react + - typescript + - uploadthing + - utf-8-validate + - zod + + '@reown/appkit-pay@1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.4))(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@reown/appkit-common': 1.8.17(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-ui': 1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-utils': 1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.4))(utf-8-validate@5.0.10)(valtio@2.1.7(@types/react@19.2.11)(react@19.2.4))(zod@3.25.76) + lit: 3.3.0 + valtio: 2.1.7(@types/react@19.2.11)(react@19.2.4) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - debug + - encoding + - fastestsmallesttextencoderdecoder + - immer + - ioredis + - react + - typescript + - uploadthing + - use-sync-external-store + - utf-8-validate + - zod + + '@reown/appkit-pay@1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.2.4))(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@reown/appkit-common': 1.8.17(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-ui': 1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-utils': 1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.2.4))(utf-8-validate@5.0.10)(valtio@2.1.7(@types/react@19.2.11)(react@19.2.4))(zod@3.25.76) + lit: 3.3.0 + valtio: 2.1.7(@types/react@19.2.11)(react@19.2.4) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' - '@types/react' - '@upstash/redis' - '@vercel/blob' - '@vercel/functions' - '@vercel/kv' - - '@walletconnect/ethereum-provider' - aws4fetch - bufferutil - db0 @@ -5159,7 +6234,6 @@ snapshots: - fastestsmallesttextencoderdecoder - immer - ioredis - - porto - react - typescript - uploadthing @@ -5167,35 +6241,19 @@ snapshots: - utf-8-validate - zod - '@reown/appkit-common@1.8.17(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.22.4)': - dependencies: - big.js: 6.2.2 - dayjs: 1.11.13 - viem: 2.45.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.22.4) - transitivePeerDependencies: - - bufferutil - - typescript - - utf-8-validate - - zod - - '@reown/appkit-common@1.8.17(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@reown/appkit-polyfills@1.8.17': dependencies: - big.js: 6.2.2 - dayjs: 1.11.13 - viem: 2.45.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) - transitivePeerDependencies: - - bufferutil - - typescript - - utf-8-validate - - zod + buffer: 6.0.3 - '@reown/appkit-controllers@1.8.17(@types/react@19.2.9)(bufferutil@4.1.0)(react@19.2.3)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@reown/appkit-scaffold-ui@1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.4))(utf-8-validate@5.0.10)(valtio@2.1.7(@types/react@19.2.11)(react@19.2.4))(zod@3.25.76)': dependencies: '@reown/appkit-common': 1.8.17(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-pay': 1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.4))(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-ui': 1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-utils': 1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.4))(utf-8-validate@5.0.10)(valtio@2.1.7(@types/react@19.2.11)(react@19.2.4))(zod@3.25.76) '@reown/appkit-wallet': 1.8.17(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) - '@walletconnect/universal-provider': 2.23.2(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) - valtio: 2.1.7(@types/react@19.2.9)(react@19.2.3) - viem: 2.45.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + lit: 3.3.0 transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -5216,22 +6274,28 @@ snapshots: - aws4fetch - bufferutil - db0 + - debug - encoding + - fastestsmallesttextencoderdecoder + - immer - ioredis - react - typescript - uploadthing + - use-sync-external-store - utf-8-validate + - valtio - zod - '@reown/appkit-pay@1.8.17(@types/react@19.2.9)(bufferutil@4.1.0)(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(utf-8-validate@5.0.10)(zod@3.25.76)': + '@reown/appkit-scaffold-ui@1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.2.4))(utf-8-validate@5.0.10)(valtio@2.1.7(@types/react@19.2.11)(react@19.2.4))(zod@3.25.76)': dependencies: '@reown/appkit-common': 1.8.17(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-controllers': 1.8.17(@types/react@19.2.9)(bufferutil@4.1.0)(react@19.2.3)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-ui': 1.8.17(@types/react@19.2.9)(bufferutil@4.1.0)(react@19.2.3)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-utils': 1.8.17(@types/react@19.2.9)(bufferutil@4.1.0)(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(utf-8-validate@5.0.10)(valtio@2.1.7(@types/react@19.2.9)(react@19.2.3))(zod@3.25.76) + '@reown/appkit-controllers': 1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-pay': 1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.2.4))(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-ui': 1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-utils': 1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.2.4))(utf-8-validate@5.0.10)(valtio@2.1.7(@types/react@19.2.11)(react@19.2.4))(zod@3.25.76) + '@reown/appkit-wallet': 1.8.17(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) lit: 3.3.0 - valtio: 2.1.7(@types/react@19.2.9)(react@19.2.3) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -5262,21 +6326,17 @@ snapshots: - uploadthing - use-sync-external-store - utf-8-validate + - valtio - zod - '@reown/appkit-polyfills@1.8.17': - dependencies: - buffer: 6.0.3 - - '@reown/appkit-scaffold-ui@1.8.17(@types/react@19.2.9)(bufferutil@4.1.0)(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(utf-8-validate@5.0.10)(valtio@2.1.7(@types/react@19.2.9)(react@19.2.3))(zod@3.25.76)': + '@reown/appkit-ui@1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: + '@phosphor-icons/webcomponents': 2.1.5 '@reown/appkit-common': 1.8.17(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-controllers': 1.8.17(@types/react@19.2.9)(bufferutil@4.1.0)(react@19.2.3)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-pay': 1.8.17(@types/react@19.2.9)(bufferutil@4.1.0)(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-ui': 1.8.17(@types/react@19.2.9)(bufferutil@4.1.0)(react@19.2.3)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-utils': 1.8.17(@types/react@19.2.9)(bufferutil@4.1.0)(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(utf-8-validate@5.0.10)(valtio@2.1.7(@types/react@19.2.9)(react@19.2.3))(zod@3.25.76) + '@reown/appkit-controllers': 1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) '@reown/appkit-wallet': 1.8.17(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) lit: 3.3.0 + qrcode: 1.5.3 transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -5297,27 +6357,29 @@ snapshots: - aws4fetch - bufferutil - db0 - - debug - encoding - - fastestsmallesttextencoderdecoder - - immer - ioredis - react - typescript - uploadthing - - use-sync-external-store - utf-8-validate - - valtio - zod - '@reown/appkit-ui@1.8.17(@types/react@19.2.9)(bufferutil@4.1.0)(react@19.2.3)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@reown/appkit-utils@1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.4))(utf-8-validate@5.0.10)(valtio@2.1.7(@types/react@19.2.11)(react@19.2.4))(zod@3.25.76)': dependencies: - '@phosphor-icons/webcomponents': 2.1.5 '@reown/appkit-common': 1.8.17(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-controllers': 1.8.17(@types/react@19.2.9)(bufferutil@4.1.0)(react@19.2.3)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-polyfills': 1.8.17 '@reown/appkit-wallet': 1.8.17(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) - lit: 3.3.0 - qrcode: 1.5.3 + '@wallet-standard/wallet': 1.1.0 + '@walletconnect/logger': 3.0.2 + '@walletconnect/universal-provider': 2.23.2(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + valtio: 2.1.7(@types/react@19.2.11)(react@19.2.4) + viem: 2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + optionalDependencies: + '@base-org/account': 2.4.0(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.4))(utf-8-validate@5.0.10)(zod@3.25.76) + '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -5338,27 +6400,31 @@ snapshots: - aws4fetch - bufferutil - db0 + - debug - encoding + - fastestsmallesttextencoderdecoder + - immer - ioredis - react - typescript - uploadthing + - use-sync-external-store - utf-8-validate - zod - '@reown/appkit-utils@1.8.17(@types/react@19.2.9)(bufferutil@4.1.0)(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(utf-8-validate@5.0.10)(valtio@2.1.7(@types/react@19.2.9)(react@19.2.3))(zod@3.25.76)': + '@reown/appkit-utils@1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.2.4))(utf-8-validate@5.0.10)(valtio@2.1.7(@types/react@19.2.11)(react@19.2.4))(zod@3.25.76)': dependencies: '@reown/appkit-common': 1.8.17(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-controllers': 1.8.17(@types/react@19.2.9)(bufferutil@4.1.0)(react@19.2.3)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) '@reown/appkit-polyfills': 1.8.17 '@reown/appkit-wallet': 1.8.17(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) '@wallet-standard/wallet': 1.1.0 '@walletconnect/logger': 3.0.2 '@walletconnect/universal-provider': 2.23.2(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) - valtio: 2.1.7(@types/react@19.2.9)(react@19.2.3) - viem: 2.45.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + valtio: 2.1.7(@types/react@19.2.11)(react@19.2.4) + viem: 2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) optionalDependencies: - '@base-org/account': 2.4.0(@types/react@19.2.9)(bufferutil@4.1.0)(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(utf-8-validate@5.0.10)(zod@3.25.76) + '@base-org/account': 2.4.0(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.2.4))(utf-8-validate@5.0.10)(zod@3.25.76) '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: @@ -5404,23 +6470,72 @@ snapshots: - typescript - utf-8-validate - '@reown/appkit@1.8.17(@types/react@19.2.9)(bufferutil@4.1.0)(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(utf-8-validate@5.0.10)(zod@3.25.76)': + '@reown/appkit@1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.4))(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@reown/appkit-common': 1.8.17(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-pay': 1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.4))(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-polyfills': 1.8.17 + '@reown/appkit-scaffold-ui': 1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.4))(utf-8-validate@5.0.10)(valtio@2.1.7(@types/react@19.2.11)(react@19.2.4))(zod@3.25.76) + '@reown/appkit-ui': 1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-utils': 1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.4))(utf-8-validate@5.0.10)(valtio@2.1.7(@types/react@19.2.11)(react@19.2.4))(zod@3.25.76) + '@reown/appkit-wallet': 1.8.17(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) + '@walletconnect/universal-provider': 2.23.2(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + bs58: 6.0.0 + semver: 7.7.2 + valtio: 2.1.7(@types/react@19.2.11)(react@19.2.4) + viem: 2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + optionalDependencies: + '@lit/react': 1.0.8(@types/react@19.2.11) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - debug + - encoding + - fastestsmallesttextencoderdecoder + - immer + - ioredis + - react + - typescript + - uploadthing + - use-sync-external-store + - utf-8-validate + - zod + + '@reown/appkit@1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.2.4))(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@reown/appkit-common': 1.8.17(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-controllers': 1.8.17(@types/react@19.2.9)(bufferutil@4.1.0)(react@19.2.3)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-pay': 1.8.17(@types/react@19.2.9)(bufferutil@4.1.0)(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-pay': 1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.2.4))(utf-8-validate@5.0.10)(zod@3.25.76) '@reown/appkit-polyfills': 1.8.17 - '@reown/appkit-scaffold-ui': 1.8.17(@types/react@19.2.9)(bufferutil@4.1.0)(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(utf-8-validate@5.0.10)(valtio@2.1.7(@types/react@19.2.9)(react@19.2.3))(zod@3.25.76) - '@reown/appkit-ui': 1.8.17(@types/react@19.2.9)(bufferutil@4.1.0)(react@19.2.3)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-utils': 1.8.17(@types/react@19.2.9)(bufferutil@4.1.0)(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(utf-8-validate@5.0.10)(valtio@2.1.7(@types/react@19.2.9)(react@19.2.3))(zod@3.25.76) + '@reown/appkit-scaffold-ui': 1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.2.4))(utf-8-validate@5.0.10)(valtio@2.1.7(@types/react@19.2.11)(react@19.2.4))(zod@3.25.76) + '@reown/appkit-ui': 1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-utils': 1.8.17(@types/react@19.2.11)(bufferutil@4.1.0)(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.2.4))(utf-8-validate@5.0.10)(valtio@2.1.7(@types/react@19.2.11)(react@19.2.4))(zod@3.25.76) '@reown/appkit-wallet': 1.8.17(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) '@walletconnect/universal-provider': 2.23.2(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) bs58: 6.0.0 semver: 7.7.2 - valtio: 2.1.7(@types/react@19.2.9)(react@19.2.3) - viem: 2.45.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + valtio: 2.1.7(@types/react@19.2.11)(react@19.2.4) + viem: 2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) optionalDependencies: - '@lit/react': 1.0.8(@types/react@19.2.9) + '@lit/react': 1.0.8(@types/react@19.2.11) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -5453,97 +6568,97 @@ snapshots: - utf-8-validate - zod - '@rolldown/pluginutils@1.0.0-beta.53': {} + '@rolldown/pluginutils@1.0.0-rc.2': {} - '@rollup/plugin-inject@5.0.5(rollup@4.56.0)': + '@rollup/plugin-inject@5.0.5(rollup@4.57.1)': dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.56.0) + '@rollup/pluginutils': 5.3.0(rollup@4.57.1) estree-walker: 2.0.2 magic-string: 0.30.21 optionalDependencies: - rollup: 4.56.0 + rollup: 4.57.1 - '@rollup/pluginutils@5.3.0(rollup@4.56.0)': + '@rollup/pluginutils@5.3.0(rollup@4.57.1)': dependencies: '@types/estree': 1.0.8 estree-walker: 2.0.2 picomatch: 4.0.3 optionalDependencies: - rollup: 4.56.0 + rollup: 4.57.1 - '@rollup/rollup-android-arm-eabi@4.56.0': + '@rollup/rollup-android-arm-eabi@4.57.1': optional: true - '@rollup/rollup-android-arm64@4.56.0': + '@rollup/rollup-android-arm64@4.57.1': optional: true - '@rollup/rollup-darwin-arm64@4.56.0': + '@rollup/rollup-darwin-arm64@4.57.1': optional: true - '@rollup/rollup-darwin-x64@4.56.0': + '@rollup/rollup-darwin-x64@4.57.1': optional: true - '@rollup/rollup-freebsd-arm64@4.56.0': + '@rollup/rollup-freebsd-arm64@4.57.1': optional: true - '@rollup/rollup-freebsd-x64@4.56.0': + '@rollup/rollup-freebsd-x64@4.57.1': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.56.0': + '@rollup/rollup-linux-arm-gnueabihf@4.57.1': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.56.0': + '@rollup/rollup-linux-arm-musleabihf@4.57.1': optional: true - '@rollup/rollup-linux-arm64-gnu@4.56.0': + '@rollup/rollup-linux-arm64-gnu@4.57.1': optional: true - '@rollup/rollup-linux-arm64-musl@4.56.0': + '@rollup/rollup-linux-arm64-musl@4.57.1': optional: true - '@rollup/rollup-linux-loong64-gnu@4.56.0': + '@rollup/rollup-linux-loong64-gnu@4.57.1': optional: true - '@rollup/rollup-linux-loong64-musl@4.56.0': + '@rollup/rollup-linux-loong64-musl@4.57.1': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.56.0': + '@rollup/rollup-linux-ppc64-gnu@4.57.1': optional: true - '@rollup/rollup-linux-ppc64-musl@4.56.0': + '@rollup/rollup-linux-ppc64-musl@4.57.1': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.56.0': + '@rollup/rollup-linux-riscv64-gnu@4.57.1': optional: true - '@rollup/rollup-linux-riscv64-musl@4.56.0': + '@rollup/rollup-linux-riscv64-musl@4.57.1': optional: true - '@rollup/rollup-linux-s390x-gnu@4.56.0': + '@rollup/rollup-linux-s390x-gnu@4.57.1': optional: true - '@rollup/rollup-linux-x64-gnu@4.56.0': + '@rollup/rollup-linux-x64-gnu@4.57.1': optional: true - '@rollup/rollup-linux-x64-musl@4.56.0': + '@rollup/rollup-linux-x64-musl@4.57.1': optional: true - '@rollup/rollup-openbsd-x64@4.56.0': + '@rollup/rollup-openbsd-x64@4.57.1': optional: true - '@rollup/rollup-openharmony-arm64@4.56.0': + '@rollup/rollup-openharmony-arm64@4.57.1': optional: true - '@rollup/rollup-win32-arm64-msvc@4.56.0': + '@rollup/rollup-win32-arm64-msvc@4.57.1': optional: true - '@rollup/rollup-win32-ia32-msvc@4.56.0': + '@rollup/rollup-win32-ia32-msvc@4.57.1': optional: true - '@rollup/rollup-win32-x64-gnu@4.56.0': + '@rollup/rollup-win32-x64-gnu@4.57.1': optional: true - '@rollup/rollup-win32-x64-msvc@4.56.0': + '@rollup/rollup-win32-x64-msvc@4.57.1': optional: true '@safe-global/safe-apps-provider@0.18.6(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': @@ -5560,7 +6675,7 @@ snapshots: '@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@safe-global/safe-gateway-typescript-sdk': 3.23.1 - viem: 2.45.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - bufferutil - typescript @@ -5575,7 +6690,7 @@ snapshots: '@scure/bip32@1.7.0': dependencies: - '@noble/curves': 1.9.1 + '@noble/curves': 1.9.7 '@noble/hashes': 1.8.0 '@scure/base': 1.2.6 @@ -5584,46 +6699,46 @@ snapshots: '@noble/hashes': 1.8.0 '@scure/base': 1.2.6 - '@solana-program/system@0.10.0(@solana/kit@5.4.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10))': + '@solana-program/system@0.10.0(@solana/kit@5.5.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10))': dependencies: - '@solana/kit': 5.4.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) + '@solana/kit': 5.5.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) optional: true - '@solana-program/token@0.9.0(@solana/kit@5.4.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10))': + '@solana-program/token@0.9.0(@solana/kit@5.5.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10))': dependencies: - '@solana/kit': 5.4.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) + '@solana/kit': 5.5.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) optional: true - '@solana/accounts@5.4.0(typescript@5.9.3)': + '@solana/accounts@5.5.1(typescript@5.9.3)': dependencies: - '@solana/addresses': 5.4.0(typescript@5.9.3) - '@solana/codecs-core': 5.4.0(typescript@5.9.3) - '@solana/codecs-strings': 5.4.0(typescript@5.9.3) - '@solana/errors': 5.4.0(typescript@5.9.3) - '@solana/rpc-spec': 5.4.0(typescript@5.9.3) - '@solana/rpc-types': 5.4.0(typescript@5.9.3) + '@solana/addresses': 5.5.1(typescript@5.9.3) + '@solana/codecs-core': 5.5.1(typescript@5.9.3) + '@solana/codecs-strings': 5.5.1(typescript@5.9.3) + '@solana/errors': 5.5.1(typescript@5.9.3) + '@solana/rpc-spec': 5.5.1(typescript@5.9.3) + '@solana/rpc-types': 5.5.1(typescript@5.9.3) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder optional: true - '@solana/addresses@5.4.0(typescript@5.9.3)': + '@solana/addresses@5.5.1(typescript@5.9.3)': dependencies: - '@solana/assertions': 5.4.0(typescript@5.9.3) - '@solana/codecs-core': 5.4.0(typescript@5.9.3) - '@solana/codecs-strings': 5.4.0(typescript@5.9.3) - '@solana/errors': 5.4.0(typescript@5.9.3) - '@solana/nominal-types': 5.4.0(typescript@5.9.3) + '@solana/assertions': 5.5.1(typescript@5.9.3) + '@solana/codecs-core': 5.5.1(typescript@5.9.3) + '@solana/codecs-strings': 5.5.1(typescript@5.9.3) + '@solana/errors': 5.5.1(typescript@5.9.3) + '@solana/nominal-types': 5.5.1(typescript@5.9.3) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder optional: true - '@solana/assertions@5.4.0(typescript@5.9.3)': + '@solana/assertions@5.5.1(typescript@5.9.3)': dependencies: - '@solana/errors': 5.4.0(typescript@5.9.3) + '@solana/errors': 5.5.1(typescript@5.9.3) optionalDependencies: typescript: 5.9.3 optional: true @@ -5639,18 +6754,18 @@ snapshots: typescript: 5.9.3 optional: true - '@solana/codecs-core@5.4.0(typescript@5.9.3)': + '@solana/codecs-core@5.5.1(typescript@5.9.3)': dependencies: - '@solana/errors': 5.4.0(typescript@5.9.3) + '@solana/errors': 5.5.1(typescript@5.9.3) optionalDependencies: typescript: 5.9.3 optional: true - '@solana/codecs-data-structures@5.4.0(typescript@5.9.3)': + '@solana/codecs-data-structures@5.5.1(typescript@5.9.3)': dependencies: - '@solana/codecs-core': 5.4.0(typescript@5.9.3) - '@solana/codecs-numbers': 5.4.0(typescript@5.9.3) - '@solana/errors': 5.4.0(typescript@5.9.3) + '@solana/codecs-core': 5.5.1(typescript@5.9.3) + '@solana/codecs-numbers': 5.5.1(typescript@5.9.3) + '@solana/errors': 5.5.1(typescript@5.9.3) optionalDependencies: typescript: 5.9.3 optional: true @@ -5662,30 +6777,30 @@ snapshots: typescript: 5.9.3 optional: true - '@solana/codecs-numbers@5.4.0(typescript@5.9.3)': + '@solana/codecs-numbers@5.5.1(typescript@5.9.3)': dependencies: - '@solana/codecs-core': 5.4.0(typescript@5.9.3) - '@solana/errors': 5.4.0(typescript@5.9.3) + '@solana/codecs-core': 5.5.1(typescript@5.9.3) + '@solana/errors': 5.5.1(typescript@5.9.3) optionalDependencies: typescript: 5.9.3 optional: true - '@solana/codecs-strings@5.4.0(typescript@5.9.3)': + '@solana/codecs-strings@5.5.1(typescript@5.9.3)': dependencies: - '@solana/codecs-core': 5.4.0(typescript@5.9.3) - '@solana/codecs-numbers': 5.4.0(typescript@5.9.3) - '@solana/errors': 5.4.0(typescript@5.9.3) + '@solana/codecs-core': 5.5.1(typescript@5.9.3) + '@solana/codecs-numbers': 5.5.1(typescript@5.9.3) + '@solana/errors': 5.5.1(typescript@5.9.3) optionalDependencies: typescript: 5.9.3 optional: true - '@solana/codecs@5.4.0(typescript@5.9.3)': + '@solana/codecs@5.5.1(typescript@5.9.3)': dependencies: - '@solana/codecs-core': 5.4.0(typescript@5.9.3) - '@solana/codecs-data-structures': 5.4.0(typescript@5.9.3) - '@solana/codecs-numbers': 5.4.0(typescript@5.9.3) - '@solana/codecs-strings': 5.4.0(typescript@5.9.3) - '@solana/options': 5.4.0(typescript@5.9.3) + '@solana/codecs-core': 5.5.1(typescript@5.9.3) + '@solana/codecs-data-structures': 5.5.1(typescript@5.9.3) + '@solana/codecs-numbers': 5.5.1(typescript@5.9.3) + '@solana/codecs-strings': 5.5.1(typescript@5.9.3) + '@solana/options': 5.5.1(typescript@5.9.3) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: @@ -5699,7 +6814,7 @@ snapshots: typescript: 5.9.3 optional: true - '@solana/errors@5.4.0(typescript@5.9.3)': + '@solana/errors@5.5.1(typescript@5.9.3)': dependencies: chalk: 5.6.2 commander: 14.0.2 @@ -5707,75 +6822,75 @@ snapshots: typescript: 5.9.3 optional: true - '@solana/fast-stable-stringify@5.4.0(typescript@5.9.3)': + '@solana/fast-stable-stringify@5.5.1(typescript@5.9.3)': optionalDependencies: typescript: 5.9.3 optional: true - '@solana/functional@5.4.0(typescript@5.9.3)': + '@solana/functional@5.5.1(typescript@5.9.3)': optionalDependencies: typescript: 5.9.3 optional: true - '@solana/instruction-plans@5.4.0(typescript@5.9.3)': + '@solana/instruction-plans@5.5.1(typescript@5.9.3)': dependencies: - '@solana/errors': 5.4.0(typescript@5.9.3) - '@solana/instructions': 5.4.0(typescript@5.9.3) - '@solana/keys': 5.4.0(typescript@5.9.3) - '@solana/promises': 5.4.0(typescript@5.9.3) - '@solana/transaction-messages': 5.4.0(typescript@5.9.3) - '@solana/transactions': 5.4.0(typescript@5.9.3) + '@solana/errors': 5.5.1(typescript@5.9.3) + '@solana/instructions': 5.5.1(typescript@5.9.3) + '@solana/keys': 5.5.1(typescript@5.9.3) + '@solana/promises': 5.5.1(typescript@5.9.3) + '@solana/transaction-messages': 5.5.1(typescript@5.9.3) + '@solana/transactions': 5.5.1(typescript@5.9.3) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder optional: true - '@solana/instructions@5.4.0(typescript@5.9.3)': + '@solana/instructions@5.5.1(typescript@5.9.3)': dependencies: - '@solana/codecs-core': 5.4.0(typescript@5.9.3) - '@solana/errors': 5.4.0(typescript@5.9.3) + '@solana/codecs-core': 5.5.1(typescript@5.9.3) + '@solana/errors': 5.5.1(typescript@5.9.3) optionalDependencies: typescript: 5.9.3 optional: true - '@solana/keys@5.4.0(typescript@5.9.3)': + '@solana/keys@5.5.1(typescript@5.9.3)': dependencies: - '@solana/assertions': 5.4.0(typescript@5.9.3) - '@solana/codecs-core': 5.4.0(typescript@5.9.3) - '@solana/codecs-strings': 5.4.0(typescript@5.9.3) - '@solana/errors': 5.4.0(typescript@5.9.3) - '@solana/nominal-types': 5.4.0(typescript@5.9.3) + '@solana/assertions': 5.5.1(typescript@5.9.3) + '@solana/codecs-core': 5.5.1(typescript@5.9.3) + '@solana/codecs-strings': 5.5.1(typescript@5.9.3) + '@solana/errors': 5.5.1(typescript@5.9.3) + '@solana/nominal-types': 5.5.1(typescript@5.9.3) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder optional: true - '@solana/kit@5.4.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)': - dependencies: - '@solana/accounts': 5.4.0(typescript@5.9.3) - '@solana/addresses': 5.4.0(typescript@5.9.3) - '@solana/codecs': 5.4.0(typescript@5.9.3) - '@solana/errors': 5.4.0(typescript@5.9.3) - '@solana/functional': 5.4.0(typescript@5.9.3) - '@solana/instruction-plans': 5.4.0(typescript@5.9.3) - '@solana/instructions': 5.4.0(typescript@5.9.3) - '@solana/keys': 5.4.0(typescript@5.9.3) - '@solana/offchain-messages': 5.4.0(typescript@5.9.3) - '@solana/plugin-core': 5.4.0(typescript@5.9.3) - '@solana/programs': 5.4.0(typescript@5.9.3) - '@solana/rpc': 5.4.0(typescript@5.9.3) - '@solana/rpc-api': 5.4.0(typescript@5.9.3) - '@solana/rpc-parsed-types': 5.4.0(typescript@5.9.3) - '@solana/rpc-spec-types': 5.4.0(typescript@5.9.3) - '@solana/rpc-subscriptions': 5.4.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) - '@solana/rpc-types': 5.4.0(typescript@5.9.3) - '@solana/signers': 5.4.0(typescript@5.9.3) - '@solana/sysvars': 5.4.0(typescript@5.9.3) - '@solana/transaction-confirmation': 5.4.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) - '@solana/transaction-messages': 5.4.0(typescript@5.9.3) - '@solana/transactions': 5.4.0(typescript@5.9.3) + '@solana/kit@5.5.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)': + dependencies: + '@solana/accounts': 5.5.1(typescript@5.9.3) + '@solana/addresses': 5.5.1(typescript@5.9.3) + '@solana/codecs': 5.5.1(typescript@5.9.3) + '@solana/errors': 5.5.1(typescript@5.9.3) + '@solana/functional': 5.5.1(typescript@5.9.3) + '@solana/instruction-plans': 5.5.1(typescript@5.9.3) + '@solana/instructions': 5.5.1(typescript@5.9.3) + '@solana/keys': 5.5.1(typescript@5.9.3) + '@solana/offchain-messages': 5.5.1(typescript@5.9.3) + '@solana/plugin-core': 5.5.1(typescript@5.9.3) + '@solana/programs': 5.5.1(typescript@5.9.3) + '@solana/rpc': 5.5.1(typescript@5.9.3) + '@solana/rpc-api': 5.5.1(typescript@5.9.3) + '@solana/rpc-parsed-types': 5.5.1(typescript@5.9.3) + '@solana/rpc-spec-types': 5.5.1(typescript@5.9.3) + '@solana/rpc-subscriptions': 5.5.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) + '@solana/rpc-types': 5.5.1(typescript@5.9.3) + '@solana/signers': 5.5.1(typescript@5.9.3) + '@solana/sysvars': 5.5.1(typescript@5.9.3) + '@solana/transaction-confirmation': 5.5.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) + '@solana/transaction-messages': 5.5.1(typescript@5.9.3) + '@solana/transactions': 5.5.1(typescript@5.9.3) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: @@ -5784,118 +6899,118 @@ snapshots: - utf-8-validate optional: true - '@solana/nominal-types@5.4.0(typescript@5.9.3)': + '@solana/nominal-types@5.5.1(typescript@5.9.3)': optionalDependencies: typescript: 5.9.3 optional: true - '@solana/offchain-messages@5.4.0(typescript@5.9.3)': + '@solana/offchain-messages@5.5.1(typescript@5.9.3)': dependencies: - '@solana/addresses': 5.4.0(typescript@5.9.3) - '@solana/codecs-core': 5.4.0(typescript@5.9.3) - '@solana/codecs-data-structures': 5.4.0(typescript@5.9.3) - '@solana/codecs-numbers': 5.4.0(typescript@5.9.3) - '@solana/codecs-strings': 5.4.0(typescript@5.9.3) - '@solana/errors': 5.4.0(typescript@5.9.3) - '@solana/keys': 5.4.0(typescript@5.9.3) - '@solana/nominal-types': 5.4.0(typescript@5.9.3) + '@solana/addresses': 5.5.1(typescript@5.9.3) + '@solana/codecs-core': 5.5.1(typescript@5.9.3) + '@solana/codecs-data-structures': 5.5.1(typescript@5.9.3) + '@solana/codecs-numbers': 5.5.1(typescript@5.9.3) + '@solana/codecs-strings': 5.5.1(typescript@5.9.3) + '@solana/errors': 5.5.1(typescript@5.9.3) + '@solana/keys': 5.5.1(typescript@5.9.3) + '@solana/nominal-types': 5.5.1(typescript@5.9.3) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder optional: true - '@solana/options@5.4.0(typescript@5.9.3)': + '@solana/options@5.5.1(typescript@5.9.3)': dependencies: - '@solana/codecs-core': 5.4.0(typescript@5.9.3) - '@solana/codecs-data-structures': 5.4.0(typescript@5.9.3) - '@solana/codecs-numbers': 5.4.0(typescript@5.9.3) - '@solana/codecs-strings': 5.4.0(typescript@5.9.3) - '@solana/errors': 5.4.0(typescript@5.9.3) + '@solana/codecs-core': 5.5.1(typescript@5.9.3) + '@solana/codecs-data-structures': 5.5.1(typescript@5.9.3) + '@solana/codecs-numbers': 5.5.1(typescript@5.9.3) + '@solana/codecs-strings': 5.5.1(typescript@5.9.3) + '@solana/errors': 5.5.1(typescript@5.9.3) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder optional: true - '@solana/plugin-core@5.4.0(typescript@5.9.3)': + '@solana/plugin-core@5.5.1(typescript@5.9.3)': optionalDependencies: typescript: 5.9.3 optional: true - '@solana/programs@5.4.0(typescript@5.9.3)': + '@solana/programs@5.5.1(typescript@5.9.3)': dependencies: - '@solana/addresses': 5.4.0(typescript@5.9.3) - '@solana/errors': 5.4.0(typescript@5.9.3) + '@solana/addresses': 5.5.1(typescript@5.9.3) + '@solana/errors': 5.5.1(typescript@5.9.3) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder optional: true - '@solana/promises@5.4.0(typescript@5.9.3)': + '@solana/promises@5.5.1(typescript@5.9.3)': optionalDependencies: typescript: 5.9.3 optional: true - '@solana/rpc-api@5.4.0(typescript@5.9.3)': + '@solana/rpc-api@5.5.1(typescript@5.9.3)': dependencies: - '@solana/addresses': 5.4.0(typescript@5.9.3) - '@solana/codecs-core': 5.4.0(typescript@5.9.3) - '@solana/codecs-strings': 5.4.0(typescript@5.9.3) - '@solana/errors': 5.4.0(typescript@5.9.3) - '@solana/keys': 5.4.0(typescript@5.9.3) - '@solana/rpc-parsed-types': 5.4.0(typescript@5.9.3) - '@solana/rpc-spec': 5.4.0(typescript@5.9.3) - '@solana/rpc-transformers': 5.4.0(typescript@5.9.3) - '@solana/rpc-types': 5.4.0(typescript@5.9.3) - '@solana/transaction-messages': 5.4.0(typescript@5.9.3) - '@solana/transactions': 5.4.0(typescript@5.9.3) + '@solana/addresses': 5.5.1(typescript@5.9.3) + '@solana/codecs-core': 5.5.1(typescript@5.9.3) + '@solana/codecs-strings': 5.5.1(typescript@5.9.3) + '@solana/errors': 5.5.1(typescript@5.9.3) + '@solana/keys': 5.5.1(typescript@5.9.3) + '@solana/rpc-parsed-types': 5.5.1(typescript@5.9.3) + '@solana/rpc-spec': 5.5.1(typescript@5.9.3) + '@solana/rpc-transformers': 5.5.1(typescript@5.9.3) + '@solana/rpc-types': 5.5.1(typescript@5.9.3) + '@solana/transaction-messages': 5.5.1(typescript@5.9.3) + '@solana/transactions': 5.5.1(typescript@5.9.3) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder optional: true - '@solana/rpc-parsed-types@5.4.0(typescript@5.9.3)': + '@solana/rpc-parsed-types@5.5.1(typescript@5.9.3)': optionalDependencies: typescript: 5.9.3 optional: true - '@solana/rpc-spec-types@5.4.0(typescript@5.9.3)': + '@solana/rpc-spec-types@5.5.1(typescript@5.9.3)': optionalDependencies: typescript: 5.9.3 optional: true - '@solana/rpc-spec@5.4.0(typescript@5.9.3)': + '@solana/rpc-spec@5.5.1(typescript@5.9.3)': dependencies: - '@solana/errors': 5.4.0(typescript@5.9.3) - '@solana/rpc-spec-types': 5.4.0(typescript@5.9.3) + '@solana/errors': 5.5.1(typescript@5.9.3) + '@solana/rpc-spec-types': 5.5.1(typescript@5.9.3) optionalDependencies: typescript: 5.9.3 optional: true - '@solana/rpc-subscriptions-api@5.4.0(typescript@5.9.3)': + '@solana/rpc-subscriptions-api@5.5.1(typescript@5.9.3)': dependencies: - '@solana/addresses': 5.4.0(typescript@5.9.3) - '@solana/keys': 5.4.0(typescript@5.9.3) - '@solana/rpc-subscriptions-spec': 5.4.0(typescript@5.9.3) - '@solana/rpc-transformers': 5.4.0(typescript@5.9.3) - '@solana/rpc-types': 5.4.0(typescript@5.9.3) - '@solana/transaction-messages': 5.4.0(typescript@5.9.3) - '@solana/transactions': 5.4.0(typescript@5.9.3) + '@solana/addresses': 5.5.1(typescript@5.9.3) + '@solana/keys': 5.5.1(typescript@5.9.3) + '@solana/rpc-subscriptions-spec': 5.5.1(typescript@5.9.3) + '@solana/rpc-transformers': 5.5.1(typescript@5.9.3) + '@solana/rpc-types': 5.5.1(typescript@5.9.3) + '@solana/transaction-messages': 5.5.1(typescript@5.9.3) + '@solana/transactions': 5.5.1(typescript@5.9.3) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder optional: true - '@solana/rpc-subscriptions-channel-websocket@5.4.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)': + '@solana/rpc-subscriptions-channel-websocket@5.5.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)': dependencies: - '@solana/errors': 5.4.0(typescript@5.9.3) - '@solana/functional': 5.4.0(typescript@5.9.3) - '@solana/rpc-subscriptions-spec': 5.4.0(typescript@5.9.3) - '@solana/subscribable': 5.4.0(typescript@5.9.3) + '@solana/errors': 5.5.1(typescript@5.9.3) + '@solana/functional': 5.5.1(typescript@5.9.3) + '@solana/rpc-subscriptions-spec': 5.5.1(typescript@5.9.3) + '@solana/subscribable': 5.5.1(typescript@5.9.3) ws: 8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) optionalDependencies: typescript: 5.9.3 @@ -5904,29 +7019,29 @@ snapshots: - utf-8-validate optional: true - '@solana/rpc-subscriptions-spec@5.4.0(typescript@5.9.3)': + '@solana/rpc-subscriptions-spec@5.5.1(typescript@5.9.3)': dependencies: - '@solana/errors': 5.4.0(typescript@5.9.3) - '@solana/promises': 5.4.0(typescript@5.9.3) - '@solana/rpc-spec-types': 5.4.0(typescript@5.9.3) - '@solana/subscribable': 5.4.0(typescript@5.9.3) + '@solana/errors': 5.5.1(typescript@5.9.3) + '@solana/promises': 5.5.1(typescript@5.9.3) + '@solana/rpc-spec-types': 5.5.1(typescript@5.9.3) + '@solana/subscribable': 5.5.1(typescript@5.9.3) optionalDependencies: typescript: 5.9.3 optional: true - '@solana/rpc-subscriptions@5.4.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)': + '@solana/rpc-subscriptions@5.5.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)': dependencies: - '@solana/errors': 5.4.0(typescript@5.9.3) - '@solana/fast-stable-stringify': 5.4.0(typescript@5.9.3) - '@solana/functional': 5.4.0(typescript@5.9.3) - '@solana/promises': 5.4.0(typescript@5.9.3) - '@solana/rpc-spec-types': 5.4.0(typescript@5.9.3) - '@solana/rpc-subscriptions-api': 5.4.0(typescript@5.9.3) - '@solana/rpc-subscriptions-channel-websocket': 5.4.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) - '@solana/rpc-subscriptions-spec': 5.4.0(typescript@5.9.3) - '@solana/rpc-transformers': 5.4.0(typescript@5.9.3) - '@solana/rpc-types': 5.4.0(typescript@5.9.3) - '@solana/subscribable': 5.4.0(typescript@5.9.3) + '@solana/errors': 5.5.1(typescript@5.9.3) + '@solana/fast-stable-stringify': 5.5.1(typescript@5.9.3) + '@solana/functional': 5.5.1(typescript@5.9.3) + '@solana/promises': 5.5.1(typescript@5.9.3) + '@solana/rpc-spec-types': 5.5.1(typescript@5.9.3) + '@solana/rpc-subscriptions-api': 5.5.1(typescript@5.9.3) + '@solana/rpc-subscriptions-channel-websocket': 5.5.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) + '@solana/rpc-subscriptions-spec': 5.5.1(typescript@5.9.3) + '@solana/rpc-transformers': 5.5.1(typescript@5.9.3) + '@solana/rpc-types': 5.5.1(typescript@5.9.3) + '@solana/subscribable': 5.5.1(typescript@5.9.3) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: @@ -5935,108 +7050,108 @@ snapshots: - utf-8-validate optional: true - '@solana/rpc-transformers@5.4.0(typescript@5.9.3)': + '@solana/rpc-transformers@5.5.1(typescript@5.9.3)': dependencies: - '@solana/errors': 5.4.0(typescript@5.9.3) - '@solana/functional': 5.4.0(typescript@5.9.3) - '@solana/nominal-types': 5.4.0(typescript@5.9.3) - '@solana/rpc-spec-types': 5.4.0(typescript@5.9.3) - '@solana/rpc-types': 5.4.0(typescript@5.9.3) + '@solana/errors': 5.5.1(typescript@5.9.3) + '@solana/functional': 5.5.1(typescript@5.9.3) + '@solana/nominal-types': 5.5.1(typescript@5.9.3) + '@solana/rpc-spec-types': 5.5.1(typescript@5.9.3) + '@solana/rpc-types': 5.5.1(typescript@5.9.3) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder optional: true - '@solana/rpc-transport-http@5.4.0(typescript@5.9.3)': + '@solana/rpc-transport-http@5.5.1(typescript@5.9.3)': dependencies: - '@solana/errors': 5.4.0(typescript@5.9.3) - '@solana/rpc-spec': 5.4.0(typescript@5.9.3) - '@solana/rpc-spec-types': 5.4.0(typescript@5.9.3) - undici-types: 7.19.1 + '@solana/errors': 5.5.1(typescript@5.9.3) + '@solana/rpc-spec': 5.5.1(typescript@5.9.3) + '@solana/rpc-spec-types': 5.5.1(typescript@5.9.3) + undici-types: 7.19.2 optionalDependencies: typescript: 5.9.3 optional: true - '@solana/rpc-types@5.4.0(typescript@5.9.3)': + '@solana/rpc-types@5.5.1(typescript@5.9.3)': dependencies: - '@solana/addresses': 5.4.0(typescript@5.9.3) - '@solana/codecs-core': 5.4.0(typescript@5.9.3) - '@solana/codecs-numbers': 5.4.0(typescript@5.9.3) - '@solana/codecs-strings': 5.4.0(typescript@5.9.3) - '@solana/errors': 5.4.0(typescript@5.9.3) - '@solana/nominal-types': 5.4.0(typescript@5.9.3) + '@solana/addresses': 5.5.1(typescript@5.9.3) + '@solana/codecs-core': 5.5.1(typescript@5.9.3) + '@solana/codecs-numbers': 5.5.1(typescript@5.9.3) + '@solana/codecs-strings': 5.5.1(typescript@5.9.3) + '@solana/errors': 5.5.1(typescript@5.9.3) + '@solana/nominal-types': 5.5.1(typescript@5.9.3) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder optional: true - '@solana/rpc@5.4.0(typescript@5.9.3)': + '@solana/rpc@5.5.1(typescript@5.9.3)': dependencies: - '@solana/errors': 5.4.0(typescript@5.9.3) - '@solana/fast-stable-stringify': 5.4.0(typescript@5.9.3) - '@solana/functional': 5.4.0(typescript@5.9.3) - '@solana/rpc-api': 5.4.0(typescript@5.9.3) - '@solana/rpc-spec': 5.4.0(typescript@5.9.3) - '@solana/rpc-spec-types': 5.4.0(typescript@5.9.3) - '@solana/rpc-transformers': 5.4.0(typescript@5.9.3) - '@solana/rpc-transport-http': 5.4.0(typescript@5.9.3) - '@solana/rpc-types': 5.4.0(typescript@5.9.3) + '@solana/errors': 5.5.1(typescript@5.9.3) + '@solana/fast-stable-stringify': 5.5.1(typescript@5.9.3) + '@solana/functional': 5.5.1(typescript@5.9.3) + '@solana/rpc-api': 5.5.1(typescript@5.9.3) + '@solana/rpc-spec': 5.5.1(typescript@5.9.3) + '@solana/rpc-spec-types': 5.5.1(typescript@5.9.3) + '@solana/rpc-transformers': 5.5.1(typescript@5.9.3) + '@solana/rpc-transport-http': 5.5.1(typescript@5.9.3) + '@solana/rpc-types': 5.5.1(typescript@5.9.3) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder optional: true - '@solana/signers@5.4.0(typescript@5.9.3)': + '@solana/signers@5.5.1(typescript@5.9.3)': dependencies: - '@solana/addresses': 5.4.0(typescript@5.9.3) - '@solana/codecs-core': 5.4.0(typescript@5.9.3) - '@solana/errors': 5.4.0(typescript@5.9.3) - '@solana/instructions': 5.4.0(typescript@5.9.3) - '@solana/keys': 5.4.0(typescript@5.9.3) - '@solana/nominal-types': 5.4.0(typescript@5.9.3) - '@solana/offchain-messages': 5.4.0(typescript@5.9.3) - '@solana/transaction-messages': 5.4.0(typescript@5.9.3) - '@solana/transactions': 5.4.0(typescript@5.9.3) + '@solana/addresses': 5.5.1(typescript@5.9.3) + '@solana/codecs-core': 5.5.1(typescript@5.9.3) + '@solana/errors': 5.5.1(typescript@5.9.3) + '@solana/instructions': 5.5.1(typescript@5.9.3) + '@solana/keys': 5.5.1(typescript@5.9.3) + '@solana/nominal-types': 5.5.1(typescript@5.9.3) + '@solana/offchain-messages': 5.5.1(typescript@5.9.3) + '@solana/transaction-messages': 5.5.1(typescript@5.9.3) + '@solana/transactions': 5.5.1(typescript@5.9.3) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder optional: true - '@solana/subscribable@5.4.0(typescript@5.9.3)': + '@solana/subscribable@5.5.1(typescript@5.9.3)': dependencies: - '@solana/errors': 5.4.0(typescript@5.9.3) + '@solana/errors': 5.5.1(typescript@5.9.3) optionalDependencies: typescript: 5.9.3 optional: true - '@solana/sysvars@5.4.0(typescript@5.9.3)': + '@solana/sysvars@5.5.1(typescript@5.9.3)': dependencies: - '@solana/accounts': 5.4.0(typescript@5.9.3) - '@solana/codecs': 5.4.0(typescript@5.9.3) - '@solana/errors': 5.4.0(typescript@5.9.3) - '@solana/rpc-types': 5.4.0(typescript@5.9.3) + '@solana/accounts': 5.5.1(typescript@5.9.3) + '@solana/codecs': 5.5.1(typescript@5.9.3) + '@solana/errors': 5.5.1(typescript@5.9.3) + '@solana/rpc-types': 5.5.1(typescript@5.9.3) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder optional: true - '@solana/transaction-confirmation@5.4.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)': + '@solana/transaction-confirmation@5.5.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)': dependencies: - '@solana/addresses': 5.4.0(typescript@5.9.3) - '@solana/codecs-strings': 5.4.0(typescript@5.9.3) - '@solana/errors': 5.4.0(typescript@5.9.3) - '@solana/keys': 5.4.0(typescript@5.9.3) - '@solana/promises': 5.4.0(typescript@5.9.3) - '@solana/rpc': 5.4.0(typescript@5.9.3) - '@solana/rpc-subscriptions': 5.4.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) - '@solana/rpc-types': 5.4.0(typescript@5.9.3) - '@solana/transaction-messages': 5.4.0(typescript@5.9.3) - '@solana/transactions': 5.4.0(typescript@5.9.3) + '@solana/addresses': 5.5.1(typescript@5.9.3) + '@solana/codecs-strings': 5.5.1(typescript@5.9.3) + '@solana/errors': 5.5.1(typescript@5.9.3) + '@solana/keys': 5.5.1(typescript@5.9.3) + '@solana/promises': 5.5.1(typescript@5.9.3) + '@solana/rpc': 5.5.1(typescript@5.9.3) + '@solana/rpc-subscriptions': 5.5.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) + '@solana/rpc-types': 5.5.1(typescript@5.9.3) + '@solana/transaction-messages': 5.5.1(typescript@5.9.3) + '@solana/transactions': 5.5.1(typescript@5.9.3) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: @@ -6045,37 +7160,37 @@ snapshots: - utf-8-validate optional: true - '@solana/transaction-messages@5.4.0(typescript@5.9.3)': + '@solana/transaction-messages@5.5.1(typescript@5.9.3)': dependencies: - '@solana/addresses': 5.4.0(typescript@5.9.3) - '@solana/codecs-core': 5.4.0(typescript@5.9.3) - '@solana/codecs-data-structures': 5.4.0(typescript@5.9.3) - '@solana/codecs-numbers': 5.4.0(typescript@5.9.3) - '@solana/errors': 5.4.0(typescript@5.9.3) - '@solana/functional': 5.4.0(typescript@5.9.3) - '@solana/instructions': 5.4.0(typescript@5.9.3) - '@solana/nominal-types': 5.4.0(typescript@5.9.3) - '@solana/rpc-types': 5.4.0(typescript@5.9.3) + '@solana/addresses': 5.5.1(typescript@5.9.3) + '@solana/codecs-core': 5.5.1(typescript@5.9.3) + '@solana/codecs-data-structures': 5.5.1(typescript@5.9.3) + '@solana/codecs-numbers': 5.5.1(typescript@5.9.3) + '@solana/errors': 5.5.1(typescript@5.9.3) + '@solana/functional': 5.5.1(typescript@5.9.3) + '@solana/instructions': 5.5.1(typescript@5.9.3) + '@solana/nominal-types': 5.5.1(typescript@5.9.3) + '@solana/rpc-types': 5.5.1(typescript@5.9.3) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder optional: true - '@solana/transactions@5.4.0(typescript@5.9.3)': - dependencies: - '@solana/addresses': 5.4.0(typescript@5.9.3) - '@solana/codecs-core': 5.4.0(typescript@5.9.3) - '@solana/codecs-data-structures': 5.4.0(typescript@5.9.3) - '@solana/codecs-numbers': 5.4.0(typescript@5.9.3) - '@solana/codecs-strings': 5.4.0(typescript@5.9.3) - '@solana/errors': 5.4.0(typescript@5.9.3) - '@solana/functional': 5.4.0(typescript@5.9.3) - '@solana/instructions': 5.4.0(typescript@5.9.3) - '@solana/keys': 5.4.0(typescript@5.9.3) - '@solana/nominal-types': 5.4.0(typescript@5.9.3) - '@solana/rpc-types': 5.4.0(typescript@5.9.3) - '@solana/transaction-messages': 5.4.0(typescript@5.9.3) + '@solana/transactions@5.5.1(typescript@5.9.3)': + dependencies: + '@solana/addresses': 5.5.1(typescript@5.9.3) + '@solana/codecs-core': 5.5.1(typescript@5.9.3) + '@solana/codecs-data-structures': 5.5.1(typescript@5.9.3) + '@solana/codecs-numbers': 5.5.1(typescript@5.9.3) + '@solana/codecs-strings': 5.5.1(typescript@5.9.3) + '@solana/errors': 5.5.1(typescript@5.9.3) + '@solana/functional': 5.5.1(typescript@5.9.3) + '@solana/instructions': 5.5.1(typescript@5.9.3) + '@solana/keys': 5.5.1(typescript@5.9.3) + '@solana/nominal-types': 5.5.1(typescript@5.9.3) + '@solana/rpc-types': 5.5.1(typescript@5.9.3) + '@solana/transaction-messages': 5.5.1(typescript@5.9.3) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: @@ -6086,7 +7201,7 @@ snapshots: dependencies: '@babel/runtime': 7.28.6 '@noble/curves': 1.9.7 - '@noble/hashes': 1.4.0 + '@noble/hashes': 1.8.0 '@solana/buffer-layout': 4.0.1 '@solana/codecs-numbers': 2.3.0(typescript@5.9.3) agentkeepalive: 4.6.0 @@ -6106,39 +7221,39 @@ snapshots: - utf-8-validate optional: true - '@solid-primitives/event-listener@2.4.3(solid-js@1.9.10)': + '@solid-primitives/event-listener@2.4.3(solid-js@1.9.11)': dependencies: - '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) - solid-js: 1.9.10 + '@solid-primitives/utils': 6.3.2(solid-js@1.9.11) + solid-js: 1.9.11 - '@solid-primitives/keyboard@1.3.3(solid-js@1.9.10)': + '@solid-primitives/keyboard@1.3.3(solid-js@1.9.11)': dependencies: - '@solid-primitives/event-listener': 2.4.3(solid-js@1.9.10) - '@solid-primitives/rootless': 1.5.2(solid-js@1.9.10) - '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) - solid-js: 1.9.10 + '@solid-primitives/event-listener': 2.4.3(solid-js@1.9.11) + '@solid-primitives/rootless': 1.5.2(solid-js@1.9.11) + '@solid-primitives/utils': 6.3.2(solid-js@1.9.11) + solid-js: 1.9.11 - '@solid-primitives/resize-observer@2.1.3(solid-js@1.9.10)': + '@solid-primitives/resize-observer@2.1.3(solid-js@1.9.11)': dependencies: - '@solid-primitives/event-listener': 2.4.3(solid-js@1.9.10) - '@solid-primitives/rootless': 1.5.2(solid-js@1.9.10) - '@solid-primitives/static-store': 0.1.2(solid-js@1.9.10) - '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) - solid-js: 1.9.10 + '@solid-primitives/event-listener': 2.4.3(solid-js@1.9.11) + '@solid-primitives/rootless': 1.5.2(solid-js@1.9.11) + '@solid-primitives/static-store': 0.1.2(solid-js@1.9.11) + '@solid-primitives/utils': 6.3.2(solid-js@1.9.11) + solid-js: 1.9.11 - '@solid-primitives/rootless@1.5.2(solid-js@1.9.10)': + '@solid-primitives/rootless@1.5.2(solid-js@1.9.11)': dependencies: - '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) - solid-js: 1.9.10 + '@solid-primitives/utils': 6.3.2(solid-js@1.9.11) + solid-js: 1.9.11 - '@solid-primitives/static-store@0.1.2(solid-js@1.9.10)': + '@solid-primitives/static-store@0.1.2(solid-js@1.9.11)': dependencies: - '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) - solid-js: 1.9.10 + '@solid-primitives/utils': 6.3.2(solid-js@1.9.11) + solid-js: 1.9.11 - '@solid-primitives/utils@6.3.2(solid-js@1.9.10)': + '@solid-primitives/utils@6.3.2(solid-js@1.9.11)': dependencies: - solid-js: 1.9.10 + solid-js: 1.9.11 '@stacks/common@6.16.0': dependencies: @@ -6233,12 +7348,12 @@ snapshots: '@tailwindcss/oxide-win32-arm64-msvc': 4.1.18 '@tailwindcss/oxide-win32-x64-msvc': 4.1.18 - '@tailwindcss/vite@4.1.18(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))': + '@tailwindcss/vite@4.1.18(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@tailwindcss/node': 4.1.18 '@tailwindcss/oxide': 4.1.18 tailwindcss: 4.1.18 - vite: 7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) '@tanstack/devtools-client@0.0.5': dependencies: @@ -6253,43 +7368,43 @@ snapshots: '@tanstack/devtools-event-client@0.4.0': {} - '@tanstack/devtools-ui@0.4.4(csstype@3.2.3)(solid-js@1.9.10)': + '@tanstack/devtools-ui@0.4.4(csstype@3.2.3)(solid-js@1.9.11)': dependencies: clsx: 2.1.1 goober: 2.1.18(csstype@3.2.3) - solid-js: 1.9.10 + solid-js: 1.9.11 transitivePeerDependencies: - csstype - '@tanstack/devtools-vite@0.4.1(bufferutil@4.1.0)(utf-8-validate@5.0.10)(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))': + '@tanstack/devtools-vite@0.5.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))': dependencies: - '@babel/core': 7.28.6 - '@babel/generator': 7.28.6 - '@babel/parser': 7.28.6 - '@babel/traverse': 7.28.6 - '@babel/types': 7.28.6 + '@babel/core': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/parser': 7.29.0 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 '@tanstack/devtools-client': 0.0.5 '@tanstack/devtools-event-bus': 0.4.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) chalk: 5.6.2 launch-editor: 2.12.0 picomatch: 4.0.3 - vite: 7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - '@tanstack/devtools@0.10.3(bufferutil@4.1.0)(csstype@3.2.3)(solid-js@1.9.10)(utf-8-validate@5.0.10)': + '@tanstack/devtools@0.10.5(bufferutil@4.1.0)(csstype@3.2.3)(solid-js@1.9.11)(utf-8-validate@5.0.10)': dependencies: - '@solid-primitives/event-listener': 2.4.3(solid-js@1.9.10) - '@solid-primitives/keyboard': 1.3.3(solid-js@1.9.10) - '@solid-primitives/resize-observer': 2.1.3(solid-js@1.9.10) + '@solid-primitives/event-listener': 2.4.3(solid-js@1.9.11) + '@solid-primitives/keyboard': 1.3.3(solid-js@1.9.11) + '@solid-primitives/resize-observer': 2.1.3(solid-js@1.9.11) '@tanstack/devtools-client': 0.0.5 '@tanstack/devtools-event-bus': 0.4.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) - '@tanstack/devtools-ui': 0.4.4(csstype@3.2.3)(solid-js@1.9.10) + '@tanstack/devtools-ui': 0.4.4(csstype@3.2.3)(solid-js@1.9.11) clsx: 2.1.1 goober: 2.1.18(csstype@3.2.3) - solid-js: 1.9.10 + solid-js: 1.9.11 transitivePeerDependencies: - bufferutil - csstype @@ -6299,78 +7414,68 @@ snapshots: '@tanstack/query-core@5.90.20': {} - '@tanstack/react-devtools@0.9.2(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(bufferutil@4.1.0)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(solid-js@1.9.10)(utf-8-validate@5.0.10)': + '@tanstack/react-devtools@0.9.4(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(bufferutil@4.1.0)(csstype@3.2.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(solid-js@1.9.11)(utf-8-validate@5.0.10)': dependencies: - '@tanstack/devtools': 0.10.3(bufferutil@4.1.0)(csstype@3.2.3)(solid-js@1.9.10)(utf-8-validate@5.0.10) - '@types/react': 19.2.9 - '@types/react-dom': 19.2.3(@types/react@19.2.9) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + '@tanstack/devtools': 0.10.5(bufferutil@4.1.0)(csstype@3.2.3)(solid-js@1.9.11)(utf-8-validate@5.0.10) + '@types/react': 19.2.11 + '@types/react-dom': 19.2.3(@types/react@19.2.11) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) transitivePeerDependencies: - bufferutil - csstype - solid-js - utf-8-validate - '@tanstack/react-query@5.90.20(react@19.2.3)': + '@tanstack/react-query@5.90.20(react@19.2.4)': dependencies: '@tanstack/query-core': 5.90.20 - react: 19.2.3 + react: 19.2.4 - '@tanstack/react-router-devtools@1.157.8(@tanstack/react-router@1.157.8(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.157.15)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@tanstack/react-router-devtools@1.158.0(@tanstack/react-router@1.158.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(@tanstack/router-core@1.158.0)(csstype@3.2.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@tanstack/react-router': 1.157.8(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@tanstack/router-devtools-core': 1.157.8(@tanstack/router-core@1.157.15)(csstype@3.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + '@tanstack/react-router': 1.158.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@tanstack/router-devtools-core': 1.158.0(@tanstack/router-core@1.158.0)(csstype@3.2.3) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@tanstack/router-core': 1.157.15 + '@tanstack/router-core': 1.158.0 transitivePeerDependencies: - csstype - '@tanstack/react-router@1.157.8(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@tanstack/react-router@1.158.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@tanstack/history': 1.154.14 - '@tanstack/react-store': 0.8.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@tanstack/router-core': 1.157.8 - isbot: 5.1.33 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + '@tanstack/react-store': 0.8.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@tanstack/router-core': 1.158.0 + isbot: 5.1.34 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) tiny-invariant: 1.3.3 tiny-warning: 1.0.3 - '@tanstack/react-store@0.8.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@tanstack/react-store@0.8.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@tanstack/store': 0.8.0 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - use-sync-external-store: 1.6.0(react@19.2.3) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + use-sync-external-store: 1.6.0(react@19.2.4) - '@tanstack/react-virtual@3.13.18(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@tanstack/react-virtual@3.13.18(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@tanstack/virtual-core': 3.13.18 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) - '@tanstack/router-cli@1.157.15': + '@tanstack/router-cli@1.158.0': dependencies: - '@tanstack/router-generator': 1.157.15 + '@tanstack/router-generator': 1.158.0 chokidar: 3.6.0 yargs: 17.7.2 transitivePeerDependencies: - supports-color - '@tanstack/router-core@1.157.15': - dependencies: - '@tanstack/history': 1.154.14 - '@tanstack/store': 0.8.0 - cookie-es: 2.0.0 - seroval: 1.5.0 - seroval-plugins: 1.5.0(seroval@1.5.0) - tiny-invariant: 1.3.3 - tiny-warning: 1.0.3 - - '@tanstack/router-core@1.157.8': + '@tanstack/router-core@1.158.0': dependencies: '@tanstack/history': 1.154.14 '@tanstack/store': 0.8.0 @@ -6380,32 +7485,19 @@ snapshots: tiny-invariant: 1.3.3 tiny-warning: 1.0.3 - '@tanstack/router-devtools-core@1.157.8(@tanstack/router-core@1.157.15)(csstype@3.2.3)': + '@tanstack/router-devtools-core@1.158.0(@tanstack/router-core@1.158.0)(csstype@3.2.3)': dependencies: - '@tanstack/router-core': 1.157.15 + '@tanstack/router-core': 1.158.0 clsx: 2.1.1 goober: 2.1.18(csstype@3.2.3) tiny-invariant: 1.3.3 optionalDependencies: csstype: 3.2.3 - '@tanstack/router-generator@1.157.15': - dependencies: - '@tanstack/router-core': 1.157.15 - '@tanstack/router-utils': 1.154.7 - '@tanstack/virtual-file-routes': 1.154.7 - prettier: 3.8.1 - recast: 0.23.11 - source-map: 0.7.6 - tsx: 4.21.0 - zod: 3.25.76 - transitivePeerDependencies: - - supports-color - - '@tanstack/router-generator@1.157.8': + '@tanstack/router-generator@1.158.0': dependencies: - '@tanstack/router-core': 1.157.8 - '@tanstack/router-utils': 1.154.7 + '@tanstack/router-core': 1.158.0 + '@tanstack/router-utils': 1.158.0 '@tanstack/virtual-file-routes': 1.154.7 prettier: 3.8.1 recast: 0.23.11 @@ -6415,7 +7507,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@tanstack/router-plugin@1.157.8(@tanstack/react-router@1.157.8(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))': + '@tanstack/router-plugin@1.158.0(@tanstack/react-router@1.158.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@babel/core': 7.28.6 '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.28.6) @@ -6423,26 +7515,27 @@ snapshots: '@babel/template': 7.28.6 '@babel/traverse': 7.28.6 '@babel/types': 7.28.6 - '@tanstack/router-core': 1.157.8 - '@tanstack/router-generator': 1.157.8 - '@tanstack/router-utils': 1.154.7 + '@tanstack/router-core': 1.158.0 + '@tanstack/router-generator': 1.158.0 + '@tanstack/router-utils': 1.158.0 '@tanstack/virtual-file-routes': 1.154.7 - babel-dead-code-elimination: 1.0.12 chokidar: 3.6.0 unplugin: 2.3.11 zod: 3.25.76 optionalDependencies: - '@tanstack/react-router': 1.157.8(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - vite: 7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + '@tanstack/react-router': 1.158.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + vite: 7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - supports-color - '@tanstack/router-utils@1.154.7': + '@tanstack/router-utils@1.158.0': dependencies: '@babel/core': 7.28.6 '@babel/generator': 7.28.6 '@babel/parser': 7.28.6 + '@babel/types': 7.28.6 ansis: 4.2.0 + babel-dead-code-elimination: 1.0.12 diff: 8.0.3 pathe: 2.0.3 tinyglobby: 0.2.15 @@ -6457,8 +7550,8 @@ snapshots: '@testing-library/dom@10.4.1': dependencies: - '@babel/code-frame': 7.27.1 - '@babel/runtime': 7.28.4 + '@babel/code-frame': 7.28.6 + '@babel/runtime': 7.28.6 '@types/aria-query': 5.0.4 aria-query: 5.3.0 dom-accessibility-api: 0.5.16 @@ -6466,15 +7559,15 @@ snapshots: picocolors: 1.1.1 pretty-format: 27.5.1 - '@testing-library/react@16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@testing-library/react@16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@babel/runtime': 7.28.6 '@testing-library/dom': 10.4.1 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.9 - '@types/react-dom': 19.2.3(@types/react@19.2.9) + '@types/react': 19.2.11 + '@types/react-dom': 19.2.3(@types/react@19.2.11) '@tim-smart/openapi-gen@0.4.13(patch_hash=36720013d0f70c201ce8f233e38a7b93fc9fce74a17f9bc4293c3cf891b4fdc6)': dependencies: @@ -6498,28 +7591,28 @@ snapshots: '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.28.5 - '@babel/types': 7.28.5 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 '@types/babel__generator': 7.27.0 '@types/babel__template': 7.4.4 '@types/babel__traverse': 7.28.0 '@types/babel__generator@7.27.0': dependencies: - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.28.5 - '@babel/types': 7.28.5 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 '@types/babel__traverse@7.28.0': dependencies: - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 '@types/bn.js@5.2.0': dependencies: - '@types/node': 25.0.10 + '@types/node': 25.2.0 '@types/chai@5.2.3': dependencies: @@ -6528,7 +7621,7 @@ snapshots: '@types/connect@3.4.38': dependencies: - '@types/node': 25.0.10 + '@types/node': 25.2.0 optional: true '@types/deep-eql@4.0.2': {} @@ -6542,15 +7635,15 @@ snapshots: dependencies: undici-types: 5.26.5 - '@types/node@25.0.10': + '@types/node@25.2.0': dependencies: undici-types: 7.16.0 - '@types/react-dom@19.2.3(@types/react@19.2.9)': + '@types/react-dom@19.2.3(@types/react@19.2.11)': dependencies: - '@types/react': 19.2.9 + '@types/react': 19.2.11 - '@types/react@19.2.9': + '@types/react@19.2.11': dependencies: csstype: 3.2.3 @@ -6561,12 +7654,12 @@ snapshots: '@types/ws@7.4.7': dependencies: - '@types/node': 25.0.10 + '@types/node': 25.2.0 optional: true '@types/ws@8.18.1': dependencies: - '@types/node': 25.0.10 + '@types/node': 25.2.0 optional: true '@vite-pwa/assets-generator@1.0.2': @@ -6578,41 +7671,41 @@ snapshots: sharp-ico: 0.1.5 unconfig: 7.4.2 - '@vitejs/plugin-react@5.1.2(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))': + '@vitejs/plugin-react@5.1.3(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))': dependencies: - '@babel/core': 7.28.5 - '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.28.5) - '@rolldown/pluginutils': 1.0.0-beta.53 + '@babel/core': 7.29.0 + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.29.0) + '@rolldown/pluginutils': 1.0.0-rc.2 '@types/babel__core': 7.20.5 react-refresh: 0.18.0 - vite: 7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - supports-color - '@vitest/browser-playwright@4.0.18(bufferutil@4.1.0)(playwright@1.58.0)(utf-8-validate@5.0.10)(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18)': + '@vitest/browser-playwright@4.0.18(bufferutil@4.1.0)(playwright@1.58.0)(utf-8-validate@5.0.10)(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18)': dependencies: - '@vitest/browser': 4.0.18(bufferutil@4.1.0)(utf-8-validate@5.0.10)(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18) - '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) + '@vitest/browser': 4.0.18(bufferutil@4.1.0)(utf-8-validate@5.0.10)(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18) + '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) playwright: 1.58.0 tinyrainbow: 3.0.3 - vitest: 4.0.18(@types/node@25.0.10)(@vitest/browser-playwright@4.0.18)(jiti@2.6.1)(jsdom@27.4.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + vitest: 4.0.18(@types/node@25.2.0)(@vitest/browser-playwright@4.0.18)(jiti@2.6.1)(jsdom@28.0.0(@noble/hashes@1.8.0))(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - bufferutil - msw - utf-8-validate - vite - '@vitest/browser@4.0.18(bufferutil@4.1.0)(utf-8-validate@5.0.10)(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18)': + '@vitest/browser@4.0.18(bufferutil@4.1.0)(utf-8-validate@5.0.10)(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18)': dependencies: - '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) + '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) '@vitest/utils': 4.0.18 magic-string: 0.30.21 pixelmatch: 7.1.0 pngjs: 7.0.0 sirv: 3.0.2 tinyrainbow: 3.0.3 - vitest: 4.0.18(@types/node@25.0.10)(@vitest/browser-playwright@4.0.18)(jiti@2.6.1)(jsdom@27.4.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + vitest: 4.0.18(@types/node@25.2.0)(@vitest/browser-playwright@4.0.18)(jiti@2.6.1)(jsdom@28.0.0(@noble/hashes@1.8.0))(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) ws: 8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) transitivePeerDependencies: - bufferutil @@ -6629,13 +7722,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.0.3 - '@vitest/mocker@4.0.18(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))': + '@vitest/mocker@4.0.18(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@vitest/spy': 4.0.18 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) '@vitest/pretty-format@4.0.18': dependencies: @@ -6659,21 +7752,57 @@ snapshots: '@vitest/pretty-format': 4.0.18 tinyrainbow: 3.0.3 - '@wagmi/connectors@7.1.5(@safe-global/safe-apps-provider@0.18.6(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@wagmi/core@3.3.1(@tanstack/query-core@5.90.20)(@types/react@19.2.9)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(viem@2.45.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(typescript@5.9.3)(viem@2.45.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))': + '@wagmi/connectors@7.1.5(@safe-global/safe-apps-provider@0.18.6(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@wagmi/core@3.3.2(@tanstack/query-core@5.90.20)(@types/react@19.2.11)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.4))(viem@2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(typescript@5.9.3)(viem@2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))': + dependencies: + '@wagmi/core': 3.3.2(@tanstack/query-core@5.90.20)(@types/react@19.2.11)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.4))(viem@2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + viem: 2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + optionalDependencies: + '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + typescript: 5.9.3 + optional: true + + '@wagmi/connectors@7.1.5(@safe-global/safe-apps-provider@0.18.6(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@wagmi/core@3.3.2(@tanstack/query-core@5.90.20)(@types/react@19.2.11)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.2.4))(viem@2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(typescript@5.9.3)(viem@2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))': + dependencies: + '@wagmi/core': 3.3.2(@tanstack/query-core@5.90.20)(@types/react@19.2.11)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.2.4))(viem@2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + viem: 2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + optionalDependencies: + '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + typescript: 5.9.3 + optional: true + + '@wagmi/connectors@7.1.6(@safe-global/safe-apps-provider@0.18.6(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@wagmi/core@3.3.2(@tanstack/query-core@5.90.20)(@types/react@19.2.11)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.4))(viem@2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(typescript@5.9.3)(viem@2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))': dependencies: - '@wagmi/core': 3.3.1(@tanstack/query-core@5.90.20)(@types/react@19.2.9)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(viem@2.45.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) - viem: 2.45.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@wagmi/core': 3.3.2(@tanstack/query-core@5.90.20)(@types/react@19.2.11)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.4))(viem@2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + viem: 2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) optionalDependencies: '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) typescript: 5.9.3 - '@wagmi/core@3.3.1(@tanstack/query-core@5.90.20)(@types/react@19.2.9)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(viem@2.45.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))': + '@wagmi/core@3.3.2(@tanstack/query-core@5.90.20)(@types/react@19.2.11)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.4))(viem@2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))': + dependencies: + eventemitter3: 5.0.1 + mipd: 0.0.7(typescript@5.9.3) + viem: 2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + zustand: 5.0.0(@types/react@19.2.11)(react@19.2.4)(use-sync-external-store@1.4.0(react@19.2.4)) + optionalDependencies: + '@tanstack/query-core': 5.90.20 + ox: 0.11.3(typescript@5.9.3)(zod@3.25.76) + typescript: 5.9.3 + transitivePeerDependencies: + - '@types/react' + - immer + - react + - use-sync-external-store + + '@wagmi/core@3.3.2(@tanstack/query-core@5.90.20)(@types/react@19.2.11)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.2.4))(viem@2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))': dependencies: eventemitter3: 5.0.1 mipd: 0.0.7(typescript@5.9.3) - viem: 2.45.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) - zustand: 5.0.0(@types/react@19.2.9)(react@19.2.3)(use-sync-external-store@1.4.0(react@19.2.3)) + viem: 2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + zustand: 5.0.0(@types/react@19.2.11)(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4)) optionalDependencies: '@tanstack/query-core': 5.90.20 ox: 0.11.3(typescript@5.9.3)(zod@3.25.76) @@ -7019,6 +8148,13 @@ snapshots: humanize-ms: 1.2.1 optional: true + ajv@8.17.1: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.0 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + ansi-regex@5.0.1: {} ansi-styles@4.3.0: @@ -7034,10 +8170,14 @@ snapshots: normalize-path: 3.0.0 picomatch: 2.3.1 + argparse@2.0.1: {} + aria-query@5.3.0: dependencies: dequal: 2.0.3 + array-ify@1.0.0: {} + asn1.js@4.10.1: dependencies: bn.js: 4.12.2 @@ -7067,13 +8207,13 @@ snapshots: dependencies: possible-typed-array-names: 1.1.0 - axios-retry@4.5.0(axios@1.13.3): + axios-retry@4.5.0(axios@1.13.4): dependencies: - axios: 1.13.3 + axios: 1.13.4 is-retry-allowed: 2.2.0 optional: true - axios@1.13.3: + axios@1.13.4: dependencies: follow-redirects: 1.15.11 form-data: 4.0.5 @@ -7093,7 +8233,7 @@ snapshots: babel-plugin-react-compiler@1.0.0: dependencies: - '@babel/types': 7.28.5 + '@babel/types': 7.28.6 base-x@3.0.11: dependencies: @@ -7106,7 +8246,7 @@ snapshots: base64-js@1.5.1: {} - baseline-browser-mapping@2.9.11: {} + baseline-browser-mapping@2.9.19: {} bidi-js@1.0.3: dependencies: @@ -7187,9 +8327,9 @@ snapshots: browserslist@4.28.1: dependencies: - baseline-browser-mapping: 2.9.11 - caniuse-lite: 1.0.30001762 - electron-to-chromium: 1.5.267 + baseline-browser-mapping: 2.9.19 + caniuse-lite: 1.0.30001766 + electron-to-chromium: 1.5.283 node-releases: 2.0.27 update-browserslist-db: 1.2.3(browserslist@4.28.1) @@ -7245,9 +8385,11 @@ snapshots: call-bind-apply-helpers: 1.0.2 get-intrinsic: 1.3.0 + callsites@3.1.0: {} + camelcase@5.3.1: {} - caniuse-lite@1.0.30001762: {} + caniuse-lite@1.0.30001766: {} chai@6.2.2: {} @@ -7328,12 +8470,29 @@ snapshots: commander@2.20.3: optional: true + compare-func@2.0.0: + dependencies: + array-ify: 1.0.0 + dot-prop: 5.3.0 + consola@3.4.2: {} console-browserify@1.2.0: {} constants-browserify@1.0.0: {} + conventional-changelog-angular@8.1.0: + dependencies: + compare-func: 2.0.0 + + conventional-changelog-conventionalcommits@9.1.0: + dependencies: + compare-func: 2.0.0 + + conventional-commits-parser@6.2.1: + dependencies: + meow: 13.2.0 + convert-source-map@2.0.0: {} cookie-es@1.2.2: {} @@ -7342,6 +8501,22 @@ snapshots: core-util-is@1.0.3: {} + cosmiconfig-typescript-loader@6.2.0(@types/node@25.2.0)(cosmiconfig@9.0.0(typescript@5.9.3))(typescript@5.9.3): + dependencies: + '@types/node': 25.2.0 + cosmiconfig: 9.0.0(typescript@5.9.3) + jiti: 2.6.1 + typescript: 5.9.3 + + cosmiconfig@9.0.0(typescript@5.9.3): + dependencies: + env-paths: 2.2.1 + import-fresh: 3.3.1 + js-yaml: 4.1.1 + parse-json: 5.2.0 + optionalDependencies: + typescript: 5.9.3 + create-ecdh@4.0.4: dependencies: bn.js: 4.12.2 @@ -7402,16 +8577,20 @@ snapshots: cssstyle@5.3.7: dependencies: '@asamuzakjp/css-color': 4.1.1 - '@csstools/css-syntax-patches-for-csstree': 1.0.22 + '@csstools/css-syntax-patches-for-csstree': 1.0.26 css-tree: 3.1.0 - lru-cache: 11.2.4 + lru-cache: 11.2.5 csstype@3.2.3: {} - data-urls@6.0.0: + dargs@8.1.0: {} + + data-urls@7.0.0(@noble/hashes@1.8.0): dependencies: - whatwg-mimetype: 4.0.0 - whatwg-url: 15.1.0 + whatwg-mimetype: 5.0.0 + whatwg-url: 16.0.0(@noble/hashes@1.8.0) + transitivePeerDependencies: + - '@noble/hashes' dayjs@1.11.13: {} @@ -7481,18 +8660,22 @@ snapshots: domain-browser@4.22.0: {} + dot-prop@5.3.0: + dependencies: + is-obj: 2.0.0 + dunder-proto@1.0.1: dependencies: call-bind-apply-helpers: 1.0.2 es-errors: 1.3.0 gopd: 1.2.0 - effect@3.19.15: + effect@3.19.16: dependencies: '@standard-schema/spec': 1.1.0 fast-check: 3.23.2 - electron-to-chromium@1.5.267: {} + electron-to-chromium@1.5.283: {} elliptic@6.6.1: dependencies: @@ -7515,6 +8698,12 @@ snapshots: entities@6.0.1: {} + env-paths@2.2.1: {} + + error-ex@1.3.4: + dependencies: + is-arrayish: 0.2.1 + es-define-property@1.0.1: {} es-errors@1.3.0: {} @@ -7600,9 +8789,13 @@ snapshots: dependencies: pure-rand: 6.1.0 + fast-deep-equal@3.1.3: {} + fast-stable-stringify@1.0.0: optional: true + fast-uri@3.1.0: {} + fdir@6.5.0(picomatch@4.0.3): optionalDependencies: picomatch: 4.0.3 @@ -7675,10 +8868,20 @@ snapshots: dependencies: resolve-pkg-maps: 1.0.0 + git-raw-commits@4.0.0: + dependencies: + dargs: 8.1.0 + meow: 12.1.1 + split2: 4.2.0 + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 + global-directory@4.0.1: + dependencies: + ini: 4.1.1 + goober@2.1.18(csstype@3.2.3): dependencies: csstype: 3.2.3 @@ -7736,11 +8939,11 @@ snapshots: minimalistic-assert: 1.0.1 minimalistic-crypto-utils: 1.0.1 - html-encoding-sniffer@6.0.0: + html-encoding-sniffer@6.0.0(@noble/hashes@1.8.0): dependencies: - '@exodus/bytes': 1.8.0 + '@exodus/bytes': 1.11.0(@noble/hashes@1.8.0) transitivePeerDependencies: - - '@exodus/crypto' + - '@noble/hashes' http-proxy-agent@7.0.2: dependencies: @@ -7763,6 +8966,8 @@ snapshots: ms: 2.1.3 optional: true + husky@9.1.7: {} + ico-endec@0.1.6: {} idb-keyval@6.2.1: @@ -7772,8 +8977,17 @@ snapshots: ieee754@1.2.1: {} + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + import-meta-resolve@4.2.0: {} + inherits@2.0.4: {} + ini@4.1.1: {} + iron-webcrypto@1.2.1: {} is-arguments@1.2.0: @@ -7781,6 +8995,8 @@ snapshots: call-bound: 1.0.4 has-tostringtag: 1.0.2 + is-arrayish@0.2.1: {} + is-arrayish@0.3.4: {} is-binary-path@2.1.0: @@ -7819,6 +9035,10 @@ snapshots: is-number@7.0.0: {} + is-obj@2.0.0: {} + + is-plain-obj@4.1.0: {} + is-potential-custom-element-name@1.0.1: {} is-regex@1.2.1: @@ -7839,7 +9059,7 @@ snapshots: isarray@2.0.5: {} - isbot@5.1.33: {} + isbot@5.1.34: {} isomorphic-timers-promises@1.0.1: {} @@ -7878,15 +9098,19 @@ snapshots: js-tokens@4.0.0: {} - jsdom@27.4.0(bufferutil@4.1.0)(utf-8-validate@5.0.10): + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + + jsdom@28.0.0(@noble/hashes@1.8.0): dependencies: - '@acemir/cssom': 0.9.30 - '@asamuzakjp/dom-selector': 6.7.6 - '@exodus/bytes': 1.8.0 + '@acemir/cssom': 0.9.31 + '@asamuzakjp/dom-selector': 6.7.7 + '@exodus/bytes': 1.11.0(@noble/hashes@1.8.0) cssstyle: 5.3.7 - data-urls: 6.0.0 + data-urls: 7.0.0(@noble/hashes@1.8.0) decimal.js: 10.6.0 - html-encoding-sniffer: 6.0.0 + html-encoding-sniffer: 6.0.0(@noble/hashes@1.8.0) http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.6 is-potential-custom-element-name: 1.0.1 @@ -7894,20 +9118,22 @@ snapshots: saxes: 6.0.0 symbol-tree: 3.2.4 tough-cookie: 6.0.0 + undici: 7.20.0 w3c-xmlserializer: 5.0.0 webidl-conversions: 8.0.1 - whatwg-mimetype: 4.0.0 - whatwg-url: 15.1.0 - ws: 8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) + whatwg-mimetype: 5.0.0 + whatwg-url: 16.0.0(@noble/hashes@1.8.0) xml-name-validator: 5.0.0 transitivePeerDependencies: - - '@exodus/crypto' - - bufferutil + - '@noble/hashes' - supports-color - - utf-8-validate jsesc@3.1.0: {} + json-parse-even-better-errors@2.3.1: {} + + json-schema-traverse@1.0.0: {} + json-stringify-safe@5.0.1: optional: true @@ -7973,6 +9199,8 @@ snapshots: lightningcss-win32-arm64-msvc: 1.30.2 lightningcss-win32-x64-msvc: 1.30.2 + lines-and-columns@1.2.4: {} + lit-element@4.2.2: dependencies: '@lit-labs/ssr-dom-shim': 1.5.1 @@ -7997,17 +9225,29 @@ snapshots: dependencies: p-locate: 5.0.0 + lodash.camelcase@4.3.0: {} + lodash.clonedeep@4.5.0: {} - lru-cache@11.2.4: {} + lodash.kebabcase@4.1.1: {} + + lodash.mergewith@4.6.2: {} + + lodash.snakecase@4.1.1: {} + + lodash.startcase@4.4.0: {} + + lodash.upperfirst@4.3.1: {} + + lru-cache@11.2.5: {} lru-cache@5.1.1: dependencies: yallist: 3.1.1 - lucide-react@0.563.0(react@19.2.3): + lucide-react@0.563.0(react@19.2.4): dependencies: - react: 19.2.3 + react: 19.2.4 lz-string@1.5.0: {} @@ -8019,7 +9259,7 @@ snapshots: md5.js@1.3.5: dependencies: - hash-base: 3.0.5 + hash-base: 3.1.2 inherits: 2.0.4 safe-buffer: 5.2.1 @@ -8032,6 +9272,10 @@ snapshots: mdn-data@2.12.2: {} + meow@12.1.1: {} + + meow@13.2.0: {} + miller-rabin@4.0.1: dependencies: bn.js: 4.12.2 @@ -8051,6 +9295,8 @@ snapshots: minimalistic-crypto-utils@1.0.1: {} + minimist@1.2.8: {} + mipd@0.0.7(typescript@5.9.3): optionalDependencies: typescript: 5.9.3 @@ -8249,6 +9495,10 @@ snapshots: pako@1.0.11: {} + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + parse-asn1@5.1.9: dependencies: asn1.js: 4.10.1 @@ -8257,6 +9507,13 @@ snapshots: pbkdf2: 3.1.5 safe-buffer: 5.2.1 + parse-json@5.2.0: + dependencies: + '@babel/code-frame': 7.29.0 + error-ex: 1.3.4 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + parse5@8.0.0: dependencies: entities: 6.0.1 @@ -8397,16 +9654,16 @@ snapshots: randombytes: 2.1.0 safe-buffer: 5.2.1 - react-dom@19.2.3(react@19.2.3): + react-dom@19.2.4(react@19.2.4): dependencies: - react: 19.2.3 + react: 19.2.4 scheduler: 0.27.0 react-is@17.0.2: {} react-refresh@0.18.0: {} - react@19.2.3: {} + react@19.2.4: {} readable-stream@2.3.8: dependencies: @@ -8450,6 +9707,10 @@ snapshots: reselect@5.1.1: {} + resolve-from@4.0.0: {} + + resolve-from@5.0.0: {} + resolve-pkg-maps@1.0.0: {} resolve@1.22.11: @@ -8463,35 +9724,35 @@ snapshots: hash-base: 3.1.2 inherits: 2.0.4 - rollup@4.56.0: + rollup@4.57.1: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.56.0 - '@rollup/rollup-android-arm64': 4.56.0 - '@rollup/rollup-darwin-arm64': 4.56.0 - '@rollup/rollup-darwin-x64': 4.56.0 - '@rollup/rollup-freebsd-arm64': 4.56.0 - '@rollup/rollup-freebsd-x64': 4.56.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.56.0 - '@rollup/rollup-linux-arm-musleabihf': 4.56.0 - '@rollup/rollup-linux-arm64-gnu': 4.56.0 - '@rollup/rollup-linux-arm64-musl': 4.56.0 - '@rollup/rollup-linux-loong64-gnu': 4.56.0 - '@rollup/rollup-linux-loong64-musl': 4.56.0 - '@rollup/rollup-linux-ppc64-gnu': 4.56.0 - '@rollup/rollup-linux-ppc64-musl': 4.56.0 - '@rollup/rollup-linux-riscv64-gnu': 4.56.0 - '@rollup/rollup-linux-riscv64-musl': 4.56.0 - '@rollup/rollup-linux-s390x-gnu': 4.56.0 - '@rollup/rollup-linux-x64-gnu': 4.56.0 - '@rollup/rollup-linux-x64-musl': 4.56.0 - '@rollup/rollup-openbsd-x64': 4.56.0 - '@rollup/rollup-openharmony-arm64': 4.56.0 - '@rollup/rollup-win32-arm64-msvc': 4.56.0 - '@rollup/rollup-win32-ia32-msvc': 4.56.0 - '@rollup/rollup-win32-x64-gnu': 4.56.0 - '@rollup/rollup-win32-x64-msvc': 4.56.0 + '@rollup/rollup-android-arm-eabi': 4.57.1 + '@rollup/rollup-android-arm64': 4.57.1 + '@rollup/rollup-darwin-arm64': 4.57.1 + '@rollup/rollup-darwin-x64': 4.57.1 + '@rollup/rollup-freebsd-arm64': 4.57.1 + '@rollup/rollup-freebsd-x64': 4.57.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.57.1 + '@rollup/rollup-linux-arm-musleabihf': 4.57.1 + '@rollup/rollup-linux-arm64-gnu': 4.57.1 + '@rollup/rollup-linux-arm64-musl': 4.57.1 + '@rollup/rollup-linux-loong64-gnu': 4.57.1 + '@rollup/rollup-linux-loong64-musl': 4.57.1 + '@rollup/rollup-linux-ppc64-gnu': 4.57.1 + '@rollup/rollup-linux-ppc64-musl': 4.57.1 + '@rollup/rollup-linux-riscv64-gnu': 4.57.1 + '@rollup/rollup-linux-riscv64-musl': 4.57.1 + '@rollup/rollup-linux-s390x-gnu': 4.57.1 + '@rollup/rollup-linux-x64-gnu': 4.57.1 + '@rollup/rollup-linux-x64-musl': 4.57.1 + '@rollup/rollup-openbsd-x64': 4.57.1 + '@rollup/rollup-openharmony-arm64': 4.57.1 + '@rollup/rollup-win32-arm64-msvc': 4.57.1 + '@rollup/rollup-win32-ia32-msvc': 4.57.1 + '@rollup/rollup-win32-x64-gnu': 4.57.1 + '@rollup/rollup-win32-x64-msvc': 4.57.1 fsevents: 2.3.3 rpc-websockets@9.3.3: @@ -8536,16 +9797,10 @@ snapshots: semver@7.7.3: {} - seroval-plugins@1.3.3(seroval@1.3.2): - dependencies: - seroval: 1.3.2 - seroval-plugins@1.5.0(seroval@1.5.0): dependencies: seroval: 1.5.0 - seroval@1.3.2: {} - seroval@1.5.0: {} set-blocking@2.0.0: {} @@ -8643,20 +9898,20 @@ snapshots: slow-redact@0.3.2: {} - solid-js@1.9.10: + solid-js@1.9.11: dependencies: csstype: 3.2.3 - seroval: 1.3.2 - seroval-plugins: 1.3.3(seroval@1.3.2) + seroval: 1.5.0 + seroval-plugins: 1.5.0(seroval@1.5.0) sonic-boom@4.2.0: dependencies: atomic-sleep: 1.0.0 - sonner@2.0.7(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + sonner@2.0.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) source-map-js@1.2.1: {} @@ -8749,11 +10004,11 @@ snapshots: tinyrainbow@3.0.3: {} - tldts-core@7.0.19: {} + tldts-core@7.0.22: {} - tldts@7.0.19: + tldts@7.0.22: dependencies: - tldts-core: 7.0.19 + tldts-core: 7.0.22 to-buffer@1.2.2: dependencies: @@ -8771,7 +10026,7 @@ snapshots: tough-cookie@6.0.0: dependencies: - tldts: 7.0.19 + tldts: 7.0.22 tr46@0.0.3: {} @@ -8792,6 +10047,33 @@ snapshots: tty-browserify@0.0.1: {} + turbo-darwin-64@2.8.3: + optional: true + + turbo-darwin-arm64@2.8.3: + optional: true + + turbo-linux-64@2.8.3: + optional: true + + turbo-linux-arm64@2.8.3: + optional: true + + turbo-windows-64@2.8.3: + optional: true + + turbo-windows-arm64@2.8.3: + optional: true + + turbo@2.8.3: + optionalDependencies: + turbo-darwin-64: 2.8.3 + turbo-darwin-arm64: 2.8.3 + turbo-linux-64: 2.8.3 + turbo-linux-arm64: 2.8.3 + turbo-windows-64: 2.8.3 + turbo-windows-arm64: 2.8.3 + tw-animate-css@1.4.0: {} tweetnacl@1.0.3: {} @@ -8829,10 +10111,12 @@ snapshots: undici-types@7.16.0: {} - undici-types@7.19.1: + undici-types@7.19.2: optional: true - undici@7.19.1: {} + undici@7.19.2: {} + + undici@7.20.0: {} unplugin@2.3.11: dependencies: @@ -8847,7 +10131,7 @@ snapshots: chokidar: 5.0.0 destr: 2.0.5 h3: 1.15.5 - lru-cache: 11.2.4 + lru-cache: 11.2.5 node-fetch-native: 1.6.7 ofetch: 1.5.1 ufo: 1.6.3 @@ -8865,13 +10149,13 @@ snapshots: punycode: 1.4.1 qs: 6.14.1 - use-sync-external-store@1.4.0(react@19.2.3): + use-sync-external-store@1.4.0(react@19.2.4): dependencies: - react: 19.2.3 + react: 19.2.4 - use-sync-external-store@1.6.0(react@19.2.3): + use-sync-external-store@1.6.0(react@19.2.4): dependencies: - react: 19.2.3 + react: 19.2.4 utf-8-validate@5.0.10: dependencies: @@ -8895,14 +10179,14 @@ snapshots: uuid@9.0.1: {} - valtio@2.1.7(@types/react@19.2.9)(react@19.2.3): + valtio@2.1.7(@types/react@19.2.11)(react@19.2.4): dependencies: proxy-compare: 3.0.1 optionalDependencies: - '@types/react': 19.2.9 - react: 19.2.3 + '@types/react': 19.2.11 + react: 19.2.4 - viem@2.45.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.22.4): + viem@2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.22.4): dependencies: '@noble/curves': 1.9.1 '@noble/hashes': 1.8.0 @@ -8919,7 +10203,7 @@ snapshots: - utf-8-validate - zod - viem@2.45.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76): + viem@2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76): dependencies: '@noble/curves': 1.9.1 '@noble/hashes': 1.8.0 @@ -8936,43 +10220,43 @@ snapshots: - utf-8-validate - zod - vite-plugin-node-polyfills@0.25.0(rollup@4.56.0)(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)): + vite-plugin-node-polyfills@0.25.0(rollup@4.57.1)(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)): dependencies: - '@rollup/plugin-inject': 5.0.5(rollup@4.56.0) + '@rollup/plugin-inject': 5.0.5(rollup@4.57.1) node-stdlib-browser: 1.3.1 - vite: 7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - rollup - vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2): + vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2): dependencies: esbuild: 0.27.2 fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6 - rollup: 4.56.0 + rollup: 4.57.1 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 25.0.10 + '@types/node': 25.2.0 fsevents: 2.3.3 jiti: 2.6.1 lightningcss: 1.30.2 tsx: 4.21.0 yaml: 2.8.2 - vitest-browser-react@2.0.4(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vitest@4.0.18): + vitest-browser-react@2.0.5(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@4.0.18): dependencies: - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - vitest: 4.0.18(@types/node@25.0.10)(@vitest/browser-playwright@4.0.18)(jiti@2.6.1)(jsdom@27.4.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + vitest: 4.0.18(@types/node@25.2.0)(@vitest/browser-playwright@4.0.18)(jiti@2.6.1)(jsdom@28.0.0(@noble/hashes@1.8.0))(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) optionalDependencies: - '@types/react': 19.2.9 - '@types/react-dom': 19.2.3(@types/react@19.2.9) + '@types/react': 19.2.11 + '@types/react-dom': 19.2.3(@types/react@19.2.11) - vitest@4.0.18(@types/node@25.0.10)(@vitest/browser-playwright@4.0.18)(jiti@2.6.1)(jsdom@27.4.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2): + vitest@4.0.18(@types/node@25.2.0)(@vitest/browser-playwright@4.0.18)(jiti@2.6.1)(jsdom@28.0.0(@noble/hashes@1.8.0))(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2): dependencies: '@vitest/expect': 4.0.18 - '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) + '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) '@vitest/pretty-format': 4.0.18 '@vitest/runner': 4.0.18 '@vitest/snapshot': 4.0.18 @@ -8989,12 +10273,12 @@ snapshots: tinyexec: 1.0.2 tinyglobby: 0.2.15 tinyrainbow: 3.0.3 - vite: 7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 25.0.10 - '@vitest/browser-playwright': 4.0.18(bufferutil@4.1.0)(playwright@1.58.0)(utf-8-validate@5.0.10)(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18) - jsdom: 27.4.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) + '@types/node': 25.2.0 + '@vitest/browser-playwright': 4.0.18(bufferutil@4.1.0)(playwright@1.58.0)(utf-8-validate@5.0.10)(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18) + jsdom: 28.0.0(@noble/hashes@1.8.0) transitivePeerDependencies: - jiti - less @@ -9014,14 +10298,14 @@ snapshots: dependencies: xml-name-validator: 5.0.0 - wagmi@3.4.1(@safe-global/safe-apps-provider@0.18.6(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.20(react@19.2.3))(@types/react@19.2.9)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.2.3)(typescript@5.9.3)(viem@2.45.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)): + wagmi@3.4.2(@safe-global/safe-apps-provider@0.18.6(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.20(react@19.2.4))(@types/react@19.2.11)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.2.4)(typescript@5.9.3)(viem@2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)): dependencies: - '@tanstack/react-query': 5.90.20(react@19.2.3) - '@wagmi/connectors': 7.1.5(@safe-global/safe-apps-provider@0.18.6(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@wagmi/core@3.3.1(@tanstack/query-core@5.90.20)(@types/react@19.2.9)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(viem@2.45.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(typescript@5.9.3)(viem@2.45.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) - '@wagmi/core': 3.3.1(@tanstack/query-core@5.90.20)(@types/react@19.2.9)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(viem@2.45.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) - react: 19.2.3 - use-sync-external-store: 1.4.0(react@19.2.3) - viem: 2.45.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@tanstack/react-query': 5.90.20(react@19.2.4) + '@wagmi/connectors': 7.1.6(@safe-global/safe-apps-provider@0.18.6(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@wagmi/core@3.3.2(@tanstack/query-core@5.90.20)(@types/react@19.2.11)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.4))(viem@2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(typescript@5.9.3)(viem@2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@wagmi/core': 3.3.2(@tanstack/query-core@5.90.20)(@types/react@19.2.11)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.2.4)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.4))(viem@2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + react: 19.2.4 + use-sync-external-store: 1.4.0(react@19.2.4) + viem: 2.45.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: @@ -9044,12 +10328,15 @@ snapshots: webpack-virtual-modules@0.6.2: {} - whatwg-mimetype@4.0.0: {} + whatwg-mimetype@5.0.0: {} - whatwg-url@15.1.0: + whatwg-url@16.0.0(@noble/hashes@1.8.0): dependencies: + '@exodus/bytes': 1.11.0(@noble/hashes@1.8.0) tr46: 6.0.0 webidl-conversions: 8.0.1 + transitivePeerDependencies: + - '@noble/hashes' whatwg-url@5.0.0: dependencies: @@ -9153,15 +10440,28 @@ snapshots: zod@3.25.76: {} - zustand@5.0.0(@types/react@19.2.9)(react@19.2.3)(use-sync-external-store@1.4.0(react@19.2.3)): + zustand@5.0.0(@types/react@19.2.11)(react@19.2.4)(use-sync-external-store@1.4.0(react@19.2.4)): + optionalDependencies: + '@types/react': 19.2.11 + react: 19.2.4 + use-sync-external-store: 1.4.0(react@19.2.4) + + zustand@5.0.0(@types/react@19.2.11)(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4)): + optionalDependencies: + '@types/react': 19.2.11 + react: 19.2.4 + use-sync-external-store: 1.6.0(react@19.2.4) + + zustand@5.0.3(@types/react@19.2.11)(react@19.2.4)(use-sync-external-store@1.4.0(react@19.2.4)): optionalDependencies: - '@types/react': 19.2.9 - react: 19.2.3 - use-sync-external-store: 1.4.0(react@19.2.3) + '@types/react': 19.2.11 + react: 19.2.4 + use-sync-external-store: 1.4.0(react@19.2.4) + optional: true - zustand@5.0.3(@types/react@19.2.9)(react@19.2.3)(use-sync-external-store@1.4.0(react@19.2.3)): + zustand@5.0.3(@types/react@19.2.11)(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4)): optionalDependencies: - '@types/react': 19.2.9 - react: 19.2.3 - use-sync-external-store: 1.4.0(react@19.2.3) + '@types/react': 19.2.11 + react: 19.2.4 + use-sync-external-store: 1.6.0(react@19.2.4) optional: true diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 08ba5d2..64562b7 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,5 +1,65 @@ packages: - - "!opensrc/**" + - packages/* + - apps/* + +catalog: + '@base-ui/react': ^1.1.0 + '@biomejs/biome': ^2.3.14 + '@commitlint/cli': ^20.4.1 + '@commitlint/config-conventional': ^20.4.1 + '@effect-atom/atom-react': ^0.5.0 + '@effect/experimental': ^0.58.0 + '@effect/language-service': ^0.73.0 + '@effect/platform': ^0.94.3 + '@effect/platform-node': ^0.104.1 + '@ledgerhq/wallet-api-client': ^1.12.6 + '@lucas-barake/effect-form-react': ^0.18.0 + '@reown/appkit': ^1.8.17 + '@reown/appkit-adapter-wagmi': ^1.8.17 + '@stakekit/common': ^0.0.61 + '@tailwindcss/vite': ^4.0.6 + '@tanstack/devtools-vite': ^0.5.0 + '@tanstack/react-devtools': ^0.9.4 + '@tanstack/react-query': ^5.90.20 + '@tanstack/react-router': ^1.158.0 + '@tanstack/react-router-devtools': ^1.158.0 + '@tanstack/react-virtual': ^3.13.18 + '@tanstack/router-cli': ^1.158.0 + '@tanstack/router-plugin': ^1.157.8 + '@testing-library/dom': ^10.4.0 + '@testing-library/react': ^16.3.2 + '@tim-smart/openapi-gen': ^0.4.13 + '@types/node': ^25.2.0 + '@types/react': ^19.2.11 + '@types/react-dom': ^19.2.0 + '@vite-pwa/assets-generator': ^1.0.2 + '@vitejs/plugin-react': ^5.1.3 + '@vitest/browser-playwright': ^4.0.18 + babel-plugin-react-compiler: ^1.0.0 + class-variance-authority: ^0.7.1 + clsx: ^2.1.1 + effect: ^3.19.16 + husky: ^9.1.7 + jsdom: ^28.0.0 + lucide-react: ^0.563.0 + openapi-filter: ^3.2.3 + react: ^19.2.0 + react-dom: ^19.2.0 + sonner: ^2.0.7 + tailwind-merge: ^3.0.2 + tailwindcss: ^4.0.6 + tsx: ^4.21.0 + turbo: ^2.8.3 + tw-animate-css: ^1.3.6 + typescript: ^5.7.2 + viem: ^2.45.0 + vite: ^7.3.1 + vite-plugin-node-polyfills: ^0.25.0 + vitest: ^4.0.18 + vitest-browser-react: ^2.0.4 + wagmi: ^3.4.2 + +nodeLinker: hoisted patchedDependencies: '@tim-smart/openapi-gen': patches/@tim-smart__openapi-gen.patch diff --git a/src/atoms/config-atom.ts b/src/atoms/config-atom.ts deleted file mode 100644 index 175585f..0000000 --- a/src/atoms/config-atom.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Effect } from "effect"; -import { ConfigService } from "@/services/config"; -import { runtimeAtom } from "@/services/runtime"; - -export const configAtom = runtimeAtom.atom( - Effect.gen(function* () { - const config = yield* ConfigService; - - return config; - }), -); diff --git a/src/components/modules/Account/Withdraw/state.tsx b/src/components/modules/Account/Withdraw/state.tsx deleted file mode 100644 index 1ff5fa1..0000000 --- a/src/components/modules/Account/Withdraw/state.tsx +++ /dev/null @@ -1,202 +0,0 @@ -import { - Atom, - Registry, - Result, - useAtomSet, - useAtomValue, -} from "@effect-atom/atom-react"; -import { FormBuilder, FormReact } from "@lucas-barake/effect-form-react"; -import { - Array as _Array, - Number as _Number, - Effect, - Option, - Schema, -} from "effect"; -import { actionAtom } from "@/atoms/actions-atoms"; -import { selectedProviderBalancesAtom } from "@/atoms/portfolio-atoms"; -import { providersAtom } from "@/atoms/providers-atoms"; -import { walletAtom } from "@/atoms/wallet-atom"; -import { AmountField } from "@/components/molecules/forms"; -import { isWalletConnected, type WalletConnected } from "@/domain/wallet"; -import { truncateNumber } from "@/lib/utils"; -import { ApiClientService } from "@/services/api-client"; -import type { ProviderDto } from "@/services/api-client/api-schemas"; -import { runtimeAtom } from "@/services/runtime"; - -const selectedProviderAtom = Atom.writable( - (ctx) => - ctx - .get(providersAtom) - .pipe(Result.map(_Array.head), Result.map(Option.getOrNull)), - (ctx, value: ProviderDto) => ctx.setSelf(Result.success(value)), -); - -export const useProviders = () => { - const providers = useAtomValue(providersAtom).pipe( - Result.getOrElse(() => null), - ); - - return { - providers, - }; -}; - -export const useSelectedProvider = () => { - const selectedProvider = useAtomValue(selectedProviderAtom).pipe( - Result.getOrElse(() => null), - ); - const setSelectedProvider = useAtomSet(selectedProviderAtom); - - return { - selectedProvider, - setSelectedProvider, - }; -}; - -export const useProviderBalance = (wallet: WalletConnected) => { - const providerBalance = useAtomValue( - selectedProviderBalancesAtom(wallet.currentAccount.address), - ).pipe(Result.getOrElse(() => null)); - - return { - providerBalance, - }; -}; - -export const useWithdrawForm = () => { - const submit = useAtomSet(WithdrawForm.submit); - const submitResult = useAtomValue(WithdrawForm.submit); - - return { - submit, - submitResult, - }; -}; - -export const withdrawFormBuilder = FormBuilder.empty - .addField( - "Amount", - Schema.NumberFromString.pipe( - Schema.annotations({ message: () => "Invalid amount" }), - Schema.greaterThan(0, { message: () => "Must be greater than 0" }), - ), - ) - .refineEffect((values) => - Effect.gen(function* () { - const registry = yield* Registry.AtomRegistry; - const wallet = registry - .get(walletAtom) - .pipe(Result.getOrElse(() => null)); - - if (!isWalletConnected(wallet)) { - return yield* Effect.dieMessage("No wallet"); - } - - const providerBalance = registry - .get(selectedProviderBalancesAtom(wallet.currentAccount.address)) - .pipe(Result.getOrElse(() => null)); - - if (!providerBalance) { - return { path: ["Amount"], message: "Missing provider balance" }; - } - - if (providerBalance.availableBalance <= 0) { - return { - path: ["Amount"], - message: "No available balance to withdraw", - }; - } - - if (values.Amount > providerBalance.availableBalance) { - return { - path: ["Amount"], - message: "Insufficient balance", - }; - } - }), - ); - -export const WithdrawForm = FormReact.make(withdrawFormBuilder, { - runtime: runtimeAtom, - fields: { Amount: AmountField }, - onSubmit: ({ wallet }: { wallet: WalletConnected }, { decoded }) => - Effect.gen(function* () { - const client = yield* ApiClientService; - const registry = yield* Registry.AtomRegistry; - - const selectedProvider = registry - .get(selectedProviderAtom) - .pipe(Result.getOrElse(() => null)); - - if (!selectedProvider) { - return yield* Effect.dieMessage("No selected provider"); - } - - const providerBalance = registry - .get(selectedProviderBalancesAtom(wallet.currentAccount.address)) - .pipe(Result.getOrElse(() => null)); - - if (!providerBalance) { - return yield* Effect.dieMessage("No provider balance"); - } - - const action = yield* client.ActionsControllerExecuteAction({ - providerId: selectedProvider.id, - address: wallet.currentAccount.address, - action: "withdraw", - args: { - amount: decoded.Amount.toString(), - }, - }); - - registry.set(actionAtom, action); - }), -}); - -const setAmountFieldAtom = WithdrawForm.setValue(WithdrawForm.fields.Amount); -const amountFieldAtom = WithdrawForm.getFieldAtom(WithdrawForm.fields.Amount); - -export const useSetWithdrawAmount = () => { - const setAmount = useAtomSet(setAmountFieldAtom); - - return { - setAmount, - }; -}; - -export const useWithdrawPercentage = (wallet: WalletConnected) => { - const amount = useAtomValue(amountFieldAtom).pipe( - Option.map(Number), - Option.filter((v) => !Number.isNaN(v)), - Option.getOrElse(() => 0), - ); - - const setAmount = useAtomSet(setAmountFieldAtom); - - const availableBalance = useAtomValue( - selectedProviderBalancesAtom(wallet.currentAccount.address), - ).pipe( - Result.value, - Option.map((v) => v.availableBalance), - Option.getOrElse(() => 0), - ); - - const handlePercentageChange = (newPercentage: number) => { - if (newPercentage >= 100) { - return setAmount(availableBalance.toString()); - } - - const amount = (availableBalance * newPercentage) / 100; - setAmount(truncateNumber(amount, 6).toString()); - }; - - const percentage = _Number.clamp({ minimum: 0, maximum: 100 })( - (amount / availableBalance) * 100, - ); - - return { - percentage: Math.round(percentage), - handlePercentageChange, - }; -}; diff --git a/src/components/modules/Order/Overview/state.tsx b/src/components/modules/Order/Overview/state.tsx deleted file mode 100644 index 684147c..0000000 --- a/src/components/modules/Order/Overview/state.tsx +++ /dev/null @@ -1,363 +0,0 @@ -import { - Atom, - Registry, - Result, - useAtomSet, - useAtomValue, -} from "@effect-atom/atom-react"; -import { FormBuilder, FormReact } from "@lucas-barake/effect-form-react"; -import { Number as _Number, Effect, Option, Schema } from "effect"; -import { actionAtom } from "@/atoms/actions-atoms"; -import { selectedProviderBalancesAtom } from "@/atoms/portfolio-atoms"; -import { selectedProviderAtom } from "@/atoms/providers-atoms"; -import { walletAtom } from "@/atoms/wallet-atom"; -import { AmountField } from "@/components/molecules/forms"; -import type { TPOrSLSettings } from "@/components/molecules/tp-sl-dialog"; -import { getMaxLeverage } from "@/domain/market"; -import { - calculateMargin, - getLiquidationPrice, - MIN_LEVERAGE, -} from "@/domain/position"; -import { isWalletConnected, type WalletConnected } from "@/domain/wallet"; -import { truncateNumber } from "@/lib/utils"; -import { ApiClientService } from "@/services/api-client"; -import { - type ArgumentsDto, - MarketDto, -} from "@/services/api-client/api-schemas"; -import type { PositionDtoSide } from "@/services/api-client/client-factory"; -import { runtimeAtom } from "@/services/runtime"; - -export type OrderType = "market" | "limit"; - -export const SLIDER_STOPS = [0, 25, 50, 75, 100]; - -const orderTypeAtom = Atom.writable( - () => "market", - (ctx, value) => ctx.setSelf(value), -); - -export const LeverageRangesSchema = Schema.Data( - MarketDto.fields.leverageRange, -).pipe(Schema.brand("LeverageRange")); - -const leverageAtom = Atom.family( - (leverageRanges: typeof LeverageRangesSchema.Type) => - Atom.writable( - () => getMaxLeverage(leverageRanges), - (ctx, value: number) => - ctx.setSelf( - _Number.clamp({ - minimum: MIN_LEVERAGE, - maximum: getMaxLeverage(leverageRanges), - })(value), - ), - ), -); - -const tpOrSLSettingsAtom = Atom.writable( - () => ({ - takeProfit: { - option: null, - triggerPrice: null, - percentage: null, - }, - stopLoss: { - option: null, - triggerPrice: null, - percentage: null, - }, - }), - (ctx, value) => ctx.setSelf(value), -); - -const limitPriceAtom = Atom.writable( - () => null, - (ctx, value) => ctx.setSelf(value), -); - -export const useOrderType = () => { - const orderType = useAtomValue(orderTypeAtom); - const setOrderType = useAtomSet(orderTypeAtom); - - return { - orderType, - setOrderType, - }; -}; - -export const useLeverage = ( - leverageRanges: typeof LeverageRangesSchema.Type, -) => { - const leverage = useAtomValue(leverageAtom(leverageRanges)); - const setLeverage = useAtomSet(leverageAtom(leverageRanges)); - - return { - leverage, - setLeverage, - }; -}; - -export const useTPOrSLSettings = () => { - const tpOrSLSettings = useAtomValue(tpOrSLSettingsAtom); - const setTPOrSLSettings = useAtomSet(tpOrSLSettingsAtom); - - return { - tpOrSLSettings, - setTPOrSLSettings, - }; -}; - -export const useLimitPrice = () => { - const limitPrice = useAtomValue(limitPriceAtom); - const setLimitPrice = useAtomSet(limitPriceAtom); - - return { - limitPrice, - setLimitPrice, - }; -}; - -export const useProviderBalance = (wallet: WalletConnected) => { - const providerBalance = useAtomValue( - selectedProviderBalancesAtom(wallet.currentAccount.address), - ).pipe(Result.getOrElse(() => null)); - - return { - providerBalance, - }; -}; - -export const formAtom = Atom.family( - (leverageRanges: typeof LeverageRangesSchema.Type) => { - const orderFormBuilder = FormBuilder.empty - .addField( - "Amount", - Schema.NumberFromString.pipe( - Schema.annotations({ message: () => "Invalid amount" }), - Schema.greaterThan(0, { message: () => "Must be greater than 0" }), - ), - ) - .refineEffect((values) => - Effect.gen(function* () { - const registry = yield* Registry.AtomRegistry; - const wallet = registry - .get(walletAtom) - .pipe(Result.getOrElse(() => null)); - - if (!isWalletConnected(wallet)) { - return yield* Effect.dieMessage("No wallet"); - } - - const providerBalance = registry - .get(selectedProviderBalancesAtom(wallet.currentAccount.address)) - .pipe(Result.getOrElse(() => null)); - - if (!providerBalance) { - return { path: ["Amount"], message: "Missing provider balance" }; - } - - const leverage = registry.get(leverageAtom(leverageRanges)); - const requiredMargin = calculateMargin({ - positionSize: values.Amount, - leverage, - }); - - if (requiredMargin > providerBalance.availableBalance) { - return { - path: ["Amount"], - message: "Insufficient balance", - }; - } - }), - ); - - const OrderForm = FormReact.make(orderFormBuilder, { - runtime: runtimeAtom, - fields: { Amount: AmountField }, - onSubmit: ( - { - wallet, - market, - side, - }: { - wallet: WalletConnected; - market: MarketDto; - side: PositionDtoSide; - }, - { decoded }, - ) => - Effect.gen(function* () { - const client = yield* ApiClientService; - const registry = yield* Registry.AtomRegistry; - - const selectedProvider = registry - .get(selectedProviderAtom) - .pipe(Result.getOrElse(() => null)); - - if (!selectedProvider) { - return yield* Effect.dieMessage("No selected provider"); - } - - const leverage = registry.get(leverageAtom(leverageRanges)); - const orderType = registry.get(orderTypeAtom); - const tpOrSLSettings = registry.get(tpOrSLSettingsAtom); - - const stopLossPrice: ArgumentsDto["stopLossPrice"] = - tpOrSLSettings.stopLoss.triggerPrice && - tpOrSLSettings.stopLoss.option !== null - ? tpOrSLSettings.stopLoss.triggerPrice - : undefined; - - const takeProfitPrice: ArgumentsDto["takeProfitPrice"] = - tpOrSLSettings.takeProfit.triggerPrice && - tpOrSLSettings.takeProfit.option !== null - ? tpOrSLSettings.takeProfit.triggerPrice - : undefined; - - const limitPrice = - orderType === "limit" ? registry.get(limitPriceAtom) : undefined; - - const action = yield* client.ActionsControllerExecuteAction({ - providerId: selectedProvider.id, - address: wallet.currentAccount.address, - action: "open", - args: { - marketId: market.id, - side, - size: decoded.Amount.toString(), - marginMode: "isolated", - ...(stopLossPrice && { stopLossPrice }), - ...(takeProfitPrice && { takeProfitPrice }), - ...(leverage && { leverage }), - ...(limitPrice && { limitPrice: limitPrice }), - }, - }); - - registry.set(actionAtom, action); - }), - }); - - const useOrderForm = () => { - const submit = useAtomSet(OrderForm.submit); - const submitResult = useAtomValue(OrderForm.submit); - - return { - submit, - submitResult, - }; - }; - - const setAmountFieldAtom = OrderForm.setValue(OrderForm.fields.Amount); - const amountFieldAtom = OrderForm.getFieldAtom(OrderForm.fields.Amount); - - const useHandlePercentageChange = (wallet: WalletConnected) => { - const setAmount = useAtomSet(setAmountFieldAtom); - const { providerBalance } = useProviderBalance(wallet); - const { leverage } = useLeverage(leverageRanges); - - return { - handlePercentageChange: (value: number) => { - if (!providerBalance) return; - - const clampedValue = _Number.clamp({ minimum: 0, maximum: 100 })( - value, - ); - - const marginToUse = - (clampedValue / 100) * providerBalance.availableBalance; - const positionSize = marginToUse * leverage; - - setAmount(truncateNumber(positionSize).toString()); - }, - }; - }; - - const useOrderAmount = () => { - const amount = useAtomValue(amountFieldAtom).pipe( - Option.map(Number), - Option.filter((v) => !Number.isNaN(v)), - Option.getOrElse(() => 0), - ); - - return { amount }; - }; - - const useOrderPercentage = ( - wallet: WalletConnected, - leverageRanges: typeof LeverageRangesSchema.Type, - ) => { - const amount = useAtomValue(amountFieldAtom).pipe( - Option.map(Number), - Option.filter((v) => !Number.isNaN(v)), - Option.getOrElse(() => 0), - ); - - const { leverage } = useLeverage(leverageRanges); - - const providerBalance = useAtomValue( - selectedProviderBalancesAtom(wallet.currentAccount.address), - ).pipe(Result.getOrElse(() => null)); - - if (!providerBalance) { - return { - percentage: 0, - }; - } - - const margin = calculateMargin({ positionSize: amount, leverage }); - const percentage = - Math.min( - 100, - Math.max(0, (margin / providerBalance.availableBalance) * 100), - ) || 0; - - return { - percentage: Math.round(percentage), - }; - }; - - const useOrderCalculations = (market: MarketDto, side: PositionDtoSide) => { - const { amount } = useOrderAmount(); - const { leverage } = useLeverage( - Schema.decodeSync(LeverageRangesSchema)(market.leverageRange), - ); - - const cryptoAmount = amount / market.markPrice; - - const liquidationPrice = getLiquidationPrice({ - currentPrice: market.markPrice, - leverage, - side, - }); - - const margin = calculateMargin({ positionSize: amount, leverage }); - - const feeRate = market.takerFee ? Number.parseFloat(market.takerFee) : 0; - const fees = amount * feeRate; - - return { - margin, - amount, - cryptoAmount, - liquidationPrice, - fees, - leverage, - }; - }; - - const hooks = { - useOrderForm, - useOrderAmount, - useOrderPercentage, - useOrderCalculations, - useHandlePercentageChange, - }; - - return Atom.readable(() => ({ - hooks, - form: OrderForm, - })); - }, -); diff --git a/src/components/modules/Order/Overview/utils.ts b/src/components/modules/Order/Overview/utils.ts deleted file mode 100644 index 40534f7..0000000 --- a/src/components/modules/Order/Overview/utils.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Option } from "effect"; -import type { TPOrSLSettings } from "@/components/molecules/tp-sl-dialog"; - -export function formatTPOrSLSettings( - settings: TPOrSLSettings, - side: "long" | "short" = "long", -): string { - const tp = Option.fromNullable(settings.takeProfit.percentage).pipe( - Option.filter((percentage) => percentage !== 0), - Option.map((percentage) => - side === "short" ? `TP -${percentage}%` : `TP +${percentage}%`, - ), - Option.getOrElse(() => "TP Off"), - ); - - const sl = Option.fromNullable(settings.stopLoss.percentage).pipe( - Option.filter((percentage) => percentage !== 0), - Option.map((percentage) => - side === "short" ? `SL +${percentage}%` : `SL -${percentage}%`, - ), - Option.getOrElse(() => "SL Off"), - ); - - return `${tp}, ${sl}`; -} diff --git a/src/components/modules/PositionDetails/Close/state.tsx b/src/components/modules/PositionDetails/Close/state.tsx deleted file mode 100644 index 263723b..0000000 --- a/src/components/modules/PositionDetails/Close/state.tsx +++ /dev/null @@ -1,115 +0,0 @@ -import { - Atom, - Registry, - Result, - useAtomSet, - useAtomValue, -} from "@effect-atom/atom-react"; -import { Number as _Number, Data, Effect } from "effect"; -import { actionAtom } from "@/atoms/actions-atoms"; -import { positionsAtom } from "@/atoms/portfolio-atoms"; -import { selectedProviderAtom } from "@/atoms/providers-atoms"; -import { getCloseCalculations } from "@/domain/position"; -import type { WalletAccount, WalletConnected } from "@/domain/wallet"; -import { ApiClientService } from "@/services/api-client"; -import type { PositionDto } from "@/services/api-client/client-factory"; -import { runtimeAtom } from "@/services/runtime"; - -export const SLIDER_STOPS = [0, 25, 50, 75, 100]; - -const closePercentageAtom = Atom.writable( - () => 25, - (ctx, value) => - ctx.setSelf(_Number.clamp({ minimum: 0, maximum: 100 })(value)), -); - -export const useClosePercentage = () => { - const closePercentage = useAtomValue(closePercentageAtom); - const setClosePercentage = useAtomSet(closePercentageAtom); - - return { - closePercentage, - setClosePercentage, - }; -}; - -const closePositionAtom = Atom.family( - (args: { walletAddress: WalletAccount["address"]; marketId: string }) => - runtimeAtom.atom( - Effect.fn(function* (ctx) { - const positions = yield* ctx.result(positionsAtom(args.walletAddress)); - - const position = positions.find((p) => p.marketId === args.marketId); - - if (!position) { - return yield* Effect.dieMessage("Position not found"); - } - - return position; - }), - ), -); - -export const usePosition = ( - walletAddress: WalletAccount["address"], - marketId: string, -) => { - return useAtomValue( - closePositionAtom(Data.struct({ walletAddress, marketId })), - ); -}; - -export const useCloseCalculations = (position: PositionDto) => { - const { closePercentage } = useClosePercentage(); - - return getCloseCalculations(position, closePercentage); -}; - -const submitCloseAtom = runtimeAtom.fn( - Effect.fn(function* (args: { - position: PositionDto; - wallet: WalletConnected; - }) { - const client = yield* ApiClientService; - const registry = yield* Registry.AtomRegistry; - - const selectedProvider = registry - .get(selectedProviderAtom) - .pipe(Result.getOrElse(() => null)); - - if (!selectedProvider) { - return yield* Effect.dieMessage("No selected provider"); - } - - const closePercentage = registry.get(closePercentageAtom); - const closeCalculations = - closePercentage === 100 - ? null - : getCloseCalculations(args.position, closePercentage); - - const action = yield* client.ActionsControllerExecuteAction({ - providerId: selectedProvider.id, - address: args.wallet.currentAccount.address, - action: "close", - args: { - marketId: args.position.marketId, - side: args.position.side, - ...(closeCalculations && { - size: closeCalculations.closeSizeInMarketPrice, - }), - }, - }); - - registry.set(actionAtom, action); - }), -); - -export const useSubmitClose = () => { - const submitResult = useAtomValue(submitCloseAtom); - const submitClose = useAtomSet(submitCloseAtom); - - return { - submitResult, - submitClose, - }; -}; diff --git a/src/components/modules/PositionDetails/Overview/Position/state.ts b/src/components/modules/PositionDetails/Overview/Position/state.ts deleted file mode 100644 index 56f9d13..0000000 --- a/src/components/modules/PositionDetails/Overview/Position/state.ts +++ /dev/null @@ -1,98 +0,0 @@ -import { - Atom, - Registry, - Result, - useAtomSet, - useAtomValue, -} from "@effect-atom/atom-react"; -import { Effect } from "effect"; -import { actionAtom } from "@/atoms/actions-atoms"; -import { updateLeverageAtom } from "@/atoms/position-pending-actions-atom"; -import { selectedProviderAtom } from "@/atoms/providers-atoms"; -import type { - TPOrSLOption, - TPOrSLSettings, -} from "@/components/molecules/tp-sl-dialog"; -import type { WalletConnected } from "@/domain/wallet"; -import { ApiClientService } from "@/services/api-client"; -import type { - ArgumentsDto, - PositionDto, -} from "@/services/api-client/api-schemas"; -import { runtimeAtom } from "@/services/runtime"; - -const editSLTPAtom = Atom.family((actionType: TPOrSLOption) => - runtimeAtom.fn( - Effect.fn(function* ({ - position, - wallet, - tpOrSLSettings, - }: { - position: PositionDto; - wallet: WalletConnected; - tpOrSLSettings: TPOrSLSettings; - }) { - const client = yield* ApiClientService; - const registry = yield* Registry.AtomRegistry; - - const selectedProvider = registry - .get(selectedProviderAtom) - .pipe(Result.getOrElse(() => null)); - - if (!selectedProvider) { - return yield* Effect.dieMessage("No selected provider"); - } - - const newStopLossPrice: ArgumentsDto["stopLossPrice"] = - tpOrSLSettings.stopLoss.triggerPrice && - tpOrSLSettings.stopLoss.option !== null - ? tpOrSLSettings.stopLoss.triggerPrice - : undefined; - - const newTakeProfitPrice: ArgumentsDto["takeProfitPrice"] = - tpOrSLSettings.takeProfit.triggerPrice && - tpOrSLSettings.takeProfit.option !== null - ? tpOrSLSettings.takeProfit.triggerPrice - : undefined; - - const action = yield* client.ActionsControllerExecuteAction({ - providerId: selectedProvider.id, - address: wallet.currentAccount.address, - action: actionType, - args: { - marketId: position.marketId, - ...(actionType === "stopLoss" - ? { stopLossPrice: newStopLossPrice } - : { takeProfitPrice: newTakeProfitPrice }), - }, - }); - - registry.set(actionAtom, action); - }), - ), -); - -export const useEditSLTP = () => { - const editTPResult = useAtomValue(editSLTPAtom("takeProfit")); - const editTP = useAtomSet(editSLTPAtom("takeProfit")); - - const editSLResult = useAtomValue(editSLTPAtom("stopLoss")); - const editSL = useAtomSet(editSLTPAtom("stopLoss")); - - return { - editTPResult, - editTP, - editSLResult, - editSL, - }; -}; - -export const useUpdateLeverage = () => { - const updateLeverageResult = useAtomValue(updateLeverageAtom); - const updateLeverage = useAtomSet(updateLeverageAtom); - - return { - updateLeverageResult, - updateLeverage, - }; -}; diff --git a/src/components/modules/PositionDetails/Overview/overview-tab-content.tsx b/src/components/modules/PositionDetails/Overview/overview-tab-content.tsx deleted file mode 100644 index 0b9dcf6..0000000 --- a/src/components/modules/PositionDetails/Overview/overview-tab-content.tsx +++ /dev/null @@ -1,101 +0,0 @@ -import { Card, CardSection } from "@/components/ui/card"; -import { formatAmount, formatRate } from "@/lib/utils"; -import type { MarketDto } from "@/services/api-client/client-factory"; - -function formatVolume(volume: number): string { - if (volume >= 1_000_000_000) { - return `$${(volume / 1_000_000_000).toFixed(2)}B`; - } - if (volume >= 1_000_000) { - return `$${(volume / 1_000_000).toFixed(2)}M`; - } - if (volume >= 1_000) { - return `$${(volume / 1_000).toFixed(2)}K`; - } - return formatAmount(volume); -} - -export function OverviewTabContent({ market }: { market: MarketDto }) { - const currentPrice = market.markPrice; - const priceChange24h = market.priceChange24h; - - const estimatedLow = currentPrice - Math.abs(priceChange24h); - const estimatedHigh = currentPrice + Math.abs(priceChange24h); - - return ( - - -
- - 24h low - - - {formatAmount(estimatedLow)} - -
-
- - 24h high - - - {formatAmount(estimatedHigh)} - -
-
- -
- - 24h volume - - - {formatVolume(market.volume24h)} - -
-
- - Open Interest - - - {formatVolume(market.openInterest)} - -
-
- -
- - Funding Rate - - - {formatRate(market.fundingRate, { maximumFractionDigits: 4 })} - -
-
- - Funding Interval - - - {market.fundingRateIntervalHours}h - -
-
- -
- - Maker Fee - - - {market.makerFee ? formatRate(market.makerFee) : "-"} - -
-
- - Taker Fee - - - {market.takerFee ? formatRate(market.takerFee) : "-"} - -
-
-
- ); -} diff --git a/src/components/ui/divider.tsx b/src/components/ui/divider.tsx deleted file mode 100644 index c68df7b..0000000 --- a/src/components/ui/divider.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export const Divider = () => { - return
; -}; diff --git a/src/domain/chains/index.ts b/src/domain/chains/index.ts deleted file mode 100644 index 441c8b4..0000000 --- a/src/domain/chains/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import type { SupportedEvmChain } from "@/domain/chains/evm"; - -export type SupportedSKChains = SupportedEvmChain; diff --git a/src/domain/market.ts b/src/domain/market.ts deleted file mode 100644 index a7941be..0000000 --- a/src/domain/market.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Array as _Array, Option } from "effect"; -import type { MarketDto } from "@/services/api-client/api-schemas"; - -export const MIN_LEVERAGE = 1; -export const MAX_LEVERAGE = 40; - -export const getMaxLeverage = (leverages: MarketDto["leverageRange"]): number => - _Array.last(leverages).pipe(Option.getOrElse(() => MAX_LEVERAGE)); diff --git a/src/domain/position.ts b/src/domain/position.ts deleted file mode 100644 index f6b1b0f..0000000 --- a/src/domain/position.ts +++ /dev/null @@ -1,98 +0,0 @@ -import type { PositionDto } from "@/services/api-client/api-schemas"; - -export const getPriceChangePercent = ({ - currentPrice, - pastOrFuturePrice, -}: { - currentPrice: number; - pastOrFuturePrice: number; -}) => { - if (pastOrFuturePrice === 0) return 100; - return ((currentPrice - pastOrFuturePrice) / pastOrFuturePrice) * 100; -}; - -export const getPositionChangePercent = (position: PositionDto) => - getPriceChangePercent({ - currentPrice: position.markPrice, - pastOrFuturePrice: position.entryPrice, - }); - -export const getCloseCalculations = ( - position: PositionDto, - closePercentage: number, -) => { - const ratio = closePercentage / 100; - const sizeNum = Number.parseFloat(position.size); - const positionValue = position.markPrice * sizeNum; - const closeValue = positionValue * ratio; - const marginReturn = position.margin * ratio; - const pnlReturn = position.unrealizedPnl * ratio; - const youWillReceive = marginReturn + pnlReturn; - const closeSize = sizeNum * ratio; - const closeSizeInMarketPrice = (closeSize * position.markPrice).toFixed(6); - - return { - closeValue, - marginReturn, - pnlReturn, - youWillReceive, - closeSize, - closeSizeInMarketPrice, - }; -}; - -export const getLiquidationPrice = ({ - currentPrice, - leverage, - side, -}: { - currentPrice: number; - leverage: number; - side: "long" | "short"; -}) => - side === "long" - ? currentPrice * (1 - 1 / leverage) - : currentPrice * (1 + 1 / leverage); - -export const getPriceChangePercentToLiquidation = ({ - currentPrice, - liquidationPrice, -}: { - currentPrice: number; - liquidationPrice: number; -}) => { - return getPriceChangePercent({ - currentPrice, - pastOrFuturePrice: liquidationPrice, - }); -}; - -export const MIN_LEVERAGE = 1; -export const MAX_LEVERAGE = 40; - -export const getLeveragePercent = ({ - leverage, - maxLeverage, -}: { - leverage: number; - maxLeverage: number; -}) => ((leverage - MIN_LEVERAGE) / (maxLeverage - MIN_LEVERAGE)) * 100; - -export const calculateMargin = ({ - positionSize, - leverage, -}: { - positionSize: number; - leverage: number; -}) => { - if (leverage <= 0) return positionSize; - return positionSize / leverage; -}; - -export const calculatePositionSize = ({ - margin, - leverage, -}: { - margin: number; - leverage: number; -}) => margin * leverage; diff --git a/src/lib/utils.ts b/src/lib/utils.ts deleted file mode 100644 index f504794..0000000 --- a/src/lib/utils.ts +++ /dev/null @@ -1,126 +0,0 @@ -import { type ClassValue, clsx } from "clsx"; -import { Match } from "effect"; -import { twMerge } from "tailwind-merge"; -import type { TokenString } from "@/domain/types"; -import type { Networks, TokenDto } from "@/services/api-client/api-schemas"; - -export function cn(...inputs: ClassValue[]) { - return twMerge(clsx(inputs)); -} - -export const getNetworkLogo = (network: typeof Networks.Type) => - `https://assets.stakek.it/networks/${network}.svg`; - -export const getTokenLogo = (tokenSymbol: string) => - `https://assets.stakek.it/tokens/${tokenSymbol.toLowerCase()}.svg`; - -const tokenAmountFormatter = new Intl.NumberFormat("en-US", { - minimumFractionDigits: 2, - maximumFractionDigits: 5, -}); - -export const formatTokenAmount = ({ - amount, - symbol, -}: { - amount: number | string; - symbol: string; -}) => { - const parsedAmount = typeof amount === "string" ? parseFloat(amount) : amount; - return `${symbol} ${tokenAmountFormatter.format(parsedAmount)}`; -}; - -export const formatAmount = ( - amount: number | string, - options = { symbol: "$" } as { - minimumFractionDigits?: number; - maximumFractionDigits: number; - withSign?: boolean; - symbol?: string | null; - }, -): string => { - const amountNumber = typeof amount === "string" ? parseFloat(amount) : amount; - - const symbol = options.symbol !== null ? (options.symbol ?? "$") : ""; - - const { maxDigits, minDigits } = Match.value({ amountNumber, options }).pipe( - Match.withReturnType<{ - minDigits: number | undefined; - maxDigits: number | undefined; - }>(), - Match.when({ options: Match.defined }, (v) => ({ - minDigits: v.options.minimumFractionDigits, - maxDigits: v.options.maximumFractionDigits, - })), - Match.when( - ({ amountNumber }) => amountNumber >= 1000, - () => ({ minDigits: undefined, maxDigits: 0 }), - ), - Match.when( - ({ amountNumber }) => amountNumber >= 1, - () => ({ minDigits: 2, maxDigits: 4 }), - ), - Match.when( - ({ amountNumber }) => amountNumber >= 0.01, - () => ({ minDigits: undefined, maxDigits: 4 }), - ), - Match.when( - ({ amountNumber }) => amountNumber === 0, - () => ({ minDigits: 2, maxDigits: undefined }), - ), - Match.orElse(() => ({ minDigits: 6, maxDigits: undefined })), - ); - - return `${symbol}${amountNumber.toLocaleString("en-US", { - minimumFractionDigits: minDigits, - maximumFractionDigits: maxDigits, - signDisplay: options?.withSign ? "always" : "auto", - })}`; -}; - -export const formatPercentage = ( - percentage: number, - options?: { - maximumFractionDigits?: number; - }, -) => { - return `${percentage.toFixed(options?.maximumFractionDigits ?? 2)}%`; -}; - -export const formatRate = ( - rate: string, - options?: { - maximumFractionDigits?: number; - }, -) => { - return formatPercentage(Number.parseFloat(rate) * 100, options); -}; - -export const getTokenString = (token: TokenDto): TokenString => - `${token.network}-${token.address}`; - -export const truncateAddress = (address: string, length: number = 6) => - `${address.slice(0, length)}...${address.slice(-length)}`; - -export const formatSnakeCase = (network: string) => { - let str = network[0].toUpperCase(); - for (let i = 1; i < network.length; i++) { - str += network[i] === "_" ? ` ${network[++i].toUpperCase()}` : network[i]; - } - return str; -}; - -export const formatDate = (timestamp: number): string => { - const date = new Date(timestamp); - return date.toLocaleDateString("en-US", { - day: "numeric", - month: "short", - hour: "numeric", - minute: "2-digit", - hour12: true, - }); -}; - -export const truncateNumber = (number: number, precision: number = 2) => { - return Math.floor(number * 10 ** precision) / 10 ** precision; -}; diff --git a/src/main.css b/src/main.css deleted file mode 100644 index e1f1dba..0000000 --- a/src/main.css +++ /dev/null @@ -1,13 +0,0 @@ -html { - background: #131517; -} - -#app { - min-height: 100vh; - padding: 32px; - display: flex; - justify-content: center; - align-items: flex-start; - padding-top: 60px; - background: #131517; -} diff --git a/src/styles.css b/src/styles.css deleted file mode 100644 index 090eda7..0000000 --- a/src/styles.css +++ /dev/null @@ -1,170 +0,0 @@ -@import "tailwindcss"; - -@import "tw-animate-css"; - -@custom-variant dark (&:is(.dark *)); - -:root { - --font-family: - -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", - "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; - --background: oklch(1 0 0); - --foreground: oklch(0.141 0.005 285.823); - --card: oklch(1 0 0); - --card-foreground: oklch(0.141 0.005 285.823); - --popover: oklch(1 0 0); - --popover-foreground: oklch(0.141 0.005 285.823); - --primary: oklch(0.21 0.006 285.885); - --primary-foreground: oklch(0.985 0 0); - --secondary: oklch(0.967 0.001 286.375); - --secondary-foreground: oklch(0.21 0.006 285.885); - --muted: oklch(0.967 0.001 286.375); - --muted-foreground: oklch(0.552 0.016 285.938); - --accent: oklch(0.967 0.001 286.375); - --accent-foreground: oklch(0.21 0.006 285.885); - --destructive: oklch(0.577 0.245 27.325); - --destructive-foreground: oklch(0.577 0.245 27.325); - --border: oklch(0.92 0.004 286.32); - --input: oklch(0.92 0.004 286.32); - --ring: oklch(0.871 0.006 286.286); - --chart-1: oklch(0.646 0.222 41.116); - --chart-2: oklch(0.6 0.118 184.704); - --chart-3: oklch(0.398 0.07 227.392); - --chart-4: oklch(0.828 0.189 84.429); - --chart-5: oklch(0.769 0.188 70.08); - --radius: 0.625rem; - --sidebar: oklch(0.985 0 0); - --sidebar-foreground: oklch(0.141 0.005 285.823); - --sidebar-primary: oklch(0.21 0.006 285.885); - --sidebar-primary-foreground: oklch(0.985 0 0); - --sidebar-accent: oklch(0.967 0.001 286.375); - --sidebar-accent-foreground: oklch(0.21 0.006 285.885); - --sidebar-border: oklch(0.92 0.004 286.32); - --sidebar-ring: oklch(0.871 0.006 286.286); - - --gray-1: #f6f7f999; - --gray-2: #999999; - --gray-3: #ffffff0d; - --gray-4: #ffffff40; - --gray-5: #ffffff2e; - - --accent-green: #34c759; - --accent-red: #ff383c; -} - -.dark { - --background: #000000b2; - --foreground: oklch(0.985 0 0); - --card: oklch(0.141 0.005 285.823); - --card-foreground: oklch(0.985 0 0); - --popover: oklch(0.141 0.005 285.823); - --popover-foreground: oklch(0.985 0 0); - --primary: oklch(0.985 0 0); - --primary-foreground: oklch(0.21 0.006 285.885); - --secondary: oklch(0.274 0.006 286.033); - --secondary-foreground: oklch(0.985 0 0); - --muted: oklch(0.274 0.006 286.033); - --muted-foreground: oklch(0.705 0.015 286.067); - --accent: oklch(0.274 0.006 286.033); - --accent-foreground: oklch(0.985 0 0); - --destructive: oklch(0.396 0.141 25.723); - --destructive-foreground: oklch(0.637 0.237 25.331); - --border: oklch(0.274 0.006 286.033); - --input: oklch(0.274 0.006 286.033); - --ring: oklch(0.442 0.017 285.786); - --chart-1: oklch(0.488 0.243 264.376); - --chart-2: oklch(0.696 0.17 162.48); - --chart-3: oklch(0.769 0.188 70.08); - --chart-4: oklch(0.627 0.265 303.9); - --chart-5: oklch(0.645 0.246 16.439); - --sidebar: oklch(0.21 0.006 285.885); - --sidebar-foreground: oklch(0.985 0 0); - --sidebar-primary: oklch(0.488 0.243 264.376); - --sidebar-primary-foreground: oklch(0.985 0 0); - --sidebar-accent: oklch(0.274 0.006 286.033); - --sidebar-accent-foreground: oklch(0.985 0 0); - --sidebar-border: oklch(0.274 0.006 286.033); - --sidebar-ring: oklch(0.442 0.017 285.786); - - --gray-1: #f6f7f999; - --gray-2: #999999; - --gray-3: #ffffff0d; - --gray-4: #ffffff40; - --gray-5: #ffffff2e; - - --accent-green: #34c759; - --accent-red: #ff383c; -} - -@theme inline { - --color-background: var(--background); - --color-foreground: var(--foreground); - --color-card: var(--card); - --color-card-foreground: var(--card-foreground); - --color-popover: var(--popover); - --color-popover-foreground: var(--popover-foreground); - --color-primary: var(--primary); - --color-primary-foreground: var(--primary-foreground); - --color-secondary: var(--secondary); - --color-secondary-foreground: var(--secondary-foreground); - --color-muted: var(--muted); - --color-muted-foreground: var(--muted-foreground); - --color-accent: var(--accent); - --color-accent-foreground: var(--accent-foreground); - --color-destructive: var(--destructive); - --color-destructive-foreground: var(--destructive-foreground); - --color-border: var(--border); - --color-input: var(--input); - --color-ring: var(--ring); - --color-chart-1: var(--chart-1); - --color-chart-2: var(--chart-2); - --color-chart-3: var(--chart-3); - --color-chart-4: var(--chart-4); - --color-chart-5: var(--chart-5); - --radius-sm: calc(var(--radius) - 4px); - --radius-md: calc(var(--radius) - 2px); - --radius-lg: var(--radius); - --radius-xl: calc(var(--radius) + 4px); - --color-sidebar: var(--sidebar); - --color-sidebar-foreground: var(--sidebar-foreground); - --color-sidebar-primary: var(--sidebar-primary); - --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); - --color-sidebar-accent: var(--sidebar-accent); - --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); - --color-sidebar-border: var(--sidebar-border); - --color-sidebar-ring: var(--sidebar-ring); - - --color-gray-1: var(--gray-1); - --color-gray-2: var(--gray-2); - --color-gray-3: var(--gray-3); - --color-gray-4: var(--gray-4); - --color-gray-5: var(--gray-5); - - --color-accent-green: var(--accent-green); - --color-accent-red: var(--accent-red); -} - -html { - interpolate-size: allow-keywords; -} - -body { - @apply m-0; - font-family: var(--font-family); - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -code { - font-family: - source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace; -} - -@layer base { - * { - @apply border-border outline-ring/50; - } - body { - @apply bg-background text-foreground; - } -} diff --git a/tsconfig.base.json b/tsconfig.base.json new file mode 100644 index 0000000..d33d148 --- /dev/null +++ b/tsconfig.base.json @@ -0,0 +1,42 @@ +{ + "compilerOptions": { + "strict": true, + "composite": true, + "incremental": true, + "moduleDetection": "force", + "downlevelIteration": true, + "resolveJsonModule": true, + "esModuleInterop": false, + "skipLibCheck": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "moduleResolution": "bundler", + "lib": ["ES2024", "DOM", "DOM.Iterable"], + "types": ["vite/client"], + "isolatedModules": true, + "sourceMap": true, + "declarationMap": true, + "noImplicitReturns": false, + "noUnusedLocals": true, + "noUnusedParameters": false, + "noFallthroughCasesInSwitch": true, + "noEmitOnError": false, + "noErrorTruncation": false, + "allowJs": false, + "checkJs": false, + "forceConsistentCasingInFileNames": true, + "noImplicitAny": true, + "noImplicitThis": true, + "noUncheckedIndexedAccess": false, + "strictNullChecks": true, + "target": "ES2024", + "module": "esnext", + "removeComments": false, + "jsx": "react-jsx", + "plugins": [ + { + "name": "@effect/language-service" + } + ] + } +} diff --git a/tsconfig.json b/tsconfig.json index 691e07a..dab084f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,33 +1,8 @@ { - "include": ["src", "scripts", "tests"], - "compilerOptions": { - "target": "ES2022", - "jsx": "react-jsx", - "module": "ESNext", - "lib": ["ES2022", "DOM", "DOM.Iterable"], - "types": ["vite/client"], - - /* Bundler mode */ - "moduleResolution": "bundler", - "allowImportingTsExtensions": true, - "verbatimModuleSyntax": true, - "noEmit": true, - - /* Linting */ - "skipLibCheck": true, - "strict": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noFallthroughCasesInSwitch": true, - "noUncheckedSideEffectImports": true, - "baseUrl": ".", - "paths": { - "@/*": ["./src/*"] - }, - "plugins": [ - { - "name": "@effect/language-service" - } - ] - } + "files": [], + "references": [ + { "path": "./packages/common" }, + { "path": "./packages/widget" }, + { "path": "./packages/dashboard" } + ] } diff --git a/turbo.json b/turbo.json new file mode 100644 index 0000000..deab565 --- /dev/null +++ b/turbo.json @@ -0,0 +1,23 @@ +{ + "$schema": "./node_modules/turbo/schema.json", + "tasks": { + "dev": { + "persistent": true, + "cache": false + }, + "build": { + "outputs": ["dist/**"], + "dependsOn": ["^build"] + }, + "lint": { + "inputs": ["src/**", "tests/**"] + }, + "format": { + "inputs": ["src/**", "tests/**"] + }, + "test": { + "inputs": ["src/**", "tests/**"] + } + }, + "dangerouslyDisablePackageManagerCheck": true +}