From 83fc6961b718d67b28ae7994971aca02010cf3d8 Mon Sep 17 00:00:00 2001 From: Nitish C <86357181+Nitish-bot@users.noreply.github.com> Date: Wed, 4 Mar 2026 13:38:50 +0530 Subject: [PATCH 01/17] add wallet helpers, new fonts, new logo --- .github/copilot-instructions.md | 94 ++++++ web/bun.lock | 497 ++++++++++++++++++++++++++++++++ web/index.html | 12 +- web/package.json | 5 + web/public/logo.svg | 1 + web/src/shims/empty.ts | 2 + web/tsconfig.app.json | 5 +- web/vite.config.ts | 4 + 8 files changed, 612 insertions(+), 8 deletions(-) create mode 100644 .github/copilot-instructions.md create mode 100644 web/public/logo.svg create mode 100644 web/src/shims/empty.ts diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..d88d387 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,94 @@ +# Samizdat – Copilot Instructions + +## Project Overview + +Samizdat is a **DePIN (Decentralized Physical Infrastructure) protocol on Solana** connecting content publishers with display-node operators. It's a monorepo with three major components: + +| Component | Path | Stack | +|-----------|------|-------| +| Solana program | `programs/samizdat/` | Rust, Anchor 0.32 | +| Integration tests | `tests/` | TypeScript, `node:test`, `solana-kite`, `@solana/kit` v6 | +| Web frontend | `web/` | React 19, Vite, Tailwind CSS v4, React Aria Components | + +Content lives off-chain (Arweave/IPFS CIDs); Solana handles campaign matching, payments, and proof-of-play. + +## Build & Test Commands + +```bash +bun install # root deps (tests + codama client gen) +anchor build # compile the Solana program → target/deploy/, target/idl/ +anchor test # build + start localnet + run tests (or: bun test) +bun run generate-client # anchor build → codama → generate TS client into web/client/samizdat/ +cd web && bun install && bun run dev # start web frontend at localhost:5173 +``` + +- **Package manager**: Bun everywhere (configured in `Anchor.toml` and `bunfig.toml`). +- **Rust toolchain**: 1.89.0 pinned in `rust-toolchain.toml`. +- **Deployments** use Surfpool runbooks (`runbooks/deployment/main.tx`), not `anchor deploy`. + +## Solana Program Architecture (`programs/samizdat/src/`) + +### Module layout + +- `lib.rs` – Program entrypoint; thin dispatch to `instructions::process_*` functions. +- `state/` – Account structs (`CampaignAccount`, `NodeAccount`, `PublisherAccount`, `PlayRecord`, `ClaimCooldown`) and shared types/enums/constants. +- `instructions/` – One file per instruction (e.g., `create_campaign.rs`). Each exports a `#[derive(Accounts)]` context struct and a `process_*` function. +- `definitions/` – Proof-related types. +- `errors.rs` – All error variants in `SamizdatError`. + +### Key conventions + +- **PDA seeds** are defined as constants in `state/shared.rs` (`PUBLISHER_SEED`, `CAMPAIGN_SEED`, `NODE_ACCOUNT_SEED`, `PLAY_RECORD_SEED`, `COOLDOWN_SEED`). +- All accounts use `#[derive(InitSpace)]` for automatic space calculation; account init uses `space = 8 + T::INIT_SPACE`. +- Content tags use a **bitmask** (`tag_mask` / `blocked_tag_mask`); overlap check: `campaign.tag_mask & node.blocked_tag_mask != 0` → content blocked. +- Geo coordinates are **fixed-point i64** (degrees × 1e7). +- Campaign funding is **upfront** (`bounty_per_play × total_plays` transferred at creation). The campaign account itself acts as the SOL vault. +- Play cycle: `claim_campaign` → 5-min timeout window → `confirm_play` (pays operator) or `timeout_play` (restores play count). + +### When adding a new instruction + +1. Create `instructions/.rs` with an `Accounts` struct and `process_` function. +2. Re-export in `instructions/mod.rs`. +3. Add the dispatch entry in `lib.rs` under `#[program] mod samizdat`. +4. Run `bun run generate-client` to regenerate the TS client. + +## TypeScript Client (`web/client/samizdat/`) + +Auto-generated by **Codama** from the Anchor IDL (`createCodamaClient.ts`). **Never hand-edit** files under `web/client/samizdat/src/generated/`. To update after program changes: + +```bash +bun run generate-client +``` + +The root `tsconfig.json` maps `@client/*` → `web/client/samizdat/src/generated/*`. + +## Tests (`tests/samizdat.test.ts`) + +- Uses **`node:test`** (not Jest/Mocha) with `node:assert`. +- Uses **`solana-kite`** for connection management and `@solana/kit` v6 for types. +- Test wallets are created via `connection.createWallets(n)`. +- PDAs are derived with `getPDAAndBump(SAMIZDAT_PROGRAM_ADDRESS, [...seeds])`. +- Instructions come from the generated client (`getXxxInstructionAsync` / `getXxxInstruction`). +- Timeout testing requires clock-warping (not available on localnet), so those tests only assert pre-timeout state. + +## Web Frontend (`web/`) + +### Critical conventions (from `web/CLAUDE.md`) + +- **File naming**: All files use **kebab-case** (`date-picker.tsx`, not `DatePicker.tsx`). +- **React Aria imports**: Always prefix with `Aria*`: + ```typescript + import { Button as AriaButton } from 'react-aria-components'; + ``` +- **Path alias**: `@/` → `web/src/` (configured in `web/vite.config.ts`). +- **Component structure**: Base components in `components/base/`, complex app components in `components/application/`. Uses compound component pattern with sub-components. +- **Styling**: Tailwind CSS v4 with `sortCx()` utility for organized style objects. Brand colors via `--color-brand-*` CSS variables in `src/styles/theme.css`. +- **Icons**: `@untitledui/icons` (line-style, free). +- **Routing**: React Router v7 integrated through React Aria's `RouterProvider` (see `providers/router-provider.tsx`). + +## Project-Specific Patterns + +- The `@solana/kit` v6 API is **not** the legacy `@solana/web3.js` — use `Address` (not `PublicKey`), `TransactionSigner`, `lamports()`, etc. +- `solana-kite` wraps `@solana/kit` for ergonomics (`connect()`, `sendTransactionFromInstructions()`). +- Campaigns use `campaign_id: u64` as a publisher-chosen identifier; PDA = `[CAMPAIGN_SEED, publisher_account_pda, campaign_id_le_bytes]`. +- Nodes use `node_id: u64`; PDA = `[NODE_ACCOUNT_SEED, authority, node_id_le_bytes]`. diff --git a/web/bun.lock b/web/bun.lock index d3c2275..d5330ab 100644 --- a/web/bun.lock +++ b/web/bun.lock @@ -5,10 +5,14 @@ "": { "name": "untitledui-vite-starter-kit", "dependencies": { + "@solana/kit": "^6.1.0", + "@solana/react": "^6.1.0", "@tailwindcss/typography": "^0.5.19", "@tailwindcss/vite": "^4.1.18", "@untitledui/file-icons": "^0.0.8", "@untitledui/icons": "^0.0.21", + "@wallet-standard/core": "^1.1.1", + "@wallet-standard/react": "^1.0.1", "input-otp": "^1.4.2", "motion": "^12.29.0", "qr-code-styling": "^1.9.2", @@ -18,6 +22,7 @@ "react-dom": "^19.2.3", "react-hotkeys-hook": "^5.2.3", "react-router": "^7.13.0", + "solana-kite": "^3.2.1", "tailwind-merge": "^3.4.0", "tailwindcss": "^4.1.18", "tailwindcss-animate": "^1.0.7", @@ -459,6 +464,102 @@ "@rtsao/scc": ["@rtsao/scc@1.1.0", "", {}, "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g=="], + "@solana-program/compute-budget": ["@solana-program/compute-budget@0.11.0", "", { "peerDependencies": { "@solana/kit": "^5.0" } }, "sha512-7f1ePqB/eURkTwTOO9TNIdUXZcyrZoX3Uy2hNo7cXMfNhPFWp9AVgIyRNBc2jf15sdUa9gNpW+PfP2iV8AYAaw=="], + + "@solana-program/memo": ["@solana-program/memo@0.10.0", "", { "peerDependencies": { "@solana/kit": "^5.0" } }, "sha512-1FvQFenL3lzl5SpxhWV4QJCOLU/nvAOXGXjKjS7dprvG+0u971xoanApN7bM/a4NFZolp6S+lP2xVl6vTVIxbg=="], + + "@solana-program/system": ["@solana-program/system@0.10.0", "", { "peerDependencies": { "@solana/kit": "^5.0" } }, "sha512-Go+LOEZmqmNlfr+Gjy5ZWAdY5HbYzk2RBewD9QinEU/bBSzpFfzqDRT55JjFRBGJUvMgf3C2vfXEGT4i8DSI4g=="], + + "@solana-program/token": ["@solana-program/token@0.9.0", "", { "peerDependencies": { "@solana/kit": "^5.0" } }, "sha512-vnZxndd4ED4Fc56sw93cWZ2djEeeOFxtaPS8SPf5+a+JZjKA/EnKqzbE1y04FuMhIVrLERQ8uR8H2h72eZzlsA=="], + + "@solana-program/token-2022": ["@solana-program/token-2022@0.6.1", "", { "peerDependencies": { "@solana/kit": "^5.0", "@solana/sysvars": "^5.0" } }, "sha512-Ex02cruDMGfBMvZZCrggVR45vdQQSI/unHVpt/7HPt/IwFYB4eTlXtO8otYZyqV/ce5GqZ8S6uwyRf0zy6fdbA=="], + + "@solana/accounts": ["@solana/accounts@6.1.0", "", { "dependencies": { "@solana/addresses": "6.1.0", "@solana/codecs-core": "6.1.0", "@solana/codecs-strings": "6.1.0", "@solana/errors": "6.1.0", "@solana/rpc-spec": "6.1.0", "@solana/rpc-types": "6.1.0" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-0jhmhSSS71ClLtBQIDrLlhkiNER4M9RIXTl1eJ1yJoFlE608JaKHTjNWsdVKdke7uBD6exdjNZkIVmouQPHMcA=="], + + "@solana/addresses": ["@solana/addresses@6.1.0", "", { "dependencies": { "@solana/assertions": "6.1.0", "@solana/codecs-core": "6.1.0", "@solana/codecs-strings": "6.1.0", "@solana/errors": "6.1.0", "@solana/nominal-types": "6.1.0" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-QT04Vie4iICaalQQRJFMGj/P56IxXiwFtVuZHu1qjZUNmuGTOvX6G98b27RaGtLzpJ3NIku/6OtKxLUBqAKAyQ=="], + + "@solana/assertions": ["@solana/assertions@3.0.3", "", { "dependencies": { "@solana/errors": "3.0.3" }, "peerDependencies": { "typescript": ">=5.3.3" } }, "sha512-2qspxdbWp2y62dfCIlqeWQr4g+hE8FYSSwcaP6itwMwGRb8393yDGCJfI/znuzJh6m/XVWhMHIgFgsBwnevCmg=="], + + "@solana/codecs": ["@solana/codecs@6.1.0", "", { "dependencies": { "@solana/codecs-core": "6.1.0", "@solana/codecs-data-structures": "6.1.0", "@solana/codecs-numbers": "6.1.0", "@solana/codecs-strings": "6.1.0", "@solana/options": "6.1.0" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-VHBS3t8fyVjE0Nqo6b4TUnzdwdRaVo+B5ufHhPLbbjkEXzz8HB4E/OBjgasn+zWGlfScfQAiBFOsfZjbVWu4XA=="], + + "@solana/codecs-core": ["@solana/codecs-core@6.1.0", "", { "dependencies": { "@solana/errors": "6.1.0" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-5rNnDOOm2GRFMJbd9imYCPNvGOrQ+TZ53NCkFFWbbB7f+L9KkLeuuAsDMFN1lCziJFlymvN785YtDnMeWj2W+g=="], + + "@solana/codecs-data-structures": ["@solana/codecs-data-structures@6.1.0", "", { "dependencies": { "@solana/codecs-core": "6.1.0", "@solana/codecs-numbers": "6.1.0", "@solana/errors": "6.1.0" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-1cb9g5hrrucTuGkGxqVVq7dCwSMnn4YqwTe365iKkK8HBpLBmUl8XATf1MUs5UtDun1g9eNWOL72Psr8mIUqTQ=="], + + "@solana/codecs-numbers": ["@solana/codecs-numbers@6.1.0", "", { "dependencies": { "@solana/codecs-core": "6.1.0", "@solana/errors": "6.1.0" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-YPQwwl6LE3igH23ah+d8kgpyE5xFcPbuwhxCDsLWqY/ESrvO/0YQSbsgIXahbhZxN59ZC4uq1LnHhBNbpCSVQg=="], + + "@solana/codecs-strings": ["@solana/codecs-strings@6.1.0", "", { "dependencies": { "@solana/codecs-core": "6.1.0", "@solana/codecs-numbers": "6.1.0", "@solana/errors": "6.1.0" }, "peerDependencies": { "fastestsmallesttextencoderdecoder": "^1.0.22", "typescript": "^5.0.0" }, "optionalPeers": ["fastestsmallesttextencoderdecoder", "typescript"] }, "sha512-pRH5uAn4VCFUs2rYiDITyWsRnpvs3Uh/nhSc6OSP/kusghcCcCJcUzHBIjT4x08MVacXmGUlSLe/9qPQO+QK3Q=="], + + "@solana/errors": ["@solana/errors@6.1.0", "", { "dependencies": { "chalk": "5.6.2", "commander": "14.0.3" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"], "bin": { "errors": "bin/cli.mjs" } }, "sha512-cqSwcw3Rmn85UR7PyF5nKPdlQsRYBkx7YGRvFaJ6Sal1PM+bfolhL5iT7STQoXxdhXGYwHMPg7kZYxmMdjwnJA=="], + + "@solana/fast-stable-stringify": ["@solana/fast-stable-stringify@6.1.0", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-QXUfDFaJCFeARsxJgScWmJ153Tit7Cimk9y0UWWreNBr2Aphi67Nlcj/tr7UABTO0Qaw/0gwrK76zz3m1t3nIw=="], + + "@solana/functional": ["@solana/functional@6.1.0", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-+Sm8ldVxSTHIKaZDvcBu81FPjknXx6OMPlakkKmXjKxPgVLl86ruqMo2yEwoDUHV7DysLrLLcRNn13rfulomRw=="], + + "@solana/instruction-plans": ["@solana/instruction-plans@6.1.0", "", { "dependencies": { "@solana/errors": "6.1.0", "@solana/instructions": "6.1.0", "@solana/keys": "6.1.0", "@solana/promises": "6.1.0", "@solana/transaction-messages": "6.1.0", "@solana/transactions": "6.1.0" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-zcsHg544t1zn7LLOVUxOWYlsKn9gvT7R+pL3cTiP2wFNoUN0h9En87H6nVqkZ8LWw23asgW0uM5uJGwfBx2h1Q=="], + + "@solana/instructions": ["@solana/instructions@6.1.0", "", { "dependencies": { "@solana/codecs-core": "6.1.0", "@solana/errors": "6.1.0" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-w1LdbJ3yanESckNTYC5KPckgN/25FyGCm07WWrs+dCnnpRNeLiVHIytXCPmArOVAXVkOYidXzhWmqCzqKUjYaA=="], + + "@solana/keys": ["@solana/keys@6.1.0", "", { "dependencies": { "@solana/assertions": "6.1.0", "@solana/codecs-core": "6.1.0", "@solana/codecs-strings": "6.1.0", "@solana/errors": "6.1.0", "@solana/nominal-types": "6.1.0" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-C/SGCl3VOgBQZ0mLrMxCcJYnMsGpgE8wbx29jqRY+R91m5YhS1f/GfXJPR1lN/h7QGrJ6YDm8eI0Y3AZ7goKHg=="], + + "@solana/kit": ["@solana/kit@6.1.0", "", { "dependencies": { "@solana/accounts": "6.1.0", "@solana/addresses": "6.1.0", "@solana/codecs": "6.1.0", "@solana/errors": "6.1.0", "@solana/functional": "6.1.0", "@solana/instruction-plans": "6.1.0", "@solana/instructions": "6.1.0", "@solana/keys": "6.1.0", "@solana/offchain-messages": "6.1.0", "@solana/plugin-core": "6.1.0", "@solana/plugin-interfaces": "6.1.0", "@solana/program-client-core": "6.1.0", "@solana/programs": "6.1.0", "@solana/rpc": "6.1.0", "@solana/rpc-api": "6.1.0", "@solana/rpc-parsed-types": "6.1.0", "@solana/rpc-spec-types": "6.1.0", "@solana/rpc-subscriptions": "6.1.0", "@solana/rpc-types": "6.1.0", "@solana/signers": "6.1.0", "@solana/sysvars": "6.1.0", "@solana/transaction-confirmation": "6.1.0", "@solana/transaction-messages": "6.1.0", "@solana/transactions": "6.1.0" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-24exn11BPonquufyCkGgypVtmN4JOsdGMsbF3EZ4kFyk7ZNryCn/N8eELr1FCVrHWRXoc0xy/HFaESBULTMf6g=="], + + "@solana/nominal-types": ["@solana/nominal-types@6.1.0", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-+skHjN0arNNB9TLsGqA94VCx7euyGURI+qG6wck6E4D7hH6i6DxGiVrtKRghx+smJkkLtTm9BvdVKGoeNQYr7Q=="], + + "@solana/offchain-messages": ["@solana/offchain-messages@6.1.0", "", { "dependencies": { "@solana/addresses": "6.1.0", "@solana/codecs-core": "6.1.0", "@solana/codecs-data-structures": "6.1.0", "@solana/codecs-numbers": "6.1.0", "@solana/codecs-strings": "6.1.0", "@solana/errors": "6.1.0", "@solana/keys": "6.1.0", "@solana/nominal-types": "6.1.0" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-jrUb7HGUnRA+k44upcqKeevtEdqMxYRSlFdE0JTctZunGlP3GCcTl12tFOpbnFHvBLt8RwS62+nyeES8zzNwXA=="], + + "@solana/options": ["@solana/options@6.1.0", "", { "dependencies": { "@solana/codecs-core": "6.1.0", "@solana/codecs-data-structures": "6.1.0", "@solana/codecs-numbers": "6.1.0", "@solana/codecs-strings": "6.1.0", "@solana/errors": "6.1.0" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-/4FtVfR6nkHkMCumyh7/lJ6jMqyES6tKUbOJRa6gJxcIUWeRDu+XrHTHLf3gRNUqDAbFvW8FMIrQm7PdreZgRA=="], + + "@solana/plugin-core": ["@solana/plugin-core@6.1.0", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-2nmNCPa6B1QArqpAZHWUkK6K7UXLTrekfcfJm2V//ATEtLpKEBlv0c3mrhOYwNAKP2TpNuvEV33InXWKst9oXQ=="], + + "@solana/plugin-interfaces": ["@solana/plugin-interfaces@6.1.0", "", { "dependencies": { "@solana/addresses": "6.1.0", "@solana/instruction-plans": "6.1.0", "@solana/keys": "6.1.0", "@solana/rpc-spec": "6.1.0", "@solana/rpc-subscriptions-spec": "6.1.0", "@solana/rpc-types": "6.1.0", "@solana/signers": "6.1.0" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-eWSzfOuwtHUp8vljf5V24Tkz3WxqxiV0vD/BJZBNRZMdYRw3Cw3oeWcvEqHHxGUOie6AjIK8GrKggi8F73ZXbg=="], + + "@solana/program-client-core": ["@solana/program-client-core@6.1.0", "", { "dependencies": { "@solana/accounts": "6.1.0", "@solana/addresses": "6.1.0", "@solana/codecs-core": "6.1.0", "@solana/errors": "6.1.0", "@solana/instruction-plans": "6.1.0", "@solana/instructions": "6.1.0", "@solana/plugin-interfaces": "6.1.0", "@solana/rpc-api": "6.1.0", "@solana/signers": "6.1.0" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-5Apka+ulWNfLNLYNR63pLnr5XvkXTQWeaftWED93iTWTZrZv9SyFWcmIsaes6eqGXMQ3RhlebnrWODtKuAA62g=="], + + "@solana/programs": ["@solana/programs@6.1.0", "", { "dependencies": { "@solana/addresses": "6.1.0", "@solana/errors": "6.1.0" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-i4L4gSlIHDsdYRt3/YKVKMIN3UuYSKHRqK9B+AejcIc0y6Y/AXnHqzmpBRXEhvTXz18nt59MLXpVU4wu7ASjJA=="], + + "@solana/promises": ["@solana/promises@6.1.0", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-/mUW6peXQiEOaylLpGv4vtkvPzQvSbfhX9j5PNIK/ry4S3SHRQ3j3W/oGy4y3LR5alwo7NcVbubrkh4e4xwcww=="], + + "@solana/react": ["@solana/react@6.1.0", "", { "dependencies": { "@solana/addresses": "6.1.0", "@solana/errors": "6.1.0", "@solana/keys": "6.1.0", "@solana/promises": "6.1.0", "@solana/signers": "6.1.0", "@solana/transaction-messages": "6.1.0", "@solana/transactions": "6.1.0", "@solana/wallet-standard-features": "^1.3.0", "@wallet-standard/base": "^1.1.0", "@wallet-standard/errors": "^0.1.1", "@wallet-standard/react": "^1.0.1", "@wallet-standard/ui": "^1.0.1", "@wallet-standard/ui-registry": "^1.0.1" }, "peerDependencies": { "react": ">=18" }, "optionalPeers": ["react"] }, "sha512-CpXDa3s2KdJIdClnXkDjGi0IMXGVxP/JEzLUM+o85XMIUmyvwaHeIN8skb69AqCJSBm64ANCNezeUSfd8fo40A=="], + + "@solana/rpc": ["@solana/rpc@6.1.0", "", { "dependencies": { "@solana/errors": "6.1.0", "@solana/fast-stable-stringify": "6.1.0", "@solana/functional": "6.1.0", "@solana/rpc-api": "6.1.0", "@solana/rpc-spec": "6.1.0", "@solana/rpc-spec-types": "6.1.0", "@solana/rpc-transformers": "6.1.0", "@solana/rpc-transport-http": "6.1.0", "@solana/rpc-types": "6.1.0" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-R3y5PklW9mPy5Y34hsXj40R28zN2N7AGLnHqYJVkXkllwVub/QCNpSdDxAnbbS5EGOYGoUOW8s5LFoXwMSr1LQ=="], + + "@solana/rpc-api": ["@solana/rpc-api@6.1.0", "", { "dependencies": { "@solana/addresses": "6.1.0", "@solana/codecs-core": "6.1.0", "@solana/codecs-strings": "6.1.0", "@solana/errors": "6.1.0", "@solana/keys": "6.1.0", "@solana/rpc-parsed-types": "6.1.0", "@solana/rpc-spec": "6.1.0", "@solana/rpc-transformers": "6.1.0", "@solana/rpc-types": "6.1.0", "@solana/transaction-messages": "6.1.0", "@solana/transactions": "6.1.0" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-+hO5+kZjJHuUNATUQxlJ1+ztXFkgn1j46zRwt3X7kF+VHkW3wsQ7up0JTS+Xsacmkrj1WKfymQweq8JTrsAG8A=="], + + "@solana/rpc-parsed-types": ["@solana/rpc-parsed-types@6.1.0", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-YKccynVgWt/gbs0tBYstNw6BSVuOeWdeAldTB2OgH95o2Q04DpO4v97X1MZDysA4SvSZM30Ek5Ni5ss3kskgdw=="], + + "@solana/rpc-spec": ["@solana/rpc-spec@6.1.0", "", { "dependencies": { "@solana/errors": "6.1.0", "@solana/rpc-spec-types": "6.1.0" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-RxpkIGizCYhXGUcap7npV2S/rAXZ7P/liozY/ExjMmCxYTDwGIW33kp/uH/JRxuzrL8+f8FqY76VsqqIe+2VZw=="], + + "@solana/rpc-spec-types": ["@solana/rpc-spec-types@6.1.0", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-tldMv1b6VGcvcRrY5MDWKlsyEKH6K96zE7gAIpKDX2G4T47ZOV+OMA3nh6xQpRgtyCUBsej0t80qmvTBDX/5IQ=="], + + "@solana/rpc-subscriptions": ["@solana/rpc-subscriptions@6.1.0", "", { "dependencies": { "@solana/errors": "6.1.0", "@solana/fast-stable-stringify": "6.1.0", "@solana/functional": "6.1.0", "@solana/promises": "6.1.0", "@solana/rpc-spec-types": "6.1.0", "@solana/rpc-subscriptions-api": "6.1.0", "@solana/rpc-subscriptions-channel-websocket": "6.1.0", "@solana/rpc-subscriptions-spec": "6.1.0", "@solana/rpc-transformers": "6.1.0", "@solana/rpc-types": "6.1.0", "@solana/subscribable": "6.1.0" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-sqwj+cQinWcZ7M/9+cudKxMPTkTQyGP73980vPCWM7vCpPkp2qzgrEie4DdgDGo+NMwIjeFgu2kdUuLHI3GD/g=="], + + "@solana/rpc-subscriptions-api": ["@solana/rpc-subscriptions-api@6.1.0", "", { "dependencies": { "@solana/addresses": "6.1.0", "@solana/keys": "6.1.0", "@solana/rpc-subscriptions-spec": "6.1.0", "@solana/rpc-transformers": "6.1.0", "@solana/rpc-types": "6.1.0", "@solana/transaction-messages": "6.1.0", "@solana/transactions": "6.1.0" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-I6J+3VU0dda6EySKbDyd+1urC7RGIRPRp0DcWRVcy68NOLbq0I5C40Dn9O2Zf8iCdK4PbQ7JKdCvZ/bDd45hdg=="], + + "@solana/rpc-subscriptions-channel-websocket": ["@solana/rpc-subscriptions-channel-websocket@6.1.0", "", { "dependencies": { "@solana/errors": "6.1.0", "@solana/functional": "6.1.0", "@solana/rpc-subscriptions-spec": "6.1.0", "@solana/subscribable": "6.1.0", "ws": "^8.19.0" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-vsx9b+uyCr9L3giao/BTiBFA8DxV5+gDNFq0t5uL21uQ17JXzBektwzHuHoth9IjkvXV/h+IhwXfuLE9Qm4GQg=="], + + "@solana/rpc-subscriptions-spec": ["@solana/rpc-subscriptions-spec@6.1.0", "", { "dependencies": { "@solana/errors": "6.1.0", "@solana/promises": "6.1.0", "@solana/rpc-spec-types": "6.1.0", "@solana/subscribable": "6.1.0" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-P06jhqzHpZGaLeJmIQkpDeMDD1xUp53ARpmXMsduMC+U5ZKQt29CLo+JrR18boNtls6WfttjVMEbzF25/4UPVA=="], + + "@solana/rpc-transformers": ["@solana/rpc-transformers@6.1.0", "", { "dependencies": { "@solana/errors": "6.1.0", "@solana/functional": "6.1.0", "@solana/nominal-types": "6.1.0", "@solana/rpc-spec-types": "6.1.0", "@solana/rpc-types": "6.1.0" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-OsSuuRPmsmS02eR9Zz+4iTsr+21hvEMEex5vwbwN6LAGPFlQ4ohqGkxgZCwmYd+Q5HWpnn9Uuf1MDTLLrKQkig=="], + + "@solana/rpc-transport-http": ["@solana/rpc-transport-http@6.1.0", "", { "dependencies": { "@solana/errors": "6.1.0", "@solana/rpc-spec": "6.1.0", "@solana/rpc-spec-types": "6.1.0", "undici-types": "^7.21.0" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-3ebaTYuglLJagaXtjwDPVI7SQeeeFN2fpetpGKsuMAiti4fzYqEkNN8FIo+nXBzqqG/cVc2421xKjXl6sO1k/g=="], + + "@solana/rpc-types": ["@solana/rpc-types@6.1.0", "", { "dependencies": { "@solana/addresses": "6.1.0", "@solana/codecs-core": "6.1.0", "@solana/codecs-numbers": "6.1.0", "@solana/codecs-strings": "6.1.0", "@solana/errors": "6.1.0", "@solana/nominal-types": "6.1.0" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-lR+Cb3v5Rpl49HsXWASy++TSE1AD86eRKabY+iuWnbBMYVGI4MamAvYwgBiygsCNc30nyO2TFNj9STMeSD/gAg=="], + + "@solana/signers": ["@solana/signers@6.1.0", "", { "dependencies": { "@solana/addresses": "6.1.0", "@solana/codecs-core": "6.1.0", "@solana/errors": "6.1.0", "@solana/instructions": "6.1.0", "@solana/keys": "6.1.0", "@solana/nominal-types": "6.1.0", "@solana/offchain-messages": "6.1.0", "@solana/transaction-messages": "6.1.0", "@solana/transactions": "6.1.0" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-WDPGZJr6jIe2dEChv/2KQBnaga8dqOjd6ceBj/HcDHxnCudo66t7GlyZ9+9jMO40AgOOb7EDE5FDqPMrHMg5Yw=="], + + "@solana/subscribable": ["@solana/subscribable@6.1.0", "", { "dependencies": { "@solana/errors": "6.1.0" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-HiUfkxN7638uxPmY4t0gI4+yqnFLZYJKFaT9EpWIuGrOB1d9n+uOHNs3NU7cVMwWXgfZUbztTCKyCVTbcwesNg=="], + + "@solana/sysvars": ["@solana/sysvars@6.1.0", "", { "dependencies": { "@solana/accounts": "6.1.0", "@solana/codecs": "6.1.0", "@solana/errors": "6.1.0", "@solana/rpc-types": "6.1.0" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-KwJyBBrAOx0BgkiZqOKAaySDb/0JrUFSBQL9/O1kSKGy9TCRX55Ytr1HxNTcTPppWNpbM6JZVK+yW3Ruey0HRw=="], + + "@solana/transaction-confirmation": ["@solana/transaction-confirmation@6.1.0", "", { "dependencies": { "@solana/addresses": "6.1.0", "@solana/codecs-strings": "6.1.0", "@solana/errors": "6.1.0", "@solana/keys": "6.1.0", "@solana/promises": "6.1.0", "@solana/rpc": "6.1.0", "@solana/rpc-subscriptions": "6.1.0", "@solana/rpc-types": "6.1.0", "@solana/transaction-messages": "6.1.0", "@solana/transactions": "6.1.0" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-akSjcqAMOGPFvKctFDSzhjcRc/45WbEVdVQ9mjgH6OYo7B11WZZZaeGPlzAw5KyuG34Px941xmICkBmNqEH47Q=="], + + "@solana/transaction-messages": ["@solana/transaction-messages@6.1.0", "", { "dependencies": { "@solana/addresses": "6.1.0", "@solana/codecs-core": "6.1.0", "@solana/codecs-data-structures": "6.1.0", "@solana/codecs-numbers": "6.1.0", "@solana/errors": "6.1.0", "@solana/functional": "6.1.0", "@solana/instructions": "6.1.0", "@solana/nominal-types": "6.1.0", "@solana/rpc-types": "6.1.0" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-Dpv54LRVcfFbFEa/uB53LaY/TRfKuPGMKR7Z4F290zBgkj9xkpZkI+WLiJBiSloI7Qo2KZqXj3514BIeZvJLcg=="], + + "@solana/transactions": ["@solana/transactions@6.1.0", "", { "dependencies": { "@solana/addresses": "6.1.0", "@solana/codecs-core": "6.1.0", "@solana/codecs-data-structures": "6.1.0", "@solana/codecs-numbers": "6.1.0", "@solana/codecs-strings": "6.1.0", "@solana/errors": "6.1.0", "@solana/functional": "6.1.0", "@solana/instructions": "6.1.0", "@solana/keys": "6.1.0", "@solana/nominal-types": "6.1.0", "@solana/rpc-types": "6.1.0", "@solana/transaction-messages": "6.1.0" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-1dkiNJcTtlHm4Fvs5VohNVpv7RbvbUYYKV7lYXMPIskoLF1eZp0tVlEqD/cRl91RNz7HEysfHqBAwlcJcRmrRg=="], + + "@solana/wallet-standard-features": ["@solana/wallet-standard-features@1.3.0", "", { "dependencies": { "@wallet-standard/base": "^1.1.0", "@wallet-standard/features": "^1.1.0" } }, "sha512-ZhpZtD+4VArf6RPitsVExvgkF+nGghd1rzPjd97GmBximpnt1rsUxMOEyoIEuH3XBxPyNB6Us7ha7RHWQR+abg=="], + "@swc/core": ["@swc/core@1.15.10", "", { "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.25" }, "optionalDependencies": { "@swc/core-darwin-arm64": "1.15.10", "@swc/core-darwin-x64": "1.15.10", "@swc/core-linux-arm-gnueabihf": "1.15.10", "@swc/core-linux-arm64-gnu": "1.15.10", "@swc/core-linux-arm64-musl": "1.15.10", "@swc/core-linux-x64-gnu": "1.15.10", "@swc/core-linux-x64-musl": "1.15.10", "@swc/core-win32-arm64-msvc": "1.15.10", "@swc/core-win32-ia32-msvc": "1.15.10", "@swc/core-win32-x64-msvc": "1.15.10" }, "peerDependencies": { "@swc/helpers": ">=0.5.17" }, "optionalPeers": ["@swc/helpers"] }, "sha512-udNofxftduMUEv7nqahl2nvodCiCDQ4Ge0ebzsEm6P8s0RC2tBM0Hqx0nNF5J/6t9uagFJyWIDjXy3IIWMHDJw=="], "@swc/core-darwin-arm64": ["@swc/core-darwin-arm64@1.15.10", "", { "os": "darwin", "cpu": "arm64" }, "sha512-U72pGqmJYbjrLhMndIemZ7u9Q9owcJczGxwtfJlz/WwMaGYAV/g4nkGiUVk/+QSX8sFCAjanovcU1IUsP2YulA=="], @@ -561,6 +662,34 @@ "@vitejs/plugin-react-swc": ["@vitejs/plugin-react-swc@4.2.2", "", { "dependencies": { "@rolldown/pluginutils": "1.0.0-beta.47", "@swc/core": "^1.13.5" }, "peerDependencies": { "vite": "^4 || ^5 || ^6 || ^7" } }, "sha512-x+rE6tsxq/gxrEJN3Nv3dIV60lFflPj94c90b+NNo6n1QV1QQUTLoL0MpaOVasUZ0zqVBn7ead1B5ecx1JAGfA=="], + "@wallet-standard/app": ["@wallet-standard/app@1.1.0", "", { "dependencies": { "@wallet-standard/base": "^1.1.0" } }, "sha512-3CijvrO9utx598kjr45hTbbeeykQrQfKmSnxeWOgU25TOEpvcipD/bYDQWIqUv1Oc6KK4YStokSMu/FBNecGUQ=="], + + "@wallet-standard/base": ["@wallet-standard/base@1.1.0", "", {}, "sha512-DJDQhjKmSNVLKWItoKThJS+CsJQjR9AOBOirBVT1F9YpRyC9oYHE+ZnSf8y8bxUphtKqdQMPVQ2mHohYdRvDVQ=="], + + "@wallet-standard/core": ["@wallet-standard/core@1.1.1", "", { "dependencies": { "@wallet-standard/app": "^1.1.0", "@wallet-standard/base": "^1.1.0", "@wallet-standard/errors": "^0.1.1", "@wallet-standard/features": "^1.1.0", "@wallet-standard/wallet": "^1.1.0" } }, "sha512-5Xmjc6+Oe0hcPfVc5n8F77NVLwx1JVAoCVgQpLyv/43/bhtIif+Gx3WUrDlaSDoM8i2kA2xd6YoFbHCxs+e0zA=="], + + "@wallet-standard/errors": ["@wallet-standard/errors@0.1.1", "", { "dependencies": { "chalk": "^5.4.1", "commander": "^13.1.0" }, "bin": { "errors": "bin/cli.mjs" } }, "sha512-V8Ju1Wvol8i/VDyQOHhjhxmMVwmKiwyxUZBnHhtiPZJTWY0U/Shb2iEWyGngYEbAkp2sGTmEeNX1tVyGR7PqNw=="], + + "@wallet-standard/experimental-features": ["@wallet-standard/experimental-features@0.2.0", "", { "dependencies": { "@wallet-standard/base": "^1.1.0" } }, "sha512-B6fBLgouurN3IAoqhh8/1Mm33IAWIErQXVyvMcyBJM+elOD6zkNDUjew5QMG19qCbJ+ZiZUZmdOUC5PxxWw69w=="], + + "@wallet-standard/features": ["@wallet-standard/features@1.1.0", "", { "dependencies": { "@wallet-standard/base": "^1.1.0" } }, "sha512-hiEivWNztx73s+7iLxsuD1sOJ28xtRix58W7Xnz4XzzA/pF0+aicnWgjOdA10doVDEDZdUuZCIIqG96SFNlDUg=="], + + "@wallet-standard/react": ["@wallet-standard/react@1.0.1", "", { "dependencies": { "@wallet-standard/react-core": "^1.0.1" } }, "sha512-StpPv234R94MmJCCUZurQvQSsX6Xe1eOd2lNgwVonvSVdPqCNVS/haVpdrBMx0wX1Ut24X77qyBLP7SGxK5OUg=="], + + "@wallet-standard/react-core": ["@wallet-standard/react-core@1.0.1", "", { "dependencies": { "@wallet-standard/app": "^1.1.0", "@wallet-standard/base": "^1.1.0", "@wallet-standard/errors": "^0.1.1", "@wallet-standard/experimental-features": "^0.2.0", "@wallet-standard/features": "^1.1.0", "@wallet-standard/ui": "^1.0.1", "@wallet-standard/ui-registry": "^1.0.1" }, "peerDependencies": { "react": ">=18", "react-dom": ">=18" } }, "sha512-g+vZaLlAGlYMwZEoKsmjjI5qz1D8P3FF1aqiI3WLooWOVk55Nszbpk01QCbIFdIMF0UDhxia2FU667TCv509iw=="], + + "@wallet-standard/ui": ["@wallet-standard/ui@1.0.1", "", { "dependencies": { "@wallet-standard/ui-compare": "^1.0.1", "@wallet-standard/ui-core": "^1.0.0", "@wallet-standard/ui-features": "^1.0.1" } }, "sha512-3b1iSfHOB3YpuBM645ZAgA0LMGZv+3Eh4y9lM3kS+NnvK4NxwnEdn1mLbFxevRhyulNjFZ50m2Cq5mpEOYs2mw=="], + + "@wallet-standard/ui-compare": ["@wallet-standard/ui-compare@1.0.1", "", { "dependencies": { "@wallet-standard/base": "1.1.0", "@wallet-standard/ui-core": "1.0.0", "@wallet-standard/ui-registry": "1.0.1" } }, "sha512-Qr6AjgxTgTNgjUm/HQend08jFCUJ2ugbONpbC1hSl4Ndul+theJV3CwVZ2ffKun584bHoR8OAibJ+QA4ecogEA=="], + + "@wallet-standard/ui-core": ["@wallet-standard/ui-core@1.0.0", "", { "dependencies": { "@wallet-standard/base": "1.1.0" } }, "sha512-pnpBfxJois0fIAI0IBJ6hopOguw81JniB6DzOs5J7C16W7/M2kC0OKHQFKrz6cgSGMq8X0bPA8nZTXFTSNbURg=="], + + "@wallet-standard/ui-features": ["@wallet-standard/ui-features@1.0.1", "", { "dependencies": { "@wallet-standard/base": "1.1.0", "@wallet-standard/errors": "0.1.1", "@wallet-standard/ui-core": "1.0.0", "@wallet-standard/ui-registry": "1.0.1" } }, "sha512-0/lZFx599bGcDEvisAWtbFMuRM/IuqP/o0vbhAeQdLWsWsaqFTUIKZtMt8JJq+fFBMQGc6tuRH6ehrgm+Y0biQ=="], + + "@wallet-standard/ui-registry": ["@wallet-standard/ui-registry@1.0.1", "", { "dependencies": { "@wallet-standard/base": "1.1.0", "@wallet-standard/errors": "0.1.1", "@wallet-standard/ui-core": "1.0.0" } }, "sha512-+SeXEwSoyqEWv9B6JLxRioRlgN5ksSFObZMf+XKm2U+vwmc/mfm43I8zw5wvGBpubzmywbe2eejd5k/snyx+uA=="], + + "@wallet-standard/wallet": ["@wallet-standard/wallet@1.1.0", "", { "dependencies": { "@wallet-standard/base": "^1.1.0" } }, "sha512-Gt8TnSlDZpAl+RWOOAB/kuvC7RpcdWAlFbHNoi4gsXsfaWa1QCT6LBcfIYTPdOZC9OVZUDwqGuGAcqZejDmHjg=="], + "acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="], "acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="], @@ -659,6 +788,8 @@ "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], + "commander": ["commander@14.0.3", "", {}, "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw=="], + "concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="], "console-browserify": ["console-browserify@1.2.0", "", {}, "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA=="], @@ -715,6 +846,8 @@ "domain-browser": ["domain-browser@4.22.0", "", {}, "sha512-IGBwjF7tNk3cwypFNH/7bfzBcgSCbaMOD3GsaY1AU/JRrnHnYgEM0+9kQt52iZxjNsjBtJYtao146V+f8jFZNw=="], + "dotenv": ["dotenv@16.6.1", "", {}, "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow=="], + "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="], "electron-to-chromium": ["electron-to-chromium@1.5.302", "", {}, "sha512-sM6HAN2LyK82IyPBpznDRqlTQAtuSaO+ShzFiWTvoMJLHyZ+Y39r8VMfHzwbU8MVBzQ4Wdn85+wlZl2TLGIlwg=="], @@ -1179,6 +1312,8 @@ "side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="], + "solana-kite": ["solana-kite@3.2.1", "", { "dependencies": { "@solana-program/compute-budget": "^0.11.0", "@solana-program/memo": "^0.10.0", "@solana-program/system": "^0.10.0", "@solana-program/token": "^0.9.0", "@solana-program/token-2022": "^0.6.1", "@solana/assertions": "^3.0.3", "@solana/errors": "^3.0.3", "@solana/kit": "^5.4.0", "@solana/promises": "^3.0.3", "@solana/transaction-confirmation": "^5.0.0", "dotenv": "^16.4.5", "ws": "^8.18.3" } }, "sha512-jH9kd3AnJwun/6LgQnN/fC0BT7QeGVw4RQ+Q1FovPMVIYUIkxRyPoflQzwaCiaqn2pxYJFS4GVCuehuEJXDvSw=="], + "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], "stop-iteration-iterator": ["stop-iteration-iterator@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "internal-slot": "^1.1.0" } }, "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ=="], @@ -1281,6 +1416,8 @@ "word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="], + "ws": ["ws@8.19.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg=="], + "xtend": ["xtend@4.0.2", "", {}, "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="], "yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], @@ -1317,6 +1454,18 @@ "@eslint/eslintrc/globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="], + "@solana-program/token-2022/@solana/sysvars": ["@solana/sysvars@5.5.1", "", { "dependencies": { "@solana/accounts": "5.5.1", "@solana/codecs": "5.5.1", "@solana/errors": "5.5.1", "@solana/rpc-types": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-k3Quq87Mm+geGUu1GWv6knPk0ALsfY6EKSJGw9xUJDHzY/RkYSBnh0RiOrUhtFm2TDNjOailg8/m0VHmi3reFA=="], + + "@solana/addresses/@solana/assertions": ["@solana/assertions@6.1.0", "", { "dependencies": { "@solana/errors": "6.1.0" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-pLgxB2xxTk2QfTaWpnRpSMYgaPkKYDQgptRvbwmuDQnOW1Zopg+42MT2UrDGd3UFMML1uOFPxIwKM6m51H0uXw=="], + + "@solana/assertions/@solana/errors": ["@solana/errors@3.0.3", "", { "dependencies": { "chalk": "5.6.2", "commander": "14.0.0" }, "peerDependencies": { "typescript": ">=5.3.3" }, "bin": { "errors": "bin/cli.mjs" } }, "sha512-1l84xJlHNva6io62PcYfUamwWlc0eM95nHgCrKX0g0cLoC6D6QHYPCEbEVkR+C5UtP9JDgyQM8MFiv+Ei5tO9Q=="], + + "@solana/errors/chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], + + "@solana/keys/@solana/assertions": ["@solana/assertions@6.1.0", "", { "dependencies": { "@solana/errors": "6.1.0" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-pLgxB2xxTk2QfTaWpnRpSMYgaPkKYDQgptRvbwmuDQnOW1Zopg+42MT2UrDGd3UFMML1uOFPxIwKM6m51H0uXw=="], + + "@solana/rpc-transport-http/undici-types": ["undici-types@7.22.0", "", {}, "sha512-RKZvifiL60xdsIuC80UY0dq8Z7DbJUV8/l2hOVbyZAxBzEeQU4Z58+4ZzJ6WN2Lidi9KzT5EbiGX+PI/UGYuRw=="], + "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.8.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg=="], "@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.8.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg=="], @@ -1349,6 +1498,10 @@ "@typescript-eslint/typescript-estree/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="], + "@wallet-standard/errors/chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], + + "@wallet-standard/errors/commander": ["commander@13.1.0", "", {}, "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw=="], + "asn1.js/bn.js": ["bn.js@4.12.3", "", {}, "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g=="], "browser-resolve/resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="], @@ -1373,8 +1526,28 @@ "ripemd160/hash-base": ["hash-base@3.1.2", "", { "dependencies": { "inherits": "^2.0.4", "readable-stream": "^2.3.8", "safe-buffer": "^5.2.1", "to-buffer": "^1.2.1" } }, "sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg=="], + "solana-kite/@solana/errors": ["@solana/errors@3.0.3", "", { "dependencies": { "chalk": "5.6.2", "commander": "14.0.0" }, "peerDependencies": { "typescript": ">=5.3.3" }, "bin": { "errors": "bin/cli.mjs" } }, "sha512-1l84xJlHNva6io62PcYfUamwWlc0eM95nHgCrKX0g0cLoC6D6QHYPCEbEVkR+C5UtP9JDgyQM8MFiv+Ei5tO9Q=="], + + "solana-kite/@solana/kit": ["@solana/kit@5.5.1", "", { "dependencies": { "@solana/accounts": "5.5.1", "@solana/addresses": "5.5.1", "@solana/codecs": "5.5.1", "@solana/errors": "5.5.1", "@solana/functional": "5.5.1", "@solana/instruction-plans": "5.5.1", "@solana/instructions": "5.5.1", "@solana/keys": "5.5.1", "@solana/offchain-messages": "5.5.1", "@solana/plugin-core": "5.5.1", "@solana/programs": "5.5.1", "@solana/rpc": "5.5.1", "@solana/rpc-api": "5.5.1", "@solana/rpc-parsed-types": "5.5.1", "@solana/rpc-spec-types": "5.5.1", "@solana/rpc-subscriptions": "5.5.1", "@solana/rpc-types": "5.5.1", "@solana/signers": "5.5.1", "@solana/sysvars": "5.5.1", "@solana/transaction-confirmation": "5.5.1", "@solana/transaction-messages": "5.5.1", "@solana/transactions": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-irKUGiV2yRoyf+4eGQ/ZeCRxa43yjFEL1DUI5B0DkcfZw3cr0VJtVJnrG8OtVF01vT0OUfYOcUn6zJW5TROHvQ=="], + + "solana-kite/@solana/promises": ["@solana/promises@3.0.3", "", { "peerDependencies": { "typescript": ">=5.3.3" } }, "sha512-K+UflGBVxj30XQMHTylHHZJdKH5QG3oj5k2s42GrZ/Wbu72oapVJySMBgpK45+p90t8/LEqV6rRPyTXlet9J+Q=="], + + "solana-kite/@solana/transaction-confirmation": ["@solana/transaction-confirmation@5.5.1", "", { "dependencies": { "@solana/addresses": "5.5.1", "@solana/codecs-strings": "5.5.1", "@solana/errors": "5.5.1", "@solana/keys": "5.5.1", "@solana/promises": "5.5.1", "@solana/rpc": "5.5.1", "@solana/rpc-subscriptions": "5.5.1", "@solana/rpc-types": "5.5.1", "@solana/transaction-messages": "5.5.1", "@solana/transactions": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-j4mKlYPHEyu+OD7MBt3jRoX4ScFgkhZC6H65on4Fux6LMScgivPJlwnKoZMnsgxFgWds0pl+BYzSiALDsXlYtw=="], + "uri-js/punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], + "@solana-program/token-2022/@solana/sysvars/@solana/accounts": ["@solana/accounts@5.5.1", "", { "dependencies": { "@solana/addresses": "5.5.1", "@solana/codecs-core": "5.5.1", "@solana/codecs-strings": "5.5.1", "@solana/errors": "5.5.1", "@solana/rpc-spec": "5.5.1", "@solana/rpc-types": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-TfOY9xixg5rizABuLVuZ9XI2x2tmWUC/OoN556xwfDlhBHBjKfszicYYOyD6nbFmwTGYarCmyGIdteXxTXIdhQ=="], + + "@solana-program/token-2022/@solana/sysvars/@solana/codecs": ["@solana/codecs@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/codecs-data-structures": "5.5.1", "@solana/codecs-numbers": "5.5.1", "@solana/codecs-strings": "5.5.1", "@solana/options": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-Vea29nJub/bXjfzEV7ZZQ/PWr1pYLZo3z0qW0LQL37uKKVzVFRQlwetd7INk3YtTD3xm9WUYr7bCvYUk3uKy2g=="], + + "@solana-program/token-2022/@solana/sysvars/@solana/errors": ["@solana/errors@5.5.1", "", { "dependencies": { "chalk": "5.6.2", "commander": "14.0.2" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"], "bin": { "errors": "bin/cli.mjs" } }, "sha512-vFO3p+S7HoyyrcAectnXbdsMfwUzY2zYFUc2DEe5BwpiE9J1IAxPBGjOWO6hL1bbYdBrlmjNx8DXCslqS+Kcmg=="], + + "@solana-program/token-2022/@solana/sysvars/@solana/rpc-types": ["@solana/rpc-types@5.5.1", "", { "dependencies": { "@solana/addresses": "5.5.1", "@solana/codecs-core": "5.5.1", "@solana/codecs-numbers": "5.5.1", "@solana/codecs-strings": "5.5.1", "@solana/errors": "5.5.1", "@solana/nominal-types": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-bibTFQ7PbHJJjGJPmfYC2I+/5CRFS4O2p9WwbFraX1Keeel+nRrt/NBXIy8veP5AEn2sVJIyJPpWBRpCx1oATA=="], + + "@solana/assertions/@solana/errors/chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], + + "@solana/assertions/@solana/errors/commander": ["commander@14.0.0", "", {}, "sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA=="], + "@trivago/prettier-plugin-sort-imports/@babel/traverse/@babel/code-frame": ["@babel/code-frame@7.28.6", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q=="], "@trivago/prettier-plugin-sort-imports/@babel/traverse/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], @@ -1391,6 +1564,104 @@ "ripemd160/hash-base/readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="], + "solana-kite/@solana/errors/chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], + + "solana-kite/@solana/errors/commander": ["commander@14.0.0", "", {}, "sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA=="], + + "solana-kite/@solana/kit/@solana/accounts": ["@solana/accounts@5.5.1", "", { "dependencies": { "@solana/addresses": "5.5.1", "@solana/codecs-core": "5.5.1", "@solana/codecs-strings": "5.5.1", "@solana/errors": "5.5.1", "@solana/rpc-spec": "5.5.1", "@solana/rpc-types": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-TfOY9xixg5rizABuLVuZ9XI2x2tmWUC/OoN556xwfDlhBHBjKfszicYYOyD6nbFmwTGYarCmyGIdteXxTXIdhQ=="], + + "solana-kite/@solana/kit/@solana/addresses": ["@solana/addresses@5.5.1", "", { "dependencies": { "@solana/assertions": "5.5.1", "@solana/codecs-core": "5.5.1", "@solana/codecs-strings": "5.5.1", "@solana/errors": "5.5.1", "@solana/nominal-types": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-5xoah3Q9G30HQghu/9BiHLb5pzlPKRC3zydQDmE3O9H//WfayxTFppsUDCL6FjYUHqj/wzK6CWHySglc2RkpdA=="], + + "solana-kite/@solana/kit/@solana/codecs": ["@solana/codecs@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/codecs-data-structures": "5.5.1", "@solana/codecs-numbers": "5.5.1", "@solana/codecs-strings": "5.5.1", "@solana/options": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-Vea29nJub/bXjfzEV7ZZQ/PWr1pYLZo3z0qW0LQL37uKKVzVFRQlwetd7INk3YtTD3xm9WUYr7bCvYUk3uKy2g=="], + + "solana-kite/@solana/kit/@solana/errors": ["@solana/errors@5.5.1", "", { "dependencies": { "chalk": "5.6.2", "commander": "14.0.2" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"], "bin": { "errors": "bin/cli.mjs" } }, "sha512-vFO3p+S7HoyyrcAectnXbdsMfwUzY2zYFUc2DEe5BwpiE9J1IAxPBGjOWO6hL1bbYdBrlmjNx8DXCslqS+Kcmg=="], + + "solana-kite/@solana/kit/@solana/functional": ["@solana/functional@5.5.1", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-tTHoJcEQq3gQx5qsdsDJ0LEJeFzwNpXD80xApW9o/PPoCNimI3SALkZl+zNW8VnxRrV3l3yYvfHWBKe/X3WG3w=="], + + "solana-kite/@solana/kit/@solana/instruction-plans": ["@solana/instruction-plans@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1", "@solana/instructions": "5.5.1", "@solana/keys": "5.5.1", "@solana/promises": "5.5.1", "@solana/transaction-messages": "5.5.1", "@solana/transactions": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-7z3CB7YMcFKuVvgcnNY8bY6IsZ8LG61Iytbz7HpNVGX2u1RthOs1tRW8luTzSG1MPL0Ox7afyAVMYeFqSPHnaQ=="], + + "solana-kite/@solana/kit/@solana/instructions": ["@solana/instructions@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-h0G1CG6S+gUUSt0eo6rOtsaXRBwCq1+Js2a+Ps9Bzk9q7YHNFA75/X0NWugWLgC92waRp66hrjMTiYYnLBoWOQ=="], + + "solana-kite/@solana/kit/@solana/keys": ["@solana/keys@5.5.1", "", { "dependencies": { "@solana/assertions": "5.5.1", "@solana/codecs-core": "5.5.1", "@solana/codecs-strings": "5.5.1", "@solana/errors": "5.5.1", "@solana/nominal-types": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-KRD61cL7CRL+b4r/eB9dEoVxIf/2EJ1Pm1DmRYhtSUAJD2dJ5Xw8QFuehobOGm9URqQ7gaQl+Fkc1qvDlsWqKg=="], + + "solana-kite/@solana/kit/@solana/offchain-messages": ["@solana/offchain-messages@5.5.1", "", { "dependencies": { "@solana/addresses": "5.5.1", "@solana/codecs-core": "5.5.1", "@solana/codecs-data-structures": "5.5.1", "@solana/codecs-numbers": "5.5.1", "@solana/codecs-strings": "5.5.1", "@solana/errors": "5.5.1", "@solana/keys": "5.5.1", "@solana/nominal-types": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-g+xHH95prTU+KujtbOzj8wn+C7ZNoiLhf3hj6nYq3MTyxOXtBEysguc97jJveUZG0K97aIKG6xVUlMutg5yxhw=="], + + "solana-kite/@solana/kit/@solana/plugin-core": ["@solana/plugin-core@5.5.1", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-VUZl30lDQFJeiSyNfzU1EjYt2QZvoBFKEwjn1lilUJw7KgqD5z7mbV7diJhT+dLFs36i0OsjXvq5kSygn8YJ3A=="], + + "solana-kite/@solana/kit/@solana/programs": ["@solana/programs@5.5.1", "", { "dependencies": { "@solana/addresses": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-7U9kn0Jsx1NuBLn5HRTFYh78MV4XN145Yc3WP/q5BlqAVNlMoU9coG5IUTJIG847TUqC1lRto3Dnpwm6T4YRpA=="], + + "solana-kite/@solana/kit/@solana/rpc": ["@solana/rpc@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1", "@solana/fast-stable-stringify": "5.5.1", "@solana/functional": "5.5.1", "@solana/rpc-api": "5.5.1", "@solana/rpc-spec": "5.5.1", "@solana/rpc-spec-types": "5.5.1", "@solana/rpc-transformers": "5.5.1", "@solana/rpc-transport-http": "5.5.1", "@solana/rpc-types": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-ku8zTUMrkCWci66PRIBC+1mXepEnZH/q1f3ck0kJZ95a06bOTl5KU7HeXWtskkyefzARJ5zvCs54AD5nxjQJ+A=="], + + "solana-kite/@solana/kit/@solana/rpc-api": ["@solana/rpc-api@5.5.1", "", { "dependencies": { "@solana/addresses": "5.5.1", "@solana/codecs-core": "5.5.1", "@solana/codecs-strings": "5.5.1", "@solana/errors": "5.5.1", "@solana/keys": "5.5.1", "@solana/rpc-parsed-types": "5.5.1", "@solana/rpc-spec": "5.5.1", "@solana/rpc-transformers": "5.5.1", "@solana/rpc-types": "5.5.1", "@solana/transaction-messages": "5.5.1", "@solana/transactions": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-XWOQQPhKl06Vj0xi3RYHAc6oEQd8B82okYJ04K7N0Vvy3J4PN2cxeK7klwkjgavdcN9EVkYCChm2ADAtnztKnA=="], + + "solana-kite/@solana/kit/@solana/rpc-parsed-types": ["@solana/rpc-parsed-types@5.5.1", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-HEi3G2nZqGEsa3vX6U0FrXLaqnUCg4SKIUrOe8CezD+cSFbRTOn3rCLrUmJrhVyXlHoQVaRO9mmeovk31jWxJg=="], + + "solana-kite/@solana/kit/@solana/rpc-spec-types": ["@solana/rpc-spec-types@5.5.1", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-6OFKtRpIEJQs8Jb2C4OO8KyP2h2Hy1MFhatMAoXA+0Ik8S3H+CicIuMZvGZ91mIu/tXicuOOsNNLu3HAkrakrw=="], + + "solana-kite/@solana/kit/@solana/rpc-subscriptions": ["@solana/rpc-subscriptions@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1", "@solana/fast-stable-stringify": "5.5.1", "@solana/functional": "5.5.1", "@solana/promises": "5.5.1", "@solana/rpc-spec-types": "5.5.1", "@solana/rpc-subscriptions-api": "5.5.1", "@solana/rpc-subscriptions-channel-websocket": "5.5.1", "@solana/rpc-subscriptions-spec": "5.5.1", "@solana/rpc-transformers": "5.5.1", "@solana/rpc-types": "5.5.1", "@solana/subscribable": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-CTMy5bt/6mDh4tc6vUJms9EcuZj3xvK0/xq8IQ90rhkpYvate91RjBP+egvjgSayUg9yucU9vNuUpEjz4spM7w=="], + + "solana-kite/@solana/kit/@solana/rpc-types": ["@solana/rpc-types@5.5.1", "", { "dependencies": { "@solana/addresses": "5.5.1", "@solana/codecs-core": "5.5.1", "@solana/codecs-numbers": "5.5.1", "@solana/codecs-strings": "5.5.1", "@solana/errors": "5.5.1", "@solana/nominal-types": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-bibTFQ7PbHJJjGJPmfYC2I+/5CRFS4O2p9WwbFraX1Keeel+nRrt/NBXIy8veP5AEn2sVJIyJPpWBRpCx1oATA=="], + + "solana-kite/@solana/kit/@solana/signers": ["@solana/signers@5.5.1", "", { "dependencies": { "@solana/addresses": "5.5.1", "@solana/codecs-core": "5.5.1", "@solana/errors": "5.5.1", "@solana/instructions": "5.5.1", "@solana/keys": "5.5.1", "@solana/nominal-types": "5.5.1", "@solana/offchain-messages": "5.5.1", "@solana/transaction-messages": "5.5.1", "@solana/transactions": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-FY0IVaBT2kCAze55vEieR6hag4coqcuJ31Aw3hqRH7mv6sV8oqwuJmUrx+uFwOp1gwd5OEAzlv6N4hOOple4sQ=="], + + "solana-kite/@solana/kit/@solana/sysvars": ["@solana/sysvars@5.5.1", "", { "dependencies": { "@solana/accounts": "5.5.1", "@solana/codecs": "5.5.1", "@solana/errors": "5.5.1", "@solana/rpc-types": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-k3Quq87Mm+geGUu1GWv6knPk0ALsfY6EKSJGw9xUJDHzY/RkYSBnh0RiOrUhtFm2TDNjOailg8/m0VHmi3reFA=="], + + "solana-kite/@solana/kit/@solana/transaction-messages": ["@solana/transaction-messages@5.5.1", "", { "dependencies": { "@solana/addresses": "5.5.1", "@solana/codecs-core": "5.5.1", "@solana/codecs-data-structures": "5.5.1", "@solana/codecs-numbers": "5.5.1", "@solana/errors": "5.5.1", "@solana/functional": "5.5.1", "@solana/instructions": "5.5.1", "@solana/nominal-types": "5.5.1", "@solana/rpc-types": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-aXyhMCEaAp3M/4fP0akwBBQkFPr4pfwoC5CLDq999r/FUwDax2RE/h4Ic7h2Xk+JdcUwsb+rLq85Y52hq84XvQ=="], + + "solana-kite/@solana/kit/@solana/transactions": ["@solana/transactions@5.5.1", "", { "dependencies": { "@solana/addresses": "5.5.1", "@solana/codecs-core": "5.5.1", "@solana/codecs-data-structures": "5.5.1", "@solana/codecs-numbers": "5.5.1", "@solana/codecs-strings": "5.5.1", "@solana/errors": "5.5.1", "@solana/functional": "5.5.1", "@solana/instructions": "5.5.1", "@solana/keys": "5.5.1", "@solana/nominal-types": "5.5.1", "@solana/rpc-types": "5.5.1", "@solana/transaction-messages": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-8hHtDxtqalZ157pnx6p8k10D7J/KY/biLzfgh9R09VNLLY3Fqi7kJvJCr7M2ik3oRll56pxhraAGCC9yIT6eOA=="], + + "solana-kite/@solana/transaction-confirmation/@solana/addresses": ["@solana/addresses@5.5.1", "", { "dependencies": { "@solana/assertions": "5.5.1", "@solana/codecs-core": "5.5.1", "@solana/codecs-strings": "5.5.1", "@solana/errors": "5.5.1", "@solana/nominal-types": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-5xoah3Q9G30HQghu/9BiHLb5pzlPKRC3zydQDmE3O9H//WfayxTFppsUDCL6FjYUHqj/wzK6CWHySglc2RkpdA=="], + + "solana-kite/@solana/transaction-confirmation/@solana/codecs-strings": ["@solana/codecs-strings@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/codecs-numbers": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "fastestsmallesttextencoderdecoder": "^1.0.22", "typescript": "^5.0.0" }, "optionalPeers": ["fastestsmallesttextencoderdecoder", "typescript"] }, "sha512-7klX4AhfHYA+uKKC/nxRGP2MntbYQCR3N6+v7bk1W/rSxYuhNmt+FN8aoThSZtWIKwN6BEyR1167ka8Co1+E7A=="], + + "solana-kite/@solana/transaction-confirmation/@solana/errors": ["@solana/errors@5.5.1", "", { "dependencies": { "chalk": "5.6.2", "commander": "14.0.2" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"], "bin": { "errors": "bin/cli.mjs" } }, "sha512-vFO3p+S7HoyyrcAectnXbdsMfwUzY2zYFUc2DEe5BwpiE9J1IAxPBGjOWO6hL1bbYdBrlmjNx8DXCslqS+Kcmg=="], + + "solana-kite/@solana/transaction-confirmation/@solana/keys": ["@solana/keys@5.5.1", "", { "dependencies": { "@solana/assertions": "5.5.1", "@solana/codecs-core": "5.5.1", "@solana/codecs-strings": "5.5.1", "@solana/errors": "5.5.1", "@solana/nominal-types": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-KRD61cL7CRL+b4r/eB9dEoVxIf/2EJ1Pm1DmRYhtSUAJD2dJ5Xw8QFuehobOGm9URqQ7gaQl+Fkc1qvDlsWqKg=="], + + "solana-kite/@solana/transaction-confirmation/@solana/promises": ["@solana/promises@5.5.1", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-T9lfuUYkGykJmppEcssNiCf6yiYQxJkhiLPP+pyAc2z84/7r3UVIb2tNJk4A9sucS66pzJnVHZKcZVGUUp6wzA=="], + + "solana-kite/@solana/transaction-confirmation/@solana/rpc": ["@solana/rpc@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1", "@solana/fast-stable-stringify": "5.5.1", "@solana/functional": "5.5.1", "@solana/rpc-api": "5.5.1", "@solana/rpc-spec": "5.5.1", "@solana/rpc-spec-types": "5.5.1", "@solana/rpc-transformers": "5.5.1", "@solana/rpc-transport-http": "5.5.1", "@solana/rpc-types": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-ku8zTUMrkCWci66PRIBC+1mXepEnZH/q1f3ck0kJZ95a06bOTl5KU7HeXWtskkyefzARJ5zvCs54AD5nxjQJ+A=="], + + "solana-kite/@solana/transaction-confirmation/@solana/rpc-subscriptions": ["@solana/rpc-subscriptions@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1", "@solana/fast-stable-stringify": "5.5.1", "@solana/functional": "5.5.1", "@solana/promises": "5.5.1", "@solana/rpc-spec-types": "5.5.1", "@solana/rpc-subscriptions-api": "5.5.1", "@solana/rpc-subscriptions-channel-websocket": "5.5.1", "@solana/rpc-subscriptions-spec": "5.5.1", "@solana/rpc-transformers": "5.5.1", "@solana/rpc-types": "5.5.1", "@solana/subscribable": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-CTMy5bt/6mDh4tc6vUJms9EcuZj3xvK0/xq8IQ90rhkpYvate91RjBP+egvjgSayUg9yucU9vNuUpEjz4spM7w=="], + + "solana-kite/@solana/transaction-confirmation/@solana/rpc-types": ["@solana/rpc-types@5.5.1", "", { "dependencies": { "@solana/addresses": "5.5.1", "@solana/codecs-core": "5.5.1", "@solana/codecs-numbers": "5.5.1", "@solana/codecs-strings": "5.5.1", "@solana/errors": "5.5.1", "@solana/nominal-types": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-bibTFQ7PbHJJjGJPmfYC2I+/5CRFS4O2p9WwbFraX1Keeel+nRrt/NBXIy8veP5AEn2sVJIyJPpWBRpCx1oATA=="], + + "solana-kite/@solana/transaction-confirmation/@solana/transaction-messages": ["@solana/transaction-messages@5.5.1", "", { "dependencies": { "@solana/addresses": "5.5.1", "@solana/codecs-core": "5.5.1", "@solana/codecs-data-structures": "5.5.1", "@solana/codecs-numbers": "5.5.1", "@solana/errors": "5.5.1", "@solana/functional": "5.5.1", "@solana/instructions": "5.5.1", "@solana/nominal-types": "5.5.1", "@solana/rpc-types": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-aXyhMCEaAp3M/4fP0akwBBQkFPr4pfwoC5CLDq999r/FUwDax2RE/h4Ic7h2Xk+JdcUwsb+rLq85Y52hq84XvQ=="], + + "solana-kite/@solana/transaction-confirmation/@solana/transactions": ["@solana/transactions@5.5.1", "", { "dependencies": { "@solana/addresses": "5.5.1", "@solana/codecs-core": "5.5.1", "@solana/codecs-data-structures": "5.5.1", "@solana/codecs-numbers": "5.5.1", "@solana/codecs-strings": "5.5.1", "@solana/errors": "5.5.1", "@solana/functional": "5.5.1", "@solana/instructions": "5.5.1", "@solana/keys": "5.5.1", "@solana/nominal-types": "5.5.1", "@solana/rpc-types": "5.5.1", "@solana/transaction-messages": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-8hHtDxtqalZ157pnx6p8k10D7J/KY/biLzfgh9R09VNLLY3Fqi7kJvJCr7M2ik3oRll56pxhraAGCC9yIT6eOA=="], + + "@solana-program/token-2022/@solana/sysvars/@solana/accounts/@solana/addresses": ["@solana/addresses@5.5.1", "", { "dependencies": { "@solana/assertions": "5.5.1", "@solana/codecs-core": "5.5.1", "@solana/codecs-strings": "5.5.1", "@solana/errors": "5.5.1", "@solana/nominal-types": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-5xoah3Q9G30HQghu/9BiHLb5pzlPKRC3zydQDmE3O9H//WfayxTFppsUDCL6FjYUHqj/wzK6CWHySglc2RkpdA=="], + + "@solana-program/token-2022/@solana/sysvars/@solana/accounts/@solana/codecs-core": ["@solana/codecs-core@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-TgBt//bbKBct0t6/MpA8ElaOA3sa8eYVvR7LGslCZ84WiAwwjCY0lW/lOYsFHJQzwREMdUyuEyy5YWBKtdh8Rw=="], + + "@solana-program/token-2022/@solana/sysvars/@solana/accounts/@solana/codecs-strings": ["@solana/codecs-strings@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/codecs-numbers": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "fastestsmallesttextencoderdecoder": "^1.0.22", "typescript": "^5.0.0" }, "optionalPeers": ["fastestsmallesttextencoderdecoder", "typescript"] }, "sha512-7klX4AhfHYA+uKKC/nxRGP2MntbYQCR3N6+v7bk1W/rSxYuhNmt+FN8aoThSZtWIKwN6BEyR1167ka8Co1+E7A=="], + + "@solana-program/token-2022/@solana/sysvars/@solana/accounts/@solana/rpc-spec": ["@solana/rpc-spec@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1", "@solana/rpc-spec-types": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-m3LX2bChm3E3by4mQrH4YwCAFY57QBzuUSWqlUw7ChuZ+oLLOq7b2czi4i6L4Vna67j3eCmB3e+4tqy1j5wy7Q=="], + + "@solana-program/token-2022/@solana/sysvars/@solana/codecs/@solana/codecs-core": ["@solana/codecs-core@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-TgBt//bbKBct0t6/MpA8ElaOA3sa8eYVvR7LGslCZ84WiAwwjCY0lW/lOYsFHJQzwREMdUyuEyy5YWBKtdh8Rw=="], + + "@solana-program/token-2022/@solana/sysvars/@solana/codecs/@solana/codecs-data-structures": ["@solana/codecs-data-structures@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/codecs-numbers": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-97bJWGyUY9WvBz3mX1UV3YPWGDTez6btCfD0ip3UVEXJbItVuUiOkzcO5iFDUtQT5riKT6xC+Mzl+0nO76gd0w=="], + + "@solana-program/token-2022/@solana/sysvars/@solana/codecs/@solana/codecs-numbers": ["@solana/codecs-numbers@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-rllMIZAHqmtvC0HO/dc/21wDuWaD0B8Ryv8o+YtsICQBuiL/0U4AGwH7Pi5GNFySYk0/crSuwfIqQFtmxNSPFw=="], + + "@solana-program/token-2022/@solana/sysvars/@solana/codecs/@solana/codecs-strings": ["@solana/codecs-strings@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/codecs-numbers": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "fastestsmallesttextencoderdecoder": "^1.0.22", "typescript": "^5.0.0" }, "optionalPeers": ["fastestsmallesttextencoderdecoder", "typescript"] }, "sha512-7klX4AhfHYA+uKKC/nxRGP2MntbYQCR3N6+v7bk1W/rSxYuhNmt+FN8aoThSZtWIKwN6BEyR1167ka8Co1+E7A=="], + + "@solana-program/token-2022/@solana/sysvars/@solana/codecs/@solana/options": ["@solana/options@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/codecs-data-structures": "5.5.1", "@solana/codecs-numbers": "5.5.1", "@solana/codecs-strings": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-eo971c9iLNLmk+yOFyo7yKIJzJ/zou6uKpy6mBuyb/thKtS/haiKIc3VLhyTXty3OH2PW8yOlORJnv4DexJB8A=="], + + "@solana-program/token-2022/@solana/sysvars/@solana/errors/chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], + + "@solana-program/token-2022/@solana/sysvars/@solana/errors/commander": ["commander@14.0.2", "", {}, "sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ=="], + + "@solana-program/token-2022/@solana/sysvars/@solana/rpc-types/@solana/addresses": ["@solana/addresses@5.5.1", "", { "dependencies": { "@solana/assertions": "5.5.1", "@solana/codecs-core": "5.5.1", "@solana/codecs-strings": "5.5.1", "@solana/errors": "5.5.1", "@solana/nominal-types": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-5xoah3Q9G30HQghu/9BiHLb5pzlPKRC3zydQDmE3O9H//WfayxTFppsUDCL6FjYUHqj/wzK6CWHySglc2RkpdA=="], + + "@solana-program/token-2022/@solana/sysvars/@solana/rpc-types/@solana/codecs-core": ["@solana/codecs-core@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-TgBt//bbKBct0t6/MpA8ElaOA3sa8eYVvR7LGslCZ84WiAwwjCY0lW/lOYsFHJQzwREMdUyuEyy5YWBKtdh8Rw=="], + + "@solana-program/token-2022/@solana/sysvars/@solana/rpc-types/@solana/codecs-numbers": ["@solana/codecs-numbers@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-rllMIZAHqmtvC0HO/dc/21wDuWaD0B8Ryv8o+YtsICQBuiL/0U4AGwH7Pi5GNFySYk0/crSuwfIqQFtmxNSPFw=="], + + "@solana-program/token-2022/@solana/sysvars/@solana/rpc-types/@solana/codecs-strings": ["@solana/codecs-strings@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/codecs-numbers": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "fastestsmallesttextencoderdecoder": "^1.0.22", "typescript": "^5.0.0" }, "optionalPeers": ["fastestsmallesttextencoderdecoder", "typescript"] }, "sha512-7klX4AhfHYA+uKKC/nxRGP2MntbYQCR3N6+v7bk1W/rSxYuhNmt+FN8aoThSZtWIKwN6BEyR1167ka8Co1+E7A=="], + + "@solana-program/token-2022/@solana/sysvars/@solana/rpc-types/@solana/nominal-types": ["@solana/nominal-types@5.5.1", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-I1ImR+kfrLFxN5z22UDiTWLdRZeKtU0J/pkWkO8qm/8WxveiwdIv4hooi8pb6JnlR4mSrWhq0pCIOxDYrL9GIQ=="], + "md5.js/hash-base/readable-stream/isarray": ["isarray@1.0.0", "", {}, "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="], "md5.js/hash-base/readable-stream/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="], @@ -1402,5 +1673,231 @@ "ripemd160/hash-base/readable-stream/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="], "ripemd160/hash-base/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="], + + "solana-kite/@solana/kit/@solana/accounts/@solana/codecs-core": ["@solana/codecs-core@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-TgBt//bbKBct0t6/MpA8ElaOA3sa8eYVvR7LGslCZ84WiAwwjCY0lW/lOYsFHJQzwREMdUyuEyy5YWBKtdh8Rw=="], + + "solana-kite/@solana/kit/@solana/accounts/@solana/codecs-strings": ["@solana/codecs-strings@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/codecs-numbers": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "fastestsmallesttextencoderdecoder": "^1.0.22", "typescript": "^5.0.0" }, "optionalPeers": ["fastestsmallesttextencoderdecoder", "typescript"] }, "sha512-7klX4AhfHYA+uKKC/nxRGP2MntbYQCR3N6+v7bk1W/rSxYuhNmt+FN8aoThSZtWIKwN6BEyR1167ka8Co1+E7A=="], + + "solana-kite/@solana/kit/@solana/accounts/@solana/rpc-spec": ["@solana/rpc-spec@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1", "@solana/rpc-spec-types": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-m3LX2bChm3E3by4mQrH4YwCAFY57QBzuUSWqlUw7ChuZ+oLLOq7b2czi4i6L4Vna67j3eCmB3e+4tqy1j5wy7Q=="], + + "solana-kite/@solana/kit/@solana/addresses/@solana/assertions": ["@solana/assertions@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-YTCSWAlGwSlVPnWtWLm3ukz81wH4j2YaCveK+TjpvUU88hTy6fmUqxi0+hvAMAe4zKXpJyj3Az7BrLJRxbIm4Q=="], + + "solana-kite/@solana/kit/@solana/addresses/@solana/codecs-core": ["@solana/codecs-core@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-TgBt//bbKBct0t6/MpA8ElaOA3sa8eYVvR7LGslCZ84WiAwwjCY0lW/lOYsFHJQzwREMdUyuEyy5YWBKtdh8Rw=="], + + "solana-kite/@solana/kit/@solana/addresses/@solana/codecs-strings": ["@solana/codecs-strings@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/codecs-numbers": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "fastestsmallesttextencoderdecoder": "^1.0.22", "typescript": "^5.0.0" }, "optionalPeers": ["fastestsmallesttextencoderdecoder", "typescript"] }, "sha512-7klX4AhfHYA+uKKC/nxRGP2MntbYQCR3N6+v7bk1W/rSxYuhNmt+FN8aoThSZtWIKwN6BEyR1167ka8Co1+E7A=="], + + "solana-kite/@solana/kit/@solana/addresses/@solana/nominal-types": ["@solana/nominal-types@5.5.1", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-I1ImR+kfrLFxN5z22UDiTWLdRZeKtU0J/pkWkO8qm/8WxveiwdIv4hooi8pb6JnlR4mSrWhq0pCIOxDYrL9GIQ=="], + + "solana-kite/@solana/kit/@solana/codecs/@solana/codecs-core": ["@solana/codecs-core@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-TgBt//bbKBct0t6/MpA8ElaOA3sa8eYVvR7LGslCZ84WiAwwjCY0lW/lOYsFHJQzwREMdUyuEyy5YWBKtdh8Rw=="], + + "solana-kite/@solana/kit/@solana/codecs/@solana/codecs-data-structures": ["@solana/codecs-data-structures@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/codecs-numbers": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-97bJWGyUY9WvBz3mX1UV3YPWGDTez6btCfD0ip3UVEXJbItVuUiOkzcO5iFDUtQT5riKT6xC+Mzl+0nO76gd0w=="], + + "solana-kite/@solana/kit/@solana/codecs/@solana/codecs-numbers": ["@solana/codecs-numbers@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-rllMIZAHqmtvC0HO/dc/21wDuWaD0B8Ryv8o+YtsICQBuiL/0U4AGwH7Pi5GNFySYk0/crSuwfIqQFtmxNSPFw=="], + + "solana-kite/@solana/kit/@solana/codecs/@solana/codecs-strings": ["@solana/codecs-strings@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/codecs-numbers": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "fastestsmallesttextencoderdecoder": "^1.0.22", "typescript": "^5.0.0" }, "optionalPeers": ["fastestsmallesttextencoderdecoder", "typescript"] }, "sha512-7klX4AhfHYA+uKKC/nxRGP2MntbYQCR3N6+v7bk1W/rSxYuhNmt+FN8aoThSZtWIKwN6BEyR1167ka8Co1+E7A=="], + + "solana-kite/@solana/kit/@solana/codecs/@solana/options": ["@solana/options@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/codecs-data-structures": "5.5.1", "@solana/codecs-numbers": "5.5.1", "@solana/codecs-strings": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-eo971c9iLNLmk+yOFyo7yKIJzJ/zou6uKpy6mBuyb/thKtS/haiKIc3VLhyTXty3OH2PW8yOlORJnv4DexJB8A=="], + + "solana-kite/@solana/kit/@solana/errors/chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], + + "solana-kite/@solana/kit/@solana/errors/commander": ["commander@14.0.2", "", {}, "sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ=="], + + "solana-kite/@solana/kit/@solana/instruction-plans/@solana/promises": ["@solana/promises@5.5.1", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-T9lfuUYkGykJmppEcssNiCf6yiYQxJkhiLPP+pyAc2z84/7r3UVIb2tNJk4A9sucS66pzJnVHZKcZVGUUp6wzA=="], + + "solana-kite/@solana/kit/@solana/instructions/@solana/codecs-core": ["@solana/codecs-core@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-TgBt//bbKBct0t6/MpA8ElaOA3sa8eYVvR7LGslCZ84WiAwwjCY0lW/lOYsFHJQzwREMdUyuEyy5YWBKtdh8Rw=="], + + "solana-kite/@solana/kit/@solana/keys/@solana/assertions": ["@solana/assertions@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-YTCSWAlGwSlVPnWtWLm3ukz81wH4j2YaCveK+TjpvUU88hTy6fmUqxi0+hvAMAe4zKXpJyj3Az7BrLJRxbIm4Q=="], + + "solana-kite/@solana/kit/@solana/keys/@solana/codecs-core": ["@solana/codecs-core@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-TgBt//bbKBct0t6/MpA8ElaOA3sa8eYVvR7LGslCZ84WiAwwjCY0lW/lOYsFHJQzwREMdUyuEyy5YWBKtdh8Rw=="], + + "solana-kite/@solana/kit/@solana/keys/@solana/codecs-strings": ["@solana/codecs-strings@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/codecs-numbers": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "fastestsmallesttextencoderdecoder": "^1.0.22", "typescript": "^5.0.0" }, "optionalPeers": ["fastestsmallesttextencoderdecoder", "typescript"] }, "sha512-7klX4AhfHYA+uKKC/nxRGP2MntbYQCR3N6+v7bk1W/rSxYuhNmt+FN8aoThSZtWIKwN6BEyR1167ka8Co1+E7A=="], + + "solana-kite/@solana/kit/@solana/keys/@solana/nominal-types": ["@solana/nominal-types@5.5.1", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-I1ImR+kfrLFxN5z22UDiTWLdRZeKtU0J/pkWkO8qm/8WxveiwdIv4hooi8pb6JnlR4mSrWhq0pCIOxDYrL9GIQ=="], + + "solana-kite/@solana/kit/@solana/offchain-messages/@solana/codecs-core": ["@solana/codecs-core@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-TgBt//bbKBct0t6/MpA8ElaOA3sa8eYVvR7LGslCZ84WiAwwjCY0lW/lOYsFHJQzwREMdUyuEyy5YWBKtdh8Rw=="], + + "solana-kite/@solana/kit/@solana/offchain-messages/@solana/codecs-data-structures": ["@solana/codecs-data-structures@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/codecs-numbers": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-97bJWGyUY9WvBz3mX1UV3YPWGDTez6btCfD0ip3UVEXJbItVuUiOkzcO5iFDUtQT5riKT6xC+Mzl+0nO76gd0w=="], + + "solana-kite/@solana/kit/@solana/offchain-messages/@solana/codecs-numbers": ["@solana/codecs-numbers@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-rllMIZAHqmtvC0HO/dc/21wDuWaD0B8Ryv8o+YtsICQBuiL/0U4AGwH7Pi5GNFySYk0/crSuwfIqQFtmxNSPFw=="], + + "solana-kite/@solana/kit/@solana/offchain-messages/@solana/codecs-strings": ["@solana/codecs-strings@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/codecs-numbers": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "fastestsmallesttextencoderdecoder": "^1.0.22", "typescript": "^5.0.0" }, "optionalPeers": ["fastestsmallesttextencoderdecoder", "typescript"] }, "sha512-7klX4AhfHYA+uKKC/nxRGP2MntbYQCR3N6+v7bk1W/rSxYuhNmt+FN8aoThSZtWIKwN6BEyR1167ka8Co1+E7A=="], + + "solana-kite/@solana/kit/@solana/offchain-messages/@solana/nominal-types": ["@solana/nominal-types@5.5.1", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-I1ImR+kfrLFxN5z22UDiTWLdRZeKtU0J/pkWkO8qm/8WxveiwdIv4hooi8pb6JnlR4mSrWhq0pCIOxDYrL9GIQ=="], + + "solana-kite/@solana/kit/@solana/rpc/@solana/fast-stable-stringify": ["@solana/fast-stable-stringify@5.5.1", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-Ni7s2FN33zTzhTFgRjEbOVFO+UAmK8qi3Iu0/GRFYK4jN696OjKHnboSQH/EacQ+yGqS54bfxf409wU5dsLLCw=="], + + "solana-kite/@solana/kit/@solana/rpc/@solana/rpc-spec": ["@solana/rpc-spec@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1", "@solana/rpc-spec-types": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-m3LX2bChm3E3by4mQrH4YwCAFY57QBzuUSWqlUw7ChuZ+oLLOq7b2czi4i6L4Vna67j3eCmB3e+4tqy1j5wy7Q=="], + + "solana-kite/@solana/kit/@solana/rpc/@solana/rpc-transformers": ["@solana/rpc-transformers@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1", "@solana/functional": "5.5.1", "@solana/nominal-types": "5.5.1", "@solana/rpc-spec-types": "5.5.1", "@solana/rpc-types": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-OsWqLCQdcrRJKvHiMmwFhp9noNZ4FARuMkHT5us3ustDLXaxOjF0gfqZLnMkulSLcKt7TGXqMhBV+HCo7z5M8Q=="], + + "solana-kite/@solana/kit/@solana/rpc/@solana/rpc-transport-http": ["@solana/rpc-transport-http@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1", "@solana/rpc-spec": "5.5.1", "@solana/rpc-spec-types": "5.5.1", "undici-types": "^7.19.2" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-yv8GoVSHqEV0kUJEIhkdOVkR2SvJ6yoWC51cJn2rSV7plr6huLGe0JgujCmB7uZhhaLbcbP3zxXxu9sOjsi7Fg=="], + + "solana-kite/@solana/kit/@solana/rpc-api/@solana/codecs-core": ["@solana/codecs-core@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-TgBt//bbKBct0t6/MpA8ElaOA3sa8eYVvR7LGslCZ84WiAwwjCY0lW/lOYsFHJQzwREMdUyuEyy5YWBKtdh8Rw=="], + + "solana-kite/@solana/kit/@solana/rpc-api/@solana/codecs-strings": ["@solana/codecs-strings@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/codecs-numbers": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "fastestsmallesttextencoderdecoder": "^1.0.22", "typescript": "^5.0.0" }, "optionalPeers": ["fastestsmallesttextencoderdecoder", "typescript"] }, "sha512-7klX4AhfHYA+uKKC/nxRGP2MntbYQCR3N6+v7bk1W/rSxYuhNmt+FN8aoThSZtWIKwN6BEyR1167ka8Co1+E7A=="], + + "solana-kite/@solana/kit/@solana/rpc-api/@solana/rpc-spec": ["@solana/rpc-spec@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1", "@solana/rpc-spec-types": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-m3LX2bChm3E3by4mQrH4YwCAFY57QBzuUSWqlUw7ChuZ+oLLOq7b2czi4i6L4Vna67j3eCmB3e+4tqy1j5wy7Q=="], + + "solana-kite/@solana/kit/@solana/rpc-api/@solana/rpc-transformers": ["@solana/rpc-transformers@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1", "@solana/functional": "5.5.1", "@solana/nominal-types": "5.5.1", "@solana/rpc-spec-types": "5.5.1", "@solana/rpc-types": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-OsWqLCQdcrRJKvHiMmwFhp9noNZ4FARuMkHT5us3ustDLXaxOjF0gfqZLnMkulSLcKt7TGXqMhBV+HCo7z5M8Q=="], + + "solana-kite/@solana/kit/@solana/rpc-subscriptions/@solana/fast-stable-stringify": ["@solana/fast-stable-stringify@5.5.1", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-Ni7s2FN33zTzhTFgRjEbOVFO+UAmK8qi3Iu0/GRFYK4jN696OjKHnboSQH/EacQ+yGqS54bfxf409wU5dsLLCw=="], + + "solana-kite/@solana/kit/@solana/rpc-subscriptions/@solana/promises": ["@solana/promises@5.5.1", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-T9lfuUYkGykJmppEcssNiCf6yiYQxJkhiLPP+pyAc2z84/7r3UVIb2tNJk4A9sucS66pzJnVHZKcZVGUUp6wzA=="], + + "solana-kite/@solana/kit/@solana/rpc-subscriptions/@solana/rpc-subscriptions-api": ["@solana/rpc-subscriptions-api@5.5.1", "", { "dependencies": { "@solana/addresses": "5.5.1", "@solana/keys": "5.5.1", "@solana/rpc-subscriptions-spec": "5.5.1", "@solana/rpc-transformers": "5.5.1", "@solana/rpc-types": "5.5.1", "@solana/transaction-messages": "5.5.1", "@solana/transactions": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-5Oi7k+GdeS8xR2ly1iuSFkAv6CZqwG0Z6b1QZKbEgxadE1XGSDrhM2cn59l+bqCozUWCqh4c/A2znU/qQjROlw=="], + + "solana-kite/@solana/kit/@solana/rpc-subscriptions/@solana/rpc-subscriptions-channel-websocket": ["@solana/rpc-subscriptions-channel-websocket@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1", "@solana/functional": "5.5.1", "@solana/rpc-subscriptions-spec": "5.5.1", "@solana/subscribable": "5.5.1", "ws": "^8.19.0" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-7tGfBBrYY8TrngOyxSHoCU5shy86iA9SRMRrPSyBhEaZRAk6dnbdpmUTez7gtdVo0BCvh9nzQtUycKWSS7PnFQ=="], + + "solana-kite/@solana/kit/@solana/rpc-subscriptions/@solana/rpc-subscriptions-spec": ["@solana/rpc-subscriptions-spec@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1", "@solana/promises": "5.5.1", "@solana/rpc-spec-types": "5.5.1", "@solana/subscribable": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-iq+rGq5fMKP3/mKHPNB6MC8IbVW41KGZg83Us/+LE3AWOTWV1WT20KT2iH1F1ik9roi42COv/TpoZZvhKj45XQ=="], + + "solana-kite/@solana/kit/@solana/rpc-subscriptions/@solana/rpc-transformers": ["@solana/rpc-transformers@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1", "@solana/functional": "5.5.1", "@solana/nominal-types": "5.5.1", "@solana/rpc-spec-types": "5.5.1", "@solana/rpc-types": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-OsWqLCQdcrRJKvHiMmwFhp9noNZ4FARuMkHT5us3ustDLXaxOjF0gfqZLnMkulSLcKt7TGXqMhBV+HCo7z5M8Q=="], + + "solana-kite/@solana/kit/@solana/rpc-subscriptions/@solana/subscribable": ["@solana/subscribable@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-9K0PsynFq0CsmK1CDi5Y2vUIJpCqkgSS5yfDN0eKPgHqEptLEaia09Kaxc90cSZDZU5mKY/zv1NBmB6Aro9zQQ=="], + + "solana-kite/@solana/kit/@solana/rpc-types/@solana/codecs-core": ["@solana/codecs-core@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-TgBt//bbKBct0t6/MpA8ElaOA3sa8eYVvR7LGslCZ84WiAwwjCY0lW/lOYsFHJQzwREMdUyuEyy5YWBKtdh8Rw=="], + + "solana-kite/@solana/kit/@solana/rpc-types/@solana/codecs-numbers": ["@solana/codecs-numbers@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-rllMIZAHqmtvC0HO/dc/21wDuWaD0B8Ryv8o+YtsICQBuiL/0U4AGwH7Pi5GNFySYk0/crSuwfIqQFtmxNSPFw=="], + + "solana-kite/@solana/kit/@solana/rpc-types/@solana/codecs-strings": ["@solana/codecs-strings@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/codecs-numbers": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "fastestsmallesttextencoderdecoder": "^1.0.22", "typescript": "^5.0.0" }, "optionalPeers": ["fastestsmallesttextencoderdecoder", "typescript"] }, "sha512-7klX4AhfHYA+uKKC/nxRGP2MntbYQCR3N6+v7bk1W/rSxYuhNmt+FN8aoThSZtWIKwN6BEyR1167ka8Co1+E7A=="], + + "solana-kite/@solana/kit/@solana/rpc-types/@solana/nominal-types": ["@solana/nominal-types@5.5.1", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-I1ImR+kfrLFxN5z22UDiTWLdRZeKtU0J/pkWkO8qm/8WxveiwdIv4hooi8pb6JnlR4mSrWhq0pCIOxDYrL9GIQ=="], + + "solana-kite/@solana/kit/@solana/signers/@solana/codecs-core": ["@solana/codecs-core@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-TgBt//bbKBct0t6/MpA8ElaOA3sa8eYVvR7LGslCZ84WiAwwjCY0lW/lOYsFHJQzwREMdUyuEyy5YWBKtdh8Rw=="], + + "solana-kite/@solana/kit/@solana/signers/@solana/nominal-types": ["@solana/nominal-types@5.5.1", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-I1ImR+kfrLFxN5z22UDiTWLdRZeKtU0J/pkWkO8qm/8WxveiwdIv4hooi8pb6JnlR4mSrWhq0pCIOxDYrL9GIQ=="], + + "solana-kite/@solana/kit/@solana/transaction-messages/@solana/codecs-core": ["@solana/codecs-core@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-TgBt//bbKBct0t6/MpA8ElaOA3sa8eYVvR7LGslCZ84WiAwwjCY0lW/lOYsFHJQzwREMdUyuEyy5YWBKtdh8Rw=="], + + "solana-kite/@solana/kit/@solana/transaction-messages/@solana/codecs-data-structures": ["@solana/codecs-data-structures@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/codecs-numbers": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-97bJWGyUY9WvBz3mX1UV3YPWGDTez6btCfD0ip3UVEXJbItVuUiOkzcO5iFDUtQT5riKT6xC+Mzl+0nO76gd0w=="], + + "solana-kite/@solana/kit/@solana/transaction-messages/@solana/codecs-numbers": ["@solana/codecs-numbers@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-rllMIZAHqmtvC0HO/dc/21wDuWaD0B8Ryv8o+YtsICQBuiL/0U4AGwH7Pi5GNFySYk0/crSuwfIqQFtmxNSPFw=="], + + "solana-kite/@solana/kit/@solana/transaction-messages/@solana/nominal-types": ["@solana/nominal-types@5.5.1", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-I1ImR+kfrLFxN5z22UDiTWLdRZeKtU0J/pkWkO8qm/8WxveiwdIv4hooi8pb6JnlR4mSrWhq0pCIOxDYrL9GIQ=="], + + "solana-kite/@solana/kit/@solana/transactions/@solana/codecs-core": ["@solana/codecs-core@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-TgBt//bbKBct0t6/MpA8ElaOA3sa8eYVvR7LGslCZ84WiAwwjCY0lW/lOYsFHJQzwREMdUyuEyy5YWBKtdh8Rw=="], + + "solana-kite/@solana/kit/@solana/transactions/@solana/codecs-data-structures": ["@solana/codecs-data-structures@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/codecs-numbers": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-97bJWGyUY9WvBz3mX1UV3YPWGDTez6btCfD0ip3UVEXJbItVuUiOkzcO5iFDUtQT5riKT6xC+Mzl+0nO76gd0w=="], + + "solana-kite/@solana/kit/@solana/transactions/@solana/codecs-numbers": ["@solana/codecs-numbers@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-rllMIZAHqmtvC0HO/dc/21wDuWaD0B8Ryv8o+YtsICQBuiL/0U4AGwH7Pi5GNFySYk0/crSuwfIqQFtmxNSPFw=="], + + "solana-kite/@solana/kit/@solana/transactions/@solana/codecs-strings": ["@solana/codecs-strings@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/codecs-numbers": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "fastestsmallesttextencoderdecoder": "^1.0.22", "typescript": "^5.0.0" }, "optionalPeers": ["fastestsmallesttextencoderdecoder", "typescript"] }, "sha512-7klX4AhfHYA+uKKC/nxRGP2MntbYQCR3N6+v7bk1W/rSxYuhNmt+FN8aoThSZtWIKwN6BEyR1167ka8Co1+E7A=="], + + "solana-kite/@solana/kit/@solana/transactions/@solana/nominal-types": ["@solana/nominal-types@5.5.1", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-I1ImR+kfrLFxN5z22UDiTWLdRZeKtU0J/pkWkO8qm/8WxveiwdIv4hooi8pb6JnlR4mSrWhq0pCIOxDYrL9GIQ=="], + + "solana-kite/@solana/transaction-confirmation/@solana/addresses/@solana/assertions": ["@solana/assertions@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-YTCSWAlGwSlVPnWtWLm3ukz81wH4j2YaCveK+TjpvUU88hTy6fmUqxi0+hvAMAe4zKXpJyj3Az7BrLJRxbIm4Q=="], + + "solana-kite/@solana/transaction-confirmation/@solana/addresses/@solana/codecs-core": ["@solana/codecs-core@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-TgBt//bbKBct0t6/MpA8ElaOA3sa8eYVvR7LGslCZ84WiAwwjCY0lW/lOYsFHJQzwREMdUyuEyy5YWBKtdh8Rw=="], + + "solana-kite/@solana/transaction-confirmation/@solana/addresses/@solana/nominal-types": ["@solana/nominal-types@5.5.1", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-I1ImR+kfrLFxN5z22UDiTWLdRZeKtU0J/pkWkO8qm/8WxveiwdIv4hooi8pb6JnlR4mSrWhq0pCIOxDYrL9GIQ=="], + + "solana-kite/@solana/transaction-confirmation/@solana/codecs-strings/@solana/codecs-core": ["@solana/codecs-core@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-TgBt//bbKBct0t6/MpA8ElaOA3sa8eYVvR7LGslCZ84WiAwwjCY0lW/lOYsFHJQzwREMdUyuEyy5YWBKtdh8Rw=="], + + "solana-kite/@solana/transaction-confirmation/@solana/codecs-strings/@solana/codecs-numbers": ["@solana/codecs-numbers@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-rllMIZAHqmtvC0HO/dc/21wDuWaD0B8Ryv8o+YtsICQBuiL/0U4AGwH7Pi5GNFySYk0/crSuwfIqQFtmxNSPFw=="], + + "solana-kite/@solana/transaction-confirmation/@solana/errors/chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], + + "solana-kite/@solana/transaction-confirmation/@solana/errors/commander": ["commander@14.0.2", "", {}, "sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ=="], + + "solana-kite/@solana/transaction-confirmation/@solana/keys/@solana/assertions": ["@solana/assertions@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-YTCSWAlGwSlVPnWtWLm3ukz81wH4j2YaCveK+TjpvUU88hTy6fmUqxi0+hvAMAe4zKXpJyj3Az7BrLJRxbIm4Q=="], + + "solana-kite/@solana/transaction-confirmation/@solana/keys/@solana/codecs-core": ["@solana/codecs-core@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-TgBt//bbKBct0t6/MpA8ElaOA3sa8eYVvR7LGslCZ84WiAwwjCY0lW/lOYsFHJQzwREMdUyuEyy5YWBKtdh8Rw=="], + + "solana-kite/@solana/transaction-confirmation/@solana/keys/@solana/nominal-types": ["@solana/nominal-types@5.5.1", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-I1ImR+kfrLFxN5z22UDiTWLdRZeKtU0J/pkWkO8qm/8WxveiwdIv4hooi8pb6JnlR4mSrWhq0pCIOxDYrL9GIQ=="], + + "solana-kite/@solana/transaction-confirmation/@solana/rpc/@solana/fast-stable-stringify": ["@solana/fast-stable-stringify@5.5.1", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-Ni7s2FN33zTzhTFgRjEbOVFO+UAmK8qi3Iu0/GRFYK4jN696OjKHnboSQH/EacQ+yGqS54bfxf409wU5dsLLCw=="], + + "solana-kite/@solana/transaction-confirmation/@solana/rpc/@solana/functional": ["@solana/functional@5.5.1", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-tTHoJcEQq3gQx5qsdsDJ0LEJeFzwNpXD80xApW9o/PPoCNimI3SALkZl+zNW8VnxRrV3l3yYvfHWBKe/X3WG3w=="], + + "solana-kite/@solana/transaction-confirmation/@solana/rpc/@solana/rpc-api": ["@solana/rpc-api@5.5.1", "", { "dependencies": { "@solana/addresses": "5.5.1", "@solana/codecs-core": "5.5.1", "@solana/codecs-strings": "5.5.1", "@solana/errors": "5.5.1", "@solana/keys": "5.5.1", "@solana/rpc-parsed-types": "5.5.1", "@solana/rpc-spec": "5.5.1", "@solana/rpc-transformers": "5.5.1", "@solana/rpc-types": "5.5.1", "@solana/transaction-messages": "5.5.1", "@solana/transactions": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-XWOQQPhKl06Vj0xi3RYHAc6oEQd8B82okYJ04K7N0Vvy3J4PN2cxeK7klwkjgavdcN9EVkYCChm2ADAtnztKnA=="], + + "solana-kite/@solana/transaction-confirmation/@solana/rpc/@solana/rpc-spec": ["@solana/rpc-spec@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1", "@solana/rpc-spec-types": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-m3LX2bChm3E3by4mQrH4YwCAFY57QBzuUSWqlUw7ChuZ+oLLOq7b2czi4i6L4Vna67j3eCmB3e+4tqy1j5wy7Q=="], + + "solana-kite/@solana/transaction-confirmation/@solana/rpc/@solana/rpc-spec-types": ["@solana/rpc-spec-types@5.5.1", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-6OFKtRpIEJQs8Jb2C4OO8KyP2h2Hy1MFhatMAoXA+0Ik8S3H+CicIuMZvGZ91mIu/tXicuOOsNNLu3HAkrakrw=="], + + "solana-kite/@solana/transaction-confirmation/@solana/rpc/@solana/rpc-transformers": ["@solana/rpc-transformers@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1", "@solana/functional": "5.5.1", "@solana/nominal-types": "5.5.1", "@solana/rpc-spec-types": "5.5.1", "@solana/rpc-types": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-OsWqLCQdcrRJKvHiMmwFhp9noNZ4FARuMkHT5us3ustDLXaxOjF0gfqZLnMkulSLcKt7TGXqMhBV+HCo7z5M8Q=="], + + "solana-kite/@solana/transaction-confirmation/@solana/rpc/@solana/rpc-transport-http": ["@solana/rpc-transport-http@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1", "@solana/rpc-spec": "5.5.1", "@solana/rpc-spec-types": "5.5.1", "undici-types": "^7.19.2" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-yv8GoVSHqEV0kUJEIhkdOVkR2SvJ6yoWC51cJn2rSV7plr6huLGe0JgujCmB7uZhhaLbcbP3zxXxu9sOjsi7Fg=="], + + "solana-kite/@solana/transaction-confirmation/@solana/rpc-subscriptions/@solana/fast-stable-stringify": ["@solana/fast-stable-stringify@5.5.1", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-Ni7s2FN33zTzhTFgRjEbOVFO+UAmK8qi3Iu0/GRFYK4jN696OjKHnboSQH/EacQ+yGqS54bfxf409wU5dsLLCw=="], + + "solana-kite/@solana/transaction-confirmation/@solana/rpc-subscriptions/@solana/functional": ["@solana/functional@5.5.1", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-tTHoJcEQq3gQx5qsdsDJ0LEJeFzwNpXD80xApW9o/PPoCNimI3SALkZl+zNW8VnxRrV3l3yYvfHWBKe/X3WG3w=="], + + "solana-kite/@solana/transaction-confirmation/@solana/rpc-subscriptions/@solana/rpc-spec-types": ["@solana/rpc-spec-types@5.5.1", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-6OFKtRpIEJQs8Jb2C4OO8KyP2h2Hy1MFhatMAoXA+0Ik8S3H+CicIuMZvGZ91mIu/tXicuOOsNNLu3HAkrakrw=="], + + "solana-kite/@solana/transaction-confirmation/@solana/rpc-subscriptions/@solana/rpc-subscriptions-api": ["@solana/rpc-subscriptions-api@5.5.1", "", { "dependencies": { "@solana/addresses": "5.5.1", "@solana/keys": "5.5.1", "@solana/rpc-subscriptions-spec": "5.5.1", "@solana/rpc-transformers": "5.5.1", "@solana/rpc-types": "5.5.1", "@solana/transaction-messages": "5.5.1", "@solana/transactions": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-5Oi7k+GdeS8xR2ly1iuSFkAv6CZqwG0Z6b1QZKbEgxadE1XGSDrhM2cn59l+bqCozUWCqh4c/A2znU/qQjROlw=="], + + "solana-kite/@solana/transaction-confirmation/@solana/rpc-subscriptions/@solana/rpc-subscriptions-channel-websocket": ["@solana/rpc-subscriptions-channel-websocket@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1", "@solana/functional": "5.5.1", "@solana/rpc-subscriptions-spec": "5.5.1", "@solana/subscribable": "5.5.1", "ws": "^8.19.0" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-7tGfBBrYY8TrngOyxSHoCU5shy86iA9SRMRrPSyBhEaZRAk6dnbdpmUTez7gtdVo0BCvh9nzQtUycKWSS7PnFQ=="], + + "solana-kite/@solana/transaction-confirmation/@solana/rpc-subscriptions/@solana/rpc-subscriptions-spec": ["@solana/rpc-subscriptions-spec@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1", "@solana/promises": "5.5.1", "@solana/rpc-spec-types": "5.5.1", "@solana/subscribable": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-iq+rGq5fMKP3/mKHPNB6MC8IbVW41KGZg83Us/+LE3AWOTWV1WT20KT2iH1F1ik9roi42COv/TpoZZvhKj45XQ=="], + + "solana-kite/@solana/transaction-confirmation/@solana/rpc-subscriptions/@solana/rpc-transformers": ["@solana/rpc-transformers@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1", "@solana/functional": "5.5.1", "@solana/nominal-types": "5.5.1", "@solana/rpc-spec-types": "5.5.1", "@solana/rpc-types": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-OsWqLCQdcrRJKvHiMmwFhp9noNZ4FARuMkHT5us3ustDLXaxOjF0gfqZLnMkulSLcKt7TGXqMhBV+HCo7z5M8Q=="], + + "solana-kite/@solana/transaction-confirmation/@solana/rpc-subscriptions/@solana/subscribable": ["@solana/subscribable@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-9K0PsynFq0CsmK1CDi5Y2vUIJpCqkgSS5yfDN0eKPgHqEptLEaia09Kaxc90cSZDZU5mKY/zv1NBmB6Aro9zQQ=="], + + "solana-kite/@solana/transaction-confirmation/@solana/rpc-types/@solana/codecs-core": ["@solana/codecs-core@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-TgBt//bbKBct0t6/MpA8ElaOA3sa8eYVvR7LGslCZ84WiAwwjCY0lW/lOYsFHJQzwREMdUyuEyy5YWBKtdh8Rw=="], + + "solana-kite/@solana/transaction-confirmation/@solana/rpc-types/@solana/codecs-numbers": ["@solana/codecs-numbers@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-rllMIZAHqmtvC0HO/dc/21wDuWaD0B8Ryv8o+YtsICQBuiL/0U4AGwH7Pi5GNFySYk0/crSuwfIqQFtmxNSPFw=="], + + "solana-kite/@solana/transaction-confirmation/@solana/rpc-types/@solana/nominal-types": ["@solana/nominal-types@5.5.1", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-I1ImR+kfrLFxN5z22UDiTWLdRZeKtU0J/pkWkO8qm/8WxveiwdIv4hooi8pb6JnlR4mSrWhq0pCIOxDYrL9GIQ=="], + + "solana-kite/@solana/transaction-confirmation/@solana/transaction-messages/@solana/codecs-core": ["@solana/codecs-core@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-TgBt//bbKBct0t6/MpA8ElaOA3sa8eYVvR7LGslCZ84WiAwwjCY0lW/lOYsFHJQzwREMdUyuEyy5YWBKtdh8Rw=="], + + "solana-kite/@solana/transaction-confirmation/@solana/transaction-messages/@solana/codecs-data-structures": ["@solana/codecs-data-structures@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/codecs-numbers": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-97bJWGyUY9WvBz3mX1UV3YPWGDTez6btCfD0ip3UVEXJbItVuUiOkzcO5iFDUtQT5riKT6xC+Mzl+0nO76gd0w=="], + + "solana-kite/@solana/transaction-confirmation/@solana/transaction-messages/@solana/codecs-numbers": ["@solana/codecs-numbers@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-rllMIZAHqmtvC0HO/dc/21wDuWaD0B8Ryv8o+YtsICQBuiL/0U4AGwH7Pi5GNFySYk0/crSuwfIqQFtmxNSPFw=="], + + "solana-kite/@solana/transaction-confirmation/@solana/transaction-messages/@solana/functional": ["@solana/functional@5.5.1", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-tTHoJcEQq3gQx5qsdsDJ0LEJeFzwNpXD80xApW9o/PPoCNimI3SALkZl+zNW8VnxRrV3l3yYvfHWBKe/X3WG3w=="], + + "solana-kite/@solana/transaction-confirmation/@solana/transaction-messages/@solana/instructions": ["@solana/instructions@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-h0G1CG6S+gUUSt0eo6rOtsaXRBwCq1+Js2a+Ps9Bzk9q7YHNFA75/X0NWugWLgC92waRp66hrjMTiYYnLBoWOQ=="], + + "solana-kite/@solana/transaction-confirmation/@solana/transaction-messages/@solana/nominal-types": ["@solana/nominal-types@5.5.1", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-I1ImR+kfrLFxN5z22UDiTWLdRZeKtU0J/pkWkO8qm/8WxveiwdIv4hooi8pb6JnlR4mSrWhq0pCIOxDYrL9GIQ=="], + + "solana-kite/@solana/transaction-confirmation/@solana/transactions/@solana/codecs-core": ["@solana/codecs-core@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-TgBt//bbKBct0t6/MpA8ElaOA3sa8eYVvR7LGslCZ84WiAwwjCY0lW/lOYsFHJQzwREMdUyuEyy5YWBKtdh8Rw=="], + + "solana-kite/@solana/transaction-confirmation/@solana/transactions/@solana/codecs-data-structures": ["@solana/codecs-data-structures@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/codecs-numbers": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-97bJWGyUY9WvBz3mX1UV3YPWGDTez6btCfD0ip3UVEXJbItVuUiOkzcO5iFDUtQT5riKT6xC+Mzl+0nO76gd0w=="], + + "solana-kite/@solana/transaction-confirmation/@solana/transactions/@solana/codecs-numbers": ["@solana/codecs-numbers@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-rllMIZAHqmtvC0HO/dc/21wDuWaD0B8Ryv8o+YtsICQBuiL/0U4AGwH7Pi5GNFySYk0/crSuwfIqQFtmxNSPFw=="], + + "solana-kite/@solana/transaction-confirmation/@solana/transactions/@solana/functional": ["@solana/functional@5.5.1", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-tTHoJcEQq3gQx5qsdsDJ0LEJeFzwNpXD80xApW9o/PPoCNimI3SALkZl+zNW8VnxRrV3l3yYvfHWBKe/X3WG3w=="], + + "solana-kite/@solana/transaction-confirmation/@solana/transactions/@solana/instructions": ["@solana/instructions@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-h0G1CG6S+gUUSt0eo6rOtsaXRBwCq1+Js2a+Ps9Bzk9q7YHNFA75/X0NWugWLgC92waRp66hrjMTiYYnLBoWOQ=="], + + "solana-kite/@solana/transaction-confirmation/@solana/transactions/@solana/nominal-types": ["@solana/nominal-types@5.5.1", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-I1ImR+kfrLFxN5z22UDiTWLdRZeKtU0J/pkWkO8qm/8WxveiwdIv4hooi8pb6JnlR4mSrWhq0pCIOxDYrL9GIQ=="], + + "@solana-program/token-2022/@solana/sysvars/@solana/accounts/@solana/addresses/@solana/assertions": ["@solana/assertions@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-YTCSWAlGwSlVPnWtWLm3ukz81wH4j2YaCveK+TjpvUU88hTy6fmUqxi0+hvAMAe4zKXpJyj3Az7BrLJRxbIm4Q=="], + + "@solana-program/token-2022/@solana/sysvars/@solana/accounts/@solana/addresses/@solana/nominal-types": ["@solana/nominal-types@5.5.1", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-I1ImR+kfrLFxN5z22UDiTWLdRZeKtU0J/pkWkO8qm/8WxveiwdIv4hooi8pb6JnlR4mSrWhq0pCIOxDYrL9GIQ=="], + + "@solana-program/token-2022/@solana/sysvars/@solana/accounts/@solana/codecs-strings/@solana/codecs-numbers": ["@solana/codecs-numbers@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-rllMIZAHqmtvC0HO/dc/21wDuWaD0B8Ryv8o+YtsICQBuiL/0U4AGwH7Pi5GNFySYk0/crSuwfIqQFtmxNSPFw=="], + + "@solana-program/token-2022/@solana/sysvars/@solana/accounts/@solana/rpc-spec/@solana/rpc-spec-types": ["@solana/rpc-spec-types@5.5.1", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-6OFKtRpIEJQs8Jb2C4OO8KyP2h2Hy1MFhatMAoXA+0Ik8S3H+CicIuMZvGZ91mIu/tXicuOOsNNLu3HAkrakrw=="], + + "@solana-program/token-2022/@solana/sysvars/@solana/rpc-types/@solana/addresses/@solana/assertions": ["@solana/assertions@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-YTCSWAlGwSlVPnWtWLm3ukz81wH4j2YaCveK+TjpvUU88hTy6fmUqxi0+hvAMAe4zKXpJyj3Az7BrLJRxbIm4Q=="], + + "solana-kite/@solana/kit/@solana/accounts/@solana/codecs-strings/@solana/codecs-numbers": ["@solana/codecs-numbers@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-rllMIZAHqmtvC0HO/dc/21wDuWaD0B8Ryv8o+YtsICQBuiL/0U4AGwH7Pi5GNFySYk0/crSuwfIqQFtmxNSPFw=="], + + "solana-kite/@solana/kit/@solana/addresses/@solana/codecs-strings/@solana/codecs-numbers": ["@solana/codecs-numbers@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-rllMIZAHqmtvC0HO/dc/21wDuWaD0B8Ryv8o+YtsICQBuiL/0U4AGwH7Pi5GNFySYk0/crSuwfIqQFtmxNSPFw=="], + + "solana-kite/@solana/kit/@solana/keys/@solana/codecs-strings/@solana/codecs-numbers": ["@solana/codecs-numbers@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-rllMIZAHqmtvC0HO/dc/21wDuWaD0B8Ryv8o+YtsICQBuiL/0U4AGwH7Pi5GNFySYk0/crSuwfIqQFtmxNSPFw=="], + + "solana-kite/@solana/kit/@solana/rpc-api/@solana/codecs-strings/@solana/codecs-numbers": ["@solana/codecs-numbers@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-rllMIZAHqmtvC0HO/dc/21wDuWaD0B8Ryv8o+YtsICQBuiL/0U4AGwH7Pi5GNFySYk0/crSuwfIqQFtmxNSPFw=="], + + "solana-kite/@solana/kit/@solana/rpc-api/@solana/rpc-transformers/@solana/nominal-types": ["@solana/nominal-types@5.5.1", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-I1ImR+kfrLFxN5z22UDiTWLdRZeKtU0J/pkWkO8qm/8WxveiwdIv4hooi8pb6JnlR4mSrWhq0pCIOxDYrL9GIQ=="], + + "solana-kite/@solana/kit/@solana/rpc-subscriptions/@solana/rpc-transformers/@solana/nominal-types": ["@solana/nominal-types@5.5.1", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-I1ImR+kfrLFxN5z22UDiTWLdRZeKtU0J/pkWkO8qm/8WxveiwdIv4hooi8pb6JnlR4mSrWhq0pCIOxDYrL9GIQ=="], + + "solana-kite/@solana/kit/@solana/rpc/@solana/rpc-transformers/@solana/nominal-types": ["@solana/nominal-types@5.5.1", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-I1ImR+kfrLFxN5z22UDiTWLdRZeKtU0J/pkWkO8qm/8WxveiwdIv4hooi8pb6JnlR4mSrWhq0pCIOxDYrL9GIQ=="], + + "solana-kite/@solana/kit/@solana/rpc/@solana/rpc-transport-http/undici-types": ["undici-types@7.22.0", "", {}, "sha512-RKZvifiL60xdsIuC80UY0dq8Z7DbJUV8/l2hOVbyZAxBzEeQU4Z58+4ZzJ6WN2Lidi9KzT5EbiGX+PI/UGYuRw=="], + + "solana-kite/@solana/transaction-confirmation/@solana/rpc-subscriptions/@solana/rpc-transformers/@solana/nominal-types": ["@solana/nominal-types@5.5.1", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-I1ImR+kfrLFxN5z22UDiTWLdRZeKtU0J/pkWkO8qm/8WxveiwdIv4hooi8pb6JnlR4mSrWhq0pCIOxDYrL9GIQ=="], + + "solana-kite/@solana/transaction-confirmation/@solana/rpc/@solana/rpc-api/@solana/codecs-core": ["@solana/codecs-core@5.5.1", "", { "dependencies": { "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-TgBt//bbKBct0t6/MpA8ElaOA3sa8eYVvR7LGslCZ84WiAwwjCY0lW/lOYsFHJQzwREMdUyuEyy5YWBKtdh8Rw=="], + + "solana-kite/@solana/transaction-confirmation/@solana/rpc/@solana/rpc-api/@solana/rpc-parsed-types": ["@solana/rpc-parsed-types@5.5.1", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-HEi3G2nZqGEsa3vX6U0FrXLaqnUCg4SKIUrOe8CezD+cSFbRTOn3rCLrUmJrhVyXlHoQVaRO9mmeovk31jWxJg=="], + + "solana-kite/@solana/transaction-confirmation/@solana/rpc/@solana/rpc-transformers/@solana/nominal-types": ["@solana/nominal-types@5.5.1", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-I1ImR+kfrLFxN5z22UDiTWLdRZeKtU0J/pkWkO8qm/8WxveiwdIv4hooi8pb6JnlR4mSrWhq0pCIOxDYrL9GIQ=="], + + "solana-kite/@solana/transaction-confirmation/@solana/rpc/@solana/rpc-transport-http/undici-types": ["undici-types@7.22.0", "", {}, "sha512-RKZvifiL60xdsIuC80UY0dq8Z7DbJUV8/l2hOVbyZAxBzEeQU4Z58+4ZzJ6WN2Lidi9KzT5EbiGX+PI/UGYuRw=="], } } diff --git a/web/index.html b/web/index.html index a7c00c7..467b21e 100644 --- a/web/index.html +++ b/web/index.html @@ -1,20 +1,20 @@ - + - + - - + + - Starter kit — Untitled UI + Samizdat diff --git a/web/package.json b/web/package.json index 3360d6a..c219f18 100644 --- a/web/package.json +++ b/web/package.json @@ -13,10 +13,14 @@ "format:fix": "bunx prettier --write ." }, "dependencies": { + "@solana/kit": "^6.1.0", + "@solana/react": "^6.1.0", "@tailwindcss/typography": "^0.5.19", "@tailwindcss/vite": "^4.1.18", "@untitledui/file-icons": "^0.0.8", "@untitledui/icons": "^0.0.21", + "@wallet-standard/core": "^1.1.1", + "@wallet-standard/react": "^1.0.1", "input-otp": "^1.4.2", "motion": "^12.29.0", "qr-code-styling": "^1.9.2", @@ -26,6 +30,7 @@ "react-dom": "^19.2.3", "react-hotkeys-hook": "^5.2.3", "react-router": "^7.13.0", + "solana-kite": "^3.2.1", "tailwind-merge": "^3.4.0", "tailwindcss": "^4.1.18", "tailwindcss-animate": "^1.0.7", diff --git a/web/public/logo.svg b/web/public/logo.svg new file mode 100644 index 0000000..282f186 --- /dev/null +++ b/web/public/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/web/src/shims/empty.ts b/web/src/shims/empty.ts new file mode 100644 index 0000000..3287843 --- /dev/null +++ b/web/src/shims/empty.ts @@ -0,0 +1,2 @@ +// Empty shim for Node.js modules (fs/promises, etc.) that don't exist in the browser. +export default {}; diff --git a/web/tsconfig.app.json b/web/tsconfig.app.json index a8c7c99..de23fc7 100644 --- a/web/tsconfig.app.json +++ b/web/tsconfig.app.json @@ -13,7 +13,7 @@ "isolatedModules": true, "moduleDetection": "force", "noEmit": true, - "jsx": "preserve", + "jsx": "react-jsx", /* Linting */ "strict": true, @@ -23,7 +23,8 @@ "noUncheckedSideEffectImports": true, "baseUrl": ".", "paths": { - "@/*": ["./src/*"] + "@/*": ["./src/*"], + "@client/*": ["./client/samizdat/src/generated/*"] } }, "include": ["src"] diff --git a/web/vite.config.ts b/web/vite.config.ts index 4fb8dc7..90fe200 100644 --- a/web/vite.config.ts +++ b/web/vite.config.ts @@ -18,6 +18,10 @@ export default defineConfig({ resolve: { alias: { '@': path.resolve(__dirname, './src'), + '@client': path.resolve(__dirname, './client/samizdat/src/generated'), + // solana-kite uses dynamic import("fs/promises") which the node-polyfills + // plugin can't resolve in the browser. Point at our own empty shim. + 'fs/promises': path.resolve(__dirname, './src/shims/empty.ts'), }, }, }); From d0b41cf07d3d36229e8a5bb267112c25a8333cbf Mon Sep 17 00:00:00 2001 From: Nitish C <86357181+Nitish-bot@users.noreply.github.com> Date: Wed, 4 Mar 2026 13:41:52 +0530 Subject: [PATCH 02/17] add chain, connection and selected wallet context --- web/src/context/chain-context-provider.tsx | 9 ++ web/src/context/chain-context.tsx | 21 ++++ .../context/connection-context-provider.tsx | 26 ++++ web/src/context/connection-context.tsx | 15 +++ ...lected-wallet-account-context-provider.tsx | 119 ++++++++++++++++++ .../selected-wallet-account-context.tsx | 19 +++ 6 files changed, 209 insertions(+) create mode 100644 web/src/context/chain-context-provider.tsx create mode 100644 web/src/context/chain-context.tsx create mode 100644 web/src/context/connection-context-provider.tsx create mode 100644 web/src/context/connection-context.tsx create mode 100644 web/src/context/selected-wallet-account-context-provider.tsx create mode 100644 web/src/context/selected-wallet-account-context.tsx diff --git a/web/src/context/chain-context-provider.tsx b/web/src/context/chain-context-provider.tsx new file mode 100644 index 0000000..3ccffad --- /dev/null +++ b/web/src/context/chain-context-provider.tsx @@ -0,0 +1,9 @@ +import { useMemo } from 'react'; + +import { ChainContext, DEFAULT_CHAIN_CONFIG } from '@/context/chain-context'; + +export function ChainContextProvider({ children }: { children: React.ReactNode }) { + const contextValue = useMemo(() => DEFAULT_CHAIN_CONFIG, []); + + return {children}; +} diff --git a/web/src/context/chain-context.tsx b/web/src/context/chain-context.tsx new file mode 100644 index 0000000..84dd7d6 --- /dev/null +++ b/web/src/context/chain-context.tsx @@ -0,0 +1,21 @@ +import { createContext } from 'react'; + +import { devnet } from '@solana/kit'; + +import type { ClusterUrl } from '@solana/kit'; + +export type ChainContextType = Readonly<{ + chain: `solana:${string}`; + displayName: string; + solanaRpcSubscriptionsUrl: ClusterUrl; + solanaRpcUrl: ClusterUrl; +}>; + +export const DEFAULT_CHAIN_CONFIG: ChainContextType = { + chain: 'solana:devnet', + displayName: 'Devnet', + solanaRpcSubscriptionsUrl: devnet('wss://api.devnet.solana.com'), + solanaRpcUrl: devnet('https://api.devnet.solana.com'), +}; + +export const ChainContext = createContext(DEFAULT_CHAIN_CONFIG); diff --git a/web/src/context/connection-context-provider.tsx b/web/src/context/connection-context-provider.tsx new file mode 100644 index 0000000..c68a915 --- /dev/null +++ b/web/src/context/connection-context-provider.tsx @@ -0,0 +1,26 @@ +import { type ReactNode, useContext, useMemo } from 'react'; + +import { connect } from 'solana-kite'; + +import { ChainContext } from '@/context/chain-context'; +import { + ConnectionContext, + type ConnectionContextType, +} from '@/context/connection-context'; + +export function ConnectionContextProvider({ children }: { children: ReactNode }) { + const { solanaRpcUrl, solanaRpcSubscriptionsUrl } = useContext(ChainContext); + + const contextValue: ConnectionContextType = useMemo( + () => ({ + connection: connect(solanaRpcUrl, solanaRpcSubscriptionsUrl), + }), + [solanaRpcUrl, solanaRpcSubscriptionsUrl] + ); + + return ( + + {children} + + ); +} diff --git a/web/src/context/connection-context.tsx b/web/src/context/connection-context.tsx new file mode 100644 index 0000000..6b463f5 --- /dev/null +++ b/web/src/context/connection-context.tsx @@ -0,0 +1,15 @@ +import { createContext } from 'react'; + +import { connect, type Connection } from 'solana-kite'; + +export type ConnectionContextType = { + connection: Connection; +}; + +const defaultConnectionContext: ConnectionContextType = { + connection: connect('devnet'), +}; + +export const ConnectionContext = createContext( + defaultConnectionContext +); diff --git a/web/src/context/selected-wallet-account-context-provider.tsx b/web/src/context/selected-wallet-account-context-provider.tsx new file mode 100644 index 0000000..0bcca5b --- /dev/null +++ b/web/src/context/selected-wallet-account-context-provider.tsx @@ -0,0 +1,119 @@ +import { useEffect, useMemo, useState } from 'react'; + +import { + getUiWalletAccountStorageKey, + UiWallet, + UiWalletAccount, + uiWalletAccountBelongsToUiWallet, + uiWalletAccountsAreSame, + useWallets, +} from '@wallet-standard/react'; + +import { + SelectedWalletAccountContext, + type SelectedWalletAccountState, +} from '@/context/selected-wallet-account-context'; + +const STORAGE_KEY = 'cayed:selected-wallet'; + +let wasSetterInvoked = false; +function getSavedWalletAccount( + wallets: readonly UiWallet[] +): UiWalletAccount | undefined { + if (wasSetterInvoked) { + // After the user makes an explicit choice of wallet, stop trying to auto-select the + // saved wallet, if and when it appears. + return; + } + const savedWalletNameAndAddress = localStorage.getItem(STORAGE_KEY); + if (!savedWalletNameAndAddress || typeof savedWalletNameAndAddress !== 'string') { + return; + } + const [savedWalletName, savedAccountAddress] = savedWalletNameAndAddress.split(':'); + if (!savedWalletName || !savedAccountAddress) { + return; + } + for (const wallet of wallets) { + if (wallet.name === savedWalletName) { + for (const account of wallet.accounts) { + if (account.address === savedAccountAddress) { + return account; + } + } + } + } +} + +/** + * Saves the selected wallet account's storage key to the browser's local storage. In future + * sessions it will try to return that same wallet account, or at least one from the same brand of + * wallet if the wallet from which it came is still in the Wallet Standard registry. + */ +export function SelectedWalletAccountContextProvider({ + children, +}: { + children: React.ReactNode; +}) { + const wallets = useWallets(); + const [selectedWalletAccount, setSelectedWalletAccountInternal] = + useState(() => getSavedWalletAccount(wallets)); + const setSelectedWalletAccount: React.Dispatch< + React.SetStateAction + > = setStateAction => { + setSelectedWalletAccountInternal(prevSelectedWalletAccount => { + wasSetterInvoked = true; + const nextWalletAccount = + typeof setStateAction === 'function' + ? setStateAction(prevSelectedWalletAccount) + : setStateAction; + const accountKey = nextWalletAccount + ? getUiWalletAccountStorageKey(nextWalletAccount) + : undefined; + if (accountKey) { + localStorage.setItem(STORAGE_KEY, accountKey); + } else { + localStorage.removeItem(STORAGE_KEY); + } + return nextWalletAccount; + }); + }; + useEffect(() => { + const savedWalletAccount = getSavedWalletAccount(wallets); + if (savedWalletAccount) { + setSelectedWalletAccountInternal(savedWalletAccount); + } + }, [wallets]); + const walletAccount = useMemo(() => { + if (selectedWalletAccount) { + for (const uiWallet of wallets) { + for (const uiWalletAccount of uiWallet.accounts) { + if (uiWalletAccountsAreSame(selectedWalletAccount, uiWalletAccount)) { + return uiWalletAccount; + } + } + if ( + uiWalletAccountBelongsToUiWallet(selectedWalletAccount, uiWallet) && + uiWallet.accounts[0] + ) { + // If the selected account belongs to this connected wallet, at least, then + // select one of its accounts. + return uiWallet.accounts[0]; + } + } + } + }, [selectedWalletAccount, wallets]); + useEffect(() => { + // If there is a selected wallet account but the wallet to which it belongs has since + // disconnected, clear the selected wallet. + if (selectedWalletAccount && !walletAccount) { + setSelectedWalletAccountInternal(undefined); + } + }, [selectedWalletAccount, walletAccount]); + return ( + [walletAccount, setSelectedWalletAccount], [walletAccount])} + > + {children} + + ); +} diff --git a/web/src/context/selected-wallet-account-context.tsx b/web/src/context/selected-wallet-account-context.tsx new file mode 100644 index 0000000..03eac1f --- /dev/null +++ b/web/src/context/selected-wallet-account-context.tsx @@ -0,0 +1,19 @@ +import { createContext } from 'react'; + +import type { UiWalletAccount } from '@wallet-standard/react'; + +export type SelectedWalletAccountState = UiWalletAccount | undefined; + +export const SelectedWalletAccountContext = createContext< + readonly [ + selectedWalletAccount: SelectedWalletAccountState, + setSelectedWalletAccount: React.Dispatch< + React.SetStateAction + >, + ] +>([ + undefined, + function setSelectedWalletAccount() { + /* noop default */ + }, +]); From 9385faaab0fa5b902d4b8d0ca95dcfc0bdd314ee Mon Sep 17 00:00:00 2001 From: Nitish C <86357181+Nitish-bot@users.noreply.github.com> Date: Wed, 4 Mar 2026 13:50:42 +0530 Subject: [PATCH 03/17] add wallet connectivity helpers --- .../application/connect-wallet-menu.tsx | 240 ++++++++++++++++++ .../application/wallet-account-icon.tsx | 25 ++ web/src/hooks/use-balance.ts | 65 +++++ 3 files changed, 330 insertions(+) create mode 100644 web/src/components/application/connect-wallet-menu.tsx create mode 100644 web/src/components/application/wallet-account-icon.tsx create mode 100644 web/src/hooks/use-balance.ts diff --git a/web/src/components/application/connect-wallet-menu.tsx b/web/src/components/application/connect-wallet-menu.tsx new file mode 100644 index 0000000..2779216 --- /dev/null +++ b/web/src/components/application/connect-wallet-menu.tsx @@ -0,0 +1,240 @@ +import { useCallback, useContext, useState } from 'react'; + +import { Wallet01, LogOut01, AlertCircle, ChevronDown } from '@untitledui/icons'; +import { StandardConnect, StandardDisconnect } from '@wallet-standard/core'; +import type { UiWallet, UiWalletAccount } from '@wallet-standard/react'; +import { + uiWalletAccountBelongsToUiWallet, + uiWalletAccountsAreSame, + useConnect, + useDisconnect, + useWallets, +} from '@wallet-standard/react'; + +import { Button } from '@/components/base/buttons/button'; +import { Dropdown } from '@/components/base/dropdown/dropdown'; +import { SelectedWalletAccountContext } from '@/context/selected-wallet-account-context'; +import { formatSol, useBalance } from '@/hooks/use-balance'; +import { cx } from '@/utils/cx'; + +import { WalletAccountIcon } from './wallet-account-icon'; +import { ChainContext } from '@/context/chain-context'; + +// ─── Connectable Wallet Item ──────────────────────────────────────────────── + +function ConnectableWalletItem({ + wallet, + onAccountSelect, + onDisconnect, +}: { + wallet: UiWallet; + onAccountSelect: (account: UiWalletAccount) => void; + onDisconnect: (wallet: UiWallet) => void; +}) { + const [isConnecting, connect] = useConnect(wallet); + const [isDisconnecting, disconnect] = useDisconnect(wallet); + const isPending = isConnecting || isDisconnecting; + const isConnected = wallet.accounts.length > 0; + const [selectedWalletAccount] = useContext(SelectedWalletAccountContext); + + const handleClick = useCallback(async () => { + if (isConnected) return; // Already connected — sub-accounts shown below + try { + const existingAccounts = [...wallet.accounts]; + const nextAccounts = await connect(); + // Prefer first new account + for (const next of nextAccounts) { + if ( + !existingAccounts.some(existing => + uiWalletAccountsAreSame(next, existing) + ) + ) { + onAccountSelect(next); + return; + } + } + if (nextAccounts[0]) { + onAccountSelect(nextAccounts[0]); + } + } catch { + /* wallet refused */ + } + }, [connect, isConnected, onAccountSelect, wallet.accounts]); + + return ( +
+ {/* Wallet row */} + + + {/* Connected accounts */} + {isConnected && ( +
+ {wallet.accounts.map(account => { + const isSelected = + selectedWalletAccount && + uiWalletAccountsAreSame(selectedWalletAccount, account); + + return ( + + ); + })} + + {/* Disconnect */} + +
+ )} +
+ ); +} + +// ─── Connected Wallet Display ─────────────────────────────────────────────── + +function ConnectedDisplay({ account }: { account: UiWalletAccount }) { + const { balance } = useBalance(account); + + return ( + + + + {account.address.slice(0, 4)}…{account.address.slice(-4)} + + {balance != null && ( + + {formatSol(balance)} SOL + + )} + + ); +} + +// ─── Main ConnectWalletMenu ───────────────────────────────────────────────── + +export function ConnectWalletMenu() { + const wallets = useWallets(); + const [selectedWalletAccount, setSelectedWalletAccount] = useContext( + SelectedWalletAccountContext + ); + const [menuKey, setMenuKey] = useState(0); + const chainDetails = useContext(ChainContext); + + // Filter wallets by capability + const connectable: UiWallet[] = []; + for (const wallet of wallets) { + if ( + wallet.features.includes(StandardConnect) && + wallet.features.includes(StandardDisconnect) && + wallet.chains.includes(chainDetails.chain) + ) { + connectable.push(wallet); + } + } + + return ( + + + + +
+ {wallets.length === 0 ? ( +
+ + No wallets detected in this browser. +
+ ) : ( + <> + {connectable.map(wallet => ( + { + setSelectedWalletAccount(account); + setMenuKey(k => k + 1); + }} + onDisconnect={wallet => { + if ( + selectedWalletAccount && + uiWalletAccountBelongsToUiWallet( + selectedWalletAccount, + wallet + ) + ) { + setSelectedWalletAccount(undefined); + } + }} + /> + ))} + + )} +
+
+
+ ); +} diff --git a/web/src/components/application/wallet-account-icon.tsx b/web/src/components/application/wallet-account-icon.tsx new file mode 100644 index 0000000..b5f1ba7 --- /dev/null +++ b/web/src/components/application/wallet-account-icon.tsx @@ -0,0 +1,25 @@ +import type { UiWalletAccount } from '@wallet-standard/react'; +import { uiWalletAccountBelongsToUiWallet, useWallets } from '@wallet-standard/react'; + +type WalletAccountIconProps = React.ComponentProps<'img'> & + Readonly<{ + account: UiWalletAccount; + }>; + +export function WalletAccountIcon({ account, ...imgProps }: WalletAccountIconProps) { + const wallets = useWallets(); + let icon: string | undefined; + + if (account.icon) { + icon = account.icon; + } else { + for (const wallet of wallets) { + if (uiWalletAccountBelongsToUiWallet(account, wallet)) { + icon = wallet.icon; + break; + } + } + } + + return icon ? : null; +} diff --git a/web/src/hooks/use-balance.ts b/web/src/hooks/use-balance.ts new file mode 100644 index 0000000..00a268f --- /dev/null +++ b/web/src/hooks/use-balance.ts @@ -0,0 +1,65 @@ +import { useContext, useEffect, useState } from 'react'; + +import { address as toAddress, type Lamports } from '@solana/kit'; + +import { ConnectionContext } from '@/context/connection-context'; + +import type { UiWalletAccount } from '@wallet-standard/react'; + + +/** + * Simple hook to fetch and poll the SOL balance for a wallet account. + * Polls every 10 seconds to keep the balance reasonably up to date. + */ +export function useBalance(account: UiWalletAccount | undefined) { + const { connection } = useContext(ConnectionContext); + const [balance, setBalance] = useState(null); + const [error, setError] = useState(null); + + useEffect(() => { + if (!account) { + setBalance(null); + setError(null); + return; + } + + let cancelled = false; + + async function fetchBalance() { + try { + const { value: lamports } = await connection.rpc + .getBalance(toAddress(account!.address), { commitment: 'confirmed' }) + .send(); + + if (!cancelled) { + setBalance(lamports); + setError(null); + } + } catch (err) { + if (!cancelled) { + setError(err); + } + } + } + + fetchBalance(); + const interval = setInterval(fetchBalance, 10_000); + + return () => { + cancelled = true; + clearInterval(interval); + }; + }, [account, connection]); + + return { balance, error }; +} + +/** + * Format lamports as a human-readable SOL string. + */ +export function formatSol(lamports: Lamports): string { + return new Intl.NumberFormat(undefined, { maximumFractionDigits: 5 }).format( + // Lamports is a bigint; convert to SOL + Number(lamports) / 1e9 + ); +} From 9b56a874d8a42a673cf421e9647f0dc2b0503559 Mon Sep 17 00:00:00 2001 From: Nitish C <86357181+Nitish-bot@users.noreply.github.com> Date: Wed, 4 Mar 2026 13:51:50 +0530 Subject: [PATCH 04/17] add new fonts to css and some other helper classes --- web/src/styles/globals.css | 68 ++++++++++++++++++++++++++++++++++++++ web/src/styles/theme.css | 30 ++++++++--------- 2 files changed, 83 insertions(+), 15 deletions(-) diff --git a/web/src/styles/globals.css b/web/src/styles/globals.css index 13ff688..53e3240 100755 --- a/web/src/styles/globals.css +++ b/web/src/styles/globals.css @@ -22,6 +22,46 @@ scrollbar-width: none; /* Firefox */ } +@utility noise-overlay { + position: relative; + + &::before { + content: ''; + position: absolute; + inset: 0; + z-index: 1; + pointer-events: none; + opacity: 0.04; + background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E"); + background-repeat: repeat; + background-size: 256px 256px; + } +} + +@utility scanline-overlay { + position: relative; + + &::after { + content: ''; + position: absolute; + inset: 0; + z-index: 2; + pointer-events: none; + background: repeating-linear-gradient( + 0deg, + transparent, + transparent 2px, + rgba(0 0 0 / 0.08) 2px, + rgba(0 0 0 / 0.08) 4px + ); + animation: scanline-scroll 8s linear infinite; + } +} + +@utility pulse-dot { + animation: pulse-dot 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; +} + @utility transition-inherit-all { transition-property: inherit; transition-duration: inherit; @@ -67,3 +107,31 @@ input[type='search']::-webkit-search-cancel-button { .recharts-surface path { outline: none; } + +/* Samizdat keyframes */ +@keyframes scanline-scroll { + 0% { + transform: translateY(0); + } + 100% { + transform: translateY(4px); + } +} + +@keyframes pulse-dot { + 0%, 100% { + opacity: 1; + } + 50% { + opacity: 0.3; + } +} + +@keyframes flicker { + 0%, 100% { opacity: 1; } + 92% { opacity: 1; } + 93% { opacity: 0.8; } + 94% { opacity: 1; } + 96% { opacity: 0.9; } + 97% { opacity: 1; } +} diff --git a/web/src/styles/theme.css b/web/src/styles/theme.css index d9aa57a..1ea0209 100644 --- a/web/src/styles/theme.css +++ b/web/src/styles/theme.css @@ -1,11 +1,11 @@ @theme { /* FONT FAMILY */ --font-body: - var(--font-inter, 'Inter'), -apple-system, 'Segoe UI', Roboto, Arial, sans-serif; + 'Inter', -apple-system, 'Segoe UI', Roboto, Arial, sans-serif; --font-display: - var(--font-inter, 'Inter'), -apple-system, 'Segoe UI', Roboto, Arial, sans-serif; + 'Instrument Serif', Georgia, 'Times New Roman', serif; --font-mono: - ui-monospace, 'Roboto Mono', SFMono-Regular, Menlo, Monaco, Consolas, + 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace; /* FONT SIZE */ @@ -138,18 +138,18 @@ --color-white: rgb(255 255 255); --color-black: rgb(0 0 0); - --color-brand-25: rgb(252 250 255); - --color-brand-50: rgb(249 245 255); - --color-brand-100: rgb(244 235 255); - --color-brand-200: rgb(233 215 254); - --color-brand-300: rgb(214 187 251); - --color-brand-400: rgb(182 146 246); - --color-brand-500: rgb(158 119 237); - --color-brand-600: rgb(127 86 217); - --color-brand-700: rgb(105 65 198); - --color-brand-800: rgb(83 56 158); - --color-brand-900: rgb(66 48 125); - --color-brand-950: rgb(44 28 95); + --color-brand-25: rgb(255 250 245); + --color-brand-50: rgb(255 244 237); + --color-brand-100: rgb(255 230 213); + --color-brand-200: rgb(255 200 163); + --color-brand-300: rgb(255 156 102); + --color-brand-400: rgb(255 120 56); + --color-brand-500: rgb(255 77 0); + --color-brand-600: rgb(230 60 0); + --color-brand-700: rgb(188 42 0); + --color-brand-800: rgb(151 33 0); + --color-brand-900: rgb(119 28 0); + --color-brand-950: rgb(80 18 0); --color-error-25: rgb(255 251 250); --color-error-50: rgb(254 243 242); From fff6533340259a1bb154b948f3e96fc0388aed3e Mon Sep 17 00:00:00 2001 From: Nitish C <86357181+Nitish-bot@users.noreply.github.com> Date: Wed, 4 Mar 2026 13:52:59 +0530 Subject: [PATCH 05/17] remove needless React import --- web/src/components/application/pagination/pagination-base.tsx | 2 +- web/src/components/base/buttons/button.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/web/src/components/application/pagination/pagination-base.tsx b/web/src/components/application/pagination/pagination-base.tsx index 3b09a04..d392ccf 100644 --- a/web/src/components/application/pagination/pagination-base.tsx +++ b/web/src/components/application/pagination/pagination-base.tsx @@ -1,5 +1,5 @@ import type { CSSProperties, FC, HTMLAttributes, ReactNode } from 'react'; -import React, { +import { cloneElement, createContext, isValidElement, diff --git a/web/src/components/base/buttons/button.tsx b/web/src/components/base/buttons/button.tsx index 02d48ea..88252c5 100644 --- a/web/src/components/base/buttons/button.tsx +++ b/web/src/components/base/buttons/button.tsx @@ -5,7 +5,7 @@ import type { FC, ReactNode, } from 'react'; -import React, { isValidElement } from 'react'; +import { isValidElement } from 'react'; import { Button as AriaButton, Link as AriaLink } from 'react-aria-components'; import type { ButtonProps as AriaButtonProps, From ea32ff248974a36546ac023aacd22f780c581610 Mon Sep 17 00:00:00 2001 From: Nitish C <86357181+Nitish-bot@users.noreply.github.com> Date: Wed, 4 Mar 2026 14:46:31 +0530 Subject: [PATCH 06/17] landing page done --- web/src/components/application/app-layout.tsx | 93 ++++++ .../application/connect-wallet-menu.tsx | 28 +- web/src/hooks/use-balance.ts | 65 ---- web/src/pages/landing.tsx | 311 ++++++++++++++++++ 4 files changed, 415 insertions(+), 82 deletions(-) create mode 100644 web/src/components/application/app-layout.tsx delete mode 100644 web/src/hooks/use-balance.ts create mode 100644 web/src/pages/landing.tsx diff --git a/web/src/components/application/app-layout.tsx b/web/src/components/application/app-layout.tsx new file mode 100644 index 0000000..b393737 --- /dev/null +++ b/web/src/components/application/app-layout.tsx @@ -0,0 +1,93 @@ +import type { FC } from 'react'; +import { Outlet, useLocation } from 'react-router'; + +import { + Globe05, + Monitor04, + Send01, + Signal01, +} from '@untitledui/icons'; + +import { ConnectWalletMenu } from '@/components/application/connect-wallet-menu'; +import { cx } from '@/utils/cx'; + +interface NavItem { + label: string; + href: string; + icon: FC<{ className?: string }>; +} + +const NAV_ITEMS: NavItem[] = [ + { label: 'Protocol', href: '/', icon: Globe05 }, + { label: 'Publisher', href: '/publisher', icon: Send01 }, + { label: 'Node Operator', href: '/node', icon: Monitor04 }, + { label: 'Digital Twin', href: '/twin', icon: Signal01 }, +]; + +export function AppLayout() { + const { pathname } = useLocation(); + + return ( +
+ {/* Header */} +
+
+ {/* Logo */} + + Samizdat + + samizdat + + + + {/* Nav */} + + + {/* Wallet */} + +
+
+ + {/* Page content */} +
+ +
+ + {/* Footer */} +
+
+ SAMIZDAT PROTOCOL + + SOLANA DEVNET • {new Date().getFullYear()} + +
+
+
+ ); +} diff --git a/web/src/components/application/connect-wallet-menu.tsx b/web/src/components/application/connect-wallet-menu.tsx index 2779216..e526d36 100644 --- a/web/src/components/application/connect-wallet-menu.tsx +++ b/web/src/components/application/connect-wallet-menu.tsx @@ -14,7 +14,6 @@ import { import { Button } from '@/components/base/buttons/button'; import { Dropdown } from '@/components/base/dropdown/dropdown'; import { SelectedWalletAccountContext } from '@/context/selected-wallet-account-context'; -import { formatSol, useBalance } from '@/hooks/use-balance'; import { cx } from '@/utils/cx'; import { WalletAccountIcon } from './wallet-account-icon'; @@ -143,8 +142,6 @@ function ConnectableWalletItem({ // ─── Connected Wallet Display ─────────────────────────────────────────────── function ConnectedDisplay({ account }: { account: UiWalletAccount }) { - const { balance } = useBalance(account); - return ( {account.address.slice(0, 4)}…{account.address.slice(-4)} - {balance != null && ( - - {formatSol(balance)} SOL - - )} ); } @@ -190,15 +182,17 @@ export function ConnectWalletMenu() { return ( diff --git a/web/src/hooks/use-balance.ts b/web/src/hooks/use-balance.ts deleted file mode 100644 index 00a268f..0000000 --- a/web/src/hooks/use-balance.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { useContext, useEffect, useState } from 'react'; - -import { address as toAddress, type Lamports } from '@solana/kit'; - -import { ConnectionContext } from '@/context/connection-context'; - -import type { UiWalletAccount } from '@wallet-standard/react'; - - -/** - * Simple hook to fetch and poll the SOL balance for a wallet account. - * Polls every 10 seconds to keep the balance reasonably up to date. - */ -export function useBalance(account: UiWalletAccount | undefined) { - const { connection } = useContext(ConnectionContext); - const [balance, setBalance] = useState(null); - const [error, setError] = useState(null); - - useEffect(() => { - if (!account) { - setBalance(null); - setError(null); - return; - } - - let cancelled = false; - - async function fetchBalance() { - try { - const { value: lamports } = await connection.rpc - .getBalance(toAddress(account!.address), { commitment: 'confirmed' }) - .send(); - - if (!cancelled) { - setBalance(lamports); - setError(null); - } - } catch (err) { - if (!cancelled) { - setError(err); - } - } - } - - fetchBalance(); - const interval = setInterval(fetchBalance, 10_000); - - return () => { - cancelled = true; - clearInterval(interval); - }; - }, [account, connection]); - - return { balance, error }; -} - -/** - * Format lamports as a human-readable SOL string. - */ -export function formatSol(lamports: Lamports): string { - return new Intl.NumberFormat(undefined, { maximumFractionDigits: 5 }).format( - // Lamports is a bigint; convert to SOL - Number(lamports) / 1e9 - ); -} diff --git a/web/src/pages/landing.tsx b/web/src/pages/landing.tsx new file mode 100644 index 0000000..3388428 --- /dev/null +++ b/web/src/pages/landing.tsx @@ -0,0 +1,311 @@ +import { useRef } from 'react'; + +import { + ArrowRight, + CurrencyDollarCircle, + Database01, + Globe05, + LinkExternal01, + Monitor04, + Send01, + Shield01, + Zap, +} from '@untitledui/icons'; +import { motion, useInView } from 'motion/react'; + +import { Button } from '@/components/base/buttons/button'; + +// ============================================================================ +// Landing Page — Soviet-era brutalist editorial aesthetic +// ============================================================================ + +function StaggerRevealText({ + text, + className, + delay = 0, +}: { + text: string; + className?: string; + delay?: number; +}) { + const ref = useRef(null); + const isInView = useInView(ref, { once: true, margin: '-100px' }); + const words = text.split(' '); + + return ( + + {words.map((word, i) => ( + + {word} + + ))} + + ); +} + +function ProtocolFlowDiagram() { + const ref = useRef(null); + const isInView = useInView(ref, { once: true, margin: '-50px' }); + + const steps = [ + { icon: Send01, label: 'Publisher', sublabel: 'Uploads content + funds campaign' }, + { icon: Database01, label: 'Solana', sublabel: 'On-chain matching & escrow' }, + { icon: Monitor04, label: 'Node', sublabel: 'Claims & displays content' }, + { icon: CurrencyDollarCircle, label: 'Payment', sublabel: 'Instant SOL settlement' }, + ]; + + return ( +
+ {steps.map((step, i) => ( +
+ +
+ +
+
+

+ {step.label} +

+

{step.sublabel}

+
+
+ + {i < steps.length - 1 && ( + + )} +
+ ))} +
+ ); +} + +interface FeatureCardProps { + icon: React.FC<{ className?: string }>; + title: string; + description: string; + index: number; +} + +function FeatureCard({ icon: Icon, title, description, index }: FeatureCardProps) { + const ref = useRef(null); + const isInView = useInView(ref, { once: true, margin: '-80px' }); + + return ( + +
+ +
+
+

{title}

+

{description}

+
+
+ ); +} + +export function LandingPage() { + return ( +
+ {/* Hero Section */} +
+
+ {/* Oversized typographic header */} +
+
+ + + Live on Solana Devnet + +
+ +

+ +
+ +

+ + + A DePIN protocol connecting content publishers with physical display nodes. + Fund campaigns, match screens, pay per play — all on-chain. + + + + + + +
+ + {/* Oversized bg accent text */} + +
+
+ + {/* Protocol Flow */} +
+
+
+ + How it works + +

+ From publisher to screen in four steps +

+
+ + +
+
+ + {/* Feature Grid */} +
+
+
+ + Protocol Features + +

+ Built for scale. Secured by Solana. +

+
+ +
+ + + + + + +
+
+
+ + {/* CTA Section */} +
+
+
+

+ Ready to broadcast? +

+

+ Whether you're publishing content or operating screens, Samizdat connects + you to a permissionless advertising network. +

+ +
+ + +
+ +
+
+ + + 8 active campaigns + +
+
+ + + 1,247 total plays + +
+
+
+
+
+
+ ); +} From 4386f9effdd2faa29ec8821fd458f8cb75025d18 Mon Sep 17 00:00:00 2001 From: Nitish C <86357181+Nitish-bot@users.noreply.github.com> Date: Wed, 4 Mar 2026 14:47:47 +0530 Subject: [PATCH 07/17] Recreate types --- web/src/types/samizdat.ts | 169 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 web/src/types/samizdat.ts diff --git a/web/src/types/samizdat.ts b/web/src/types/samizdat.ts new file mode 100644 index 0000000..ece4d4a --- /dev/null +++ b/web/src/types/samizdat.ts @@ -0,0 +1,169 @@ +// ============================================================================ +// Samizdat Protocol Types +// Mirrors the on-chain account structures from programs/samizdat/src/state/ +// ============================================================================ + +// --- Enums --- + +export enum CampaignStatus { + Active = 'Active', + Paused = 'Paused', + Depleted = 'Depleted', + Closed = 'Closed', +} + +export enum NodeStatus { + Active = 'Active', + Offline = 'Offline', + Suspended = 'Suspended', +} + +export enum PublisherStatus { + Active = 'Active', + Suspended = 'Suspended', +} + +export enum PlayStatus { + Claimed = 'Claimed', + Paid = 'Paid', + TimedOut = 'TimedOut', +} + +export enum ScreenSize { + Small = 'Small', + Medium = 'Medium', + Large = 'Large', + XLarge = 'XLarge', +} + +// --- Content Tags (bitmask) --- + +export const TAG_LABELS: Record = { + 0: 'None', + 1: 'Crypto', + 2: 'Betting', + 4: 'NSFW', + 8: 'Political', + 16: 'Alcohol', +}; + +export const TAG_BITS = [ + { bit: 1, label: 'Crypto' }, + { bit: 2, label: 'Betting' }, + { bit: 4, label: 'NSFW' }, + { bit: 8, label: 'Political' }, + { bit: 16, label: 'Alcohol' }, +] as const; + +// --- Structs --- + +export interface GeoLocation { + /** Latitude in fixed-point (degrees × 1e7) */ + latitude: number; + /** Longitude in fixed-point (degrees × 1e7) */ + longitude: number; +} + +export interface Resolution { + width: number; + height: number; +} + +export interface GeoBounds { + minLat: number; + maxLat: number; + minLon: number; + maxLon: number; +} + +export interface TargetFilters { + minFootfall: number | null; + maxFootfall: number | null; + screenSizes: ScreenSize[]; + geoBounds: GeoBounds | null; + establishmentTypes: string[]; + requiredLandmarks: string[]; +} + +// --- Account Types --- + +export interface PublisherAccount { + address: string; + authority: string; + totalCampaigns: number; + totalSpent: number; + registeredAt: number; + status: PublisherStatus; +} + +export interface CampaignAccount { + address: string; + publisherAccount: string; + campaignId: number; + cids: string[]; + bountyPerPlay: number; + playsRemaining: number; + playsCompleted: number; + tagMask: number; + targetFilters: TargetFilters; + status: CampaignStatus; + claimCooldown: number; + createdAt: number; +} + +export interface NodeAccount { + address: string; + authority: string; + nodeId: number; + location: GeoLocation; + screenSize: ScreenSize; + resolution: Resolution; + landmarks: string[]; + blockedTagMask: number; + estimatedFootfall: number; + establishmentType: string; + totalPlays: number; + totalEarnings: number; + registeredAt: number; + status: NodeStatus; +} + +export interface PlayRecord { + address: string; + campaignAccount: string; + nodeAccount: string; + nonce: number; + claimedAt: number; + confirmedAt: number; + cidIndex: number; + paymentAmount: number; + status: PlayStatus; +} + +export interface ClaimCooldown { + campaign: string; + node: string; + lastClaimedAt: number; +} + +// --- Helpers --- + +/** Convert fixed-point i64 (× 1e7) to human-readable degrees */ +export function geoToDecimal(fixedPoint: number): number { + return fixedPoint / 1e7; +} + +/** Convert lamports to SOL */ +export function lamportsToSol(lamports: number): number { + return lamports / 1e9; +} + +/** Extract tag labels from a bitmask */ +export function tagsFromMask(mask: number): string[] { + return TAG_BITS.filter(t => (mask & t.bit) !== 0).map(t => t.label); +} + +/** Truncate a Solana address for display */ +export function shortenAddress(address: string, chars = 4): string { + return `${address.slice(0, chars)}...${address.slice(-chars)}`; +} From acb70b1a4af51f7c34e6b51fb7a7c866b8766de9 Mon Sep 17 00:00:00 2001 From: Nitish C <86357181+Nitish-bot@users.noreply.github.com> Date: Thu, 5 Mar 2026 15:45:49 +0530 Subject: [PATCH 08/17] Add samizdat service to talk to blockchain --- .../providers/samizdat-service-provider.tsx | 161 +++++++++ web/src/services/samizdat-service.ts | 309 ++++++++++++++++++ web/src/types/samizdat.ts | 246 ++++++-------- 3 files changed, 567 insertions(+), 149 deletions(-) create mode 100644 web/src/providers/samizdat-service-provider.tsx create mode 100644 web/src/services/samizdat-service.ts diff --git a/web/src/providers/samizdat-service-provider.tsx b/web/src/providers/samizdat-service-provider.tsx new file mode 100644 index 0000000..649e01a --- /dev/null +++ b/web/src/providers/samizdat-service-provider.tsx @@ -0,0 +1,161 @@ +import { createContext, useContext, useMemo, type ReactNode } from 'react'; + +import { useWalletAccountTransactionSendingSigner } from '@solana/react'; + + +import { ChainContext } from '@/context/chain-context'; +import { ConnectionContext } from '@/context/connection-context'; +import { SelectedWalletAccountContext } from '@/context/selected-wallet-account-context'; +import { SamizdatBlockchainService } from '@/services/samizdat-service'; +import type { WithAddress } from '@/types/samizdat'; + +import type { + CampaignAccount, + CreateCampaignInstructionDataArgs, + NodeAccount, + PlayRecord, + PublisherAccount, + RegisterNodeInstructionDataArgs, + UpdateCampaignInstructionDataArgs, + UpdateNodeMetadataInstructionDataArgs, +} from '@client/index'; + +// ============================================================================ +// Samizdat Service — interface for blockchain interactions. +// +// Uses generated Codama types directly. All account data returned with +// `WithAddress` so callers always have the on-chain PDA address. +// ============================================================================ + +export interface SamizdatService { + // Publisher + registerPublisher(): Promise>; + getPublisher(authority: string): Promise | null>; + + // Campaigns + createCampaign(args: CreateCampaignInstructionDataArgs): Promise>; + getCampaigns(): Promise[]>; + getCampaign(address: string): Promise | null>; + fundCampaign(campaignAddress: string, amount: number): Promise; + updateCampaign( + campaignAddress: string, + args: UpdateCampaignInstructionDataArgs, + ): Promise; + addCidsToCampaign(campaignAddress: string, newCids: string[]): Promise; + closeCampaign(campaignAddress: string): Promise; + + // Node Operator + registerNode(args: RegisterNodeInstructionDataArgs): Promise>; + getNode(authority: string): Promise | null>; + updateNodeMetadata( + nodeAddress: string, + args: UpdateNodeMetadataInstructionDataArgs, + ): Promise; + + // Play Cycle + claimCampaign( + campaignAddress: string, + nodeAddress: string, + cidIndex: number, + ): Promise>; + confirmPlay(playRecordAddress: string): Promise; + timeoutPlay(playRecordAddress: string): Promise; + getPlayRecords(): Promise[]>; +} + +const SamizdatServiceContext = createContext(null); + +export function useSamizdatService(): SamizdatService { + const ctx = useContext(SamizdatServiceContext); + + if (!ctx) { + throw new Error('useSamizdatService must be used within a SamizdatServiceProvider'); + } + + return ctx; +} + +interface SamizdatServiceProviderProps { + children: ReactNode; + service: SamizdatService; +} + +export function SamizdatServiceProvider({ + children, + service, +}: SamizdatServiceProviderProps) { + return ( + + {children} + + ); +} + +// ============================================================================ +// Connected provider — instantiates the real service with wallet signer +// ============================================================================ + +/** + * Wraps children with SamizdatServiceProvider when a wallet is connected. + * When no wallet is connected, the service context is null (callers should + * check via useSamizdatService which will throw if used without a wallet). + */ +export function SamizdatServiceProviderConnected({ + children, +}: { + children: ReactNode; +}) { + const [selectedWalletAccount] = useContext(SelectedWalletAccountContext); + const { chain } = useContext(ChainContext); + const { connection } = useContext(ConnectionContext); + + // Only create the signer + service when a wallet account is selected + if (!selectedWalletAccount) { + return ( + + {children} + + ); + } + + return ( + + {children} + + ); +} + +/** + * Inner component that calls hooks unconditionally (hooks can't be conditional). + */ +function SamizdatServiceProviderInner({ + children, + chain, + connection, +}: { + children: ReactNode; + chain: `solana:${string}`; + connection: import('solana-kite').Connection; +}) { + const [selectedWalletAccount] = useContext(SelectedWalletAccountContext); + + // This hook must be called unconditionally — guarded by the parent check + const transactionSendingSigner = useWalletAccountTransactionSendingSigner( + selectedWalletAccount!, + chain + ); + + const service = useMemo( + () => new SamizdatBlockchainService(connection, transactionSendingSigner), + [connection, transactionSendingSigner] + ); + + return ( + + {children} + + ); +} diff --git a/web/src/services/samizdat-service.ts b/web/src/services/samizdat-service.ts new file mode 100644 index 0000000..efdee9d --- /dev/null +++ b/web/src/services/samizdat-service.ts @@ -0,0 +1,309 @@ +/** + * Samizdat blockchain service — real implementation using Codama-generated + * client and solana-kite for connection management. + */ +import { + CAMPAIGN_ACCOUNT_DISCRIMINATOR, + NODE_ACCOUNT_DISCRIMINATOR, + PLAY_RECORD_DISCRIMINATOR, + SAMIZDAT_PROGRAM_ADDRESS, + fetchMaybeCampaignAccount, + fetchMaybeNodeAccount, + fetchMaybePlayRecord, + fetchMaybePublisherAccount, + getAddCidsToCampaignInstructionAsync, + getCampaignAccountDecoder, + getClaimCampaignInstructionAsync, + getCloseCampaignInstructionAsync, + getConfirmPlayInstruction, + getCreateCampaignInstructionAsync, + getFundCampaignInstructionAsync, + getNodeAccountDecoder, + getPlayRecordDecoder, + getRegisterNodeInstructionAsync, + getRegisterPublisherInstructionAsync, + getTimeoutPlayInstruction, + getUpdateCampaignInstructionAsync, + getUpdateNodeMetadataInstruction, +} from '@client/index'; +import { + type Address, + type TransactionSendingSigner, + type TransactionSigner, + address as toAddress, + appendTransactionMessageInstructions, + createTransactionMessage, + lamports, + pipe, + setTransactionMessageFeePayerSigner, + setTransactionMessageLifetimeUsingBlockhash, + signAndSendTransactionMessageWithSigners, +} from '@solana/kit'; + + +import type { SamizdatService } from '@/providers/samizdat-service-provider'; +import type { WithAddress } from '@/types/samizdat'; + +import type { + CampaignAccount, + CreateCampaignInstructionDataArgs, + NodeAccount, + PlayRecord, + PublisherAccount, + RegisterNodeInstructionDataArgs, + UpdateCampaignInstructionDataArgs, + UpdateNodeMetadataInstructionDataArgs, +} from '@client/index'; +import type { Connection } from 'solana-kite'; + +// ─── Service Implementation ───────────────────────────────────────────────── + +export class SamizdatBlockchainService implements SamizdatService { + constructor( + private connection: Connection, + private signer: TransactionSendingSigner, + ) {} + + /** Widen to TransactionSigner for Codama instruction account metas. */ + private get authority(): TransactionSigner { + return this.signer as TransactionSigner; + } + + /** Build a v0 tx and let the wallet sign + send via TransactionSendingSigner. */ + private async sendIx( + instructions: Parameters[0]['instructions'], + ) { + const { value: latestBlockhash } = await this.connection.rpc.getLatestBlockhash().send(); + const txMsg = pipe( + createTransactionMessage({ version: 0 }), + (m) => setTransactionMessageFeePayerSigner(this.signer, m), + (m) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, m), + (m) => appendTransactionMessageInstructions(instructions, m), + ); + await signAndSendTransactionMessageWithSigners(txMsg); + } + + // ─── Publisher ────────────────────────────────────────────────────────── + + async registerPublisher(): Promise> { + const ix = await getRegisterPublisherInstructionAsync({ authority: this.authority }); + await this.sendIx([ix]); + const { pda } = await this.connection.getPDAAndBump( + SAMIZDAT_PROGRAM_ADDRESS, + ['publisher', this.signer.address], + ); + return this.fetchPublisher(pda); + } + + async getPublisher(authority: string): Promise | null> { + const { pda } = await this.connection.getPDAAndBump( + SAMIZDAT_PROGRAM_ADDRESS, + ['publisher', authority], + ); + try { + return await this.fetchPublisher(pda); + } catch { + return null; + } + } + + private async fetchPublisher(addr: Address): Promise> { + const acct = await fetchMaybePublisherAccount(this.connection.rpc, addr); + if (!acct.exists) throw new Error(`Publisher not found at ${addr}`); + return { ...acct.data, address: String(addr) }; + } + + // ─── Campaigns ────────────────────────────────────────────────────────── + + async createCampaign(args: CreateCampaignInstructionDataArgs): Promise> { + const ix = await getCreateCampaignInstructionAsync({ + authority: this.authority, + ...args, + }); + await this.sendIx([ix]); + + const { pda: publisherPDA } = await this.connection.getPDAAndBump( + SAMIZDAT_PROGRAM_ADDRESS, + ['publisher', this.signer.address], + ); + const { pda: campaignPDA } = await this.connection.getPDAAndBump( + SAMIZDAT_PROGRAM_ADDRESS, + ['campaign', publisherPDA, BigInt(args.campaignId)], + ); + return this.fetchCampaign(campaignPDA); + } + + async getCampaigns(): Promise[]> { + const getAll = this.connection.getAccountsFactory( + SAMIZDAT_PROGRAM_ADDRESS, + CAMPAIGN_ACCOUNT_DISCRIMINATOR, + getCampaignAccountDecoder(), + ); + const accounts = await getAll(); + return accounts + .filter((a) => a.exists) + .map((a) => ({ ...(a as { data: CampaignAccount }).data, address: String(a.address) })); + } + + async getCampaign(addr: string): Promise | null> { + try { + return await this.fetchCampaign(toAddress(addr)); + } catch { + return null; + } + } + + async fundCampaign(campaignAddress: string, amount: number): Promise { + const ix = await getFundCampaignInstructionAsync({ + authority: this.authority, + campaignAccount: toAddress(campaignAddress), + amount: lamports(BigInt(amount)), + }); + await this.sendIx([ix]); + } + + async updateCampaign( + campaignAddress: string, + args: UpdateCampaignInstructionDataArgs, + ): Promise { + const ix = await getUpdateCampaignInstructionAsync({ + authority: this.authority, + campaignAccount: toAddress(campaignAddress), + ...args, + }); + await this.sendIx([ix]); + } + + async addCidsToCampaign(campaignAddress: string, newCids: string[]): Promise { + const ix = await getAddCidsToCampaignInstructionAsync({ + authority: this.authority, + campaignAccount: toAddress(campaignAddress), + newCids, + }); + await this.sendIx([ix]); + } + + async closeCampaign(campaignAddress: string): Promise { + const ix = await getCloseCampaignInstructionAsync({ + authority: this.authority, + campaignAccount: toAddress(campaignAddress), + }); + await this.sendIx([ix]); + } + + // ─── Node Operator ────────────────────────────────────────────────────── + + async registerNode(args: RegisterNodeInstructionDataArgs): Promise> { + const ix = await getRegisterNodeInstructionAsync({ authority: this.authority, ...args }); + await this.sendIx([ix]); + const { pda } = await this.connection.getPDAAndBump( + SAMIZDAT_PROGRAM_ADDRESS, + ['node_account', this.signer.address, BigInt(args.nodeId)], + ); + return this.fetchNode(pda); + } + + async getNode(authority: string): Promise | null> { + const getAll = this.connection.getAccountsFactory( + SAMIZDAT_PROGRAM_ADDRESS, + NODE_ACCOUNT_DISCRIMINATOR, + getNodeAccountDecoder(), + ); + const accounts = await getAll(); + const match = accounts.find( + (a) => a.exists && (a as { data: NodeAccount }).data.authority === authority, + ); + if (!match || !match.exists) return null; + return { ...(match as { data: NodeAccount }).data, address: String(match.address) }; + } + + async updateNodeMetadata( + nodeAddress: string, + args: UpdateNodeMetadataInstructionDataArgs, + ): Promise { + const ix = getUpdateNodeMetadataInstruction({ + authority: this.authority, + nodeAccount: toAddress(nodeAddress), + ...args, + }); + await this.sendIx([ix]); + } + + // ─── Play Cycle ───────────────────────────────────────────────────────── + + async claimCampaign( + campaignAddress: string, + nodeAddress: string, + cidIndex: number, + ): Promise> { + const claimNonce = BigInt(Date.now()); + const ix = await getClaimCampaignInstructionAsync({ + authority: this.authority, + campaignAccount: toAddress(campaignAddress), + nodeAccount: toAddress(nodeAddress), + cidIndex, + claimNonce, + }); + await this.sendIx([ix]); + + const { pda } = await this.connection.getPDAAndBump( + SAMIZDAT_PROGRAM_ADDRESS, + ['play_record', campaignAddress, nodeAddress, claimNonce], + ); + return this.fetchPlayRecord(pda); + } + + async confirmPlay(playRecordAddress: string): Promise { + const record = await this.fetchPlayRecord(toAddress(playRecordAddress)); + const campaign = await this.fetchCampaign(record.campaignAccount); + const ix = getConfirmPlayInstruction({ + authority: this.authority, + playRecord: toAddress(playRecordAddress), + campaignAccount: record.campaignAccount, + publisherAccount: campaign.publisherAccount, + nodeAccount: record.nodeAccount, + }); + await this.sendIx([ix]); + } + + async timeoutPlay(playRecordAddress: string): Promise { + const record = await this.fetchPlayRecord(toAddress(playRecordAddress)); + const ix = getTimeoutPlayInstruction({ + playRecord: toAddress(playRecordAddress), + campaignAccount: record.campaignAccount, + }); + await this.sendIx([ix]); + } + + async getPlayRecords(): Promise[]> { + const getAll = this.connection.getAccountsFactory( + SAMIZDAT_PROGRAM_ADDRESS, + PLAY_RECORD_DISCRIMINATOR, + getPlayRecordDecoder(), + ); + const accounts = await getAll(); + return accounts + .filter((a) => a.exists) + .map((a) => ({ ...(a as { data: PlayRecord }).data, address: String(a.address) })); + } + + // ─── Private helpers ──────────────────────────────────────────────────── + + private async fetchCampaign(addr: Address): Promise> { + const acct = await fetchMaybeCampaignAccount(this.connection.rpc, addr); + if (!acct.exists) throw new Error(`Campaign not found at ${addr}`); + return { ...acct.data, address: String(addr) }; + } + + private async fetchNode(addr: Address): Promise> { + const acct = await fetchMaybeNodeAccount(this.connection.rpc, addr); + if (!acct.exists) throw new Error(`Node not found at ${addr}`); + return { ...acct.data, address: String(addr) }; + } + + private async fetchPlayRecord(addr: Address): Promise> { + const acct = await fetchMaybePlayRecord(this.connection.rpc, addr); + if (!acct.exists) throw new Error(`PlayRecord not found at ${addr}`); + return { ...acct.data, address: String(addr) }; + } +} diff --git a/web/src/types/samizdat.ts b/web/src/types/samizdat.ts index ece4d4a..fed5f3e 100644 --- a/web/src/types/samizdat.ts +++ b/web/src/types/samizdat.ts @@ -1,169 +1,117 @@ -// ============================================================================ -// Samizdat Protocol Types -// Mirrors the on-chain account structures from programs/samizdat/src/state/ -// ============================================================================ - -// --- Enums --- - -export enum CampaignStatus { - Active = 'Active', - Paused = 'Paused', - Depleted = 'Depleted', - Closed = 'Closed', -} +/** + * Samizdat Protocol — shared types and helpers. + * + * All account structs, enums and value types come directly from the + * Codama-generated client (`@client/index`). This file re-exports + * the ones the UI cares about and adds a thin display-helper layer. + */ + +import { + CampaignStatus, + NodeStatus, + PlayStatus, + PublisherStatus, + ScreenSize, +} from '@client/index'; +import { isSome, type Option } from '@solana/kit'; + +// ─── Re-exports from generated client ─────────────────────────────────────── + +export { CampaignStatus, NodeStatus, PlayStatus, PublisherStatus, ScreenSize }; + +export type { + CampaignAccount, + NodeAccount, + PlayRecord, + PublisherAccount, +} from '@client/index'; + +export type { + GeoLocation, + GeoBounds, + Resolution, + TargetFilters, + TargetFiltersArgs, +} from '@client/index'; + +// ─── Utility: attach a PDA address to an account data struct ──────────────── + +/** The generated account types don't carry their on-chain address. + * We pair them with the address from the `Account` envelope. */ +export type WithAddress = T & { address: string }; + +// ─── bigint → number for display ──────────────────────────────────────────── + +/** Safely coerce bigint/number to JS number for display. */ +export const num = (v: bigint | number): number => Number(v); + +// ─── Option unwrapping ─────────────────────────────────────────────────── + +/** Unwrap Option → T | null (avoids importing isSome in every page). */ +export function unwrap(opt: Option): T | null { + return isSome(opt) ? opt.value : null; +} + +// ─── ScreenSize display helpers ───────────────────────────────────────────── + +/** The four enum members as a plain array (avoids Object.values quirks). */ +export const SCREEN_SIZES = [ + ScreenSize.Small, + ScreenSize.Medium, + ScreenSize.Large, + ScreenSize.XLarge, +] as const; -export enum NodeStatus { - Active = 'Active', - Offline = 'Offline', - Suspended = 'Suspended', -} +/** Numeric ScreenSize → human label. Uses the enum's reverse mapping. */ +export const screenSizeLabel = (s: ScreenSize): string => ScreenSize[s]; -export enum PublisherStatus { - Active = 'Active', - Suspended = 'Suspended', -} +/** Form string → numeric enum lookup. */ +export const parseScreenSize = (s: string): ScreenSize => + ScreenSize[s as keyof typeof ScreenSize]; -export enum PlayStatus { - Claimed = 'Claimed', - Paid = 'Paid', - TimedOut = 'TimedOut', -} +// ─── CampaignStatus display helpers ───────────────────────────────────────── -export enum ScreenSize { - Small = 'Small', - Medium = 'Medium', - Large = 'Large', - XLarge = 'XLarge', -} +/** The four statuses as a plain array. */ +export const CAMPAIGN_STATUSES = [ + CampaignStatus.Active, + CampaignStatus.Paused, + CampaignStatus.Depleted, + CampaignStatus.Closed, +] as const; -// --- Content Tags (bitmask) --- +/** Numeric CampaignStatus → human label. */ +export const campaignStatusLabel = (s: CampaignStatus): string => + CampaignStatus[s]; -export const TAG_LABELS: Record = { - 0: 'None', - 1: 'Crypto', - 2: 'Betting', - 4: 'NSFW', - 8: 'Political', - 16: 'Alcohol', -}; +// ─── Content-tag bitmask helpers ──────────────────────────────────────────── export const TAG_BITS = [ - { bit: 1, label: 'Crypto' }, - { bit: 2, label: 'Betting' }, - { bit: 4, label: 'NSFW' }, - { bit: 8, label: 'Political' }, - { bit: 16, label: 'Alcohol' }, + { bit: 1n, label: 'Crypto' }, + { bit: 2n, label: 'Betting' }, + { bit: 4n, label: 'NSFW' }, + { bit: 8n, label: 'Political' }, + { bit: 16n, label: 'Alcohol' }, ] as const; -// --- Structs --- - -export interface GeoLocation { - /** Latitude in fixed-point (degrees × 1e7) */ - latitude: number; - /** Longitude in fixed-point (degrees × 1e7) */ - longitude: number; -} - -export interface Resolution { - width: number; - height: number; -} - -export interface GeoBounds { - minLat: number; - maxLat: number; - minLon: number; - maxLon: number; -} - -export interface TargetFilters { - minFootfall: number | null; - maxFootfall: number | null; - screenSizes: ScreenSize[]; - geoBounds: GeoBounds | null; - establishmentTypes: string[]; - requiredLandmarks: string[]; +/** Extract human-readable tag labels from a bitmask. */ +export function tagsFromMask(mask: bigint | number): string[] { + const m = BigInt(mask); + return TAG_BITS.filter(t => (m & t.bit) !== 0n).map(t => t.label); } -// --- Account Types --- - -export interface PublisherAccount { - address: string; - authority: string; - totalCampaigns: number; - totalSpent: number; - registeredAt: number; - status: PublisherStatus; -} - -export interface CampaignAccount { - address: string; - publisherAccount: string; - campaignId: number; - cids: string[]; - bountyPerPlay: number; - playsRemaining: number; - playsCompleted: number; - tagMask: number; - targetFilters: TargetFilters; - status: CampaignStatus; - claimCooldown: number; - createdAt: number; -} - -export interface NodeAccount { - address: string; - authority: string; - nodeId: number; - location: GeoLocation; - screenSize: ScreenSize; - resolution: Resolution; - landmarks: string[]; - blockedTagMask: number; - estimatedFootfall: number; - establishmentType: string; - totalPlays: number; - totalEarnings: number; - registeredAt: number; - status: NodeStatus; -} - -export interface PlayRecord { - address: string; - campaignAccount: string; - nodeAccount: string; - nonce: number; - claimedAt: number; - confirmedAt: number; - cidIndex: number; - paymentAmount: number; - status: PlayStatus; -} - -export interface ClaimCooldown { - campaign: string; - node: string; - lastClaimedAt: number; -} - -// --- Helpers --- - -/** Convert fixed-point i64 (× 1e7) to human-readable degrees */ -export function geoToDecimal(fixedPoint: number): number { - return fixedPoint / 1e7; -} +// ─── Display helpers ──────────────────────────────────────────────────────── -/** Convert lamports to SOL */ -export function lamportsToSol(lamports: number): number { - return lamports / 1e9; +/** Convert fixed-point i64 (degrees × 1e7) to decimal degrees. */ +export function geoToDecimal(fixedPoint: bigint | number): number { + return Number(BigInt(fixedPoint)) / 1e7; } -/** Extract tag labels from a bitmask */ -export function tagsFromMask(mask: number): string[] { - return TAG_BITS.filter(t => (mask & t.bit) !== 0).map(t => t.label); +/** Convert lamports (u64) to SOL. */ +export function lamportsToSol(lamports: bigint | number): number { + return Number(BigInt(lamports)) / 1e9; } -/** Truncate a Solana address for display */ +/** Truncate a Solana address for display. */ export function shortenAddress(address: string, chars = 4): string { return `${address.slice(0, chars)}...${address.slice(-chars)}`; } From f57b9c6bc6801688c30a7429af4dae773e20bf0c Mon Sep 17 00:00:00 2001 From: Nitish C <86357181+Nitish-bot@users.noreply.github.com> Date: Thu, 5 Mar 2026 15:46:30 +0530 Subject: [PATCH 09/17] setup react form hook and schemas w zod --- web/bun.lock | 9 +++ web/package.json | 5 +- web/src/utils/schemas.ts | 118 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 web/src/utils/schemas.ts diff --git a/web/bun.lock b/web/bun.lock index d5330ab..5dc891f 100644 --- a/web/bun.lock +++ b/web/bun.lock @@ -5,6 +5,7 @@ "": { "name": "untitledui-vite-starter-kit", "dependencies": { + "@hookform/resolvers": "^5.2.2", "@solana/kit": "^6.1.0", "@solana/react": "^6.1.0", "@tailwindcss/typography": "^0.5.19", @@ -20,6 +21,7 @@ "react-aria": "^3.46.0", "react-aria-components": "^1.15.1", "react-dom": "^19.2.3", + "react-hook-form": "^7.71.2", "react-hotkeys-hook": "^5.2.3", "react-router": "^7.13.0", "solana-kite": "^3.2.1", @@ -27,6 +29,7 @@ "tailwindcss": "^4.1.18", "tailwindcss-animate": "^1.0.7", "tailwindcss-react-aria-components": "^2.0.1", + "zod": "^4.3.6", }, "devDependencies": { "@tailwindcss/postcss": "^4.1.18", @@ -164,6 +167,8 @@ "@formatjs/intl-localematcher": ["@formatjs/intl-localematcher@0.6.2", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-XOMO2Hupl0wdd172Y06h6kLpBz6Dv+J4okPLl4LPtzbr8f66WbIoy4ev98EBuZ6ZK4h5ydTN6XneT4QVpD7cdA=="], + "@hookform/resolvers": ["@hookform/resolvers@5.2.2", "", { "dependencies": { "@standard-schema/utils": "^0.3.0" }, "peerDependencies": { "react-hook-form": "^7.55.0" } }, "sha512-A/IxlMLShx3KjV/HeTcTfaMxdwy690+L/ZADoeaTltLx+CVuzkeVIPuybK3jrRfw7YZnmdKsVVHAlEPIAEUNlA=="], + "@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="], "@humanfs/node": ["@humanfs/node@0.16.7", "", { "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.4.0" } }, "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ=="], @@ -560,6 +565,8 @@ "@solana/wallet-standard-features": ["@solana/wallet-standard-features@1.3.0", "", { "dependencies": { "@wallet-standard/base": "^1.1.0", "@wallet-standard/features": "^1.1.0" } }, "sha512-ZhpZtD+4VArf6RPitsVExvgkF+nGghd1rzPjd97GmBximpnt1rsUxMOEyoIEuH3XBxPyNB6Us7ha7RHWQR+abg=="], + "@standard-schema/utils": ["@standard-schema/utils@0.3.0", "", {}, "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g=="], + "@swc/core": ["@swc/core@1.15.10", "", { "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.25" }, "optionalDependencies": { "@swc/core-darwin-arm64": "1.15.10", "@swc/core-darwin-x64": "1.15.10", "@swc/core-linux-arm-gnueabihf": "1.15.10", "@swc/core-linux-arm64-gnu": "1.15.10", "@swc/core-linux-arm64-musl": "1.15.10", "@swc/core-linux-x64-gnu": "1.15.10", "@swc/core-linux-x64-musl": "1.15.10", "@swc/core-win32-arm64-msvc": "1.15.10", "@swc/core-win32-ia32-msvc": "1.15.10", "@swc/core-win32-x64-msvc": "1.15.10" }, "peerDependencies": { "@swc/helpers": ">=0.5.17" }, "optionalPeers": ["@swc/helpers"] }, "sha512-udNofxftduMUEv7nqahl2nvodCiCDQ4Ge0ebzsEm6P8s0RC2tBM0Hqx0nNF5J/6t9uagFJyWIDjXy3IIWMHDJw=="], "@swc/core-darwin-arm64": ["@swc/core-darwin-arm64@1.15.10", "", { "os": "darwin", "cpu": "arm64" }, "sha512-U72pGqmJYbjrLhMndIemZ7u9Q9owcJczGxwtfJlz/WwMaGYAV/g4nkGiUVk/+QSX8sFCAjanovcU1IUsP2YulA=="], @@ -1254,6 +1261,8 @@ "react-dom": ["react-dom@19.2.3", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.3" } }, "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg=="], + "react-hook-form": ["react-hook-form@7.71.2", "", { "peerDependencies": { "react": "^16.8.0 || ^17 || ^18 || ^19" } }, "sha512-1CHvcDYzuRUNOflt4MOq3ZM46AronNJtQ1S7tnX6YN4y72qhgiUItpacZUAQ0TyWYci3yz1X+rXaSxiuEm86PA=="], + "react-hotkeys-hook": ["react-hotkeys-hook@5.2.3", "", { "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-Q27F8EuImYJOVSXAjSQrQPj9cx4GSNY+WdSdk5tSNN085H8/a00W6LZp0PrytEDwF6iT0pGTJeVEDKPRpEK2Bg=="], "react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="], diff --git a/web/package.json b/web/package.json index c219f18..4f348d0 100644 --- a/web/package.json +++ b/web/package.json @@ -13,6 +13,7 @@ "format:fix": "bunx prettier --write ." }, "dependencies": { + "@hookform/resolvers": "^5.2.2", "@solana/kit": "^6.1.0", "@solana/react": "^6.1.0", "@tailwindcss/typography": "^0.5.19", @@ -28,13 +29,15 @@ "react-aria": "^3.46.0", "react-aria-components": "^1.15.1", "react-dom": "^19.2.3", + "react-hook-form": "^7.71.2", "react-hotkeys-hook": "^5.2.3", "react-router": "^7.13.0", "solana-kite": "^3.2.1", "tailwind-merge": "^3.4.0", "tailwindcss": "^4.1.18", "tailwindcss-animate": "^1.0.7", - "tailwindcss-react-aria-components": "^2.0.1" + "tailwindcss-react-aria-components": "^2.0.1", + "zod": "^4.3.6" }, "devDependencies": { "@tailwindcss/postcss": "^4.1.18", diff --git a/web/src/utils/schemas.ts b/web/src/utils/schemas.ts new file mode 100644 index 0000000..d9ca7e9 --- /dev/null +++ b/web/src/utils/schemas.ts @@ -0,0 +1,118 @@ +import { z } from 'zod'; + +// ============================================================================ +// Zod Validation Schemas — form validation for Samizdat protocol interactions +// ============================================================================ + +// --- Create Campaign --- + +export const createCampaignSchema = z.object({ + campaignId: z.coerce + .number({ message: 'Required' }) + .int('Must be an integer') + .positive('Must be positive'), + cids: z + .string() + .min(1, 'At least one CID is required') + .transform(val => + val + .split('\n') + .map(s => s.trim()) + .filter(Boolean) + ) + .refine(arr => arr.length <= 10, 'Max 10 CIDs') + .refine(arr => arr.every(s => s.length >= 10), 'Each CID must be at least 10 characters'), + bountyPerPlay: z.coerce + .number({ message: 'Required' }) + .positive('Must be positive'), + totalPlays: z.coerce + .number({ message: 'Required' }) + .int('Must be an integer') + .positive('Must be positive'), + claimCooldown: z.coerce + .number({ message: 'Required' }) + .int('Must be an integer') + .positive('Must be positive'), + tagMask: z.number().int().min(0).default(0), + + // Target filters — optional + minFootfall: z.union([z.coerce.number().int().min(0), z.literal('')]).optional(), + maxFootfall: z.union([z.coerce.number().int().min(0), z.literal('')]).optional(), + screenSizes: z.array(z.string()).default([]), + geoBoundsMinLat: z.union([z.coerce.number(), z.literal('')]).optional(), + geoBoundsMaxLat: z.union([z.coerce.number(), z.literal('')]).optional(), + geoBoundsMinLon: z.union([z.coerce.number(), z.literal('')]).optional(), + geoBoundsMaxLon: z.union([z.coerce.number(), z.literal('')]).optional(), + establishmentTypes: z.string().optional(), + requiredLandmarks: z.string().optional(), +}); + +export type CreateCampaignForm = z.infer; +export type CreateCampaignFormInput = z.input; + +// --- Register Node --- + +export const registerNodeSchema = z.object({ + nodeId: z.coerce + .number({ message: 'Required' }) + .int('Must be an integer') + .positive('Must be positive'), + latitude: z.coerce + .number({ message: 'Required' }) + .min(-90, 'Min -90°') + .max(90, 'Max 90°'), + longitude: z.coerce + .number({ message: 'Required' }) + .min(-180, 'Min -180°') + .max(180, 'Max 180°'), + screenSize: z.enum(['Small', 'Medium', 'Large', 'XLarge'], { + message: 'Select a screen size', + }), + resolutionWidth: z.coerce + .number({ message: 'Required' }) + .int() + .positive('Must be positive'), + resolutionHeight: z.coerce + .number({ message: 'Required' }) + .int() + .positive('Must be positive'), + landmarks: z.string().optional(), + blockedTagMask: z.number().int().min(0).default(0), + estimatedFootfall: z.coerce + .number({ message: 'Required' }) + .int() + .min(0, 'Must be non-negative'), + establishmentType: z.string().min(1, 'Required'), +}); + +export type RegisterNodeForm = z.infer; + +// --- Update Node Settings --- + +export const updateNodeSettingsSchema = z.object({ + latitude: z.coerce + .number({ message: 'Required' }) + .min(-90, 'Min -90°') + .max(90, 'Max 90°'), + longitude: z.coerce + .number({ message: 'Required' }) + .min(-180, 'Min -180°') + .max(180, 'Max 180°'), + estimatedFootfall: z.coerce + .number({ message: 'Required' }) + .int() + .min(0, 'Must be non-negative'), + blockedTagMask: z.bigint().min(0n).default(0n), +}); + +export type UpdateNodeSettingsForm = z.infer; + +// --- Fund Campaign --- + +export const fundCampaignSchema = z.object({ + amount: z.coerce + .number({ message: 'Required' }) + .positive('Must be positive'), +}); + +export type FundCampaignForm = z.infer; From 834c9a05019191fced79f4386d4be402f511eda6 Mon Sep 17 00:00:00 2001 From: Nitish C <86357181+Nitish-bot@users.noreply.github.com> Date: Thu, 5 Mar 2026 15:47:03 +0530 Subject: [PATCH 10/17] add publisher page --- web/src/pages/publisher.tsx | 936 ++++++++++++++++++++++++++++++++++++ 1 file changed, 936 insertions(+) create mode 100644 web/src/pages/publisher.tsx diff --git a/web/src/pages/publisher.tsx b/web/src/pages/publisher.tsx new file mode 100644 index 0000000..12609bb --- /dev/null +++ b/web/src/pages/publisher.tsx @@ -0,0 +1,936 @@ +import { useCallback, useContext, useEffect, useState } from 'react'; + +import { zodResolver } from '@hookform/resolvers/zod'; +import { + AlertCircle, + CheckCircle, + Clock, + CurrencyDollar, + Eye, + Loading01, + PauseCircle, + Plus, + Send01, + Trash01, + XCircle, + Zap, +} from '@untitledui/icons'; +import { UiWalletAccount } from '@wallet-standard/react'; +import { AnimatePresence, motion } from 'motion/react'; +import { Controller, useForm } from 'react-hook-form'; + +import { Badge, BadgeWithDot } from '@/components/base/badges/badges'; +import { Button } from '@/components/base/buttons/button'; +import { Checkbox } from '@/components/base/checkbox/checkbox'; +import { Input } from '@/components/base/input/input'; +import { ProgressBar } from '@/components/base/progress-indicators/progress-indicators'; +import { TextArea } from '@/components/base/textarea/textarea'; +import { SelectedWalletAccountContext } from '@/context/selected-wallet-account-context'; +import { + useSamizdatService, + type SamizdatService, +} from '@/providers/samizdat-service-provider'; +import { + CAMPAIGN_STATUSES, + type CampaignAccount, + CampaignStatus, + type PublisherAccount, + SCREEN_SIZES, + TAG_BITS, + type TargetFiltersArgs, + type WithAddress, + campaignStatusLabel, + lamportsToSol, + num, + parseScreenSize, + screenSizeLabel, + shortenAddress, + tagsFromMask, + unwrap, +} from '@/types/samizdat'; +import { pollUntilReady } from '@/utils/poll-until-ready'; +import { + type CreateCampaignForm, + type CreateCampaignFormInput, + createCampaignSchema, +} from '@/utils/schemas'; + +// ============================================================================ +// Publisher Dashboard +// ============================================================================ + +function StatusBadge({ status }: { status: CampaignStatus }) { + const config = { + [CampaignStatus.Active]: { color: 'success' as const, label: 'Active' }, + [CampaignStatus.Paused]: { color: 'warning' as const, label: 'Paused' }, + [CampaignStatus.Depleted]: { color: 'error' as const, label: 'Depleted' }, + [CampaignStatus.Closed]: { color: 'gray' as const, label: 'Closed' }, + }; + + const c = config[status]; + + return ( + + {c.label} + + ); +} + +function CampaignRow({ + campaign, + onSelect, +}: { + campaign: WithAddress; + onSelect: (c: WithAddress) => void; +}) { + const total = num(campaign.playsRemaining) + num(campaign.playsCompleted); + const pct = total > 0 ? (num(campaign.playsCompleted) / total) * 100 : 0; + const tags = tagsFromMask(campaign.tagMask); + + return ( + onSelect(campaign)} + initial={{ opacity: 0, y: 10 }} + animate={{ opacity: 1, y: 0 }} + layout + > + + #{String(campaign.campaignId)} + + + + + + + {lamportsToSol(campaign.bountyPerPlay)} SOL + + + +
+
+ + {num(campaign.playsCompleted)}/{total} + + {Math.round(pct)}% +
+ +
+ + +
+ {tags.length > 0 ? ( + tags.map(tag => ( + + {tag} + + )) + ) : ( + None + )} +
+ + + + {new Date(num(campaign.createdAt) * 1000).toLocaleDateString()} + + +
+ ); +} + +function CampaignDetail({ + campaign, + service, + onClose, + onRefresh, +}: { + campaign: WithAddress; + service: SamizdatService; + onClose: () => void; + onRefresh: () => void; +}) { + const [busy, setBusy] = useState(false); + const total = num(campaign.playsRemaining) + num(campaign.playsCompleted); + const pct = total > 0 ? (num(campaign.playsCompleted) / total) * 100 : 0; + const tags = tagsFromMask(campaign.tagMask); + const tf = campaign.targetFilters; + + const doAction = async (label: string, fn: () => Promise) => { + if (busy) return; + setBusy(true); + try { + await fn(); + onRefresh(); + onClose(); + } catch (err) { + console.error(`${label} failed:`, err); + alert(`${label} failed: ${err instanceof Error ? err.message : String(err)}`); + } finally { + setBusy(false); + } + }; + + return ( + + e.stopPropagation()} + > + {/* Header */} +
+
+
+

+ Campaign #{String(campaign.campaignId)} +

+ +
+

+ {campaign.address} +

+
+ +
+ + {/* Stats */} +
+
+

Bounty/Play

+

+ {lamportsToSol(campaign.bountyPerPlay)} SOL +

+
+
+

Plays

+

+ {num(campaign.playsCompleted)} + / {total} +

+
+
+

Total Spent

+

+ {lamportsToSol(num(campaign.playsCompleted) * num(campaign.bountyPerPlay))} SOL +

+
+
+ + {/* Progress */} +
+
+ Campaign Progress + {Math.round(pct)}% +
+ +
+ + {/* Details */} +
+
+

Tags

+
+ {tags.length > 0 ? ( + tags.map(tag => ( + + {tag} + + )) + ) : ( + None + )} +
+
+
+

Screen Sizes

+

+ {tf.screenSizes.length > 0 + ? tf.screenSizes.map(screenSizeLabel).join(', ') + : 'Any'} +

+
+
+

Establishment Types

+

+ {tf.establishmentTypes.length > 0 + ? tf.establishmentTypes.join(', ') + : 'Any'} +

+
+
+

Footfall Range

+

+ {unwrap(tf.minFootfall) ?? '—'} – {unwrap(tf.maxFootfall) ?? '∞'} +

+
+
+

Content CIDs

+
+ {campaign.cids.map((cid, i) => ( + + {cid} + + ))} +
+
+
+ + {/* Actions */} +
+ {campaign.status === CampaignStatus.Active && ( + + )} + {campaign.status === CampaignStatus.Paused && ( + + )} + {campaign.status !== CampaignStatus.Closed && ( + + )} + {busy && ( + + + Processing... + + )} +
+
+
+ ); +} + +function CreateCampaignModal({ + service, + onClose, + onCreated, +}: { + service: SamizdatService; + onClose: () => void; + onCreated: () => void; +}) { + const [submitting, setSubmitting] = useState(false); + + const { + control, + handleSubmit, + watch, + setValue, + } = useForm({ + resolver: zodResolver(createCampaignSchema), + defaultValues: { + campaignId: undefined, + cids: '', + bountyPerPlay: undefined, + totalPlays: undefined, + claimCooldown: 300, + tagMask: 0, + minFootfall: '', + maxFootfall: '', + screenSizes: [], + geoBoundsMinLat: '', + geoBoundsMaxLat: '', + geoBoundsMinLon: '', + geoBoundsMaxLon: '', + establishmentTypes: '', + requiredLandmarks: '', + }, + }); + + const tagMask = watch('tagMask') ?? 0; + const screenSizes = watch('screenSizes') ?? []; + + const toggleTag = (bit: number) => setValue('tagMask', tagMask ^ bit); + const toggleScreenSize = (size: string) => { + setValue('screenSizes', screenSizes.includes(size) ? screenSizes.filter(s => s !== size) : [...screenSizes, size]); + }; + + const onSubmit = async (data: CreateCampaignForm) => { + setSubmitting(true); + try { + const hasGeo = + data.geoBoundsMinLat !== '' && data.geoBoundsMaxLat !== '' && + data.geoBoundsMinLon !== '' && data.geoBoundsMaxLon !== ''; + + const targetFilters: TargetFiltersArgs = { + minFootfall: data.minFootfall !== '' && data.minFootfall != null ? Number(data.minFootfall) : null, + maxFootfall: data.maxFootfall !== '' && data.maxFootfall != null ? Number(data.maxFootfall) : null, + screenSizes: data.screenSizes.map(parseScreenSize), + geoBounds: hasGeo + ? { + minLat: Math.round(Number(data.geoBoundsMinLat) * 1e7), + maxLat: Math.round(Number(data.geoBoundsMaxLat) * 1e7), + minLon: Math.round(Number(data.geoBoundsMinLon) * 1e7), + maxLon: Math.round(Number(data.geoBoundsMaxLon) * 1e7), + } + : null, + establishmentTypes: data.establishmentTypes + ? data.establishmentTypes.split(',').map(s => s.trim()).filter(Boolean) + : [], + requiredLandmarks: data.requiredLandmarks + ? data.requiredLandmarks.split(',').map(s => s.trim()).filter(Boolean) + : [], + }; + + await service.createCampaign({ + campaignId: data.campaignId, + cids: data.cids, + bountyPerPlay: Math.round(data.bountyPerPlay * 1e9), + totalPlays: data.totalPlays, + tagMask: data.tagMask, + targetFilters, + claimCooldown: data.claimCooldown, + }); + + // Poll until the campaign is queryable + await pollUntilReady( + async () => { + const campaigns = await service.getCampaigns(); + const found = campaigns.find(c => Number(c.campaignId) === data.campaignId); + if (!found) throw new Error('Campaign not found'); + return found; + }, + { resourceName: 'Campaign account' } + ); + + onCreated(); + onClose(); + } catch (err) { + console.error('Create campaign failed:', err); + alert(`Failed: ${err instanceof Error ? err.message : String(err)}`); + } finally { + setSubmitting(false); + } + }; + + return ( + + e.stopPropagation()} + > +
+

Create Campaign

+ +
+ +
+ {/* Campaign ID */} + ( + + )} + /> + + {/* Content CIDs */} + ( +